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-2002 (C) Intalio, Inc. All Rights Reserved.
42   *
43   * $Id$
44   */
45  package org.exolab.castor.builder.factory;
46  
47  import java.security.InvalidParameterException;
48  
49  import org.castor.xml.JavaNaming;
50  import org.castor.xml.JavaNamingImpl;
51  import org.castor.xml.JavaNamingNGImpl;
52  import org.exolab.castor.builder.SourceGeneratorConstants;
53  import org.exolab.castor.builder.info.CollectionInfo;
54  import org.exolab.castor.builder.info.CollectionInfoJ2;
55  import org.exolab.castor.builder.info.CollectionInfoJ2Collection;
56  import org.exolab.castor.builder.info.CollectionInfoJ2Set;
57  import org.exolab.castor.builder.info.CollectionInfoJ2SortedSet;
58  import org.exolab.castor.builder.info.CollectionInfoODMG30;
59  import org.exolab.castor.builder.info.FieldInfo;
60  import org.exolab.castor.builder.info.IdentityInfo;
61  import org.exolab.castor.builder.types.XSType;
62  
63  /**
64   * This class is used as a factory to create all the FieldInfo objects used by
65   * the source generator. You may override the FieldInfo classes and this factory
66   * for specific adaptions.
67   * 
68   * @author <a href="mailto:frank.thelen@poet.de">Frank Thelen</a>
69   * @author <a href="mailto:blandin@intalio.com">Arnaud Blandin</a>
70   * @version $Revision$ $Date: 2005-03-05 06:42:06 -0700 (Sat, 05 Mar
71   *          2005) $
72   */
73  public class FieldInfoFactory {
74     /** The default collection name. */
75     private String _default = null;
76  
77     /**
78      * A flag indicating that "extra" accessor methods should be created for
79      * returning and setting a reference to the underlying collection.
80      */
81     private boolean _extraMethods = false;
82  
83     /** The reference suffix to use. */
84     private String _referenceSuffix = null;
85  
86     /** If true, code for bound properties will be generated. */
87     private boolean _bound = false;
88  
89     /* The FieldMemberAndAccessorFactories */
90     private FieldMemberAndAccessorFactory _fieldMemberAndAccessorFactory;
91     private CollectionMemberAndAccessorFactory _collectionMemberAndAccessorFactory;
92     private CollectionJ2MemberAndAccessorFactory _collectionJ2MemberAndAccessorFactory;
93     private CollectionJ2NoIndexMemberAndAccessorFactory _collectionJ2NoIndexMemberAndAccessorFactory;
94     private CollectionODMG30MemberAndAccessorFactory _collectionODMG30MemberAndAccessorFactory;
95     private IdentityMemberAndAccessorFactory _identityMemberAndAccessorFactory;
96  
97     /**
98      * The {@link JavaNaming} to use.
99      * 
100     * @since 1.1.3
101     */
102    private JavaNaming _javaNaming;
103 
104    /**
105     * Creates a new {@link FieldInfoFactory} instance. The default collection
106     * used will be Java 1 type.
107     */
108    public FieldInfoFactory() {
109       this("vector");
110    }
111 
112    /**
113     * Creates a new {@link FieldInfoFactory} instance. The default collection
114     * used will be Java 1 type.
115     * 
116     * @param useOldFieldNaming
117     *           True to indicate that old Java naming conventions should be
118     *           used.
119     */
120    public FieldInfoFactory(boolean useOldFieldNaming) {
121       this("vector", useOldFieldNaming);
122    }
123 
124    /**
125     * Creates a new {@link FieldInfoFactory} of the given collection type.
126     * 
127     * @param collectionName
128     *           The type for the FieldInfoFactory.
129     */
130    public FieldInfoFactory(final String collectionName) {
131       this(collectionName, true);
132    }
133 
134    /**
135     * Creates a new FieldInfoFactory of the given collection type.
136     * 
137     * @param collectionName
138     *           The type for the FieldInfoFactory.
139     * @param useOldFieldNaming
140     *           True to indicate that old Java naming conventions should be
141     *           used.
142     */
143    public FieldInfoFactory(final String collectionName, boolean useOldFieldNaming) {
144       super();
145       if (!(collectionName.equals(SourceGeneratorConstants.FIELD_INFO_VECTOR)
146             || collectionName.equals(SourceGeneratorConstants.FIELD_INFO_ARRAY_LIST) || collectionName
147                .equals(SourceGeneratorConstants.FIELD_INFO_ODMG))) {
148          throw new IllegalArgumentException(collectionName + " is currently not a supported Java collection type.");
149       }
150       _default = collectionName;
151 
152       if (useOldFieldNaming) {
153          _javaNaming = new JavaNamingImpl();
154       } else {
155          _javaNaming = new JavaNamingNGImpl();
156       }
157 
158       this._fieldMemberAndAccessorFactory = new FieldMemberAndAccessorFactory(_javaNaming, useOldFieldNaming);
159       this._collectionMemberAndAccessorFactory = new CollectionMemberAndAccessorFactory(_javaNaming);
160       this._collectionJ2MemberAndAccessorFactory = new CollectionJ2MemberAndAccessorFactory(_javaNaming);
161       this._collectionJ2NoIndexMemberAndAccessorFactory = new CollectionJ2NoIndexMemberAndAccessorFactory(_javaNaming);
162       this._collectionODMG30MemberAndAccessorFactory = new CollectionODMG30MemberAndAccessorFactory(_javaNaming);
163       this._identityMemberAndAccessorFactory = new IdentityMemberAndAccessorFactory(_javaNaming);
164 
165    }
166 
167    /**
168     * Creates an {@link IdentityInfo} instance for the given name.
169     * 
170     * @param name
171     *           Identity field name.
172     * @return The {@link IdentityInfo} instance just created.
173     */
174    public IdentityInfo createIdentity(final String name) {
175       IdentityInfo idInfo = new IdentityInfo(name, this._identityMemberAndAccessorFactory);
176       if (_bound) {
177          idInfo.setBound(_bound);
178       }
179       return idInfo;
180    }
181 
182    /**
183     * Creates a {@link CollectionInfo} instance based upon the various
184     * parameters provided.
185     * 
186     * @param contentType
187     *           Content type of the collection.
188     * @param name
189     *           Name of the collection member.
190     * @param elementName
191     *           Name of the (content) element.
192     * @param javaNaming
193     *           the Java naming to be used
194     * @param usejava50
195     *           Whether we are targeting Java 5.0 or above or not
196     * @return A {@link CollectionInfo} instance representing a collection typed
197     *         member.
198     * @see #createCollection(XSType, String, String, String, boolean)
199     */
200    public CollectionInfo createCollection(final XSType contentType, final String name, final String elementName,
201          final JavaNaming javaNaming, final boolean usejava50) {
202       return createCollection(contentType, name, elementName, _default, javaNaming, usejava50);
203    }
204 
205    /**
206     * Creates a {@link CollectionInfo} instance based upon the various
207     * parameters provided.
208     * 
209     * @param contentType
210     *           Content type of the collection.
211     * @param name
212     *           Name of the collection member.
213     * @param elementName
214     *           Name of the (content) element.
215     * @param collectionName
216     *           Name of the collection.
217     * @param javaNaming
218     *           the Java naming to be used
219     * @param useJava50
220     *           Whether we are targeting Java 5.0 or above or not
221     * @return A {@link CollectionInfo} instance representing a collection typed
222     *         member.
223     */
224    public CollectionInfo createCollection(final XSType contentType, final String name, final String elementName,
225          final String collectionName, final JavaNaming javaNaming, final boolean useJava50) {
226       String temp = collectionName;
227       if (temp == null || temp.length() == 0) {
228          temp = _default;
229       }
230 
231       final CollectionInfo cInfo;
232       if (temp.equalsIgnoreCase(SourceGeneratorConstants.FIELD_INFO_VECTOR)) {
233          cInfo = new CollectionInfo(contentType, name, elementName, useJava50,
234                this._collectionMemberAndAccessorFactory, this._fieldMemberAndAccessorFactory);
235       } else if (temp.equalsIgnoreCase(SourceGeneratorConstants.FIELD_INFO_ARRAY_LIST)) {
236          cInfo = new CollectionInfoJ2(contentType, name, elementName, "arraylist", useJava50,
237                this._collectionJ2MemberAndAccessorFactory, this._fieldMemberAndAccessorFactory);
238       } else if (temp.equalsIgnoreCase(SourceGeneratorConstants.FIELD_INFO_ODMG)) {
239          cInfo = new CollectionInfoODMG30(contentType, name, elementName, useJava50,
240                this._collectionODMG30MemberAndAccessorFactory, this._fieldMemberAndAccessorFactory);
241       } else if (temp.equalsIgnoreCase(SourceGeneratorConstants.FIELD_INFO_COLLECTION)) {
242          cInfo = new CollectionInfoJ2Collection(contentType, name, elementName, useJava50,
243                this._collectionJ2NoIndexMemberAndAccessorFactory, this._fieldMemberAndAccessorFactory);
244       } else if (temp.equalsIgnoreCase(SourceGeneratorConstants.FIELD_INFO_SET)) {
245          cInfo = new CollectionInfoJ2Set(contentType, name, elementName, useJava50,
246                this._collectionJ2NoIndexMemberAndAccessorFactory, this._fieldMemberAndAccessorFactory);
247       } else if (temp.equalsIgnoreCase(SourceGeneratorConstants.FIELD_INFO_SORTED_SET)) {
248          cInfo = new CollectionInfoJ2SortedSet(contentType, name, elementName, useJava50,
249                this._collectionJ2NoIndexMemberAndAccessorFactory, this._fieldMemberAndAccessorFactory);
250       } else {
251          throw new InvalidParameterException("Unrecognized collection type: " + temp);
252       }
253 
254       // --not sure it is pluggable enough, it is not really beautiful to
255       // specify
256       // --the collection to use here
257       cInfo.setCreateExtraMethods(_extraMethods);
258       if (_referenceSuffix != null) {
259          cInfo.setReferenceMethodSuffix(_referenceSuffix);
260       }
261       if (_bound) {
262          cInfo.setBound(true);
263       }
264       return cInfo;
265    }
266 
267    /**
268     * Creates a {@link FieldInfo} instance for the given {@link XSType} and its
269     * name.
270     * 
271     * @param type
272     *           {@link XSType} of the field.
273     * @param name
274     *           Field name.
275     * @return The {@link FieldInfo} instance just created.
276     */
277    public FieldInfo createFieldInfo(final XSType type, final String name) {
278       FieldInfo fieldInfo = new FieldInfo(type, name, this._fieldMemberAndAccessorFactory);
279       if (_bound) {
280          fieldInfo.setBound(true);
281       }
282       return fieldInfo;
283    }
284 
285    /**
286     * Sets whether or not the fields should be bound properties.
287     * 
288     * @param bound
289     *           a boolean that when true indicates the FieldInfo should have the
290     *           bound property enabled.
291     */
292    public final void setBoundProperties(final boolean bound) {
293       _bound = bound;
294    }
295 
296    /**
297     * Sets whether or not to create extra collection methods for accessing the
298     * actual collection.
299     * 
300     * @param extraMethods
301     *           a boolean that when true indicates that extra collection
302     *           accessor methods should be created. False by default.
303     * @see org.exolab.castor.builder.FieldInfoFactory#setReferenceMethodSuffix
304     */
305    public final void setCreateExtraMethods(final boolean extraMethods) {
306       _extraMethods = extraMethods;
307    }
308 
309    /**
310     * Sets the method suffix (ending) to use when creating the extra collection
311     * methods.
312     * 
313     * @param suffix
314     *           the method suffix to use when creating the extra collection
315     *           methods. If null or emtpty the default value, as specified in
316     *           CollectionInfo will be used.
317     * @see org.exolab.castor.builder.FieldInfoFactory#setCreateExtraMethods
318     */
319    public final void setReferenceMethodSuffix(final String suffix) {
320       _referenceSuffix = suffix;
321    }
322 }