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