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.ComplexType;
44  import org.exolab.castor.xml.schema.ContentType;
45  import org.exolab.castor.xml.schema.SchemaContext;
46  import org.exolab.castor.xml.schema.SchemaNames;
47  
48  /**
49   * A class for Unmarshalling simpleContent
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 ComplexContentUnmarshaller extends ComponentReader {
55  
56    // --------------------/
57    // - Member Variables -/
58    // --------------------/
59  
60    /**
61     * The current ComponentReader
62     **/
63    private ComponentReader unmarshaller;
64  
65    /**
66     * The current branch depth
67     **/
68    private int depth = 0;
69  
70    /**
71     * The Attribute reference for the Attribute we are constructing
72     **/
73    private ComplexType _complexType = null;
74  
75    private boolean foundAnnotation = false;
76    private boolean foundExtension = false;
77    private boolean foundRestriction = false;
78  
79    // ----------------/
80    // - Constructors -/
81    // ----------------/
82  
83    /**
84     * Creates a new ComplexContentUnmarshaller.
85     * 
86     * @param schemaContext the schema context to get some configuration settings from
87     * @param complexType the complexType we are unmarshalling
88     * @param atts the AttributeList
89     **/
90    public ComplexContentUnmarshaller(final SchemaContext schemaContext,
91        final ComplexType complexType, final AttributeSet atts) throws XMLException {
92      super(schemaContext);
93  
94      _complexType = complexType;
95  
96      // -- read contentType
97      String content = atts.getValue(SchemaNames.MIXED);
98  
99      if (content != null) {
100       if (content.equals("true")) {
101         _complexType.setContentType(ContentType.valueOf("mixed"));
102       }
103       if (content.equals("false")) {
104         _complexType.setContentType(ContentType.valueOf("elementOnly"));
105       }
106     }
107 
108   } // -- ComplexContentUnmarshaller
109 
110   // -----------/
111   // - Methods -/
112   // -----------/
113 
114   /**
115    * Returns the name of the element that this ComponentReader handles
116    * 
117    * @return the name of the element that this ComponentReader handles
118    **/
119   public String elementName() {
120     return SchemaNames.COMPLEX_CONTENT;
121   } // -- elementName
122 
123   /**
124    * Returns the Object created by this ComponentReader
125    * 
126    * @return the Object created by this ComponentReader
127    **/
128   public Object getObject() {
129     return null;
130   } // -- getObject
131 
132   /**
133    * Signals the start of an element with the given name.
134    *
135    * @param name the NCName of the element. It is an error if the name is a QName (ie. contains a
136    *        prefix).
137    * @param namespace the namespace of the element. This may be null. Note: A null namespace is not
138    *        the same as the default namespace unless the default namespace is also null.
139    * @param atts the AttributeSet containing the attributes associated with the element.
140    * @param nsDecls the namespace declarations being declared for this element. This may be null.
141    **/
142   public void startElement(String name, String namespace, AttributeSet atts, Namespaces nsDecls)
143       throws XMLException {
144     // -- Do delagation if necessary
145     if (unmarshaller != null) {
146       unmarshaller.startElement(name, namespace, atts, nsDecls);
147       ++depth;
148       return;
149     }
150 
151     // -- extension
152     if (SchemaNames.EXTENSION.equals(name)) {
153 
154       if (foundExtension)
155         error("Only (1) 'extension' element may appear as a child "
156             + "of 'complexContent' elements.");
157 
158       if (foundRestriction)
159         error("Both 'extension' and 'restriction' elements may not "
160             + "appear as children of the same complexContent " + "definition.");
161 
162       foundExtension = true;
163 
164       ExtensionUnmarshaller extension =
165           new ExtensionUnmarshaller(getSchemaContext(), _complexType, atts);
166       unmarshaller = extension;
167     }
168     // -- restriction
169     else if (SchemaNames.RESTRICTION.equals(name)) {
170 
171       if (foundRestriction)
172         error("Only (1) 'restriction' element may appear as a child "
173             + "of 'complexContent' elements.");
174 
175       if (foundExtension)
176         error("Both 'extension' and 'restriction' elements may not "
177             + "appear as children of the same complexContent " + "definition.");
178 
179       foundRestriction = true;
180       unmarshaller =
181           new ComplexContentRestrictionUnmarshaller(getSchemaContext(), _complexType, atts);
182     }
183     // -- annotation
184     else if (name.equals(SchemaNames.ANNOTATION)) {
185       if (foundAnnotation)
186         error("Only (1) 'annotation' element may appear as a child "
187             + "of 'complexContent' elements.");
188 
189       if (foundRestriction || foundExtension)
190         error("An 'annotation' may only appear as the first child "
191             + "of a 'complexContent' element.");
192 
193       foundAnnotation = true;
194       unmarshaller = new AnnotationUnmarshaller(getSchemaContext(), atts);
195     } else
196       illegalElement(name);
197 
198   } // -- startElement
199 
200   /**
201    * Signals to end of the element with the given name.
202    *
203    * @param name the NCName of the element. It is an error if the name is a QName (ie. contains a
204    *        prefix).
205    * @param namespace the namespace of the element.
206    **/
207   public void endElement(String name, String namespace) throws XMLException {
208 
209     // -- Do delagation if necessary
210     if ((unmarshaller != null) && (depth > 0)) {
211       unmarshaller.endElement(name, namespace);
212       --depth;
213       return;
214     }
215 
216     // -- have unmarshaller perform any necessary clean up
217     unmarshaller.finish();
218 
219     // -- annotation
220     if (SchemaNames.ANNOTATION.equals(name)) {
221       Annotation ann = ((AnnotationUnmarshaller) unmarshaller).getAnnotation();
222       _complexType.addAnnotation(ann);
223     }
224 
225     unmarshaller = null;
226   } // -- endElement
227 
228   public void characters(char[] ch, int start, int length) throws XMLException {
229     // -- Do delagation if necessary
230     if (unmarshaller != null) {
231       unmarshaller.characters(ch, start, length);
232     }
233   } // -- characters
234 
235 } // -- ComplexContentUnmarshaller