/** * Construct a new field descriptor for the specified field. * * @param fieldName The field name * @param typeInfo The field type information * @param handler The field handler (may be null) * @param trans True if the field is transient */ public JDOFieldDescriptorImpl( final String fieldName, final TypeInfo typeInfo, final FieldHandler handler, final boolean trans, final String[] sqlName, final int[] sqlType, final String manyTable, final String[] manyKey, final boolean dirtyCheck, final boolean readonly) { super(); if (fieldName == null) { throw new IllegalArgumentException("Argument 'fieldName' is null"); } if (handler == null) { throw new IllegalArgumentException("Argument 'fieldDesc' has no handler"); } setFieldName(fieldName); setFieldType(typeInfo.getFieldType()); setHandler(handler); setTransient(trans); setImmutable(typeInfo.isImmutable()); setRequired(typeInfo.isRequired()); setMultivalued(typeInfo.getCollectionHandler() != null); _convertor = typeInfo.getConvertorFrom(); _sqlName = (sqlName.length == 0 ? null : sqlName); _sqlType = sqlType; _manyTable = manyTable; _manyKey = (manyKey.length > 0 ? manyKey : null); _dirtyCheck = dirtyCheck; _readonly = readonly; }
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; }