Esempio n. 1
0
  public void bind(Object value) {

    if (_expr == null && _spCall == null)
      throw new IllegalStateException("Must create query before using it");
    if (_fieldNum == _paramInfo.size())
      throw new IllegalArgumentException("Only " + _paramInfo.size() + " fields in this query");
    try {
      ParamInfo info = (ParamInfo) _paramInfo.get(new Integer(_fieldNum + 1));

      // do type checking and conversion
      Class paramClass = info.getTheClass();
      Class valueClass = value.getClass();
      Class numberClass = java.lang.Number.class;

      if (value != null && !paramClass.isAssignableFrom(valueClass))
        if (info.isUserDefined())
          // If the user specified a type they must pass that exact type.

          throw new IllegalArgumentException(
              "Query paramter "
                  + (_fieldNum + 1)
                  + " is not of the expected type "
                  + paramClass
                  + " it is an instance of the class "
                  + valueClass);
        else if (numberClass.isAssignableFrom(paramClass)) {
          // if the user did not specify a type, we'll get a converter for numeric types.

          try {
            TypeConvertor tc = Types.getConvertor(valueClass, paramClass);
            value = tc.convert(value, null);
          } catch (MappingException e) {
            throw new IllegalArgumentException(
                "Query parameter "
                    + (_fieldNum + 1)
                    + " cannot be converted from "
                    + valueClass
                    + " to "
                    + paramClass
                    + ", because no convertor can be found.");
          }
        }

      if (_bindValues == null) _bindValues = new Object[_bindTypes.length];

      for (Enumeration e = info.getParamMap().elements(); e.hasMoreElements(); ) {
        int fieldNum = ((Integer) e.nextElement()).intValue();
        _bindValues[fieldNum - 1] = value;
      }

    } catch (IllegalArgumentException except) {
      throw except;
    }
    ++_fieldNum;
  }
  protected TypeInfo getTypeInfo(
      final Class fieldType, final CollectionHandler colHandler, final FieldMapping fieldMap)
      throws MappingException {
    Class internalFieldType = Types.typeFromPrimitive(fieldType);
    String typeName = null;
    Class sqlType = null;
    String sqlParam = null;

    String[] sqlTypes = getSqlTypes(fieldMap);
    if ((fieldMap.getSql() != null) && (sqlTypes.length > 0)) {
      // --TO Check
      typeName = sqlTypes[0];
      sqlType = SQLTypeInfos.sqlTypeName2javaType(definition2type(typeName));
      sqlParam = definition2param(typeName);
    } else {
      sqlType = internalFieldType;
    }

    if (_factory != null) {
      sqlType = _factory.adjustSqlType(sqlType);
    }

    TypeConvertor convertorTo = null;
    TypeConvertor convertorFrom = null;

    if (internalFieldType != sqlType) {
      try {
        convertorTo = _typeConvertorRegistry.getConvertor(sqlType, internalFieldType, sqlParam);
      } catch (MappingException ex) {
        boolean isTypeSafeEnum = false;
        // -- check for type-safe enum style classes
        if ((internalFieldType != null) && (!isPrimitive(internalFieldType))) {
          // -- make sure no default constructor
          Constructor cons = null;
          try {
            cons = internalFieldType.getConstructor(EMPTY_ARGS);
            if (!Modifier.isPublic(cons.getModifiers())) {
              cons = null;
            }
          } catch (NoSuchMethodException nsmx) {
            // -- Do nothing
          }

          if (cons == null) {
            // -- make sure a valueOf factory method exists
            try {
              Method method = internalFieldType.getMethod(VALUE_OF, STRING_ARG);
              Class returnType = method.getReturnType();
              if ((returnType != null) && internalFieldType.isAssignableFrom(returnType)) {
                int mods = method.getModifiers();
                if (Modifier.isStatic(mods)) {
                  // create individual SQLTypeConverter
                  convertorTo = new String2EnumTypeConvertor(sqlType, internalFieldType, method);

                  Types.addEnumType(internalFieldType);

                  isTypeSafeEnum = true;
                }
              }
            } catch (NoSuchMethodException nsmx) {
              // -- Do nothing
            }
          }

          if (isTypeSafeEnum) {
            // -- check if name() method should be used instead of toString()
            try {
              Method method = internalFieldType.getMethod(NAME);
              if (String.class == method.getReturnType()) {
                convertorFrom = new Enum2StringTypeConvertor(internalFieldType, sqlType, method);
              }
            } catch (NoSuchMethodException nsmx) {
              // -- Do nothing
            }
          }
        }

        if (!isTypeSafeEnum) {
          throw new MappingException(
              "mapping.noConvertor", sqlType.getName(), internalFieldType.getName());
        }
      }

      if (convertorFrom == null) {
        convertorFrom = _typeConvertorRegistry.getConvertor(internalFieldType, sqlType, sqlParam);
      }

      if ((convertorTo != null) && (convertorFrom != null)) {
        Types.addConvertibleType(internalFieldType);
      }
    }

    return new TypeInfo(
        internalFieldType, convertorTo, convertorFrom, fieldMap.getRequired(), null, colHandler);
  }
  protected ClassDescriptor createClassDescriptor(final ClassMapping classMapping)
      throws MappingException {
    // If there is no SQL information for class, ignore it.
    if ((classMapping.getMapTo() == null) || (classMapping.getMapTo().getTable() == null)) {
      LOG.info(Messages.format("mapping.ignoringMapping", classMapping.getName()));
      return null;
    }

    // Create the class descriptor, and register the JDO nature with it.
    ClassDescriptorImpl clsDesc = new ClassDescriptorImpl();
    clsDesc.addNature(ClassDescriptorJDONature.class.getName());
    ClassDescriptorJDONature jdoNature = new ClassDescriptorJDONature(clsDesc);

    // Obtain the Java class.
    Class<?> javaClass = resolveType(classMapping.getName());
    if (!Types.isConstructable(javaClass, true)) {
      throw new MappingException("mapping.classNotConstructable", javaClass.getName());
    }
    clsDesc.setJavaClass(javaClass);

    // If this class extends another class, we need to obtain the extended
    // class and make sure this class indeed extends it.
    ClassDescriptor extDesc = getExtended(classMapping, javaClass);
    if (extDesc != null) {
      if (!(extDesc.hasNature(ClassDescriptorJDONature.class.getName()))) {
        throw new IllegalArgumentException("Extended class does not have a JDO descriptor");
      }

      new ClassDescriptorJDONature(extDesc).addExtended(clsDesc);
    }
    clsDesc.setExtends(extDesc);

    // If this class depends on another class, obtain the class it depends upon.
    clsDesc.setDepends(getDepended(classMapping, javaClass));

    // Create all field descriptors.
    FieldDescriptorImpl[] allFields = createFieldDescriptors(classMapping, javaClass);

    // Make sure there are no two fields with the same name.
    checkFieldNameDuplicates(allFields, javaClass);

    // Set class descriptor containing the field
    for (int i = 0; i < allFields.length; i++) {
      allFields[i].setContainingClassDescriptor(clsDesc);
    }

    // Identify identity and normal fields. Note that order must be preserved.
    List<FieldDescriptor> fieldList = new ArrayList<FieldDescriptor>(allFields.length);
    List<FieldDescriptor> idList = new ArrayList<FieldDescriptor>();
    if (extDesc == null) {
      // Sort fields into 2 lists based on identity definition of field.
      for (int i = 0; i < allFields.length; i++) {
        if (!allFields[i].isIdentity()) {
          fieldList.add(allFields[i]);
        } else {
          idList.add(allFields[i]);
        }
      }

      if (idList.size() == 0) {
        // Found no identities based on identity definition of field.
        // Try to find identities based on identity definition on class.
        String[] idNames = classMapping.getIdentity();
        if ((idNames == null) || (idNames.length == 0)) {
          // There are also no identity definitions on class.
          throw new MappingException("mapping.noIdentity", javaClass.getName());
        }

        FieldDescriptor identity;
        for (int i = 0; i < idNames.length; i++) {
          identity = findIdentityByName(fieldList, idNames[i], javaClass);
          if (identity != null) {
            idList.add(identity);
          } else {
            throw new MappingException("mapping.identityMissing", idNames[i], javaClass.getName());
          }
        }
      }
    } else {
      // Add all fields of extending class to field list.
      for (int i = 0; i < allFields.length; i++) {
        fieldList.add(allFields[i]);
      }

      // Add all identities of extended class to identity list.
      FieldDescriptor[] extIds = ((ClassDescriptorImpl) extDesc).getIdentities();
      for (int i = 0; i < extIds.length; i++) {
        idList.add(extIds[i]);
      }

      // Search redefined identities in extending class.
      FieldDescriptor identity;
      for (int i = 0; i < idList.size(); i++) {
        String idName = (idList.get(i)).getFieldName();
        identity = findIdentityByName(fieldList, idName, javaClass);
        if (identity != null) {
          idList.set(i, identity);
        }
      }
    }

    // Set identities on class descriptor.
    FieldDescriptor[] ids = new FieldDescriptor[idList.size()];
    clsDesc.setIdentities(idList.toArray(ids));

    // Set fields on class descriptor.
    FieldDescriptor[] fields = new FieldDescriptor[fieldList.size()];
    clsDesc.setFields(fieldList.toArray(fields));

    jdoNature.setTableName(classMapping.getMapTo().getTable());

    // Set the field name used for object modification checks.
    jdoNature.setVersionField(classMapping.getVersion());

    extractAndSetAccessMode(jdoNature, classMapping);
    extractAndAddCacheParams(jdoNature, classMapping, javaClass);
    extractAndAddNamedQueries(jdoNature, classMapping);
    extractAndAddNamedNativeQueries(jdoNature, classMapping);
    extractAndSetKeyGeneratorDescriptor(jdoNature, classMapping.getKeyGenerator());

    return clsDesc;
  }