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-2003 (C) Intalio Inc. All Rights Reserved. 42 * 43 * This file was originally developed by Keith Visco during the 44 * course of employment at Intalio Inc. 45 * All portions of this file developed by Keith Visco after Jan 19 2005 are 46 * Copyright (C) 2005 Keith Visco. All Rights Reserved. 47 * 48 * $Id$ 49 */ 50 package org.exolab.castor.builder; 51 52 import java.util.Vector; 53 54 import org.exolab.castor.builder.binding.XMLBindingComponent; 55 import org.exolab.castor.builder.info.ClassInfo; 56 import org.exolab.castor.builder.info.FieldInfo; 57 import org.exolab.castor.xml.schema.Annotated; 58 import org.exolab.javasource.JClass; 59 import org.exolab.javasource.JEnum; 60 61 /** 62 * A class used to save State information for the SourceFactory. 63 * 64 * @author <a href="mailto:keith AT kvisco DOT com">Keith Visco</a> 65 */ 66 public class FactoryState implements ClassInfoResolver { 67 68 /** The JClass for which we are currently generating code. */ 69 private final JClass _jClass; 70 71 /** A ClassInfo for <code>_jClass</code>. */ 72 private final ClassInfo _classInfo; 73 74 /** A FieldInfo used to handle <code>xsd:choice</code>. */ 75 private FieldInfo _fieldInfoForChoice = null; 76 77 /** Package for the class currently being generated. */ 78 private final String _packageName; 79 80 /** Our ClassInfoResolver to keep track of ClassInfos for easy lookup. */ 81 private ClassInfoResolver _resolver = null; 82 83 /** Keeps track of which classes have been processed. */ 84 private Vector<Annotated> _processed = null; 85 86 /** SourceGenerator state. */ 87 private SGStateInfo _sgState = null; 88 89 /** If true, we are currently generating code for a group. */ 90 private boolean _createGroupItem = false; 91 92 /** 93 * Keeps track of whether or not the BoundProperties methods have been 94 * created. 95 */ 96 private boolean _bound = false; 97 98 /** Keeps track of the different FactoryState. */ 99 private FactoryState _parent = null; 100 101 /** 102 * {@link JClassRegistry} instance used for automatic class name conflict 103 * resolution. 104 */ 105 private JClassRegistry _xmlInfoRegistry = null; 106 107 /** 108 * Constructs a new FactoryState. 109 * 110 * @param className 111 * Class name of the class currently being generated. 112 * @param sgState 113 * Source Generator State object 114 * @param packageName 115 * package name for generated code. 116 * @param component 117 * TODO 118 */ 119 public FactoryState(final String className, final SGStateInfo sgState, 120 final String packageName, final XMLBindingComponent component) { 121 this(className, sgState, packageName, component, false); 122 } 123 124 /** 125 * Constructs a factory state with the option of choosing between JClass and JEnum. 126 * 127 * @param className 128 * Class name of the class currently being generated. 129 * @param sgState 130 * Source Generator State object 131 * @param packageName 132 * package name for generated code. 133 * @param component 134 * TODO 135 * @param enumeration 136 * use a JEnum instead if a JClass 137 */ 138 public FactoryState(final String className, final SGStateInfo sgState, 139 final String packageName, final XMLBindingComponent component, final boolean enumeration) { 140 if (sgState == null) { 141 throw new IllegalArgumentException("SGStateInfo cannot be null."); 142 } 143 144 _sgState = sgState; 145 _processed = new Vector<Annotated>(); 146 147 // keep the elements and complexType already processed 148 // if (resolver instanceof FactoryState) { 149 // _processed = ((FactoryState)resolver)._processed; 150 // } 151 152 if (enumeration) { 153 _jClass = new JEnum(className); 154 } else { 155 _jClass = new JClass(className); 156 } 157 158 // if configured, try automatic class name conflict resolution 159 if (_sgState.getSourceGenerator().isAutomaticConflictResolution()) { 160 _xmlInfoRegistry = sgState.getSourceGenerator() 161 .getXMLInfoRegistry(); 162 _xmlInfoRegistry.bind(_jClass, component, "class"); 163 } 164 165 _classInfo = new ClassInfo(_jClass); 166 167 _resolver = sgState; 168 169 _packageName = packageName; 170 171 // -- boundProperties 172 _bound = sgState.getSourceGenerator().boundPropertiesEnabled(); 173 174 } // -- FactoryState 175 176 /** 177 * Get JClass for which we are currently generating code. 178 * 179 * @return JClass for which we are currently generating code. 180 */ 181 public final JClass getJClass() { 182 return _jClass; 183 } 184 185 /** 186 * Get ClassInfo for <code>_jClass</code>. 187 * 188 * @return ClassInfo for <code>_jClass</code>. 189 */ 190 public final ClassInfo getClassInfo() { 191 return _classInfo; 192 } 193 194 /** 195 * Get FieldInfo used to handle <code>xsd:choice</code>. 196 * 197 * @return FieldInfo used to handle <code>xsd:choice</code>. 198 */ 199 public final FieldInfo getFieldInfoForChoice() { 200 return _fieldInfoForChoice; 201 } 202 203 /** 204 * Set FieldInfo used to handle <code>xsd:choice</code>. 205 * 206 * @param fieldInfoForChoice 207 * FieldInfo used to handle <code>xsd:choice</code>. 208 */ 209 public final void setFieldInfoForChoice(final FieldInfo fieldInfoForChoice) { 210 _fieldInfoForChoice = fieldInfoForChoice; 211 } 212 213 /** 214 * Get package for the class currently being generated. 215 * 216 * @return Package for the class currently being generated. 217 */ 218 public final String getPackageName() { 219 return _packageName; 220 } 221 222 /** 223 * Adds the given Reference to this ClassInfo resolver. 224 * 225 * @param key 226 * the key to bind a reference to 227 * @param classInfoRef 228 * the ClassInfo which is being referenced 229 */ 230 public void bindReference(final Object key, final ClassInfo classInfoRef) { 231 _resolver.bindReference(key, classInfoRef); 232 } // -- bindReference 233 234 /** 235 * Returns the SGStateInfo. 236 * 237 * @return the SGStateInfo. 238 */ 239 public SGStateInfo getSGStateInfo() { 240 return _sgState; 241 } // -- getSGStateInfo 242 243 /** 244 * Marks the given Annotated XML Schema structure as having been processed. 245 * 246 * @param annotated 247 * the Annotated XML Schema structure to mark as having been 248 * processed. 249 */ 250 public void markAsProcessed(final Annotated annotated) { 251 _processed.addElement(annotated); 252 } // -- markAsProcessed 253 254 /** 255 * Returns true if the given Annotated XML Schema structure has been marked 256 * as processed. 257 * 258 * @param annotated 259 * the Annotated XML Schema structure to check for being marked 260 * as processed 261 * @return true if the given Annotated XML Schema structure has been marked 262 * as processed 263 */ 264 public boolean processed(final Annotated annotated) { 265 boolean result = _processed.contains(annotated); 266 if (!result && _parent != null) { 267 return _parent.processed(annotated); 268 } 269 return result; 270 } // -- processed 271 272 /** 273 * Returns true if any bound properties have been found. 274 * 275 * @return true if any bound properties have been found. 276 */ 277 public boolean hasBoundProperties() { 278 return _bound; 279 } // -- hasBoundProperties 280 281 /** 282 * Allows setting the bound properties flag. 283 * 284 * @param bound 285 * the new value of the bound properties flag 286 * @see #hasBoundProperties 287 */ 288 public void setBoundProperties(final boolean bound) { 289 _bound = bound; 290 } // -- setBoundProperties 291 292 /** 293 * Returns the ClassInfo which has been bound to the given key. 294 * 295 * @param key 296 * the object to which the ClassInfo has been bound 297 * @return the ClassInfo which has been bound to the given key 298 */ 299 public ClassInfo resolve(final Object key) { 300 return _resolver.resolve(key); 301 } // -- resolve 302 303 /** 304 * Returns true if we are currently in the state of creating a group item 305 * class. 306 * 307 * @return true if we are currently in the state of creating a group item 308 * class. 309 */ 310 public boolean isCreateGroupItem() { 311 return _createGroupItem; 312 } 313 314 /** 315 * Sets to true if we are currently generating a class to represent items in 316 * a group. 317 * 318 * @param createGroupItem 319 * true if we are currently generating a class to represent items 320 * in a group. 321 */ 322 public void setCreateGroupItem(final boolean createGroupItem) { 323 _createGroupItem = createGroupItem; 324 } 325 326 /** 327 * Returns the parent of this FactoryState. The parent of a factory state is 328 * the previous item of the list that contained all the created factory 329 * states. 330 * 331 * @return the parent of this FactoryState. 332 */ 333 FactoryState getParent() { 334 return _parent; 335 } 336 337 /** 338 * Sets the parent of this FactoryState. 339 * 340 * @param parent 341 * the parent FactoryState 342 * @see #getParent 343 */ 344 public void setParent(final FactoryState parent) { 345 _parent = parent; 346 } 347 348 } // -- FactoryState