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 2000-2003 (C) Intalio, Inc. All Rights Reserved.
32   *
33   * $Id$
34   */
35  
36  
37  package org.exolab.castor.xml.schema;
38  
39  import org.exolab.castor.xml.ValidationException;
40  
41  import java.util.Vector;
42  import java.util.Enumeration;
43  
44  /**
45   * An XML Schema Attribute Group Definition
46   * 
47   * @author <a href="mailto:kvisco@intalio.com">Keith Visco</a>
48   * @version $Revision$ $Date: 2006-04-25 15:08:23 -0600 (Tue, 25 Apr 2006) $
49   **/
50  public final class AttributeGroupDecl extends AttributeGroup {
51    /** SerialVersionUID */
52    private static final long serialVersionUID = -5401452412514803353L;
53  
54    /**
55     * Error message for a null argument
56     **/
57    private static String NULL_ARGUMENT =
58        "A null argument was passed to the constructor of " + AttributeDecl.class.getName();
59  
60  
61    /**
62     * The name of this AttributeGroup
63     **/
64    private String _name = null;
65  
66    /**
67     * The Schema to which this AttributeDecl belongs
68     **/
69    private final Schema _schema;
70  
71  
72    /**
73     * The collection of attributes for this AttributeGroup
74     **/
75    private final Vector<AttributeDecl> _attributes = new Vector<>();
76  
77    /**
78     * The collection of AttributesGroupReferences for this AttributeGroup
79     **/
80    private final Vector<AttributeGroupReference> _references = new Vector<>();
81  
82    /**
83     * the anyattribute wilcard, if any
84     */
85    private Wildcard _anyAttribute = null;
86  
87    /**
88     * An attribute that indicates if this AttributeGroupDecl is a redefinition
89     */
90    private boolean _redefinition = false;
91  
92    /**
93     * Creates a new AttributeGroup definition
94     * 
95     * @param schema the Schema that this AttributeGroup belongs to.
96     **/
97    public AttributeGroupDecl(Schema schema) {
98      if (schema == null) {
99        String err = NULL_ARGUMENT + "; 'schema' must not be null.";
100       throw new IllegalArgumentException(err);
101     }
102     _schema = schema;
103   } // -- AttributeGroupDecl
104 
105   /**
106    * Adds the given attribute definition to this AttributeGroup
107    *
108    * @param attrDecl the AttributeDecl to add
109    **/
110   public void addAttribute(AttributeDecl attrDecl) {
111 
112     if (attrDecl == null)
113       return;
114 
115     // -- add validation code
116 
117     // -- add to internal collection
118     _attributes.add(attrDecl);
119     // --set the parent
120     attrDecl.setParent(this);
121 
122   } // -- addAttribute
123 
124   /**
125    * Adds the given AttributeGroupReference to this AttributeGroup
126    *
127    * @param attrGroup the AttributeGroupReference to add
128    **/
129   public void addReference(AttributeGroupReference attrGroup) {
130 
131     if (attrGroup == null)
132       return;
133 
134     // -- add validation code
135 
136     // -- add to internal collection
137     _references.add(attrGroup);
138 
139   } // -- addReference
140 
141 
142   /**
143    * Returns the attributes of THIS attribute group. (not those of the nested groups)
144    */
145   public Enumeration<AttributeDecl> getLocalAttributes() {
146     return _attributes.elements();
147   }
148 
149   /**
150    * Returns the AttributeGroupReference of THIS attribute group. (not those of the nested groups)
151    */
152   public Enumeration<AttributeGroupReference> getLocalAttributeGroupReferences() {
153     return _references.elements();
154   }
155 
156   /**
157    * Returns the wilcard used in this complexType (can be null)
158    * 
159    * @return the wilcard used in this complexType (can be null)
160    */
161   public Wildcard getAnyAttribute() {
162     return _anyAttribute;
163   }
164 
165   /**
166    * Returns the AttributeDecl associated with the given name
167    * 
168    * @return the AttributeDecl associated with the given name, or null if no AttributeDecl with the
169    *         given name was found.
170    **/
171   public AttributeDecl getAttribute(String name) {
172 
173     if (name == null)
174       return null;
175 
176     for (int i = 0; i < _attributes.size(); i++) {
177       AttributeDecl attr = (AttributeDecl) _attributes.elementAt(i);
178       if (name.equals(attr.getName()))
179         return attr;
180     }
181 
182     for (int i = 0; i < _references.size(); i++) {
183       AttributeGroupReference ref = (AttributeGroupReference) _references.elementAt(i);
184 
185       AttributeDecl attr = ref.getAttribute(name);
186       if (attr != null)
187         return attr;
188     }
189 
190     return null;
191   } // -- getAttribute
192 
193   /**
194    * Returns an Enumeration of all the attributes of this attribute group. The enumeration includes
195    * attributes from all AttributeGroupReferences contained in this AttributeGroup.
196    *
197    * @return an Enumeration of all the attributes of this attribute group.
198    **/
199   public Enumeration<AttributeDecl> getAttributes() {
200     return new AttributeGroupEnumeration(_attributes, _references);
201   } // -- getAttributes
202 
203 
204   /**
205    * Returns the name of this AttributeGroup
206    * 
207    * @return the name of this AttributeGroup, or null, if no name was defined.
208    **/
209   public String getName() {
210     return _name;
211   } // -- getName
212 
213   /**
214    * Returns the Schema that this AttributeGroupDecl belongs to.
215    *
216    * @return the Schema that this AttributeGroupDecl belongs to
217    **/
218   public Schema getSchema() {
219     return _schema;
220   } // -- getSchema
221 
222   /**
223    * Returns true if this AttributeGroup does not contain any AttributeDecls or any non-empty
224    * AttributeGroups
225    *
226    * @return true if this AttributeGroup does not contain any AttributeDecls or any non-empty
227    *         AttributeGroups
228    **/
229   public boolean isEmpty() {
230 
231     if (!_attributes.isEmpty())
232       return false;
233 
234     if (_references.isEmpty())
235       return true;
236 
237     for (AttributeGroup attributeGroup : _references) {
238       if (!attributeGroup.isEmpty())
239         return false;
240     }
241     return true;
242 
243   } // -- isEmpty
244 
245   /**
246    * Returns true if this attributeGroupDecl is a redefinition.
247    * 
248    * @return true if this attributeGroupDecl is a redefinition.
249    */
250   public boolean isRedefined() {
251     return _redefinition;
252   }
253 
254   /**
255    * Removes the given AttributeDecl from this AttributeGroup.
256    * 
257    * @param attr the attribute to remove.
258    **/
259   public boolean removeAttribute(AttributeDecl attr) {
260     if (attr == null)
261       return false;
262     return _attributes.remove(attr);
263   } // -- removeAttribute
264 
265   /**
266    * Removes the given AttributeGroupReference from this AttributeGroup.
267    * 
268    * @param attrGroupReference the AttributeGroupReference to remove.
269    **/
270   public boolean removeReference(AttributeGroupReference attrGroupReference) {
271     if (attrGroupReference == null)
272       return false;
273     return _references.remove(attrGroupReference);
274   } // -- removeReference
275 
276   /**
277    * Sets the wildcard (anyAttribute) of this attribute Group
278    * 
279    * @exception SchemaException thrown when a wildcard as already be set or when the wildCard is not
280    *            an {@literal <anyAttribute>}.
281    */
282   public void setAnyAttribute(Wildcard wildcard) throws SchemaException {
283     if (wildcard != null) {
284       if (_anyAttribute != null) {
285         String err = "<anyAttribute> already set in this AttributeGroup: " + this.getName();
286         throw new SchemaException(err);
287       }
288 
289       if (!wildcard.isAttributeWildcard()) {
290         String err =
291             "In AttributeGroup, " + this.getName() + "the wildcard must be an <anyAttribute>";
292         throw new SchemaException(err);
293       }
294     }
295     _anyAttribute = wildcard;
296 
297   }
298 
299   /**
300    * Sets the name of this AttributeGroup
301    * 
302    * @param name the name of this AttributeGroup
303    **/
304   public void setName(String name) {
305 
306     if (name == null)
307       throw new IllegalArgumentException("name must not be null");
308 
309     // -- strip namespace prefix if necessary
310     int idx = name.indexOf(':');
311     if (idx >= 0)
312       this._name = name.substring(idx + 1);
313     else
314       this._name = name;
315 
316   } // -- setName
317 
318 
319   /**
320    * Sets this Group has redefined.
321    */
322   public void setRedefined() {
323     _redefinition = true;
324   }
325   // -------------------------------/
326   // - Implementation of Structure -/
327   // -------------------------------/
328 
329   /**
330    * Returns the type of this Schema Structure
331    * 
332    * @return the type of this Schema Structure
333    **/
334   public short getStructureType() {
335     return Structure.ATTRIBUTE_GROUP;
336   } // -- getStructureType
337 
338   /**
339    * Checks the validity of this Attribute declaration
340    * 
341    * @exception ValidationException when this Attribute declaration is invalid
342    **/
343   public void validate() throws ValidationException {
344     // -- no validation currently needed
345 
346   } // -- validate
347 
348 
349 } // -- AttributeGroup
350 
351 
352 /**
353  * A simple enumerator for the AttributeGroup class
354  **/
355 class AttributeGroupEnumeration implements Enumeration<AttributeDecl> {
356 
357   private Vector<AttributeGroupReference> references = null;
358   int index = 0;
359 
360   private Enumeration<AttributeDecl> enumeration = null;
361 
362 
363   AttributeGroupEnumeration(Vector<AttributeDecl> definitions,
364       Vector<AttributeGroupReference> references) {
365     enumeration = definitions.elements();
366     if (!enumeration.hasMoreElements())
367       enumeration = null;
368     this.references = references;
369   } // -- AttributeGroupEnumeration
370 
371   public boolean hasMoreElements() {
372     if (enumeration != null)
373       return true;
374 
375     int i = index;
376     while (i < references.size()) {
377       AttributeGroupReference ref = references.elementAt(i);
378       ++i;
379       if (!ref.isEmpty())
380         return true;
381     }
382     return false;
383 
384   } // -- hasMoreElements
385 
386   public AttributeDecl nextElement() {
387 
388     if (enumeration != null) {
389       AttributeDecl obj = enumeration.nextElement();
390       if (!enumeration.hasMoreElements())
391         enumeration = null;
392       return obj;
393     }
394 
395     while (index < references.size()) {
396       AttributeGroupReference ref = references.elementAt(index);
397 
398       ++index;
399 
400       enumeration = ref.getAttributes();
401       if (enumeration.hasMoreElements()) {
402         AttributeDecl obj = enumeration.nextElement();
403         if (!enumeration.hasMoreElements())
404           enumeration = null;
405         return obj;
406       }
407     }
408 
409     return null;
410   }
411 } // -- AttributeGroupEnumeration