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-2002 (C) Intalio, Inc. All Rights Reserved.
32   *
33   * $Id$
34   */
35  
36  package org.exolab.castor.xml.schema.reader;
37  
38  // -- imported classes and packages
39  import org.exolab.castor.xml.AttributeSet;
40  import org.exolab.castor.xml.Namespaces;
41  import org.exolab.castor.xml.XMLException;
42  import org.exolab.castor.xml.schema.Annotation;
43  import org.exolab.castor.xml.schema.Group;
44  import org.exolab.castor.xml.schema.ModelGroup;
45  import org.exolab.castor.xml.schema.Schema;
46  import org.exolab.castor.xml.schema.SchemaContext;
47  import org.exolab.castor.xml.schema.SchemaException;
48  import org.exolab.castor.xml.schema.SchemaNames;
49  
50  /**
51   * A class for Unmarshalling ModelGroups Definition
52   * 
53   * @author <a href="mailto:kvisco@intalio.com">Keith Visco</a>
54   * @version $Revisio:$ $Date: 2005-12-13 14:58:48 -0700 (Tue, 13 Dec 2005) $
55   **/
56  public class ModelGroupUnmarshaller extends ComponentReader {
57  
58    // --------------------------/
59    // - Static Class Variables -/
60    // --------------------------/
61  
62    /**
63     * The value of the maximum occurance wild card
64     */
65    private static final String MAX_OCCURS_WILDCARD = "unbounded";
66  
67    // --------------------/
68    // - Member Variables -/
69    // --------------------/
70  
71    /**
72     * The current ComponentReader
73     **/
74    private ComponentReader unmarshaller;
75  
76    /**
77     * The current branch depth
78     **/
79    private int depth = 0;
80  
81    /**
82     * The ModelGroup reference for the ModelGroup we are constructing
83     **/
84    private ModelGroup _group = null;
85  
86    /**
87     * The Schema being "unmarshalled"
88     **/
89    private Schema _schema = null;
90  
91    /**
92     * Flag to indicate if we have already encounter an {@literal <annotation>}
93     */
94    private boolean foundAnnotation = false;
95    // ----------------/
96    // - Constructors -/
97    // ----------------/
98  
99    /**
100    * Creates a new ModelGroupUnmarshaller.
101    * 
102    * @param schemaContext the {@link SchemaContext} to get some configuration settings from
103    * @param schema the Schema to which the ModelGroup belongs
104    * @param atts the AttributeList
105    **/
106   public ModelGroupUnmarshaller(final SchemaContext schemaContext, final Schema schema,
107       final AttributeSet atts) {
108     super(schemaContext);
109 
110     this._schema = schema;
111 
112     _group = new ModelGroup(_schema);
113 
114     // -- handle attributes
115     String attValue = null;
116 
117 
118     // -- set name
119     _group.setName(atts.getValue("name"));
120 
121     /*
122      * @maxOccurs If maxOccurs is present, the value is either unbounded or the int value of the
123      * attribute, otherwise maxOccurs equals the minOccurs value.
124      */
125     attValue = atts.getValue(SchemaNames.MAX_OCCURS_ATTR);
126     if (attValue != null) {
127       if (_group.getName() != null)
128         throw new IllegalArgumentException(
129             "In <group>: " + _group.getName() + "'maxOccurs' cannot appear in a named <group>");
130       if (MAX_OCCURS_WILDCARD.equals(attValue))
131         attValue = "-1";
132       int maxOccurs = toInt(attValue);
133       _group.setMaxOccurs(maxOccurs);
134     }
135     // -- minOccurs
136     attValue = atts.getValue("minOccurs");
137     if (attValue != null) {
138       if (_group.getName() != null)
139         throw new IllegalArgumentException(
140             "In <group>: " + _group.getName() + ", 'minOccurs' cannot appear in a named <group>");
141       _group.setMinOccurs(toInt(attValue));
142     }
143 
144     // -- @ref
145     attValue = atts.getValue("ref");
146     if (attValue != null) {
147       if (_group.getName() != null)
148         throw new IllegalArgumentException(
149             "In <group>: " + _group.getName() + ", 'ref' cannot appear in a named <group>");
150       // String name = attValue;
151       // int idx = name.indexOf(':');
152       // String ns = null;
153       // if (idx >= 0) {
154       // String nsPrefix = name.substring(0,idx);
155       // name = name.substring(idx + 1);
156       // ns = (String) schema.getNamespace(nsPrefix);
157       // if (ns == null) {
158       // String err = "in the <group> referring: "+attValue;
159       // err += " The Namespace prefix is not recognized '"+nsPrefix+"'";
160       // throw new IllegalArgumentException(err);
161       // }
162       // }
163       //
164       // if (ns != null) {
165       // Schema tempSchema = schema.getImportedSchema(ns);
166       // if (tempSchema!=null) {
167       // _group.setSchema(tempSchema);
168       // }
169       // tempSchema = null;
170       // }
171 
172       _group.setReference(attValue);
173     }
174     // -- id
175     attValue = atts.getValue("id");
176     _group.setId(attValue);
177     // -- not yet supported
178 
179 
180   } // -- ModelGroupUnmarshaller
181 
182   // -----------/
183   // - Methods -/
184   // -----------/
185 
186 
187 
188   /**
189    * Returns the Group that was unmarshalled by this Unmarshaller. This method should only be called
190    * after unmarshalling has been completed.
191    *
192    * @return the unmarshalled Group
193    **/
194   public ModelGroup getGroup() {
195     return _group;
196   } // -- getGroup
197 
198   /**
199    * Returns the Object created by this ComponentReader
200    * 
201    * @return the Object created by this ComponentReader
202    **/
203   public Object getObject() {
204     return getGroup();
205   } // -- getObject
206 
207   /**
208    * Sets the name of the element that this UnknownUnmarshaller handles
209    **/
210   public String elementName() {
211     return SchemaNames.GROUP;
212   } // -- elementName
213 
214   /**
215    * Signals the start of an element with the given name.
216    *
217    * @param name the NCName of the element. It is an error if the name is a QName (ie. contains a
218    *        prefix).
219    * @param namespace the namespace of the element. This may be null. Note: A null namespace is not
220    *        the same as the default namespace unless the default namespace is also null.
221    * @param atts the AttributeSet containing the attributes associated with the element.
222    * @param nsDecls the namespace declarations being declared for this element. This may be null.
223    **/
224   public void startElement(String name, String namespace, AttributeSet atts, Namespaces nsDecls)
225       throws XMLException {
226     // -- Do delagation if necessary
227     if (unmarshaller != null) {
228       unmarshaller.startElement(name, namespace, atts, nsDecls);
229       ++depth;
230       return;
231     }
232 
233     if (SchemaNames.ANNOTATION.equals(name)) {
234       if (foundAnnotation)
235         error("Only one (1) 'annotation' is allowed as a child of " + "element definitions.");
236 
237       foundAnnotation = true;
238       unmarshaller = new AnnotationUnmarshaller(getSchemaContext(), atts);
239     }
240 
241     else if (SchemaNames.isGroupName(name)) {
242       unmarshaller = new GroupUnmarshaller(getSchemaContext(), _schema, name, atts);
243     } else {
244       StringBuffer err = new StringBuffer("illegal element <");
245       err.append(name);
246       err.append("> found in <group>.");
247       throw new SchemaException(err.toString());
248     }
249 
250   } // -- startElement
251 
252   /**
253    * Signals to end of the element with the given name.
254    *
255    * @param name the NCName of the element. It is an error if the name is a QName (ie. contains a
256    *        prefix).
257    * @param namespace the namespace of the element.
258    **/
259   public void endElement(String name, String namespace) throws XMLException {
260 
261     // -- Do delagation if necessary
262     if ((unmarshaller != null) && (depth > 0)) {
263       unmarshaller.endElement(name, namespace);
264       --depth;
265       return;
266     }
267 
268     // -- check for name mismatches
269     if (unmarshaller != null) {
270       if (!name.equals(unmarshaller.elementName())) {
271         String err = "missing end element for ";
272         err += unmarshaller.elementName();
273         throw new SchemaException(err);
274       }
275     }
276 
277     if (SchemaNames.ANNOTATION.equals(name)) {
278       Annotation ann = (Annotation) unmarshaller.getObject();
279       _group.addAnnotation(ann);
280     }
281 
282     else if (SchemaNames.isGroupName(name)) {
283       Group group = ((GroupUnmarshaller) unmarshaller).getGroup();
284       _group.addGroup(group);
285     }
286 
287     // -- have unmarshaller perform any necessary clean up
288     unmarshaller.finish();
289     unmarshaller = null;
290   } // -- endElement
291 
292   public void characters(char[] ch, int start, int length) throws XMLException {
293     // -- Do delagation if necessary
294     if (unmarshaller != null) {
295       unmarshaller.characters(ch, start, length);
296     }
297   } // -- characters
298 
299 } // -- ModelGroupUnmarshaller