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