
org.datanucleus.api.jdo.metadata.JDOAnnotationReader Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of datanucleus-api-jdo Show documentation
Show all versions of datanucleus-api-jdo Show documentation
Plugin providing DataNucleus implementation of the JDO API.
/**********************************************************************
Copyright (c) 2006 Andy Jefferson and others. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Contributors:
...
**********************************************************************/
package org.datanucleus.api.jdo.metadata;
import java.lang.reflect.Method;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import javax.jdo.AttributeConverter;
import javax.jdo.AttributeConverter.UseDefault;
import javax.jdo.annotations.Column;
import javax.jdo.annotations.Discriminator;
import javax.jdo.annotations.DiscriminatorStrategy;
import javax.jdo.annotations.Embedded;
import javax.jdo.annotations.Extension;
import javax.jdo.annotations.FetchGroup;
import javax.jdo.annotations.FetchPlan;
import javax.jdo.annotations.ForeignKey;
import javax.jdo.annotations.ForeignKeyAction;
import javax.jdo.annotations.IdGeneratorStrategy;
import javax.jdo.annotations.Index;
import javax.jdo.annotations.InheritanceStrategy;
import javax.jdo.annotations.Join;
import javax.jdo.annotations.NullValue;
import javax.jdo.annotations.PersistenceModifier;
import javax.jdo.annotations.Persistent;
import javax.jdo.annotations.Query;
import javax.jdo.annotations.SequenceStrategy;
import javax.jdo.annotations.Unique;
import javax.jdo.annotations.VersionStrategy;
import org.datanucleus.ClassLoaderResolver;
import org.datanucleus.PropertyNames;
import org.datanucleus.api.jdo.JDOQuery;
import org.datanucleus.api.jdo.JDOTypeConverter;
import org.datanucleus.api.jdo.JDOTypeConverterUtils;
import org.datanucleus.api.jdo.NucleusJDOHelper;
import org.datanucleus.metadata.AbstractClassMetaData;
import org.datanucleus.metadata.AbstractMemberMetaData;
import org.datanucleus.metadata.ArrayMetaData;
import org.datanucleus.metadata.ClassPersistenceModifier;
import org.datanucleus.metadata.CollectionMetaData;
import org.datanucleus.metadata.ColumnMetaData;
import org.datanucleus.metadata.ContainerMetaData;
import org.datanucleus.metadata.DiscriminatorMetaData;
import org.datanucleus.metadata.ElementMetaData;
import org.datanucleus.metadata.EmbeddedMetaData;
import org.datanucleus.metadata.ExtensionMetaData;
import org.datanucleus.metadata.FetchGroupMemberMetaData;
import org.datanucleus.metadata.FetchGroupMetaData;
import org.datanucleus.metadata.FetchPlanMetaData;
import org.datanucleus.metadata.FieldMetaData;
import org.datanucleus.metadata.FieldPersistenceModifier;
import org.datanucleus.metadata.ForeignKeyMetaData;
import org.datanucleus.metadata.IdentityMetaData;
import org.datanucleus.metadata.IdentityStrategy;
import org.datanucleus.metadata.IdentityType;
import org.datanucleus.metadata.IndexMetaData;
import org.datanucleus.metadata.IndexedValue;
import org.datanucleus.metadata.InheritanceMetaData;
import org.datanucleus.metadata.InvalidClassMetaDataException;
import org.datanucleus.metadata.JoinMetaData;
import org.datanucleus.metadata.KeyMetaData;
import org.datanucleus.metadata.MapMetaData;
import org.datanucleus.metadata.MetaData;
import org.datanucleus.metadata.MetaDataManager;
import org.datanucleus.metadata.MetaDataUtils;
import org.datanucleus.metadata.OrderMetaData;
import org.datanucleus.metadata.PackageMetaData;
import org.datanucleus.metadata.PrimaryKeyMetaData;
import org.datanucleus.metadata.PropertyMetaData;
import org.datanucleus.metadata.QueryLanguage;
import org.datanucleus.metadata.QueryMetaData;
import org.datanucleus.metadata.SequenceMetaData;
import org.datanucleus.metadata.UniqueMetaData;
import org.datanucleus.metadata.ValueMetaData;
import org.datanucleus.metadata.VersionMetaData;
import org.datanucleus.metadata.annotations.AbstractAnnotationReader;
import org.datanucleus.metadata.annotations.AnnotationObject;
import org.datanucleus.metadata.annotations.Member;
import org.datanucleus.store.types.ContainerHandler;
import org.datanucleus.store.types.TypeManager;
import org.datanucleus.util.ClassUtils;
import org.datanucleus.util.Localiser;
import org.datanucleus.util.NucleusLogger;
import org.datanucleus.util.StringUtils;
/**
* Implementation for Annotation Reader for java annotations using the JDO definition.
*/
public class JDOAnnotationReader extends AbstractAnnotationReader
{
/**
* Constructor.
* @param mgr MetaData manager
*/
public JDOAnnotationReader(MetaDataManager mgr)
{
super(mgr);
// We support JDO and DataNucleus annotations in this reader.
setSupportedAnnotationPackages(new String[]{"javax.jdo", "org.datanucleus"});
}
/**
* 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)
{
AbstractClassMetaData cmd = null;
if (annotations != null && annotations.length > 0)
{
AnnotationObject pcAnnotation = isClassPersistable(cls);
if (pcAnnotation != null)
{
// persistable class
if (cls.isInterface())
{
cmd = pmd.newInterfaceMetadata(ClassUtils.getClassNameForClass(cls));
}
else
{
cmd = pmd.newClassMetadata(ClassUtils.getClassNameForClass(cls));
}
cmd.setPersistenceModifier(ClassPersistenceModifier.PERSISTENCE_CAPABLE);
Map annotationValues = pcAnnotation.getNameValueMap();
cmd.setTable((String) annotationValues.get("table"));
cmd.setCatalog((String) annotationValues.get("catalog"));
cmd.setSchema((String) annotationValues.get("schema"));
String detachableStr = (String) annotationValues.get("detachable");
if (mgr.getNucleusContext().getConfiguration().getBooleanProperty(PropertyNames.PROPERTY_METADATA_ALWAYS_DETACHABLE))
{
cmd.setDetachable(true);
}
else
{
cmd.setDetachable(detachableStr);
}
cmd.setRequiresExtent((String) annotationValues.get("requiresExtent"));
String idClassName = null;
Class idClass = (Class) annotationValues.get("objectIdClass");
if (idClass != null && idClass != void.class)
{
idClassName = idClass.getName();
}
cmd.setObjectIdClass(NucleusJDOHelper.getObjectIdClassForInputIdClass(idClassName));
// PersistenceCapable class
cmd.setPersistenceModifier(ClassPersistenceModifier.PERSISTENCE_CAPABLE);
cmd.setEmbeddedOnly((String) annotationValues.get("embeddedOnly"));
javax.jdo.annotations.IdentityType idTypeVal = (javax.jdo.annotations.IdentityType) annotationValues.get("identityType");
String identityType = JDOAnnotationUtils.getIdentityTypeString(idTypeVal);
cmd.setIdentityType(IdentityType.getIdentityType(identityType));
cmd.setCacheable((String) annotationValues.get("cacheable"));
String serializeRead = (String) annotationValues.get("serializeRead");
if (serializeRead != null)
{
cmd.setSerializeRead(serializeRead.equals("true") ? true : false);
}
JDOAnnotationUtils.addExtensionsToMetaData(cmd, (Extension[]) annotationValues.get("extensions"));
// Members typically providing specification of overridden fields/properties
Persistent[] members = (Persistent[]) annotationValues.get("members");
if (members != null)
{
// Add on the fields/properties direct to the metadata for the class/interface
for (int j = 0; j < members.length; j++)
{
String memberName = members[j].name();
if (memberName.indexOf('.') > 0)
{
memberName = memberName.substring(memberName.lastIndexOf('.') + 1);
}
boolean isField = isMemberOfClassAField(cls, memberName);
AbstractMemberMetaData fmd = getFieldMetaDataForPersistent(cmd, members[j], isField);
cmd.addMember(fmd);
}
}
}
else if (isClassPersistenceAware(cls))
{
// PersistenceAware class
cmd = pmd.newClassMetadata(ClassUtils.getClassNameForClass(cls));
cmd.setPersistenceModifier(ClassPersistenceModifier.PERSISTENCE_AWARE);
}
else if (doesClassHaveNamedQueries(cls))
{
// 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;
}
processNamedQueries(cmd, cls, annotations);
if (cmd.getPersistenceModifier() != ClassPersistenceModifier.PERSISTENCE_CAPABLE)
{
// Not persistable, so no further information needed
return cmd;
}
// Class is persistable so process remaining annotations
InheritanceMetaData inhmd = null;
DiscriminatorMetaData dismd = null;
IdentityMetaData idmd = null;
PrimaryKeyMetaData pkmd = null;
VersionMetaData vermd = null;
JoinMetaData[] joins = null;
FetchPlanMetaData[] fetchPlans = null;
FetchGroupMetaData[] fetchGroups = null;
SequenceMetaData seqmd = null;
String cacheable = null;
boolean embeddedOnly = false;
ColumnMetaData[] unmappedColumns = null;
HashSet indices = null;
HashSet uniqueKeys = null;
HashSet fks = null;
HashSet extensions = null;
for (int i = 0; i < annotations.length; i++)
{
Map annotationValues = annotations[i].getNameValueMap();
String annName = annotations[i].getName();
if (annName.equals(JDOAnnotationUtils.EMBEDDED_ONLY))
{
embeddedOnly = 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");
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"));
}
else if (annName.equals(JDOAnnotationUtils.DATASTORE_IDENTITY))
{
String strategy = JDOAnnotationUtils.getIdentityStrategyString((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");
idmd = new IdentityMetaData();
idmd.setColumnName(column);
idmd.setValueStrategy(IdentityStrategy.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"));
}
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");
pkmd = new PrimaryKeyMetaData();
pkmd.setName(pkName);
pkmd.setColumnName(pkColumn);
if (columns != null && columns.length > 0)
{
for (int j = 0; j < columns.length; j++)
{
pkmd.addColumn(JDOAnnotationUtils.getColumnMetaDataForColumnAnnotation(columns[j]));
}
}
JDOAnnotationUtils.addExtensionsToMetaData(pkmd, (Extension[]) annotationValues.get("extensions"));
}
else if (annName.equals(JDOAnnotationUtils.JOINS))
{
if (joins != null)
{
NucleusLogger.METADATA.warn(Localiser.msg("044210", cmd.getFullClassName()));
}
Join[] js = (Join[]) annotationValues.get("value");
if (js != null && js.length > 0)
{
joins = new JoinMetaData[js.length];
for (int j = 0; j < js.length; j++)
{
joins[j] = new JoinMetaData();
joins[j].setTable(js[j].table());
joins[j].setColumnName(js[j].column());
joins[j].setIndexed(IndexedValue.getIndexedValue(js[j].indexed()));
joins[j].setOuter(MetaDataUtils.getBooleanForString(js[j].outer(), false));
joins[j].setUnique(js[j].unique());
joins[j].setDeleteAction(JDOAnnotationUtils.getForeignKeyActionString(js[j].deleteAction()));
}
}
}
else if (annName.equals(JDOAnnotationUtils.JOIN))
{
if (joins != null)
{
NucleusLogger.METADATA.warn(Localiser.msg("044210", cmd.getFullClassName()));
}
joins = new JoinMetaData[1];
joins[0] = new JoinMetaData();
joins[0].setTable((String) annotationValues.get("table"));
joins[0].setColumnName((String) annotationValues.get("column"));
joins[0].setIndexed(IndexedValue.getIndexedValue((String) annotationValues.get("indexed")));
joins[0].setOuter(MetaDataUtils.getBooleanForString((String) annotationValues.get("outer"), false));
joins[0].setUnique((String) annotationValues.get("unique"));
joins[0].setDeleteAction(((ForeignKeyAction) annotationValues.get("deleteAction")).toString());
JDOAnnotationUtils.addExtensionsToMetaData(joins[0], (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;
}
inhmd = new InheritanceMetaData();
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");
dismd = new DiscriminatorMetaData();
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))
{
if (fetchPlans != null)
{
NucleusLogger.METADATA.warn(Localiser.msg("044207", cmd.getFullClassName()));
}
FetchPlan[] plans = (FetchPlan[]) annotationValues.get("value");
fetchPlans = new FetchPlanMetaData[plans.length];
for (int j = 0; j < plans.length; j++)
{
fetchPlans[j] = new FetchPlanMetaData(plans[j].name());
fetchPlans[j].setMaxFetchDepth(plans[j].maxFetchDepth());
fetchPlans[j].setFetchSize(plans[j].fetchSize());
int numGroups = plans[j].fetchGroups().length;
for (int k = 0; k < numGroups; k++)
{
FetchGroupMetaData fgmd = new FetchGroupMetaData(plans[j].fetchGroups()[k]);
fetchPlans[j].addFetchGroup(fgmd);
}
}
}
else if (annName.equals(JDOAnnotationUtils.FETCHPLAN))
{
if (fetchPlans != null)
{
NucleusLogger.METADATA.warn(Localiser.msg("044207", cmd.getFullClassName()));
}
fetchPlans = new FetchPlanMetaData[1];
int maxFetchDepth = ((Integer) annotationValues.get("maxFetchDepth")).intValue();
int fetchSize = ((Integer) annotationValues.get("fetchSize")).intValue();
fetchPlans[0] = new FetchPlanMetaData((String) annotationValues.get("name"));
fetchPlans[0].setMaxFetchDepth(maxFetchDepth);
fetchPlans[0].setFetchSize(fetchSize);
}
else if (annName.equals(JDOAnnotationUtils.FETCHGROUPS))
{
if (fetchGroups != null)
{
NucleusLogger.METADATA.warn(Localiser.msg("044208", cmd.getFullClassName()));
}
FetchGroup[] groups = (FetchGroup[]) annotationValues.get("value");
fetchGroups = new FetchGroupMetaData[groups.length];
for (int j = 0; j < groups.length; j++)
{
fetchGroups[j] = new FetchGroupMetaData(groups[j].name());
if (!StringUtils.isWhitespace(groups[j].postLoad()))
{
fetchGroups[j].setPostLoad(Boolean.valueOf(groups[j].postLoad()));
}
int numFields = groups[j].members().length;
for (int k = 0; k < numFields; k++)
{
FetchGroupMemberMetaData fgmmd = new FetchGroupMemberMetaData(fetchGroups[j], groups[j].members()[k].name());
fgmmd.setRecursionDepth(groups[j].members()[k].recursionDepth());
fetchGroups[j].addMember(fgmmd);
}
int numGroups = groups[j].fetchGroups().length;
for (int k = 0; k < numGroups; k++)
{
FetchGroupMetaData subgrp = new FetchGroupMetaData(groups[j].fetchGroups()[k]);
fetchGroups[j].addFetchGroup(subgrp);
}
}
}
else if (annName.equals(JDOAnnotationUtils.FETCHGROUP))
{
if (fetchGroups != null)
{
NucleusLogger.METADATA.warn(Localiser.msg("044208", cmd.getFullClassName()));
}
fetchGroups = new FetchGroupMetaData[1];
fetchGroups[0] = new FetchGroupMetaData((String) annotationValues.get("name"));
String postLoadStr = (String) annotationValues.get("postLoad");
if (!StringUtils.isWhitespace(postLoadStr))
{
fetchGroups[0].setPostLoad(Boolean.valueOf(postLoadStr));
}
Persistent[] fields = (Persistent[]) annotationValues.get("members");
if (fields != null)
{
for (int j = 0; j < fields.length; j++)
{
FetchGroupMemberMetaData fgmmd = new FetchGroupMemberMetaData(fetchGroups[0], fields[j].name());
fgmmd.setRecursionDepth(fields[j].recursionDepth());
fetchGroups[0].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());
}
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"));
}
else if (annName.equals(JDOAnnotationUtils.INDICES))
{
// Multiple Indices for the class
Index[] values = (Index[]) annotationValues.get("value");
if (values != null && values.length > 0)
{
indices = new HashSet(values.length);
for (int j = 0; j < values.length; j++)
{
IndexMetaData idxmd = JDOAnnotationUtils.getIndexMetaData(values[j].name(), values[j].table(), "" + values[j].unique(),
values[j].members(), values[j].columns());
if (idxmd.getNumberOfColumns() == 0 && idxmd.getNumberOfMembers() == 0)
{
NucleusLogger.METADATA.warn(Localiser.msg("044204", cls.getName()));
}
else
{
indices.add(idxmd);
}
}
}
}
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
{
indices = new HashSet(1);
indices.add(idxmd);
}
}
else if (annName.equals(JDOAnnotationUtils.UNIQUES))
{
// Multiple Unique Constraints for the class
Unique[] values = (Unique[]) annotationValues.get("value");
if (values != null && values.length > 0)
{
uniqueKeys = new HashSet(values.length);
for (int j = 0; j < values.length; j++)
{
UniqueMetaData unimd = JDOAnnotationUtils.getUniqueMetaData(values[j].name(), values[j].table(), "" + values[j].deferred(),
values[j].members(), values[j].columns());
if (unimd.getNumberOfColumns() == 0 && unimd.getNumberOfMembers() == 0)
{
NucleusLogger.METADATA.warn(Localiser.msg("044205", cls.getName()));
}
else
{
uniqueKeys.add(unimd);
}
}
}
}
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
{
uniqueKeys = new HashSet(1);
uniqueKeys.add(unimd);
}
}
else if (annName.equals(JDOAnnotationUtils.FOREIGNKEYS))
{
// Multiple FKs for the class
ForeignKey[] values = (ForeignKey[]) annotationValues.get("value");
if (values != null && values.length > 0)
{
fks = new HashSet(values.length);
for (int j = 0; j < values.length; j++)
{
String deleteAction = JDOAnnotationUtils.getForeignKeyActionString(values[j].deleteAction());
String updateAction = JDOAnnotationUtils.getForeignKeyActionString(values[j].updateAction());
ForeignKeyMetaData fkmd = JDOAnnotationUtils.getFKMetaData(values[j].name(), values[j].table(), values[j].unique(),
"" + values[j].deferred(), deleteAction, updateAction, values[j].members(), values[j].columns());
if (fkmd.getNumberOfColumns() == 0 && fkmd.getNumberOfMembers() == 0)
{
NucleusLogger.METADATA.warn(Localiser.msg("044206", cls.getName()));
}
else
{
fks.add(fkmd);
}
}
}
}
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
{
fks = new HashSet(1);
fks.add(fkmd);
}
}
else if (annName.equals(JDOAnnotationUtils.COLUMNS))
{
// Unmapped column specification
Column[] cols = (Column[]) annotationValues.get("value");
if (cols != null && cols.length > 0)
{
unmappedColumns = new ColumnMetaData[cols.length];
for (int j = 0; j < cols.length; j++)
{
unmappedColumns[j] = JDOAnnotationUtils.getColumnMetaDataForColumnAnnotation(cols[j]);
JDOAnnotationUtils.addExtensionsToMetaData(unmappedColumns[j], cols[j].extensions());
}
}
}
else if (annName.equals(JDOAnnotationUtils.CACHEABLE))
{
String cache = (String) annotationValues.get("value");
if (cache != null)
{
cacheable = cache;
}
}
else if (annName.equals(JDOAnnotationUtils.EXTENSIONS))
{
Extension[] values = (Extension[]) annotationValues.get("value");
if (values != null && values.length > 0)
{
extensions = new HashSet(values.length);
for (int j = 0; j < values.length; j++)
{
ExtensionMetaData extmd = new ExtensionMetaData(values[j].vendorName(), values[j].key().toString(), values[j].value().toString());
extensions.add(extmd);
}
}
}
else if (annName.equals(JDOAnnotationUtils.EXTENSION))
{
ExtensionMetaData extmd = new ExtensionMetaData((String) annotationValues.get("vendorName"), (String) annotationValues.get("key"),
(String) annotationValues.get("value"));
extensions = new HashSet(1);
extensions.add(extmd);
}
else
{
if (!annName.equals(JDOAnnotationUtils.PERSISTENCE_CAPABLE) && !annName.equals(JDOAnnotationUtils.PERSISTENCE_AWARE) &&
!annName.equals(JDOAnnotationUtils.QUERIES) && !annName.equals(JDOAnnotationUtils.QUERY))
{
NucleusLogger.METADATA.debug(Localiser.msg("044203", cls.getName(), annotations[i].getName()));
}
}
}
// Either PersistenceCapable, PersistenceAware or PersistentInterface so build up the metadata
NucleusLogger.METADATA.debug(Localiser.msg("044200", cls.getName(), "JDO"));
if (embeddedOnly)
{
cmd.setEmbeddedOnly(true);
}
if (idmd != null)
{
// Datastore identity
idmd.setParent(cmd);
cmd.setIdentityMetaData(idmd);
}
if (pkmd != null)
{
// Primary Key
pkmd.setParent(cmd);
cmd.setPrimaryKeyMetaData(pkmd);
}
if (vermd != null)
{
// Version
vermd.setParent(cmd);
cmd.setVersionMetaData(vermd);
}
if (inhmd != null)
{
// Inheritance
if (dismd != null)
{
inhmd.setDiscriminatorMetaData(dismd);
}
inhmd.setParent(cmd);
cmd.setInheritanceMetaData(inhmd);
}
else if (dismd != null)
{
inhmd = new InheritanceMetaData();
inhmd.setDiscriminatorMetaData(dismd);
cmd.setInheritanceMetaData(inhmd);
}
if (joins != null && joins.length > 0)
{
// Joins
for (int i = 0; i < joins.length; i++)
{
cmd.addJoin(joins[i]);
}
}
if (fetchGroups != null && fetchGroups.length > 0)
{
// Fetch Groups
for (int i = 0; i < fetchGroups.length; i++)
{
fetchGroups[i].setParent(cmd);
cmd.addFetchGroup(fetchGroups[i]);
}
}
if (seqmd != null)
{
// Sequence - currently only allowing 1 per class (should really be on the package)
cmd.getPackageMetaData().addSequence(seqmd);
}
if (indices != null)
{
Iterator iter = indices.iterator();
while (iter.hasNext())
{
IndexMetaData idxmd = (IndexMetaData) iter.next();
idxmd.setParent(cmd);
cmd.addIndex(idxmd);
}
}
if (uniqueKeys != null)
{
Iterator iter = uniqueKeys.iterator();
while (iter.hasNext())
{
UniqueMetaData unimd = (UniqueMetaData) iter.next();
unimd.setParent(cmd);
cmd.addUniqueConstraint(unimd);
}
}
if (fks != null)
{
Iterator iter = fks.iterator();
while (iter.hasNext())
{
ForeignKeyMetaData fkmd = (ForeignKeyMetaData) iter.next();
fkmd.setParent(cmd);
cmd.addForeignKey(fkmd);
}
}
if (unmappedColumns != null)
{
for (int i = 0; i < unmappedColumns.length; i++)
{
ColumnMetaData colmd = unmappedColumns[i];
colmd.setParent(cmd);
cmd.addUnmappedColumn(colmd);
}
}
if (cacheable != null && cacheable.equalsIgnoreCase("false"))
{
cmd.setCacheable(false);
}
if (extensions != null)
{
Iterator iter = extensions.iterator();
while (iter.hasNext())
{
ExtensionMetaData extmd = iter.next();
cmd.addExtension(extmd.getVendorName(), extmd.getKey(), extmd.getValue());
}
}
}
return cmd;
}
/**
* Convenience method to process @Queries, @Query.
* @param cmd Metadata for the class, to which any queries will be added
* @param cls Class that the named queries are registered against
* @param annotations Annotations specified on the class
*/
protected void processNamedQueries(AbstractClassMetaData cmd, Class cls, AnnotationObject[] annotations)
{
QueryMetaData[] queries = null;
for (int i = 0; i < annotations.length; i++)
{
Map annotationValues = annotations[i].getNameValueMap();
String annName = annotations[i].getName();
if (annName.equals(JDOAnnotationUtils.QUERIES))
{
if (queries != null)
{
NucleusLogger.METADATA.warn(Localiser.msg("044209", cmd.getFullClassName()));
}
Query[] qs = (Query[]) annotationValues.get("value");
queries = new QueryMetaData[qs.length];
for (int j = 0; j < queries.length; j++)
{
String lang = JDOAnnotationUtils.getQueryLanguageName(qs[j].language());
if (!StringUtils.isWhitespace(lang))
{
if (lang.equals(JDOQuery.JDOQL_QUERY_LANGUAGE)) // Convert to JDOQL
{
lang = QueryLanguage.JDOQL.toString();
}
else if (lang.equals(JDOQuery.SQL_QUERY_LANGUAGE)) // Convert to SQL
{
lang = QueryLanguage.SQL.toString();
}
else if (lang.equals(JDOQuery.JPQL_QUERY_LANGUAGE)) // Convert to JPQL
{
lang = QueryLanguage.JPQL.toString();
}
}
String resultClassName = (qs[j].resultClass() != null && qs[j].resultClass() != void.class ? qs[j].resultClass().getName() : null);
if (StringUtils.isWhitespace(qs[j].name()))
{
throw new InvalidClassMetaDataException("044154", cmd.getFullClassName());
}
queries[j] = new QueryMetaData(qs[j].name());
queries[j].setScope(cls.getName());
queries[j].setLanguage(lang);
queries[j].setUnmodifiable(qs[j].unmodifiable());
queries[j].setResultClass(resultClassName);
queries[j].setUnique(qs[j].unique());
queries[j].setFetchPlanName(qs[j].fetchPlan());
queries[j].setQuery(qs[j].value());
JDOAnnotationUtils.addExtensionsToMetaData(queries[j], qs[j].extensions());
}
}
else if (annName.equals(JDOAnnotationUtils.QUERY))
{
if (queries != null)
{
NucleusLogger.METADATA.warn(Localiser.msg("044209", cmd.getFullClassName()));
}
queries = new QueryMetaData[1];
String unmodifiable = "" + annotationValues.get("unmodifiable");
Class resultClassValue = (Class) annotationValues.get("resultClass");
String resultClassName = (resultClassValue != null && resultClassValue != void.class ? resultClassValue.getName() : null);
String lang = JDOAnnotationUtils.getQueryLanguageName((String) annotationValues.get("language"));
if (!StringUtils.isWhitespace(lang))
{
if (lang.equals(JDOQuery.JDOQL_QUERY_LANGUAGE)) // Convert to JDOQL
{
lang = QueryLanguage.JDOQL.toString();
}
else if (lang.equals(JDOQuery.SQL_QUERY_LANGUAGE)) // Convert to SQL
{
lang = QueryLanguage.SQL.toString();
}
else if (lang.equals(JDOQuery.JPQL_QUERY_LANGUAGE)) // Convert to JPQL
{
lang = QueryLanguage.JPQL.toString();
}
}
if (StringUtils.isWhitespace((String) annotationValues.get("name")))
{
throw new InvalidClassMetaDataException("044154", cmd.getFullClassName());
}
queries[0] = new QueryMetaData((String) annotationValues.get("name"));
queries[0].setScope(cls.getName());
queries[0].setLanguage(lang);
queries[0].setUnmodifiable(unmodifiable);
queries[0].setResultClass(resultClassName);
queries[0].setUnique((String) annotationValues.get("unique"));
queries[0].setFetchPlanName((String) annotationValues.get("fetchPlan"));
queries[0].setQuery((String) annotationValues.get("value"));
JDOAnnotationUtils.addExtensionsToMetaData(queries[0], (Extension[]) annotationValues.get("extensions"));
}
}
if (queries != null && queries.length > 0)
{
// Named Queries
for (int i = 0; i < queries.length; i++)
{
queries[i].setParent(cmd);
cmd.addQuery(queries[i]);
}
}
}
/**
* 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
* @param propertyAccessor if there are properties for this class
* @return The FieldMetaData/PropertyMetaData that was added (if any)
*/
protected AbstractMemberMetaData processMemberAnnotations(AbstractClassMetaData cmd, Member member, AnnotationObject[] annotations, boolean propertyAccessor)
{
AbstractMemberMetaData mmd = null;
if (annotations != null && annotations.length > 0)
{
boolean primaryKey = false;
boolean serialised = false;
boolean nonPersistentField = false;
boolean transactionalField = false;
String cacheable = null;
Class[] elementTypes = null;
String embeddedElement = null;
String serializedElement = null;
String dependentElement = null;
Class keyType = null;
String embeddedKey = null;
String serializedKey = null;
String dependentKey = null;
Class valueType = 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;
HashSet extensions = null;
Class convertConverterCls = null;
for (int i = 0; i < annotations.length; i++)
{
String annName = annotations[i].getName();
Map annotationValues = annotations[i].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.getIdentityStrategyString((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 (int j = 0; j < fieldTypes.length; j++)
{
if (typeStr.length() > 0)
{
typeStr.append(',');
}
if (fieldTypes[j] != null && fieldTypes[j] != void.class)
{
typeStr.append(fieldTypes[j].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");
if (member.isProperty())
{
// Property
mmd = new PropertyMetaData(cmd, member.getName());
}
else
{
// Field
mmd = new FieldMetaData(cmd, member.getName());
}
if (disableConversion)
{
mmd.setTypeConverterDisabled();
}
else if (converterCls != null)
{
TypeManager typeMgr = mgr.getNucleusContext().getTypeManager();
if (typeMgr.getTypeConverterForName(converterCls.getName()) == null)
{
// Not yet cached an instance of this converter so create one
AttributeConverter conv = (AttributeConverter)ClassUtils.newInstance(converterCls, null, null);
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, attrType, dbType);
typeMgr.registerConverter(converterCls.getName(), typeConv);
}
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 (int j = 0; j < columns.length; j++)
{
mmd.addColumn(JDOAnnotationUtils.getColumnMetaDataForColumnAnnotation(columns[j]));
}
}
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 (int j = 0; j < joinColumns.length; j++)
{
joinmd.addColumn(JDOAnnotationUtils.getColumnMetaDataForColumnAnnotation(joinColumns[j]));
}
}
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 elementTable = (String) annotationValues.get("table");
String elementColumn = (String) annotationValues.get("column");
String elementDeleteAction = JDOAnnotationUtils.getForeignKeyActionString((ForeignKeyAction) annotationValues.get("deleteAction"));
String elementUpdateAction = JDOAnnotationUtils.getForeignKeyActionString((ForeignKeyAction) annotationValues.get("updateAction"));
String elementMappedBy = (String) annotationValues.get("mappedBy");
Column[] elementColumns = (Column[]) annotationValues.get("columns");
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(elementTable);
elemmd.setColumnName(elementColumn);
elemmd.setDeleteAction(elementDeleteAction);
elemmd.setUpdateAction(elementUpdateAction);
elemmd.setIndexed(IndexedValue.getIndexedValue(indexed));
elemmd.setUnique(MetaDataUtils.getBooleanForString(unique, false));
elemmd.setMappedBy(elementMappedBy);
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);
}
if (elementColumns != null && elementColumns.length > 0)
{
for (int j = 0; j < elementColumns.length; j++)
{
elemmd.addColumn(JDOAnnotationUtils.getColumnMetaDataForColumnAnnotation(elementColumns[j]));
}
}
if (disableConversion)
{
// TODO Specify this on the element?
}
else if (converterCls != null)
{
TypeManager typeMgr = mgr.getNucleusContext().getTypeManager();
if (typeMgr.getTypeConverterForName(converterCls.getName()) == null)
{
// Not yet cached an instance of this converter so create one
AttributeConverter conv = (AttributeConverter)ClassUtils.newInstance(converterCls, null, null);
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, attrType, dbType);
typeMgr.registerConverter(converterCls.getName(), typeConv);
}
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
Class[] keyTypes = (Class[]) annotationValues.get("types");
if (keyTypes != null && keyTypes.length > 0)
{
// TODO Support more than 1 value
keyType = keyTypes[0];
}
embeddedKey = (String) annotationValues.get("embedded");
serializedKey = (String) annotationValues.get("serialized");
dependentKey = (String) annotationValues.get("dependent");
String keyTable = (String) annotationValues.get("table");
String keyColumn = (String) annotationValues.get("column");
String keyDeleteAction = JDOAnnotationUtils.getForeignKeyActionString((ForeignKeyAction) annotationValues.get("deleteAction"));
String keyUpdateAction = JDOAnnotationUtils.getForeignKeyActionString((ForeignKeyAction) annotationValues.get("updateAction"));
String keyMappedBy = (String) annotationValues.get("mappedBy");
Column[] keyColumns = (Column[]) annotationValues.get("columns");
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(keyTable);
keymd.setColumnName(keyColumn);
keymd.setDeleteAction(keyDeleteAction);
keymd.setUpdateAction(keyUpdateAction);
keymd.setIndexed(IndexedValue.getIndexedValue(indexed));
keymd.setUnique(MetaDataUtils.getBooleanForString(unique, false));
keymd.setMappedBy(keyMappedBy);
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);
}
if (keyColumns != null && keyColumns.length > 0)
{
for (int j = 0; j < keyColumns.length; j++)
{
keymd.addColumn(JDOAnnotationUtils.getColumnMetaDataForColumnAnnotation(keyColumns[j]));
}
}
if (disableConversion)
{
// TODO Specify this on the key?
}
else if (converterCls != null)
{
TypeManager typeMgr = mgr.getNucleusContext().getTypeManager();
if (typeMgr.getTypeConverterForName(converterCls.getName()) == null)
{
// Not yet cached an instance of this converter so create one
AttributeConverter conv = (AttributeConverter)ClassUtils.newInstance(converterCls, null, null);
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, attrType, dbType);
typeMgr.registerConverter(converterCls.getName(), typeConv);
}
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
Class[] valueTypes = (Class[]) annotationValues.get("types");
if (valueTypes != null && valueTypes.length > 0)
{
// TODO Support more than 1 value
valueType = valueTypes[0];
}
embeddedValue = (String) annotationValues.get("embedded");
serializedValue = (String) annotationValues.get("serialized");
dependentValue = (String) annotationValues.get("dependent");
String valueTable = (String) annotationValues.get("table");
String valueColumn = (String) annotationValues.get("column");
String valueDeleteAction = JDOAnnotationUtils.getForeignKeyActionString((ForeignKeyAction) annotationValues.get("deleteAction"));
String valueUpdateAction = JDOAnnotationUtils.getForeignKeyActionString((ForeignKeyAction) annotationValues.get("updateAction"));
String valueMappedBy = (String) annotationValues.get("mappedBy");
Column[] valueColumns = (Column[]) annotationValues.get("columns");
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(valueTable);
valuemd.setColumnName(valueColumn);
valuemd.setDeleteAction(valueDeleteAction);
valuemd.setUpdateAction(valueUpdateAction);
valuemd.setIndexed(IndexedValue.getIndexedValue(indexed));
valuemd.setUnique(MetaDataUtils.getBooleanForString(unique, false));
valuemd.setMappedBy(valueMappedBy);
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);
}
if (valueColumns != null && valueColumns.length > 0)
{
for (int j = 0; j < valueColumns.length; j++)
{
valuemd.addColumn(JDOAnnotationUtils.getColumnMetaDataForColumnAnnotation(valueColumns[j]));
}
}
if (disableConversion)
{
// TODO Specify this on the value?
}
else if (converterCls != null)
{
TypeManager typeMgr = mgr.getNucleusContext().getTypeManager();
if (typeMgr.getTypeConverterForName(converterCls.getName()) == null)
{
// Not yet cached an instance of this converter so create one
AttributeConverter conv = (AttributeConverter)ClassUtils.newInstance(converterCls, null, null);
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, attrType, dbType);
typeMgr.registerConverter(converterCls.getName(), typeConv);
}
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))
{
String orderColumn = (String) annotationValues.get("column");
String orderMappedBy = (String) annotationValues.get("mappedBy");
Column[] orderColumns = (Column[]) annotationValues.get("columns");
ordermd = new OrderMetaData();
ordermd.setColumnName(orderColumn);
ordermd.setMappedBy(orderMappedBy);
if (orderColumns != null && orderColumns.length > 0)
{
for (int j = 0; j < orderColumns.length; j++)
{
ordermd.addColumn(JDOAnnotationUtils.getColumnMetaDataForColumnAnnotation(orderColumns[j]));
}
}
JDOAnnotationUtils.addExtensionsToMetaData(ordermd, (Extension[]) annotationValues.get("extensions"));
}
else if (annName.equals(JDOAnnotationUtils.EMBEDDED))
{
embeddedOwnerField = (String) annotationValues.get("ownerMember");
embeddedNullIndicatorColumn = (String) annotationValues.get("nullIndicatorColumn");
embeddedNullIndicatorValue = (String) annotationValues.get("nullIndicatorValue");
embeddedMembers = (Persistent[]) annotationValues.get("members");
// 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 HashSet(values.length);
for (int j = 0; j < values.length; j++)
{
ExtensionMetaData extmd = new ExtensionMetaData(values[j].vendorName(), values[j].key().toString(), values[j].value().toString());
extensions.add(extmd);
}
}
}
else if (annName.equals(JDOAnnotationUtils.EXTENSION))
{
ExtensionMetaData extmd = new ExtensionMetaData((String) annotationValues.get("vendorName"), (String) annotationValues.get("key"),
(String) annotationValues.get("value"));
extensions = new HashSet(1);
extensions.add(extmd);
}
else
{
NucleusLogger.METADATA.debug(Localiser.msg("044211", cmd.getFullClassName(), member.getName(), annotations[i].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
if (member.isProperty())
{
mmd = new PropertyMetaData(cmd, member.getName());
}
else
{
mmd = 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 (nonPersistentField)
{
mmd.setNotPersistent();
}
if (transactionalField)
{
mmd.setTransactional();
}
if (convertConverterCls != null)
{
TypeManager typeMgr = mgr.getNucleusContext().getTypeManager();
if (typeMgr.getTypeConverterForName(convertConverterCls.getName()) == null)
{
// Not yet cached an instance of this converter so create one
AttributeConverter conv = (AttributeConverter)ClassUtils.newInstance(convertConverterCls, null, null);
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, attrType, dbType);
typeMgr.registerConverter(convertConverterCls.getName(), typeConv);
}
mmd.setTypeConverterName(convertConverterCls.getName());
}
// Add any embedded info
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 (int j = 0; j < embeddedMembers.length; j++)
{
// Add the metadata for the embedded field/property to the embedded metadata
String memberName = embeddedMembers[j].name();
if (memberName.indexOf('.') > 0)
{
memberName = memberName.substring(memberName.lastIndexOf('.') + 1);
}
AbstractMemberMetaData embfmd = getFieldMetaDataForPersistent(embmd, embeddedMembers[j],
isMemberOfClassAField(member.getType(), memberName));
embmd.addMember(embfmd);
}
}
}
TypeManager typeManager = mgr.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 (int j = 0; j < elementTypes.length; j++)
{
if (elementTypeStr.length() > 0)
{
elementTypeStr.append(',');
}
elementTypeStr.append(elementTypes[j].getName());
}
collectionElementType = elementTypes[0]; // Use the first only
}
else
{
// Try to derive element type from generics info
collectionElementType = ClassUtils.getCollectionElementType(member.getType(), member.getGenericType());
}
contmd = new CollectionMetaData();
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 ("true".equalsIgnoreCase(embeddedElement) && elemmd.getEmbeddedMetaData() == null)
{
EmbeddedMetaData embmd = new EmbeddedMetaData();
elemmd.setEmbeddedMetaData(embmd);
}
if (embeddedElementMembers != null)
{
// Add any embedded element mappings
EmbeddedMetaData embmd = elemmd.getEmbeddedMetaData();
for (int j = 0; j < embeddedElementMembers.length; j++)
{
// Add the metadata for the embedded element to the embedded metadata
String memberName = embeddedElementMembers[j].name();
if (memberName.indexOf('.') > 0)
{
memberName = memberName.substring(memberName.lastIndexOf('.') + 1);
}
AbstractMemberMetaData embfmd = getFieldMetaDataForPersistent(embmd, embeddedElementMembers[j],
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 (int j = 0; j < elementTypes.length; j++)
{
if (elementTypeStr.length() > 0)
{
elementTypeStr.append(',');
}
elementTypeStr.append(elementTypes[j].getName());
}
}
else
{
// Derive from component type
elementTypeStr.append(member.getType().getComponentType().getName());
}
contmd = new ArrayMetaData();
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 (keyType != null && keyType != void.class)
{
// User-specified key type
mapKeyType = keyType;
}
else
{
// Try to derive key type from generics info
mapKeyType = ClassUtils.getMapKeyType(member.getType(), member.getGenericType());
}
Class mapValueType = null;
if (valueType != null && valueType != void.class)
{
// User-specified value type
mapValueType = valueType;
}
else
{
// Try to derive value type from generics info
mapValueType = ClassUtils.getMapValueType(member.getType(), member.getGenericType());
}
contmd = new MapMetaData();
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 ("true".equalsIgnoreCase(embeddedKey) && keymd.getEmbeddedMetaData() == null)
{
EmbeddedMetaData embmd = new EmbeddedMetaData();
keymd.setEmbeddedMetaData(embmd);
}
if (embeddedKeyMembers != null)
{
// Add any embedded key mappings
EmbeddedMetaData embmd = keymd.getEmbeddedMetaData();
for (int j = 0; j < embeddedKeyMembers.length; j++)
{
// Add the metadata for the embedded key to the embedded metadata
String memberName = embeddedKeyMembers[j].name();
if (memberName.indexOf('.') > 0)
{
memberName = memberName.substring(memberName.lastIndexOf('.') + 1);
}
AbstractMemberMetaData embfmd = getFieldMetaDataForPersistent(embmd, embeddedKeyMembers[j],
isMemberOfClassAField(mapKeyType, memberName));
embmd.addMember(embfmd);
}
}
}
if ((embeddedKeyMembers != null || "true".equalsIgnoreCase(embeddedKey)) && valuemd == null)
{
valuemd = new ValueMetaData();
mmd.setValueMetaData(valuemd);
}
if (valuemd != null)
{
if ("true".equalsIgnoreCase(embeddedValue) && valuemd.getEmbeddedMetaData() == null)
{
EmbeddedMetaData embmd = new EmbeddedMetaData();
valuemd.setEmbeddedMetaData(embmd);
}
if (embeddedValueMembers != null)
{
// Add any embedded value mappings
EmbeddedMetaData embmd = valuemd.getEmbeddedMetaData();
for (int j = 0; j < embeddedValueMembers.length; j++)
{
// Add the metadata for the embedded value to the embedded metadata
String memberName = embeddedValueMembers[j].name();
if (memberName.indexOf('.') > 0)
{
memberName = memberName.substring(memberName.lastIndexOf('.') + 1);
}
AbstractMemberMetaData embfmd = getFieldMetaDataForPersistent(embmd, embeddedValueMembers[j],
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 (int i = 0; i < colmds.length; i++)
{
mmd.addColumn(colmds[i]);
}
}
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)
{
Iterator iter = extensions.iterator();
while (iter.hasNext())
{
ExtensionMetaData extmd = iter.next();
mmd.addExtension(extmd.getVendorName(), extmd.getKey(), extmd.getValue());
}
}
}
}
return mmd;
}
/**
* Method to take the passed in outline ClassMetaData and process the annotations for method adding any
* necessary MetaData to the ClassMetaData.
* @param cmd The ClassMetaData/InterfaceMetaData (to be updated)
* @param method The method
*/
protected void processMethodAnnotations(AbstractClassMetaData cmd, Method method)
{
// do nothing
}
/**
* Convenience method to create MetaData for a @Persistent annotation representing a field or property.
* @param parent Parent MetaData
* @param member The @Persistent annotation
* @param isField Whether this is a field (otherwise is a property)
* @return The metadata for the field/property
*/
private AbstractMemberMetaData getFieldMetaDataForPersistent(MetaData parent, Persistent member, boolean isField)
{
FieldPersistenceModifier modifier = JDOAnnotationUtils.getFieldPersistenceModifier(member.persistenceModifier());
String nullValue = JDOAnnotationUtils.getNullValueString(member.nullValue());
String valueStrategy = JDOAnnotationUtils.getIdentityStrategyString(member.valueStrategy());
String fieldTypeName = null;
Class[] fieldTypes = member.types();
if (fieldTypes != null && fieldTypes.length > 0)
{
StringBuilder typeStr = new StringBuilder();
for (int j = 0; j < fieldTypes.length; j++)
{
if (typeStr.length() > 0)
{
typeStr.append(',');
}
if (fieldTypes[j] != null && fieldTypes[j] != void.class)
{
typeStr.append(fieldTypes[j].getName());
}
}
fieldTypeName = typeStr.toString();
}
AbstractMemberMetaData fmd = null;
if (isField)
{
fmd = new FieldMetaData(parent, member.name());
}
else
{
fmd = new PropertyMetaData(parent, member.name());
}
if (modifier != null)
{
fmd.setPersistenceModifier(modifier);
}
if (!StringUtils.isWhitespace(member.defaultFetchGroup()))
{
fmd.setDefaultFetchGroup(Boolean.valueOf(member.defaultFetchGroup()));
}
if (!StringUtils.isWhitespace(member.primaryKey()))
{
fmd.setPrimaryKey(Boolean.valueOf(member.primaryKey()));
}
if (!StringUtils.isWhitespace(member.embedded()))
{
fmd.setEmbedded(Boolean.valueOf(member.embedded()));
}
if (!StringUtils.isWhitespace(member.serialized()))
{
fmd.setSerialised(Boolean.valueOf(member.serialized()));
}
if (!StringUtils.isWhitespace(member.dependent()))
{
fmd.setDependent(Boolean.valueOf(member.dependent()));
}
fmd.setNullValue(org.datanucleus.metadata.NullValue.getNullValue(nullValue));
fmd.setMappedBy(member.mappedBy());
fmd.setColumn(member.column());
fmd.setTable(member.table());
fmd.setLoadFetchGroup(member.loadFetchGroup());
fmd.setValueStrategy(valueStrategy);
fmd.setSequence(member.sequence());
fmd.setFieldTypes(fieldTypeName);
// Add any columns defined on the @Persistent
Column[] columns = member.columns();
if (columns != null && columns.length > 0)
{
for (int j = 0; j < columns.length; j++)
{
fmd.addColumn(JDOAnnotationUtils.getColumnMetaDataForColumnAnnotation(columns[j]));
}
}
return fmd;
}
/**
* Convenience method that tries to find if a specified member name (field or property) is for a field.
* @param cls The class
* @param memberName Name of the member
* @return Whether it is a field (else it's a property).
*/
private boolean isMemberOfClassAField(Class cls, String memberName)
{
try
{
cls.getDeclaredField(memberName);
}
catch (NoSuchFieldException nsfe)
{
return false;
}
// TODO It is possible that a memberName is a field AND a property. What do we do then ?
return true;
}
/**
* Check if class is persistable, by looking at annotations
* @param cls the Class
* @return The annotationObject for PersistenceCapable
*/
protected AnnotationObject isClassPersistable(Class cls)
{
AnnotationObject[] annotations = getClassAnnotationsForClass(cls);
for (int i = 0; i < annotations.length; i++)
{
String annClassName = annotations[i].getName();
if (annClassName.equals(JDOAnnotationUtils.PERSISTENCE_CAPABLE))
{
return annotations[i];
}
}
return null;
}
/**
* Check if class is persistence aware, by looking at annotations
* @param cls the Class
* @return true if the class has @PersistenceAware
*/
protected boolean isClassPersistenceAware(Class cls)
{
AnnotationObject[] annotations = getClassAnnotationsForClass(cls);
for (int i = 0; i < annotations.length; i++)
{
String annName = annotations[i].getName();
if (annName.equals(JDOAnnotationUtils.PERSISTENCE_AWARE))
{
return true;
}
}
return false;
}
/**
* Check if class has Query annotations (for classes that are not persistable but provide named query
* definitions.
* @param cls the Class
* @return true if the class has Named query annotations
*/
protected boolean doesClassHaveNamedQueries(Class cls)
{
AnnotationObject[] annotations = getClassAnnotationsForClass(cls);
for (int i = 0; i < annotations.length; i++)
{
String annClassName = annotations[i].getName();
if (annClassName.equals(JDOAnnotationUtils.QUERIES) || annClassName.equals(JDOAnnotationUtils.QUERY))
{
return true;
}
}
return false;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy