View Javadoc
1   /**
2    * Redistribution and use of this software and associated documentation ("Software"), with or
3    * without modification, are permitted provided that the following conditions are met:
4    *
5    * 1. Redistributions of source code must retain copyright statements and notices. Redistributions
6    * must also contain a copy of this document.
7    *
8    * 2. Redistributions in binary form must reproduce the above copyright notice, this list of
9    * conditions and the following disclaimer in the documentation and/or other materials provided with
10   * the distribution.
11   *
12   * 3. The name "Exolab" must not be used to endorse or promote products derived from this Software
13   * without prior written permission of Intalio, Inc. For written permission, please contact
14   * info@exolab.org.
15   *
16   * 4. Products derived from this Software may not be called "Exolab" nor may "Exolab" appear in
17   * their names without prior written permission of Intalio, Inc. Exolab is a registered trademark of
18   * Intalio, Inc.
19   *
20   * 5. Due credit should be given to the Exolab Project (http://www.exolab.org/).
21   *
22   * THIS SOFTWARE IS PROVIDED BY INTALIO, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESSED OR
23   * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
24   * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTALIO, INC. OR ITS
25   * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27   * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28   * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
29   * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30   *
31   * Copyright 1999-2004 (C) Intalio, Inc. All Rights Reserved.
32   *
33   * $Id$
34   */
35  
36  package org.exolab.castor.xml.schema;
37  
38  import java.util.Enumeration;
39  import java.util.Vector;
40  
41  /**
42   * An implementation of an XML Schema content model group.
43   *
44   * @author <a href="mailto:kvisco@intalio.com">Keith Visco</a>
45   * @author <a href="mailto:blandin@intalio.com">Arnaud Blandin</a>
46   * @version $Revision$ $Date: 2006-04-14 04:14:43 -0600 (Fri, 14 Apr 2006) $
47   */
48  class ContentModelGroupImpl implements ContentModelGroup, java.io.Serializable {
49    /** SerialVersionUID */
50    private static final long serialVersionUID = -2477271185972337873L;
51  
52    /**
53     * Collection holding all {@link Particle}s of this content model group.
54     */
55    private final Vector<Particle> _contentModel = new Vector<>();
56  
57    private transient ScopableResolver _resolver = new ScopableResolver();
58  
59    /**
60     * {@inheritDoc}
61     * 
62     * @see org.exolab.castor.xml.schema.ContentModelGroup#addWildcard(org.exolab.castor.xml.schema.Wildcard)
63     */
64    public void addWildcard(final Wildcard wildcard) throws SchemaException {
65      if (wildcard.isAttributeWildcard()) {
66        throw new SchemaException("only <any> should be add in a group.");
67      }
68      _contentModel.add(wildcard);
69    }
70  
71    /**
72     * {@inheritDoc}
73     * 
74     * @see org.exolab.castor.xml.schema.ContentModelGroup#addElementDecl(org.exolab.castor.xml.schema.ElementDecl)
75     */
76    public void addElementDecl(final ElementDecl elementDecl) throws SchemaException {
77  
78      if (elementDecl == null) {
79        return;
80      }
81  
82      String name = elementDecl.getName();
83  
84      if (!elementDecl.isReference()) {
85        String key = "element:" + name;
86        // -- check for naming collisions
87        if (_resolver.resolve(key) != null) {
88          String err = "An element declaration with the given name, ";
89          err += name + ", already exists in this scope.";
90          throw new SchemaException(err);
91        }
92        _resolver.addResolvable(key, elementDecl);
93      }
94  
95      // -- add to content model
96      _contentModel.add(elementDecl);
97  
98    }
99  
100   /**
101    * {@inheritDoc}
102    * 
103    * @see org.exolab.castor.xml.schema.ContentModelGroup#removeElementDecl(org.exolab.castor.xml.schema.ElementDecl)
104    */
105   public boolean removeElementDecl(final ElementDecl elementDecl) {
106     if (elementDecl == null) {
107       return false;
108     }
109     int position = _contentModel.indexOf(elementDecl);
110     if (position >= 0) {
111       _contentModel.removeElementAt(position);
112       if (!elementDecl.isReference()) {
113         String key = "element:" + elementDecl.getName();
114         _resolver.removeResolvable(key);
115       }
116       return true;
117     }
118     return false;
119   }
120 
121   /**
122    * {@inheritDoc}
123    * 
124    * @see org.exolab.castor.xml.schema.ContentModelGroup#addGroup(org.exolab.castor.xml.schema.Group)
125    */
126   public void addGroup(final Group group) throws SchemaException {
127     if (group == null) {
128       return;
129     }
130 
131     String name = group.getName();
132     if (name != null) {
133       String key = "group:" + name;
134       // -- check for naming collisions
135       if (_resolver.resolve(key) != null) {
136         String err = "A group definition with the given name, ";
137         err += name + ", already exists in this scope.";
138         throw new SchemaException(err);
139       }
140 
141       _resolver.addResolvable(key, group);
142     }
143 
144     // -- add to content model
145     _contentModel.add(group);
146   }
147 
148   /**
149    * {@inheritDoc}
150    * 
151    * @see org.exolab.castor.xml.schema.ContentModelGroup#removeGroup(org.exolab.castor.xml.schema.Group)
152    */
153   public boolean removeGroup(final Group group) {
154     if (group == null) {
155       return false;
156     }
157     int position = _contentModel.indexOf(group);
158     if (position >= 0) {
159       String name = group.getName();
160       if (name != null) {
161         String key = "group:" + name;
162         _resolver.removeResolvable(key);
163       }
164       _contentModel.removeElementAt(position);
165       return true;
166     }
167     return false;
168   }
169 
170   /**
171    * {@inheritDoc}
172    * 
173    * @see org.exolab.castor.xml.schema.ContentModelGroup#addGroup(org.exolab.castor.xml.schema.ModelGroup)
174    */
175   public void addGroup(final ModelGroup group) throws SchemaException {
176     if (group == null) {
177       return;
178     }
179 
180     String name = group.getName();
181     if ((name != null) && (!group.isReference())) {
182       String key = "group:" + name;
183       // -- check for naming collisions
184       if (_resolver.resolve(key) != null) {
185         String err = "An element declaration with the given name, ";
186         err += name + ", already exists in this scope.";
187         throw new SchemaException(err);
188       }
189 
190       _resolver.addResolvable(key, group);
191     }
192 
193     // -- add to content model
194     _contentModel.add(group);
195   }
196 
197   /**
198    * {@inheritDoc}
199    * 
200    * @see org.exolab.castor.xml.schema.ContentModelGroup#removeGroup(org.exolab.castor.xml.schema.ModelGroup)
201    */
202   public boolean removeGroup(final ModelGroup group) {
203     if (group == null) {
204       return false;
205     }
206     int position = _contentModel.indexOf(group);
207     if (position >= 0) {
208       String name = group.getName();
209       if ((name != null) && (!group.isReference())) {
210         String key = "group:" + name;
211         _resolver.removeResolvable(key);
212       }
213       _contentModel.removeElementAt(position);
214       return true;
215     }
216     return false;
217   }
218 
219   /**
220    * {@inheritDoc}
221    * 
222    * @see org.exolab.castor.xml.schema.ContentModelGroup#removeWildcard(org.exolab.castor.xml.schema.Wildcard)
223    */
224   public boolean removeWildcard(final Wildcard wildcard) {
225     if (wildcard == null) {
226       return false;
227     }
228     int position = _contentModel.indexOf(wildcard);
229     if (position >= 0) {
230       _contentModel.removeElementAt(position);
231       return true;
232     }
233     return false;
234   }
235 
236   /**
237    * {@inheritDoc}
238    * 
239    * @see org.exolab.castor.xml.schema.ContentModelGroup#enumerate()
240    */
241   public Enumeration<Particle> enumerate() {
242     return _contentModel.elements();
243   }
244 
245   /**
246    * {@inheritDoc}
247    * 
248    * @see org.exolab.castor.xml.schema.ContentModelGroup#getElementDecl(java.lang.String)
249    */
250   public ElementDecl getElementDecl(final String name) {
251     if (name == null) {
252       return null;
253     }
254     ElementDecl result = null;
255     if (_resolver != null) {
256       String key = "element:" + name;
257       result = (ElementDecl) _resolver.resolve(key);
258       // resolver is always not null (initialized in the constructor)
259       // but it may not contain the element (in case of a complexType)
260       if (result != null) {
261         return result;
262       }
263     }
264     for (Particle particle : _contentModel) {
265       switch (particle.getStructureType()) {
266         case Structure.ELEMENT:
267           ElementDecl e = (ElementDecl) particle;
268           if (name.equals(e.getName())) {
269             result = e;
270           }
271           break;
272         case Structure.GROUP:
273         case Structure.MODELGROUP:
274           result = ((ContentModelGroup) particle).getElementDecl(name);
275           break;
276         default:
277           break;
278       }
279       if (result != null) {
280         break;
281       }
282     }
283     return result;
284   }
285 
286   /**
287    * {@inheritDoc}
288    * 
289    * @see org.exolab.castor.xml.schema.ContentModelGroup#getMaxOccurs()
290    */
291   public int getMaxOccurs() {
292     return 1;
293   }
294 
295   /**
296    * {@inheritDoc}
297    * 
298    * @see org.exolab.castor.xml.schema.ContentModelGroup#getMinOccurs()
299    */
300   public int getMinOccurs() {
301     return 1;
302   }
303 
304   /**
305    * {@inheritDoc}
306    * 
307    * @see org.exolab.castor.xml.schema.ContentModelGroup#getParticle(int)
308    */
309   public Particle getParticle(final int index) {
310     return _contentModel.elementAt(index);
311   }
312 
313   /**
314    * {@inheritDoc}
315    * 
316    * @see org.exolab.castor.xml.schema.ContentModelGroup#getParticleCount()
317    */
318   public int getParticleCount() {
319     return _contentModel.size();
320   }
321 
322 }