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 }