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 2001-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.IdentityConstraint;
44  import org.exolab.castor.xml.schema.IdentityField;
45  import org.exolab.castor.xml.schema.IdentitySelector;
46  import org.exolab.castor.xml.schema.Key;
47  import org.exolab.castor.xml.schema.KeyRef;
48  import org.exolab.castor.xml.schema.SchemaContext;
49  import org.exolab.castor.xml.schema.SchemaNames;
50  import org.exolab.castor.xml.schema.Unique;
51  
52  /**
53   * A class for Unmarshalling Identity Constraints
54   *
55   * @author <a href="mailto:kvisco@intalio.com">Keith Visco</a>
56   * @version $Revision$ $Date: 2003-03-03 00:05:44 -0700 (Mon, 03 Mar 2003) $
57   **/
58  public class IdentityConstraintUnmarshaller extends ComponentReader {
59  
60    // --------------------/
61    // - Member Variables -/
62    // --------------------/
63  
64    /**
65     * The current ComponentReader
66     **/
67    private ComponentReader _unmarshaller;
68  
69    /**
70     * The current branch depth
71     **/
72    private int _depth = 0;
73  
74    /**
75     * The IdentityConstraint we are unmarshalling
76     **/
77    private IdentityConstraint _identityConstraint = null;
78  
79    private boolean _foundAnnotation = false;
80    private boolean _foundSelector = false;
81    private boolean _foundField = false;
82  
83    private String _elementName = null;
84  
85    // ----------------/
86    // - Constructors -/
87    // ----------------/
88  
89    /**
90     * Creates a new IdentityConstraintUnmarshaller.
91     *
92     * @param schemaContext the {@link SchemaContext} to get some configuration settings from
93     * @param elementName the resolver being used for reference resolving
94     * @param atts the AttributeList
95     **/
96    public IdentityConstraintUnmarshaller(final SchemaContext schemaContext, final String elementName,
97        final AttributeSet atts) throws XMLException {
98      super(schemaContext);
99  
100     _elementName = elementName;
101 
102     String name = atts.getValue(SchemaNames.NAME_ATTR);
103     if (name == null) {
104       error("The 'name' attribute for an identity-constraint must exist.");
105     }
106 
107     atts.getValue(SchemaNames.ID_ATTR);
108 
109     // -- keyref
110     if (SchemaNames.KEYREF.equals(elementName)) {
111       String refer = atts.getValue("refer");
112       if (refer == null) {
113         error("The 'refer' attribute for keyref must exist.");
114       }
115       _identityConstraint = new KeyRef(name, refer);
116     }
117     // -- unique
118     else if (SchemaNames.UNIQUE.equals(elementName)) {
119       _identityConstraint = new Unique(name);
120     }
121     // -- key
122     else {
123       _identityConstraint = new Key(name);
124     }
125 
126   } // -- IdentityConstraintUnmarshaller
127 
128   // -----------/
129   // - Methods -/
130   // -----------/
131 
132   /**
133    * Returns the name of the element that this ComponentReader handles
134    * 
135    * @return the name of the element that this ComponentReader handles
136    **/
137   public String elementName() {
138     return _elementName;
139   } // -- elementName
140 
141   /**
142    * Returns the IdentityConstraint created.
143    *
144    * @return the IdentityConstraint created.
145    **/
146   public IdentityConstraint getIdentityConstraint() {
147     return _identityConstraint;
148   } // -- getIdentityConstraint
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 getIdentityConstraint();
157   } // -- getObject
158 
159   public void finish() throws XMLException {
160     if (!_foundSelector) {
161       error("Invalid " + _elementName + "; missing 'selector'.");
162     } else if (!_foundField) {
163       error("Invalid " + _elementName + "; missing 'field'.");
164     }
165   } // -- finish
166 
167   /**
168    * Signals the start of an element with the given name.
169    *
170    * @param name the NCName of the element. It is an error if the name is a QName (ie. contains a
171    *        prefix).
172    * @param namespace the namespace of the element. This may be null. Note: A null namespace is not
173    *        the same as the default namespace unless the default namespace is also null.
174    * @param atts the AttributeSet containing the attributes associated with the element.
175    * @param nsDecls the namespace declarations being declared for this element. This may be null.
176    **/
177   public void startElement(String name, String namespace, AttributeSet atts, Namespaces nsDecls)
178       throws XMLException {
179     // -- Do delagation if necessary
180     if (_unmarshaller != null) {
181       _unmarshaller.startElement(name, namespace, atts, nsDecls);
182       ++_depth;
183       return;
184     }
185 
186     if (SchemaNames.ANNOTATION.equals(name)) {
187 
188       if (_foundAnnotation)
189         error("Only one (1) annotation may appear as a child of '" + _elementName + "'.");
190 
191       if (_foundSelector || _foundField)
192         error("An annotation may only appear as the first child of '" + _elementName + "'.");
193 
194       _foundAnnotation = true;
195       _unmarshaller = new AnnotationUnmarshaller(getSchemaContext(), atts);
196     } else if (SchemaNames.SELECTOR.equals(name)) {
197 
198       if (_foundField) {
199         String err = "The 'selector' element of '" + _elementName
200             + "' must appear before any 'field' elements.";
201         error(err);
202       }
203       if (_foundSelector)
204         error("Only one (1) 'selector' may appear as a child of '" + _elementName + "'.");
205 
206       _foundSelector = true;
207 
208       _unmarshaller = new FieldOrSelectorUnmarshaller(getSchemaContext(), name, atts);
209     } else if (SchemaNames.FIELD.equals(name)) {
210       _foundField = true;
211       _unmarshaller = new FieldOrSelectorUnmarshaller(getSchemaContext(), name, atts);
212     } else
213       illegalElement(name);
214 
215   } // -- startElement
216 
217   /**
218    * Signals to end of the element with the given name.
219    *
220    * @param name the NCName of the element. It is an error if the name is a QName (ie. contains a
221    *        prefix).
222    * @param namespace the namespace of the element.
223    **/
224   public void endElement(String name, String namespace) throws XMLException {
225 
226     // -- Do delagation if necessary
227     if ((_unmarshaller != null) && (_depth > 0)) {
228       _unmarshaller.endElement(name, namespace);
229       --_depth;
230       return;
231     }
232 
233     // -- have unmarshaller perform any necessary clean up
234     _unmarshaller.finish();
235 
236     if (SchemaNames.ANNOTATION.equals(name)) {
237       Annotation annotation = (Annotation) _unmarshaller.getObject();
238       _identityConstraint.addAnnotation(annotation);
239     } else if (SchemaNames.SELECTOR.equals(name)) {
240       IdentitySelector selector = (IdentitySelector) _unmarshaller.getObject();
241       _identityConstraint.setSelector(selector);
242     } else if (SchemaNames.FIELD.equals(name)) {
243       IdentityField field = (IdentityField) _unmarshaller.getObject();
244       _identityConstraint.addField(field);
245     }
246 
247 
248     _unmarshaller = null;
249   } // -- endElement
250 
251   public void characters(char[] ch, int start, int length) throws XMLException {
252     // -- Do delagation if necessary
253     if (_unmarshaller != null) {
254       _unmarshaller.characters(ch, start, length);
255     }
256   } // -- characters
257 
258 } // -- IdentityConstraintUnmarshaller