Search in sources :

Example 1 with Basic

use of org.apache.openejb.jee.jpa.Basic in project tomee by apache.

the class CmpJpaConversion method mapClass2x.

/**
     * Generate the JPA mapping for a CMP 2.x bean.  Since
     * the field accessors are all defined as abstract methods
     * and the fields will not be defined in the implementation
     * class, we don't need to deal with mapped superclasses.
     * All of the fields and concrete methods will be
     * implemented by the generated subclass, so from
     * a JPA standpoint, there are no mapped superclasses
     * required.
     *
     * @param mapping     The mapping information we're updating.
     * @param bean        The entity bean meta data
     * @param classLoader The classloader for resolving class references and
     *                    primary key classes.
     */
private Collection<MappedSuperclass> mapClass2x(final Mapping mapping, final EntityBean bean, final ClassLoader classLoader) {
    final Set<String> allFields = new TreeSet<String>();
    // get an acculated set of the CMP fields. 
    for (final CmpField cmpField : bean.getCmpField()) {
        allFields.add(cmpField.getFieldName());
    }
    Class<?> beanClass = null;
    try {
        beanClass = classLoader.loadClass(bean.getEjbClass());
    } catch (final ClassNotFoundException e) {
        // if it does fail, just return null from here
        return null;
    }
    // build a map from the field name to the super class that contains that field.
    // If this is a strictly CMP 2.x class, this is generally an empty map.  However, 
    // we support some migration steps toward EJB3, so this can be defined completely 
    // or partially as a POJO with concrete fields and accessors.  This allows us to 
    // locate and generate the mappings 
    final Map<String, MappedSuperclass> superclassByField = mapFields(beanClass, allFields);
    for (final Method method : beanClass.getMethods()) {
        if (!Modifier.isAbstract(method.getModifiers())) {
            continue;
        }
        if (method.getParameterTypes().length != 0) {
            continue;
        }
        if (method.getReturnType().equals(Void.TYPE)) {
            continue;
        }
        // Skip relationships: anything of type EJBLocalObject or Collection
        if (EJBLocalObject.class.isAssignableFrom(method.getReturnType())) {
            continue;
        }
        if (Collection.class.isAssignableFrom(method.getReturnType())) {
            continue;
        }
        if (Map.class.isAssignableFrom(method.getReturnType())) {
            continue;
        }
        String name = method.getName();
        if (name.startsWith("get")) {
            name = name.substring("get".length(), name.length());
        } else if (name.startsWith("is")) {
            // boolean. 
            if (method.getReturnType() == Boolean.TYPE) {
                name = name.substring("is".length(), name.length());
            } else {
                // not an acceptable "is" method. 
                continue;
            }
        } else {
            continue;
        }
        // the property needs the first character lowercased.  Generally, 
        // we'll have this field already in our list, but it might have been 
        // omitted from the meta data. 
        name = Strings.lcfirst(name);
        if (!allFields.contains(name)) {
            allFields.add(name);
            bean.addCmpField(name);
        }
    }
    //
    // id: the primary key
    //
    final Set<String> primaryKeyFields = new HashSet<String>();
    if (bean.getPrimkeyField() != null) {
        final String fieldName = bean.getPrimkeyField();
        final MappedSuperclass superclass = superclassByField.get(fieldName);
        // this need not be here...for CMP 2.x, these are generally autogenerated fields. 
        if (superclass != null) {
            // ok, add this field to the superclass mapping 
            superclass.addField(new Id(fieldName));
            // the direct mapping is an over ride 
            mapping.addField(new AttributeOverride(fieldName));
        } else {
            // this is a normal generated field, it will be in the main class mapping. 
            mapping.addField(new Id(fieldName));
        }
        primaryKeyFields.add(fieldName);
    } else if ("java.lang.Object".equals(bean.getPrimKeyClass())) {
        // the automatically generated keys use a special property name 
        // and will always be in the generated superclass. 
        final String fieldName = "OpenEJB_pk";
        final Id field = new Id(fieldName);
        field.setGeneratedValue(new GeneratedValue(GenerationType.AUTO));
        mapping.addField(field);
        primaryKeyFields.add(fieldName);
    } else if (bean.getPrimKeyClass() != null) {
        Class<?> pkClass = null;
        try {
            pkClass = classLoader.loadClass(bean.getPrimKeyClass());
            MappedSuperclass idclass = null;
            // to make sure everything maps correctly. 
            for (final Field pkField : pkClass.getFields()) {
                final String pkFieldName = pkField.getName();
                final int modifiers = pkField.getModifiers();
                if (Modifier.isPublic(modifiers) && !Modifier.isStatic(modifiers) && allFields.contains(pkFieldName)) {
                    // see if the bean field is concretely defined in one of the superclasses 
                    final MappedSuperclass superclass = superclassByField.get(pkFieldName);
                    if (superclass != null) {
                        // ok, we have an override that needs to be specified at the main class level. 
                        superclass.addField(new Id(pkFieldName));
                        mapping.addField(new AttributeOverride(pkFieldName));
                        idclass = resolveIdClass(idclass, superclass, beanClass);
                    } else {
                        // this field will be autogenerated 
                        mapping.addField(new Id(pkFieldName));
                    }
                    primaryKeyFields.add(pkFieldName);
                }
            }
            // if we've located an ID class, set it as such 
            if (idclass != null) {
                idclass.setIdClass(new IdClass(bean.getPrimKeyClass()));
            } else {
                // do this for the toplevel mapping 
                mapping.setIdClass(new IdClass(bean.getPrimKeyClass()));
            }
        } catch (final ClassNotFoundException e) {
            throw (IllegalStateException) new IllegalStateException("Could not find entity primary key class " + bean.getPrimKeyClass()).initCause(e);
        }
    }
    //
    for (final CmpField cmpField : bean.getCmpField()) {
        // only add entries for cmp fields that are not part of the primary key 
        if (!primaryKeyFields.contains(cmpField.getFieldName())) {
            final String fieldName = cmpField.getFieldName();
            // this will be here if we've already processed this 
            final MappedSuperclass superclass = superclassByField.get(fieldName);
            // we need to provide a mapping for this. 
            if (superclass != null) {
                // we need to mark this as being in one of the superclasses 
                superclass.addField(new Basic(fieldName));
                mapping.addField(new AttributeOverride(fieldName));
            } else {
                // directly generated. 
                mapping.addField(new Basic(fieldName));
            }
        }
    }
    // the field mappings 
    return new HashSet<MappedSuperclass>(superclassByField.values());
}
Also used : Basic(org.apache.openejb.jee.jpa.Basic) Method(java.lang.reflect.Method) QueryMethod(org.apache.openejb.jee.QueryMethod) AttributeOverride(org.apache.openejb.jee.jpa.AttributeOverride) GeneratedValue(org.apache.openejb.jee.jpa.GeneratedValue) RelationField(org.apache.openejb.jee.jpa.RelationField) CmpField(org.apache.openejb.jee.CmpField) Field(java.lang.reflect.Field) IdClass(org.apache.openejb.jee.jpa.IdClass) CmpField(org.apache.openejb.jee.CmpField) TreeSet(java.util.TreeSet) MappedSuperclass(org.apache.openejb.jee.jpa.MappedSuperclass) Id(org.apache.openejb.jee.jpa.Id) HashSet(java.util.HashSet)

