View Javadoc
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