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-2002 (C) Intalio Inc. All Rights Reserved.
42   *
43   * $Id$
44   */
45  
46  package org.exolab.castor.xml.schema.reader;
47  
48  import org.exolab.castor.xml.AttributeSet;
49  import org.exolab.castor.xml.Namespaces;
50  import org.exolab.castor.xml.XMLException;
51  import org.exolab.castor.xml.schema.Annotation;
52  import org.exolab.castor.xml.schema.AttributeDecl;
53  import org.exolab.castor.xml.schema.AttributeGroup;
54  import org.exolab.castor.xml.schema.AttributeGroupDecl;
55  import org.exolab.castor.xml.schema.AttributeGroupReference;
56  import org.exolab.castor.xml.schema.SchemaContext;
57  import org.exolab.castor.xml.schema.Schema;
58  import org.exolab.castor.xml.schema.SchemaException;
59  import org.exolab.castor.xml.schema.SchemaNames;
60  import org.exolab.castor.xml.schema.Wildcard;
61  
62  /**
63   * A class for Unmarshalling AttributeGroups
64   * @author <a href="mailto:kvisco@intalio.com">Keith Visco</a>
65   * @version $Revision$ $Date: 2005-12-13 14:58:48 -0700 (Tue, 13 Dec 2005) $
66  **/
67  public class AttributeGroupUnmarshaller extends ComponentReader {
68  
69  
70        //--------------------/
71       //- Member Variables -/
72      //--------------------/
73  
74      /**
75       * The current ComponentReader
76      **/
77      private ComponentReader unmarshaller;
78  
79      /**
80       * The current branch depth
81      **/
82      private int depth = 0;
83  
84      /**
85       * The AttributeGroup we are constructing
86      **/
87      private AttributeGroup _attributeGroup = null;
88  
89      private boolean allowAnnotation   = true;
90      private boolean foundAnyAttribute = false;
91      private boolean isRef             = false;
92  
93      private Schema _schema = null;
94  
95        //----------------/
96       //- Constructors -/
97      //----------------/
98  
99      /**
100      * Creates a new AttributeGroupUnmarshaller.
101      * @param schemaContext the schema context to get some configuration settings from
102      * @param schema the Schema to which the AttributeGroup belongs
103      * @param atts the AttributeList
104     **/
105     public AttributeGroupUnmarshaller(
106             final SchemaContext schemaContext, 
107             final Schema schema, 
108             final AttributeSet atts) 
109     throws XMLException {
110         super(schemaContext);
111         this._schema = schema;
112 
113 
114         String ref = atts.getValue(SchemaNames.REF_ATTR);
115         if (ref != null) {
116             if (ref.length() > 0) {
117                 isRef = true;
118                 _attributeGroup = new AttributeGroupReference(schema, ref);
119             }
120             else {
121                 String err = "The value of the '" + SchemaNames.REF_ATTR +
122                     "' attribute for attribute group must contain a " +
123                     "valid value.";
124                 throw new SchemaException(err);
125             }
126         }
127         else {
128             AttributeGroupDecl attDecl = new AttributeGroupDecl(schema);
129             _attributeGroup = attDecl;
130 
131             //-- handle attributes
132             attDecl.setName(atts.getValue(SchemaNames.NAME_ATTR));
133             attDecl.setId(atts.getValue(SchemaNames.ID_ATTR));
134         }
135 
136 
137 
138     } //-- AttributeGroupUnmarshaller
139 
140       //-----------/
141      //- Methods -/
142     //-----------/
143 
144     /**
145      * Returns the name of the element that this ComponentReader
146      * handles
147      * @return the name of the element that this ComponentReader
148      * handles
149     **/
150     public String elementName() {
151         return SchemaNames.ATTRIBUTE_GROUP;
152     } //-- elementName
153 
154     /**
155      * Returns the AttributeGroup created by this
156      * AttributeGroupUnmarshaller
157      *
158      * @return the AttributeGroup created by this
159      * AttributeGroupUnmarshaller
160     **/
161     public AttributeGroup getAttributeGroup() {
162         return _attributeGroup;
163     } //-- getAttributeGroup
164 
165     /**
166      * Returns the Object created by this ComponentReader
167      * @return the Object created by this ComponentReader
168     **/
169     public Object getObject() {
170         return getAttributeGroup();
171     } //-- getObject
172 
173     /**
174      * Signals the start of an element with the given name.
175      *
176      * @param name the NCName of the element. It is an error
177      * if the name is a QName (ie. contains a prefix).
178      * @param namespace the namespace of the element. This may be null.
179      * Note: A null namespace is not the same as the default namespace unless
180      * the default namespace is also null.
181      * @param atts the AttributeSet containing the attributes associated
182      * with the element.
183      * @param nsDecls the namespace declarations being declared for this 
184      * element. This may be null.
185     **/
186     public void startElement(String name, String namespace, AttributeSet atts,
187         Namespaces nsDecls)
188         throws XMLException
189     {
190         //-- Do delagation if necessary
191         if (unmarshaller != null) {
192             unmarshaller.startElement(name, namespace, atts, nsDecls);
193             ++depth;
194             return;
195         }
196 
197         //-- <anyAttribute>
198         if (SchemaNames.ANY_ATTRIBUTE.equals(name)) {
199             if (foundAnyAttribute)
200                 error("an anyAttribute element can appear only once as a child "+
201                     "of an 'AttributeGroup'.");
202             foundAnyAttribute = true;
203             allowAnnotation = true;
204             unmarshaller
205                  = new WildcardUnmarshaller(getSchemaContext(), _attributeGroup, _schema, name, atts);
206         }
207         //-- attribute declarations
208         else if (SchemaNames.ATTRIBUTE.equals(name)) {
209             allowAnnotation = false;
210 
211             if (isRef)
212                 error("AttributeGroup references may not have children.");
213 
214             unmarshaller
215                 = new AttributeUnmarshaller(getSchemaContext(), _schema, atts);
216         }
217         //-- element declarations
218         else if (SchemaNames.ATTRIBUTE_GROUP.equals(name)) {
219             allowAnnotation = false;
220             if (isRef)
221                 error("AttributeGroup references may not have children.");
222             unmarshaller
223                 = new AttributeGroupUnmarshaller(getSchemaContext(), _schema, atts);
224         }
225         else if (name.equals(SchemaNames.ANNOTATION)) {
226             if (!allowAnnotation) outOfOrder(name);
227             unmarshaller = new AnnotationUnmarshaller(getSchemaContext(), atts);
228         }
229         else illegalElement(name);
230 
231     } //-- startElement
232 
233     /**
234      * Signals to end of the element with the given name.
235      *
236      * @param name the NCName of the element. It is an error
237      * if the name is a QName (ie. contains a prefix).
238      * @param namespace the namespace of the element.
239     **/
240     public void endElement(String name, String namespace)
241         throws XMLException
242     {
243 
244         //-- Do delagation if necessary
245         if ((unmarshaller != null) && (depth > 0)) {
246             unmarshaller.endElement(name, namespace);
247             --depth;
248             return;
249         }
250 
251         //-- have unmarshaller perform any necessary clean up
252         unmarshaller.finish();
253 
254          //-- <anyAttribute>
255         if (SchemaNames.ANY_ATTRIBUTE.equals(name)) {
256            Wildcard wildcard =
257                  ((WildcardUnmarshaller)unmarshaller).getWildcard();
258             try {
259                 ((AttributeGroupDecl)_attributeGroup).setAnyAttribute(wildcard);
260             } catch (SchemaException e) {
261                 throw new IllegalArgumentException(e.getMessage());
262             }
263         }
264 
265 
266         //-- attribute declarations
267         else if (SchemaNames.ATTRIBUTE.equals(name)) {
268             AttributeDecl attrDecl =
269                 ((AttributeUnmarshaller)unmarshaller).getAttribute();
270 
271             ((AttributeGroupDecl)_attributeGroup).addAttribute(attrDecl);
272         }
273         //-- attribute group references
274         else if (SchemaNames.ATTRIBUTE_GROUP.equals(name)) {
275 
276             Object obj = unmarshaller.getObject();
277 
278             try {
279                 ((AttributeGroupDecl)_attributeGroup).addReference(
280                     (AttributeGroupReference) obj);
281             }
282             catch (ClassCastException ex) {
283                 String err = "AttributeGroups cannot contain new " +
284                     "AttributeGroup definitions, only references to " +
285                     "top-level AttributeGroups are allowed.";
286                 error(err);
287             }
288         }
289         //-- annotation
290         else if (SchemaNames.ANNOTATION.equals(name)) {
291             Annotation ann = ((AnnotationUnmarshaller)unmarshaller).getAnnotation();
292             _attributeGroup.addAnnotation(ann);
293         }
294 
295         unmarshaller = null;
296     } //-- endElement
297 
298     public void characters(char[] ch, int start, int length)
299         throws XMLException
300     {
301         //-- Do delagation if necessary
302         if (unmarshaller != null) {
303             unmarshaller.characters(ch, start, length);
304         }
305     } //-- characters
306 
307 } //-- AttributeGroupUnmarshaller