/* * 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.ejb.cmp3.metadata; import java.util.Map; import java.util.List; import java.util.Vector; import java.util.HashMap; import java.util.Iterator; import java.util.ArrayList; import java.util.Collection; import oracle.toplink.essentials.mappings.DatabaseMapping; import oracle.toplink.essentials.exceptions.ValidationException; import oracle.toplink.essentials.descriptors.ClassDescriptor; import oracle.toplink.essentials.descriptors.VersionLockingPolicy; import oracle.toplink.essentials.descriptors.RelationalDescriptor; import oracle.toplink.essentials.internal.helper.DatabaseField; import oracle.toplink.essentials.internal.helper.DatabaseTable; import oracle.toplink.essentials.internal.ejb.cmp3.base.CMP3Policy; /** * Common metatata descriptor for the annotation and xml processors. * * @author Guy Pelletier, Dave McCann * @since TopLink EJB 3.0 Reference Implementation */ public abstract class MetadataDescriptor { protected ClassDescriptor m_descriptor; protected Class m_javaClass; protected Class m_inheritanceRootClass; protected MetadataDescriptor m_inheritanceRootDmd; protected boolean m_isInheritanceRoot; protected boolean m_ignoreIDAnnotations; protected boolean m_ignoreTableAnnotations; protected boolean m_ignoreInheritanceAnnotations; protected boolean m_usesSingleTableInheritanceStrategy; protected String m_primaryTableName; protected String m_embeddedIdAttributeName; protected Map m_accessors; protected Map m_pkClassIDs; protected Map m_setMethodNames; protected Map m_attributeOverrides; protected Map m_associationOverrides; protected Map m_manyToManyAccessors; protected Map m_relationshipAccessors; protected List m_idAttributeNames; protected List m_idOrderByAttributeNames; protected List m_mappedSuperclasses; protected List m_aggregateDmds; protected List m_orderByAttributeNames; /********************* Values set during XML processing *********************/ // Used to determine if access type was specified for this entity/descriptor. protected Boolean m_isXmlPropertyAccess; // Used to determine if cascade-persist was specified for this entity/descriptor. protected Boolean m_isCascadePersistSet; // By default we don't exclude default listeners unless explicitly set. protected boolean m_xmlExcludeDefaultListeners; // By default we don't exclude superclass listeners unless explicitely set. protected boolean m_xmlExcludeSuperclassListeners; // True is meta-data complete is specified. Ignore annotations except for defaults. protected boolean m_ignoreAnnotations; // Only to be used if the entity is defined in XML and not annotated. protected String m_xmlCatalog; // Only to be used if the entity is defined in XML and not annotated. protected String m_xmlSchema; // List of default listeners to apply to this entity/descriptor protected List m_defaultListeners; // Indicates no id element was defined in XML, so the default (TOPLINKDEFAULTID) was used. protected boolean m_isDefaultPrimaryKeySet; // Indicates no table element was defined in XML, so the default was used. protected boolean m_isDefaultPrimaryTableSet; // List of fields which have the default table name set. protected List m_fieldsWithDefaultPrimaryKeySet; // List of fields with name in the format, entity/attribute name + "_" + TOPLINKDEFAULTID protected List m_fieldsWithComplexDefaultPrimaryKeySet; // List of fields with name = TOPLINKDEFAULTID protected List m_fieldsWithDefaultPrimaryTableSet; /** * INTERNAL: */ public MetadataDescriptor(Class javaClass) { init(); m_descriptor = new RelationalDescriptor(); m_descriptor.setExistenceChecking("Check database"); // In case of alias==null, TopLink populates it with short class name // in desc.getAlias(), which causes descriptor being added with this // alias to the project (addDescriptor method) before we have a chance // to set the desired alias. Setting "" stops default alias generation. // WIP - fix this code. m_descriptor.setAlias(""); setJavaClass(javaClass); } /** * INTERNAL: * Constructor used for wrapping an existing descriptor which was presumably * loaded from the project xml. */ public MetadataDescriptor(ClassDescriptor descriptor, Class javaClass) { init(); m_descriptor = descriptor; setJavaClass(javaClass); } /** * INTERNAL: * Copy constructor. Used for creation of annotations meta data out of xml * meta data. All the attributes should be processed. */ public MetadataDescriptor(MetadataDescriptor md) { m_descriptor = md.m_descriptor; m_javaClass = md.m_javaClass; m_inheritanceRootClass = null; m_inheritanceRootDmd = null; m_isInheritanceRoot = md.m_isInheritanceRoot; m_ignoreIDAnnotations = md.m_ignoreIDAnnotations; m_ignoreTableAnnotations = md.m_ignoreIDAnnotations; m_ignoreInheritanceAnnotations = md.m_ignoreInheritanceAnnotations; m_usesSingleTableInheritanceStrategy = md.m_usesSingleTableInheritanceStrategy; m_primaryTableName = md.m_primaryTableName; m_embeddedIdAttributeName = md.m_embeddedIdAttributeName; m_pkClassIDs = md.m_pkClassIDs; m_setMethodNames = md.m_setMethodNames; m_attributeOverrides = md.m_attributeOverrides; m_associationOverrides = md.m_associationOverrides; m_accessors = md.m_accessors; m_manyToManyAccessors = md.m_manyToManyAccessors; m_relationshipAccessors = md.m_relationshipAccessors; m_idAttributeNames = md.m_idAttributeNames; m_idOrderByAttributeNames = md.m_idOrderByAttributeNames; m_mappedSuperclasses = md.m_mappedSuperclasses; m_aggregateDmds = md.m_aggregateDmds; m_orderByAttributeNames = md.m_orderByAttributeNames; m_isCascadePersistSet = md.m_isCascadePersistSet; m_xmlExcludeDefaultListeners = md.m_xmlExcludeDefaultListeners; m_xmlExcludeSuperclassListeners = md.m_xmlExcludeSuperclassListeners; m_ignoreAnnotations = md.m_ignoreAnnotations; m_defaultListeners = md.m_defaultListeners; m_xmlCatalog = md.m_xmlCatalog; m_xmlSchema = md.m_xmlSchema; m_isDefaultPrimaryKeySet = md.m_isDefaultPrimaryKeySet; m_isDefaultPrimaryTableSet = md.m_isDefaultPrimaryTableSet; m_fieldsWithDefaultPrimaryKeySet = md.m_fieldsWithDefaultPrimaryKeySet; m_fieldsWithComplexDefaultPrimaryKeySet = md.m_fieldsWithComplexDefaultPrimaryKeySet; m_fieldsWithDefaultPrimaryTableSet = md.m_fieldsWithDefaultPrimaryTableSet; } /** * INTERNAL: */ public void addAccessor(MetadataAccessor accessor) { m_accessors.put(accessor.getAttributeName(), accessor); if (accessor.isRelationship()) { m_relationshipAccessors.put(accessor.getAttributeName(), accessor); } // Store ManyToMany relationships so that we may look at attribute // names when defaulting join columns for bi and uni directional M-M's. if (accessor.isManyToMany()) { m_manyToManyAccessors.put(accessor.getReferenceClass(), accessor); } } /** * INTERNAL: */ public void addAggregateDmd(MetadataDescriptor aggregateDmd) { m_aggregateDmds.add(aggregateDmd); } /** * INTERNAL: */ public void addAssociationOverride(String attributeName, Object[] joinColumns) { m_associationOverrides.put(attributeName, joinColumns); } /** * INTERNAL: */ public void addAttributeOverride(String attributeName, DatabaseField field) { m_attributeOverrides.put(attributeName, field); } /** * INTERNAL: */ public void addClassIndicator(Class entityClass, String value) { if (isInheritanceSubclass()) { getInheritanceRootDmd().addClassIndicator(entityClass, value); } else { m_descriptor.getInheritancePolicy().addClassNameIndicator(entityClass.getName(), value); } } /** * INTERNAL: */ public void addDefaultEventListener(MetadataEntityListener listener) { m_descriptor.getEventManager().addDefaultEventListener(listener); } /** * INTERNAL: */ public void addEntityEventListener(MetadataEntityListener listener) { m_descriptor.getEventManager().setEntityEventListener(listener); } /** * INTERNAL: */ public void addEntityListenerEventListener(MetadataEntityListener listener) { m_descriptor.getEventManager().addEntityListenerEventListener(listener); } /** * INTERNAL: */ public void addIdAttributeName(String idAttributeName) { m_idAttributeNames.add(idAttributeName); } /** * INTERNAL: */ public void addListener(MetadataEntityListener listener) { m_descriptor.getEventManager().addListener(listener); } /** * INTERNAL: */ public void addMapping(DatabaseMapping mapping) { m_descriptor.addMapping(mapping); } /** * INTERNAL: */ public void addMultipleTableForeignKeyField(DatabaseField pkField, DatabaseField fkField) { m_descriptor.addMultipleTableForeignKeyField(pkField, fkField); } /** * INTERNAL: */ public void addMultipleTablePrimaryKeyField(DatabaseField pkField, DatabaseField fkField) { m_descriptor.addMultipleTablePrimaryKeyField(pkField, fkField); } /** * INTERNAL: * We store these to validate the primary class when processing * the entity class. */ public void addPKClassId(String attributeName, Class type) { m_pkClassIDs.put(attributeName, type); } /** * INTERNAL: */ public void addPrimaryKeyField(DatabaseField field) { m_descriptor.addPrimaryKeyField(field); } /** * INTERNAL: */ public void addSetMethodName(String getMethodName, String setMethodName) { m_setMethodNames.put(getMethodName, setMethodName); } /** * INTERNAL: */ public void addTable(DatabaseTable table) { m_descriptor.addTable(table); } /** * INTERNAL: */ public boolean excludeSuperclassListeners() { return m_descriptor.getEventManager().excludeSuperclassListeners(); } /** * INTERNAL: */ public MetadataAccessor getAccessorFor(String fieldOrPropertyName) { MetadataAccessor accessor = (MetadataAccessor) m_accessors.get(fieldOrPropertyName); if (accessor == null) { return (MetadataAccessor) m_accessors.get(MetadataHelper.getAttributeNameFromMethodName(fieldOrPropertyName)); } return accessor; } /** * INTERNAL: */ public String getAlias() { return m_descriptor.getAlias(); } /** * INTERNAL: */ public Object[] getAssociationOverrideFor(MetadataAccessor accessor) { return (Object[]) m_associationOverrides.get(accessor.getAttributeName()); } /** * INTERNAL: */ public DatabaseField getAttributeOverrideFor(MetadataAccessor accessor) { return getAttributeOverrideFor(accessor.getAttributeName()); } /** * INTERNAL: */ public DatabaseField getAttributeOverrideFor(String attributeName) { return (DatabaseField) m_attributeOverrides.get(attributeName); } /** * INTERNAL: */ public DatabaseField getClassIndicatorField() { if (getInheritanceRootDmd() != null) { return getInheritanceRootDmd().getDescriptor().getInheritancePolicy().getClassIndicatorField(); } else { if (getDescriptor().hasInheritance()) { return getDescriptor().getInheritancePolicy().getClassIndicatorField(); } else { return null; } } } /** * INTERNAL: * A list of default listeners to be applied to this entity if * shouldExcludeDefaultListeners() is false. The listeners are of type * MetadataDefaultListener. The initializeCallbackMethods(ClassLoader) * method must be called on each listener before adding them to the event * manager. */ public List getDefaultListeners() { if (m_defaultListeners == null) { m_defaultListeners = new ArrayList(); } return m_defaultListeners; } /** * INTERNAL: * The default table name is the descriptor alias, unless this descriptor * metadata is an inheritance subclass with a SINGLE_TABLE strategy. Then * it is the table name of the root descriptor metadata. */ public String getDefaultTableName() { String defaultTableName = getAlias().toUpperCase(); if (isInheritanceSubclass()) { if (m_inheritanceRootDmd.usesSingleTableInheritanceStrategy()) { defaultTableName = m_inheritanceRootDmd.getPrimaryTableName(); } } return defaultTableName; } /** * INTERNAL: */ public ClassDescriptor getDescriptor() { return m_descriptor; } /** * INTERNAL: * The value for m_catalog will be one of: * - persistence unit default * - entity-mappings default * - empty string */ public String getCatalog() { return m_xmlCatalog; } /** * INTERNAL: */ public String getEmbeddedIdAttributeName() { return m_embeddedIdAttributeName; } /** * INTERNAL: */ public List getFieldsWithComplexDefaultPrimaryKeySet() { if (m_fieldsWithComplexDefaultPrimaryKeySet == null) { m_fieldsWithComplexDefaultPrimaryKeySet = new ArrayList(); } return m_fieldsWithComplexDefaultPrimaryKeySet; } /** * INTERNAL: */ public List getFieldsWithDefaultPrimaryKeySet() { if (m_fieldsWithDefaultPrimaryKeySet == null) { m_fieldsWithDefaultPrimaryKeySet = new ArrayList(); } return m_fieldsWithDefaultPrimaryKeySet; } /** * INTERNAL: */ public List getFieldsWithDefaultPrimaryTableSet() { if (m_fieldsWithDefaultPrimaryTableSet == null) { m_fieldsWithDefaultPrimaryTableSet = new ArrayList(); } return m_fieldsWithDefaultPrimaryTableSet; } /** * INTERNAL: * Return the primary key attribute name for this entity. */ public String getIdAttributeName() { if (getIdAttributeNames().isEmpty()) { if (isInheritanceSubclass()) { return getInheritanceRootDmd().getIdAttributeName(); } else { return ""; } } else { return (String) getIdAttributeNames().get(0); } } /** * INTERNAL: * Return the id attribute names declared on this descriptor metadata. */ public List getIdAttributeNames() { return m_idAttributeNames; } /** * INTERNAL: * Return the primary key attribute names for this entity. If there are no * id attribute names set then we are either: * 1) an inheritance subclass, get the id attribute names from the root * of the inheritance structure. * 2) we have an embedded id. Get the id attribute names from the embedded * descriptor metadata, which is equal the attribute names of all the * direct to field mappings on that descriptor metadata. Currently does * not traverse nested embeddables. */ public List getIdOrderByAttributeNames() { if (m_idOrderByAttributeNames.isEmpty()) { if (m_idAttributeNames.isEmpty()) { if (isInheritanceSubclass()) { // Get the id attribute names from our root parent. m_idOrderByAttributeNames = m_inheritanceRootDmd.getIdAttributeNames(); } else { // We must have a composite primary key as a result of an embedded id. m_idOrderByAttributeNames = getAccessorFor(getEmbeddedIdAttributeName()).getReferenceMetadataDescriptor().getOrderByAttributeNames(); } } else { m_idOrderByAttributeNames = m_idAttributeNames; } } return m_idOrderByAttributeNames; } /** * INTERNAL: */ public MetadataAccessor getManyToManyAccessor(Class cls) { return (MetadataAccessor) m_manyToManyAccessors.get(cls); } /** * INTERNAL: * This will return the attribute names for all the direct to field mappings * on this descriptor metadata. This method will typically be called when an * @Embedded or @EmbeddedId attribute has been specified in an @OrderBy. */ public List getOrderByAttributeNames() { if (m_orderByAttributeNames.isEmpty()) { for (Iterator mapIt = getMappings().iterator(); mapIt.hasNext(); ) { DatabaseMapping mapping = (DatabaseMapping) mapIt.next(); if (mapping.isDirectToFieldMapping()) { m_orderByAttributeNames.add(mapping.getAttributeName()); } } } return m_orderByAttributeNames; } /** * INTERNAL: * This method assumes that isInheritanceSubclass(HashMap) has already been * called to determine the inheritance root class. It returns the root * parent class in an inheritance hierarchy, null otherwise. */ public Class getInheritanceRootClass() { return m_inheritanceRootClass; } /** * INTERNAL: * Store the descriptor metadata for the root of our inheritance hierarchy. */ public MetadataDescriptor getInheritanceRootDmd() { return m_inheritanceRootDmd; } /** * INTERNAL: */ public Class getJavaClass() { return m_javaClass; } /** * INTERNAL: */ public DatabaseMapping getMappingForAttributeName(String attributeName) { MetadataAccessor accessor = (MetadataAccessor) getAccessorFor(attributeName); if (accessor != null) { // If the accessor is a relationship accessor than it may or may // not have been processed yet. Fast track its processing if it // needs to be. The process call will do nothing if it has already // been processed. if (accessor.isRelationship()) { accessor.process(); } return m_descriptor.getMappingForAttributeName(attributeName); } // We didn't find a mapping on this descriptor, check our aggregate // descriptors now. for (Iterator mapIt = m_aggregateDmds.iterator(); mapIt.hasNext(); ) { MetadataDescriptor aggregateDmd = (MetadataDescriptor) mapIt.next(); DatabaseMapping mapping = aggregateDmd.getMappingForAttributeName(attributeName); if (mapping != null) { return mapping; } } // We didn't find a mapping on the aggregate descriptors. If we are an // inheritance subclass, check for a mapping on the inheritance root // descriptor metadata. if (isInheritanceSubclass()) { return getInheritanceRootDmd().getMappingForAttributeName(attributeName); } // Found nothing ... return null. return null; } /** * INTERNAL: */ public List getMappings() { return m_descriptor.getMappings(); } /** * INTERNAL: */ public String getPKClassName() { String pkClassName = null; if (m_descriptor.hasCMPPolicy()) { pkClassName = ((CMP3Policy) m_descriptor.getCMPPolicy()).getPKClassName(); } return pkClassName; } /** * INTERNAL: * Method to return the primary key field for the given descriptor * metadata. Assumes there is one and only one. */ public String getPrimaryKeyFieldName() { // This must be here for an override feature otherwise it shouldn't be // necessary. WIP - investigate. if (getPrimaryKeyFields() == null || !(getPrimaryKeyFields().iterator().hasNext())) { return ""; } return ((DatabaseField)(getPrimaryKeyFields().iterator().next())).getName(); } /** * INTERNAL: * Return the primary key fields for this descriptor metadata. If this is * an inheritance subclass and it has no primary key fields, then grab the * primary key fields from the root. */ public List getPrimaryKeyFields() { List primaryKeyFields = m_descriptor.getPrimaryKeyFields(); if (primaryKeyFields.isEmpty() && isInheritanceSubclass()) { primaryKeyFields = getInheritanceRootDmd().getPrimaryKeyFields(); } return primaryKeyFields; } /** * INTERNAL: */ public String getPrimaryTableName() { // Assumes tables have been specified via XML and that the first // table is the primary table. Vector tables = m_descriptor.getTables(); if (m_primaryTableName == null && !tables.isEmpty()) { m_primaryTableName = ((DatabaseTable) tables.firstElement()).getQualifiedName(); } else if (m_primaryTableName == null && tables.isEmpty()) { m_primaryTableName = ""; } return m_primaryTableName; } /** * INTERNAL: */ public Collection getRelationshipAccessors() { return m_relationshipAccessors.values(); } /** * INTERNAL: * The value for m_schema will be one of: * - persistence unit default * - entity-mappings default * - empty string */ public String getSchema() { return m_xmlSchema; } /** * INTERNAL: */ public String getSetMethodName(String getMethodName) { return (String) m_setMethodNames.get(getMethodName); } /** * INTERNAL: */ public abstract void handlePotentialDefaultTableUsage(DatabaseField dbField); /** * INTERNAL: */ public boolean hasAssociationOverrideFor(MetadataAccessor accessor) { return m_associationOverrides.containsKey(accessor.getAttributeName()); } /** * INTERNAL: */ public boolean hasAttributeOverrideFor(MetadataAccessor accessor) { return hasAttributeOverrideFor(accessor.getAttributeName()); } /** * INTERNAL: */ public boolean hasAttributeOverrideFor(String attributeName) { return m_attributeOverrides.containsKey(attributeName); } /** * INTERNAL: */ public boolean hasCompositePrimaryKey() { return getPrimaryKeyFields().size() > 1 || getPKClassName() != null; } /** * INTERNAL: */ public boolean hasEmbeddedIdAttribute() { return m_embeddedIdAttributeName != null; } /** * INTERNAL: */ public boolean hasEntityEventListener() { return m_descriptor.getEventManager().hasEntityEventListener(); } /** * INTERNAL: */ public boolean hasEntityListenerEventListeners() { return m_descriptor.getEventManager().hasEntityListenerEventListeners(); } /** * INTERNAL: */ protected abstract boolean hasEntityTag(Class cls); /** * INTERNAL: */ protected abstract boolean hasInheritanceTag(Class entityClass); /** * INTERNAL: */ public boolean hasManyToManyAccessorFor(Class cls) { return m_manyToManyAccessors.containsKey(cls); } /** * INTERNAL: */ protected abstract boolean hasMappedSuperclassTag(Class cls); /** * INTERNAL: */ public boolean hasMappingForAccessor(MetadataAccessor accessor) { return hasMappingForAttributeName(accessor.getAttributeName()); } /** * INTERNAL: */ public boolean hasMappingForAttributeName(String attributeName) { return m_descriptor.getMappingForAttributeName(attributeName) != null; } /** * INTERNAL: * Returns a list of mapped superclasses for this metadata descriptor. */ public List getMappedSuperclasses() { if (m_mappedSuperclasses == null) { m_mappedSuperclasses = new ArrayList(); Class parent = m_javaClass.getSuperclass(); while (parent != Object.class) { if (hasMappedSuperclassTag(parent)) { m_mappedSuperclasses.add(parent); } parent = parent.getSuperclass(); } } return (ArrayList) m_mappedSuperclasses; } /** * INTERNAL: * Return true is the descriptor has primary key fields set. */ public boolean hasPrimaryKeyFields() { return m_descriptor.getPrimaryKeyFields().size() > 0; } /** * INTERNAL: */ public abstract boolean hasPrimaryKeyJoinColumns(); /** * INTERNAL: */ public boolean ignoreIDAnnotations() { return m_ignoreIDAnnotations; } /** * INTERNAL: */ public boolean ignoreInheritanceAnnotations() { return m_ignoreInheritanceAnnotations; } /** * INTERNAL: */ public boolean ignoreTableAnnotations() { return m_ignoreTableAnnotations; } /** * INTERNAL: */ private void init() { m_isInheritanceRoot = false; m_ignoreIDAnnotations = false; m_ignoreTableAnnotations = false; m_ignoreInheritanceAnnotations = false; m_pkClassIDs = new HashMap(); m_accessors = new HashMap(); m_setMethodNames = new HashMap(); m_idAttributeNames = new ArrayList(); m_orderByAttributeNames = new ArrayList(); m_idOrderByAttributeNames = new ArrayList(); m_aggregateDmds = new ArrayList(); m_attributeOverrides = new HashMap(); m_associationOverrides = new HashMap(); m_manyToManyAccessors = new HashMap(); m_relationshipAccessors = new HashMap(); // initialize values set during XML processing m_isXmlPropertyAccess = null; m_isCascadePersistSet = null; m_xmlExcludeDefaultListeners = false; m_xmlExcludeSuperclassListeners = false; m_ignoreAnnotations = false; m_xmlCatalog = ""; m_xmlSchema = ""; m_isDefaultPrimaryKeySet = false; m_isDefaultPrimaryTableSet = false; } /** * INTERNAL: * If "set", indicates that cascade-persist should be applied to all * relationship mappings for this entity. */ public boolean isAggregate() { return m_descriptor.isAggregateDescriptor(); } /** * INTERNAL: * If "set", indicates that cascade-persist should be applied to all * relationship mappings for this entity. */ public Boolean isCascadePersistSet() { return m_isCascadePersistSet != null; } /** * INTERNAL: */ public boolean isDefaultPrimaryKeySet() { return m_isDefaultPrimaryKeySet; } /** * INTERNAL: */ public boolean isDefaultPrimaryTableSet() { return m_isDefaultPrimaryTableSet; } /** * INTERNAL: * If "set", indicates that default listeners in the m_defaultListenerList * list NOT should be applied to the entity. */ public boolean isXmlExcludeDefaultListenersSet() { return m_xmlExcludeDefaultListeners; } /** * INTERNAL: * If "set", indicates that superclass listeners should NOT be applied to * the entity. */ public boolean isXmlExcludeSuperclassListenersSet() { return m_xmlExcludeSuperclassListeners; } /** * INTERNAL: * Indicates that we found an XML field access type for this metadata * descriptor. */ public boolean isXmlFieldAccess() { return (m_isXmlPropertyAccess != null && m_isXmlPropertyAccess.booleanValue() == false); } /** * INTERNAL: * Indicates that we found an XML property access type for this metadata * descriptor. */ public boolean isXmlPropertyAccess() { return (m_isXmlPropertyAccess != null && m_isXmlPropertyAccess.booleanValue() == true); } /** * INTERNAL: * Return true is this descriptor metadata is an inheritance root. */ public boolean isInheritanceRoot() { return m_isInheritanceRoot; } /** * INTERNAL: * Method to determine if the given class is an inheritance subclass. */ public boolean isInheritanceSubclass() { return (getInheritanceRootClass() != null); } /** * INTERNAL: * Calls to this method should only be made once to determine if this * descriptor metadata is part of an inhertiance hierarchy. Any consecutive * inquiries should be made through the isInheritanceSubclass() call. */ protected boolean isInheritanceSubclass(HashMap m_metadataDescriptors) { Class lastParent = null; Class parent = m_javaClass.getSuperclass(); while (parent != Object.class) { if (hasInheritanceTag(parent) || m_metadataDescriptors.containsKey(parent) || hasEntityTag(parent)) { lastParent = parent; } parent = parent.getSuperclass(); } // Finally set whatever we found as the inheritance root class. Which // may be null. m_inheritanceRootClass = lastParent; return isInheritanceSubclass(); } /** * INTERNAL: */ public boolean pkClassWasNotValidated() { return ! m_pkClassIDs.isEmpty(); } /** * INTERNAL: */ public void setAlias(String alias) { m_descriptor.setAlias(alias); } /** * INTERNAL: */ public void setCatalog(String xmlCatalog) { m_xmlCatalog = xmlCatalog; } /** * INTERNAL: */ public void setClassIndicatorField(DatabaseField field) { m_descriptor.getInheritancePolicy().setClassIndicatorField(field); } /** * INTERNAL: */ public void setDefaultListeners(List defaultListeners) { m_defaultListeners = defaultListeners; } /** * INTERNAL: */ public void setDefaultPrimaryKey() { m_isDefaultPrimaryKeySet = true; } /** * INTERNAL: */ public void setDefaultPrimaryTable() { m_isDefaultPrimaryTableSet = true; } /** * INTERNAL: */ public void setDescriptor(RelationalDescriptor descriptor) { m_descriptor = descriptor; } /** * INTERNAL: */ public void setDescriptorIsEmbeddable() { m_descriptor.descriptorIsAggregate(); } /** * INTERNAL: */ public void setEmbeddedIdAttributeName(String embeddedIdAttributeName) { m_embeddedIdAttributeName = embeddedIdAttributeName; } /** * INTERNAL: */ public void setExcludeDefaultListeners(boolean excludeDefaultListeners) { m_descriptor.getEventManager().setExcludeDefaultListeners(excludeDefaultListeners); } /** * INTERNAL: */ public void setExcludeSuperclassListeners(boolean excludeSuperclassListeners) { m_descriptor.getEventManager().setExcludeSuperclassListeners(excludeSuperclassListeners); } /** * INTERNAL: */ public void setIgnoreFlags() { m_ignoreInheritanceAnnotations = m_descriptor.hasInheritance(); m_ignoreTableAnnotations = m_descriptor.getTableNames().size() > 0; m_ignoreIDAnnotations = m_descriptor.getPrimaryKeyFieldNames().size() > 0 && !isDefaultPrimaryKeySet(); } /** * INTERNAL: * Store the descriptor metadata for the root of our inheritance hierarchy. */ public void setInheritanceRootDmd(MetadataDescriptor inheritanceRootDmd) { m_inheritanceRootDmd = inheritanceRootDmd; } /** * INTERNAL: * Store the java class for the root of our inheritance hierarchy. */ public void setInheritanceRootClass(Class rootClass) { m_inheritanceRootClass = rootClass; } /** * INTERNAL: * Stored on the root class of an inheritance hierarchy. */ public void setInheritanceStrategy(String inheritanceStrategy) { if (inheritanceStrategy.equals(MetadataConstants.TABLE_PER_CLASS)) { throw ValidationException.tablePerClassInheritanceNotSupported(m_javaClass); } m_usesSingleTableInheritanceStrategy = (inheritanceStrategy.equals(MetadataConstants.SINGLE_TABLE)); } /** * INTERNAL: * Set this descriptor metadata as an inheritance root. Because the * inheritance root class may or may not have an @Inheritance annotation * defined then we need to ensure that descriptor metadata knows it is. */ public void setIsInheritanceRoot(boolean isInheritanceRoot) { m_isInheritanceRoot = isInheritanceRoot; } /** * INTERNAL: * Indicates that we found an XML field access type for this metadata * descriptor. */ public void setIsXmlFieldAccess() { m_isXmlPropertyAccess = new Boolean(false); } /** * INTERNAL: * Indicates that we found an XML property access type for this metadata * descriptor. */ public void setIsXmlPropertyAccess() { m_isXmlPropertyAccess = new Boolean(true); } /** * INTERNAL: * Used to set this descriptors java class. */ public void setJavaClass(Class javaClass) { m_javaClass = javaClass; if ((m_javaClass != null) && (m_descriptor != null)){ m_descriptor.setJavaClassName(m_javaClass.getName()); } else if (m_descriptor != null) { m_descriptor.setJavaClassName(null); } } /** * INTERNAL: */ public void setOptimisticLockingPolicy(DatabaseField field) { VersionLockingPolicy vlp = new VersionLockingPolicy(); vlp.setWriteLockField(field); vlp.storeInObject(); m_descriptor.setOptimisticLockingPolicy(vlp); } /** * INTERNAL: * Should only be called from those descriptor metadata's that are in * fact part of an inheritance hierarchy. It figures out the parent and * then sets it. */ public void setParentClass() { Class parent = m_javaClass.getSuperclass(); while (parent != Object.class) { if (hasEntityTag(parent)) { break; } parent = parent.getSuperclass(); } setParentClass(parent); } /** * INTERNAL: * Set the inheritance parent class for this descriptor metadata. */ public void setParentClass(Class parent) { m_descriptor.getInheritancePolicy().setParentClassName(parent.getName()); } /** * INTERNAL: */ public void setPKClass(Class pkClass) { CMP3Policy policy = new CMP3Policy(); policy.setPrimaryKeyClassName(pkClass.getName()); m_descriptor.setCMPPolicy(policy); } /** * INTERNAL: */ public void setPrimaryTable(DatabaseTable primaryTable) { Vector tables = m_descriptor.getTables(); if (tables != null && !tables.isEmpty()) { tables.remove(0); } tables.add(0, primaryTable); m_primaryTableName = primaryTable.getQualifiedName(); } /** * INTERNAL: */ public void setSchema(String xmlSchema) { m_xmlSchema = xmlSchema; } /** * INTERNAL: */ public void setSequenceNumberField(DatabaseField field) { DatabaseField existingField = m_descriptor.getSequenceNumberField(); if (existingField == null) { m_descriptor.setSequenceNumberField(field); } else { if (!existingField.equals(field)) { throw ValidationException.onlyOneGeneratedValueIsAllowed(m_javaClass, existingField.getQualifiedName(), field.getQualifiedName()); } } } /** * INTERNAL: */ public void setSequenceNumberName(String name) { m_descriptor.setSequenceNumberName(name); } /** * INTERNAL: * Indicates that default listeners are NOT to be applied to the entity. */ public void setXmlExcludeDefaultListeners(boolean xmlExcludeDefaultListeners) { m_xmlExcludeDefaultListeners = xmlExcludeDefaultListeners; } /** * INTERNAL: * Indicates that superclass listeners are NOT to be applied to the entity. */ public void setXmlExcludeSuperclassListeners(boolean xmlExcludeSuperclassListeners) { m_xmlExcludeSuperclassListeners = xmlExcludeSuperclassListeners; } /** * INTERNAL: * Indicates that all annotations should be ignored, and only default values * set by the annotations processor. */ public void setShouldIgnoreAnnotations(boolean ignoreAnnotations) { m_ignoreAnnotations = ignoreAnnotations; } /** * INTERNAL: * Indicates that cascade-persist should be added to the set of cascade * values for all relationship mappings. */ public void setShouldUseCascadePersist() { m_isCascadePersistSet = true; } /** * INTERNAL: * Sets the strategy on the descriptor's inheritance policy to SINGLE_TABLE. * The default is JOINED. */ public void setSingleTableInheritanceStrategy() { m_descriptor.getInheritancePolicy().setSingleTableStrategy(); } /** * INTERNAL: * Indicates whether or not annotations should be ignored, i.e. only default * values processed. */ public boolean shouldIgnoreAnnotations() { return m_ignoreAnnotations; } /** * INTERNAL: */ public boolean usesOptimisticLocking() { return m_descriptor.usesOptimisticLocking(); } /** * INTERNAL: * Returns true if this entity uses property access. */ public abstract boolean usesPropertyAccess(); /** * INTERNAL: * Indicates if the strategy on the descriptor's inheritance policy is * SINGLE_TABLE or JOINED. * * @return true if SINGLE_TABLE, false otherwise */ public boolean usesSingleTableInheritanceStrategy() { return m_usesSingleTableInheritanceStrategy; } /** * INTERNAL: * This method is used only to validate id fields that were found on a * pk class were also found on the entity. */ public void validatePKClassId(String attributeName, Class type) { if (m_pkClassIDs.containsKey(attributeName)) { Class value = (Class) m_pkClassIDs.get(attributeName); if (value == type) { m_pkClassIDs.remove(attributeName); } else { throw ValidationException.invalidCompositePKAttribute(m_javaClass, getPKClassName(), attributeName, value, type); } } } }