KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > oracle > toplink > essentials > mappings > converters > ObjectTypeConverter


1 /*
2  * The contents of this file are subject to the terms
3  * of the Common Development and Distribution License
4  * (the "License"). You may not use this file except
5  * in compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * glassfish/bootstrap/legal/CDDLv1.0.txt or
9  * https://glassfish.dev.java.net/public/CDDLv1.0.html.
10  * See the License for the specific language governing
11  * permissions and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL
14  * HEADER in each file and include the License file at
15  * glassfish/bootstrap/legal/CDDLv1.0.txt. If applicable,
16  * add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your
18  * own identifying information: Portions Copyright [yyyy]
19  * [name of copyright owner]
20  */

21 // Copyright (c) 1998, 2006, Oracle. All rights reserved.
22
package oracle.toplink.essentials.mappings.converters;
23
24 import java.util.*;
25 import oracle.toplink.essentials.mappings.*;
26 import oracle.toplink.essentials.exceptions.*;
27 import oracle.toplink.essentials.internal.helper.*;
28 import oracle.toplink.essentials.mappings.foundation.AbstractDirectMapping;
29 import oracle.toplink.essentials.sessions.*;
30 import oracle.toplink.essentials.internal.sessions.AbstractSession;
31
32 /**
33  * <b>Purpose</b>: Object type converter is used to match a fixed number of database data values
34  * to Java object value. It can be used when the values on the database and in the Java differ.
35  * To create an object type converter, simply specify the set of conversion value pairs.
36  * A default value and one-way conversion are also supported for legacy data situations.
37  *
38  * @author James Sutherland
39  * @since Toplink 10
40  */

