gdamour     2005/08/19 23:49:08

  Modified:    modules/openejb-builder/src/java/org/openejb/deployment
                        CMPContainerBuilder.java
  Log:

  o GERONIMO-675 CMR / CMP Fields should not be read-only
  
  Some additional enhancement to support the scenario where a primary key column
  is also a foreign key column.
  
  This basically implements the rules that Jeremy was recommending to apply
  in such a case:
  
  when the primary key is set in the ejbCreate<Method> the associated CMR field,
  i.e. the CMR mapped to the foreign key column, is marked as under 
construction.
  
  From this point, the CMR must be set before the commit of the current
  transaction. If not set, then the transaction is marked as rolled back.
  
  Also, if an attempt is made to reset the pk field by relating the entity to
  the wrong entity, an IllegalStateException is thrown.
  
  o Also sync the code with the refactoring of the Association and 
AssociationEnd
  classes: the Association.isOneToOne, isOneToMany, isManyToOne and
  isManyToMany methods have been moved to AssociationEnd.
  
  Revision  Changes    Path
  1.27      +27 -8     
openejb/modules/openejb-builder/src/java/org/openejb/deployment/CMPContainerBuilder.java
  
  Index: CMPContainerBuilder.java
  ===================================================================
  RCS file: 
/home/projects/openejb/scm/openejb/modules/openejb-builder/src/java/org/openejb/deployment/CMPContainerBuilder.java,v
  retrieving revision 1.26
  retrieving revision 1.27
  diff -u -r1.26 -r1.27
  --- CMPContainerBuilder.java  5 Aug 2005 11:00:23 -0000       1.26
  +++ CMPContainerBuilder.java  20 Aug 2005 03:49:07 -0000      1.27
  @@ -105,6 +105,8 @@
   import org.tranql.ejb.CMPFieldTransform;
   import org.tranql.ejb.CMPMappedToCMRAccessor;
   import org.tranql.ejb.CMRField;
  +import org.tranql.ejb.CMRMappedToInversePKCMP;
  +import org.tranql.ejb.CMRMappedToOwningPKCMP;
   import org.tranql.ejb.EJB;
   import org.tranql.ejb.EJBSchema;
   import org.tranql.ejb.FinderEJBQLQuery;
  @@ -315,9 +317,8 @@
   
           if (buildContainer) {
               return createContainer(signatures, contextFactory, 
interceptorBuilder, pool);
  -        } else {
  -            return createConfiguration(classLoader, signatures, 
contextFactory, interceptorBuilder, pool, timerName);
           }
  +        return createConfiguration(classLoader, signatures, contextFactory, 
interceptorBuilder, pool, timerName);
       }
   
       private LinkedHashMap createCMPFieldAccessors(SQLQueryBuilder 
queryBuilder, LinkedHashMap cmrFieldAccessor) throws QueryException {
  @@ -407,12 +408,16 @@
               FaultHandler relatedFaultHandler = 
buildFaultHandler(queryBuilder, relatedEJB, relatedField, relatedIndex, 
prefetch);
               CMPFieldTransform relatedAccessor = new CMPFieldAccessor(new 
CacheRowAccessor(relatedIndex, null), name);
               relatedAccessor = new CMPFieldFaultTransform(relatedAccessor, 
relatedFaultHandler, new int[]{relatedIndex});
  -            if ( association.isOneToOne() ) {
  +            if ( field.isOneToOne() ) {
                   accessor = new OneToOneCMR(accessor, identityDefiner, 
relatedAccessor, relatedIdentityDefiner);
  -            } else if ( association.isOneToMany(field) ) {
  +                accessor = buildCMRMappedToPKCMP(relatedEJB, relatedField, 
accessor, false, relatedIndex);
  +                accessor = buildCMRMappedToPKCMP(ejb, field, accessor, true, 
i);
  +            } else if ( field.isOneToMany() ) {
  +                relatedAccessor = buildCMRMappedToPKCMP(relatedEJB, 
relatedField, relatedAccessor, true, relatedIndex);
                   accessor = new ManyToOneCMR(accessor, identityDefiner, 
relatedAccessor, relatedIdentityDefiner);
  -            } else if ( association.isManyToOne(field) ) {
  +            } else if ( field.isManyToOne() ) {
                   accessor = new OneToManyCMR(accessor, relatedAccessor, 
relatedIdentityDefiner);
  +                accessor = buildCMRMappedToPKCMP(ejb, field, accessor, true, 
i);
               } else {
                   CacheTable mtm = (CacheTable) 
getGlobalSchema().getEntity(association.getManyToManyEntity().getName());
                   boolean isRight = 
association.getRightJoinDefinition().getPKEntity() == ejb;
  @@ -422,7 +427,7 @@
               cmrFaultAccessors.put(name, accessor);
   
               IdentityTransform relatedIdentityTransform = 
identityDefinerBuilder.getPrimaryKeyTransform(relatedEJB);
  -            if ( association.isOneToOne() || association.isManyToOne(field) 
) {
  +            if ( field.isOneToOne() || field.isManyToOne() ) {
                   accessor = new SingleValuedCMRAccessor(accessor,
                           new LocalProxyTransform(relatedIdentityTransform, 
relatedEJB.getProxyFactory()));
               } else {
  @@ -437,6 +442,20 @@
           return new LinkedHashMap[] {cmrFaultAccessors, cmrFieldAccessors};
       }
   
  +    private CMPFieldTransform buildCMRMappedToPKCMP(Entity entity, 
AssociationEnd end, CMPFieldTransform accessor, boolean owning, int cmrSlot) {
  +        List pkFields = entity.getPrimaryKeyFields();
  +        for (Iterator iter = pkFields.iterator(); iter.hasNext();) {
  +            Attribute pkField = (Attribute) iter.next();
  +            if (end.hasFKAttribute(pkField.getName())) {
  +                if (owning) {
  +                    return new CMRMappedToOwningPKCMP(accessor, cmrSlot);
  +                }
  +                return new CMRMappedToInversePKCMP(accessor, cmrSlot);
  +            }
  +        }
  +        return accessor;
  +    }
  +    
       private FaultHandler buildFaultHandler(SQLQueryBuilder queryBuilder, EJB 
definingEJB, CMRField field, int slot, boolean prefetch) throws QueryException {
           IdentityDefinerBuilder identityDefinerBuilder = new 
IdentityDefinerBuilder(ejbSchema, globalSchema);
           Association association = field.getAssociation();
  @@ -458,7 +477,7 @@
           }
   
           QueryCommand faultCommand = 
queryBuilder.buildLoadAssociationEnd(definingEJB.getName(), field.getName(), 
prefetch);
  -        if ( association.isOneToOne() || association.isManyToOne(field) ) {
  +        if ( field.isOneToOne() || field.isManyToOne() ) {
               return new SingleValuedCMRFaultHandler(faultCommand,
                       identityDefiner,
                       new EmptySlotLoader[]{new EmptySlotLoader(slot, new 
ReferenceAccessor(relatedIdentityDefiner))});
  
  
  

Reply via email to