User: dsundstrom
  Date: 01/07/25 19:39:03

  Modified:    src/main/org/jboss/ejb/plugins/cmp/jdbc/metadata
                        JDBCRelationMetaData.java
                        JDBCRelationshipRoleMetaData.java
  Log:
  Changed to be immutable and added configuration of relation mapping.
  
  Revision  Changes    Path
  1.2       +345 -107  
jboss/src/main/org/jboss/ejb/plugins/cmp/jdbc/metadata/JDBCRelationMetaData.java
  
  Index: JDBCRelationMetaData.java
  ===================================================================
  RCS file: 
/cvsroot/jboss/jboss/src/main/org/jboss/ejb/plugins/cmp/jdbc/metadata/JDBCRelationMetaData.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- JDBCRelationMetaData.java 2001/07/09 21:47:26     1.1
  +++ JDBCRelationMetaData.java 2001/07/26 02:39:03     1.2
  @@ -14,176 +14,349 @@
   import org.w3c.dom.Element;
   
   /**
  - * Represents one ejb-relation element found in the ejb-jar.xml
  + * Imutable class that represents one ejb-relation element found in the ejb-jar.xml
    * file's relationships elements.
    *    
    * @author <a href="mailto:[EMAIL PROTECTED]";>Dain Sundstrom</a>
  - *   @version $Revision: 1.1 $
  + *   @version $Revision: 1.2 $
    */
  -public class JDBCRelationMetaData extends MetaData {
  +public final class JDBCRelationMetaData {
        private final static int TABLE = 1;
        private final static int FOREIGN_KEY = 2;
        
        /** Name of the relation. Loaded from the ejb-relation-name element. */
  -     private String relationName;
  +     private final String relationName;
   
        /** 
         * The left jdbc relationship role. Loaded from an ejb-relationship-role.
         * Left/right assignment is completely arbitrary.
         */
  -     private JDBCRelationshipRoleMetaData left;
  +     private final JDBCRelationshipRoleMetaData left;
   
        /** 
         * The right relationship role. Loaded from an ejb-relationship-role.
         * Left/right assignment is completely arbitrary.
         */
  -     private JDBCRelationshipRoleMetaData right;
  +     private final JDBCRelationshipRoleMetaData right;
        
        /**
         * The mapping style for this relation (i.e., TABLE or FOREIGN_KEY).
         */
  -     private int mappingStyle;
  +     private final int mappingStyle;
        
  -     // the name of the table to use for this bean
  -     private String tableName;
  +     /** data source name in jndi */
  +     private final String dataSourceName;
        
  -     // do we have to try and create the table on deployment?
  -     private boolean createTable;
  +     /** type mapping used for the relation table */
  +     private final JDBCTypeMappingMetaData typeMapping;
        
  -     // do we have to drop the table on undeployment?
  -     private boolean removeTable;
  +     /** should excess debug information be logged */
  +     private final boolean debug;
        
  -     // do we use 'SELECT ... FOR UPDATE' syntax?
  -     private boolean selectForUpdate;
  +     /** the name of the table to use for this bean */
  +     private final String tableName;
        
  -     // is the bean read-only?
  -     private boolean readOnly;
  +     /** should we create the table when deployed */
  +     private final boolean createTable;
        
  -     // how long is read valid
  -     private int readTimeOut = -1;
  +     /** should we drop the table when deployed */
  +     private final boolean removeTable;
        
  -     // should the table have a primary key constraint?
  -     private boolean primaryKeyConstraint;
  +     /** should we use 'SELECT ... FOR UPDATE' syntax? */
  +     private final boolean selectForUpdate;
  +     
  +     /** should the table have a primary key constraint? */
  +     private final boolean primaryKeyConstraint;
  +     
  +     /** is the relationship read-only? */
  +     private final boolean readOnly;
  +     
  +     /** how long is read valid */
  +     private final int readTimeOut;
                
  -     public JDBCRelationMetaData(
  -                     RelationMetaData relationMetaData,
  -                     JDBCApplicationMetaData applicationMetaData) {
  +     /**
  +      * Constructs jdbc relation meta data with the data from the relation meta 
data loaded
  +      * from the ejb-jar.xml file.
  +      *
  +      * @param jdbcApplication used to retrieve the entities of this relation
  +      * @param relationMetaData relation meta data loaded from the ejb-jar.xml file
  +      */
  +     public JDBCRelationMetaData(JDBCApplicationMetaData jdbcApplication, 
RelationMetaData relationMetaData) throws DeploymentException {
                relationName = relationMetaData.getRelationName();
                
                RelationshipRoleMetaData leftRole = 
relationMetaData.getLeftRelationshipRole();
                RelationshipRoleMetaData rightRole = 
relationMetaData.getRightRelationshipRole();
   
  -             left = new JDBCRelationshipRoleMetaData(leftRole, this, 
applicationMetaData);
  -             right = new JDBCRelationshipRoleMetaData(rightRole, this, 
applicationMetaData);
  -             
  -             // give each role a referance to the other
  -             left.setRelatedRole(right);
  -             right.setRelatedRole(left);
  -     
  -             if(left.isMultiplicityMany() && right.isMultiplicityMany()) {
  +             // set the default mapping style
  +             if(leftRole.isMultiplicityMany() && rightRole.isMultiplicityMany()) {
                        mappingStyle = TABLE;
  -                     tableName = left.getEntity().getName() + "_" + 
left.getCMRFieldName() +
  -                                     right.getEntity().getName() + "_" + 
right.getCMRFieldName();
  +             } else {
  +                     mappingStyle = FOREIGN_KEY;
  +             }
  +
  +             dataSourceName = null;
  +             typeMapping = null;
  +             debug = false;
  +             createTable = false;
  +             removeTable = false;
  +             selectForUpdate = false;
  +             primaryKeyConstraint = false;
  +             readOnly = false;
  +             readTimeOut = -1;               
  +
  +             left = new JDBCRelationshipRoleMetaData(
  +                                             this, 
  +                                             jdbcApplication,
  +                                             leftRole);
  +                                             
  +             right = new JDBCRelationshipRoleMetaData(
  +                                             this, 
  +                                             jdbcApplication,                
  +                                             rightRole); 
  +                                             
  +             if(mappingStyle == TABLE) {
  +                     tableName = createDefaultTableName();                   
                } else {
  -                     mappingStyle = FOREIGN_KEY; 
  -             }               
  +                tableName = null;
  +             }
        }
   
  -     public void importXml(Element element) throws DeploymentException {            
 
  -             // mapping style
  -             String mappingStyleString = 
getElementContent(getOptionalChild(element, "mapping-style"));
  -             if(mappingStyleString != null) {
  -                     if(mappingStyleString.equals("table")) {
  +     /**
  +      * Constructs relation meta data with the data contained in the ejb-relation 
element 
  +      * or the defaults element from a jbosscmp-jdbc xml file. Optional values of 
the xml
  +      * element that are not present are loaded from the defalutValues parameter.
  +      *
  +      * @param jdbcApplication used to retrieve type mappings in table mapping style
  +      * @param element the xml Element which contains the metadata about this 
relation
  +      * @param defaultValues the JDBCApplicationMetaData which contains the values
  +      *              for optional elements of the element
  +      * @throws DeploymentException if the xml element is not semantically correct
  +      */
  +     public JDBCRelationMetaData(JDBCApplicationMetaData jdbcApplication, Element 
element, JDBCRelationMetaData defaultValues) throws DeploymentException {
  +             relationName = defaultValues.getRelationName();
  +
  +             // enable extra debugging?
  +             String debugString = MetaData.getOptionalChildContent(element, 
"debug");
  +             if(debugString != null) {
  +                     debug = Boolean.valueOf(debugString).booleanValue();
  +             } else {
  +                     debug = defaultValues.isDebug();
  +             }       
  +             
  +             // get the mapping element; may be the defaults, table-mapping, or 
foreigh-key-mapping
  +             Element mappingElement;
  +             if("defaults".equals(element.getTagName())) {
  +                     mappingElement = element;
  +                     // set mapping style based on perferred-relation-mapping (if 
possible) 
  +                     String perferredRelationMapping = 
MetaData.getOptionalChildContent(element, "preferred-relation-mapping");
  +                     if("table".equals(perferredRelationMapping) || 
defaultValues.isManyToMany()) {
                                mappingStyle = TABLE;
  -                     } else if(mappingStyleString.equals("foreign-key")) {
  +                     } else {
                                mappingStyle = FOREIGN_KEY;
  -                             if(left.isMultiplicityMany() && 
right.isMultiplicityMany()) {
  -                                     throw new DeploymentException("Foreign key 
mapping-style is not allowed for many-to-many relationsips.");
  -                             }
  +                     }
  +             } else {
  +                     // check for table mapping style
  +                     mappingElement = MetaData.getOptionalChild(element, 
"table-mapping");
  +                     if(mappingElement != null) {
  +                             mappingStyle = TABLE;
                        } else {
  -                             throw new DeploymentException("Unknown mapping-style: 
" + mappingStyleString);
  +                             // check for foreign key mapping 
  +                             mappingElement = MetaData.getOptionalChild(element, 
"foreign-key-mapping");
  +                             if(mappingElement != null) {
  +                                     mappingStyle = FOREIGN_KEY;
  +                                     if(defaultValues.isManyToMany()) {
  +                                             throw new DeploymentException("Foreign 
key mapping-style is not allowed for many-to-many relationsips.");
  +                                     }
  +                             } else {
  +                                     // no mapping style element, will use 
defaultValues
  +                                     if(defaultValues.isForeignKeyMappingStyle()) {
  +                                             mappingStyle = FOREIGN_KEY;
  +                                     } else {
  +                                             mappingStyle = TABLE;
  +                                     }
  +                             }
                        }
  -             }                       
  -             
  -             // get table name
  -             String tableString = getElementContent(getOptionalChild(element, 
"table-name"));
  -             if(tableString != null) {
  -                     tableName = tableString;
                }
  +                             
  +             // if no mapping element given, use defaultValues
  +             if(mappingElement == null) {
  +                     dataSourceName = defaultValues.getDataSourceName();
  +                     typeMapping = defaultValues.getTypeMapping();
  +                     tableName = defaultValues.getTableName();
  +                     createTable = defaultValues.getCreateTable();
  +                     removeTable = defaultValues.getRemoveTable();
  +                     selectForUpdate = defaultValues.hasSelectForUpdate();
  +                     primaryKeyConstraint = defaultValues.hasPrimaryKeyConstraint();
  +                     readOnly = defaultValues.isReadOnly();
  +                     readTimeOut = defaultValues.getReadTimeOut();
                        
  -             // create table?  If not provided, keep default.
  -             String createString = getElementContent(getOptionalChild(element, 
"create-table"));
  -             if(createString != null) {
  -             createTable = Boolean.valueOf(createString).booleanValue();
  -             }
  +                     left = new JDBCRelationshipRoleMetaData(
  +                                                     this,
  +                                                     jdbcApplication,               
                                         
  +                                                
defaultValues.getLeftRelationshipRole());
  +                                                     
  +                     right = new JDBCRelationshipRoleMetaData(
  +                                                     this,
  +                                                     jdbcApplication,
  +                                                
defaultValues.getRightRelationshipRole());
                        
  -     // remove table?  If not provided, keep default.
  -             String removeString = getElementContent(getOptionalChild(element, 
"remove-table"));
  -             if(removeString != null) {
  -                     removeTable = Boolean.valueOf(removeString).booleanValue();
  -             }
  -     
  -             // read-only
  -             String readOnlyString = getElementContent(getOptionalChild(element, 
"read-only"));
  -             if(readOnlyString != null) {
  -                     readOnly = Boolean.valueOf(readOnlyString).booleanValue();
  -             }
  -
  -             // read-time-out
  -             if(isReadOnly()) {
  +                     return;         
  +             } 
  +        
  +             if(mappingStyle == TABLE) {
  +                     // datasource name
  +                     String dataSourceNameString = 
MetaData.getOptionalChildContent(mappingElement, "datasource");
  +                     if(dataSourceNameString != null) {
  +                             dataSourceName = dataSourceNameString;
  +                     } else {
  +                             dataSourceName = defaultValues.getDataSourceName();
  +                     }
  +                     
  +                     // get the type mapping for this datasource (optional, but 
always set in standardjbosscmp-jdbc.xml)
  +                     String typeMappingString = 
MetaData.getOptionalChildContent(mappingElement, "type-mapping");            
  +                     if(typeMappingString != null) {
  +                             typeMapping = 
jdbcApplication.getTypeMappingByName(typeMappingString);
  +                     
  +                             if(typeMapping == null) {
  +                                     throw new DeploymentException("Error in 
jbosscmp-jdbc.xml : type-mapping " + typeMappingString + " not found");
  +                             }
  +                     } else {
  +                             typeMapping = defaultValues.getTypeMapping();
  +                     }
  +                     
  +                     // get table name
  +                     String tableNameString = 
MetaData.getOptionalChildContent(mappingElement, "table-name");
  +                     if(tableNameString == null) {
  +                             tableNameString = defaultValues.getTableName();
  +                             if(tableNameString == null) {
  +                                     // use defaultValues to create default, 
because left/right 
  +                                     // have not been assigned yet, and values used 
to generate
  +                                     // default table name never change
  +                                     tableNameString = 
defaultValues.createDefaultTableName();
  +                             }
  +                     }
  +                     tableName = tableNameString;
  +                             
  +                     // create table?  If not provided, keep default.
  +                     String createString = 
MetaData.getOptionalChildContent(mappingElement, "create-table");
  +                     if(createString != null) {
  +                             createTable = 
Boolean.valueOf(createString).booleanValue();
  +                     } else {
  +                             createTable = defaultValues.getCreateTable();
  +                     }
  +                             
  +                     // remove table?  If not provided, keep default.
  +                     String removeString = 
MetaData.getOptionalChildContent(mappingElement, "remove-table");
  +                     if(removeString != null) {
  +                             removeTable = 
Boolean.valueOf(removeString).booleanValue();
  +                     } else {
  +                             removeTable = defaultValues.getRemoveTable();
  +                     }
  +     
  +                     // select for update
  +                     String sForUpString = 
MetaData.getOptionalChildContent(mappingElement, "select-for-update");
  +                     if(sForUpString != null) {
  +                             selectForUpdate = !isReadOnly() && 
(Boolean.valueOf(sForUpString).booleanValue());
  +                     } else {
  +                             selectForUpdate = defaultValues.hasSelectForUpdate();
  +                     }
  +     
  +                     // primary key constraint?  If not provided, keep default.
  +                     String pkString = 
MetaData.getOptionalChildContent(mappingElement, "pk-constraint");
  +                     if(pkString != null) {
  +                             primaryKeyConstraint = 
Boolean.valueOf(pkString).booleanValue();
  +                     } else {
  +                             primaryKeyConstraint = 
defaultValues.hasPrimaryKeyConstraint();
  +                     }
  +                     
  +                     // read-only
  +                     String readOnlyString = 
MetaData.getOptionalChildContent(mappingElement, "read-only");
  +                     if(readOnlyString != null) {
  +                             readOnly = 
Boolean.valueOf(readOnlyString).booleanValue();
  +                     } else {
  +                             readOnly = defaultValues.isReadOnly();
  +                     }
  +     
                        // read-time-out
  -                     String readTimeOutString = 
getElementContent(getOptionalChild(element, "read-time-out"));
  -                if(readTimeOutString != null) {
  +                     String readTimeOutString = 
MetaData.getOptionalChildContent(mappingElement, "read-time-out");
  +                     if(readTimeOutString != null) {
                                readTimeOut = Integer.parseInt(readTimeOutString);
  -                     }
  -             }               
  -
  -             String sForUpString = getElementContent(getOptionalChild(element, 
"select-for-update"));
  -             if(sForUpString != null) {
  -             selectForUpdate = (Boolean.valueOf(sForUpString).booleanValue());
  -                     selectForUpdate = selectForUpdate && !isReadOnly();
  -             }
  +                     } else {
  +                             readTimeOut = defaultValues.getReadTimeOut();
  +                     }               
  +             } else {
  +                     dataSourceName = null;
  +                     typeMapping = null;
  +                     tableName = null;
  +                     createTable = false;
  +                     removeTable = false;
  +                     selectForUpdate = false;
  +                     primaryKeyConstraint = false;
  +                     readOnly = false;
  +                     readTimeOut = -1;               
  +             }       
   
  -             // primary key constraint?  If not provided, keep default.
  -             String pkString = getElementContent(getOptionalChild(element, 
"pk-constraint"));
  -             if(pkString != null) {
  -                     primaryKeyConstraint = 
Boolean.valueOf(pkString).booleanValue();
  -             }
  +             //
  +             // load metadata for each specified role
  +             //
  +             String leftRoleName = 
defaultValues.getLeftRelationshipRole().getRelationshipRoleName();
  +             String rightRoleName = 
defaultValues.getRightRelationshipRole().getRelationshipRoleName();
  +             JDBCRelationshipRoleMetaData leftRole = null;
  +             JDBCRelationshipRoleMetaData rightRole = null;
                
  -             JDBCRelationshipRoleMetaData other = null;
  -             Iterator iter = getChildrenByTagName(element, "ejb-relationship-role");
  -             if(iter.hasNext()) {
  +             Iterator iter = MetaData.getChildrenByTagName(mappingElement, 
"ejb-relationship-role");
  +             for(int i=0; iter.hasNext(); i++) {
  +                     
  +                     // only 2 roles are allow 
  +                     if(i > 1) {
  +                             throw new DeploymentException("Expected only 2 
ejb-relationship-role but found more then 2");
  +                     }
  +                     
                        Element relationshipRoleElement = (Element)iter.next();
  -                     String relationshipRoleName = 
getElementContent(getOptionalChild(relationshipRoleElement, 
"ejb-relationship-role-name"));
  -                     
if(left.getRelationshipRoleName().equals(relationshipRoleName)) {
  -                             left.importXml(relationshipRoleElement);
  -                             other = right;
  -                     } else 
if(right.getRelationshipRoleName().equals(relationshipRoleName)) {
  -                             right.importXml(relationshipRoleElement);
  -                             other = left;
  +                     String relationshipRoleName = 
MetaData.getUniqueChildContent(relationshipRoleElement, "ejb-relationship-role-name");
  +                     if(leftRoleName.equals(relationshipRoleName)) {
  +                             leftRole = new JDBCRelationshipRoleMetaData(
  +                                                             this,
  +                                                        jdbcApplication,
  +                                                             
relationshipRoleElement, 
  +                                                             
defaultValues.getLeftRelationshipRole());
  +                     } else if(rightRoleName.equals(relationshipRoleName)) {
  +                             rightRole = new JDBCRelationshipRoleMetaData(
  +                                                             this,
  +                                                        jdbcApplication,
  +                                                             
relationshipRoleElement, 
  +                                                             
defaultValues.getRightRelationshipRole());
                        } else {
                                throw new DeploymentException("Found 
ejb-relationship-role '" + relationshipRoleName + "' in jboss-cmp.xml, but no matching 
role exits in ejb-jar.xml");
                        }
                }
                
  -             if(iter.hasNext()) {
  -                     Element relationshipRoleElement = (Element)iter.next();
  -                     String relationshipRoleName = 
getElementContent(getOptionalChild(relationshipRoleElement, 
"ejb-relationship-role-name"));
  -                     
if(other.getRelationshipRoleName().equals(relationshipRoleName)) {
  -                             other.importXml(relationshipRoleElement);
  -                     } else {
  -                             throw new DeploymentException("Found 
ejb-relationship-role '" + relationshipRoleName + "' in jboss-cmp.xml, but no matching 
role exits in ejb-jar.xml");
  -                     }
  +             // if left role was not specified create a new one for this relation
  +             if(leftRole == null) {
  +                     leftRole = new JDBCRelationshipRoleMetaData(
  +                                                     this,
  +                                                     jdbcApplication,               
                                         
  +                                                
defaultValues.getLeftRelationshipRole());
  +                                                     
                }
  -
  -             if(iter.hasNext()) {
  -                     throw new DeploymentException("Expected only 2 
ejb-relationship-role but found more then 2");
  +             
  +             // if right role was not specified create a new one for this relation
  +             if(rightRole == null) {
  +                     rightRole = new JDBCRelationshipRoleMetaData(
  +                                                     this,
  +                                                     jdbcApplication,
  +                                                
defaultValues.getRightRelationshipRole());
                }
  +             
  +             // assign the final roles
  +             left = leftRole;
  +             right = rightRole;
        }
   
        /** 
         * Gets the relation name. 
         * Relation name is loaded from the ejb-relation-name element.
  +      * @return the name of this relation
         */
        public String getRelationName() {
           return relationName;
  @@ -193,6 +366,7 @@
         * Gets the left jdbc relationship role. 
         * The relationship role is loaded from an ejb-relationship-role.
         * Left/right assignment is completely arbitrary.
  +      * @return the left JDBCRelationshipRoleMetaData
         */
        public JDBCRelationshipRoleMetaData getLeftRelationshipRole() {
                return left;
  @@ -202,13 +376,31 @@
         * Gets the right jdbc relationship role.
         * The relationship role is loaded from an ejb-relationship-role.
         * Left/right assignment is completely arbitrary.
  +      * @return the right JDBCRelationshipRoleMetaData
         */
        public JDBCRelationshipRoleMetaData getRightRelationshipRole() {
                return right;
        }
        
  +     /** 
  +      * Gets the relationship role related to the specified role.
  +      * @param role the relationship role that the related role is desired
  +      * @return the elationship role related to the specified role.
  +      * @throws DeploymentException if the role parameter is not the left or right 
role of this relation
  +      */
  +     public JDBCRelationshipRoleMetaData 
getOtherRelationshipRole(JDBCRelationshipRoleMetaData role) {
  +             if(left == role) {
  +                     return right;
  +             } else if(right == role) {
  +                     return left;
  +             } else {
  +                     throw new IllegalArgumentException("Specified role is not the 
left or right role. role=" + role);
  +             }
  +     }
  +     
        /**
         * Should this relation be mapped to a relation table.
  +      * @return true if this relation is mapped to a table
         */
        public boolean isTableMappingStyle() {
                return mappingStyle == TABLE;
  @@ -216,13 +408,39 @@
        
        /**
         * Should this relation use foreign keys for storage.
  +      * @return true if this relation is mapped to foreign keys
         */
        public boolean isForeignKeyMappingStyle() {
                return mappingStyle == FOREIGN_KEY;
        }
        
        /**
  +      * Gets the name of the datasource in jndi for this entity
  +      * @return the name of datasource in jndi
  +      */
  +     public String getDataSourceName() {
  +             return dataSourceName;
  +     }
  +
  +     /**
  +      * Gets the jdbc type mapping for this entity
  +      * @return the jdbc type mapping for this entity
  +      */
  +     public JDBCTypeMappingMetaData getTypeMapping() {
  +             return typeMapping;
  +     }
  +     
  +     /**
  +      * Is extra debug info being logged?
  +      * @return true if extra debug info is being logged
  +      */
  +     public boolean isDebug() {
  +             return debug;
  +     }
  +     
  +     /**
         * Gets the name of the relation table.
  +      * @return the name of the relation table to which is relation is mapped
         */
        public String getTableName() {
                return tableName;
  @@ -230,6 +448,7 @@
        
        /**
         * Should the relation table be created on startup.
  +      * @return true if the store mananager should attempt to create the relation 
table
         */
        public boolean getCreateTable() {
                return createTable;
  @@ -237,6 +456,7 @@
        
        /**
         * Should the relation table be removed on shutdown.
  +      * @return true if the store mananager should attempt to remove the relation 
table
         */
        public boolean getRemoveTable() {
                return removeTable;
  @@ -244,6 +464,8 @@
        
        /**
         * When the relation table is created, should it have a primary key constraint.
  +      * @return true if the store mananager should add a primary key constraint to 
the
  +      *              the create table sql statement
         */
        public boolean hasPrimaryKeyConstraint() {
                return primaryKeyConstraint;
  @@ -268,5 +490,21 @@
         */
        public boolean hasSelectForUpdate() {
                return selectForUpdate;
  +     }
  +     
  +     private String createDefaultTableName() {
  +             String defaultTableName = left.getEntity().getName();
  +             if(left.getCMRFieldName() != null) {
  +                     defaultTableName += "_" + left.getCMRFieldName();
  +             }
  +             defaultTableName += "_" + right.getEntity().getName();
  +             if(right.getCMRFieldName() != null) {
  +                     defaultTableName += "_" + right.getCMRFieldName();
  +             }
  +             return defaultTableName;
  +     }
  +     
  +     private boolean isManyToMany() {
  +             return left.isMultiplicityMany() && right.isMultiplicityMany();
        }
   }
  
  
  
  1.2       +206 -32   
jboss/src/main/org/jboss/ejb/plugins/cmp/jdbc/metadata/JDBCRelationshipRoleMetaData.java
  
  Index: JDBCRelationshipRoleMetaData.java
  ===================================================================
  RCS file: 
/cvsroot/jboss/jboss/src/main/org/jboss/ejb/plugins/cmp/jdbc/metadata/JDBCRelationshipRoleMetaData.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- JDBCRelationshipRoleMetaData.java 2001/07/09 21:45:59     1.1
  +++ JDBCRelationshipRoleMetaData.java 2001/07/26 02:39:03     1.2
  @@ -6,65 +6,68 @@
    */
   package org.jboss.ejb.plugins.cmp.jdbc.metadata;
   
  +import java.util.Collection;
  +import java.util.Collections;
  +import java.util.HashMap;
  +import java.util.Iterator;
  +import java.util.Map;
  +
   import org.jboss.ejb.DeploymentException;
   import org.jboss.metadata.MetaData;
   import org.jboss.metadata.RelationshipRoleMetaData;
   import org.w3c.dom.Element;
   
   /** 
  - * Represents one ejb-relationship-role element found in the ejb-jar.xml
  - * file's ejb-relation elements.
  + * Imutable class which represents one ejb-relationship-role element found in the
  + * ejb-jar.xml file's ejb-relation elements.
    *
    * @author <a href="mailto:[EMAIL PROTECTED]";>Dain Sundstrom</a>
  - * @version $Revision: 1.1 $
  + * @version $Revision: 1.2 $
    */
  -public class JDBCRelationshipRoleMetaData extends MetaData {
  +public final class JDBCRelationshipRoleMetaData {
        /**
         * Relation to which this role belongs.
         */
  -     private JDBCRelationMetaData relationMetaData;
  +     private final JDBCRelationMetaData relationMetaData;
   
        /**
         * Role name
         */
  -     private String relationshipRoleName;
  +     private final String relationshipRoleName;
        
        /**
  -      * is the multiplicity one?
  +      * Is the multiplicity one? If not, multiplicity is many.
         */
  -     private boolean multiplicityOne;
  +     private final boolean multiplicityOne;
        
        /**
         * Should this entity be deleted when related entity is deleted.
         */
  -     private boolean cascadeDelete;
  +     private final boolean cascadeDelete;
        
        /**
         * The entity that has this role.
         */
  -     private JDBCEntityMetaData entity;
  +     private final JDBCEntityMetaData entity;
        
        /**
         * Name of the entity's cmr field for this role.
         */
  -     private String cmrFieldName;
  -
  +     private final String cmrFieldName;
                
        /**
         * Type of the cmr field (i.e., collection or set)
         */
  -     private String cmrFieldType;
  +     private final String cmrFieldType;
        
  -     /**
  -      * The related role's jdbc meta data.
  -      */
  -     private JDBCRelationshipRoleMetaData relatedRole;
  -
  +     private final Map tableKeyFields = new HashMap();
  +     private final Map foreignKeyFields = new HashMap();
  +     
        public JDBCRelationshipRoleMetaData(
  -                     RelationshipRoleMetaData relationshipRole,
                        JDBCRelationMetaData relationMetaData,
  -                     JDBCApplicationMetaData applicationMetaData) {
  -                             
  +                     JDBCApplicationMetaData application,
  +                     RelationshipRoleMetaData relationshipRole)  throws 
DeploymentException {
  +             
                this.relationMetaData = relationMetaData;
                
                relationshipRoleName = relationshipRole.getRelationshipRoleName();
  @@ -73,15 +76,95 @@
                
                cmrFieldName = relationshipRole.getCMRFieldName();
                cmrFieldType = relationshipRole.getCMRFieldType();
  +
  +             entity = 
application.getBeanByEjbName(relationshipRole.getEntityName());
  +             
  +             if(relationMetaData.isTableMappingStyle()) {
  +                     // load all pks of entity into tableKeys map
  +                     for(Iterator i = entity.getCMPFields().iterator(); 
i.hasNext(); ) {
  +                             JDBCCMPFieldMetaData cmpField = 
(JDBCCMPFieldMetaData)i.next();
  +                             if(cmpField.isPrimaryKeyMember()) {
  +                                     cmpField = new JDBCCMPFieldMetaData(entity, 
cmpField, entity.getName() + "_" + cmpField.getFieldName(), false);
  +                                     tableKeyFields.put(cmpField.getFieldName(), 
cmpField);
  +                             }
  +                     }
  +             } else 
if(relationshipRole.getRelatedRoleMetaData().isMultiplicityOne()){       
  +                     // load all pks of related entity into foreignKeys map
  +                     String relatedEntityName = 
relationshipRole.getRelatedRoleMetaData().getEntityName();
  +                     JDBCEntityMetaData relatedEntity = 
application.getBeanByEjbName(relatedEntityName);
  +                     for(Iterator i = relatedEntity.getCMPFields().iterator(); 
i.hasNext(); ) {
  +                             JDBCCMPFieldMetaData cmpField = 
(JDBCCMPFieldMetaData)i.next();
  +                             if(cmpField.isPrimaryKeyMember()) {
  +                                     cmpField = new JDBCCMPFieldMetaData(entity, 
cmpField, relatedEntity.getName() + "_" + cmpField.getFieldName(), false);
  +                                     foreignKeyFields.put(cmpField.getFieldName(), 
cmpField);
  +                             }
  +                     }
  +             }
  +     }
  +
  +     public JDBCRelationshipRoleMetaData(
  +                     JDBCRelationMetaData relationMetaData,
  +                     JDBCApplicationMetaData application,
  +                     JDBCRelationshipRoleMetaData defaultValues) throws 
DeploymentException {
  +
  +             this.relationMetaData = relationMetaData;
   
  -             String entityName = relationshipRole.getEntityName();
  +             entity = 
application.getBeanByEjbName(defaultValues.getEntity().getName());
  +
  +             relationshipRoleName = defaultValues.getRelationshipRoleName();
  +             multiplicityOne = defaultValues.isMultiplicityOne();
  +             cascadeDelete = defaultValues.isCascadeDelete();
                
  -             entity = applicationMetaData.getBeanByEjbName(entityName);
  +             cmrFieldName = defaultValues.getCMRFieldName();
  +             cmrFieldType = defaultValues.getCMRFieldType(); 
                
  -             // inform the entity about this role
  -             entity.addRelationshipRole(this);
  +             if(relationMetaData.isTableMappingStyle()) {
  +                     // load all pks of entity into tableKeys map
  +                     for(Iterator i = entity.getCMPFields().iterator(); 
i.hasNext(); ) {
  +                             JDBCCMPFieldMetaData cmpField = 
(JDBCCMPFieldMetaData)i.next();
  +                             if(cmpField.isPrimaryKeyMember()) {
  +                                     cmpField = new JDBCCMPFieldMetaData(entity, 
cmpField, entity.getName() + "_" + cmpField.getFieldName(), false);
  +                                     tableKeyFields.put(cmpField.getFieldName(), 
cmpField);
  +                             }
  +                     }
  +             } else if(defaultValues.getRelatedRole().isMultiplicityOne()){  
  +                     // load all pks of related entity into foreignKeys map
  +                     String relatedEntityName = 
defaultValues.getRelatedRole().getEntity().getName();
  +                     JDBCEntityMetaData relatedEntity = 
application.getBeanByEjbName(relatedEntityName);
  +                     for(Iterator i = relatedEntity.getCMPFields().iterator(); 
i.hasNext(); ) {
  +                             JDBCCMPFieldMetaData cmpField = 
(JDBCCMPFieldMetaData)i.next();
  +                             if(cmpField.isPrimaryKeyMember()) {
  +                                     cmpField = new JDBCCMPFieldMetaData(entity, 
cmpField, relatedEntity.getName() + "_" + cmpField.getFieldName(), false);
  +                                     foreignKeyFields.put(cmpField.getFieldName(), 
cmpField);
  +                             }
  +                     }
  +             }
        }
   
  +     public JDBCRelationshipRoleMetaData(
  +                     JDBCRelationMetaData relationMetaData,
  +                     JDBCApplicationMetaData application,
  +                     Element element, 
  +                     JDBCRelationshipRoleMetaData defaultValues) throws 
DeploymentException {
  +             
  +             this.relationMetaData = relationMetaData;
  +             this.entity = 
application.getBeanByEjbName(defaultValues.getEntity().getName());
  +             
  +             relationshipRoleName = defaultValues.getRelationshipRoleName();
  +             multiplicityOne = defaultValues.isMultiplicityOne();
  +             cascadeDelete = defaultValues.isCascadeDelete();
  +             
  +             cmrFieldName = defaultValues.getCMRFieldName();
  +             cmrFieldType = defaultValues.getCMRFieldType();         
  +             
  +             if(relationMetaData.isTableMappingStyle()) {
  +                     loadTableKeyFields(element);
  +             } else if(defaultValues.getRelatedRole().isMultiplicityOne()){  
  +                     String relatedEntityName = 
defaultValues.getRelatedRole().getEntity().getName();
  +                     loadForeignKeyFields(element, 
application.getBeanByEjbName(relatedEntityName));
  +             }
  +     }
  +
        /**
         * Gets the relation to which this role belongs.
         */
  @@ -139,19 +222,110 @@
        }       
   
        /**
  -      * Sets the related role's jdbc meta data.
  +      * Gets the related role's jdbc meta data.
         */
  -     public void setRelatedRole(JDBCRelationshipRoleMetaData relatedRole) {
  -             this.relatedRole = relatedRole;
  +     public JDBCRelationshipRoleMetaData getRelatedRole() {
  +             return relationMetaData.getOtherRelationshipRole(this);
        }
        
        /**
  -      * Gets the related role's jdbc meta data.
  +      * Gets the foreign key fields of this role. The foreign key fields hold the
  +      * primary keys of the related entity. A relationship role has foreign key 
  +      * fields if the relation mapping style is foreign key and the other side of
  +      * the relationship has a multiplicity of one.
  +      * @return an unmodifiable collection of JDBCCMPFieldMetaData objects
         */
  -     public JDBCRelationshipRoleMetaData getRelatedRole() {
  -             return relatedRole;
  +     public Collection getForeignKeyFields() {
  +             return Collections.unmodifiableCollection(foreignKeyFields.values());
  +     }
  +     
  +     /**
  +      * Gets the key fields of this role in the relation table. The table key fields
  +      * hold the primary keys of this role's entity. A relationship role has table 
key 
  +      * fields if the relation is mapped to a relation table.
  +      * @return an unmodifiable collection of JDBCCMPFieldMetaData objects
  +      */
  +     public Collection getTableKeyFields() {
  +             return Collections.unmodifiableCollection(tableKeyFields.values());
        }
  +     
  +     /**
  +      * Loads the foreign key fields for this role based on the primary keys of the
  +      * specified related entity and the override data from the xml element.
  +      */
  +     private void loadForeignKeyFields(Element element, JDBCEntityMetaData 
relatedEntity) throws DeploymentException {
  +             // load all pks of related entity into foreignKeys map
  +             for(Iterator i = relatedEntity.getCMPFields().iterator(); i.hasNext(); 
) {
  +                     JDBCCMPFieldMetaData cmpField = (JDBCCMPFieldMetaData)i.next();
  +                     if(cmpField.isPrimaryKeyMember()) {
  +                             cmpField = new JDBCCMPFieldMetaData(entity, cmpField, 
relatedEntity.getName() + "_" + cmpField.getFieldName(), false);
  +                             foreignKeyFields.put(cmpField.getFieldName(), 
cmpField);
  +                     }
  +             }
   
  -     public void importXml(Element element) throws DeploymentException {            
 
  +             Element foreignKeysElement = 
MetaData.getOptionalChild(element,"foreign-key-fields");
  +             
  +             // no field overrides, we're done
  +             if(foreignKeysElement == null) {
  +                     System.out.println("NO FOREIGN KEY OVERRIDE");
  +                     return;
  +             }
  +             
  +             // load overrides
  +             Iterator fkIter = MetaData.getChildrenByTagName(foreignKeysElement, 
"foreign-key-field");
  +             
  +             // if empty foreign-key-fields element, no fk should be used
  +             if(!fkIter.hasNext()) {
  +                     System.out.println("NO FOREIGN KEY FOR THIS RELATION");
  +                     foreignKeyFields.clear();
  +             }
  +             
  +             while(fkIter.hasNext()) {
  +                     Element foreignKeyElement = (Element)fkIter.next();
  +                     String foreignKeyName = 
MetaData.getUniqueChildContent(foreignKeyElement, "field-name");
  +                     System.out.println("OVERRIDE foreignKeyName="+foreignKeyName);
  +                     JDBCCMPFieldMetaData cmpField = 
(JDBCCMPFieldMetaData)foreignKeyFields.get(foreignKeyName);
  +                     if(cmpField == null) {
  +                             throw new DeploymentException("CMP field for foreign 
key not found: field name="+foreignKeyName);
  +                     }
  +                     cmpField = new JDBCCMPFieldMetaData(entity, foreignKeyElement, 
cmpField, false);
  +                     foreignKeyFields.put(cmpField.getFieldName(), cmpField);
  +             }
  +     }
  +
  +     /**
  +      * Loads the table key fields for this role based on the primary keys of the
  +      * this entity and the override data from the xml element.
  +      */
  +     private void loadTableKeyFields(Element element) throws DeploymentException {
  +             // load all pks of entity into tableKeys map
  +             System.out.println("Entity cmp field count" + 
entity.getCMPFields().size());
  +             for(Iterator i = entity.getCMPFields().iterator(); i.hasNext(); ) {
  +                     JDBCCMPFieldMetaData cmpField = (JDBCCMPFieldMetaData)i.next();
  +                     System.out.println("TableKeyField : 
name="+cmpField.getFieldName()+" isPk="+cmpField.isPrimaryKeyMember());
  +                     if(cmpField.isPrimaryKeyMember()) {
  +                             cmpField = new JDBCCMPFieldMetaData(entity, cmpField, 
entity.getName() + "_" + cmpField.getFieldName(), false);
  +                             tableKeyFields.put(cmpField.getFieldName(), cmpField);
  +                     }
  +             }
  +
  +             Element tableKeysElement = 
MetaData.getOptionalChild(element,"table-key-fields");
  +             
  +             // no field overrides, we're done
  +             if(tableKeysElement == null) {
  +                     return;
  +             }
  +             
  +             // load overrides
  +             for(Iterator i = MetaData.getChildrenByTagName(tableKeysElement, 
"table-key-field"); i.hasNext(); ) {
  +                     Element tableKeyElement = (Element)i.next();
  +                     String tableKeyName = 
MetaData.getUniqueChildContent(tableKeyElement, "field-name");
  +                     JDBCCMPFieldMetaData cmpField = 
(JDBCCMPFieldMetaData)tableKeyFields.get(tableKeyName);
  +                     if(cmpField == null) {
  +                             throw new DeploymentException("CMP field for table key 
not found: field name="+tableKeyName);
  +                     }
  +                     cmpField = new JDBCCMPFieldMetaData(entity, tableKeyElement, 
cmpField, false);
  +                     tableKeyFields.put(cmpField.getFieldName(), cmpField);
  +             }
        }
   }
  
  
  

_______________________________________________
Jboss-development mailing list
[EMAIL PROTECTED]
http://lists.sourceforge.net/lists/listinfo/jboss-development

Reply via email to