001: /******************************************************************
002: Copyright (c) 2004 Andy Jefferson and others. All rights reserved.
003: Licensed under the Apache License, Version 2.0 (the "License");
004: you may not use this file except in compliance with the License.
005: You may obtain a copy of the License at
006:
007: http://www.apache.org/licenses/LICENSE-2.0
008:
009: Unless required by applicable law or agreed to in writing, software
010: distributed under the License is distributed on an "AS IS" BASIS,
011: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012: See the License for the specific language governing permissions and
013: limitations under the License.
014:
015:
016: Contributors:
017: ...
018: *****************************************************************/package org.jpox.store.mapping;
019:
020: import org.jpox.ClassLoaderResolver;
021: import org.jpox.ClassNameConstants;
022: import org.jpox.TypeManager;
023: import org.jpox.api.ApiAdapter;
024: import org.jpox.exceptions.JPOXException;
025: import org.jpox.exceptions.JPOXUserException;
026: import org.jpox.metadata.AbstractClassMetaData;
027: import org.jpox.metadata.AbstractMemberMetaData;
028: import org.jpox.plugin.PluginManager;
029: import org.jpox.store.DatastoreAdapter;
030: import org.jpox.store.DatastoreClass;
031: import org.jpox.store.DatastoreContainerObject;
032: import org.jpox.store.StoreManager;
033: import org.jpox.store.exceptions.NoTableManagedException;
034: import org.jpox.util.JPOXLogger;
035: import org.jpox.util.Localiser;
036:
037: /**
038: * Base implementation of a MappingManager. Datastores should extend this to add their own specifics, and to
039: * add the initialisation of their supported types.
040: * <P>
041: * The idea behind a MappingManager is that at the Java side we have a series of Java type mappings,
042: * and at the datastore side we have a series of datastore type mappings. We need a link between the two
043: * to say that "this Java type can map to any of these 3 datastore types, and by default use this one".
044: *
045: * @version $Revision: 1.77 $
046: */
047: public abstract class AbstractMappingManager implements MappingManager {
048: protected static final Localiser LOCALISER = Localiser
049: .getInstance("org.jpox.store.Localisation");
050:
051: /**
052: * Default constructor.
053: */
054: public AbstractMappingManager() {
055: }
056:
057: /**
058: * Load all datastore mappings defined in the associated plugins.
059: * To be implemented by the datastore mapping managers since they have the knowledge of
060: * the attributes supported by that datastore (e.g RDBMS datastores use jdbc-type, sql-type)
061: * @param mgr the PluginManager
062: * @param clr the ClassLoaderResolver
063: * @param vendorId the datastore vendor id
064: */
065: public abstract void loadDatastoreMapping(PluginManager mgr,
066: ClassLoaderResolver clr, String vendorId);
067:
068: /**
069: * Accessor for the mapping for the specified class.
070: * TODO Merge this with the method below, or at least say why use this or the other
071: * @param c Java type
072: * @param serialised Whether the type is serialised
073: * @param embedded Whether the type is embedded
074: * @param storeMgr Manager for the datastore
075: * @param fieldName Name of the field (for logging)
076: * @return The mapping for the class.
077: */
078: public JavaTypeMapping getMapping(Class c, boolean serialised,
079: boolean embedded, StoreManager storeMgr, String fieldName) {
080: Class mc = getMappingClass(c, serialised, embedded, fieldName,
081: storeMgr.getOMFContext().getTypeManager(), storeMgr
082: .getApiAdapter());
083: mc = getOverrideMappingClass(mc, null, -1); // Allow for overriding in subclasses
084:
085: JavaTypeMapping m = MappingFactory.createMapping(mc, storeMgr
086: .getDatastoreAdapter(), c.getName());
087: if (m == null) {
088: String name = mc.getName();
089: name = name.substring(name.lastIndexOf('.') + 1);
090:
091: throw new JPOXUserException(LOCALISER.msg("041012", name));
092: }
093: return m;
094: }
095:
096: /**
097: * Accessor for the mapping for the specified class.
098: * Usually only called by JDOQL query expressions.
099: * @param c Java type
100: * @param serialised Whether the type is serialised
101: * @param embedded Whether the type is embedded
102: * @param storeMgr Manager for the store
103: * @param clr ClassLoader resolver
104: * @return The mapping for the class.
105: */
106: public JavaTypeMapping getMapping(Class c, boolean serialised,
107: boolean embedded, StoreManager storeMgr,
108: ClassLoaderResolver clr) {
109: JavaTypeMapping m;
110: try {
111: // TODO This doesnt take into account serialised/embedded
112: DatastoreClass datastoreClass = storeMgr.getDatastoreClass(
113: c.getName(), clr);
114: m = datastoreClass.getIDMapping();
115: } catch (NoTableManagedException ex) {
116: // Note that this doesnt allow for whether a field is serialised or embedded so they get the default mapping only
117: Class mc = getMappingClass(c, serialised, embedded, null,
118: storeMgr.getOMFContext().getTypeManager(), storeMgr
119: .getApiAdapter());
120: mc = getOverrideMappingClass(mc, null, -1); // Allow for overriding in subclasses
121: m = MappingFactory.createMapping(mc, storeMgr
122: .getDatastoreAdapter(), c.getName());
123: if (m == null) {
124: String name = mc.getName();
125: name = name.substring(name.lastIndexOf('.') + 1);
126:
127: throw new JPOXUserException(LOCALISER.msg("041012",
128: name));
129: }
130: if (m instanceof SimpleDatastoreRepresentation) {
131: createDatastoreMapping(m, storeMgr, null, m
132: .getJavaTypeForDatastoreMapping(0));
133: }
134: }
135: return m;
136: }
137:
138: /**
139: * Accessor for the mapping for the field of the specified table.
140: * Can be used for fields of a class, elements of a collection of a class, elements of an array of
141: * a class, keys of a map of a class, values of a map of a class. This is controlled by the final
142: * argument "roleForField".
143: * @param datastoreContainer Table to add the mapping to
144: * @param fmd FieldMetaData for the field to map
145: * @param dba Datastore adapter
146: * @param clr The ClassLoaderResolver
147: * @param roleForField Role that this mapping plays for the field
148: * @return The mapping for the field.
149: */
150: public JavaTypeMapping getMapping(
151: DatastoreContainerObject datastoreContainer,
152: AbstractMemberMetaData fmd, DatastoreAdapter dba,
153: ClassLoaderResolver clr, int roleForField) {
154: Class mc = null;
155:
156: String userMappingClassName = fmd
157: .getValueForExtension("mapping-class");
158: if (userMappingClassName != null
159: && roleForField != JavaTypeMapping.MAPPING_ARRAY_ELEMENT
160: && roleForField != JavaTypeMapping.MAPPING_COLLECTION_ELEMENT
161: && roleForField != JavaTypeMapping.MAPPING_MAP_KEY
162: && roleForField != JavaTypeMapping.MAPPING_MAP_VALUE) {
163: // User has defined their own mapping class for this field so use that
164: try {
165: mc = clr.classForName(userMappingClassName);
166: } catch (JPOXException jpe) {
167: throw new JPOXUserException(LOCALISER.msg("041014",
168: userMappingClassName)).setFatal();
169: }
170: } else if (roleForField == JavaTypeMapping.MAPPING_COLLECTION_ELEMENT
171: || roleForField == JavaTypeMapping.MAPPING_ARRAY_ELEMENT) {
172: // Mapping a collection/array element (in a join table)
173: mc = getElementMappingClass(datastoreContainer, fmd, dba,
174: clr);
175: } else if (roleForField == JavaTypeMapping.MAPPING_MAP_KEY) {
176: // Mapping a map key (in a join table)
177: mc = getKeyMappingClass(datastoreContainer, fmd, dba, clr);
178: } else if (roleForField == JavaTypeMapping.MAPPING_MAP_VALUE) {
179: // Mapping a map value (in a join table)
180: mc = getValueMappingClass(datastoreContainer, fmd, dba, clr);
181: } else {
182: // Assumed to be a normal field
183: AbstractClassMetaData acmd = null;
184: if (fmd.getType().isInterface()) {
185: acmd = datastoreContainer.getStoreManager()
186: .getMetaDataManager().getMetaDataForInterface(
187: fmd.getType(), clr);
188: } else {
189: acmd = datastoreContainer.getStoreManager()
190: .getMetaDataManager().getMetaDataForClass(
191: fmd.getType(), clr);
192: }
193: StoreManager storeMgr = datastoreContainer
194: .getStoreManager();
195: TypeManager typeMgr = storeMgr.getOMFContext()
196: .getTypeManager();
197:
198: if (fmd.isSerialized()) {
199: // Field is marked as serialised then we have no other option - serialise it
200: mc = getMappingClass(fmd.getType(), true, false, fmd
201: .getFullFieldName(), typeMgr, storeMgr
202: .getApiAdapter());
203: } else if (fmd.getEmbeddedMetaData() != null) {
204: // Field has an <embedded> specification so use that
205: mc = getMappingClass(fmd.getType(), false, true, fmd
206: .getFullFieldName(), typeMgr, storeMgr
207: .getApiAdapter());
208: } else if (acmd != null && acmd.isEmbeddedOnly()) {
209: // If the reference type is declared with embedded only
210: mc = getMappingClass(fmd.getType(), false, true, fmd
211: .getFullFieldName(), typeMgr, storeMgr
212: .getApiAdapter());
213: } else if (fmd.isEmbedded()) {
214: // Otherwise, if the field is embedded then we request that it be serialised into the owner table
215: // This is particularly for java.lang.Object which should be "embedded" by default, and hence serialised
216: mc = getMappingClass(fmd.getType(), true, false, fmd
217: .getFullFieldName(), typeMgr, storeMgr
218: .getApiAdapter());
219: } else {
220: // Just get the basic mapping for the type
221: mc = getMappingClass(fmd.getType(), false, false, fmd
222: .getFullFieldName(), typeMgr, storeMgr
223: .getApiAdapter());
224: }
225: }
226: mc = getOverrideMappingClass(mc, fmd, roleForField); // Allow for overriding in subclasses
227:
228: // Create the mapping of the selected type
229: JavaTypeMapping m = MappingFactory.createMapping(mc, dba, fmd,
230: roleForField, datastoreContainer, clr);
231: if (m == null) {
232: throw new JPOXException(LOCALISER.msg("041011", mc
233: .getName())).setFatal();
234: }
235:
236: return m;
237: }
238:
239: /**
240: * Convenience method to allow overriding of particular mapping classes.
241: * @param mappingClass The mapping class selected
242: * @param fmd Field meta data for the field (if appropriate)
243: * @param roleForField Role for the field (e.g collection element)
244: * @return The mapping class to use
245: */
246: protected Class getOverrideMappingClass(Class mappingClass,
247: AbstractMemberMetaData fmd, int roleForField) {
248: return mappingClass;
249: }
250:
251: /**
252: * Accessor for the mapping class for the specified class.
253: * Provides special handling for interface types and for classes that are
254: * being embedded in a field (detected using the FieldMetaData argument).
255: * Refers others to its mapping manager lookup.
256: * @param c Class to query
257: * @param serialised Whether the field is serialised
258: * @param embedded Whether the field is embedded
259: * @param fieldName The full field name (for logging only)
260: * @param typeMgr the TypeManager
261: * @param api API Adapter
262: * @return The mapping class for the class
263: **/
264: protected Class getMappingClass(Class c, boolean serialised,
265: boolean embedded, String fieldName, TypeManager typeMgr,
266: ApiAdapter api) {
267: if (api.isPersistable(c)) {
268: // Persistence Capable field
269: if (serialised) {
270: // Serialised PC field
271: return SerialisedPCMapping.class;
272: } else if (embedded) {
273: // Embedded PC field
274: return EmbeddedPCMapping.class;
275: } else {
276: // PC field
277: return PersistenceCapableMapping.class;
278: }
279: }
280:
281: if (c.isInterface() && !typeMgr.isSupportedType(c.getName())) {
282: // Interface field
283: if (serialised) {
284: // Serialised Interface field
285: return SerialisedReferenceMapping.class;
286: } else if (embedded) {
287: // Interface field
288: //return InterfaceMapping.class;
289: return EmbeddedPCMapping.class;
290: // Embedded Interface field - anyone want to support these ? I don't ;-)
291: // throw new JPOXUserException(LOCALISER.msg("041041", fieldName));
292: } else {
293: // Interface field
294: return InterfaceMapping.class;
295: }
296: }
297:
298: if (c == java.lang.Object.class) {
299: // Object field
300: if (serialised) {
301: // Serialised Object field
302: return SerialisedReferenceMapping.class;
303: } else if (embedded) {
304: // Embedded Object field - do we ever want to support this ? I think not ;-)
305: throw new JPOXUserException(LOCALISER.msg("041042",
306: fieldName)).setFatal();
307: } else {
308: // Object field as reference to PC object
309: return ObjectMapping.class;
310: }
311: }
312:
313: if (c.isArray()) {
314: // Array field
315: if (api.isPersistable(c.getComponentType())) {
316: // Array of PC objects
317: return ArrayMapping.class;
318: } else if (c.getComponentType().isInterface()
319: && !typeMgr.isSupportedType(c.getComponentType()
320: .getName())) {
321: // Array of interface objects
322: return ArrayMapping.class;
323: } else if (c.getComponentType() == java.lang.Object.class) {
324: // Array of Object reference objects
325: return ArrayMapping.class;
326: }
327: // Other array types will be caught by the default mappings
328: }
329:
330: // Try the default mapping (doesnt allow for serialised setting)
331: Class mappingClass = getDefaultJavaTypeMapping(typeMgr, c);
332: if (mappingClass == null) {
333: Class super Class = c.getSuperclass();
334: while (super Class != null
335: && !super Class.getName().equals(
336: ClassNameConstants.Object)
337: && mappingClass == null) {
338: mappingClass = getDefaultJavaTypeMapping(typeMgr,
339: super Class);
340: super Class = super Class.getSuperclass();
341: }
342: }
343: if (mappingClass == null) {
344: if (typeMgr.isSupportedType(c.getName())) {
345: // "supported" type yet no FCO mapping !
346: throw new JPOXUserException(LOCALISER.msg("041001",
347: fieldName, c.getName()));
348: } else {
349: Class super Class = c; // start in this class
350: while (super Class != null
351: && !super Class.getName().equals(
352: ClassNameConstants.Object)
353: && mappingClass == null) {
354: Class[] interfaces = super Class.getInterfaces();
355: for (int i = 0; i < interfaces.length
356: && mappingClass == null; i++) {
357: mappingClass = getDefaultJavaTypeMapping(
358: typeMgr, interfaces[i]);
359: }
360: super Class = super Class.getSuperclass();
361: }
362: if (mappingClass == null) {
363: //TODO if serialised == false, should we raise an exception?
364: // Treat as serialised
365: mappingClass = SerialisedMapping.class;
366: }
367: }
368: }
369: return mappingClass;
370: }
371:
372: /**
373: * Convenience accessor for the mapping class of the element mapping for a collection/array of PC elements.
374: * Currently only used where the collection/array elements are either serialised or embedded into a join table.
375: * @param container The container
376: * @param fmd MetaData for the collection field containing the collection/array of PCs
377: * @param dba Database adapter
378: * @param clr ClassLoader resolver
379: * @return The mapping class
380: */
381: protected Class getElementMappingClass(
382: DatastoreContainerObject container,
383: AbstractMemberMetaData fmd, DatastoreAdapter dba,
384: ClassLoaderResolver clr) {
385: if (!fmd.hasCollection() && !fmd.hasArray()) {
386: // TODO Localise this message
387: throw new JPOXException(
388: "Attempt to get element mapping for field "
389: + fmd.getFullFieldName()
390: + " that has no collection/array!")
391: .setFatal();
392: }
393: if (fmd.getJoinMetaData() == null) {
394: throw new JPOXException(
395: "Attempt to get element mapping for field "
396: + fmd.getFullFieldName()
397: + " that has no join table defined for the collection/array")
398: .setFatal();
399: }
400:
401: String userMappingClassName = null;
402: if (fmd.getElementMetaData() != null) {
403: userMappingClassName = fmd.getElementMetaData()
404: .getValueForExtension("mapping-class");
405: }
406: if (userMappingClassName != null) {
407: // User has defined their own mapping class for this element so use that
408: try {
409: return clr.classForName(userMappingClassName);
410: } catch (JPOXException jpe) {
411: throw new JPOXUserException(LOCALISER.msg("041014",
412: userMappingClassName)).setFatal();
413: }
414: }
415:
416: boolean serialised = ((fmd.hasCollection() && fmd
417: .getCollection().isSerializedElement()) || (fmd
418: .hasArray() && fmd.getArray().isSerializedElement()));
419: boolean embeddedPC = (fmd.getElementMetaData() != null && fmd
420: .getElementMetaData().getEmbeddedMetaData() != null);
421: boolean elementPC = ((fmd.hasCollection() && fmd
422: .getCollection().getElementClassMetaData() != null) || (fmd
423: .hasArray() && fmd.getArray().getElementClassMetaData() != null));
424: boolean embedded = true;
425: if (fmd.hasCollection()) {
426: embedded = fmd.getCollection().isEmbeddedElement();
427: } else if (fmd.hasArray()) {
428: embedded = fmd.getArray().isEmbeddedElement();
429: }
430:
431: TypeManager typeMgr = fmd.getMetaDataManager().getOMFContext()
432: .getTypeManager();
433: Class elementCls = null;
434: if (fmd.hasCollection()) {
435: elementCls = clr.classForName(fmd.getCollection()
436: .getElementType());
437: } else if (fmd.hasArray()) {
438: elementCls = clr.classForName(fmd.getArray()
439: .getElementType());
440: }
441: boolean elementReference = typeMgr.isReferenceType(elementCls);
442:
443: Class mc = null;
444: if (serialised) {
445: if (elementPC) {
446: // Serialised PC element
447: mc = SerialisedElementPCMapping.class;
448: } else if (elementReference) {
449: // Serialised Reference element
450: mc = SerialisedReferenceMapping.class;
451: } else {
452: // Serialised Non-PC element
453: mc = SerialisedMapping.class;
454: }
455: } else if (embedded) {
456: if (embeddedPC) {
457: // Embedded PC type
458: mc = EmbeddedElementPCMapping.class;
459: } else if (elementPC) {
460: // "Embedded" PC type but no <embedded> so dont embed for now. Is this correct?
461: mc = PersistenceCapableMapping.class;
462: } else {
463: // Embedded Non-PC type
464: mc = getMappingClass(elementCls, serialised, embedded,
465: fmd.getFullFieldName(), typeMgr, container
466: .getStoreManager().getApiAdapter());
467: }
468: } else {
469: // TODO Allow for other element mappings
470: throw new JPOXException(
471: "Attempt to get element mapping for field "
472: + fmd.getFullFieldName()
473: + " when not embedded or serialised - please report this to JPOX developers")
474: .setFatal();
475: }
476:
477: return mc;
478: }
479:
480: /**
481: * Convenience accessor for the mapping class of the key mapping for a map of PC keys.
482: * Currently only used where the keys are either serialised or embedded into a join table.
483: * @param container The container
484: * @param fmd MetaData for the field containing the map that this key is for
485: * @param dba Database adapter
486: * @param clr ClassLoader resolver
487: * @return The mapping class
488: */
489: protected Class getKeyMappingClass(
490: DatastoreContainerObject container,
491: AbstractMemberMetaData fmd, DatastoreAdapter dba,
492: ClassLoaderResolver clr) {
493: if (fmd.getMap() == null) {
494: throw new JPOXException(
495: "Attempt to get key mapping for field that has no map!")
496: .setFatal();
497: }
498:
499: String userMappingClassName = null;
500: if (fmd.getKeyMetaData() != null) {
501: userMappingClassName = fmd.getKeyMetaData()
502: .getValueForExtension("mapping-class");
503: }
504: if (userMappingClassName != null) {
505: // User has defined their own mapping class for this key so use that
506: try {
507: return clr.classForName(userMappingClassName);
508: } catch (JPOXException jpe) {
509: throw new JPOXUserException(LOCALISER.msg("041014",
510: userMappingClassName)).setFatal();
511: }
512: }
513:
514: boolean serialised = (fmd.hasMap() && fmd.getMap()
515: .isSerializedKey());
516: boolean embedded = (fmd.hasMap() && fmd.getMap()
517: .isEmbeddedKey());
518: boolean embeddedPC = (fmd.getKeyMetaData() != null && fmd
519: .getKeyMetaData().getEmbeddedMetaData() != null);
520: boolean keyPC = (fmd.hasMap() && fmd.getMap()
521: .getKeyClassMetaData() != null);
522: TypeManager typeMgr = fmd.getMetaDataManager().getOMFContext()
523: .getTypeManager();
524: Class keyCls = clr.classForName(fmd.getMap().getKeyType());
525: boolean keyReference = typeMgr.isReferenceType(keyCls);
526:
527: Class mc = null;
528: if (serialised) {
529: if (keyPC) {
530: // Serialised PC key
531: mc = SerialisedKeyPCMapping.class;
532: } else if (keyReference) {
533: // Serialised Reference key
534: mc = SerialisedReferenceMapping.class;
535: } else {
536: // Serialised Non-PC element
537: mc = SerialisedMapping.class;
538: }
539: } else if (embedded) {
540: if (embeddedPC) {
541: // Embedded PC key
542: mc = EmbeddedKeyPCMapping.class;
543: } else if (keyPC) {
544: // "Embedded" PC type but no <embedded> so dont embed for now. Is this correct?
545: mc = PersistenceCapableMapping.class;
546: } else {
547: // Embedded Non-PC type
548: mc = getMappingClass(keyCls, serialised, embedded, fmd
549: .getFullFieldName(), typeMgr, container
550: .getStoreManager().getApiAdapter());
551: }
552: } else {
553: // TODO Allow for other key mappings
554: throw new JPOXException(
555: "Attempt to get key mapping for field "
556: + fmd.getFullFieldName()
557: + " when not embedded or serialised - please report this to JPOX developers")
558: .setFatal();
559: }
560:
561: return mc;
562: }
563:
564: /**
565: * Convenience accessor for the mapping class of the value mapping for a map of PC values.
566: * Currently only used where the value are either serialised or embedded into a join table.
567: * @param container The container
568: * @param fmd MetaData for the field containing the map that this value is for
569: * @param dba Database adapter
570: * @param clr ClassLoader resolver
571: * @return The mapping class
572: */
573: protected Class getValueMappingClass(
574: DatastoreContainerObject container,
575: AbstractMemberMetaData fmd, DatastoreAdapter dba,
576: ClassLoaderResolver clr) {
577: if (fmd.getMap() == null) {
578: throw new JPOXException(
579: "Attempt to get value mapping for field that has no map!")
580: .setFatal();
581: }
582:
583: String userMappingClassName = null;
584: if (fmd.getValueMetaData() != null) {
585: userMappingClassName = fmd.getValueMetaData()
586: .getValueForExtension("mapping-class");
587: }
588: if (userMappingClassName != null) {
589: // User has defined their own mapping class for this value so use that
590: try {
591: return clr.classForName(userMappingClassName);
592: } catch (JPOXException jpe) {
593: throw new JPOXUserException(LOCALISER.msg("041014",
594: userMappingClassName)).setFatal();
595: }
596: }
597:
598: boolean serialised = (fmd.hasMap() && fmd.getMap()
599: .isSerializedValue());
600: boolean embedded = (fmd.hasMap() && fmd.getMap()
601: .isEmbeddedValue());
602: boolean embeddedPC = (fmd.getValueMetaData() != null && fmd
603: .getValueMetaData().getEmbeddedMetaData() != null);
604: boolean valuePC = (fmd.hasMap() && fmd.getMap()
605: .getValueClassMetaData() != null);
606: TypeManager typeMgr = fmd.getMetaDataManager().getOMFContext()
607: .getTypeManager();
608: Class valueCls = clr.classForName(fmd.getMap().getValueType());
609: boolean valueReference = typeMgr.isReferenceType(valueCls);
610:
611: Class mc = null;
612: if (serialised) {
613: if (valuePC) {
614: // Serialised PC value
615: mc = SerialisedValuePCMapping.class;
616: } else if (valueReference) {
617: // Serialised Reference value
618: mc = SerialisedReferenceMapping.class;
619: } else {
620: // Serialised Non-PC element
621: mc = SerialisedMapping.class;
622: }
623: } else if (embedded) {
624: if (embeddedPC) {
625: // Embedded PC key
626: mc = EmbeddedValuePCMapping.class;
627: } else if (valuePC) {
628: // "Embedded" PC type but no <embedded> so dont embed for now. Is this correct?
629: mc = PersistenceCapableMapping.class;
630: } else {
631: // Embedded Non-PC type
632: mc = getMappingClass(valueCls, serialised, embedded,
633: fmd.getFullFieldName(), typeMgr, container
634: .getStoreManager().getApiAdapter());
635: }
636: } else {
637: // TODO Allow for other value mappings
638: throw new JPOXException(
639: "Attempt to get value mapping for field "
640: + fmd.getFullFieldName()
641: + " when not embedded or serialised - please report this to JPOX developers")
642: .setFatal();
643: }
644:
645: return mc;
646: }
647:
648: /**
649: * Method to return the default java type mapping class for a specified java type.
650: * @param javaType java type
651: * @param typeMgr the TypeManager
652: * @return The mapping class to use (by default)
653: */
654: protected Class getDefaultJavaTypeMapping(TypeManager typeMgr,
655: Class javaType) {
656: Class cls = typeMgr.getMappingType(javaType.getName());
657: if (cls == null) {
658: JPOXLogger.PERSISTENCE.debug(LOCALISER.msg("041000",
659: javaType.getName()));
660: return null;
661: }
662: return cls;
663: }
664:
665: /**
666: * Utility to register a datastore mapping for a java type, and the SQL/JDBC types it can be mapped to.
667: * This can also be called to change the default setting of a mapping - just supply the same
668: * values of java/JDBC/SQL types and a different default value
669: * @param javaTypeName Name of the java type
670: * @param datastoreMappingType The datastore mapping
671: * @param jdbcType The JDBC type that can be used
672: * @param sqlType The SQL type that can be used
673: * @param dflt Whether this type should be used as the default mapping for this Java type
674: */
675: public abstract void registerDatastoreMapping(String javaTypeName,
676: Class datastoreMappingType, String jdbcType,
677: String sqlType, boolean dflt);
678:
679: protected class TypeMapping {
680: Class javaMappingType;
681:
682: boolean isDefault;
683:
684: /**
685: * Constructor
686: * @param javaMappingType Mapping type to use for thie java type
687: * @param isDefault Whether it is the default mapping for this java type
688: */
689: public TypeMapping(Class javaMappingType, boolean isDefault) {
690: this .javaMappingType = javaMappingType;
691: this .isDefault = isDefault;
692: }
693:
694: /**
695: * @return Returns the isDefault.
696: */
697: public boolean isDefault() {
698: return isDefault;
699: }
700:
701: /**
702: * Mutator for whether this is the default datastore mapping for the mapping
703: * @param isDefault Whether it is the default.
704: */
705: public void setDefault(boolean isDefault) {
706: this .isDefault = isDefault;
707: }
708:
709: /**
710: * @return Returns the mappingType.
711: */
712: public Class getMappingType() {
713: return javaMappingType;
714: }
715: }
716: }
|