Example 2 with Basic

use of org.apache.openejb.jee.jpa.Basic in project tomee by apache.

the class CmpJpaConversion method mapClass1x.

/**
     * Create the class mapping for a CMP 1.x entity bean.
     * Since the fields for 1.x persistence are defined
     * in the objects directly, we need to create superclass
     * mappings for each of the defined fields to identify
     * which classes implement each of the managed fields.
     *
     * @param ejbClassName The name of the class we're processing.
     * @param mapping      The mappings we're going to generate.
     * @param bean         The bean metadata for the ejb.
     * @param classLoader  The classloader used to load the bean class for
     *                     inspection.
     * @return The set of mapped superclasses used in this
     * bean mapping.
     */
private Collection<MappedSuperclass> mapClass1x(final String ejbClassName, final Mapping mapping, final EntityBean bean, final ClassLoader classLoader) {
    final Class ejbClass = loadClass(classLoader, ejbClassName);
    // build a set of all field names
    final Set<String> allFields = new TreeSet<String>();
    for (final CmpField cmpField : bean.getCmpField()) {
        allFields.add(cmpField.getFieldName());
    }
    // build a map from the field name to the super class that contains that field
    final Map<String, MappedSuperclass> superclassByField = mapFields(ejbClass, allFields);
    //
    // id: the primary key
    //
    final Set<String> primaryKeyFields = new HashSet<String>();
    if (bean.getPrimkeyField() != null) {
        final String fieldName = bean.getPrimkeyField();
        final MappedSuperclass superclass = superclassByField.get(fieldName);
        if (superclass == null) {
            throw new IllegalStateException("Primary key field " + fieldName + " is not defined in class " + ejbClassName + " or any super classes");
        }
        superclass.addField(new Id(fieldName));
        mapping.addField(new AttributeOverride(fieldName));
        primaryKeyFields.add(fieldName);
    } else if ("java.lang.Object".equals(bean.getPrimKeyClass())) {
        // a primary field type of Object is an automatically generated 
        // pk field.  Mark it as such and add it to the mapping.  
        final String fieldName = "OpenEJB_pk";
        final Id field = new Id(fieldName);
        field.setGeneratedValue(new GeneratedValue(GenerationType.AUTO));
        mapping.addField(field);
    } else if (bean.getPrimKeyClass() != null) {
        // we have a primary key class.  We need to define the mappings between the key class fields 
        // and the bean's managed fields. 
        Class<?> pkClass = null;
        try {
            pkClass = classLoader.loadClass(bean.getPrimKeyClass());
            MappedSuperclass superclass = null;
            MappedSuperclass idclass = null;
            for (final Field pkField : pkClass.getFields()) {
                final String fieldName = pkField.getName();
                final int modifiers = pkField.getModifiers();
                // AND must also exist in the class hierarchy (not enforced by mapFields()); 
                if (Modifier.isPublic(modifiers) && !Modifier.isStatic(modifiers) && allFields.contains(fieldName)) {
                    superclass = superclassByField.get(fieldName);
                    if (superclass == null) {
                        throw new IllegalStateException("Primary key field " + fieldName + " is not defined in class " + ejbClassName + " or any super classes");
                    }
                    // these are defined ast ID fields because they are part of the primary key 
                    superclass.addField(new Id(fieldName));
                    mapping.addField(new AttributeOverride(fieldName));
                    primaryKeyFields.add(fieldName);
                    idclass = resolveIdClass(idclass, superclass, ejbClass);
                }
            }
            // if we've located an ID class, set it as such 
            if (idclass != null) {
                idclass.setIdClass(new IdClass(bean.getPrimKeyClass()));
            }
        } catch (final ClassNotFoundException e) {
            throw (IllegalStateException) new IllegalStateException("Could not find entity primary key class " + bean.getPrimKeyClass()).initCause(e);
        }
    }
    //
    for (final CmpField cmpField : bean.getCmpField()) {
        final String fieldName = cmpField.getFieldName();
        // all of the primary key fields have been processed, so only handle whatever is left over 
        if (!primaryKeyFields.contains(fieldName)) {
            final MappedSuperclass superclass = superclassByField.get(fieldName);
            if (superclass == null) {
                throw new IllegalStateException("CMP field " + fieldName + " is not defined in class " + ejbClassName + " or any super classes");
            }
            superclass.addField(new Basic(fieldName));
            mapping.addField(new AttributeOverride(fieldName));
        }
    }
    // the field mappings 
    return new HashSet<MappedSuperclass>(superclassByField.values());
}
Also used : Basic(org.apache.openejb.jee.jpa.Basic) AttributeOverride(org.apache.openejb.jee.jpa.AttributeOverride) GeneratedValue(org.apache.openejb.jee.jpa.GeneratedValue) RelationField(org.apache.openejb.jee.jpa.RelationField) CmpField(org.apache.openejb.jee.CmpField) Field(java.lang.reflect.Field) IdClass(org.apache.openejb.jee.jpa.IdClass) CmpField(org.apache.openejb.jee.CmpField) TreeSet(java.util.TreeSet) MappedSuperclass(org.apache.openejb.jee.jpa.MappedSuperclass) IdClass(org.apache.openejb.jee.jpa.IdClass) Id(org.apache.openejb.jee.jpa.Id) HashSet(java.util.HashSet)

Aggregations

Field (java.lang.reflect.Field)2 HashSet (java.util.HashSet)2 TreeSet (java.util.TreeSet)2 CmpField (org.apache.openejb.jee.CmpField)2 AttributeOverride (org.apache.openejb.jee.jpa.AttributeOverride)2 Basic (org.apache.openejb.jee.jpa.Basic)2 GeneratedValue (org.apache.openejb.jee.jpa.GeneratedValue)2 Id (org.apache.openejb.jee.jpa.Id)2 IdClass (org.apache.openejb.jee.jpa.IdClass)2 MappedSuperclass (org.apache.openejb.jee.jpa.MappedSuperclass)2 RelationField (org.apache.openejb.jee.jpa.RelationField)2 Method (java.lang.reflect.Method)1 QueryMethod (org.apache.openejb.jee.QueryMethod)1