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 2001-2002 (C) Intalio Inc. All Rights Reserved.
042: *
043: * $Id: UnionUnmarshaller.java 6230 2006-09-19 07:56:07Z wguttmn $
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.Schema;
052: import org.exolab.castor.xml.schema.SchemaNames;
053: import org.exolab.castor.xml.schema.SimpleType;
054: import org.exolab.castor.xml.schema.Union;
055:
056: import java.util.StringTokenizer;
057:
058: /**
059: * A class for Unmarshalling XML Schema Union types
060: *
061: * @author <a href="mailto:kvisco@intalio.com">Keith Visco</a>
062: * @version $Revision: 6230 $ $Date: 2003-03-03 00:05:44 -0700 (Mon, 03 Mar 2003) $
063: **/
064: public class UnionUnmarshaller extends ComponentReader {
065:
066: //--------------------/
067: //- Member Variables -/
068: //--------------------/
069:
070: /**
071: * The current ComponentReader
072: **/
073: private ComponentReader _unmarshaller;
074:
075: /**
076: * The current branch depth
077: **/
078: private int _depth = 0;
079:
080: /**
081: * The Union we are unmarshalling
082: **/
083: private Union _union = null;
084:
085: /**
086: * The parent Schema for the Union
087: **/
088: private Schema _schema = null;
089:
090: private boolean _foundAnnotation = false;
091: private boolean _foundSimpleType = false;
092:
093: //----------------/
094: //- Constructors -/
095: //----------------/
096:
097: /**
098: * Creates a new IdentityConstraintUnmarshaller
099: *
100: * @param atts the AttributeList
101: **/
102: public UnionUnmarshaller(Schema schema, AttributeSet atts)
103: throws XMLException {
104: super ();
105:
106: if (schema == null) {
107: String err = "'schema' must not be null.";
108: throw new IllegalStateException(err);
109: }
110: _schema = schema;
111:
112: _union = new Union(_schema);
113: _union.setId(atts.getValue(SchemaNames.ID_ATTR));
114:
115: String memberTypes = atts
116: .getValue(SchemaNames.MEMBER_TYPES_ATTR);
117: processMemberTypes(memberTypes);
118:
119: } //-- UnionUnmarshaller
120:
121: //-----------/
122: //- Methods -/
123: //-----------/
124:
125: /**
126: * Returns the name of the element that this ComponentReader
127: * handles
128: * @return the name of the element that this ComponentReader
129: * handles
130: **/
131: public String elementName() {
132: return SchemaNames.UNION;
133: } //-- elementName
134:
135: /**
136: * Returns the Object created by this ComponentReader
137: *
138: * @return the Object created by this ComponentReader
139: **/
140: public Object getObject() {
141: return _union;
142: } //-- getObject
143:
144: public void finish() throws XMLException {
145: //-- do nothing
146: } //-- finish
147:
148: /**
149: * Signals the start of an element with the given name.
150: *
151: * @param name the NCName of the element. It is an error
152: * if the name is a QName (ie. contains a prefix).
153: * @param namespace the namespace of the element. This may be null.
154: * Note: A null namespace is not the same as the default namespace unless
155: * the default namespace is also null.
156: * @param atts the AttributeSet containing the attributes associated
157: * with the element.
158: * @param nsDecls the namespace declarations being declared for this
159: * element. This may be null.
160: **/
161: public void startElement(String name, String namespace,
162: AttributeSet atts, Namespaces nsDecls) throws XMLException {
163: //-- Do delagation if necessary
164: if (_unmarshaller != null) {
165: _unmarshaller.startElement(name, namespace, atts, nsDecls);
166: ++_depth;
167: return;
168: }
169:
170: if (SchemaNames.ANNOTATION.equals(name)) {
171:
172: if (_foundAnnotation)
173: error("Only one (1) annotation may appear as a child of '"
174: + elementName() + "'.");
175:
176: if (_foundSimpleType)
177: error("An annotation may only appear as the first child of '"
178: + elementName() + "'.");
179:
180: _foundAnnotation = true;
181: _unmarshaller = new AnnotationUnmarshaller(atts);
182: } else if (SchemaNames.SIMPLE_TYPE.equals(name)) {
183: _foundSimpleType = true;
184: _unmarshaller = new SimpleTypeUnmarshaller(_schema, atts);
185: } else
186: illegalElement(name);
187:
188: } //-- startElement
189:
190: /**
191: * Signals to end of the element with the given name.
192: *
193: * @param name the NCName of the element. It is an error
194: * if the name is a QName (ie. contains a prefix).
195: * @param namespace the namespace of the element.
196: **/
197: public void endElement(String name, String namespace)
198: throws XMLException {
199:
200: //-- Do delagation if necessary
201: if ((_unmarshaller != null) && (_depth > 0)) {
202: _unmarshaller.endElement(name, namespace);
203: --_depth;
204: return;
205: }
206:
207: //-- have unmarshaller perform any necessary clean up
208: _unmarshaller.finish();
209:
210: if (SchemaNames.ANNOTATION.equals(name)) {
211: _union.setLocalAnnotation((Annotation) _unmarshaller
212: .getObject());
213: } else if (SchemaNames.SIMPLE_TYPE.equals(name)) {
214:
215: SimpleType simpleType = (SimpleType) _unmarshaller
216: .getObject();
217:
218: //-- make sure type is not another Union
219: if (simpleType instanceof Union) {
220: String err = "A 'union' may only contain SimpleTypes of "
221: + "the atomic or list variety.";
222: error(err);
223: }
224: //-- make sure type is atomic or list
225: // XXXX to be added later
226:
227: _union.addMemberType(simpleType);
228: }
229:
230: _unmarshaller = null;
231: } //-- endElement
232:
233: public void characters(char[] ch, int start, int length)
234: throws XMLException {
235: //-- Do delagation if necessary
236: if (_unmarshaller != null) {
237: _unmarshaller.characters(ch, start, length);
238: }
239: } //-- characters
240:
241: /**
242: * Processes the given string into the referenced simpleTypes
243: * for the Union being unmarshalled.
244: *
245: * @param memberTypes the memberTypes list.
246: **/
247: private void processMemberTypes(String memberTypes) {
248: if ((memberTypes == null) || (memberTypes.length() == 0))
249: return;
250:
251: StringTokenizer st = new StringTokenizer(memberTypes);
252: while (st.hasMoreTokens()) {
253: String typeName = st.nextToken();
254: SimpleType simpleType = _schema.getSimpleType(typeName);
255: if (simpleType != null) {
256: _union.addMemberType(simpleType);
257: } else {
258: _union.addMemberType(typeName);
259: }
260:
261: }
262: } //-- processMemberTypes
263:
264: } //-- UnionUnmarshaller
|