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.Group; 44 import org.exolab.castor.xml.schema.ModelGroup; 45 import org.exolab.castor.xml.schema.Schema; 46 import org.exolab.castor.xml.schema.SchemaContext; 47 import org.exolab.castor.xml.schema.SchemaException; 48 import org.exolab.castor.xml.schema.SchemaNames; 49 50 /** 51 * A class for Unmarshalling ModelGroups Definition 52 * 53 * @author <a href="mailto:kvisco@intalio.com">Keith Visco</a> 54 * @version $Revisio:$ $Date: 2005-12-13 14:58:48 -0700 (Tue, 13 Dec 2005) $ 55 **/ 56 public class ModelGroupUnmarshaller extends ComponentReader { 57 58 // --------------------------/ 59 // - Static Class Variables -/ 60 // --------------------------/ 61 62 /** 63 * The value of the maximum occurance wild card 64 */ 65 private static final String MAX_OCCURS_WILDCARD = "unbounded"; 66 67 // --------------------/ 68 // - Member Variables -/ 69 // --------------------/ 70 71 /** 72 * The current ComponentReader 73 **/ 74 private ComponentReader unmarshaller; 75 76 /** 77 * The current branch depth 78 **/ 79 private int depth = 0; 80 81 /** 82 * The ModelGroup reference for the ModelGroup we are constructing 83 **/ 84 private ModelGroup _group = null; 85 86 /** 87 * The Schema being "unmarshalled" 88 **/ 89 private Schema _schema = null; 90 91 /** 92 * Flag to indicate if we have already encounter an {@literal <annotation>} 93 */ 94 private boolean foundAnnotation = false; 95 // ----------------/ 96 // - Constructors -/ 97 // ----------------/ 98 99 /** 100 * Creates a new ModelGroupUnmarshaller. 101 * 102 * @param schemaContext the {@link SchemaContext} to get some configuration settings from 103 * @param schema the Schema to which the ModelGroup belongs 104 * @param atts the AttributeList 105 **/ 106 public ModelGroupUnmarshaller(final SchemaContext schemaContext, final Schema schema, 107 final AttributeSet atts) { 108 super(schemaContext); 109 110 this._schema = schema; 111 112 _group = new ModelGroup(_schema); 113 114 // -- handle attributes 115 String attValue = null; 116 117 118 // -- set name 119 _group.setName(atts.getValue("name")); 120 121 /* 122 * @maxOccurs If maxOccurs is present, the value is either unbounded or the int value of the 123 * attribute, otherwise maxOccurs equals the minOccurs value. 124 */ 125 attValue = atts.getValue(SchemaNames.MAX_OCCURS_ATTR); 126 if (attValue != null) { 127 if (_group.getName() != null) 128 throw new IllegalArgumentException( 129 "In <group>: " + _group.getName() + "'maxOccurs' cannot appear in a named <group>"); 130 if (MAX_OCCURS_WILDCARD.equals(attValue)) 131 attValue = "-1"; 132 int maxOccurs = toInt(attValue); 133 _group.setMaxOccurs(maxOccurs); 134 } 135 // -- minOccurs 136 attValue = atts.getValue("minOccurs"); 137 if (attValue != null) { 138 if (_group.getName() != null) 139 throw new IllegalArgumentException( 140 "In <group>: " + _group.getName() + ", 'minOccurs' cannot appear in a named <group>"); 141 _group.setMinOccurs(toInt(attValue)); 142 } 143 144 // -- @ref 145 attValue = atts.getValue("ref"); 146 if (attValue != null) { 147 if (_group.getName() != null) 148 throw new IllegalArgumentException( 149 "In <group>: " + _group.getName() + ", 'ref' cannot appear in a named <group>"); 150 // String name = attValue; 151 // int idx = name.indexOf(':'); 152 // String ns = null; 153 // if (idx >= 0) { 154 // String nsPrefix = name.substring(0,idx); 155 // name = name.substring(idx + 1); 156 // ns = (String) schema.getNamespace(nsPrefix); 157 // if (ns == null) { 158 // String err = "in the <group> referring: "+attValue; 159 // err += " The Namespace prefix is not recognized '"+nsPrefix+"'"; 160 // throw new IllegalArgumentException(err); 161 // } 162 // } 163 // 164 // if (ns != null) { 165 // Schema tempSchema = schema.getImportedSchema(ns); 166 // if (tempSchema!=null) { 167 // _group.setSchema(tempSchema); 168 // } 169 // tempSchema = null; 170 // } 171 172 _group.setReference(attValue); 173 } 174 // -- id 175 attValue = atts.getValue("id"); 176 _group.setId(attValue); 177 // -- not yet supported 178 179 180 } // -- ModelGroupUnmarshaller 181 182 // -----------/ 183 // - Methods -/ 184 // -----------/ 185 186 187 188 /** 189 * Returns the Group that was unmarshalled by this Unmarshaller. This method should only be called 190 * after unmarshalling has been completed. 191 * 192 * @return the unmarshalled Group 193 **/ 194 public ModelGroup getGroup() { 195 return _group; 196 } // -- getGroup 197 198 /** 199 * Returns the Object created by this ComponentReader 200 * 201 * @return the Object created by this ComponentReader 202 **/ 203 public Object getObject() { 204 return getGroup(); 205 } // -- getObject 206 207 /** 208 * Sets the name of the element that this UnknownUnmarshaller handles 209 **/ 210 public String elementName() { 211 return SchemaNames.GROUP; 212 } // -- elementName 213 214 /** 215 * Signals the start of an element with the given name. 216 * 217 * @param name the NCName of the element. It is an error if the name is a QName (ie. contains a 218 * prefix). 219 * @param namespace the namespace of the element. This may be null. Note: A null namespace is not 220 * the same as the default namespace unless the default namespace is also null. 221 * @param atts the AttributeSet containing the attributes associated with the element. 222 * @param nsDecls the namespace declarations being declared for this element. This may be null. 223 **/ 224 public void startElement(String name, String namespace, AttributeSet atts, Namespaces nsDecls) 225 throws XMLException { 226 // -- Do delagation if necessary 227 if (unmarshaller != null) { 228 unmarshaller.startElement(name, namespace, atts, nsDecls); 229 ++depth; 230 return; 231 } 232 233 if (SchemaNames.ANNOTATION.equals(name)) { 234 if (foundAnnotation) 235 error("Only one (1) 'annotation' is allowed as a child of " + "element definitions."); 236 237 foundAnnotation = true; 238 unmarshaller = new AnnotationUnmarshaller(getSchemaContext(), atts); 239 } 240 241 else if (SchemaNames.isGroupName(name)) { 242 unmarshaller = new GroupUnmarshaller(getSchemaContext(), _schema, name, atts); 243 } else { 244 StringBuffer err = new StringBuffer("illegal element <"); 245 err.append(name); 246 err.append("> found in <group>."); 247 throw new SchemaException(err.toString()); 248 } 249 250 } // -- startElement 251 252 /** 253 * Signals to end of the element with the given name. 254 * 255 * @param name the NCName of the element. It is an error if the name is a QName (ie. contains a 256 * prefix). 257 * @param namespace the namespace of the element. 258 **/ 259 public void endElement(String name, String namespace) throws XMLException { 260 261 // -- Do delagation if necessary 262 if ((unmarshaller != null) && (depth > 0)) { 263 unmarshaller.endElement(name, namespace); 264 --depth; 265 return; 266 } 267 268 // -- check for name mismatches 269 if (unmarshaller != null) { 270 if (!name.equals(unmarshaller.elementName())) { 271 String err = "missing end element for "; 272 err += unmarshaller.elementName(); 273 throw new SchemaException(err); 274 } 275 } 276 277 if (SchemaNames.ANNOTATION.equals(name)) { 278 Annotation ann = (Annotation) unmarshaller.getObject(); 279 _group.addAnnotation(ann); 280 } 281 282 else if (SchemaNames.isGroupName(name)) { 283 Group group = ((GroupUnmarshaller) unmarshaller).getGroup(); 284 _group.addGroup(group); 285 } 286 287 // -- have unmarshaller perform any necessary clean up 288 unmarshaller.finish(); 289 unmarshaller = null; 290 } // -- endElement 291 292 public void characters(char[] ch, int start, int length) throws XMLException { 293 // -- Do delagation if necessary 294 if (unmarshaller != null) { 295 unmarshaller.characters(ch, start, length); 296 } 297 } // -- characters 298 299 } // -- ModelGroupUnmarshaller