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