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