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 2001-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.Annotated;
53 import org.exolab.castor.xml.schema.Annotation;
54 import org.exolab.castor.xml.schema.IdentityField;
55 import org.exolab.castor.xml.schema.IdentitySelector;
56 import org.exolab.castor.xml.schema.SchemaContext;
57 import org.exolab.castor.xml.schema.SchemaNames;
58
59 /**
60 * A class for Unmarshalling Selector or Field elements for
61 * identity-constraints
62 *
63 * @author <a href="mailto:kvisco@intalio.com">Keith Visco</a>
64 * @version $Revision$ $Date: 2003-03-03 00:05:44 -0700 (Mon, 03 Mar 2003) $
65 **/
66 public class FieldOrSelectorUnmarshaller extends ComponentReader {
67
68 //--------------------/
69 //- Member Variables -/
70 //--------------------/
71
72 /**
73 * The current ComponentReader
74 **/
75 private ComponentReader _unmarshaller;
76
77 /**
78 * The current branch depth
79 **/
80 private int _depth = 0;
81
82 /**
83 * The Field or Selector we are unmarshalling
84 **/
85 private Annotated _fieldOrSelector = null;
86
87 private boolean _foundAnnotation = false;
88
89 private String _elementName = null;
90
91 //----------------/
92 //- Constructors -/
93 //----------------/
94
95 /**
96 * Creates a new FieldOrSelectorUnmarshaller.
97 *
98 * @param schemaContext the {@link SchemaContext} to get some configuration settings from
99 * @param elementName the name of the element being unmarshalled.
100 * @param atts the AttributeList.
101 **/
102 public FieldOrSelectorUnmarshaller(
103 final SchemaContext schemaContext,
104 final String elementName,
105 final AttributeSet atts)
106 throws XMLException
107 {
108 super(schemaContext);
109
110 _elementName = elementName;
111
112 String xpath = atts.getValue(SchemaNames.XPATH_ATTR);
113 if (xpath == null) {
114 error("The 'xpath' attribute for '" + _elementName + "' must exist.");
115 }
116
117 String id = atts.getValue(SchemaNames.ID_ATTR);
118
119 //-- selector
120 if (SchemaNames.SELECTOR.equals(elementName)) {
121 _fieldOrSelector = new IdentitySelector(xpath);
122 if (id != null) {
123 ((IdentitySelector)_fieldOrSelector).setId(id);
124 }
125 }
126 //-- field
127 else {
128 _fieldOrSelector = new IdentityField(xpath);
129 if (id != null) {
130 ((IdentityField)_fieldOrSelector).setId(id);
131 }
132 }
133
134 } //-- FieldOrSelectorUnmarshaller
135
136 //-----------/
137 //- Methods -/
138 //-----------/
139
140 /**
141 * Returns the name of the element that this ComponentReader
142 * handles
143 * @return the name of the element that this ComponentReader
144 * handles
145 **/
146 public String elementName() {
147 return _elementName;
148 } //-- elementName
149
150 /**
151 * Returns the Object created by this ComponentReader
152 *
153 * @return the Object created by this ComponentReader
154 **/
155 public Object getObject() {
156 return _fieldOrSelector;
157 } //-- getObject
158
159 public void finish()
160 throws XMLException {
161 //-- do nothing
162 } //-- finish
163
164 /**
165 * Signals the start of an element with the given name.
166 *
167 * @param name the NCName of the element. It is an error
168 * if the name is a QName (ie. contains a prefix).
169 * @param namespace the namespace of the element. This may be null.
170 * Note: A null namespace is not the same as the default namespace unless
171 * the default namespace is also null.
172 * @param atts the AttributeSet containing the attributes associated
173 * with the element.
174 * @param nsDecls the namespace declarations being declared for this
175 * element. This may be null.
176 **/
177 public void startElement(String name, String namespace, AttributeSet atts,
178 Namespaces nsDecls)
179 throws XMLException
180 {
181 //-- Do delagation if necessary
182 if (_unmarshaller != null) {
183 _unmarshaller.startElement(name, namespace, atts, nsDecls);
184 ++_depth;
185 return;
186 }
187
188 if (SchemaNames.ANNOTATION.equals(name)) {
189
190 if (_foundAnnotation)
191 error("Only one (1) annotation may appear as a child of '" +
192 _elementName + "'.");
193 _foundAnnotation = true;
194 _unmarshaller = new AnnotationUnmarshaller(getSchemaContext(), atts);
195 }
196 else 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
204 * if the name is a QName (ie. contains a prefix).
205 * @param namespace the namespace of the element.
206 **/
207 public void endElement(String name, String namespace)
208 throws XMLException
209 {
210
211 //-- Do delagation if necessary
212 if ((_unmarshaller != null) && (_depth > 0)) {
213 _unmarshaller.endElement(name, namespace);
214 --_depth;
215 return;
216 }
217
218 //-- have unmarshaller perform any necessary clean up
219 _unmarshaller.finish();
220
221 if (SchemaNames.ANNOTATION.equals(name)) {
222 Annotation annotation = (Annotation)_unmarshaller.getObject();
223 _fieldOrSelector.addAnnotation(annotation);
224 }
225
226 _unmarshaller = null;
227 } //-- endElement
228
229 public void characters(char[] ch, int start, int length)
230 throws XMLException
231 {
232 //-- Do delagation if necessary
233 if (_unmarshaller != null) {
234 _unmarshaller.characters(ch, start, length);
235 }
236 } //-- characters
237
238 } //-- FieldOrSelectorUnmarshaller