Search in sources :

Example 1 with IndexMetaData

use of org.datanucleus.metadata.IndexMetaData in project datanucleus-rdbms by datanucleus.

the class ClassTable method getExpectedIndices.

/**
 * Accessor for the indices for this table. This includes both the
 * user-defined indices (via MetaData), and the ones required by foreign
 * keys (required by relationships).
 * @param clr The ClassLoaderResolver
 * @return The indices
 */
@Override
protected Set<Index> getExpectedIndices(ClassLoaderResolver clr) {
    // Auto mode allows us to decide which indices are needed as well as using what is in the users MetaData
    boolean autoMode = false;
    if (storeMgr.getStringProperty(RDBMSPropertyNames.PROPERTY_RDBMS_CONSTRAINT_CREATE_MODE).equals("DataNucleus")) {
        autoMode = true;
    }
    Set<Index> indices = new HashSet();
    // Add on any user-required indices for the fields/properties
    Set memberNumbersSet = memberMappingsMap.keySet();
    Iterator iter = memberNumbersSet.iterator();
    while (iter.hasNext()) {
        AbstractMemberMetaData fmd = (AbstractMemberMetaData) iter.next();
        JavaTypeMapping fieldMapping = memberMappingsMap.get(fmd);
        if (fieldMapping instanceof EmbeddedPCMapping) {
            // Add indexes for fields of this embedded PC object
            EmbeddedPCMapping embMapping = (EmbeddedPCMapping) fieldMapping;
            for (int i = 0; i < embMapping.getNumberOfJavaTypeMappings(); i++) {
                JavaTypeMapping embFieldMapping = embMapping.getJavaTypeMapping(i);
                IndexMetaData imd = embFieldMapping.getMemberMetaData().getIndexMetaData();
                if (imd != null) {
                    Index index = TableUtils.getIndexForField(this, imd, embFieldMapping);
                    if (index != null) {
                        indices.add(index);
                    }
                }
            }
        } else if (fieldMapping instanceof SerialisedMapping) {
        // Don't index these
        } else {
            // Add any required index for this field
            IndexMetaData imd = fmd.getIndexMetaData();
            if (imd != null) {
                // Index defined so add it
                Index index = TableUtils.getIndexForField(this, imd, fieldMapping);
                if (index != null) {
                    indices.add(index);
                }
            } else if (autoMode) {
                if (fmd.getIndexed() == null) {
                    // Indexing not set, so add where we think it is appropriate
                    if (// Ignore PKs since they will be indexed anyway
                    !fmd.isPrimaryKey()) {
                        // TODO Some RDBMS create index automatically for all FK cols so we don't need to really
                        RelationType relationType = fmd.getRelationType(clr);
                        if (relationType == RelationType.ONE_TO_ONE_UNI) {
                            // 1-1 with FK at this side so index the FK
                            if (fieldMapping instanceof ReferenceMapping) {
                                ReferenceMapping refMapping = (ReferenceMapping) fieldMapping;
                                if (refMapping.getMappingStrategy() == ReferenceMapping.PER_IMPLEMENTATION_MAPPING) {
                                    // Cols per implementation : index each of implementations
                                    if (refMapping.getJavaTypeMapping() != null) {
                                        int colNum = 0;
                                        JavaTypeMapping[] implMappings = refMapping.getJavaTypeMapping();
                                        for (int i = 0; i < implMappings.length; i++) {
                                            int numColsInImpl = implMappings[i].getNumberOfColumnMappings();
                                            Index index = new Index(this, false, null);
                                            for (int j = 0; j < numColsInImpl; j++) {
                                                index.setColumn(j, fieldMapping.getColumnMapping(colNum++).getColumn());
                                            }
                                            indices.add(index);
                                        }
                                    }
                                }
                            } else {
                                Index index = new Index(this, false, null);
                                for (int i = 0; i < fieldMapping.getNumberOfColumnMappings(); i++) {
                                    index.setColumn(i, fieldMapping.getColumnMapping(i).getColumn());
                                }
                                indices.add(index);
                            }
                        } else if (relationType == RelationType.ONE_TO_ONE_BI && fmd.getMappedBy() == null) {
                            // 1-1 with FK at this side so index the FK
                            Index index = new Index(this, false, null);
                            for (int i = 0; i < fieldMapping.getNumberOfColumnMappings(); i++) {
                                index.setColumn(i, fieldMapping.getColumnMapping(i).getColumn());
                            }
                            indices.add(index);
                        } else if (relationType == RelationType.MANY_TO_ONE_BI) {
                            // N-1 with FK at this side so index the FK
                            AbstractMemberMetaData relMmd = fmd.getRelatedMemberMetaData(clr)[0];
                            if (relMmd.getJoinMetaData() == null && fmd.getJoinMetaData() == null) {
                                if (fieldMapping.getNumberOfColumnMappings() > 0) {
                                    Index index = new Index(this, false, null);
                                    for (int i = 0; i < fieldMapping.getNumberOfColumnMappings(); i++) {
                                        index.setColumn(i, fieldMapping.getColumnMapping(i).getColumn());
                                    }
                                    indices.add(index);
                                } else {
                                    // TODO How do we get this?
                                    NucleusLogger.DATASTORE_SCHEMA.warn("Table " + this + " manages member " + fmd.getFullFieldName() + " which is a N-1 but there is no column for this mapping so not adding index!");
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    // Check if any version column needs indexing
    if (versionMapping != null) {
        IndexMetaData idxmd = getVersionMetaData().getIndexMetaData();
        if (idxmd != null) {
            Index index = new Index(this, idxmd.isUnique(), idxmd.getExtensions());
            if (idxmd.getName() != null) {
                index.setName(idxmd.getName());
            }
            int countVersionFields = versionMapping.getNumberOfColumnMappings();
            for (int i = 0; i < countVersionFields; i++) {
                index.addColumn(versionMapping.getColumnMapping(i).getColumn());
            }
            indices.add(index);
        }
    }
    // Check if any discriminator column needs indexing
    if (discriminatorMapping != null) {
        DiscriminatorMetaData dismd = getDiscriminatorMetaData();
        IndexMetaData idxmd = dismd.getIndexMetaData();
        if (idxmd != null) {
            Index index = new Index(this, idxmd.isUnique(), idxmd.getExtensions());
            if (idxmd.getName() != null) {
                index.setName(idxmd.getName());
            }
            int numCols = discriminatorMapping.getNumberOfColumnMappings();
            for (int i = 0; i < numCols; i++) {
                index.addColumn(discriminatorMapping.getColumnMapping(i).getColumn());
            }
            indices.add(index);
        }
    }
    // Check if multitenancy discriminator present and needs indexing
    if (multitenancyMapping != null) {
        MultitenancyMetaData mtmd = cmd.getMultitenancyMetaData();
        IndexMetaData idxmd = mtmd.getIndexMetaData();
        if (idxmd != null) {
            Index index = new Index(this, false, null);
            if (idxmd.getName() != null) {
                index.setName(idxmd.getName());
            }
            int numCols = multitenancyMapping.getNumberOfColumnMappings();
            for (int i = 0; i < numCols; i++) {
                index.addColumn(multitenancyMapping.getColumnMapping(i).getColumn());
            }
            indices.add(index);
        }
    }
    // Check if soft delete column present and needs indexing
    if (softDeleteMapping != null) {
        SoftDeleteMetaData sdmd = cmd.getSoftDeleteMetaData();
        IndexMetaData idxmd = sdmd.getIndexMetaData();
        if (idxmd != null) {
            Index index = new Index(this, false, null);
            if (idxmd.getName() != null) {
                index.setName(idxmd.getName());
            }
            int numCols = softDeleteMapping.getNumberOfColumnMappings();
            for (int i = 0; i < numCols; i++) {
                index.addColumn(softDeleteMapping.getColumnMapping(i).getColumn());
            }
            indices.add(index);
        }
    }
    // Add on any order fields (for lists, arrays, collections) that need indexing
    Set orderMappingsEntries = getExternalOrderMappings().entrySet();
    Iterator orderMappingsEntriesIter = orderMappingsEntries.iterator();
    while (orderMappingsEntriesIter.hasNext()) {
        Map.Entry entry = (Map.Entry) orderMappingsEntriesIter.next();
        AbstractMemberMetaData fmd = (AbstractMemberMetaData) entry.getKey();
        JavaTypeMapping mapping = (JavaTypeMapping) entry.getValue();
        OrderMetaData omd = fmd.getOrderMetaData();
        if (omd != null && omd.getIndexMetaData() != null) {
            Index index = getIndexForIndexMetaDataAndMapping(omd.getIndexMetaData(), mapping);
            if (index != null) {
                indices.add(index);
            }
        }
    }
    // Add on any user-required indices for the class(es) as a whole (subelement of <class>)
    Iterator<AbstractClassMetaData> cmdIter = managedClassMetaData.iterator();
    while (cmdIter.hasNext()) {
        AbstractClassMetaData thisCmd = cmdIter.next();
        List<IndexMetaData> classIndices = thisCmd.getIndexMetaData();
        if (classIndices != null) {
            for (IndexMetaData idxmd : classIndices) {
                Index index = getIndexForIndexMetaData(idxmd);
                if (index != null) {
                    indices.add(index);
                }
            }
        }
    }
    if (cmd.getIdentityType() == IdentityType.APPLICATION) {
        // Make sure there is no reuse of PK fields that cause a duplicate index for the PK. Remove it if required
        PrimaryKey pk = getPrimaryKey();
        Iterator<Index> indicesIter = indices.iterator();
        while (indicesIter.hasNext()) {
            Index idx = indicesIter.next();
            if (idx.getColumnList().equals(pk.getColumnList())) {
                NucleusLogger.DATASTORE_SCHEMA.debug("Index " + idx + " is for the same columns as the PrimaryKey so being removed from expected set of indices. PK is always indexed");
                indicesIter.remove();
            }
        }
    }
    return indices;
}
Also used : SoftDeleteMetaData(org.datanucleus.metadata.SoftDeleteMetaData) Set(java.util.Set) HashSet(java.util.HashSet) JavaTypeMapping(org.datanucleus.store.rdbms.mapping.java.JavaTypeMapping) PrimaryKey(org.datanucleus.store.rdbms.key.PrimaryKey) Index(org.datanucleus.store.rdbms.key.Index) AbstractClassMetaData(org.datanucleus.metadata.AbstractClassMetaData) OrderMetaData(org.datanucleus.metadata.OrderMetaData) ReferenceMapping(org.datanucleus.store.rdbms.mapping.java.ReferenceMapping) RelationType(org.datanucleus.metadata.RelationType) Iterator(java.util.Iterator) MultitenancyMetaData(org.datanucleus.metadata.MultitenancyMetaData) HashSet(java.util.HashSet) EmbeddedPCMapping(org.datanucleus.store.rdbms.mapping.java.EmbeddedPCMapping) IndexMetaData(org.datanucleus.metadata.IndexMetaData) DiscriminatorMetaData(org.datanucleus.metadata.DiscriminatorMetaData) SerialisedMapping(org.datanucleus.store.rdbms.mapping.java.SerialisedMapping) AbstractMemberMetaData(org.datanucleus.metadata.AbstractMemberMetaData) Map(java.util.Map) HashMap(java.util.HashMap)

Example 2 with IndexMetaData

use of org.datanucleus.metadata.IndexMetaData in project datanucleus-rdbms by datanucleus.

the class MapTable method getExpectedIndices.

/**
 * Accessor for the indices for this table.
 * This includes both the user-defined indices (via MetaData), and the ones required by foreign keys.
 * @param clr The ClassLoaderResolver
 * @return The indices
 */
@Override
protected Set getExpectedIndices(ClassLoaderResolver clr) {
    Set indices = new HashSet();
    // Index for FK back to owner
    if (mmd.getIndexMetaData() != null) {
        Index index = TableUtils.getIndexForField(this, mmd.getIndexMetaData(), ownerMapping);
        if (index != null) {
            indices.add(index);
        }
    } else if (mmd.getJoinMetaData() != null && mmd.getJoinMetaData().getIndexMetaData() != null) {
        Index index = TableUtils.getIndexForField(this, mmd.getJoinMetaData().getIndexMetaData(), ownerMapping);
        if (index != null) {
            indices.add(index);
        }
    } else {
        // Fallback to an index for the foreign-key to the owner
        Index index = TableUtils.getIndexForField(this, null, ownerMapping);
        if (index != null) {
            indices.add(index);
        }
    }
    // Index for the key FK (if required)
    if (keyMapping instanceof EmbeddedKeyPCMapping) {
        // Add all indices required by fields of the embedded key
        EmbeddedKeyPCMapping embMapping = (EmbeddedKeyPCMapping) keyMapping;
        for (int i = 0; i < embMapping.getNumberOfJavaTypeMappings(); i++) {
            JavaTypeMapping embFieldMapping = embMapping.getJavaTypeMapping(i);
            IndexMetaData imd = embFieldMapping.getMemberMetaData().getIndexMetaData();
            if (imd != null) {
                Index index = TableUtils.getIndexForField(this, imd, embFieldMapping);
                if (index != null) {
                    indices.add(index);
                }
            }
        }
    } else {
        KeyMetaData keymd = mmd.getKeyMetaData();
        if (keymd != null && keymd.getIndexMetaData() != null) {
            IndexMetaData idxmd = mmd.getKeyMetaData().getIndexMetaData();
            Index index = TableUtils.getIndexForField(this, idxmd, keyMapping);
            if (index != null) {
                indices.add(index);
            }
        } else {
            // Fallback to an index for any foreign-key to the key
            if (keyMapping instanceof PersistableMapping) {
                Index index = TableUtils.getIndexForField(this, null, keyMapping);
                if (index != null) {
                    indices.add(index);
                }
            }
        }
    }
    // Index for the value FK (if required)
    if (valueMapping instanceof EmbeddedValuePCMapping) {
        // Add all indices required by fields of the embedded value
        EmbeddedValuePCMapping embMapping = (EmbeddedValuePCMapping) valueMapping;
        for (int i = 0; i < embMapping.getNumberOfJavaTypeMappings(); i++) {
            JavaTypeMapping embFieldMapping = embMapping.getJavaTypeMapping(i);
            IndexMetaData imd = embFieldMapping.getMemberMetaData().getIndexMetaData();
            if (imd != null) {
                Index index = TableUtils.getIndexForField(this, imd, embFieldMapping);
                if (index != null) {
                    indices.add(index);
                }
            }
        }
    } else {
        ValueMetaData valmd = mmd.getValueMetaData();
        if (valmd != null && valmd.getIndexMetaData() != null) {
            IndexMetaData idxmd = mmd.getValueMetaData().getIndexMetaData();
            Index index = TableUtils.getIndexForField(this, idxmd, valueMapping);
            if (index != null) {
                indices.add(index);
            }
        } else {
            // Fallback to an index for any foreign-key to the value
            if (valueMapping instanceof PersistableMapping) {
                Index index = TableUtils.getIndexForField(this, null, valueMapping);
                if (index != null) {
                    indices.add(index);
                }
            }
        }
    }
    return indices;
}
Also used : PersistableMapping(org.datanucleus.store.rdbms.mapping.java.PersistableMapping) HashSet(java.util.HashSet) Set(java.util.Set) JavaTypeMapping(org.datanucleus.store.rdbms.mapping.java.JavaTypeMapping) KeyMetaData(org.datanucleus.metadata.KeyMetaData) PrimaryKeyMetaData(org.datanucleus.metadata.PrimaryKeyMetaData) ForeignKeyMetaData(org.datanucleus.metadata.ForeignKeyMetaData) ValueMetaData(org.datanucleus.metadata.ValueMetaData) Index(org.datanucleus.store.rdbms.key.Index) EmbeddedValuePCMapping(org.datanucleus.store.rdbms.mapping.java.EmbeddedValuePCMapping) HashSet(java.util.HashSet) EmbeddedKeyPCMapping(org.datanucleus.store.rdbms.mapping.java.EmbeddedKeyPCMapping) IndexMetaData(org.datanucleus.metadata.IndexMetaData)

Example 3 with IndexMetaData

use of org.datanucleus.metadata.IndexMetaData in project tests by datanucleus.

the class AnnotationTest method testIndexOnField.

/**
 * Test of Index at field level
 */
public void testIndexOnField() {
    ClassMetaData cmd1 = (ClassMetaData) metaDataMgr.getMetaDataForClass(Person.class.getName(), clr);
    AbstractMemberMetaData fmd = cmd1.getMetaDataForMember("age");
    assertNotNull("JDOPerson.age metadata should have had an Index constraint but didnt", fmd.getIndexMetaData());
    IndexMetaData idxmd = fmd.getIndexMetaData();
    assertEquals("PERSON_AGE_IDX", idxmd.getName());
}
Also used : AbstractMemberMetaData(org.datanucleus.metadata.AbstractMemberMetaData) ClassMetaData(org.datanucleus.metadata.ClassMetaData) IndexMetaData(org.datanucleus.metadata.IndexMetaData)

Example 4 with IndexMetaData

use of org.datanucleus.metadata.IndexMetaData in project datanucleus-api-jdo by datanucleus.

the class JDOAnnotationReader method processClassAnnotations.

/**
 * Method to process the "class" level annotations and create the outline ClassMetaData object.
 * Supports classes annotated with @PersistenceCapable, classes annotated with @PersistenceAware, and classes which have neither of those but have @Queries or @Query.
 * @param pmd Parent PackageMetaData
 * @param cls The class
 * @param annotations Annotations for this class
 * @param clr ClassLoader resolver
 * @return The ClassMetaData/InterfaceMetaData (or null if no annotations)
 */
protected AbstractClassMetaData processClassAnnotations(PackageMetaData pmd, Class cls, AnnotationObject[] annotations, ClassLoaderResolver clr) {
    if (annotations == null || annotations.length == 0) {
        return null;
    }
    AbstractClassMetaData cmd = null;
    AnnotationObject pcAnnotation = isClassPersistable(annotations);
    if (pcAnnotation != null) {
        // PersistenceCapable class
        cmd = (cls.isInterface()) ? pmd.newInterfaceMetadata(ClassUtils.getClassNameForClass(cls)) : pmd.newClassMetadata(ClassUtils.getClassNameForClass(cls));
        cmd.setPersistenceModifier(ClassPersistenceModifier.PERSISTENCE_CAPABLE);
        // Process all attributes here in case needed for other annotations
        processPersistenceCapableAnnotation(cls, cmd, pcAnnotation.getNameValueMap());
    } else if (isClassPersistenceAware(annotations)) {
        // PersistenceAware class
        cmd = pmd.newClassMetadata(ClassUtils.getClassNameForClass(cls));
        cmd.setPersistenceModifier(ClassPersistenceModifier.PERSISTENCE_AWARE);
    } else if (doesClassHaveNamedQueries(annotations)) {
        // Class with named query specified
        cmd = pmd.newClassMetadata(ClassUtils.getClassNameForClass(cls));
        cmd.setPersistenceModifier(ClassPersistenceModifier.NON_PERSISTENT);
    } else {
        // Not involved in the persistence process
        return null;
    }
    // Cater for named queries being specified on a persistence aware, or other class
    processNamedQueries(cmd, cls, annotations);
    if (cmd.getPersistenceModifier() != ClassPersistenceModifier.PERSISTENCE_CAPABLE) {
        // Not persistable, so no further information needed
        return cmd;
    }
    // Class is persistable so process annotations
    for (AnnotationObject annotation : annotations) {
        String annName = annotation.getName();
        if (annName.equals(JDOAnnotationUtils.PERSISTENCE_CAPABLE)) {
            // @PersistenceCapable is merged and processed above
            continue;
        }
        Map<String, Object> annotationValues = annotation.getNameValueMap();
        if (annName.equals(JDOAnnotationUtils.EMBEDDED_ONLY)) {
            cmd.setEmbeddedOnly(true);
        } else if (annName.equals(JDOAnnotationUtils.VERSION)) {
            VersionStrategy versionStrategy = (VersionStrategy) annotationValues.get("strategy");
            String strategy = JDOAnnotationUtils.getVersionStrategyString(versionStrategy);
            String indexed = (String) annotationValues.get("indexed");
            String column = (String) annotationValues.get("column");
            Column[] columns = (Column[]) annotationValues.get("columns");
            VersionMetaData vermd = new VersionMetaData();
            vermd.setStrategy(strategy);
            vermd.setColumnName(column);
            vermd.setIndexed(IndexedValue.getIndexedValue(indexed));
            if (columns != null && columns.length > 0) {
                // Only use the first column
                ColumnMetaData colmd = JDOAnnotationUtils.getColumnMetaDataForColumnAnnotation(columns[0]);
                vermd.setColumnMetaData(colmd);
            }
            JDOAnnotationUtils.addExtensionsToMetaData(vermd, (Extension[]) annotationValues.get("extensions"));
            vermd.setParent(cmd);
            cmd.setVersionMetaData(vermd);
        } else if (annName.equals(JDOAnnotationUtils.DATASTORE_IDENTITY)) {
            String strategy = JDOAnnotationUtils.getValueGenerationStrategyString((IdGeneratorStrategy) annotationValues.get("strategy"));
            String customStrategy = (String) annotationValues.get("customStrategy");
            if (!StringUtils.isWhitespace(customStrategy)) {
                // User has provided an extension strategy
                strategy = customStrategy;
            }
            String sequence = (String) annotationValues.get("sequence");
            String column = (String) annotationValues.get("column");
            Column[] columns = (Column[]) annotationValues.get("columns");
            IdentityMetaData idmd = new IdentityMetaData();
            idmd.setColumnName(column);
            idmd.setValueStrategy(ValueGenerationStrategy.getIdentityStrategy(strategy));
            idmd.setSequence(sequence);
            if (columns != null && columns.length > 0) {
                // Only use the first column
                ColumnMetaData colmd = JDOAnnotationUtils.getColumnMetaDataForColumnAnnotation(columns[0]);
                idmd.setColumnMetaData(colmd);
            }
            JDOAnnotationUtils.addExtensionsToMetaData(idmd, (Extension[]) annotationValues.get("extensions"));
            idmd.setParent(cmd);
            cmd.setIdentityMetaData(idmd);
        } else if (annName.equals(JDOAnnotationUtils.PRIMARY_KEY)) {
            String pkName = (String) annotationValues.get("name");
            String pkColumn = (String) annotationValues.get("column");
            Column[] columns = (Column[]) annotationValues.get("columns");
            PrimaryKeyMetaData pkmd = new PrimaryKeyMetaData();
            pkmd.setName(pkName);
            pkmd.setColumnName(pkColumn);
            if (columns != null && columns.length > 0) {
                for (Column column : columns) {
                    pkmd.addColumn(JDOAnnotationUtils.getColumnMetaDataForColumnAnnotation(column));
                }
            }
            JDOAnnotationUtils.addExtensionsToMetaData(pkmd, (Extension[]) annotationValues.get("extensions"));
            pkmd.setParent(cmd);
            cmd.setPrimaryKeyMetaData(pkmd);
        } else if (annName.equals(JDOAnnotationUtils.JOINS)) {
            Join[] js = (Join[]) annotationValues.get("value");
            if (js != null && js.length > 0) {
                for (Join join : js) {
                    JoinMetaData joinmd = cmd.newJoinMetaData();
                    joinmd.setTable(join.table());
                    joinmd.setColumnName(join.column());
                    joinmd.setIndexed(IndexedValue.getIndexedValue(join.indexed()));
                    joinmd.setOuter(MetaDataUtils.getBooleanForString(join.outer(), false));
                    joinmd.setUnique(join.unique());
                    joinmd.setDeleteAction(JDOAnnotationUtils.getForeignKeyActionString(join.deleteAction()));
                    JDOAnnotationUtils.addExtensionsToMetaData(joinmd, join.extensions());
                }
            }
        } else if (annName.equals(JDOAnnotationUtils.JOIN)) {
            JoinMetaData joinmd = cmd.newJoinMetaData();
            joinmd.setTable((String) annotationValues.get("table"));
            joinmd.setColumnName((String) annotationValues.get("column"));
            joinmd.setIndexed(IndexedValue.getIndexedValue((String) annotationValues.get("indexed")));
            joinmd.setOuter(MetaDataUtils.getBooleanForString((String) annotationValues.get("outer"), false));
            joinmd.setUnique((String) annotationValues.get("unique"));
            joinmd.setDeleteAction(((ForeignKeyAction) annotationValues.get("deleteAction")).toString());
            JDOAnnotationUtils.addExtensionsToMetaData(joinmd, (Extension[]) annotationValues.get("extensions"));
        } else if (annName.equals(JDOAnnotationUtils.INHERITANCE)) {
            String strategy = JDOAnnotationUtils.getInheritanceStrategyString((InheritanceStrategy) annotationValues.get("strategy"));
            String customStrategy = (String) annotationValues.get("customStrategy");
            if (!StringUtils.isWhitespace(customStrategy)) {
                // User has provided an extension strategy
                strategy = customStrategy;
            }
            InheritanceMetaData inhmd = cmd.getInheritanceMetaData();
            if (inhmd == null) {
                inhmd = cmd.newInheritanceMetadata();
            }
            inhmd.setStrategy(strategy);
        } else if (annName.equals(JDOAnnotationUtils.DISCRIMINATOR)) {
            DiscriminatorStrategy discriminatorStrategy = (DiscriminatorStrategy) annotationValues.get("strategy");
            String strategy = JDOAnnotationUtils.getDiscriminatorStrategyString(discriminatorStrategy);
            String column = (String) annotationValues.get("column");
            String indexed = (String) annotationValues.get("indexed");
            String value = (String) annotationValues.get("value");
            Column[] columns = (Column[]) annotationValues.get("columns");
            InheritanceMetaData inhmd = cmd.getInheritanceMetaData();
            if (inhmd == null) {
                inhmd = cmd.newInheritanceMetadata();
            }
            DiscriminatorMetaData dismd = inhmd.newDiscriminatorMetadata();
            dismd.setColumnName(column);
            dismd.setValue(value);
            dismd.setStrategy(strategy);
            dismd.setIndexed(indexed);
            if (columns != null && columns.length > 0) {
                // Only use the first column
                ColumnMetaData colmd = JDOAnnotationUtils.getColumnMetaDataForColumnAnnotation(columns[0]);
                dismd.setColumnMetaData(colmd);
            }
        } else if (annName.equals(JDOAnnotationUtils.FETCHPLANS)) {
            FileMetaData filemd = (FileMetaData) pmd.getParent();
            FetchPlan[] plans = (FetchPlan[]) annotationValues.get("value");
            for (FetchPlan plan : plans) {
                FetchPlanMetaData fpmd = filemd.newFetchPlanMetadata(plan.name());
                fpmd.setFetchSize(plan.fetchSize());
                fpmd.setMaxFetchDepth(plan.maxFetchDepth());
                int numGroups = plan.fetchGroups().length;
                for (int k = 0; k < numGroups; k++) {
                    fpmd.addFetchGroup(new FetchGroupMetaData(plan.fetchGroups()[k]));
                }
            }
        } else if (annName.equals(JDOAnnotationUtils.FETCHPLAN)) {
            FileMetaData filemd = (FileMetaData) pmd.getParent();
            FetchPlanMetaData fpmd = filemd.newFetchPlanMetadata((String) annotationValues.get("name"));
            fpmd.setFetchSize(((Integer) annotationValues.get("fetchSize")).intValue());
            fpmd.setMaxFetchDepth(((Integer) annotationValues.get("maxFetchDepth")).intValue());
            String[] fpFetchGroups = (String[]) annotationValues.get("fetchGroups");
            for (String fpFetchGroup : fpFetchGroups) {
                fpmd.addFetchGroup(new FetchGroupMetaData(fpFetchGroup));
            }
        } else if (annName.equals(JDOAnnotationUtils.FETCHGROUPS)) {
            FetchGroup[] groups = (FetchGroup[]) annotationValues.get("value");
            for (FetchGroup group : groups) {
                FetchGroupMetaData fgmd = cmd.newFetchGroupMetaData(group.name());
                if (!StringUtils.isWhitespace(group.postLoad())) {
                    fgmd.setPostLoad(Boolean.valueOf(group.postLoad()));
                }
                int numFields = group.members().length;
                for (int k = 0; k < numFields; k++) {
                    FetchGroupMemberMetaData fgmmd = new FetchGroupMemberMetaData(fgmd, group.members()[k].name());
                    fgmmd.setRecursionDepth(group.members()[k].recursionDepth());
                    fgmd.addMember(fgmmd);
                }
                int numGroups = group.fetchGroups().length;
                for (int k = 0; k < numGroups; k++) {
                    fgmd.addFetchGroup(new FetchGroupMetaData(group.fetchGroups()[k]));
                }
            }
        } else if (annName.equals(JDOAnnotationUtils.FETCHGROUP)) {
            FetchGroupMetaData fgmd = cmd.newFetchGroupMetaData((String) annotationValues.get("name"));
            String postLoadStr = (String) annotationValues.get("postLoad");
            if (!StringUtils.isWhitespace(postLoadStr)) {
                fgmd.setPostLoad(Boolean.valueOf(postLoadStr));
            }
            Persistent[] fields = (Persistent[]) annotationValues.get("members");
            if (fields != null) {
                for (Persistent field : fields) {
                    FetchGroupMemberMetaData fgmmd = new FetchGroupMemberMetaData(fgmd, field.name());
                    fgmmd.setRecursionDepth(field.recursionDepth());
                    fgmd.addMember(fgmmd);
                }
            }
        } else if (annName.equals(JDOAnnotationUtils.SEQUENCE)) {
            String seqName = (String) annotationValues.get("name");
            String seqStrategy = JDOAnnotationUtils.getSequenceStrategyString((SequenceStrategy) annotationValues.get("strategy"));
            String seqSeq = (String) annotationValues.get("datastoreSequence");
            Class seqFactory = (Class) annotationValues.get("factoryClass");
            String seqFactoryClassName = null;
            if (seqFactory != null && seqFactory != void.class) {
                seqFactoryClassName = seqFactory.getName();
            }
            Integer seqSize = (Integer) annotationValues.get("allocationSize");
            Integer seqStart = (Integer) annotationValues.get("initialValue");
            if (StringUtils.isWhitespace(seqName)) {
                throw new InvalidClassMetaDataException("044155", cmd.getFullClassName());
            }
            SequenceMetaData seqmd = new SequenceMetaData(seqName, seqStrategy);
            seqmd.setFactoryClass(seqFactoryClassName);
            seqmd.setDatastoreSequence(seqSeq);
            if (seqSize != null) {
                seqmd.setAllocationSize(seqSize);
            }
            if (seqStart != null) {
                seqmd.setInitialValue(seqStart);
            }
            JDOAnnotationUtils.addExtensionsToMetaData(seqmd, (Extension[]) annotationValues.get("extensions"));
            // Sequence - currently only allowing 1 per class (should really be on the package)
            cmd.getPackageMetaData().addSequence(seqmd);
        } else if (annName.equals(JDOAnnotationUtils.INDICES)) {
            // Multiple Indices for the class
            Index[] values = (Index[]) annotationValues.get("value");
            if (values != null && values.length > 0) {
                for (Index idx : values) {
                    IndexMetaData idxmd = JDOAnnotationUtils.getIndexMetaData(idx.name(), idx.table(), "" + idx.unique(), idx.members(), idx.columns());
                    if (idxmd.getNumberOfColumns() == 0 && idxmd.getNumberOfMembers() == 0) {
                        NucleusLogger.METADATA.warn(Localiser.msg("044204", cls.getName()));
                    } else {
                        cmd.addIndex(idxmd);
                        idxmd.setParent(cmd);
                    }
                }
            }
        } else if (annName.equals(JDOAnnotationUtils.INDEX)) {
            // Single Index for the class
            String name = (String) annotationValues.get("name");
            String table = (String) annotationValues.get("table");
            String unique = (String) annotationValues.get("unique");
            String[] members = (String[]) annotationValues.get("members");
            Column[] columns = (Column[]) annotationValues.get("columns");
            IndexMetaData idxmd = JDOAnnotationUtils.getIndexMetaData(name, table, unique, members, columns);
            JDOAnnotationUtils.addExtensionsToMetaData(idxmd, (Extension[]) annotationValues.get("extensions"));
            if (idxmd.getNumberOfColumns() == 0 && idxmd.getNumberOfMembers() == 0) {
                NucleusLogger.METADATA.warn(Localiser.msg("044204", cls.getName()));
            } else {
                cmd.addIndex(idxmd);
                idxmd.setParent(cmd);
            }
        } else if (annName.equals(JDOAnnotationUtils.UNIQUES)) {
            // Multiple Unique Constraints for the class
            Unique[] values = (Unique[]) annotationValues.get("value");
            if (values != null && values.length > 0) {
                for (Unique uni : values) {
                    UniqueMetaData unimd = JDOAnnotationUtils.getUniqueMetaData(uni.name(), uni.table(), "" + uni.deferred(), uni.members(), uni.columns());
                    if (unimd.getNumberOfColumns() == 0 && unimd.getNumberOfMembers() == 0) {
                        NucleusLogger.METADATA.warn(Localiser.msg("044205", cls.getName()));
                    } else {
                        cmd.addUniqueConstraint(unimd);
                        unimd.setParent(cmd);
                    }
                }
            }
        } else if (annName.equals(JDOAnnotationUtils.UNIQUE)) {
            // Single Unique constraint for the class
            String name = (String) annotationValues.get("name");
            String table = (String) annotationValues.get("table");
            String deferred = (String) annotationValues.get("deferred");
            String[] members = (String[]) annotationValues.get("members");
            Column[] columns = (Column[]) annotationValues.get("columns");
            UniqueMetaData unimd = JDOAnnotationUtils.getUniqueMetaData(name, table, deferred, members, columns);
            JDOAnnotationUtils.addExtensionsToMetaData(unimd, (Extension[]) annotationValues.get("extensions"));
            if (unimd.getNumberOfColumns() == 0 && unimd.getNumberOfMembers() == 0) {
                NucleusLogger.METADATA.warn(Localiser.msg("044205", cls.getName()));
            } else {
                cmd.addUniqueConstraint(unimd);
                unimd.setParent(cmd);
            }
        } else if (annName.equals(JDOAnnotationUtils.FOREIGNKEYS)) {
            // Multiple FKs for the class
            ForeignKey[] values = (ForeignKey[]) annotationValues.get("value");
            if (values != null && values.length > 0) {
                for (ForeignKey fk : values) {
                    String deleteAction = JDOAnnotationUtils.getForeignKeyActionString(fk.deleteAction());
                    String updateAction = JDOAnnotationUtils.getForeignKeyActionString(fk.updateAction());
                    ForeignKeyMetaData fkmd = JDOAnnotationUtils.getFKMetaData(fk.name(), fk.table(), fk.unique(), "" + fk.deferred(), deleteAction, updateAction, fk.members(), fk.columns());
                    if (fkmd.getNumberOfColumns() == 0 && fkmd.getNumberOfMembers() == 0) {
                        NucleusLogger.METADATA.warn(Localiser.msg("044206", cls.getName()));
                    } else {
                        cmd.addForeignKey(fkmd);
                        fkmd.setParent(cmd);
                    }
                }
            }
        } else if (annName.equals(JDOAnnotationUtils.FOREIGNKEY)) {
            // Single FK constraint for the class
            String name = (String) annotationValues.get("name");
            String table = (String) annotationValues.get("table");
            String unique = (String) annotationValues.get("unique");
            String deferred = (String) annotationValues.get("deferred");
            String deleteAction = JDOAnnotationUtils.getForeignKeyActionString((ForeignKeyAction) annotationValues.get("deleteAction"));
            String updateAction = JDOAnnotationUtils.getForeignKeyActionString((ForeignKeyAction) annotationValues.get("updateAction"));
            String[] members = (String[]) annotationValues.get("members");
            Column[] columns = (Column[]) annotationValues.get("columns");
            ForeignKeyMetaData fkmd = JDOAnnotationUtils.getFKMetaData(name, table, unique, deferred, deleteAction, updateAction, members, columns);
            JDOAnnotationUtils.addExtensionsToMetaData(fkmd, (Extension[]) annotationValues.get("extensions"));
            if (fkmd.getNumberOfColumns() == 0 && fkmd.getNumberOfMembers() == 0) {
                NucleusLogger.METADATA.warn(Localiser.msg("044206", cls.getName()));
            } else {
                cmd.addForeignKey(fkmd);
                fkmd.setParent(cmd);
            }
        } else if (annName.equals(JDOAnnotationUtils.COLUMNS)) {
            // Unmapped column specification
            Column[] cols = (Column[]) annotationValues.get("value");
            if (cols != null && cols.length > 0) {
                for (Column col : cols) {
                    ColumnMetaData colmd = JDOAnnotationUtils.getColumnMetaDataForColumnAnnotation(col);
                    JDOAnnotationUtils.addExtensionsToMetaData(colmd, col.extensions());
                    colmd.setParent(cmd);
                    cmd.addUnmappedColumn(colmd);
                }
            }
        } else if (annName.equals(JDOAnnotationUtils.CACHEABLE)) {
            String cache = (String) annotationValues.get("value");
            if (cache != null && cache.equalsIgnoreCase("false")) {
                cmd.setCacheable(false);
            }
        } else if (annName.equals(JDOAnnotationUtils.EXTENSIONS)) {
            Extension[] values = (Extension[]) annotationValues.get("value");
            if (values != null && values.length > 0) {
                for (Extension ext : values) {
                    String vendorName = ext.vendorName();
                    if (StringUtils.isWhitespace(vendorName)) {
                        throw new InvalidMetaDataException("044160", vendorName, ext.key().toString(), ext.value().toString());
                    } else if (vendorName.equalsIgnoreCase(MetaData.VENDOR_NAME)) {
                        cmd.addExtension(ext.key().toString(), ext.value().toString());
                    }
                }
            }
        } else if (annName.equals(JDOAnnotationUtils.EXTENSION)) {
            String vendorName = (String) annotationValues.get("vendorName");
            if (StringUtils.isWhitespace(vendorName)) {
                throw new InvalidMetaDataException("044160", vendorName, annotationValues.get("key"), annotationValues.get("value"));
            } else if (vendorName.equalsIgnoreCase(MetaData.VENDOR_NAME)) {
                cmd.addExtension((String) annotationValues.get("key"), (String) annotationValues.get("value"));
            }
        } else {
            if (!annName.equals(JDOAnnotationUtils.PERSISTENCE_AWARE) && !annName.equals(JDOAnnotationUtils.QUERIES) && !annName.equals(JDOAnnotationUtils.QUERY)) {
                NucleusLogger.METADATA.debug(Localiser.msg("044203", cls.getName(), annotation.getName()));
            }
        }
    }
    NucleusLogger.METADATA.debug(Localiser.msg("044200", cls.getName(), "JDO"));
    return cmd;
}
Also used : DiscriminatorStrategy(javax.jdo.annotations.DiscriminatorStrategy) InvalidMetaDataException(org.datanucleus.metadata.InvalidMetaDataException) VersionMetaData(org.datanucleus.metadata.VersionMetaData) Index(javax.jdo.annotations.Index) AnnotationObject(org.datanucleus.metadata.annotations.AnnotationObject) FetchPlan(javax.jdo.annotations.FetchPlan) FetchPlanMetaData(org.datanucleus.metadata.FetchPlanMetaData) IdentityMetaData(org.datanucleus.metadata.IdentityMetaData) InheritanceMetaData(org.datanucleus.metadata.InheritanceMetaData) AbstractClassMetaData(org.datanucleus.metadata.AbstractClassMetaData) SequenceMetaData(org.datanucleus.metadata.SequenceMetaData) InvalidClassMetaDataException(org.datanucleus.metadata.InvalidClassMetaDataException) Column(javax.jdo.annotations.Column) ForeignKeyAction(javax.jdo.annotations.ForeignKeyAction) VersionStrategy(javax.jdo.annotations.VersionStrategy) ForeignKeyMetaData(org.datanucleus.metadata.ForeignKeyMetaData) ColumnMetaData(org.datanucleus.metadata.ColumnMetaData) FileMetaData(org.datanucleus.metadata.FileMetaData) FetchGroupMemberMetaData(org.datanucleus.metadata.FetchGroupMemberMetaData) Join(javax.jdo.annotations.Join) Persistent(javax.jdo.annotations.Persistent) UniqueMetaData(org.datanucleus.metadata.UniqueMetaData) ForeignKey(javax.jdo.annotations.ForeignKey) PrimaryKeyMetaData(org.datanucleus.metadata.PrimaryKeyMetaData) IndexMetaData(org.datanucleus.metadata.IndexMetaData) Extension(javax.jdo.annotations.Extension) DiscriminatorMetaData(org.datanucleus.metadata.DiscriminatorMetaData) FetchGroup(javax.jdo.annotations.FetchGroup) AnnotationObject(org.datanucleus.metadata.annotations.AnnotationObject) JoinMetaData(org.datanucleus.metadata.JoinMetaData) Unique(javax.jdo.annotations.Unique) FetchGroupMetaData(org.datanucleus.metadata.FetchGroupMetaData)

Example 5 with IndexMetaData

use of org.datanucleus.metadata.IndexMetaData in project datanucleus-api-jdo by datanucleus.

the class JDOAnnotationReader method processMemberAnnotations.

/**
 * Convenience method to process the annotations for a field/property. The passed annotations may have been specified on the field or on the getter methods.
 * @param cmd The ClassMetaData/InterfaceMetaData to update
 * @param member The field/property
 * @param annotations Annotations for the field/property
 * @return The FieldMetaData/PropertyMetaData that was added (if any)
 */
protected AbstractMemberMetaData processMemberAnnotations(AbstractClassMetaData cmd, Member member, AnnotationObject[] annotations) {
    if (annotations == null || annotations.length == 0) {
        return null;
    }
    AbstractMemberMetaData mmd = null;
    boolean primaryKey = false;
    boolean serialised = false;
    boolean embeddedMember = false;
    boolean nonPersistentField = false;
    boolean transactionalField = false;
    String cacheable = null;
    Class[] elementTypes = null;
    String embeddedElement = null;
    String serializedElement = null;
    String dependentElement = null;
    Class[] keyTypes = null;
    String embeddedKey = null;
    String serializedKey = null;
    String dependentKey = null;
    Class[] valueTypes = null;
    String embeddedValue = null;
    String serializedValue = null;
    String dependentValue = null;
    String embeddedOwnerField = null;
    String embeddedNullIndicatorColumn = null;
    String embeddedNullIndicatorValue = null;
    Persistent[] embeddedMembers = null;
    Persistent[] embeddedElementMembers = null;
    Persistent[] embeddedKeyMembers = null;
    Persistent[] embeddedValueMembers = null;
    ColumnMetaData[] colmds = null;
    JoinMetaData joinmd = null;
    ElementMetaData elemmd = null;
    KeyMetaData keymd = null;
    ValueMetaData valuemd = null;
    OrderMetaData ordermd = null;
    IndexMetaData idxmd = null;
    UniqueMetaData unimd = null;
    ForeignKeyMetaData fkmd = null;
    Map<String, String> extensions = null;
    Class convertConverterCls = null;
    for (AnnotationObject annotation : annotations) {
        String annName = annotation.getName();
        Map<String, Object> annotationValues = annotation.getNameValueMap();
        if (annName.equals(JDOAnnotationUtils.PERSISTENT)) {
            String pkStr = "" + annotationValues.get("primaryKey");
            Boolean pk = null;
            if (!StringUtils.isWhitespace(pkStr)) {
                pk = Boolean.valueOf(pkStr);
            }
            String dfgStr = (String) annotationValues.get("defaultFetchGroup");
            Boolean dfg = null;
            if (!StringUtils.isWhitespace(dfgStr)) {
                dfg = Boolean.valueOf(dfgStr);
            }
            String nullValue = JDOAnnotationUtils.getNullValueString((NullValue) annotationValues.get("nullValue"));
            String embStr = (String) annotationValues.get("embedded");
            Boolean embedded = null;
            if (!StringUtils.isWhitespace(embStr)) {
                embedded = Boolean.valueOf(embStr);
            }
            String serStr = (String) annotationValues.get("serialized");
            Boolean serialized = null;
            if (!StringUtils.isWhitespace(serStr)) {
                serialized = Boolean.valueOf(serStr);
            }
            String depStr = (String) annotationValues.get("dependent");
            Boolean dependent = null;
            if (!StringUtils.isWhitespace(depStr)) {
                dependent = Boolean.valueOf(depStr);
            }
            String valueStrategy = JDOAnnotationUtils.getValueGenerationStrategyString((IdGeneratorStrategy) annotationValues.get("valueStrategy"));
            String customValueStrategy = (String) annotationValues.get("customValueStrategy");
            if (!StringUtils.isWhitespace(customValueStrategy)) {
                // User has provided an extension strategy
                valueStrategy = customValueStrategy;
            }
            FieldPersistenceModifier modifier = JDOAnnotationUtils.getFieldPersistenceModifier((PersistenceModifier) annotationValues.get("persistenceModifier"));
            if (modifier == null) {
                modifier = FieldPersistenceModifier.PERSISTENT;
            }
            String sequence = (String) annotationValues.get("sequence");
            String mappedBy = (String) annotationValues.get("mappedBy");
            String table = (String) annotationValues.get("table");
            String column = (String) annotationValues.get("column");
            String loadFetchGroup = (String) annotationValues.get("loadFetchGroup");
            String fieldTypeName = null;
            int recursionDepth = ((Integer) annotationValues.get("recursionDepth")).intValue();
            cacheable = (String) annotationValues.get("cacheable");
            Class[] fieldTypes = (Class[]) annotationValues.get("types");
            if (fieldTypes != null && fieldTypes.length > 0) {
                StringBuilder typeStr = new StringBuilder();
                for (Class fieldType : fieldTypes) {
                    if (typeStr.length() > 0) {
                        typeStr.append(',');
                    }
                    if (fieldType != null && fieldType != void.class) {
                        typeStr.append(fieldType.getName());
                    }
                }
                fieldTypeName = typeStr.toString();
            }
            dependentElement = (String) annotationValues.get("dependentElement");
            serializedElement = (String) annotationValues.get("serializedElement");
            embeddedElement = (String) annotationValues.get("embeddedElement");
            dependentKey = (String) annotationValues.get("dependentKey");
            serializedKey = (String) annotationValues.get("serializedKey");
            embeddedKey = (String) annotationValues.get("embeddedKey");
            dependentValue = (String) annotationValues.get("dependentValue");
            serializedValue = (String) annotationValues.get("serializedValue");
            embeddedValue = (String) annotationValues.get("embeddedValue");
            Class converterCls = (Class) annotationValues.get("converter");
            if (converterCls == UseDefault.class) {
                converterCls = null;
            }
            Boolean disableConversion = (Boolean) annotationValues.get("useDefaultConversion");
            mmd = member.isProperty() ? new PropertyMetaData(cmd, member.getName()) : new FieldMetaData(cmd, member.getName());
            if (isPersistenceContext()) {
                if (disableConversion != null && disableConversion) {
                    mmd.setTypeConverterDisabled();
                } else if (converterCls != null) {
                    TypeManager typeMgr = mmgr.getNucleusContext().getTypeManager();
                    if (typeMgr.getTypeConverterForName(converterCls.getName()) == null) {
                        // Not yet cached an instance of this converter so create one
                        AttributeConverter conv = JDOTypeConverterUtils.createAttributeConverter((PersistenceNucleusContext) mmgr.getNucleusContext(), converterCls);
                        Class attrType = JDOTypeConverterUtils.getAttributeTypeForAttributeConverter(converterCls, member.getType());
                        Class dbType = JDOTypeConverterUtils.getDatastoreTypeForAttributeConverter(converterCls, attrType, null);
                        // Register the TypeConverter under the name of the AttributeConverter class
                        JDOTypeConverter typeConv = new JDOTypeConverter(conv);
                        typeMgr.registerConverter(converterCls.getName(), typeConv, attrType, dbType, false, null);
                    }
                    mmd.setTypeConverterName(converterCls.getName());
                }
            }
            if (modifier != null) {
                mmd.setPersistenceModifier(modifier);
            }
            if (dfg != null) {
                mmd.setDefaultFetchGroup(dfg);
            }
            if (pk != null) {
                mmd.setPrimaryKey(pk);
            }
            if (embedded != null) {
                mmd.setEmbedded(embedded);
            }
            if (serialized != null) {
                mmd.setSerialised(serialized);
            }
            if (dependent != null) {
                mmd.setDependent(dependent);
            }
            mmd.setNullValue(org.datanucleus.metadata.NullValue.getNullValue(nullValue));
            mmd.setMappedBy(mappedBy);
            mmd.setColumn(column);
            mmd.setTable(table);
            mmd.setRecursionDepth(recursionDepth);
            mmd.setLoadFetchGroup(loadFetchGroup);
            mmd.setValueStrategy(valueStrategy);
            mmd.setSequence(sequence);
            mmd.setFieldTypes(fieldTypeName);
            // Add any columns defined on the @Persistent
            Column[] columns = (Column[]) annotationValues.get("columns");
            if (columns != null && columns.length > 0) {
                for (Column col : columns) {
                    mmd.addColumn(JDOAnnotationUtils.getColumnMetaDataForColumnAnnotation(col));
                }
            }
            JDOAnnotationUtils.addExtensionsToMetaData(mmd, (Extension[]) annotationValues.get("extensions"));
        } else if (annName.equals(JDOAnnotationUtils.PRIMARY_KEY)) {
            primaryKey = true;
            if (cmd.getIdentityType() == IdentityType.DATASTORE) {
                // ClassMetaData was created as DATASTORE so change it to APPLICATION
                cmd.setIdentityType(IdentityType.APPLICATION);
            }
        } else if (annName.equals(JDOAnnotationUtils.SERIALIZED)) {
            serialised = true;
        } else if (annName.equals(JDOAnnotationUtils.NOTPERSISTENT)) {
            nonPersistentField = true;
        } else if (annName.equals(JDOAnnotationUtils.TRANSACTIONAL)) {
            transactionalField = true;
        } else if (annName.equals(JDOAnnotationUtils.COLUMNS)) {
            // Multiple column specification
            Column[] cols = (Column[]) annotationValues.get("value");
            if (cols != null && cols.length > 0) {
                colmds = new ColumnMetaData[cols.length];
                for (int j = 0; j < cols.length; j++) {
                    colmds[j] = JDOAnnotationUtils.getColumnMetaDataForColumnAnnotation(cols[j]);
                    JDOAnnotationUtils.addExtensionsToMetaData(colmds[j], cols[j].extensions());
                }
            }
        } else if (annName.equals(JDOAnnotationUtils.COLUMN)) {
            // Single column specification
            colmds = new ColumnMetaData[1];
            colmds[0] = JDOAnnotationUtils.getColumnMetaDataForAnnotations(annotationValues);
            JDOAnnotationUtils.addExtensionsToMetaData(colmds[0], (Extension[]) annotationValues.get("extensions"));
        } else if (annName.equals(JDOAnnotationUtils.JOIN)) {
            String joinColumn = (String) annotationValues.get("column");
            String joinOuter = (String) annotationValues.get("outer");
            String deleteAction = JDOAnnotationUtils.getForeignKeyActionString((ForeignKeyAction) annotationValues.get("deleteAction"));
            String pkName = (String) annotationValues.get("primaryKey");
            String fkName = (String) annotationValues.get("foreignKey");
            String generateFK = (String) annotationValues.get("generateForeignKey");
            String indexed = (String) annotationValues.get("indexed");
            String indexName = (String) annotationValues.get("index");
            String unique = (String) annotationValues.get("unique");
            String uniqueName = (String) annotationValues.get("uniqueKey");
            String generatePK = (String) annotationValues.get("generatePrimaryKey");
            if (!StringUtils.isWhitespace(uniqueName)) {
                unique = "true";
            }
            if (!StringUtils.isWhitespace(indexName)) {
                indexed = "true";
            }
            Column[] joinColumns = (Column[]) annotationValues.get("columns");
            joinmd = new JoinMetaData();
            joinmd.setColumnName(joinColumn);
            joinmd.setOuter(MetaDataUtils.getBooleanForString(joinOuter, false));
            joinmd.setIndexed(IndexedValue.getIndexedValue(indexed));
            joinmd.setUnique(unique);
            joinmd.setDeleteAction(deleteAction);
            if (!StringUtils.isWhitespace(pkName)) {
                PrimaryKeyMetaData pkmd = new PrimaryKeyMetaData();
                pkmd.setName(pkName);
                joinmd.setPrimaryKeyMetaData(pkmd);
            } else if (generatePK != null && generatePK.equalsIgnoreCase("true")) {
                joinmd.setPrimaryKeyMetaData(new PrimaryKeyMetaData());
            }
            if (!StringUtils.isWhitespace(fkName)) {
                ForeignKeyMetaData joinFkmd = joinmd.getForeignKeyMetaData();
                if (joinFkmd == null) {
                    joinFkmd = new ForeignKeyMetaData();
                    joinFkmd.setName(fkName);
                    joinmd.setForeignKeyMetaData(joinFkmd);
                } else {
                    joinFkmd.setName(fkName);
                }
            } else if (generateFK != null && generateFK.equalsIgnoreCase("true")) {
                joinmd.setForeignKeyMetaData(new ForeignKeyMetaData());
            }
            if (!StringUtils.isWhitespace(indexName)) {
                IndexMetaData joinIdxmd = joinmd.getIndexMetaData();
                if (joinIdxmd == null) {
                    joinIdxmd = new IndexMetaData();
                    joinmd.setIndexMetaData(joinIdxmd);
                }
                joinIdxmd.setName(indexName);
            }
            if (!StringUtils.isWhitespace(uniqueName)) {
                UniqueMetaData joinUnimd = joinmd.getUniqueMetaData();
                if (joinUnimd == null) {
                    joinUnimd = new UniqueMetaData();
                    joinmd.setUniqueMetaData(joinUnimd);
                }
                joinUnimd.setName(uniqueName);
            }
            if (joinColumns != null && joinColumns.length > 0) {
                for (Column joinCol : joinColumns) {
                    joinmd.addColumn(JDOAnnotationUtils.getColumnMetaDataForColumnAnnotation(joinCol));
                }
            }
            JDOAnnotationUtils.addExtensionsToMetaData(joinmd, (Extension[]) annotationValues.get("extensions"));
        } else if (annName.equals(JDOAnnotationUtils.ELEMENT)) {
            // Element of a Collection/Array
            elementTypes = (Class[]) annotationValues.get("types");
            embeddedElement = (String) annotationValues.get("embedded");
            serializedElement = (String) annotationValues.get("serialized");
            dependentElement = (String) annotationValues.get("dependent");
            String elementDeleteAction = JDOAnnotationUtils.getForeignKeyActionString((ForeignKeyAction) annotationValues.get("deleteAction"));
            String elementUpdateAction = JDOAnnotationUtils.getForeignKeyActionString((ForeignKeyAction) annotationValues.get("updateAction"));
            String fkName = (String) annotationValues.get("foreignKey");
            String generateFK = (String) annotationValues.get("generateForeignKey");
            String indexed = (String) annotationValues.get("indexed");
            String indexName = (String) annotationValues.get("index");
            String unique = (String) annotationValues.get("unique");
            String uniqueName = (String) annotationValues.get("uniqueKey");
            Class converterCls = (Class) annotationValues.get("converter");
            if (converterCls == UseDefault.class) {
                converterCls = null;
            }
            Boolean disableConversion = (Boolean) annotationValues.get("useDefaultConversion");
            if (!StringUtils.isWhitespace(uniqueName)) {
                unique = "true";
            }
            if (!StringUtils.isWhitespace(indexName)) {
                indexed = "true";
            }
            elemmd = new ElementMetaData();
            elemmd.setTable((String) annotationValues.get("table"));
            elemmd.setColumnName((String) annotationValues.get("column"));
            elemmd.setDeleteAction(elementDeleteAction);
            elemmd.setUpdateAction(elementUpdateAction);
            elemmd.setIndexed(IndexedValue.getIndexedValue(indexed));
            elemmd.setUnique(MetaDataUtils.getBooleanForString(unique, false));
            elemmd.setMappedBy((String) annotationValues.get("mappedBy"));
            if (!StringUtils.isWhitespace(fkName)) {
                ForeignKeyMetaData elemFkmd = elemmd.getForeignKeyMetaData();
                if (elemFkmd == null) {
                    elemFkmd = new ForeignKeyMetaData();
                    elemFkmd.setName(fkName);
                    elemmd.setForeignKeyMetaData(elemFkmd);
                } else {
                    elemFkmd.setName(fkName);
                }
            } else if (generateFK != null && generateFK.equalsIgnoreCase("true")) {
                elemmd.setForeignKeyMetaData(new ForeignKeyMetaData());
            }
            if (!StringUtils.isWhitespace(indexName)) {
                IndexMetaData elemIdxmd = elemmd.getIndexMetaData();
                if (elemIdxmd == null) {
                    elemIdxmd = new IndexMetaData();
                    elemmd.setIndexMetaData(elemIdxmd);
                }
                elemIdxmd.setName(indexName);
            }
            if (!StringUtils.isWhitespace(uniqueName)) {
                UniqueMetaData elemUnimd = elemmd.getUniqueMetaData();
                if (elemUnimd == null) {
                    elemUnimd = new UniqueMetaData();
                    elemmd.setUniqueMetaData(elemUnimd);
                }
                elemUnimd.setName(uniqueName);
            }
            Column[] elementColumns = (Column[]) annotationValues.get("columns");
            if (elementColumns != null && elementColumns.length > 0) {
                for (Column elementCol : elementColumns) {
                    elemmd.addColumn(JDOAnnotationUtils.getColumnMetaDataForColumnAnnotation(elementCol));
                }
            }
            if (isPersistenceContext()) {
                if (disableConversion != null && disableConversion) {
                    elemmd.addExtension(MetaData.EXTENSION_MEMBER_TYPE_CONVERTER_DISABLED, "true");
                } else if (converterCls != null) {
                    TypeManager typeMgr = mmgr.getNucleusContext().getTypeManager();
                    if (typeMgr.getTypeConverterForName(converterCls.getName()) == null) {
                        // Not yet cached an instance of this converter so create one
                        AttributeConverter conv = JDOTypeConverterUtils.createAttributeConverter((PersistenceNucleusContext) mmgr.getNucleusContext(), converterCls);
                        Class attrType = JDOTypeConverterUtils.getAttributeTypeForAttributeConverter(converterCls, ClassUtils.getCollectionElementType(member.getType(), member.getGenericType()));
                        Class dbType = JDOTypeConverterUtils.getDatastoreTypeForAttributeConverter(converterCls, attrType, null);
                        // Register the TypeConverter under the name of the AttributeConverter class
                        JDOTypeConverter typeConv = new JDOTypeConverter(conv);
                        typeMgr.registerConverter(converterCls.getName(), typeConv, attrType, dbType, false, null);
                    }
                    elemmd.addExtension(MetaData.EXTENSION_MEMBER_TYPE_CONVERTER_NAME, converterCls.getName());
                }
            }
            JDOAnnotationUtils.addExtensionsToMetaData(elemmd, (Extension[]) annotationValues.get("extensions"));
            Embedded[] embeddedMappings = (Embedded[]) annotationValues.get("embeddedMapping");
            if (embeddedMappings != null && embeddedMappings.length > 0) {
                // Embedded element
                EmbeddedMetaData embmd = new EmbeddedMetaData();
                embmd.setOwnerMember(embeddedMappings[0].ownerMember());
                embmd.setNullIndicatorColumn(embeddedMappings[0].nullIndicatorColumn());
                embmd.setNullIndicatorValue(embeddedMappings[0].nullIndicatorValue());
                try {
                    Discriminator disc = embeddedMappings[0].discriminatorColumnName();
                    if (disc != null) {
                        DiscriminatorMetaData dismd = embmd.newDiscriminatorMetadata();
                        dismd.setColumnName(disc.column());
                        dismd.setStrategy(JDOAnnotationUtils.getDiscriminatorStrategyString(disc.strategy()));
                    // TODO Support other attributes of discriminator?
                    }
                } catch (Throwable thr) {
                // Ignore this. Maybe not using JDO3.1 jar
                }
                elemmd.setEmbeddedMetaData(embmd);
                embeddedElementMembers = embeddedMappings[0].members();
            // Delay addition of embeddedElementMembers til completion of this loop so we have the
            // element type
            }
        } else if (annName.equals(JDOAnnotationUtils.KEY)) {
            // Key of a Map
            keyTypes = (Class[]) annotationValues.get("types");
            embeddedKey = (String) annotationValues.get("embedded");
            serializedKey = (String) annotationValues.get("serialized");
            dependentKey = (String) annotationValues.get("dependent");
            String keyDeleteAction = JDOAnnotationUtils.getForeignKeyActionString((ForeignKeyAction) annotationValues.get("deleteAction"));
            String keyUpdateAction = JDOAnnotationUtils.getForeignKeyActionString((ForeignKeyAction) annotationValues.get("updateAction"));
            String fkName = (String) annotationValues.get("foreignKey");
            String generateFK = (String) annotationValues.get("generateForeignKey");
            String indexed = (String) annotationValues.get("indexed");
            String indexName = (String) annotationValues.get("index");
            String unique = (String) annotationValues.get("unique");
            String uniqueName = (String) annotationValues.get("uniqueKey");
            Class converterCls = (Class) annotationValues.get("converter");
            if (converterCls == UseDefault.class) {
                converterCls = null;
            }
            Boolean disableConversion = (Boolean) annotationValues.get("useDefaultConversion");
            if (!StringUtils.isWhitespace(uniqueName)) {
                unique = "true";
            }
            if (!StringUtils.isWhitespace(indexName)) {
                indexed = "true";
            }
            keymd = new KeyMetaData();
            keymd.setTable((String) annotationValues.get("table"));
            keymd.setColumnName((String) annotationValues.get("column"));
            keymd.setDeleteAction(keyDeleteAction);
            keymd.setUpdateAction(keyUpdateAction);
            keymd.setIndexed(IndexedValue.getIndexedValue(indexed));
            keymd.setUnique(MetaDataUtils.getBooleanForString(unique, false));
            keymd.setMappedBy((String) annotationValues.get("mappedBy"));
            if (!StringUtils.isWhitespace(fkName)) {
                ForeignKeyMetaData keyFkmd = keymd.getForeignKeyMetaData();
                if (keyFkmd == null) {
                    keyFkmd = new ForeignKeyMetaData();
                    keyFkmd.setName(fkName);
                    keymd.setForeignKeyMetaData(keyFkmd);
                } else {
                    keyFkmd.setName(fkName);
                }
            } else if (generateFK != null && generateFK.equalsIgnoreCase("true")) {
                keymd.setForeignKeyMetaData(new ForeignKeyMetaData());
            }
            if (!StringUtils.isWhitespace(indexName)) {
                IndexMetaData keyIdxmd = keymd.getIndexMetaData();
                if (keyIdxmd == null) {
                    keyIdxmd = new IndexMetaData();
                    keymd.setIndexMetaData(keyIdxmd);
                }
                keyIdxmd.setName(indexName);
            }
            if (!StringUtils.isWhitespace(uniqueName)) {
                UniqueMetaData keyUnimd = keymd.getUniqueMetaData();
                if (keyUnimd == null) {
                    keyUnimd = new UniqueMetaData();
                    keymd.setUniqueMetaData(keyUnimd);
                }
                keyUnimd.setName(uniqueName);
            }
            Column[] keyColumns = (Column[]) annotationValues.get("columns");
            if (keyColumns != null && keyColumns.length > 0) {
                for (Column keyCol : keyColumns) {
                    keymd.addColumn(JDOAnnotationUtils.getColumnMetaDataForColumnAnnotation(keyCol));
                }
            }
            if (isPersistenceContext()) {
                if (disableConversion != null && disableConversion) {
                    keymd.addExtension(MetaData.EXTENSION_MEMBER_TYPE_CONVERTER_DISABLED, "true");
                } else if (converterCls != null) {
                    TypeManager typeMgr = mmgr.getNucleusContext().getTypeManager();
                    if (typeMgr.getTypeConverterForName(converterCls.getName()) == null) {
                        // Not yet cached an instance of this converter so create one
                        AttributeConverter conv = JDOTypeConverterUtils.createAttributeConverter((PersistenceNucleusContext) mmgr.getNucleusContext(), converterCls);
                        Class attrType = JDOTypeConverterUtils.getAttributeTypeForAttributeConverter(converterCls, ClassUtils.getMapKeyType(member.getType(), member.getGenericType()));
                        Class dbType = JDOTypeConverterUtils.getDatastoreTypeForAttributeConverter(converterCls, attrType, null);
                        // Register the TypeConverter under the name of the AttributeConverter class
                        JDOTypeConverter typeConv = new JDOTypeConverter(conv);
                        typeMgr.registerConverter(converterCls.getName(), typeConv, attrType, dbType, false, null);
                    }
                    keymd.addExtension(MetaData.EXTENSION_MEMBER_TYPE_CONVERTER_NAME, converterCls.getName());
                }
            }
            JDOAnnotationUtils.addExtensionsToMetaData(keymd, (Extension[]) annotationValues.get("extensions"));
            Embedded[] embeddedMappings = (Embedded[]) annotationValues.get("embeddedMapping");
            if (embeddedMappings != null && embeddedMappings.length > 0) {
                // Embedded key
                EmbeddedMetaData embmd = new EmbeddedMetaData();
                embmd.setOwnerMember(embeddedMappings[0].ownerMember());
                embmd.setNullIndicatorColumn(embeddedMappings[0].nullIndicatorColumn());
                embmd.setNullIndicatorValue(embeddedMappings[0].nullIndicatorValue());
                keymd.setEmbeddedMetaData(embmd);
                embeddedKeyMembers = embeddedMappings[0].members();
            // Delay addition of embeddedKeyMembers til completion of this loop so we have the key
            // type
            }
        } else if (annName.equals(JDOAnnotationUtils.VALUE)) {
            // Value of a Map
            valueTypes = (Class[]) annotationValues.get("types");
            embeddedValue = (String) annotationValues.get("embedded");
            serializedValue = (String) annotationValues.get("serialized");
            dependentValue = (String) annotationValues.get("dependent");
            String valueDeleteAction = JDOAnnotationUtils.getForeignKeyActionString((ForeignKeyAction) annotationValues.get("deleteAction"));
            String valueUpdateAction = JDOAnnotationUtils.getForeignKeyActionString((ForeignKeyAction) annotationValues.get("updateAction"));
            String fkName = (String) annotationValues.get("foreignKey");
            String generateFK = (String) annotationValues.get("generateForeignKey");
            String indexed = (String) annotationValues.get("indexed");
            String indexName = (String) annotationValues.get("index");
            String unique = (String) annotationValues.get("unique");
            String uniqueName = (String) annotationValues.get("uniqueKey");
            Class converterCls = (Class) annotationValues.get("converter");
            if (converterCls == UseDefault.class) {
                converterCls = null;
            }
            Boolean disableConversion = (Boolean) annotationValues.get("useDefaultConversion");
            if (!StringUtils.isWhitespace(uniqueName)) {
                unique = "true";
            }
            if (!StringUtils.isWhitespace(indexName)) {
                indexed = "true";
            }
            valuemd = new ValueMetaData();
            valuemd.setTable((String) annotationValues.get("table"));
            valuemd.setColumnName((String) annotationValues.get("column"));
            valuemd.setDeleteAction(valueDeleteAction);
            valuemd.setUpdateAction(valueUpdateAction);
            valuemd.setIndexed(IndexedValue.getIndexedValue(indexed));
            valuemd.setUnique(MetaDataUtils.getBooleanForString(unique, false));
            valuemd.setMappedBy((String) annotationValues.get("mappedBy"));
            if (!StringUtils.isWhitespace(fkName)) {
                ForeignKeyMetaData valueFkmd = valuemd.getForeignKeyMetaData();
                if (valueFkmd == null) {
                    valueFkmd = new ForeignKeyMetaData();
                    valueFkmd.setName(fkName);
                    valuemd.setForeignKeyMetaData(valueFkmd);
                } else {
                    valueFkmd.setName(fkName);
                }
            } else if (generateFK != null && generateFK.equalsIgnoreCase("true")) {
                valuemd.setForeignKeyMetaData(new ForeignKeyMetaData());
            }
            if (!StringUtils.isWhitespace(indexName)) {
                IndexMetaData valueIdxmd = valuemd.getIndexMetaData();
                if (valueIdxmd == null) {
                    valueIdxmd = new IndexMetaData();
                    valuemd.setIndexMetaData(valueIdxmd);
                }
                valueIdxmd.setName(indexName);
            }
            if (!StringUtils.isWhitespace(uniqueName)) {
                UniqueMetaData valueUnimd = valuemd.getUniqueMetaData();
                if (valueUnimd == null) {
                    valueUnimd = new UniqueMetaData();
                    valuemd.setUniqueMetaData(valueUnimd);
                }
                valueUnimd.setName(uniqueName);
            }
            Column[] valueColumns = (Column[]) annotationValues.get("columns");
            if (valueColumns != null && valueColumns.length > 0) {
                for (Column valueCol : valueColumns) {
                    valuemd.addColumn(JDOAnnotationUtils.getColumnMetaDataForColumnAnnotation(valueCol));
                }
            }
            if (isPersistenceContext()) {
                if (disableConversion != null && disableConversion) {
                    valuemd.addExtension(MetaData.EXTENSION_MEMBER_TYPE_CONVERTER_DISABLED, "true");
                } else if (converterCls != null) {
                    TypeManager typeMgr = mmgr.getNucleusContext().getTypeManager();
                    if (typeMgr.getTypeConverterForName(converterCls.getName()) == null) {
                        // Not yet cached an instance of this converter so create one
                        AttributeConverter conv = JDOTypeConverterUtils.createAttributeConverter((PersistenceNucleusContext) mmgr.getNucleusContext(), converterCls);
                        Class attrType = JDOTypeConverterUtils.getAttributeTypeForAttributeConverter(converterCls, ClassUtils.getMapValueType(member.getType(), member.getGenericType()));
                        Class dbType = JDOTypeConverterUtils.getDatastoreTypeForAttributeConverter(converterCls, attrType, null);
                        // Register the TypeConverter under the name of the AttributeConverter class
                        JDOTypeConverter typeConv = new JDOTypeConverter(conv);
                        typeMgr.registerConverter(converterCls.getName(), typeConv, attrType, dbType, false, null);
                    }
                    valuemd.addExtension(MetaData.EXTENSION_MEMBER_TYPE_CONVERTER_NAME, converterCls.getName());
                }
            }
            JDOAnnotationUtils.addExtensionsToMetaData(valuemd, (Extension[]) annotationValues.get("extensions"));
            Embedded[] embeddedMappings = (Embedded[]) annotationValues.get("embeddedMapping");
            if (embeddedMappings != null && embeddedMappings.length > 0) {
                // Embedded value
                EmbeddedMetaData embmd = new EmbeddedMetaData();
                embmd.setOwnerMember(embeddedMappings[0].ownerMember());
                embmd.setNullIndicatorColumn(embeddedMappings[0].nullIndicatorColumn());
                embmd.setNullIndicatorValue(embeddedMappings[0].nullIndicatorValue());
                valuemd.setEmbeddedMetaData(embmd);
                embeddedValueMembers = embeddedMappings[0].members();
            // Delay addition of embeddedValueMembers til completion of this loop so we have the value type
            }
        } else if (annName.equals(JDOAnnotationUtils.ORDER)) {
            ordermd = new OrderMetaData();
            ordermd.setColumnName((String) annotationValues.get("column"));
            ordermd.setMappedBy((String) annotationValues.get("mappedBy"));
            Column[] orderColumns = (Column[]) annotationValues.get("columns");
            if (orderColumns != null && orderColumns.length > 0) {
                for (Column orderCol : orderColumns) {
                    ordermd.addColumn(JDOAnnotationUtils.getColumnMetaDataForColumnAnnotation(orderCol));
                }
            }
            JDOAnnotationUtils.addExtensionsToMetaData(ordermd, (Extension[]) annotationValues.get("extensions"));
        } else if (annName.equals(JDOAnnotationUtils.EMBEDDED)) {
            embeddedMember = true;
            embeddedOwnerField = (String) annotationValues.get("ownerMember");
            if (StringUtils.isWhitespace(embeddedOwnerField)) {
                embeddedOwnerField = null;
            }
            embeddedNullIndicatorColumn = (String) annotationValues.get("nullIndicatorColumn");
            if (StringUtils.isWhitespace(embeddedNullIndicatorColumn)) {
                embeddedNullIndicatorColumn = null;
            }
            embeddedNullIndicatorValue = (String) annotationValues.get("nullIndicatorValue");
            if (StringUtils.isWhitespace(embeddedNullIndicatorValue)) {
                embeddedNullIndicatorValue = null;
            }
            embeddedMembers = (Persistent[]) annotationValues.get("members");
            if (embeddedMembers != null && embeddedMembers.length == 0) {
                embeddedMembers = null;
            }
        // TODO Support discriminator
        } else if (annName.equals(JDOAnnotationUtils.INDEX)) {
            // Index for the field
            String name = (String) annotationValues.get("name");
            String table = (String) annotationValues.get("table");
            String unique = (String) annotationValues.get("unique");
            String[] members = (String[]) annotationValues.get("members");
            Column[] columns = (Column[]) annotationValues.get("columns");
            idxmd = JDOAnnotationUtils.getIndexMetaData(name, table, unique, members, columns);
            JDOAnnotationUtils.addExtensionsToMetaData(idxmd, (Extension[]) annotationValues.get("extensions"));
        } else if (annName.equals(JDOAnnotationUtils.UNIQUE)) {
            // Unique for the field
            String name = (String) annotationValues.get("name");
            String table = (String) annotationValues.get("table");
            String deferred = (String) annotationValues.get("deferred");
            String[] members = (String[]) annotationValues.get("members");
            Column[] columns = (Column[]) annotationValues.get("columns");
            unimd = JDOAnnotationUtils.getUniqueMetaData(name, table, deferred, members, columns);
            JDOAnnotationUtils.addExtensionsToMetaData(unimd, (Extension[]) annotationValues.get("extensions"));
        } else if (annName.equals(JDOAnnotationUtils.FOREIGNKEY)) {
            // ForeignKey for field
            String name = (String) annotationValues.get("name");
            String table = (String) annotationValues.get("table");
            String unique = (String) annotationValues.get("unique");
            String deferred = (String) annotationValues.get("deferred");
            String deleteAction = JDOAnnotationUtils.getForeignKeyActionString((ForeignKeyAction) annotationValues.get("deleteAction"));
            String updateAction = JDOAnnotationUtils.getForeignKeyActionString((ForeignKeyAction) annotationValues.get("updateAction"));
            String[] members = (String[]) annotationValues.get("members");
            Column[] columns = (Column[]) annotationValues.get("columns");
            fkmd = JDOAnnotationUtils.getFKMetaData(name, table, unique, deferred, deleteAction, updateAction, members, columns);
            JDOAnnotationUtils.addExtensionsToMetaData(fkmd, (Extension[]) annotationValues.get("extensions"));
        } else if (annName.equals(JDOAnnotationUtils.CACHEABLE)) {
            String cache = (String) annotationValues.get("value");
            if (cache != null) {
                cacheable = cache;
            }
        } else if (annName.equals(JDOAnnotationUtils.CONVERT)) {
            convertConverterCls = (Class) annotationValues.get("value");
            if (convertConverterCls == UseDefault.class) {
                convertConverterCls = null;
            }
            Boolean enabled = (Boolean) annotationValues.get("enabled");
            if (!enabled) {
                convertConverterCls = null;
            }
        } else if (annName.equals(JDOAnnotationUtils.EXTENSIONS)) {
            Extension[] values = (Extension[]) annotationValues.get("value");
            if (values != null && values.length > 0) {
                extensions = new HashMap<String, String>(values.length);
                for (Extension ext : values) {
                    String vendorName = ext.vendorName();
                    if (StringUtils.isWhitespace(vendorName)) {
                        throw new InvalidMetaDataException("044160", vendorName, ext.key().toString(), ext.value().toString());
                    } else if (vendorName.equalsIgnoreCase(MetaData.VENDOR_NAME)) {
                        extensions.put(ext.key().toString(), ext.value().toString());
                    }
                }
            }
        } else if (annName.equals(JDOAnnotationUtils.EXTENSION)) {
            String vendorName = (String) annotationValues.get("vendorName");
            if (StringUtils.isWhitespace(vendorName)) {
                throw new InvalidMetaDataException("044160", vendorName, annotationValues.get("key"), annotationValues.get("value"));
            } else if (vendorName.equalsIgnoreCase(MetaData.VENDOR_NAME)) {
                extensions = new HashMap<String, String>(1);
                extensions.put((String) annotationValues.get("key"), (String) annotationValues.get("value"));
            }
        } else {
            NucleusLogger.METADATA.debug(Localiser.msg("044211", cmd.getFullClassName(), member.getName(), annotation.getName()));
        }
    }
    if (mmd == null && (transactionalField || nonPersistentField || primaryKey || colmds != null || serialised || embeddedOwnerField != null || embeddedNullIndicatorColumn != null || embeddedNullIndicatorValue != null || embeddedMembers != null || elemmd != null || keymd != null || valuemd != null || ordermd != null || idxmd != null || unimd != null || fkmd != null || joinmd != null || extensions != null || convertConverterCls != null)) {
        // @Persistent not supplied but other relevant annotations defined, so add default metadata element
        mmd = member.isProperty() ? new PropertyMetaData(cmd, member.getName()) : new FieldMetaData(cmd, member.getName());
        if (primaryKey) {
            mmd.setPersistenceModifier(FieldPersistenceModifier.PERSISTENT);
            mmd.setPrimaryKey(primaryKey);
        }
        if (serialised) {
            mmd.setPersistenceModifier(FieldPersistenceModifier.PERSISTENT);
        }
    }
    if (mmd != null) {
        cmd.addMember(mmd);
        if (primaryKey) {
            mmd.setPrimaryKey(true);
        }
        if (serialised) {
            mmd.setSerialised(true);
        }
        if (embeddedMember) {
            mmd.setEmbedded(true);
        }
        if (nonPersistentField) {
            mmd.setNotPersistent();
        }
        if (transactionalField) {
            mmd.setTransactional();
        }
        if (isPersistenceContext()) {
            if (convertConverterCls != null) {
                TypeManager typeMgr = mmgr.getNucleusContext().getTypeManager();
                if (typeMgr.getTypeConverterForName(convertConverterCls.getName()) == null) {
                    // Not yet cached an instance of this converter so create one
                    AttributeConverter conv = JDOTypeConverterUtils.createAttributeConverter((PersistenceNucleusContext) mmgr.getNucleusContext(), convertConverterCls);
                    Class attrType = JDOTypeConverterUtils.getAttributeTypeForAttributeConverter(convertConverterCls, member.getType());
                    Class dbType = JDOTypeConverterUtils.getDatastoreTypeForAttributeConverter(convertConverterCls, attrType, null);
                    // Register the TypeConverter under the name of the AttributeConverter class
                    JDOTypeConverter typeConv = new JDOTypeConverter(conv);
                    typeMgr.registerConverter(convertConverterCls.getName(), typeConv, attrType, dbType, false, null);
                }
                mmd.setTypeConverterName(convertConverterCls.getName());
            }
        }
        // Add any embedded info
        if (embeddedMember) {
            if (embeddedOwnerField != null || embeddedNullIndicatorColumn != null || embeddedNullIndicatorValue != null || embeddedMembers != null) {
                EmbeddedMetaData embmd = new EmbeddedMetaData();
                embmd.setOwnerMember(embeddedOwnerField);
                embmd.setNullIndicatorColumn(embeddedNullIndicatorColumn);
                embmd.setNullIndicatorValue(embeddedNullIndicatorValue);
                mmd.setEmbeddedMetaData(embmd);
                if (embeddedMembers != null && embeddedMembers.length > 0) {
                    for (Persistent embMember : embeddedMembers) {
                        // Add the metadata for the embedded field/property to the embedded metadata
                        String memberName = embMember.name();
                        if (memberName.indexOf('.') > 0) {
                            memberName = memberName.substring(memberName.lastIndexOf('.') + 1);
                        }
                        AbstractMemberMetaData embfmd = getFieldMetaDataForPersistent(embmd, embMember, isMemberOfClassAField(member.getType(), memberName));
                        embmd.addMember(embfmd);
                    }
                }
            }
        }
        TypeManager typeManager = mmgr.getNucleusContext().getTypeManager();
        ContainerHandler containerHandler = typeManager.getContainerHandler(member.getType());
        ContainerMetaData contmd = null;
        // If the field is a container then add its container element
        if (containerHandler != null) {
            contmd = containerHandler.newMetaData();
        }
        if (contmd instanceof CollectionMetaData) {
            Class collectionElementType = null;
            StringBuilder elementTypeStr = new StringBuilder();
            if (elementTypes != null && elementTypes.length > 0 && elementTypes[0] != void.class) {
                // User-specified element type(s)
                for (Class elementType : elementTypes) {
                    if (elementTypeStr.length() > 0) {
                        elementTypeStr.append(',');
                    }
                    elementTypeStr.append(elementType.getName());
                }
                // Use the first only
                collectionElementType = elementTypes[0];
            } else {
                // Try to derive element type from generics info
                collectionElementType = ClassUtils.getCollectionElementType(member.getType(), member.getGenericType());
            }
            contmd = new CollectionMetaData();
            contmd.setParent(mmd);
            CollectionMetaData collmd = (CollectionMetaData) contmd;
            collmd.setElementType(elementTypeStr.toString());
            if (!StringUtils.isWhitespace(embeddedElement)) {
                collmd.setEmbeddedElement(Boolean.valueOf(embeddedElement));
            }
            if (!StringUtils.isWhitespace(serializedElement)) {
                collmd.setSerializedElement(Boolean.valueOf(serializedElement));
            }
            if (!StringUtils.isWhitespace(dependentElement)) {
                collmd.setDependentElement(Boolean.valueOf(dependentElement));
            }
            if ((embeddedElementMembers != null || "true".equalsIgnoreCase(embeddedElement)) && elemmd == null) {
                elemmd = new ElementMetaData();
                mmd.setElementMetaData(elemmd);
            }
            if (elemmd != null) {
                if (embeddedElementMembers != null) {
                    // Add any embedded element mappings
                    EmbeddedMetaData embmd = elemmd.getEmbeddedMetaData();
                    if ("true".equalsIgnoreCase(embeddedElement) && elemmd.getEmbeddedMetaData() == null) {
                        // Create EmbeddedMetaData for element since not existing
                        embmd = elemmd.newEmbeddedMetaData();
                    }
                    for (Persistent embeddedElementMember : embeddedElementMembers) {
                        // Add the metadata for the embedded element to the embedded metadata
                        String memberName = embeddedElementMember.name();
                        if (memberName.indexOf('.') > 0) {
                            memberName = memberName.substring(memberName.lastIndexOf('.') + 1);
                        }
                        AbstractMemberMetaData embfmd = getFieldMetaDataForPersistent(embmd, embeddedElementMember, isMemberOfClassAField(collectionElementType, memberName));
                        embmd.addMember(embfmd);
                    }
                }
            }
        } else if (contmd instanceof ArrayMetaData) {
            StringBuilder elementTypeStr = new StringBuilder();
            if (elementTypes != null && elementTypes.length > 0 && elementTypes[0] != void.class) {
                // User-specified element type(s)
                for (Class elementType : elementTypes) {
                    if (elementTypeStr.length() > 0) {
                        elementTypeStr.append(',');
                    }
                    elementTypeStr.append(elementType.getName());
                }
            } else {
                // Derive from component type
                elementTypeStr.append(member.getType().getComponentType().getName());
            }
            contmd = new ArrayMetaData();
            contmd.setParent(mmd);
            ArrayMetaData arrmd = (ArrayMetaData) contmd;
            arrmd.setElementType(elementTypeStr.toString());
            if (!StringUtils.isWhitespace(embeddedElement)) {
                arrmd.setEmbeddedElement(Boolean.valueOf(embeddedElement));
            }
            if (!StringUtils.isWhitespace(serializedElement)) {
                arrmd.setSerializedElement(Boolean.valueOf(serializedElement));
            }
            if (!StringUtils.isWhitespace(dependentElement)) {
                arrmd.setDependentElement(Boolean.valueOf(dependentElement));
            }
        } else if (contmd instanceof MapMetaData) {
            Class mapKeyType = null;
            if (keyTypes != null && keyTypes.length > 0 && keyTypes[0] != void.class) {
                // User-specified key type TODO Support multiple keys (interface implementations)
                mapKeyType = keyTypes[0];
            } else {
                // Try to derive key type from generics info
                mapKeyType = ClassUtils.getMapKeyType(member.getType(), member.getGenericType());
            }
            Class mapValueType = null;
            if (valueTypes != null && valueTypes.length > 0 && valueTypes[0] != void.class) {
                // User-specified value type TODO Support multiple values (interface implementations)
                mapValueType = valueTypes[0];
            } else {
                // Try to derive value type from generics info
                mapValueType = ClassUtils.getMapValueType(member.getType(), member.getGenericType());
            }
            contmd = new MapMetaData();
            contmd.setParent(mmd);
            MapMetaData mapmd = (MapMetaData) contmd;
            mapmd.setKeyType((mapKeyType != null ? mapKeyType.getName() : null));
            if (!StringUtils.isWhitespace(embeddedKey)) {
                mapmd.setEmbeddedKey(Boolean.valueOf(embeddedKey));
            }
            if (!StringUtils.isWhitespace(serializedKey)) {
                mapmd.setSerializedKey(Boolean.valueOf(serializedKey));
            }
            if (!StringUtils.isWhitespace(dependentKey)) {
                mapmd.setDependentKey(Boolean.valueOf(dependentKey));
            }
            mapmd.setValueType((mapValueType != null ? mapValueType.getName() : null));
            if (!StringUtils.isWhitespace(embeddedValue)) {
                mapmd.setEmbeddedValue(Boolean.valueOf(embeddedValue));
            }
            if (!StringUtils.isWhitespace(serializedValue)) {
                mapmd.setSerializedValue(Boolean.valueOf(serializedValue));
            }
            if (!StringUtils.isWhitespace(dependentValue)) {
                mapmd.setDependentValue(Boolean.valueOf(dependentValue));
            }
            if ((embeddedKeyMembers != null || "true".equalsIgnoreCase(embeddedKey)) && keymd == null) {
                keymd = new KeyMetaData();
                mmd.setKeyMetaData(keymd);
            }
            if (keymd != null) {
                if (embeddedKeyMembers != null) {
                    // Add any embedded key mappings
                    EmbeddedMetaData embmd = keymd.getEmbeddedMetaData();
                    if ("true".equalsIgnoreCase(embeddedKey) && keymd.getEmbeddedMetaData() == null) {
                        // Create EmbeddedMetaData for key since not existing
                        embmd = keymd.newEmbeddedMetaData();
                    }
                    for (Persistent embeddedKeyMember : embeddedKeyMembers) {
                        // Add the metadata for the embedded key to the embedded metadata
                        String memberName = embeddedKeyMember.name();
                        if (memberName.indexOf('.') > 0) {
                            memberName = memberName.substring(memberName.lastIndexOf('.') + 1);
                        }
                        AbstractMemberMetaData embfmd = getFieldMetaDataForPersistent(embmd, embeddedKeyMember, isMemberOfClassAField(mapKeyType, memberName));
                        embmd.addMember(embfmd);
                    }
                }
            }
            if ((embeddedKeyMembers != null || "true".equalsIgnoreCase(embeddedKey)) && valuemd == null) {
                valuemd = new ValueMetaData();
                mmd.setValueMetaData(valuemd);
            }
            if (valuemd != null) {
                if (embeddedValueMembers != null) {
                    // Add any embedded value mappings
                    EmbeddedMetaData embmd = valuemd.getEmbeddedMetaData();
                    if ("true".equalsIgnoreCase(embeddedValue) && valuemd.getEmbeddedMetaData() == null) {
                        // Create EmbeddedMetaData for value since not existing
                        embmd = valuemd.newEmbeddedMetaData();
                    }
                    for (Persistent embeddedValueMember : embeddedValueMembers) {
                        // Add the metadata for the embedded value to the embedded metadata
                        String memberName = embeddedValueMember.name();
                        if (memberName.indexOf('.') > 0) {
                            memberName = memberName.substring(memberName.lastIndexOf('.') + 1);
                        }
                        AbstractMemberMetaData embfmd = getFieldMetaDataForPersistent(embmd, embeddedValueMember, isMemberOfClassAField(mapValueType, memberName));
                        embmd.addMember(embfmd);
                    }
                }
            }
        }
        if (contmd != null) {
            mmd.setContainer(contmd);
            if (elemmd != null) {
                elemmd.setParent(mmd);
                mmd.setElementMetaData(elemmd);
                if (elemmd.getMappedBy() != null && mmd.getMappedBy() == null) {
                    // With collection/array this is the same as mapped-by on the field
                    mmd.setMappedBy(elemmd.getMappedBy());
                }
            }
            if (keymd != null) {
                keymd.setParent(mmd);
                mmd.setKeyMetaData(keymd);
            }
            if (valuemd != null) {
                valuemd.setParent(mmd);
                mmd.setValueMetaData(valuemd);
            }
            if (ordermd != null) {
                ordermd.setParent(mmd);
                mmd.setOrderMetaData(ordermd);
            }
        }
        if (joinmd != null) {
            mmd.setJoinMetaData(joinmd);
        }
        if (colmds != null) {
            for (ColumnMetaData colmd : colmds) {
                mmd.addColumn(colmd);
            }
        }
        if (idxmd != null) {
            mmd.setIndexMetaData(idxmd);
        }
        if (unimd != null) {
            mmd.setUniqueMetaData(unimd);
        }
        if (fkmd != null) {
            mmd.setForeignKeyMetaData(fkmd);
        }
        if (cacheable != null && cacheable.equalsIgnoreCase("false")) {
            mmd.setCacheable(false);
        }
        if (extensions != null) {
            mmd.addExtensions(extensions);
        }
    }
    return mmd;
}
Also used : ElementMetaData(org.datanucleus.metadata.ElementMetaData) AnnotationObject(org.datanucleus.metadata.annotations.AnnotationObject) CollectionMetaData(org.datanucleus.metadata.CollectionMetaData) ForeignKeyAction(javax.jdo.annotations.ForeignKeyAction) ValueMetaData(org.datanucleus.metadata.ValueMetaData) UseDefault(javax.jdo.AttributeConverter.UseDefault) ForeignKeyMetaData(org.datanucleus.metadata.ForeignKeyMetaData) Embedded(javax.jdo.annotations.Embedded) ColumnMetaData(org.datanucleus.metadata.ColumnMetaData) EmbeddedMetaData(org.datanucleus.metadata.EmbeddedMetaData) UniqueMetaData(org.datanucleus.metadata.UniqueMetaData) PropertyMetaData(org.datanucleus.metadata.PropertyMetaData) MapMetaData(org.datanucleus.metadata.MapMetaData) PrimaryKeyMetaData(org.datanucleus.metadata.PrimaryKeyMetaData) IndexMetaData(org.datanucleus.metadata.IndexMetaData) DiscriminatorMetaData(org.datanucleus.metadata.DiscriminatorMetaData) PersistenceNucleusContext(org.datanucleus.PersistenceNucleusContext) JoinMetaData(org.datanucleus.metadata.JoinMetaData) AnnotationObject(org.datanucleus.metadata.annotations.AnnotationObject) InvalidMetaDataException(org.datanucleus.metadata.InvalidMetaDataException) JDOTypeConverter(org.datanucleus.api.jdo.JDOTypeConverter) OrderMetaData(org.datanucleus.metadata.OrderMetaData) AttributeConverter(javax.jdo.AttributeConverter) FieldMetaData(org.datanucleus.metadata.FieldMetaData) Column(javax.jdo.annotations.Column) ContainerHandler(org.datanucleus.store.types.ContainerHandler) KeyMetaData(org.datanucleus.metadata.KeyMetaData) PrimaryKeyMetaData(org.datanucleus.metadata.PrimaryKeyMetaData) ForeignKeyMetaData(org.datanucleus.metadata.ForeignKeyMetaData) Persistent(javax.jdo.annotations.Persistent) Discriminator(javax.jdo.annotations.Discriminator) Extension(javax.jdo.annotations.Extension) ArrayMetaData(org.datanucleus.metadata.ArrayMetaData) FieldPersistenceModifier(org.datanucleus.metadata.FieldPersistenceModifier) TypeManager(org.datanucleus.store.types.TypeManager) AbstractMemberMetaData(org.datanucleus.metadata.AbstractMemberMetaData) ContainerMetaData(org.datanucleus.metadata.ContainerMetaData)

Aggregations

IndexMetaData (org.datanucleus.metadata.IndexMetaData)27 AbstractMemberMetaData (org.datanucleus.metadata.AbstractMemberMetaData)5 ForeignKeyMetaData (org.datanucleus.metadata.ForeignKeyMetaData)5 ColumnMetaData (org.datanucleus.metadata.ColumnMetaData)4 DiscriminatorMetaData (org.datanucleus.metadata.DiscriminatorMetaData)4 JoinMetaData (org.datanucleus.metadata.JoinMetaData)4 PrimaryKeyMetaData (org.datanucleus.metadata.PrimaryKeyMetaData)4 HashSet (java.util.HashSet)3 AbstractClassMetaData (org.datanucleus.metadata.AbstractClassMetaData)3 FetchGroupMetaData (org.datanucleus.metadata.FetchGroupMetaData)3 InvalidMetaDataException (org.datanucleus.metadata.InvalidMetaDataException)3 KeyMetaData (org.datanucleus.metadata.KeyMetaData)3 OrderMetaData (org.datanucleus.metadata.OrderMetaData)3 UniqueMetaData (org.datanucleus.metadata.UniqueMetaData)3 Set (java.util.Set)2 AttributeConverter (javax.jdo.AttributeConverter)2 Column (javax.jdo.annotations.Column)2 Extension (javax.jdo.annotations.Extension)2 ForeignKeyAction (javax.jdo.annotations.ForeignKeyAction)2 Persistent (javax.jdo.annotations.Persistent)2