/**
  * Walks through all fields of a descriptor and resolves relation {@link ClassDescriptor}s by
  * using mapping information or, if not present, resolution by file to support generated {@link
  * ClassDescriptor}s. Resolved {@link ClassDescriptor}s will be set as a field's descriptor.
  *
  * @param clsDesc The ClassDescriptor in focus.
  */
 protected void resolveRelations(final ClassDescriptor clsDesc) {
   FieldDescriptor[] fields = clsDesc.getFields();
   for (int i = 0; i < fields.length; ++i) {
     FieldDescriptor field = fields[i];
     ClassDescriptor desc = getDescriptor(field.getFieldType().getName());
     // Resolve ClassDescriptor from the file system as well.
     if (desc == null && !field.getFieldType().isPrimitive()) {
       ClassResolutionByFile resolutionCommand = new ClassResolutionByFile();
       resolutionCommand.addNature(ClassLoaderNature.class.getName());
       ClassLoaderNature clNature = new ClassLoaderNature(resolutionCommand);
       clNature.setClassLoader(getClassLoader());
       desc = resolutionCommand.resolve(field.getFieldType());
       ((FieldDescriptorImpl) field).setClassDescriptor(desc);
     }
     if ((desc != null) && (field instanceof FieldDescriptorImpl)) {
       ((FieldDescriptorImpl) field).setClassDescriptor(desc);
     }
   }
 }
Esempio n. 2
0
 /**
  * Construct a new field descriptor for the specified field. This is a JDO field descriptor
  * wrapping a field descriptor and adding JDO related properties and methods.
  *
  * @param fieldDesc The field descriptor
  * @throws MappingException Invalid mapping information
  */
 public JDOFieldDescriptor(
     FieldDescriptorImpl fieldDesc,
     String[] sqlName,
     int[] sqlType,
     boolean dirtyCheck,
     String manyTable,
     String[] manyKey)
     throws MappingException {
   super(fieldDesc);
   if (fieldDesc.isTransient() || fieldDesc.getHandler() == null)
     throw new IllegalArgumentException(
         "Argument 'fieldDesc' is a transient field or has no handler");
   // if ( sqlName == null )
   //    throw new IllegalArgumentException( "Argument 'sqlName' is null" );
   _sqlName = (sqlName.length == 0 ? null : sqlName);
   _dirtyCheck = dirtyCheck;
   _manyTable = manyTable;
   _manyKey = (manyKey.length > 0 ? manyKey : null);
   _sqlType = sqlType;
 }
  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;
  }