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