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.Schema;
44  import org.exolab.castor.xml.schema.SchemaContext;
45  import org.exolab.castor.xml.schema.SchemaNames;
46  import org.exolab.castor.xml.schema.SimpleType;
47  
48  /**
49   * A class for Unmarshalling SimpleTypes
50   * 
51   * @author <a href="mailto:kvisco@intalio.com">Keith Visco</a>
52   * @version $Revision$ $Date: 2006-04-14 04:14:43 -0600 (Fri, 14 Apr 2006) $
53   **/
54  public class SimpleTypeUnmarshaller extends ComponentReader {
55  
56  
57    // --------------------/
58    // - Member Variables -/
59    // --------------------/
60  
61    /**
62     * The current ComponentReader
63     **/
64    private ComponentReader unmarshaller;
65  
66    /**
67     * The current branch depth
68     **/
69    private int depth = 0;
70  
71    /**
72     * The SimpleTypeDefinition we are unmarshalling
73     **/
74    private SimpleTypeDefinition _simpleTypeDef = null;
75  
76    /**
77     * A reference to the SimpleType we are unmarshalling
78     **/
79    private SimpleType _simpleType = null;
80  
81  
82    private boolean foundAnnotation = false;
83    private boolean foundList = false;
84    private boolean foundRestriction = false;
85    private boolean foundUnion = false;
86  
87    // ----------------/
88    // - Constructors -/
89    // ----------------/
90  
91    /**
92     * Creates a new SimpleTypeUnmarshaller.
93     * 
94     * @param schemaContext the {@link SchemaContext} to get some configuration settings from
95     * @param schema the Schema to which the SimpleType belongs
96     * @param atts the AttributeList
97     **/
98    public SimpleTypeUnmarshaller(final SchemaContext schemaContext, final Schema schema,
99        final AttributeSet atts) throws XMLException {
100     super(schemaContext);
101 
102     String name = atts.getValue(SchemaNames.NAME_ATTR);
103 
104     // -- strip off prefix if necessary
105     if (name != null) {
106       int idx = name.indexOf(':');
107       if (idx >= 0) {
108         String prefix = name.substring(0, idx);
109         String ns = schema.getNamespace(prefix);
110         if (ns == null) {
111           // -- should report an error here
112         } else {
113           if (ns.equals(schema.getTargetNamespace())) {
114             name = name.substring(idx + 1);
115           } else {
116             // -- should report an error here
117           }
118         }
119       }
120     }
121 
122     String id = atts.getValue(SchemaNames.ID_ATTR);
123     _simpleTypeDef = new SimpleTypeDefinition(schema, name, id);
124 
125     // -- @final
126     _simpleTypeDef.setFinal(atts.getValue(SchemaNames.FINAL_ATTR));
127 
128 
129   } // -- SimpleTypeUnmarshaller
130 
131   // -----------/
132   // - Methods -/
133   // -----------/
134 
135   /**
136    * Returns the name of the element that this ComponentReader handles
137    * 
138    * @return the name of the element that this ComponentReader handles
139    **/
140   public String elementName() {
141     return SchemaNames.SIMPLE_TYPE;
142   } // -- elementName
143 
144   /**
145    * Returns the SimpleType created
146    * 
147    * @return the SimpleType created
148    **/
149   public SimpleType getSimpleType() {
150     if (_simpleType == null) {
151       _simpleType = _simpleTypeDef.createSimpleType();
152     }
153     return _simpleType;
154   } // -- getSimpletype
155 
156   /**
157    * Returns the Object created by this ComponentReader
158    * 
159    * @return the Object created by this ComponentReader
160    **/
161   public Object getObject() {
162     return getSimpleType();
163   } // -- getObject
164 
165   public void finish() throws XMLException {
166     if (!(foundList || foundUnion || foundRestriction))
167       error("Invalid 'simpleType'; missing 'restriction' " + "| 'union' | 'list'.");
168 
169   } // -- finish
170 
171   /**
172    * Signals the start of an element with the given name.
173    *
174    * @param name the NCName of the element. It is an error if the name is a QName (ie. contains a
175    *        prefix).
176    * @param namespace the namespace of the element. This may be null. Note: A null namespace is not
177    *        the same as the default namespace unless the default namespace is also null.
178    * @param atts the AttributeSet containing the attributes associated with the element.
179    * @param nsDecls the namespace declarations being declared for this element. This may be null.
180    **/
181   public void startElement(String name, String namespace, AttributeSet atts, Namespaces nsDecls)
182       throws XMLException {
183     // -- Do delagation if necessary
184     if (unmarshaller != null) {
185       unmarshaller.startElement(name, namespace, atts, nsDecls);
186       ++depth;
187       return;
188     }
189 
190     if (SchemaNames.ANNOTATION.equals(name)) {
191 
192       if (foundAnnotation)
193         error("Only one (1) annotation may appear as a child of " + "'simpleType'.");
194 
195       if (foundList || foundUnion || foundRestriction)
196         error("An annotation may only appear as the first child " + "of 'simpleType'.");
197 
198       foundAnnotation = true;
199       unmarshaller = new AnnotationUnmarshaller(getSchemaContext(), atts);
200     } else if (SchemaNames.RESTRICTION.equals(name)) {
201 
202       if (foundList)
203         error("A 'simpleType' cannot have both a 'list' and a "
204             + "'restriction' in the same definition.");
205 
206       if (foundUnion)
207         error("A 'simpleType' cannot have both a 'union' and a "
208             + "'restriction' in the same definition.");
209 
210 
211       foundRestriction = true;
212 
213       unmarshaller =
214           new SimpleTypeRestrictionUnmarshaller(getSchemaContext(), _simpleTypeDef, atts);
215     } else if (SchemaNames.LIST.equals(name)) {
216       foundList = true;
217       Schema schema = _simpleTypeDef.getSchema();
218       unmarshaller = new SimpleTypeListUnmarshaller(getSchemaContext(), schema, atts);
219     } else if (SchemaNames.UNION.equals(name)) {
220       foundUnion = true;
221       Schema schema = _simpleTypeDef.getSchema();
222       unmarshaller = new UnionUnmarshaller(getSchemaContext(), schema, atts);
223     } else
224       illegalElement(name);
225 
226   } // -- startElement
227 
228   /**
229    * Signals to end of the element with the given name.
230    *
231    * @param name the NCName of the element. It is an error if the name is a QName (ie. contains a
232    *        prefix).
233    * @param namespace the namespace of the element.
234    **/
235   public void endElement(String name, String namespace) throws XMLException {
236 
237     // -- Do delagation if necessary
238     if ((unmarshaller != null) && (depth > 0)) {
239       unmarshaller.endElement(name, namespace);
240       --depth;
241       return;
242     }
243 
244     // -- have unmarshaller perform any necessary clean up
245     unmarshaller.finish();
246 
247     if (SchemaNames.ANNOTATION.equals(name)) {
248       Annotation annotation = (Annotation) unmarshaller.getObject();
249       _simpleTypeDef.setAnnotation(annotation);
250     } else if (SchemaNames.LIST.equals(name)) {
251       _simpleType = (SimpleType) unmarshaller.getObject();
252       _simpleTypeDef.copyInto(_simpleType);
253 
254     } else if (SchemaNames.UNION.equals(name)) {
255       _simpleType = (SimpleType) unmarshaller.getObject();
256       _simpleTypeDef.copyInto(_simpleType);
257 
258     }
259 
260     unmarshaller = null;
261   } // -- endElement
262 
263   public void characters(char[] ch, int start, int length) throws XMLException {
264     // -- Do delagation if necessary
265     if (unmarshaller != null) {
266       unmarshaller.characters(ch, start, length);
267     }
268   } // -- characters
269 
270 } // -- SimpleTypeUnmarshaller