001: /**
002: * Redistribution and use of this software and associated documentation
003: * ("Software"), with or without modification, are permitted provided
004: * that the following conditions are met:
005: *
006: * 1. Redistributions of source code must retain copyright
007: * statements and notices. Redistributions must also contain a
008: * copy of this document.
009: *
010: * 2. Redistributions in binary form must reproduce the
011: * above copyright notice, this list of conditions and the
012: * following disclaimer in the documentation and/or other
013: * materials provided with the distribution.
014: *
015: * 3. The name "Exolab" must not be used to endorse or promote
016: * products derived from this Software without prior written
017: * permission of Intalio, Inc. For written permission,
018: * please contact info@exolab.org.
019: *
020: * 4. Products derived from this Software may not be called "Exolab"
021: * nor may "Exolab" appear in their names without prior written
022: * permission of Intalio, Inc. Exolab is a registered
023: * trademark of Intalio, Inc.
024: *
025: * 5. Due credit should be given to the Exolab Project
026: * (http://www.exolab.org/).
027: *
028: * THIS SOFTWARE IS PROVIDED BY INTALIO, INC. AND CONTRIBUTORS
029: * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
030: * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
031: * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
032: * INTALIO, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
033: * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
034: * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
035: * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
036: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
037: * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
038: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
039: * OF THE POSSIBILITY OF SUCH DAMAGE.
040: *
041: * Copyright 2000-2002 (C) Intalio Inc. All Rights Reserved.
042: *
043: * $Id: ExtensionUnmarshaller.java 5951 2006-05-30 22:18:48Z bsnyder $
044: */package org.exolab.castor.xml.schema.reader;
045:
046: //-- imported classes and packages
047: import org.exolab.castor.xml.AttributeSet;
048: import org.exolab.castor.xml.Namespaces;
049: import org.exolab.castor.xml.XMLException;
050: import org.exolab.castor.xml.schema.Annotation;
051: import org.exolab.castor.xml.schema.AttributeDecl;
052: import org.exolab.castor.xml.schema.AttributeGroupReference;
053: import org.exolab.castor.xml.schema.ComplexType;
054: import org.exolab.castor.xml.schema.Group;
055: import org.exolab.castor.xml.schema.ModelGroup;
056: import org.exolab.castor.xml.schema.Resolver;
057: import org.exolab.castor.xml.schema.Schema;
058: import org.exolab.castor.xml.schema.SchemaException;
059: import org.exolab.castor.xml.schema.SchemaNames;
060: import org.exolab.castor.xml.schema.SimpleContent;
061: import org.exolab.castor.xml.schema.SimpleType;
062: import org.exolab.castor.xml.schema.Wildcard;
063: import org.exolab.castor.xml.schema.XMLType;
064:
065: /**
066: * A class for Unmarshalling extension elements
067: * @author <a href="mailto:kvisco@intalio.com">Keith Visco</a>
068: * @version $Revision: 5951 $ $Date: 2005-12-13 14:58:48 -0700 (Tue, 13 Dec 2005) $
069: **/
070: public class ExtensionUnmarshaller extends ComponentReader {
071:
072: //--------------------/
073: //- Member Variables -/
074: //--------------------/
075:
076: /**
077: * The current ComponentReader
078: **/
079: private ComponentReader unmarshaller;
080:
081: /**
082: * The current branch depth
083: **/
084: private int depth = 0;
085:
086: /**
087: * The Attribute reference for the Attribute we are constructing
088: **/
089: private ComplexType _complexType = null;
090: private Schema _schema = null;
091:
092: private boolean foundAnnotation = false;
093: private boolean foundAttributes = false;
094: private boolean foundModelGroup = false;
095:
096: //----------------/
097: //- Constructors -/
098: //----------------/
099:
100: /**
101: * Creates a new ExtensionUnmarshaller
102: * @param complexType the ComplexType being unmarshalled
103: * @param atts the AttributeList
104: * @param resolver the resolver being used for reference resolving
105: **/
106: public ExtensionUnmarshaller(ComplexType complexType,
107: AttributeSet atts, Resolver resolver) throws XMLException {
108: super ();
109:
110: setResolver(resolver);
111:
112: _complexType = complexType;
113: _schema = complexType.getSchema();
114:
115: _complexType.setDerivationMethod(SchemaNames.EXTENSION);
116:
117: //-- base
118: String base = atts.getValue(SchemaNames.BASE_ATTR);
119: if ((base != null) && (base.length() > 0)) {
120:
121: XMLType baseType = _schema.getType(base);
122: if (baseType == null) {
123: _complexType.setBase(base); //the base type has not been read
124: if (_complexType.isSimpleContent()) {
125: _complexType.setContentType(new SimpleContent(
126: _schema, base));
127: }
128: } else {
129: //--we cannot extend a simpleType in <complexContent>
130: if ((baseType.isSimpleType())
131: && (_complexType.isComplexContent())) {
132: String err = "In a 'complexContent', the base attribute "
133: + "must be a complexType but "
134: + base
135: + " is a simpleType.\n";
136: error(err);
137: }
138: _complexType.setBase(base);
139: _complexType.setBaseType(baseType);
140: if (_complexType.isSimpleContent()) {
141: //--set the content type
142: if (baseType.isSimpleType()) {
143: SimpleType simpleType = (SimpleType) baseType;
144: _complexType.setContentType(new SimpleContent(
145: simpleType));
146: } else {
147: ComplexType temp = (ComplexType) baseType;
148: SimpleContent simpleContent = (SimpleContent) temp
149: .getContentType();
150: _complexType.setContentType(simpleContent
151: .copy());
152: }
153: }
154:
155: }
156:
157: }
158:
159: } //-- ExtensionUnmarshaller
160:
161: //-----------/
162: //- Methods -/
163: //-----------/
164:
165: /**
166: * Returns the name of the element that this ComponentReader
167: * handles
168: * @return the name of the element that this ComponentReader
169: * handles
170: **/
171: public String elementName() {
172: return SchemaNames.EXTENSION;
173: } //-- elementName
174:
175: /**
176: * Returns the Object created by this ComponentReader
177: * @return the Object created by this ComponentReader
178: **/
179: public Object getObject() {
180: return null;
181: } //-- getObject
182:
183: /**
184: * Signals the start of an element with the given name.
185: *
186: * @param name the NCName of the element. It is an error
187: * if the name is a QName (ie. contains a prefix).
188: * @param namespace the namespace of the element. This may be null.
189: * Note: A null namespace is not the same as the default namespace unless
190: * the default namespace is also null.
191: * @param atts the AttributeSet containing the attributes associated
192: * with the element.
193: * @param nsDecls the namespace declarations being declared for this
194: * element. This may be null.
195: **/
196: public void startElement(String name, String namespace,
197: AttributeSet atts, Namespaces nsDecls) throws XMLException {
198: //-- Do delagation if necessary
199: if (unmarshaller != null) {
200: unmarshaller.startElement(name, namespace, atts, nsDecls);
201: ++depth;
202: return;
203: }
204:
205: //-- <anyAttribute>
206: if (SchemaNames.ANY_ATTRIBUTE.equals(name)) {
207: unmarshaller = new WildcardUnmarshaller(_complexType,
208: _schema, name, atts, getResolver());
209: }
210:
211: //-- attribute declarations
212: else if (SchemaNames.ATTRIBUTE.equals(name)) {
213: foundAttributes = true;
214: unmarshaller = new AttributeUnmarshaller(_schema, atts,
215: getResolver());
216: }
217: //-- attribute group declarations
218: else if (SchemaNames.ATTRIBUTE_GROUP.equals(name)) {
219:
220: //-- make sure we have an attribute group
221: //-- reference and not a definition
222:
223: if (atts.getValue(SchemaNames.REF_ATTR) == null) {
224: String err = "A complexType may contain referring "
225: + "attribute groups, but not defining ones.";
226: error(err);
227: }
228:
229: foundAttributes = true;
230: unmarshaller = new AttributeGroupUnmarshaller(_schema, atts);
231: }
232: //--<group>
233: else if (name.equals(SchemaNames.GROUP)) {
234: if (foundAttributes)
235: error("'" + name
236: + "' must appear before any attribute "
237: + "definitions when a child of 'complexType'.");
238: if (foundModelGroup)
239: error("'"
240: + name
241: + "' cannot appear as a child of 'complexType' "
242: + "if another 'all', 'sequence', 'choice' or "
243: + "'group' also exists.");
244:
245: foundModelGroup = true;
246: unmarshaller = new ModelGroupUnmarshaller(_schema, atts,
247: getResolver());
248: } else if (SchemaNames.isGroupName(name)
249: && (name != SchemaNames.GROUP)) {
250: if (foundAttributes)
251: error("'" + name + "' must appear before attribute "
252: + "definitions in an 'extension' element.");
253:
254: if (foundModelGroup)
255: error("'" + name
256: + "' cannot appear as a child of 'extension' "
257: + "if another 'all', 'sequence', 'choice' or "
258: + "'group' already exists.");
259:
260: if (_complexType.isSimpleContent())
261: error("'" + name
262: + "' may not appear in a 'extension' of "
263: + "'simpleContent'.");
264:
265: foundModelGroup = true;
266: unmarshaller = new GroupUnmarshaller(_schema, name, atts,
267: getResolver());
268: }
269: //-- element declarations
270: else if (SchemaNames.ANY_ATTRIBUTE.equals(name)) {
271: //-- not yet supported....
272: error("anyAttribute is not yet supported.");
273: } else if (name.equals(SchemaNames.ANNOTATION)) {
274: if (foundAttributes || foundModelGroup)
275: error("An annotation must appear as the first child of an "
276: + "'extension' element.");
277:
278: if (foundAnnotation)
279: error("Only one (1) annotation may appear as the child of "
280: + "an 'extension' element.");
281:
282: foundAnnotation = true;
283: unmarshaller = new AnnotationUnmarshaller(atts);
284: } else
285: illegalElement(name);
286:
287: unmarshaller.setDocumentLocator(getDocumentLocator());
288: } //-- startElement
289:
290: /**
291: * Signals to end of the element with the given name.
292: *
293: * @param name the NCName of the element. It is an error
294: * if the name is a QName (ie. contains a prefix).
295: * @param namespace the namespace of the element.
296: **/
297: public void endElement(String name, String namespace)
298: throws XMLException {
299:
300: //-- Do delagation if necessary
301: if ((unmarshaller != null) && (depth > 0)) {
302: unmarshaller.endElement(name, namespace);
303: --depth;
304: return;
305: }
306:
307: //-- have unmarshaller perform any necessary clean up
308: unmarshaller.finish();
309:
310: //-- <anyAttribute>
311: if (SchemaNames.ANY_ATTRIBUTE.equals(name)) {
312: Wildcard wildcard = ((WildcardUnmarshaller) unmarshaller)
313: .getWildcard();
314: try {
315: _complexType.setAnyAttribute(wildcard);
316: } catch (SchemaException e) {
317: throw new IllegalArgumentException(e.getMessage());
318: }
319: }
320:
321: //-- attribute declarations
322: else if (SchemaNames.ATTRIBUTE.equals(name)) {
323: AttributeDecl attrDecl = ((AttributeUnmarshaller) unmarshaller)
324: .getAttribute();
325:
326: _complexType.addAttributeDecl(attrDecl);
327: }
328: //-- attribute groups
329: else if (SchemaNames.ATTRIBUTE_GROUP.equals(name)) {
330: AttributeGroupReference attrGroupRef = (AttributeGroupReference) unmarshaller
331: .getObject();
332: _complexType.addAttributeGroupReference(attrGroupRef);
333: }
334: //--group
335: else if (name.equals(SchemaNames.GROUP)) {
336: ModelGroup group = ((ModelGroupUnmarshaller) unmarshaller)
337: .getGroup();
338: _complexType.addGroup(group);
339: }
340:
341: //-- group declarations (all, choice, sequence)
342: else if ((SchemaNames.isGroupName(name))
343: && (name != SchemaNames.GROUP)) {
344: Group group = ((GroupUnmarshaller) unmarshaller).getGroup();
345: _complexType.addGroup(group);
346: }
347: //-- annotation
348: else if (SchemaNames.ANNOTATION.equals(name)) {
349: Annotation ann = ((AnnotationUnmarshaller) unmarshaller)
350: .getAnnotation();
351: _complexType.addAnnotation(ann);
352: }
353:
354: unmarshaller = null;
355: } //-- endElement
356:
357: public void characters(char[] ch, int start, int length)
358: throws XMLException {
359: //-- Do delagation if necessary
360: if (unmarshaller != null) {
361: unmarshaller.characters(ch, start, length);
362: }
363: } //-- characters
364:
365: } //-- ExtensionUnmarshaller
|