41 public class ObjectTypeConverter implements Converter {
42     protected DatabaseMapping mapping;
43     protected transient Map fieldToAttributeValues;
44     protected Map attributeToFieldValues;
45     protected transient Object JavaDoc defaultAttributeValue;
46     protected transient Class JavaDoc fieldClassification;
47     protected transient String JavaDoc fieldClassificationName;
48
49     /**
50      * PUBLIC:
51      * Default constructor.
52      */

53     public ObjectTypeConverter() {
54         this.attributeToFieldValues = new HashMap(10);
55         this.fieldToAttributeValues = new HashMap(10);
56     }
57
58     /**
59      * PUBLIC:
60      * Default constructor.
61      */

62     public ObjectTypeConverter(DatabaseMapping mapping) {
63         this();
64         this.mapping = mapping;
65     }
66
67     /**
68      * PUBLIC:
69      * A type conversion value is a two-way mapping from the database to the object.
70      * The database value will be substituted for the object value when read,
71      * and the object value will be substituted for database value when written.
72      * Note that each field/attribute value must have one and only one attribute/field value to maintain a two-way mapping.
73      */

74     public void addConversionValue(Object JavaDoc fieldValue, Object JavaDoc attributeValue) {
75         if (fieldValue == null) {
76             fieldValue = Helper.getNullWrapper();
77         }
78
79         if (attributeValue == null) {
80             attributeValue = Helper.getNullWrapper();
81         }
82
83         getFieldToAttributeValues().put(fieldValue, attributeValue);
84         getAttributeToFieldValues().put(attributeValue, fieldValue);
85     }
86
87     /**
88      * PUBLIC:
89      * An attribute only conversion value is a one-way mapping from the database to the object.
90      * This can be used if multiple database values are desired to be mapped to the same object value.
91      * Note that when written only the default value will be used for the attribute, not this value.
92      */

93     public void addToAttributeOnlyConversionValue(Object JavaDoc fieldValue, Object JavaDoc attributeValue) {
94         if (fieldValue == null) {
95             fieldValue = Helper.getNullWrapper();
96         }
97
98         if (attributeValue == null) {
99             attributeValue = Helper.getNullWrapper();
100         }
101
102         getFieldToAttributeValues().put(fieldValue, attributeValue);
103     }
104
105     /**
106      * INTERNAL:
107      * Get the attribute to field mapping.
108      */

109     public Map getAttributeToFieldValues() {
110         return attributeToFieldValues;
111     }
112
113     /**
114      * INTERNAL:
115      * Convert all the class-name-based settings in this converter to actual
116      * class-based settings. This method is used when converting a project
117      * that has been built with class names to a project with classes.
118      * @param classLoader
119      */

120     public void convertClassNamesToClasses(ClassLoader JavaDoc classLoader){
121         // Does nothing right now but was implemented since EnumTypeConverter
122
// is dependent on this method but we need to avoid JDK 1.5
123
// dependencies. AbstractDirectMapping will call this method.
124
}
125     
126     /**
127      * INTERNAL:
128      * Returns the corresponding attribute value for the specified field value.
129      */

130     public Object JavaDoc convertDataValueToObjectValue(Object JavaDoc fieldValue, Session session) {
131         Object JavaDoc attributeValue = null;
132
133         if (fieldValue == null) {
134             attributeValue = getFieldToAttributeValues().get(Helper.getNullWrapper());
135         } else {
136             try {
137                 fieldValue = ((AbstractSession)session).getDatasourcePlatform().getConversionManager().convertObject(fieldValue, getFieldClassification());
138             } catch (ConversionException e) {
139                 throw ConversionException.couldNotBeConverted(mapping, mapping.getDescriptor(), e);
140             }
141
142             attributeValue = getFieldToAttributeValues().get(fieldValue);
143             if (attributeValue == null) {
144                 if (getDefaultAttributeValue() != null) {
145                     attributeValue = getDefaultAttributeValue();
146                 } else {
147                     // CR#3779
148
throw DescriptorException.noFieldValueConversionToAttributeValueProvided(fieldValue, getMapping().getField(), getMapping());
149                 }
150             }
151         }
152         return attributeValue;
153     }
154
155     /**
156      * PUBLIC:
157      * The default value can be used if the database can possibly store additional values then those that
158      * have been mapped. Any value retreived from the database that is not mapped will be substitued for the default value.
159      */

160     public Object JavaDoc getDefaultAttributeValue() {
161         return defaultAttributeValue;
162     }
163
164     /**
165      * INTERNAL:
166      * Return the mapping.
167      */

168     protected DatabaseMapping getMapping() {
169         return mapping;
170     }
171
172     /**
173      * INTERNAL:
174      * Set the mapping.
175      */

176     protected void setMapping(DatabaseMapping mapping) {
177         this.mapping = mapping;
178     }
179
180     /**
181      * INTERNAL:
182      * Get the type of the field value to allow conversion from the database.
183      */

184     public Class JavaDoc getFieldClassification() {
185         return fieldClassification;
186     }
187
188     public String JavaDoc getFieldClassificationName() {
189         if ((fieldClassificationName == null) && (fieldClassification != null)) {
190             fieldClassificationName = fieldClassification.getName();
191         }
192         return fieldClassificationName;
193     }
194
195     /**
196      * INTERNAL:
197      * Return the classifiction for the field contained in the mapping.
198      * This is used to convert the row value to a consistent java value.
199      * By default this is null which means unknown.
200      */

201     public Class JavaDoc getFieldClassification(DatabaseField fieldToClassify) {
202         return getFieldClassification();
203     }
204
205     /**
206      * INTERNAL:
207      * Get the field to attribute mapping.
208      */

209     public Map getFieldToAttributeValues() {
210         return fieldToAttributeValues;
211     }
212
213     /**
214      * INTERNAL:
215      * Convert to the data value.
216      */

217     public Object JavaDoc convertObjectValueToDataValue(Object JavaDoc attributeValue, Session session) {
218         Object JavaDoc fieldValue;
219         if (attributeValue == null) {
220             fieldValue = getAttributeToFieldValues().get(Helper.getNullWrapper());
221         } else {
222             fieldValue = getAttributeToFieldValues().get(attributeValue);
223             if (fieldValue == null) {
224                 throw DescriptorException.noAttributeValueConversionToFieldValueProvided(attributeValue, getMapping());
225             }
226         }
227         return fieldValue;
228     }
229
230     /**
231      * INTERNAL:
232      */

233     public boolean isObjectTypeMapping() {
234         return true;
235     }
236
237     /**
238      * PUBLIC:
239      * This is a very specific protocol which maps fieldValues "T" and "F"
240      * to true and false respectively.
241      */

242     public void mapBooleans() {
243         addConversionValue("F", new Boolean JavaDoc(false));
244         addConversionValue("T", new Boolean JavaDoc(true));
245     }
246
247     /**
248      * PUBLIC:
249      * This is a very specific protocol which maps fieldValues "F" and "M"
250      * to "Female" and "Male" respectively.
251      */

252     public void mapGenders() {
253         addConversionValue("F", "Female");
254         addConversionValue("M", "Male");
255     }
256
257     /**
258      * PUBLIC:
259      * This is a very specific protocol which maps fieldValues "Y" and "N"
260      * to "Yes" and "No" respectively.
261      */

262     public void mapResponses() {
263         addConversionValue("Y", "Yes");
264         addConversionValue("N", "No");
265     }
266
267     /**
268      * INTERNAL:
269      * Set the field classification through searching the fields hashtable.
270      */

271     public void initializeFieldClassification(Session session) throws DescriptorException {
272         if (getFieldToAttributeValues().isEmpty()) {
273             return;
274         }
275         Class JavaDoc type = null;
276         Iterator fieldValuesEnum = getFieldToAttributeValues().keySet().iterator();
277         while (fieldValuesEnum.hasNext() && (type == null)) {
278             Object JavaDoc value = fieldValuesEnum.next();
279             if (value != Helper.getNullWrapper()) {
280                 type = value.getClass();
281             }
282         }
283
284         setFieldClassification(type);
285         // CR#... Mapping must also have the field classification.
286
if (getMapping().isDirectToFieldMapping()) {
287             AbstractDirectMapping directMapping = (AbstractDirectMapping)getMapping();
288
289             // Allow user to specify field type to override computed value. (i.e. blob, nchar)
290
if (directMapping.getFieldClassification() == null) {
291                 directMapping.setFieldClassification(type);
292             }
293         }
294     }
295
296     /**
297      * INTERNAL:
298      * Set the mapping.
299      */

300     public void initialize(DatabaseMapping mapping, Session session) {
301         this.mapping = mapping;
302         initializeFieldClassification(session);
303     }
304
305     /**
306      * INTERNAL:
307      * Set the attribute to field mapping.
308      */

309     public void setAttributeToFieldValues(Map attributeToFieldValues) {
310         this.attributeToFieldValues = attributeToFieldValues;
311     }
312
313     /**
314      * PUBLIC:
315      * The default value can be used if the database can possibly store additional values then those that
316      * have been mapped. Any value retreived from the database that is not mapped will be substitued for the default value.
317      */

318     public void setDefaultAttributeValue(Object JavaDoc defaultAttributeValue) {
319         this.defaultAttributeValue = defaultAttributeValue;
320     }
321
322     /**
323      * INTERNAL:
324      * Set the type of the field value to allow conversion from the database.
325      */

326     public void setFieldClassification(Class JavaDoc fieldClassification) {
327         this.fieldClassification = fieldClassification;
328     }
329
330     public void setFieldClassificationName(String JavaDoc fieldClassificationName) {
331         this.fieldClassificationName = fieldClassificationName;
332     }
333
334     /**
335      * INTERNAL:
336      * Set a collection of the field to attribute value associations.
337      */

338     public void setFieldToAttributeValueAssociations(Vector fieldToAttributeValueAssociations) {
339         setFieldToAttributeValues(new Hashtable(fieldToAttributeValueAssociations.size() + 1));
340         setAttributeToFieldValues(new Hashtable(fieldToAttributeValueAssociations.size() + 1));
341         for (Enumeration associationsEnum = fieldToAttributeValueAssociations.elements();
342                  associationsEnum.hasMoreElements();) {
343             Association association = (Association)associationsEnum.nextElement();
344             addConversionValue(association.getKey(), association.getValue());
345         }
346     }
347
348     /**
349      * INTERNAL:
350      * Set the field to attribute mapping.
351      */

352     public void setFieldToAttributeValues(Map fieldToAttributeValues) {
353         this.fieldToAttributeValues = fieldToAttributeValues;
354     }
355
356     /**
357      * INTERNAL:
358      * If the converter converts the value to a non-atomic value, i.e.
359      * a value that can have its' parts changed without being replaced,
360      * then it must return false, serialization can be non-atomic.
361      */

362     public boolean isMutable() {
363         return false;
364     }
365 }
366
Popular Tags