persistence@glassfish.java.net

Re: Fixing issue #383

From: Marina Vatkina <Marina.Vatkina_at_Sun.COM>
Date: Wed, 15 Mar 2006 13:22:50 -0800

Thanks!

Guy Pelletier wrote On 03/15/06 13:08,:
> Approved!
>
> Thanks,
> Guy
>
> ----- Original Message -----
> From: "Marina Vatkina" <Marina.Vatkina_at_Sun.COM>
> To: <persistence_at_glassfish.dev.java.net>
> Sent: Wednesday, March 15, 2006 4:05 PM
> Subject: Re: Fixing issue #383
>
>
>
>>OK. Please approve the fix:
>>
>>Index:
>>src/java/oracle/toplink/essentials/internal/annotations/EJBAnnotationsProcessor.java
>>===================================================================
>>RCS file:
>>/cvs/glassfish/entity-persistence/src/java/oracle/toplink/essentials/internal/annotations/EJBAnnotationsProcessor.java,v
>>retrieving revision 1.22
>>diff -r1.22 EJBAnnotationsProcessor.java
>>27a28
>>
>>>import java.util.Hashtable;
>>
>>1347c1348,1351
>>< m_session.getProject().getAliasDescriptors().remove("");
>>---
>>
>>> Hashtable aliasDescriptors =
>>>m_session.getProject().getAliasDescriptors();
>>> if (aliasDescriptors != null) {
>>> aliasDescriptors.remove("");
>>> }
>>
>>
>>thanks,
>>-marina
>>
>>Tom Ware wrote On 03/15/06 06:25,:
>>
>>>I took another look. Guy is correct here. Let's go with option A.
>>>
>>>Appologies,
>>>Tom
>>>
>>>Guy Pelletier wrote:
>>>
>>>
>>>
>>>>Actually I was already looking at this. Go ahead and use option A for
>>>>now.
>>>>We will plan to take a look at this again after 100% CTS compliance.
>>>>
>>>>Cheers,
>>>>Guy
>>>>
>>>>----- Original Message -----
>>>>From: "Tom Ware" <tom.ware_at_oracle.com>
>>>>To: <persistence_at_glassfish.dev.java.net>
>>>>Sent: Wednesday, March 15, 2006 8:43 AM
>>>>Subject: Re: Fixing issue #383
>>>>
>>>>
>>>>
>>>>
>>>>
>>>>
>>>>>That sounds fine to me.
>>>>>
>>>>>-Tom
>>>>>
>>>>>Craig L Russell wrote:
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>>Hi Marina,
>>>>>>
>>>>>>FWIW, I like to use pattern b if it's a one-shot issue (which this
>>>>>>sounds
>>>>>>like). There's no downside to creating a hashtable once. If you are
>>>>>>constantly creating it and testing for an empty hashset, it's easier
>>>>>>to
>>>>>>have the hashset defined as null and avoid the construction.
>>>>>>
>>>>>>Craig
>>>>>>
>>>>>>On Mar 14, 2006, at 6:53 PM, Marina Vatkina wrote:
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>>>Tom,
>>>>>>>
>>>>>>>The NPE is caused by the following code m_session.getProject
>>>>>>>().getAliasDescriptors().remove("");
>>>>>>>
>>>>>>>When there are no entities in the PU, the alias descriptors
>>>>>>>hashtable is null because it's never created.
>>>>>>>
>>>>>>>There are 2 options to fix it:
>>>>>>>a) change the line above to
>>>>>>>Hashtable d = m_session.getProject().getAliasDescriptors();
>>>>>>>if (d != null)
>>>>>>>d.remove("");
>>>>>>>
>>>>>>>b) Change the Project class to create aliasDescriptors in the
>>>>>>>constructor.
>>>>>>>
>>>>>>>If you don't see a problem with ether fix, I can make the change.
>>>>>>>
>>>>>>>regards,
>>>>>>>-marina
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>
>>>>>>Craig Russell
>>>>>>Architect, Sun Java Enterprise System http://java.sun.com/products/jdo
>>>>>>408 276-5638 mailto:Craig.Russell_at_sun.com
>>>>>>P.S. A good JDO? O, Gasp!
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>
>>>>>--
>>>>>Tom Ware
>>>>>Principal Software Engineer
>>>>>Oracle Canada Inc.
>>>>>
>>>>>Direct: (613) 783-4598
>>>>>Email: tom.ware_at_oracle.com
>>>>>
>>>>>
>>>>>
>>>
>>>
>
>
> --------------------------------------------------------------------------------
>
>
>
>>/*
>>* The contents of this file are subject to the terms
>>* of the Common Development and Distribution License
>>* (the "License"). You may not use this file except
>>* in compliance with the License.
>>*
>>* You can obtain a copy of the license at
>>* glassfish/bootstrap/legal/CDDLv1.0.txt or
>>* https://glassfish.dev.java.net/public/CDDLv1.0.html.
>>* See the License for the specific language governing
>>* permissions and limitations under the License.
>>*
>>* When distributing Covered Code, include this CDDL
>>* HEADER in each file and include the License file at
>>* glassfish/bootstrap/legal/CDDLv1.0.txt. If applicable,
>>* add the following below this CDDL HEADER, with the
>>* fields enclosed by brackets "[]" replaced with your
>>* own identifying information: Portions Copyright [yyyy]
>>* [name of copyright owner]
>>*/
>>// Copyright (c) 1998, 2006, Oracle. All rights reserved.
>>package oracle.toplink.essentials.internal.annotations;
>>
>>import java.util.List;
>>import java.util.Vector;
>>import java.util.HashSet;
>>import java.util.HashMap;
>>import java.util.Hashtable;
>>import java.util.Iterator;
>>import java.util.ArrayList;
>>import java.util.Collection;
>>
>>import java.lang.reflect.Field;
>>import java.lang.reflect.Method;
>>import java.lang.reflect.Modifier;
>>import java.lang.reflect.AnnotatedElement;
>>
>>import java.lang.annotation.Annotation;
>>
>>import javax.persistence.EnumType;
>>import javax.persistence.FetchType;
>>import javax.persistence.CascadeType;
>>import javax.persistence.FlushModeType;
>>
>>import javax.persistence.Id;
>>import javax.persistence.Table;
>>import javax.persistence.Basic;
>>import javax.persistence.MapKey;
>>import javax.persistence.Column;
>>import javax.persistence.Entity;
>>import javax.persistence.OrderBy;
>>import javax.persistence.IdClass;
>>import javax.persistence.Temporal;
>>import javax.persistence.PostLoad;
>>import javax.persistence.OneToOne;
>>import javax.persistence.QueryHint;
>>import javax.persistence.Transient;
>>import javax.persistence.ManyToOne;
>>import javax.persistence.PreUpdate;
>>import javax.persistence.OneToMany;
>>import javax.persistence.JoinTable;
>>import javax.persistence.PreRemove;
>>import javax.persistence.PostRemove;
>>import javax.persistence.PrePersist;
>>import javax.persistence.JoinColumn;
>>import javax.persistence.PostUpdate;
>>import javax.persistence.NamedQuery;
>>import javax.persistence.ManyToMany;
>>import javax.persistence.Enumerated;
>>import javax.persistence.PostPersist;
>>import javax.persistence.Inheritance;
>>import javax.persistence.JoinColumns;
>>import javax.persistence.FieldResult;
>>import javax.persistence.NamedQueries;
>>import javax.persistence.ColumnResult;
>>import javax.persistence.EntityResult;
>>import javax.persistence.GeneratedValue;
>>import javax.persistence.TableGenerator;
>>import javax.persistence.SecondaryTable;
>>import javax.persistence.SecondaryTables;
>>import javax.persistence.EntityListeners;
>>import javax.persistence.UniqueConstraint;
>>import javax.persistence.NamedNativeQuery;
>>import javax.persistence.AttributeOverride;
>>import javax.persistence.SequenceGenerator;
>>import javax.persistence.AttributeOverrides;
>>import javax.persistence.NamedNativeQueries;
>>import javax.persistence.DiscriminatorValue;
>>import javax.persistence.DiscriminatorColumn;
>>import javax.persistence.AssociationOverride;
>>import javax.persistence.AssociationOverrides;
>>import javax.persistence.SqlResultSetMapping;
>>import javax.persistence.SqlResultSetMappings;
>>import javax.persistence.PrimaryKeyJoinColumn;
>>import javax.persistence.PrimaryKeyJoinColumns;
>>import javax.persistence.ExcludeDefaultListeners;
>>import javax.persistence.ExcludeSuperclassListeners;
>>
>>import oracle.toplink.essentials.descriptors.ClassDescriptor;
>>import oracle.toplink.essentials.internal.sessions.AbstractSession;
>>
>>import oracle.toplink.essentials.internal.helper.DatabaseField;
>>import oracle.toplink.essentials.internal.helper.DatabaseTable;
>>
>>import oracle.toplink.essentials.exceptions.ValidationException;
>>
>>import oracle.toplink.essentials.internal.ejb.cmp3.EJBQueryImpl;
>>import
>>oracle.toplink.essentials.internal.ejb.cmp3.metadata.MetadataHelper;
>>import
>>oracle.toplink.essentials.internal.ejb.cmp3.metadata.MetadataAccessor;
>>import
>>oracle.toplink.essentials.internal.ejb.cmp3.metadata.MetadataProcessor;
>>import
>>oracle.toplink.essentials.internal.ejb.cmp3.metadata.MetadataJoinColumn;
>>import
>>oracle.toplink.essentials.internal.ejb.cmp3.metadata.MetadataDescriptor;
>>import
>>oracle.toplink.essentials.internal.ejb.cmp3.metadata.MetadataDefaultListener;
>>import
>>oracle.toplink.essentials.internal.ejb.cmp3.metadata.MetadataEntityListener;
>>
>>import oracle.toplink.essentials.mappings.DatabaseMapping;
>>import oracle.toplink.essentials.mappings.OneToOneMapping;
>>import oracle.toplink.essentials.mappings.ManyToManyMapping;
>>import oracle.toplink.essentials.mappings.CollectionMapping;
>>import oracle.toplink.essentials.mappings.DirectToFieldMapping;
>>import oracle.toplink.essentials.mappings.AggregateObjectMapping;
>>import oracle.toplink.essentials.mappings.ForeignReferenceMapping;
>>import oracle.toplink.essentials.queryframework.EJBQLPlaceHolderQuery;
>>
>>/**
>>* Process the CMP annotations on a set of classes into a given TopLink
>>* session's project.
>>*
>>* @author Guy Pelletier
>>* @since TopLink 10.1.3/EJB 3.0 Preview
>>*/
>>public class EJBAnnotationsProcessor extends MetadataProcessor {
>> private Collection<Class> m_classes;
>>
>> // Store the named queries when processing O/R annotations.
>> private HashSet<DescriptorMetadata> m_entitiesWithQueries;
>>
>> // Responsible for all sequencing-related processing.
>> private SequencingProcessor m_sequencingProcessor;
>>
>> /**
>> * INTERNAL:
>> */
>> public EJBAnnotationsProcessor(AbstractSession session, ClassLoader
>>loader, Collection<Class> classes) {
>> m_loader = loader;
>> m_classes = classes;
>> m_session = session;
>> m_enableLazyForOneToOne = false;
>> m_metadataDescriptors = new HashMap();
>> m_logger = new EJBAnnotationsLogger(m_session);
>> m_sequencingProcessor = new SequencingProcessor();
>> m_relatedEntities = new HashSet<DescriptorMetadata>();
>> m_entitiesWithQueries = new HashSet<DescriptorMetadata>();
>> m_processingContext = EJB_ANNOTATIONS;
>> }
>>
>> /**
>> * INTERNAL:
>> * Called for XML/Annotation merging.
>> */
>> public EJBAnnotationsProcessor(AbstractSession session, ClassLoader
>>loader, Collection<Class> classes, boolean enableLazyForOneToOne,
>>HashMap<Class, MetadataDescriptor> metadataDescriptors) {
>> this(session, loader, classes);
>> m_enableLazyForOneToOne = enableLazyForOneToOne;
>>
>> // Convert the metadata descriptors (if there are any) to
>>annotations
>> // meta data from xml meta data.
>> if (metadataDescriptors != null && !metadataDescriptors.isEmpty())
>>{
>> for (MetadataDescriptor mdd : metadataDescriptors.values()) {
>> DescriptorMetadata dmd = new DescriptorMetadata(mdd);
>> m_metadataDescriptors.put(dmd.getJavaClass(), dmd);
>> }
>> }
>> }
>>
>> /**
>> * INTERNAL:
>> * Method to place EntityListener's on the descriptors from the given
>> * session. This call is made from the EntityManagerSetup deploy call.
>> */
>> public void addEntityListeners(AbstractSession session,
>>Collection<Class> entityClasses) {
>> updateClassesInMetadata();
>>
>> for (Class entityClass: entityClasses) {
>> DescriptorMetadata dmd = (DescriptorMetadata)
>>m_metadataDescriptors.get(entityClass);
>>
>> // We likely have a mapped superclass to which there is no dmd,
>> // so ignore it.
>> if (dmd != null) {
>> // By default use the XML exclude-superclass-listeners
>>flag.
>>
>>dmd.setExcludeSuperclassListeners(dmd.isXmlExcludeSuperclassListenersSet());
>>
>> // By default use the XML exclude-superclass-listeners
>>flag.
>>
>>dmd.setExcludeDefaultListeners(dmd.isXmlExcludeSuperclassListenersSet());
>>
>> // Check for default listeners and add them. We add them
>> // regardless if the exclude-default-listeners is set. This
>> // allows the user to change the exlcude flag at runtime
>>and
>> // have the default listeners available to them.
>> for (MetadataDefaultListener defaultListener :
>>(List<MetadataDefaultListener>) dmd.getDefaultListeners()) {
>> // Init the default listener with what we found in XML.
>> defaultListener.initializeCallbackMethods(m_loader);
>>
>> // Process the default listener for annotated call back
>> // methods and add when necessary.
>>
>>processCallbackMethods(MetadataHelper.getMethods(defaultListener.getListenerClass()),
>>defaultListener, dmd);
>>
>> // Add the default listener to the descriptor event
>>manager.
>> dmd.addDefaultEventListener(defaultListener);
>> }
>>
>> // Set the @ExcludeSuperclassListeners flag. Don't
>>overwrite a
>> // 'true' value XML default though.
>> if
>>(AnnotationsHelper.isAnnotationPresent(ExcludeSuperclassListeners.class,
>>dmd)) {
>> dmd.setExcludeSuperclassListeners(true);
>> }
>>
>> // Set the @ExcludeDefaultListeners flag. Don't overwrite
>>a
>> // 'true' value XML default though.
>> if
>>(AnnotationsHelper.isAnnotationPresent(ExcludeDefaultListeners.class,
>>dmd)) {
>> dmd.setExcludeDefaultListeners(true);
>> }
>>
>> // Check for @EntityListeners.
>> if
>>(AnnotationsHelper.isAnnotationPresent(EntityListeners.class, dmd)) {
>> EntityListeners entityListeners =
>>AnnotationsHelper.getAnnotation(EntityListeners.class, dmd);
>>
>> for (Class entityListener : entityListeners.value()) {
>> MetadataEntityListener listener = new
>>MetadataEntityListener(entityListener, entityClass);
>>
>>processCallbackMethods(MetadataHelper.getMethods(entityListener),
>>listener, dmd);
>> dmd.addEntityListenerEventListener(listener);
>> }
>> }
>>
>> // Check for lifecycle callback methods on the entity
>>itself
>> // and its mapped superclasses.
>> AnnotationsEntityClassListener listener = new
>>AnnotationsEntityClassListener(entityClass);
>>
>> // Check the mapped superclasses ...
>> for (Class mappedSuperclass : dmd.getMappedSuperclasses())
>>{
>>
>>processCallbackMethodsFromMappedSuperclass(mappedSuperclass, listener,
>>dmd);
>> }
>>
>> // Check the entity class ...
>>
>>processCallbackMethods(MetadataHelper.getDeclaredMethods(entityClass),
>>listener, dmd);
>>
>> if (listener.hasCallbackMethods()) {
>> dmd.addEntityEventListener(listener);
>> }
>> }
>> }
>> }
>>
>> /**
>> * INTERNAL:
>> * Method to place NamedQueries and NamedNativeQueries on the given
>>session.
>> * This call is made from the EntityManagerSetup deploy call.
>> */
>> public void addNamedQueriesToSession(AbstractSession session) {
>> for (DescriptorMetadata dmd : m_entitiesWithQueries) {
>> for (NamedQuery namedQuery : dmd.getNamedQueries()) {
>> processNamedQuery(namedQuery, dmd, session);
>> }
>>
>> for (NamedNativeQuery namedNativeQuery :
>>dmd.getNamedNativeQueries()) {
>> processNamedNativeQuery(namedNativeQuery, dmd, session);
>> }
>> }
>> }
>>
>> /**
>> * INTERNAL:
>> * In the case of the XML processor using a defaulted name during
>> * processing, check for the actual table name in annotations - if one
>> * exists, set it as the primary database table for the related
>>descriptor,
>> * and update all applicable fields accordingly.
>> */
>> protected void adjustTableOnExistingFields(MetadataDescriptor md) {
>> // create the primary table based on annotations
>> Table table = AnnotationsHelper.getAnnotation(Table.class, md);
>> if (table == null) {
>> // do nothing - use the default table created by the XML Processor
>> return;
>> }
>>
>> // Process the table and add set it as primary.
>> processTable(table.name(), table.catalog(), table.schema(),
>>table.uniqueConstraints(), md);
>>
>> // now we need to update any references to the default table
>> for (Iterator fieldIt =
>>md.getFieldsWithDefaultPrimaryTableSet().iterator(); fieldIt.hasNext(); )
>>{
>> DatabaseField dbField = (DatabaseField) fieldIt.next();
>>
>>dbField.setTable((DatabaseTable)md.getDescriptor().getTables().elementAt(0));
>> }
>> }
>>
>> /**
>> * INTERNAL:
>> * Method to return the name of the join table.
>> */
>> protected DatabaseTable buildJoinTable(JoinTable joinTable,
>>MetadataAccessor accessor) {
>> DatabaseTable dbJoinTable;
>> if (joinTable != null) {
>> dbJoinTable = buildJoinTable(joinTable.name(), joinTable.catalog(),
>>joinTable.schema(), accessor);
>>
>> // Process the @UniqueConstraints for this table.
>> processUniqueConstraints(joinTable.uniqueConstraints(), dbJoinTable);
>> } else {
>> dbJoinTable = buildJoinTable(accessor);
>> }
>>
>> return dbJoinTable;
>> }
>>
>> /**
>> * INTERNAL:
>> * Return the classes set for processing
>> */
>> public Collection<Class> getClasses() {
>> return m_classes;
>> }
>>
>> /**
>> * INTERNAL:
>>* Return the logger used by this processor.
>>*/
>>public EJBAnnotationsLogger getLogger() {
>>return (EJBAnnotationsLogger) m_logger;
>> }
>>
>> /**
>> * INTERNAL:
>>* Lazily create a metadata/descriptor for any given class.
>> */
>>public DescriptorMetadata getMetadataDescriptor(Class cls) {
>>DescriptorMetadata dmd = (DescriptorMetadata)
>>m_metadataDescriptors.get(cls);
>> ClassDescriptor descriptorOnProject =
>>MetadataHelper.findDescriptor(m_session.getProject(),cls);
>>
>>if (dmd == null) {
>> // We don't have a dmd, check if there is a descriptor for this
>> // class on the project already.
>> if (descriptorOnProject != null) {
>> // Wrap the existing descriptor into a DescriptorMetadata.
>> dmd = new DescriptorMetadata(descriptorOnProject, cls);
>> } else {
>> // Create a new descriptor metadata and add it to the
>>project.
>> dmd = new DescriptorMetadata(cls);
>> m_session.getProject().addDescriptor(dmd.getDescriptor());
>> }
>>
>> m_metadataDescriptors.put(cls, dmd);
>> } else if (descriptorOnProject == null) {
>> // WIP - We have a descriptor metadata but the descriptor
>>itself is
>> // not on the project. This should never be true, it can be now
>>but
>> // should be fixed.
>> m_session.getProject().addDescriptor(dmd.getDescriptor());
>> }
>>
>> return dmd;
>>}
>>
>>/**
>> * INTERNAL:
>> */
>> protected boolean isTransient(AnnotatedElement annotatedElement, int
>>modifier, DescriptorMetadata dmd) {
>> if (AnnotationsHelper.isAnnotationPresent(Transient.class,
>>annotatedElement, dmd)) {
>> if
>>(AnnotationsHelper.getDeclaredAnnotationsCount(annotatedElement, dmd) > 1)
>>{
>> throw
>>ValidationException.mappingAnnotationsAppliedToTransientAttribute(annotatedElement);
>> }
>>
>> return true;
>> } else if (Modifier.isTransient(modifier)) {
>> if
>>(AnnotationsHelper.getDeclaredAnnotationsCount(annotatedElement, dmd) > 0)
>>{
>> throw
>>ValidationException.mappingAnnotationsAppliedToTransientAttribute(annotatedElement);
>> }
>>
>> return true;
>> }
>>
>> return false;
>> }
>>
>> /**
>> * INTERNAL:
>> * Return true is this annotated element is not marked transient,
>>static or
>> * abstract.
>> */
>> protected boolean isValidPersistenceElement(AnnotatedElement
>>annotatedElement, int modifiers, DescriptorMetadata dmd) {
>> return ! (isTransient(annotatedElement, modifiers, dmd) ||
>>Modifier.isStatic(modifiers) || Modifier.isAbstract(modifiers));
>> }
>>
>> /**
>> * INTERNAL:
>> * Check to see if this is a valid field to process for persistence. It
>>is
>> * valid if it is not static, transient or has a @Transient specified.
>> */
>> protected boolean isValidPersistenceField(Field field,
>>DescriptorMetadata dmd) {
>> return (isValidPersistenceElement(field, field.getModifiers(),
>>dmd));
>> }
>>
>> /**
>> * INTERNAL:
>> * Check to see if this is a valid method to process for persistence.
>>It is
>> * valid if it is not static, transient or has a @Transient specified.
>> */
>> protected boolean isValidPersistenceMethod(Method method,
>>DescriptorMetadata dmd) {
>> // Ignore methods marked transient, static or abstract.
>> if (isValidPersistenceElement(method, method.getModifiers(), dmd))
>>{
>> // Look for methods that begin with "get" or "is", ignore all
>>others.
>> String methodName = method.getName();
>> if (MetadataHelper.isValidPersistenceMethodName(methodName)) {
>> // Ignore get methods with parameters.
>> if (method.getParameterTypes().length > 0) {
>> return false;
>> }
>>
>> String setMethodName =
>>MetadataHelper.getSetMethodName(method, dmd.getJavaClass());
>>
>> if (setMethodName == null) {
>> if
>>(AnnotationsHelper.getDeclaredAnnotationsCount(method, dmd) > 0) {
>> // We decorated the property with annotations, but
>>have
>> // no corresponding setter property.
>> throw
>>ValidationException.noCorrespondingSetterMethodDefined(dmd.getJavaClass(),
>>method);
>> }
>>
>>
>>getLogger().logWarningMessage(EJBAnnotationsLogger.IGNORE_GET_METHOD, dmd,
>>method);
>> } else {
>> // Store the setMethodName for later retrieval to avoid
>> // figuring it out twice.
>> dmd.addSetMethodName(methodName, setMethodName);
>> return true;
>> }
>> }
>> }
>>
>> return false;
>> }
>>
>> /**
>> * INTERNAL:
>> * Method to init a collection mapping from a @OneToMany.
>> */
>> protected void populateCollectionMapping(CollectionMapping mapping,
>>Object oneToManyAnnotation, MetadataAccessor accessor) {
>> OneToMany oneToMany = (OneToMany) oneToManyAnnotation;
>>
>> // Process the annotation specifics if there is one (may have been
>> // defaulted). These are our defaults otherwise.
>> boolean usesIndirection = false;
>> Class targetEntity = void.class;
>> CascadeType[] cascade = {};
>>
>> if (oneToMany != null) {
>> // OneToMany.fetch()
>> usesIndirection = oneToMany.fetch() == FetchType.LAZY;
>> // OneToMany.targetEntity()
>> targetEntity = oneToMany.targetEntity();
>> // OneToMany.cascade()
>> cascade = oneToMany.cascade();
>> }
>>
>> populateCollectionMapping(mapping, accessor, usesIndirection,
>>targetEntity, cascade);
>> }
>>
>> /**
>> * INTERNAL:
>> */
>> protected void preProcessGeneratedValue(Object generatedValue,
>>MetadataAccessor accessor, DatabaseField field, MetadataDescriptor dmd) {
>> m_sequencingProcessor.preProcessGeneratedValue((GeneratedValue)
>>generatedValue, (Accessor) accessor, field, (DescriptorMetadata) dmd);
>> }
>>
>> /**
>> * INTERNAL:
>> */
>> protected void preProcessSequencing(MetadataAccessor ma) {
>> Accessor accessor = (Accessor) ma;
>> preProcessSequencing(accessor.getAnnotatedElement(),
>>accessor.getMetadataDescriptor());
>> }
>>
>> /**
>> * INTERNAL:
>> * Preprocess the sequencing annotations. Gather the necessary info.
>>The
>> * real sequencing setup is performed after all the sequencing-related
>> * annotations on all classes are preprocessed.
>> */
>> protected void preProcessSequencing(AnnotatedElement annotatedElement,
>>DescriptorMetadata dmd) {
>> TableGenerator tableGenerator =
>>AnnotationsHelper.getAnnotation(TableGenerator.class, annotatedElement,
>>dmd);
>> m_sequencingProcessor.preProcessTableGenerator(tableGenerator,
>>annotatedElement);
>>
>> SequenceGenerator sequenceGenerator =
>>AnnotationsHelper.getAnnotation(SequenceGenerator.class, annotatedElement,
>>dmd);
>>
>>m_sequencingProcessor.preProcessSequenceGenerator(sequenceGenerator,
>>annotatedElement);
>> }
>>
>> /**
>> * INTERNAL:
>> * Create mappings from the fields directly.
>> */
>> protected void processAccessorFields(Class cls, DescriptorMetadata dmd)
>>{
>> for (Field field : MetadataHelper.getFields(cls)) {
>> if (isValidPersistenceField(field, dmd)) {
>> processAccessor(new Accessor(field, this, dmd));
>> }
>> }
>> }
>>
>> /**
>> * INTERNAL:
>> * Create mappings via the class properties.
>> */
>> protected void processAccessorMethods(Class cls, DescriptorMetadata
>>dmd) {
>> for (Method method : MetadataHelper.getDeclaredMethods(cls)) {
>> if (isValidPersistenceMethod(method, dmd)) {
>> processAccessor(new Accessor(method, this, dmd));
>> }
>> }
>> }
>>
>> /**
>> * INTERNAL:
>> * Process the accessors for the given descriptor metadata class.
>> */
>> protected void processAccessors(MetadataDescriptor dmd) {
>> processAccessors(dmd.getJavaClass(), dmd.usesPropertyAccess(),
>>dmd);
>> }
>>
>> /**
>> * INTERNAL:
>> * Process the accessors for the given descriptor metadata class.
>> */
>> protected void processAccessors(Class cls, boolean usePropertyAccess,
>>MetadataDescriptor md) {
>> DescriptorMetadata dmd = (DescriptorMetadata) md;
>>
>> // Process the fields or methods on the class.
>> if (usePropertyAccess) {
>> processAccessorMethods(cls, dmd);
>> } else {
>> processAccessorFields(cls, dmd);
>> }
>> }
>>
>> /**
>> * INTERNAL:
>> * Process a @JoinTable.
>> */
>> protected void processJoinTable(MetadataAccessor accessor,
>>ManyToManyMapping mapping) {
>> JoinTable joinTable =
>>AnnotationsHelper.getAnnotation(JoinTable.class, accessor);
>>
>> // Figure out the join table name and set it on the mapping.
>> DatabaseTable relationTable = buildJoinTable(joinTable, accessor);
>> mapping.setRelationTable(relationTable);
>> String relationTableName = relationTable.getQualifiedName();
>>
>> // Process the JoinColumns and InverseJoinColumns.
>> Vector<MetadataJoinColumn> sourceKeys = new
>>Vector<MetadataJoinColumn>();
>> Vector<MetadataJoinColumn> targetKeys = new
>>Vector<MetadataJoinColumn>();
>>
>> // If the join table is not null, look for join columns.
>> if (joinTable != null) {
>> // Process the JoinColumns - source keys.
>> for (JoinColumn joinColumn : joinTable.joinColumns()) {
>> sourceKeys.add(processJoinColumn(joinColumn, accessor,
>>relationTableName, accessor.getMetadataDescriptor()));
>> }
>>
>> // Process the InverseJoinColumns - target keys.
>> for (JoinColumn inverseJoinColumn :
>>joinTable.inverseJoinColumns()) {
>> targetKeys.add(processJoinColumn(inverseJoinColumn,
>>accessor, relationTableName, accessor.getReferenceMetadataDescriptor()));
>> }
>> }
>>
>> processJoinTable(accessor, mapping, sourceKeys, targetKeys);
>> }
>>
>> /**
>> * INTERNAL:
>> * Process an @AssociationOverride for an Entity (or MappedSuperclass)
>> * that inherits from a MappedSuperclass.
>> *
>> * It will also look for an @AssociationOverride.
>> */
>> protected void processAssociationOverrides(Class cls,
>>DescriptorMetadata dmd) {
>> // Look for an @AssociationOverrides.
>> AssociationOverrides associationOverrides =
>>AnnotationsHelper.getAnnotation(AssociationOverrides.class, cls, dmd);
>> if (associationOverrides != null) {
>> for (AssociationOverride associationOverride :
>>associationOverrides.value()) {
>> dmd.addAssociationOverride(associationOverride.name(),
>>associationOverride.joinColumns());
>> }
>> }
>>
>> // Look for an @AssociationOverride.
>> AssociationOverride associationOverride =
>>AnnotationsHelper.getAnnotation(AssociationOverride.class, cls, dmd);
>> if (associationOverride != null) {
>> dmd.addAssociationOverride(associationOverride.name(),
>>associationOverride.joinColumns());
>> }
>> }
>>
>> /**
>> * INTERNAL:
>> * Process an @AssociationOverrides for an embedded object, that is, an
>> * aggregate object mapping in TopLink.
>> *
>> * It will also look for an @AssociationOverride.
>> */
>> protected void processAssociationOverrides(MetadataAccessor accessor,
>>AggregateObjectMapping mapping) {
>> // Look for an @AssociationOverrides.
>> AssociationOverrides associationOverrides =
>>AnnotationsHelper.getAnnotation(AssociationOverrides.class, accessor);
>> if (associationOverrides != null) {
>> for (AssociationOverride associationOverride :
>>associationOverrides.value()) {
>> processAssociationOverride(associationOverride, accessor,
>>mapping);
>> }
>> }
>>
>> // Look for an @AssociationOverride.
>> AssociationOverride associationOverride =
>>AnnotationsHelper.getAnnotation(AssociationOverride.class, accessor);
>> if (associationOverride != null) {
>> processAssociationOverride(associationOverride, accessor,
>>mapping);
>> }
>> }
>>
>> /**
>> * INTERNAL:
>> * Process an @AssociationOverride for an embedded object, that is, an
>> * aggregate object mapping in TopLink.
>> *
>> * This functionality is not supported in XML, hence why this method is
>> * defined here instead of on MetadataProcessor.
>> *
>> * Also this functionality is currently optional in the EJB 3.0 spec,
>>but
>> * since TopLink can handle it, it is implemented and assumes the user
>>has
>> * properly configured its use since it will fail silently.
>>*/
>>protected void processAssociationOverride(AssociationOverride
>>associationOverride, MetadataAccessor accessor, AggregateObjectMapping
>>aggregateMapping) {
>> MetadataDescriptor dmd = accessor.getMetadataDescriptor();
>> MetadataDescriptor aggregateDmd =
>>accessor.getReferenceMetadataDescriptor();
>>
>> // AssociationOverride.name(), the name of the attribute we want to
>> // override.
>> String name = associationOverride.name();
>> DatabaseMapping mapping =
>>aggregateDmd.getMappingForAttributeName(name);
>>
>> if (mapping == null) {
>> // WIP - For now fail silently.
>> //throw
>>ValidationException.invalidEmbeddableAttribute(aggregateDmd.getJavaClass(),
>>name, dmd.getJavaClass(), aggregateMapping.getAttributeName());
>> }
>>
>> if (mapping.isOneToOneMapping()) {
>> int index = 0;
>>
>> for (JoinColumn joinColumn : associationOverride.joinColumns())
>>{
>> // We can't change the mapping from the aggregate
>>descriptor
>> // so we have to add field name translations. This needs to
>>be
>> // tested since I am not entirely sure if this will
>>acutally
>> // work.
>> // In composite primary key case, how do we association the
>> // foreign keys? Right now we assume the association
>>overrides
>> // are specified in the same order as the original
>>joinColumns,
>> // therefore in the same order the foreign keys were added
>>to
>> // the mapping.
>> DatabaseField fkField = (DatabaseField) ((OneToOneMapping)
>>mapping).getForeignKeyFields().elementAt(index++);
>> aggregateMapping.addFieldNameTranslation(joinColumn.name(),
>>fkField.getName());
>> }
>> } else {
>> // WIP - For now fail silently.
>> }
>>}
>>
>> /**
>> * INTERNAL:
>> * Process an @AttributeOverride for an Entity (or MappedSuperclass)
>> * that inherits from a MappedSuperclass.
>> *
>> * It will also look for an @AttributeOverride.
>> */
>> protected void processAttributeOverrides(Class cls, DescriptorMetadata
>>dmd) {
>> // Look for an @AttributeOverrides.
>> AttributeOverrides attributeOverrides =
>>AnnotationsHelper.getAnnotation(AttributeOverrides.class, cls, dmd);
>> if (attributeOverrides != null) {
>> for (AttributeOverride attributeOverride :
>>attributeOverrides.value()) {
>> processAttributeOverride(attributeOverride.name(),
>>attributeOverride.column(), dmd);
>> }
>> }
>>
>> // Look for an @AttributeOverride.
>> AttributeOverride attributeOverride =
>>AnnotationsHelper.getAnnotation(AttributeOverride.class, cls, dmd);
>> if (attributeOverride != null) {
>> processAttributeOverride(attributeOverride.name(),
>>attributeOverride.column(), dmd);
>> }
>> }
>>
>> /**
>> * INTERNAL:
>> * Process an @AttributeOverrides for an embedded object, that is, an
>> * aggregate object mapping in TopLink.
>> *
>> * It will also look for an @AttributeOverride.
>> */
>> protected void processAttributeOverrides(MetadataAccessor accessor,
>>AggregateObjectMapping mapping) {
>> // Look for an @AttributeOverrides.
>> AttributeOverrides attributeOverrides =
>>AnnotationsHelper.getAnnotation(AttributeOverrides.class, accessor);
>>
>> if (attributeOverrides != null) {
>> for (AttributeOverride attributeOverride :
>>attributeOverrides.value()) {
>> processAttributeOverride(attributeOverride.name(),
>>attributeOverride.column(), accessor, mapping);
>> }
>> }
>>
>> // Look for an @AttributeOverride.
>> AttributeOverride attributeOverride =
>>AnnotationsHelper.getAnnotation(AttributeOverride.class, accessor);
>> if (attributeOverride != null) {
>> processAttributeOverride(attributeOverride.name(),
>>attributeOverride.column(), accessor, mapping);
>> }
>> }
>>
>> /**
>> * INTERNAL:
>> * Process a @Basic.
>> */
>> protected void processBasic(MetadataAccessor accessor,
>>DirectToFieldMapping mapping) {
>> Basic basic = AnnotationsHelper.getAnnotation(Basic.class,
>>accessor);
>>
>> if (basic != null) {
>> // Basic.fetch()
>> if (basic.fetch() == FetchType.LAZY) {
>>
>>getLogger().logWarningMessage(EJBAnnotationsLogger.IGNORE_BASIC_FETCH_LAZY,
>>accessor);
>> }
>>
>> // Basic.optional()
>> mapping.setIsOptional(basic.optional());
>> }
>> }
>>
>> /**
>> * INTERNAL:
>> * Process the cascade type on a mapping.
>> */
>>protected void processCascadeType(MetadataAccessor accessor, Object[]
>>types, ForeignReferenceMapping mapping) {
>>CascadeType[] cTypes = (CascadeType[]) types;
>>for (CascadeType type : cTypes) {
>>setCascadeType(type.name(), mapping);
>>}
>>
>> // apply the persistence unit default cascade-persist if necessary
>> if (accessor.getMetadataDescriptor().isCascadePersistSet() &&
>>!mapping.isCascadePersist()) {
>> setCascadeType(PERSIST, mapping);
>> }
>>}
>>
>> /**
>> * INTERNAL:
>> * Process a @Column into a DatabaseField and return it. Assumes the
>>column
>> * is not null at this point.
>> */
>> protected DatabaseField processColumn(Column column, AnnotatedElement
>>annotatedElement, String attributeName, DescriptorMetadata dmd) {
>>return processColumn(attributeName, dmd, column.name(),
>>column.columnDefinition(), column.table(),
>> column.unique(), column.nullable(), column.insertable(),
>>column.updatable(),
>> column.length(), column.precision(), column.scale(),
>>annotatedElement);
>>}
>>
>> /**
>> * INTERNAL:
>> * Process a @Column for the given accessor into a DatabaseField. If
>>there
>> * is no @Column, we will default one.
>> */
>> protected DatabaseField processColumn(MetadataAccessor accessor) {
>> MetadataDescriptor dmd = accessor.getMetadataDescriptor();
>> String attributeName = accessor.getAttributeName();
>> AnnotatedElement annotatedElement = (AnnotatedElement)
>>accessor.getAnnotatedElement();
>>
>> // Process the @Column if there is one othersie return a defaulted
>>one.
>> Column column = AnnotationsHelper.getAnnotation(Column.class,
>>accessor);
>> if (column == null) {
>> return processColumnDefaults(attributeName, dmd,
>>annotatedElement);
>> } else {
>> return processColumn(column, annotatedElement, attributeName,
>>dmd);
>> }
>> }
>>
>> /**
>> * INTERNAL:
>> * This method is called when processing an @AttributeOverride. The
>>column
>> * can not be null at this point.
>> */
>> protected DatabaseField processColumn(Object column, Object
>>annotatedElement, String attributeName, MetadataDescriptor dmd) {
>> return processColumn((Column) column, (AnnotatedElement)
>>annotatedElement, attributeName, (DescriptorMetadata) dmd);
>> }
>>
>> /**
>> * INTERNAL:
>> * Process a @DiscriminatorColumn (if there is one) to set this classes
>> * indication field name for inheritance.
>> */
>> protected void processDiscriminatorColumn(DescriptorMetadata dmd) {
>> // Process the disciminator column is there is one, otherwise,
>>default.
>> String name = "";
>> String discriminatorType = STRING;
>> String columnDefinition = "";
>> int length = 31;
>>
>> DiscriminatorColumn discriminatorColumn =
>>AnnotationsHelper.getAnnotation(DiscriminatorColumn.class, dmd);
>>
>> if (discriminatorColumn != null) {
>> // DiscriminatorColumn.name(), might default to ""
>> name = discriminatorColumn.name();
>>
>> discriminatorType =
>>discriminatorColumn.discriminatorType().toString();
>>
>> // DiscriminatorColumn.columnDefinition()
>> columnDefinition = discriminatorColumn.columnDefinition();
>>
>> // DiscriminatorColumn.length()
>> length = discriminatorColumn.length();
>> }
>>
>> processDiscriminatorColumn(dmd, name, columnDefinition, length,
>>discriminatorType);
>> }
>>
>> /**
>> * INTERNAL:
>> * Process a @DiscriminatorValue to set the class indicator on the root
>> * descriptor of the inheritance hierarchy.
>> * If there is no @DiscriminatorValue, the class indicator defaults to
>> * the class name.
>>*/
>>protected void processDiscriminatorValue(MetadataDescriptor md) {
>> DiscriminatorValue discriminatorValue =
>>AnnotationsHelper.getAnnotation(DiscriminatorValue.class, md);
>> String value = (discriminatorValue == null) ? null :
>>discriminatorValue.value();
>> processDiscriminatorValue(md, value);
>>}
>>
>> /**
>> * INTERNAL:
>> * Process the @MappedSuperclass(es) if there are any. There may be
>> * several MappedSuperclasses for any given Entity.
>> */
>> protected void processMappedSuperclasses(DescriptorMetadata dmd) {
>> for (Class cls : dmd.getMappedSuperclasses()) {
>> // Process the accessors from the mapped superclass.
>> processAccessors(cls, dmd.usesPropertyAccess(), dmd);
>>
>> // Process the attribute overrides on this MappedSuperclass, if
>> // there are any before processing its parent MappedSuperclass.
>> processAttributeOverrides(cls, dmd);
>> }
>> }
>>
>> /**
>> * INTERNAL:
>> * Process the items of interest on an entity class. The order of
>> * processing is important, care must be taken if changes must be made.
>> *
>> * Classes without an @Entity are ignored if no metadata complete flag
>> * is set.
>> */
>> protected void processEntityClass(Class cls) {
>> String entityName = "";
>> DescriptorMetadata dmd = null;
>>
>> // Check for metadata complete flag.
>> if (AnnotationsHelper.shouldIgnoreAnnotations(cls,
>>m_metadataDescriptors)) {
>> dmd = getMetadataDescriptor(cls);
>> } else {
>> // Othwerwise look for an @Entity .
>> Entity entity = AnnotationsHelper.getAnnotation(Entity.class,
>>cls);
>> if (entity != null) {
>> entityName = entity.name();
>> dmd = getMetadataDescriptor(cls);
>> }
>> }
>>
>> // If we have no descriptor metadata or if it is an aggregate
>> // descriptor, then ignore the processing for this class.
>> if (dmd != null && ! dmd.isAggregate()) {
>> // Set the ignore flags for the annotations that should not be
>> // processed since data is already defined on the descriptor.
>>Our
>> // XML/Annotation merge strategy is XML wins! We assume that
>>any
>> // data in the XML is properly and fully defined.
>> dmd.setIgnoreFlags();
>>
>> // Process the @Entity.
>> processEntity(entityName, dmd);
>>
>> // Process the @NamedQueries and @NamedQuery.
>> processNamedQueries(dmd);
>>
>> // Process the @NamedNativeQueries and @NamedNativeQuery.
>> processNamedNativeQueries(dmd);
>>
>> // Process the @SqlRessultSetMapping.
>> processSqlResultSetMappings(dmd);
>>
>> // Pre-process the sequencing annotations.
>> preProcessSequencing(cls, dmd);
>>
>> // Process the @Table if there is one. Must be processed before
>>the
>> // calls below.
>> processTable(dmd);
>>
>> // Process an @Inheritance. (only specified on the root)
>> processInheritance(dmd);
>>
>> // Process the @IdClass (pkClass).
>> processIdClass(dmd);
>>
>> // Set our attribute overrides from the entity class before
>> // processing the accessors from the mapped superclass.
>> processAttributeOverrides(cls, dmd);
>>
>> // Set our association overrides from the entity class before
>> // processing the accessors from the mapped superclass.
>> processAssociationOverrides(cls, dmd);
>>
>> // Process the @MappedSuperclass(es).
>> processMappedSuperclasses(dmd);
>>
>> // Process the accessors on this entity now.
>> processAccessors(dmd);
>>
>> // If this descriptor has a composite primary key, check that
>>all
>> // our composite primary key attributes were validated.
>> if (dmd.hasCompositePrimaryKey()) {
>> if (dmd.pkClassWasNotValidated()) {
>> throw
>>ValidationException.invalidCompositePKSpecification(cls,
>>dmd.getPKClassName());
>> }
>> } else {
>> // Descriptor has a single primary key. Validate an id
>> // attribute was found, unless we are an inheritance
>>subclass.
>> if (! dmd.hasPrimaryKeyFields() &&
>>!dmd.isInheritanceSubclass()) {
>> throw
>>ValidationException.noPrimaryKeyAnnotationsFound(cls);
>> }
>> }
>>
>> // Process the @SecondaryTable(s).
>> processSecondaryTables(dmd);
>> }
>> }
>>
>> /**
>> * INTERNAL:
>> * Process an @Enumerated. The method may still be called if no
>>@Enumerated
>> * has been specified but the accessor's reference class is a valid
>> * enumerated type.
>> */
>> protected void processEnumerated(MetadataAccessor accessor,
>>DirectToFieldMapping mapping) {
>> boolean isOrdinal = true; // default
>>
>> // If we have an @Enumerated annotation get the enumerated type.
>> if (accessor.hasEnumerated()) {
>> Enumerated enumerated =
>>AnnotationsHelper.getAnnotation(Enumerated.class, accessor);
>> isOrdinal = (enumerated.value() == EnumType.ORDINAL);
>> }
>>
>> processEnumerated(accessor, isOrdinal, mapping);
>> }
>>
>> /**
>> * INTERNAL:
>> * Process the array of methods for lifecyle callback events and set
>>them
>> * on the given event listener.
>> */
>> protected void processCallbackMethods(Method[] methods,
>>MetadataEntityListener listener, DescriptorMetadata dmd) {
>> for (Method method : methods) {
>> processPostLoad(method, listener, dmd);
>> processPostPersist(method, listener, dmd);
>> processPostRemove(method, listener, dmd);
>> processPostUpdate(method, listener, dmd);
>> processPrePersist(method, listener, dmd);
>> processPreRemove(method, listener, dmd);
>> processPreUpdate(method, listener, dmd);
>> }
>> }
>>
>> /**
>> * INTERNAL:
>> * Process lifecyle callback event methods for a mapped superclass. We
>>must
>> * 'convert' the method to the entity class context before adding it to
>>the
>> * listener.
>> */
>> protected void processCallbackMethodsFromMappedSuperclass(Class
>>mappedSuperclass, MetadataEntityListener listener, DescriptorMetadata dmd)
>>{
>> ArrayList<Method> methods = new ArrayList<Method>();
>> Method[] allMethods =
>>MetadataHelper.getMethods(dmd.getJavaClass());
>>
>> for (Method method :
>>MetadataHelper.getDeclaredMethods(mappedSuperclass)) {
>> methods.add(MetadataHelper.getMethodForName(allMethods,
>>method.getName()));
>> }
>>
>> processCallbackMethods(methods.toArray(new Method[methods.size()]),
>>listener, dmd);
>> }
>>
>> /**
>> * INTERNAL:
>> * Process an @Id if there is one.
>> */
>> protected void processId(MetadataAccessor accessor, DatabaseField
>>field) {
>> Id id = AnnotationsHelper.getAnnotation(Id.class, accessor);
>>
>> if (id != null) {
>> processId(accessor, field,
>>AnnotationsHelper.getAnnotation(GeneratedValue.class, accessor));
>> }
>> }
>>
>> /**
>> * INTERNAL:
>> * Process an @IdClass. It is used to specify composite primary keys.
>> * The primary keys will be processed and stored from the PK class so
>>that
>> * they may be validated against the fields or properties of the entity
>> * bean. The access type of a primary key class is determined by the
>>access
>> * type of the entity for which it is the primary key.
>> */
>> protected void processIdClass(DescriptorMetadata dmd) {
>> IdClass idClass = AnnotationsHelper.getAnnotation(IdClass.class, dmd);
>> if (idClass != null) {
>> // IdClass.value(), our pk class.
>> processIdClass(dmd, idClass.value());
>> }
>> }
>>
>> /**
>> * INTERNAL:
>> * Process an @Inheritance if there is one. An @Inheritance must be
>> * specified on the entity class that is the root of then entity class
>> * hierarchy.
>> */
>> protected void processInheritance(DescriptorMetadata dmd) {
>> Inheritance inheritance =
>>AnnotationsHelper.getAnnotation(Inheritance.class, dmd);
>>
>> if (inheritance != null) {
>> if (dmd.ignoreInheritanceAnnotations() ||
>>dmd.isInheritanceSubclass()) {
>> // XML/Annotation merging. XML wins, ignore annotations.
>> // Also, ignore an @Inheritance on an entity class that is
>> // already a sub-class within an inheritance hierarchy.
>>
>>getLogger().logWarningMessage(EJBAnnotationsLogger.IGNORE_INHERITANCE,
>>dmd);
>> } else {
>> // Inheritance.strategy(), store on the descriptor
>>metadata.
>> dmd.setInheritanceStrategy(inheritance.strategy());
>>
>> // Process the @DiscriminatorColumn.
>> processDiscriminatorColumn(dmd);
>>
>> // Process the @DiscriminatorValue.
>> processDiscriminatorValue(dmd);
>> }
>> }
>> }
>>
>> /**
>> * INTERNAL:
>> * Process a @JoinColumn. Returns a MetadataJoinColumn object.
>> */
>> protected MetadataJoinColumn processJoinColumn(JoinColumn joinColumn,
>>MetadataAccessor accessor, String targetTable, MetadataDescriptor
>>sourceDmd) {
>> return processJoinColumn(
>> accessor,
>> targetTable,
>> sourceDmd,
>> joinColumn.name(),
>> joinColumn.referencedColumnName(),
>> joinColumn.columnDefinition(),
>> joinColumn.table(),
>> joinColumn.unique(),
>> joinColumn.nullable(),
>> joinColumn.insertable(),
>> joinColumn.updatable());
>> }
>>
>> /**
>> * INTERNAL:
>> * Process a @JoinColumns or @JoinColumn based on if the descriptor
>>metadata
>> * from the accessor uses a composite primary key or not.
>> * Returns a Vector of MetadataJoinColumn.
>> */
>> protected Vector<MetadataJoinColumn>
>>processJoinColumns(MetadataAccessor accessor) {
>> Vector<MetadataJoinColumn> allJoinColumns = new
>>Vector<MetadataJoinColumn>();
>>
>> MetadataDescriptor dmd = accessor.getMetadataDescriptor();
>> String targetTableName = dmd.getPrimaryTableName();
>> MetadataDescriptor referenceDmd =
>>accessor.getReferenceMetadataDescriptor();
>> String sourceTableName = referenceDmd.getPrimaryTableName();
>>
>> if (referenceDmd.hasCompositePrimaryKey()) {
>> // Composite primary key, look for a @JoinColumns.
>> JoinColumn[] joinColumns;
>> if (dmd.hasAssociationOverrideFor(accessor)) {
>> joinColumns = (JoinColumn[])
>>dmd.getAssociationOverrideFor(accessor);
>> } else {
>> JoinColumns jcs =
>>AnnotationsHelper.getAnnotation(JoinColumns.class, accessor);
>>
>> if (jcs == null) {
>> throw
>>ValidationException.incompleteJoinColumnsSpecified(accessor.getAnnotatedElement(),
>>accessor.getJavaClass());
>> } else {
>> joinColumns = jcs.value();
>> }
>> }
>>
>> // The number of JoinColumn specified should equal the number
>>of primary key fields.
>> if (joinColumns.length !=
>>referenceDmd.getPrimaryKeyFields().size()) {
>> throw
>>ValidationException.incompleteJoinColumnsSpecified(accessor.getAnnotatedElement(),
>>accessor.getJavaClass());
>> }
>>
>> for (JoinColumn joinColumn : joinColumns) {
>> allJoinColumns.add(processJoinColumn(joinColumn, accessor,
>>targetTableName, referenceDmd));
>> }
>> } else {
>> // Single primary key, look for a @JoinColumn.
>> JoinColumn joinColumn;
>> if (dmd.hasAssociationOverrideFor(accessor)) {
>> joinColumn = ((JoinColumn[])
>>dmd.getAssociationOverrideFor(accessor))[0];
>> } else {
>> joinColumn =
>>AnnotationsHelper.getAnnotation(JoinColumn.class, accessor);
>> }
>>
>> if (joinColumn == null) {
>> if (accessor.hasJoinColumns()) {
>> throw
>>ValidationException.excessiveJoinColumnsSpecified(accessor.getAnnotatedElement(),
>>accessor.getJavaClass());
>> }
>>
>> addJoinColumnDefault(allJoinColumns, sourceTableName,
>>targetTableName, dmd);
>> } else {
>> allJoinColumns.add(processJoinColumn(joinColumn, accessor,
>>targetTableName, referenceDmd));
>> }
>> }
>>
>> return allJoinColumns;
>> }
>>
>> /**
>> * INTERNAL:
>> * Process a @ManyToMany into a TopLink ManyToMany mapping. The method
>> * assumes there is actually a ManyToMany annotation on the annotated
>> * element.
>> */
>> protected void processManyToMany(MetadataAccessor accessor) {
>> ManyToMany manyToMany =
>>AnnotationsHelper.getAnnotation(ManyToMany.class, accessor);
>> processManyToMany(accessor, manyToMany.mappedBy(),
>>manyToMany.cascade(), manyToMany.fetch() == FetchType.LAZY,
>>manyToMany.targetEntity());
>> }
>>
>> /**
>> * INTERNAL:
>> * Process a @ManyToOne into a TopLink OneToOne mapping. The method
>>assumes
>> * there is actually a ManyToOne annotation on the annotated element.
>> *
>> * Note: Target foreign keys are not valid for m-1 mapping
>> */
>> protected void processManyToOne(MetadataAccessor accessor) {
>> ManyToOne manyToOne =
>>AnnotationsHelper.getAnnotation(ManyToOne.class, accessor);
>> processManyToOne(accessor, manyToOne.cascade(), manyToOne.fetch()
>>== FetchType.LAZY, manyToOne.optional(), manyToOne.targetEntity());
>> }
>>
>> /**
>> * INTERNAL:
>> * Process a @MapKey for a 1-M or M-M mapping. Will return the map key
>> * method name that should be use, null otherwise.
>> */
>> protected String processMapKey(MetadataAccessor accessor,
>>CollectionMapping mapping) {
>> MapKey mapKey = AnnotationsHelper.getAnnotation(MapKey.class,
>>accessor);
>> if (mapKey == null) {
>> return null;
>> }
>>
>> return processMapKey(accessor, mapping, mapKey.name());
>> }
>>
>> /**
>> * INTERNAL:
>> * Process a @NamedNativeQueries. The method will also look for
>> * a @NamedNativeQuery. This method currently only stores the queries
>>if
>> * there are some. The actually query processing isn't done till
>> * addNamedQueriesToSession is called.
>> */
>> protected void processNamedNativeQueries(DescriptorMetadata dmd) {
>> // Look for a NamedNativeQueries annotation.
>> NamedNativeQueries namedNativeQueries =
>>AnnotationsHelper.getAnnotation(NamedNativeQueries.class, dmd);
>> if (namedNativeQueries != null) {
>> for (NamedNativeQuery namedNativeQuery :
>>namedNativeQueries.value()) {
>> dmd.addNamedNativeQuery(namedNativeQuery);
>> }
>>
>> m_entitiesWithQueries.add(dmd);
>> }
>>
>> // Look for a NamedNativeQuery annotation.
>> NamedNativeQuery namedNativeQuery =
>>AnnotationsHelper.getAnnotation(NamedNativeQuery.class, dmd);
>> if (namedNativeQuery != null) {
>> dmd.addNamedNativeQuery(namedNativeQuery);
>> m_entitiesWithQueries.add(dmd);
>> }
>> }
>>
>> /**
>> * INTERNAL:
>> * Does the actual NamedNativeQuery validation and adds the query to
>>the
>> * session.
>> */
>> protected void processNamedNativeQuery(NamedNativeQuery
>>namedNativeQuery, DescriptorMetadata dmd, AbstractSession session) {
>> // NamedNativeQuery.name()
>> String name = namedNativeQuery.name();
>>
>> if (session.getQuery(name) != null) {
>> // XML/Annotation merging. XML wins, ignore annotations.
>>
>>getLogger().logWarningMessage(EJBAnnotationsLogger.IGNORE_QUERY, dmd,
>>name);
>> } else {
>> // NamedNativeQuery.query(), contains the sql string.
>> String queryString = namedNativeQuery.query();
>>
>> // NamedNativeQuery.hints()
>> HashMap hints = processQueryHints(namedNativeQuery.hints());
>>
>> // NamedNativeQuery.resultClass()
>> Class resultClass = namedNativeQuery.resultClass();
>> if (resultClass != void.class) {
>> resultClass =
>>MetadataHelper.getClassForName(resultClass.getName(), m_loader);
>> session.addQuery(name,
>>EJBQueryImpl.buildSQLDatabaseQuery(resultClass, queryString, hints));
>> return;
>> }
>>
>> // NamedNativeQuery.resultSetMapping(), name of
>>SQLResultSetMapping
>> String resultSetMapping = namedNativeQuery.resultSetMapping();
>> if (! resultSetMapping.equals("")) {
>> session.addQuery(name,
>>EJBQueryImpl.buildSQLDatabaseQuery(resultSetMapping, queryString, hints));
>> return;
>> }
>>
>> // Neither a resultClass or resultSetMapping is specified so
>>place in a temp query on the session
>> session.addQuery(name, EJBQueryImpl.buildSQLDatabaseQuery(
>>queryString, hints));
>> }
>> }
>>
>> /**
>> * INTERNAL:
>> * Process a @NamedQueries. The method will also look for a
>>@NamedQuery.
>> * This method currently only stores the queries if there are some. The
>> * actually query processing isn't done till addNamedQueriesToSession
>>is
>> * called.
>> */
>> protected void processNamedQueries(DescriptorMetadata dmd) {
>> // Look for a NamedQueries annotation.
>> NamedQueries namedQueries =
>>AnnotationsHelper.getAnnotation(NamedQueries.class, dmd);
>> if (namedQueries != null) {
>> for (NamedQuery namedQuery : namedQueries.value()) {
>> dmd.addNamedQuery(namedQuery);
>> }
>>
>> m_entitiesWithQueries.add(dmd);
>> }
>>
>> // Look for a NamedQuery annotation.
>> NamedQuery namedQuery =
>>AnnotationsHelper.getAnnotation(NamedQuery.class, dmd);
>> if (namedQuery != null) {
>> dmd.addNamedQuery(namedQuery);
>> m_entitiesWithQueries.add(dmd);
>> }
>> }
>>
>> /**
>> * INTERNAL:
>> * Does the actual NamedQuery validation and adds the query to the
>>session.
>> */
>> protected void processNamedQuery(NamedQuery namedQuery,
>>DescriptorMetadata dmd, AbstractSession session) {
>> // NamedQuery.name(), is the name of the query.
>> String name = namedQuery.name();
>>
>> if (session.getQuery(name) != null) {
>>
>>getLogger().logWarningMessage(EJBAnnotationsLogger.IGNORE_QUERY, dmd,
>>name);
>> } else {
>> try {
>> // NamedQuery.query(), contains the ejbql string.
>> String queryString = namedQuery.query();
>>
>> // NamedQuery.hints()
>> HashMap hints = processQueryHints(namedQuery.hints());
>>
>> // Add the query.
>> session.addEjbqlPlaceHolderQuery(new
>>EJBQLPlaceHolderQuery(name, queryString, hints));
>> } catch (Exception exception) {
>> throw
>>ValidationException.errorProcessingNamedQueryAnnotation(dmd.getJavaClass(),
>>name, exception);
>> }
>> }
>> }
>>
>> /**
>> * INTERNAL:
>> * Process a @OneToMany into a TopLink OneToMany mapping. If an
>>@JoinTable
>> * is found however, we must create a ManyToMany mapping.
>> */
>> protected void processOneToMany(MetadataAccessor accessor) {
>> // Extract the annotation, if there is one. We must null check.
>> OneToMany oneToMany =
>>AnnotationsHelper.getAnnotation(OneToMany.class, accessor);
>> String mappedBy = "";
>>
>> if (oneToMany != null) {
>> mappedBy = oneToMany.mappedBy();
>> }
>>
>> processOneToMany(accessor, oneToMany, mappedBy);
>> }
>>
>> /**
>> * INTERNAL:
>> * Process a @OneToOne into a TopLink OneToOne mapping.
>> */
>> protected void processOneToOne(MetadataAccessor accessor) {
>> // Extract the annotation, if there is one. We must null check.
>> OneToOne oneToOne = AnnotationsHelper.getAnnotation(OneToOne.class,
>>accessor);
>>
>> // Process the annotation specifics if there is one (may have been
>> // defaulted). These are our defaults otherwise.
>> String mappedBy = "";
>> Class targetEntity = void.class;
>> CascadeType[] cascade = {};
>> boolean optional = true;
>> boolean usesIndirection = false;
>>
>> if (oneToOne != null) {
>> // OneToOne.targetEntity()
>> targetEntity = oneToOne.targetEntity();
>> // OneToOne.cascade()
>> cascade = oneToOne.cascade();
>> // OneToOne.fetch()
>> usesIndirection = oneToOne.fetch() == FetchType.LAZY;
>> // OneToOne.optional()
>> optional = oneToOne.optional();
>> // OneToOne.mappedBy()
>> mappedBy = oneToOne.mappedBy();
>> }
>>
>> processOneToOne(accessor, mappedBy, targetEntity, cascade,
>>optional, usesIndirection);
>> }
>>
>> /**
>> * INTERNAL:
>> * Process the annotations and fill in the project. Process in 2 steps,
>> * first step to process most metadata except relationship mappings,
>>second
>> * step to go through the classes that have relationships and fill in
>>the
>> * rest.
>> *
>> * Assumes only Entity classes have been set for processing.
>> */
>> public AbstractSession processORAnnotations() {
>> // Step 1, fill in most of the metadata.
>> for (Class cls: m_classes) {
>> // Process the entity class.
>> processEntityClass(cls);
>> }
>>
>> // Step 1.5, sequencing setup.
>> m_sequencingProcessor.process(m_session.getProject().getLogin());
>>
>> // Step 2, fill in the relationships.
>> for (DescriptorMetadata dmd: (HashSet<DescriptorMetadata>)
>>m_relatedEntities) {
>> processRelatedEntity(dmd);
>> }
>>
>> // remove from aliased descriptors the one named "" - it's there
>>under another name
>> Hashtable aliasDescriptors =
>>m_session.getProject().getAliasDescriptors();
>> if (aliasDescriptors != null) {
>> aliasDescriptors.remove("");
>> }
>>
>> // Return the modified session and we are done!
>> return m_session;
>> }
>>
>> /**
>> * INTERNAL:
>> * Process the @OrderBy annotation for collection mappings. It
>>specifies
>> * the ordering of the elements of a collection valued association at
>>the
>> * point when the association is retrieved.
>> *
>> * The syntax of the value ordering element is an orderby_list, as
>>follows:
>> *
>> * orderby_list ::= orderby_item [, orderby_item]*
>> * orderby_item ::= property_or_field_name [ASC | DESC]
>> *
>> * When ASC or DESC is not specified, ASC is assumed.
>> *
>> * If the ordering element is not specified, ordering by the primary
>>key
>> * of the associated entity is assumed.
>> *
>> * The property or field name must correspond to that of a persistent
>> * property or field of the associated class. The properties or fields
>> * used in the ordering must correspond to columns for which comparison
>> * operators are supported.
>> */
>> protected void processOrderBy(MetadataAccessor accessor,
>>CollectionMapping mapping) {
>> OrderBy orderBy = AnnotationsHelper.getAnnotation(OrderBy.class,
>>accessor);
>>
>> if (orderBy != null) {
>> processOrderBy(accessor, mapping, orderBy.value());
>> }
>> }
>>
>> /**
>> * INTERNAL:
>> * Process a @PostLoad.
>> *
>> * The PostLoad method for an entity is invoked after the entity has
>>been
>> * loaded into the current persistence context from the database or
>>after
>> * the refresh operation has been applied to it. The PostLoad method is
>> * invoked before a query result is returned or accessed or before an
>> * association is traversed.
>> */
>> protected void processPostLoad(Method method, MetadataEntityListener
>>listener, DescriptorMetadata dmd) {
>> if (AnnotationsHelper.isAnnotationPresent(PostLoad.class, method,
>>dmd)) {
>> listener.setPostCloneMethod(method);
>> listener.setPostRefreshMethod(method);
>> }
>> }
>>
>> /**
>> * INTERNAL:
>> * Process a @PostPersist.
>> *
>> * The PostPersist callback method is invoked for an entity after the
>> * EntityManager persist operations for that entity is executed. The
>> * callback will also be invoked on all entities to which these
>>operations
>> * are cascaded. The PostPersist method will be invoked after the
>>database
>> * insert operation. This may be directly after the persist operation
>>has
>> * been invoked or it may be directly after a flush operation has
>>occurred
>> * or it may be at the end of the transaction. Exceptions thrown by
>>this
>> * callback cause the current transaction to be rolled back.
>> */
>> protected void processPostPersist(Method method,
>>MetadataEntityListener listener, DescriptorMetadata dmd) {
>> if (AnnotationsHelper.isAnnotationPresent(PostPersist.class,
>>method, dmd)) {
>> listener.setPostInsertMethod(method);
>> }
>> }
>>
>> /**
>> * INTERNAL:
>> * Process a @PostRemove.
>> *
>> * The PostRemove callback method is invoked for an entity after the
>> * EntityManager remove operations for that entity is executed. The
>> * callback will also be invoked on all entities to which these
>>operations
>> * are cascaded. The PostRemove method will be invoked after the
>>database
>> * delete operation. This may be directly after the remove operation
>>has
>> * been invoked or it may be directly after a flush operation has
>>occurred
>> * or it may be at the end of the transaction. Exceptions thrown by
>>this
>> * callback cause the current transaction to be rolled back.
>> */
>> protected void processPostRemove(Method method, MetadataEntityListener
>>listener, DescriptorMetadata dmd) {
>> if (AnnotationsHelper.isAnnotationPresent(PostRemove.class, method,
>>dmd)) {
>> listener.setPostDeleteMethod(method);
>> }
>> }
>>
>> /**
>> * INTERNAL:
>> * Process a @PostUpdate.
>> *
>> * The PostUpdate callback occurs after the database update operations
>>to
>> * entity data. This may be at the time the entity state is updated or
>>it
>> * may be at the time state is flushed to the database or at the end of
>>the
>> * transaction.
>> */
>> protected void processPostUpdate(Method method, MetadataEntityListener
>>listener, DescriptorMetadata dmd) {
>> if (AnnotationsHelper.isAnnotationPresent(PostUpdate.class, method,
>>dmd)) {
>> listener.setPostUpdateMethod(method);
>> }
>> }
>>
>> /**
>> * INTERNAL:
>> * Process a @PrePersist.
>> *
>> * The PrePersist callback method is invoked for a given entity before
>>the
>> * EntityManager persist operations for that entity are executed. This
>> * callback will also be invoked on all entities to which these
>>operations
>> * are cascaded. The PrePersist method will always be invoked as part
>>of
>> * the synchronous persist operation. Exceptions thrown by this
>>callback
>> * cause the current transaction to be rolled back.
>> */
>> protected void processPrePersist(Method method, MetadataEntityListener
>>listener, DescriptorMetadata dmd) {
>> if (AnnotationsHelper.isAnnotationPresent(PrePersist.class, method,
>>dmd)) {
>> listener.setPrePersistMethod(method);
>> }
>> }
>>
>> /**
>> * INTERNAL:
>> * Process a @PreRemove.
>> *
>> * The PreRemove callback method is invoked for a given entity before
>>the
>> * EntityManager remove operations for that entity are executed. This
>> * callback will also be invoked on all entities to which these
>>operations
>> * are cascaded. The PreRemove methods will always be invoked as part
>>of
>> * the synchronous persist and remove operations. Exceptions thrown by
>>this
>> * callback cause the current transaction to be rolled back.
>> */
>> protected void processPreRemove(Method method, MetadataEntityListener
>>listener, DescriptorMetadata dmd) {
>> if (AnnotationsHelper.isAnnotationPresent(PreRemove.class, method,
>>dmd)) {
>> listener.setPreRemoveMethod(method);
>> }
>> }
>>
>> /**
>> * INTERNAL:
>> * Process a @PreUpdate.
>> *
>> * The PreUpdate callback occurs before database update operations to
>> * entity data. This may be at the time the entity state is updated or
>>it
>> * may be at the time state is flushed to the database or at the end of
>>the
>> * transaction.
>> */
>> protected void processPreUpdate(Method method, MetadataEntityListener
>>listener, DescriptorMetadata dmd) {
>> if (AnnotationsHelper.isAnnotationPresent(PreUpdate.class, method,
>>dmd)) {
>> listener.setPreUpdateWithChangesMethod(method);
>> }
>> }
>>
>> /**
>> * INTERNAL:
>> */
>> protected Vector<MetadataJoinColumn>
>>processPrimaryKeyJoinColumns(Object[] primaryKeyJoinColumns, String
>>sourceTableName, String targetTableName, MetadataDescriptor dmd) {
>> Vector<MetadataJoinColumn> metadataJoinColumns = new
>>Vector<MetadataJoinColumn>();
>>
>> for (PrimaryKeyJoinColumn primaryKeyJoinColumn :
>>(PrimaryKeyJoinColumn[]) primaryKeyJoinColumns) {
>>
>>metadataJoinColumns.add(processPrimaryKeyJoinColumn(primaryKeyJoinColumn.name(),
>>primaryKeyJoinColumn.referencedColumnName(),
>>primaryKeyJoinColumn.columnDefinition(), sourceTableName, targetTableName,
>>dmd));
>> }
>>
>> return metadataJoinColumns;
>> }
>>
>> /**
>> * INTERNAL:
>> * Process a @PrimaryKeyJoinColumns or @PrimaryKeyJoinColumn based on
>>if
>> * the descriptor metadata uses a composite primary key or not.
>> * Returns a Vector of MetadataJoinColumn.
>> */
>> protected Vector<MetadataJoinColumn>
>>processPrimaryKeyJoinColumns(String sourceTableName, String
>>targetTableName, Object element, MetadataDescriptor md) {
>> Vector<MetadataJoinColumn> allPrimaryKeyJoinColumns = new
>>Vector<MetadataJoinColumn>();
>> AnnotatedElement annotatedElement = (AnnotatedElement) element;
>> DescriptorMetadata dmd = (DescriptorMetadata) md;
>>
>> if (dmd.hasCompositePrimaryKey()) {
>> // Look for a PrimaryKeyJoinColumns.
>> PrimaryKeyJoinColumns primaryKeyJoinColumns =
>>AnnotationsHelper.getAnnotation(PrimaryKeyJoinColumns.class,
>>annotatedElement, dmd);
>>
>> // The number of PrimaryKeyJoinColumns should equal the number
>>of primary key fields.
>> if (primaryKeyJoinColumns == null ||
>>primaryKeyJoinColumns.value().length != dmd.getPrimaryKeyFields().size())
>>{
>> throw
>>ValidationException.incompletePrimaryKeyJoinColumnsSpecified(annotatedElement);
>> }
>>
>> for (PrimaryKeyJoinColumn primaryKeyJoinColumn :
>>primaryKeyJoinColumns.value()) {
>>
>>allPrimaryKeyJoinColumns.add(processPrimaryKeyJoinColumn(primaryKeyJoinColumn.name(),
>>primaryKeyJoinColumn.referencedColumnName(),
>>primaryKeyJoinColumn.columnDefinition(), sourceTableName, targetTableName,
>>dmd));
>> }
>> } else {
>> // Look for a @PrimaryKeyJoinColumn.
>> PrimaryKeyJoinColumn primaryKeyJoinColumn =
>>AnnotationsHelper.getAnnotation(PrimaryKeyJoinColumn.class,
>>annotatedElement, dmd);
>>
>> if (primaryKeyJoinColumn == null) {
>> if (dmd.hasPrimaryKeyJoinColumns()) {
>> throw
>>ValidationException.excessivePrimaryKeyJoinColumnsSpecified(annotatedElement);
>> }
>>
>> addJoinColumnDefault(allPrimaryKeyJoinColumns, sourceTableName,
>>targetTableName, dmd);
>> } else {
>>
>>allPrimaryKeyJoinColumns.add(processPrimaryKeyJoinColumn(primaryKeyJoinColumn.name(),
>>primaryKeyJoinColumn.referencedColumnName(),
>>primaryKeyJoinColumn.columnDefinition(), sourceTableName, targetTableName,
>>dmd));
>> }
>> }
>>
>> return allPrimaryKeyJoinColumns;
>> }
>>
>> /**
>> * INTERNAL:
>> * Process an array of @QueryHint.
>> */
>> protected HashMap<String, String> processQueryHints(QueryHint[]
>>queryHints) {
>> HashMap<String, String> hm = new HashMap<String, String>();
>>
>> for (QueryHint queryHint : queryHints) {
>> hm.put(queryHint.name(), queryHint.value());
>> }
>>
>> return hm;
>> }
>>
>> /**
>> * INTERNAL:
>> * Process the related entities. That is, mappings and inheritance etc.
>> */
>> protected void processRelatedEntity(DescriptorMetadata dmd) {
>> // Process an inheritance subclass specifics.
>> if (dmd.isInheritanceSubclass()) {
>> processInheritanceSubclass(dmd);
>> }
>>
>> // Process the relationship accessors.
>> for (MetadataAccessor accessor : (Collection<MetadataAccessor>)
>>dmd.getRelationshipAccessors()) {
>> processRelationshipAccessor(accessor);
>> }
>> }
>>
>> /**
>> * INTERNAL:
>> * Process a @SecondaryTable and add it to descriptor. Method assumes
>>that
>> * the class has been processed for a primary table and primary key.
>> * WIP - If the @SecondaryTable does not define the pkJoinColumns(), we
>> * could look for PrimaryKeyJoinColumns on the class itself. This is
>>not
>> * mandatory through.
>> */
>> protected void processSecondaryTable(SecondaryTable secondaryTable,
>>DescriptorMetadata dmd) {
>> if (dmd.ignoreTableAnnotations()) {
>> // XML/Annotation merging. XML wins, ignore annotations.
>>
>>getLogger().logWarningMessage(EJBAnnotationsLogger.IGNORE_SECONDARY_TABLE,
>>dmd, secondaryTable.name());
>> } else {
>> processSecondaryTable(
>> secondaryTable.name(),
>> secondaryTable.catalog(),
>> secondaryTable.schema(),
>> secondaryTable.uniqueConstraints(),
>> secondaryTable.pkJoinColumns(),
>> dmd);
>> }
>> }
>>
>> /**
>> * INTERNAL:
>> * Process a @SecondaryTables. If one isn't found, try a
>>@SecondaryTable.
>> */
>> protected void processSecondaryTables(DescriptorMetadata dmd) {
>> // Look for a SecondaryTables annotation.
>> SecondaryTables secondaryTables =
>>AnnotationsHelper.getAnnotation(SecondaryTables.class, dmd);
>> if (secondaryTables != null) {
>> for (SecondaryTable secondaryTable : secondaryTables.value()) {
>> processSecondaryTable(secondaryTable, dmd);
>> }
>> } else {
>> // Look for a SecondaryTable annotation
>> SecondaryTable secondaryTable =
>>AnnotationsHelper.getAnnotation(SecondaryTable.class, dmd);
>> if (secondaryTable != null) {
>> processSecondaryTable(secondaryTable, dmd);
>> }
>> }
>> }
>>
>> /**
>> * INTERNAL:
>> * Process a @SqlResultSetMapping. SqlResultSetMappings are stored on
>>the
>> * session.
>> */
>> protected void processSqlResultSetMapping(SqlResultSetMapping
>>sqlResultSetMapping) {
>> // SqlResultSetMapping.name(), initialize a new
>>SqlResultSetMapping.
>> oracle.toplink.essentials.queryframework.SQLResultSetMapping
>>mapping = new
>>oracle.toplink.essentials.queryframework.SQLResultSetMapping(sqlResultSetMapping.name());
>>
>> // SqlResultSetMapping.entities()
>> for (EntityResult entityResult : sqlResultSetMapping.entities()) {
>> // EntityResult.entityClass()
>> Class entityClass = entityResult.entityClass();
>> oracle.toplink.essentials.queryframework.EntityResult eResult =
>>new
>>oracle.toplink.essentials.queryframework.EntityResult(entityClass.getName());
>>
>> // EntityResult.fields()
>> for (FieldResult fieldResult : entityResult.fields()) {
>> // Use the FieldResult.name() and FieldResult.column()
>>values to
>> // create a new FieldResult and add it to the EntityResult.
>> eResult.addFieldResult(new
>>oracle.toplink.essentials.queryframework.FieldResult(fieldResult.name(),
>>fieldResult.column()));
>> }
>>
>> // EntityResult.discriminatorColumn()
>>
>>eResult.setDiscriminatorColumn(entityResult.discriminatorColumn());
>>
>> // Add the result to the SqlResultSetMapping.
>> mapping.addResult(eResult);
>> }
>>
>> // SqlResultSetMapping.columns()
>> for (ColumnResult columnResult : sqlResultSetMapping.columns()) {
>> // Use the ColumnResult.name() value to create a new
>>ColumnResult
>> // and add it to the SqlResultSetMapping.
>> mapping.addResult(new
>>oracle.toplink.essentials.queryframework.ColumnResult(columnResult.name()));
>> }
>>
>> m_session.getProject().addSQLResultSetMapping(mapping);
>> }
>>
>> /**
>> * INTERNAL:
>> * Process a @SqlResultSetMappings.
>> */
>> protected void processSqlResultSetMappings(DescriptorMetadata dmd) {
>> // Look for a SqlResultSetMappings annotation.
>> SqlResultSetMappings sqlResultSetMappings =
>>AnnotationsHelper.getAnnotation(SqlResultSetMappings.class, dmd);
>> if (sqlResultSetMappings != null) {
>> for (SqlResultSetMapping sqlResultSetMapping :
>>sqlResultSetMappings.value()) {
>> processSqlResultSetMapping(sqlResultSetMapping);
>> }
>> } else {
>> // Look for a SqlResultSetMapping annotation.
>> SqlResultSetMapping sqlResultSetMapping =
>>AnnotationsHelper.getAnnotation(SqlResultSetMapping.class, dmd);
>>
>> if (sqlResultSetMapping != null) {
>> processSqlResultSetMapping(sqlResultSetMapping);
>> }
>> }
>> }
>>
>> /**
>> * INTERNAL:
>>* Process a @Table.
>>*/
>>protected void processTable(MetadataDescriptor md) {
>>// check to see if the XML processor used a default primary table
>>// and update any existing database fields accordingly
>>if (md.isDefaultPrimaryTableSet()) {
>>adjustTableOnExistingFields(md);
>>} else {
>> if (md.ignoreTableAnnotations()) {
>> // XML/Annotation merging. XML wins, ignore annotations.
>>
>>getLogger().logWarningMessage(EJBAnnotationsLogger.IGNORE_TABLE, md);
>> } else {
>> Table table = AnnotationsHelper.getAnnotation(Table.class,
>>md);
>> if (table != null) {
>> // Process the table and add set it as primary.
>> processTable(table.name(), table.catalog(),
>>table.schema(), table.uniqueConstraints(), md);
>> } else {
>> processDefaultTable(md);
>> }
>> }
>> }
>> }
>>
>> /**
>> * INTERNAL:
>> * Process a @Temporal. The method may still be called if no @Temporal
>> * has been specified but the accessor's reference class is a valid
>> * temporal type.
>> */
>> protected void processTemporal(MetadataAccessor accessor,
>>DirectToFieldMapping mapping) {
>> Temporal temporal = AnnotationsHelper.getAnnotation(Temporal.class,
>>accessor);
>>
>> if (temporal == null) {
>> throw
>>ValidationException.noTemporalTypeSpecified(accessor.getAttributeName(),
>>accessor.getJavaClass());
>> } else {
>> processTemporal(accessor, temporal.value().name(), mapping);
>> }
>> }
>>
>> /**
>> * INTERNAL:
>> * Process a @UniqueConstraint(s) for the given table.
>> */
>> protected void processUniqueConstraints(Object[] constraints,
>>DatabaseTable table) {
>> for (UniqueConstraint uniqueConstraint : (UniqueConstraint[])
>>constraints) {
>> // UniqueConstraint.columnNames()
>> String[] columnNames = uniqueConstraint.columnNames();
>>
>> for (String columnName : columnNames) {
>> table.addUniqueConstraint(new DatabaseField(columnName));
>> }
>> }
>> }
>>
>> /**
>> * INTERNAL:
>> * Set the classes for processing.
>> */
>> public void setClasses(Collection<Class> classes) {
>> m_classes = classes;
>> }
>>}
>>