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