/** * Returns the CollectionHandler associated with the given collection, or null if no such handler * exists. * * @param clazz the Class to check * @return the CollectionHandler for the associated type. */ public CollectionHandler getCollectionHandler(final Class clazz) { CollectionHandler handler = null; try { handler = CollectionHandlers.getHandler(clazz); } catch (MappingException mx) { // -- Not a collection, or no handler exists, return null. } return handler; } // -- getCollectionHandler
protected FieldDescriptorImpl createFieldDesc(final Class javaClass, final FieldMapping fieldMap) throws MappingException { // If not an SQL field, return a stock field descriptor. Sql sql = fieldMap.getSql(); if (sql == null) { return super.createFieldDesc(javaClass, fieldMap); } String fieldName = fieldMap.getName(); // If the field type is supplied, grab it and use it to locate the // field/accessor. Class fieldType = null; if (fieldMap.getType() != null) { fieldType = resolveType(fieldMap.getType()); } // If the field is declared as a collection, grab the collection type as // well and use it to locate the field/accessor. CollectionHandler colHandler = null; boolean isLazy = fieldMap.getLazy(); if (fieldMap.getCollection() != null) { Class colType = CollectionHandlers.getCollectionType(fieldMap.getCollection().toString()); colHandler = CollectionHandlers.getHandler(colType); if (colType.getName().equals("java.util.Iterator") && isLazy) { String err = "Lazy loading not supported for collection type 'iterator'"; throw new MappingException(err); } if (colType.getName().equals("java.util.Enumeration") && isLazy) { String err = "Lazy loading not supported for collection type 'enumerate'"; throw new MappingException(err); } } TypeInfo typeInfo = getTypeInfo(fieldType, colHandler, fieldMap); ExtendedFieldHandler exfHandler = null; FieldHandler handler = null; // -- check for user supplied FieldHandler if (fieldMap.getHandler() != null) { Class handlerClass = resolveType(fieldMap.getHandler()); if (!FieldHandler.class.isAssignableFrom(handlerClass)) { String err = "The class '" + fieldMap.getHandler() + "' must implement " + FieldHandler.class.getName(); throw new MappingException(err); } // -- get default constructor to invoke. We can't use the // -- newInstance method unfortunately becaue FieldHandler // -- overloads this method Constructor constructor = null; try { constructor = handlerClass.getConstructor(new Class[0]); handler = (FieldHandler) constructor.newInstance(new Object[0]); } catch (Exception except) { String err = "The class '" + handlerClass.getName() + "' must have a default public constructor."; throw new MappingException(err); } // -- ExtendedFieldHandler? if (handler instanceof ExtendedFieldHandler) { exfHandler = (ExtendedFieldHandler) handler; } // -- Fix for Castor JDO from Steve Vaughan, Castor JDO // -- requires FieldHandlerImpl or a ClassCastException // -- will be thrown... [KV 20030131 - also make sure this new handler // -- doesn't use it's own CollectionHandler otherwise // -- it'll cause unwanted calls to the getValue method during // -- unmarshalling] colHandler = typeInfo.getCollectionHandler(); typeInfo.setCollectionHandler(null); handler = new FieldHandlerImpl(handler, typeInfo); typeInfo.setCollectionHandler(colHandler); // -- End Castor JDO fix } boolean generalized = (exfHandler instanceof GeneralizedFieldHandler); // -- if generalized we need to change the fieldType to whatever // -- is specified in the GeneralizedFieldHandler so that the // -- correct getter/setter methods can be found FieldHandler custom = handler; if (generalized) { fieldType = ((GeneralizedFieldHandler) exfHandler).getFieldType(); } if (generalized || (handler == null)) { // -- create TypeInfoRef to get new TypeInfo from call // -- to createFieldHandler TypeInfoReference typeInfoRef = new TypeInfoReference(); typeInfoRef.typeInfo = typeInfo; handler = createFieldHandler(javaClass, fieldType, fieldMap, typeInfoRef); if (custom != null) { ((GeneralizedFieldHandler) exfHandler).setFieldHandler(handler); handler = custom; } else { typeInfo = typeInfoRef.typeInfo; } } String[] sqlName = sql.getName(); String[] sqlTypes = getSqlTypes(fieldMap); int[] sqlTypeNum; if (sqlTypes.length > 0) { sqlTypeNum = new int[sqlTypes.length]; for (int i = 0; i < sqlTypes.length; i++) { String sqlTypeString = definition2type(sqlTypes[i]); Class sqlType = SQLTypeInfos.sqlTypeName2javaType(sqlTypeString); if (_factory != null) { sqlType = _factory.adjustSqlType(sqlType); } sqlTypeNum[i] = SQLTypeInfos.javaType2sqlTypeNum(sqlType); } } else { Class sqlType = typeInfo.getFieldType(); if (_factory != null) { sqlType = _factory.adjustSqlType(sqlType); } sqlTypeNum = new int[] {SQLTypeInfos.javaType2sqlTypeNum(sqlType)}; } // create FieldDescriptor(Impl) instance, and apply JDO nature FieldDescriptorImpl fieldDescriptor = new FieldDescriptorImpl(fieldName, typeInfo, handler, fieldMap.getTransient()); fieldDescriptor.addNature(FieldDescriptorJDONature.class.getName()); fieldDescriptor.setRequired(fieldMap.getRequired()); // If we're using an ExtendedFieldHandler we need to set the FieldDescriptor if (exfHandler != null) { ((FieldHandlerFriend) exfHandler).setFieldDescriptor(fieldDescriptor); } // if SQL mapping declares transient // TODO: cross-check that this should be implemented like this if (sql.getTransient()) { fieldDescriptor.setTransient(true); } // set collection type as specified in mapping file fieldDescriptor.setCollection(fieldMap.getCollection()); fieldDescriptor.setComparator(fieldMap.getComparator()); fieldDescriptor.setCreateMethod(fieldMap.getCreateMethod()); fieldDescriptor.setGetMethod(fieldMap.getGetMethod()); fieldDescriptor.setSetMethod(fieldMap.getSetMethod()); fieldDescriptor.setDirect(fieldMap.getDirect()); // extract values for 'laziness' from field mapping fieldDescriptor.setLazy(isLazy); FieldDescriptorJDONature fieldJdoNature = new FieldDescriptorJDONature(fieldDescriptor); fieldJdoNature.setTypeConvertor(typeInfo.getConvertorFrom()); if (sqlName.length > 0) { fieldJdoNature.setSQLName(sqlName); } fieldJdoNature.setSQLType(sqlTypeNum); fieldJdoNature.setManyTable(sql.getManyTable()); if (sql.getManyKey().length > 0) { fieldJdoNature.setManyKey(sql.getManyKey()); } fieldJdoNature.setDirtyCheck(!SqlDirtyType.IGNORE.equals(sql.getDirty())); fieldJdoNature.setReadOnly(sql.getReadOnly()); fieldJdoNature.setCascading(sql.getCascading()); fieldJdoNature.setTransient(sql.getTransient()); return fieldDescriptor; }
/** * Returns true if the given Class is a considered a collection by the marshalling framework. * * @param clazz the Class to check * @return true if the given Class is considered a collection. TODO: joachim: this code exists * somewhere else too!! */ public static boolean isCollection(final Class clazz) { return CollectionHandlers.hasHandler(clazz); } // -- isCollection