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