001: /**
002: * Redistribution and use of this software and associated documentation
003: * ("Software"), with or without modification, are permitted provided
004: * that the following conditions are met:
005: *
006: * 1. Redistributions of source code must retain copyright
007: * statements and notices. Redistributions must also contain a
008: * copy of this document.
009: *
010: * 2. Redistributions in binary form must reproduce the
011: * above copyright notice, this list of conditions and the
012: * following disclaimer in the documentation and/or other
013: * materials provided with the distribution.
014: *
015: * 3. The name "Exolab" must not be used to endorse or promote
016: * products derived from this Software without prior written
017: * permission of Intalio, Inc. For written permission,
018: * please contact info@exolab.org.
019: *
020: * 4. Products derived from this Software may not be called "Exolab"
021: * nor may "Exolab" appear in their names without prior written
022: * permission of Intalio, Inc. Exolab is a registered
023: * trademark of Intalio, Inc.
024: *
025: * 5. Due credit should be given to the Exolab Project
026: * (http://www.exolab.org/).
027: *
028: * THIS SOFTWARE IS PROVIDED BY INTALIO, INC. AND CONTRIBUTORS
029: * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
030: * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
031: * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
032: * INTALIO, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
033: * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
034: * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
035: * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
036: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
037: * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
038: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
039: * OF THE POSSIBILITY OF SUCH DAMAGE.
040: *
041: * Copyright 1999-2004 (C) Intalio, Inc. All Rights Reserved.
042: *
043: * $Id: ContentModelGroupImpl.java 6230 2006-09-19 07:56:07Z wguttmn $
044: */package org.exolab.castor.xml.schema;
045:
046: import java.util.Enumeration;
047: import java.util.Vector;
048:
049: /**
050: * An implementation of an XML Schema ContentModelGroup
051: *
052: * @author <a href="mailto:kvisco@intalio.com">Keith Visco</a>
053: * @author <a href="mailto:blandin@intalio.com">Arnaud Blandin</a>
054: * @version $Revision: 6230 $ $Date: 2006-04-14 04:14:43 -0600 (Fri, 14 Apr 2006) $
055: */
056: class ContentModelGroupImpl implements ContentModelGroup,
057: java.io.Serializable {
058: /** SerialVersionUID */
059: private static final long serialVersionUID = -2477271185972337873L;
060:
061: private Vector _contentModel = null;
062: private transient ScopableResolver _resolver = null;
063:
064: /**
065: * Creates a new ContentModelGroup.
066: **/
067: public ContentModelGroupImpl() {
068: _contentModel = new Vector();
069: _resolver = new ScopableResolver();
070: } //-- ContentModelGroup
071:
072: /**
073: * Adds a wildcard to this contentModelGroup
074: * @param wildcard the Wildcard to add
075: * @exception SchemaException thrown when the wildcard
076: * is an <anyAttribute> element
077: */
078: public void addWildcard(Wildcard wildcard) throws SchemaException {
079: if (wildcard.isAttributeWildcard())
080: throw new SchemaException(
081: "only <any> should be add in a group.");
082: _contentModel.addElement(wildcard);
083: }
084:
085: /**
086: * Adds the given ElementDecl to this ContentModelGroup
087: * @param elementDecl the ElementDecl to add
088: * @exception SchemaException when an ElementDecl already
089: * exists with the same name as the given ElementDecl
090: **/
091: public void addElementDecl(ElementDecl elementDecl)
092: throws SchemaException {
093:
094: if (elementDecl == null)
095: return;
096:
097: String name = elementDecl.getName();
098:
099: if (!elementDecl.isReference()) {
100: String key = "element:" + name;
101: //-- check for naming collisions
102: if (_resolver.resolve(key) != null) {
103: String err = "An element declaration with the given name, ";
104: err += name + ", already exists in this scope.";
105: throw new SchemaException(err);
106: }
107: _resolver.addResolvable(key, elementDecl);
108: }
109:
110: //-- add to content model
111: _contentModel.addElement(elementDecl);
112:
113: } //-- addElementDecl
114:
115: /**
116: * Removes the given ElementDecl from this ContentModelGroup.
117: * @param elementDecl the ElementDecl to remove.
118: * @return true if the element has been successfully removed, false otherwise.
119: */
120: public boolean removeElementDecl(ElementDecl elementDecl) {
121: if (elementDecl == null)
122: return false;
123: int position = _contentModel.indexOf(elementDecl);
124: if (position >= 0) {
125: _contentModel.removeElementAt(position);
126: if (!elementDecl.isReference()) {
127: String key = "element:" + elementDecl.getName();
128: _resolver.removeResolvable(key);
129: }
130: return true;
131: }
132: return false;
133: }
134:
135: /**
136: * Adds the given Group to this ContentModelGroup
137: * @param group the Group to add
138: * @exception SchemaException when a group with the same name as the
139: * specified group already exists in the current scope
140: **/
141: public void addGroup(Group group) throws SchemaException {
142: if (group == null)
143: return;
144:
145: String name = group.getName();
146: if (name != null) {
147: String key = "group:" + name;
148: //-- check for naming collisions
149: if (_resolver.resolve(key) != null) {
150: String err = "A group definition with the given name, ";
151: err += name + ", already exists in this scope.";
152: throw new SchemaException(err);
153: }
154:
155: _resolver.addResolvable(key, group);
156: }
157:
158: //-- add to content model
159: _contentModel.addElement(group);
160: } //-- addGroup
161:
162: /**
163: * Removes the given Group from this ContentModelGroup.
164: * @param group the Group to remove.
165: * @return true if the group has been successfully removed, false otherwise.
166: */
167: public boolean removeGroup(Group group) {
168: if (group == null)
169: return false;
170: int position = _contentModel.indexOf(group);
171: if (position >= 0) {
172: String name = group.getName();
173: if (name != null) {
174: String key = "group:" + name;
175: _resolver.removeResolvable(key);
176: }
177: _contentModel.removeElementAt(position);
178: return true;
179: }
180: return false;
181: }
182:
183: /**
184: * Adds the given ModelGroup Definition to this ContentModelGroup
185: * @param group the ModelGroup to add
186: * @exception SchemaException when a modelgroup with the same name as the
187: * specified group already exists in the current scope
188: **/
189: public void addGroup(ModelGroup group) throws SchemaException {
190: if (group == null)
191: return;
192:
193: String name = group.getName();
194: if ((name != null) && (!group.isReference())) {
195: String key = "group:" + name;
196: //-- check for naming collisions
197: if (_resolver.resolve(key) != null) {
198: String err = "An element declaration with the given name, ";
199: err += name + ", already exists in this scope.";
200: throw new SchemaException(err);
201: }
202:
203: _resolver.addResolvable(key, group);
204: }
205:
206: //-- add to content model
207: _contentModel.addElement(group);
208: } //-- addGroup
209:
210: /**
211: * Removes the given ModelGroup Definition from this ContentModelGroup.
212: * @param group the ModelGroup Definition to remove.
213: * @return true if the group has been successfully removed, false otherwise.
214: */
215: public boolean removeGroup(ModelGroup group) {
216: if (group == null)
217: return false;
218: int position = _contentModel.indexOf(group);
219: if (position >= 0) {
220: String name = group.getName();
221: if ((name != null) && (!group.isReference())) {
222: String key = "group:" + name;
223: _resolver.removeResolvable(key);
224: }
225: _contentModel.removeElementAt(position);
226: return true;
227: }
228: return false;
229: }
230:
231: /**
232: * Removes the given Wildcard from this Group.
233: *
234: * @param wildcard the Wildcard to remove.
235: * @return true if the wildcard has been successfully removed, false otherwise.
236: */
237: public boolean removeWildcard(Wildcard wildcard) {
238: if (wildcard == null)
239: return false;
240: int position = _contentModel.indexOf(wildcard);
241: if (position >= 0) {
242: _contentModel.removeElementAt(position);
243: return true;
244: }
245: return false;
246: }
247:
248: /**
249: * Returns an enumeration of all the Particles contained
250: * within this ContentModelGroup
251: *
252: * @return an enumeration of all the Particels contained
253: * within this ContentModelGroup
254: **/
255: public Enumeration enumerate() {
256: return _contentModel.elements();
257: } //-- enumerate
258:
259: /**
260: * Returns the element declaration with the given name, or null if no
261: * element declaration with that name exists in this ContentModelGroup.
262: *
263: * @param name the name of the element.
264: * @return the ElementDecl with the given name, or null if no
265: * ElementDecl exists in this ContentModelGroup.
266: **/
267: public ElementDecl getElementDecl(String name) {
268: if (name == null)
269: return null;
270: ElementDecl result = null;
271: if (_resolver != null) {
272: String key = "element:" + name;
273: result = (ElementDecl) _resolver.resolve(key);
274: //resolver is always not null (initialized in the constructor)
275: //but it may not contain the element (in case of a complexType)
276: if (result != null)
277: return result;
278: }
279: for (int i = 0; i < _contentModel.size(); i++) {
280: Particle p = (Particle) _contentModel.elementAt(i);
281: switch (p.getStructureType()) {
282: case Structure.ELEMENT:
283: ElementDecl e = (ElementDecl) p;
284: if (name.equals(e.getName())) {
285: result = e;
286: }
287: break;
288: case Structure.GROUP:
289: case Structure.MODELGROUP:
290: result = ((ContentModelGroup) p).getElementDecl(name);
291: break;
292: default:
293: break;
294: }
295: if (result != null)
296: break;
297: }
298: return result;
299: } //-- getElementDecl
300:
301: /**
302: * Returns the maximum number of occurances that this ContentModelGroup
303: * may appear
304: * @return the maximum number of occurances that this ContentModelGroup
305: * may appear.
306: * A non positive (n < 1) value indicates that the
307: * value is unspecified (ie. unbounded).
308: **/
309: public int getMaxOccurs() {
310: return 1;
311: }
312:
313: /**
314: * Returns the minimum number of occurances that this ContentModelGroup
315: * must appear
316: * @return the minimum number of occurances that this ContentModelGroup
317: * must appear
318: * A negative (n < 0) value indicates that the value is unspecified.
319: **/
320: public int getMinOccurs() {
321: return 1;
322: }
323:
324: /**
325: * Returns the Particle at the specified index
326: * @param index the index of the particle to return
327: * @return the CMParticle at the specified index
328: **/
329: public Particle getParticle(int index) {
330: return (Particle) _contentModel.elementAt(index);
331: } //-- getParticle
332:
333: /**
334: * Returns the number of particles contained within
335: * this ContentModelGroup
336: *
337: * @return the number of particles
338: **/
339: public int getParticleCount() {
340: return _contentModel.size();
341: } //-- getParticleCount
342:
343: } //-- ContentModelGroup
|