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