/* */ package org.jboss.ejb.plugins.cmp.jdbc.bridge;
/* */
/* */ import java.lang.ref.WeakReference;
/* */ import java.lang.reflect.Field;
/* */ import java.lang.reflect.Method;
/* */ import java.rmi.RemoteException;
/* */ import java.sql.PreparedStatement;
/* */ import java.sql.ResultSet;
/* */ import java.util.ArrayList;
/* */ import java.util.Arrays;
/* */ import java.util.Collection;
/* */ import java.util.Collections;
/* */ import java.util.HashMap;
/* */ import java.util.HashSet;
/* */ import java.util.Iterator;
/* */ import java.util.List;
/* */ import java.util.Map;
/* */ import java.util.Set;
/* */ import javax.ejb.EJBException;
/* */ import javax.ejb.EJBLocalHome;
/* */ import javax.ejb.EJBLocalObject;
/* */ import javax.ejb.NoSuchObjectLocalException;
/* */ import javax.ejb.RemoveException;
/* */ import javax.sql.DataSource;
/* */ import javax.transaction.RollbackException;
/* */ import javax.transaction.Synchronization;
/* */ import javax.transaction.SystemException;
/* */ import javax.transaction.Transaction;
/* */ import javax.transaction.TransactionManager;
/* */ import org.jboss.deployment.DeploymentException;
/* */ import org.jboss.ejb.EntityCache;
/* */ import org.jboss.ejb.EntityContainer;
/* */ import org.jboss.ejb.EntityEnterpriseContext;
/* */ import org.jboss.ejb.LocalProxyFactory;
/* */ import org.jboss.ejb.plugins.cmp.bridge.EntityBridge;
/* */ import org.jboss.ejb.plugins.cmp.bridge.FieldBridge;
/* */ import org.jboss.ejb.plugins.cmp.ejbql.Catalog;
/* */ import org.jboss.ejb.plugins.cmp.jdbc.CascadeDeleteStrategy;
/* */ import org.jboss.ejb.plugins.cmp.jdbc.CascadeDeleteStrategy.BatchCascadeDeleteStrategy;
/* */ import org.jboss.ejb.plugins.cmp.jdbc.JDBCContext;
/* */ import org.jboss.ejb.plugins.cmp.jdbc.JDBCEntityPersistenceStore;
/* */ import org.jboss.ejb.plugins.cmp.jdbc.JDBCParameterSetter;
/* */ import org.jboss.ejb.plugins.cmp.jdbc.JDBCResultSetReader;
/* */ import org.jboss.ejb.plugins.cmp.jdbc.JDBCStoreManager;
/* */ import org.jboss.ejb.plugins.cmp.jdbc.JDBCType;
/* */ import org.jboss.ejb.plugins.cmp.jdbc.JDBCTypeFactory;
/* */ import org.jboss.ejb.plugins.cmp.jdbc.ReadAheadCache;
/* */ import org.jboss.ejb.plugins.cmp.jdbc.RelationData;
/* */ import org.jboss.ejb.plugins.cmp.jdbc.SQLUtil;
/* */ import org.jboss.ejb.plugins.cmp.jdbc.metadata.JDBCCMPFieldMetaData;
/* */ import org.jboss.ejb.plugins.cmp.jdbc.metadata.JDBCEntityMetaData;
/* */ import org.jboss.ejb.plugins.cmp.jdbc.metadata.JDBCReadAheadMetaData;
/* */ import org.jboss.ejb.plugins.cmp.jdbc.metadata.JDBCRelationMetaData;
/* */ import org.jboss.ejb.plugins.cmp.jdbc.metadata.JDBCRelationshipRoleMetaData;
/* */ import org.jboss.ejb.plugins.lock.Entrancy;
/* */ import org.jboss.invocation.InvocationType;
/* */ import org.jboss.logging.Logger;
/* */ import org.jboss.security.SecurityContext;
/* */ import org.jboss.security.SecurityContextUtil;
/* */ import org.jboss.tm.TransactionLocal;
/* */
/* */ public final class JDBCCMRFieldBridge extends JDBCAbstractCMRFieldBridge
/* */ {
/* */ private final JDBCEntityBridge entity;
/* */ private final JDBCStoreManager manager;
/* */ private final JDBCRelationshipRoleMetaData metadata;
/* */ private DataSource dataSource;
/* */ private String qualifiedTableName;
/* */ private String tableName;
/* */ private JDBCCMP2xFieldBridge[] tableKeyFields;
/* */ private JDBCType jdbcType;
/* */ private WeakReference relatedContainerRef;
/* */ private JDBCStoreManager relatedManager;
/* */ private JDBCEntityBridge relatedEntity;
/* */ private JDBCCMRFieldBridge relatedCMRField;
/* */ private final Logger log;
/* */ private JDBCCMP2xFieldBridge[] foreignKeyFields;
/* */ private boolean allFKFieldsMappedToPKFields;
/* 158 */ private final Map relatedPKFieldsByMyPKFields = new HashMap();
/* */
/* 162 */ private final Map relatedPKFieldsByMyFKFields = new HashMap();
/* */ private boolean hasFKFieldsMappedToCMPFields;
/* 174 */ private final TransactionLocal relatedPKValuesWaitingForMyPK = new TransactionLocal()
/* */ {
/* */ protected Object initialValue()
/* */ {
/* 178 */ return new HashMap();
/* */ }
/* 174 */ };
/* */ private Method relatedFindByPrimaryKey;
/* */ private final int jdbcContextIndex;
/* */ private CascadeDeleteStrategy cascadeDeleteStrategy;
/* */ private RelationDataManager relationManager;
/* 2257 */ private static final RelationDataManager EMPTY_RELATION_MANAGER = new RelationDataManager()
/* */ {
/* */ public void addRelation(JDBCCMRFieldBridge field, Object id, JDBCCMRFieldBridge relatedField, Object relatedId)
/* */ {
/* */ }
/* */
/* */ public void removeRelation(JDBCCMRFieldBridge field, Object id, JDBCCMRFieldBridge relatedField, Object relatedId)
/* */ {
/* */ }
/* */
/* */ public boolean isDirty()
/* */ {
/* 2272 */ return false;
/* */ }
/* */
/* */ public RelationData getRelationData()
/* */ {
/* 2277 */ throw new UnsupportedOperationException();
/* */ }
/* 2257 */ };
/* */
/* */ public JDBCCMRFieldBridge(JDBCEntityBridge entity, JDBCStoreManager manager, JDBCRelationshipRoleMetaData metadata)
/* */ throws DeploymentException
/* */ {
/* 210 */ this.entity = entity;
/* 211 */ this.manager = manager;
/* 212 */ this.metadata = metadata;
/* 213 */ this.jdbcContextIndex = ((JDBCEntityBridge)manager.getEntityBridge()).getNextJDBCContextIndex();
/* */
/* 216 */ String categoryName = getClass().getName() + "." + manager.getMetaData().getName() + ".";
/* */
/* 218 */ if (metadata.getCMRFieldName() != null)
/* */ {
/* 220 */ categoryName = categoryName + metadata.getCMRFieldName();
/* */ }
/* */ else
/* */ {
/* 224 */ categoryName = categoryName + metadata.getRelatedRole().getEntity().getName() + "-" + metadata.getRelatedRole().getCMRFieldName();
/* */ }
/* */
/* 227 */ this.log = Logger.getLogger(categoryName);
/* */ }
/* */
/* */ public RelationDataManager getRelationDataManager()
/* */ {
/* 232 */ return this.relationManager;
/* */ }
/* */
/* */ public void resolveRelationship()
/* */ throws DeploymentException
/* */ {
/* 243 */ String relatedEntityName = this.metadata.getRelatedRole().getEntity().getName();
/* */
/* 246 */ Catalog catalog = (Catalog)this.manager.getApplicationData("CATALOG");
/* 247 */ this.relatedEntity = ((JDBCEntityBridge)catalog.getEntityByEJBName(relatedEntityName));
/* 248 */ if (this.relatedEntity == null)
/* */ {
/* 250 */ throw new DeploymentException("Related entity not found: entity=" + this.entity.getEntityName() + ", " + "cmrField=" + getFieldName() + ", " + "relatedEntity=" + relatedEntityName);
/* */ }
/* */
/* 261 */ JDBCCMRFieldBridge[] cmrFields = (JDBCCMRFieldBridge[])(JDBCCMRFieldBridge[])this.relatedEntity.getCMRFields();
/* 262 */ for (int i = 0; i < cmrFields.length; i++)
/* */ {
/* 264 */ JDBCCMRFieldBridge cmrField = cmrFields[i];
/* 265 */ if (this.metadata.getRelatedRole() != cmrField.getMetaData())
/* */ continue;
/* 267 */ this.relatedCMRField = cmrField;
/* 268 */ break;
/* */ }
/* */
/* 274 */ if (this.relatedCMRField == null)
/* */ {
/* 276 */ String message = "Related CMR field not found in " + this.relatedEntity.getEntityName() + " for relationship from";
/* */
/* 279 */ message = message + this.entity.getEntityName() + ".";
/* 280 */ if (getFieldName() != null)
/* */ {
/* 282 */ message = message + getFieldName();
/* */ }
/* */ else
/* */ {
/* 286 */ message = message + "<no-field>";
/* */ }
/* */
/* 289 */ message = message + " to ";
/* 290 */ message = message + relatedEntityName + ".";
/* 291 */ if (this.metadata.getRelatedRole().getCMRFieldName() != null)
/* */ {
/* 293 */ message = message + this.metadata.getRelatedRole().getCMRFieldName();
/* */ }
/* */ else
/* */ {
/* 297 */ message = message + "<no-field>";
/* */ }
/* */
/* 300 */ throw new DeploymentException(message);
/* */ }
/* */
/* 304 */ this.relatedManager = ((JDBCStoreManager)this.relatedEntity.getManager());
/* */
/* 307 */ EntityContainer relatedContainer = this.relatedManager.getContainer();
/* 308 */ this.relatedContainerRef = new WeakReference(relatedContainer);
/* */
/* 311 */ Class homeClass = relatedContainer.getLocalHomeClass() != null ? relatedContainer.getLocalHomeClass() : relatedContainer.getHomeClass();
/* */ try
/* */ {
/* 315 */ this.relatedFindByPrimaryKey = homeClass.getMethod("findByPrimaryKey", new Class[] { this.relatedEntity.getPrimaryKeyClass() });
/* */ }
/* */ catch (Exception e)
/* */ {
/* 320 */ throw new DeploymentException("findByPrimaryKey(" + this.relatedEntity.getPrimaryKeyClass().getName() + " pk) was not found in " + homeClass.getName());
/* */ }
/* */
/* 328 */ if (this.metadata.getRelationMetaData().isTableMappingStyle())
/* */ {
/* 331 */ Collection tableKeys = this.metadata.getKeyFields();
/* 332 */ List keyFieldsList = new ArrayList(tableKeys.size());
/* */
/* 335 */ Map pkFieldsToFKFields = new HashMap(tableKeys.size());
/* 336 */ for (Iterator i = tableKeys.iterator(); i.hasNext(); )
/* */ {
/* 338 */ JDBCCMPFieldMetaData cmpFieldMetaData = (JDBCCMPFieldMetaData)i.next();
/* 339 */ FieldBridge pkField = this.entity.getFieldByName(cmpFieldMetaData.getFieldName());
/* 340 */ if (pkField == null)
/* */ {
/* 342 */ throw new DeploymentException("Primary key not found for key-field " + cmpFieldMetaData.getFieldName());
/* */ }
/* 344 */ pkFieldsToFKFields.put(pkField, new JDBCCMP2xFieldBridge(this.manager, cmpFieldMetaData));
/* */ }
/* */
/* 347 */ JDBCFieldBridge[] pkFields = this.entity.getPrimaryKeyFields();
/* 348 */ for (int i = 0; i < pkFields.length; i++)
/* */ {
/* 350 */ Object fkField = pkFieldsToFKFields.get(pkFields[i]);
/* 351 */ if (fkField == null)
/* */ {
/* 353 */ throw new DeploymentException("Primary key " + pkFields[i].getFieldName() + " is not mapped.");
/* */ }
/* 355 */ keyFieldsList.add(fkField);
/* */ }
/* 357 */ this.tableKeyFields = ((JDBCCMP2xFieldBridge[])(JDBCCMP2xFieldBridge[])keyFieldsList.toArray(new JDBCCMP2xFieldBridge[keyFieldsList.size()]));
/* */
/* 360 */ this.dataSource = this.metadata.getRelationMetaData().getDataSource();
/* */ }
/* */ else
/* */ {
/* 364 */ initializeForeignKeyFields();
/* 365 */ this.dataSource = (hasForeignKey() ? this.entity.getDataSource() : this.relatedEntity.getDataSource());
/* */ }
/* */
/* 372 */ this.qualifiedTableName = SQLUtil.fixTableName(this.metadata.getRelationMetaData().getDefaultTableName(), this.dataSource);
/* 373 */ this.tableName = SQLUtil.getTableNameWithoutSchema(this.qualifiedTableName);
/* */
/* 375 */ this.relationManager = this.relatedCMRField.initRelationManager(this);
/* */ }
/* */
/* */ public void start()
/* */ throws DeploymentException
/* */ {
/* 385 */ this.cascadeDeleteStrategy = CascadeDeleteStrategy.getCascadeDeleteStrategy(this);
/* */ }
/* */
/* */ public boolean removeFromRelations(EntityEnterpriseContext ctx, Object[] oldRelationsRef)
/* */ {
/* 390 */ load(ctx);
/* */
/* 392 */ FieldState fieldState = getFieldState(ctx);
/* 393 */ List value = fieldState.getValue();
/* */
/* 395 */ boolean removed = false;
/* 396 */ if (!value.isEmpty())
/* */ {
/* 398 */ if (this.hasFKFieldsMappedToCMPFields)
/* */ {
/* 400 */ if (isForeignKeyValid(value.get(0)))
/* */ {
/* 402 */ this.cascadeDeleteStrategy.removedIds(ctx, oldRelationsRef, value);
/* 403 */ removed = true;
/* */ }
/* */ }
/* */ else
/* */ {
/* 408 */ this.cascadeDeleteStrategy.removedIds(ctx, oldRelationsRef, value);
/* 409 */ removed = true;
/* */ }
/* */ }
/* 412 */ return removed;
/* */ }
/* */
/* */ public void cascadeDelete(EntityEnterpriseContext ctx, List oldValues)
/* */ throws RemoveException, RemoteException
/* */ {
/* 418 */ this.cascadeDeleteStrategy.cascadeDelete(ctx, oldValues);
/* */ }
/* */
/* */ public boolean isBatchCascadeDelete()
/* */ {
/* 423 */ return this.cascadeDeleteStrategy instanceof CascadeDeleteStrategy.BatchCascadeDeleteStrategy;
/* */ }
/* */
/* */ public JDBCStoreManager getJDBCStoreManager()
/* */ {
/* 431 */ return this.manager;
/* */ }
/* */
/* */ public JDBCAbstractEntityBridge getEntity()
/* */ {
/* 439 */ return this.entity;
/* */ }
/* */
/* */ public JDBCRelationshipRoleMetaData getMetaData()
/* */ {
/* 447 */ return this.metadata;
/* */ }
/* */
/* */ public JDBCRelationMetaData getRelationMetaData()
/* */ {
/* 455 */ return this.metadata.getRelationMetaData();
/* */ }
/* */
/* */ public String getFieldName()
/* */ {
/* 463 */ return this.metadata.getCMRFieldName();
/* */ }
/* */
/* */ public String getQualifiedTableName()
/* */ {
/* 471 */ return this.qualifiedTableName;
/* */ }
/* */
/* */ public String getTableName()
/* */ {
/* 476 */ return this.tableName;
/* */ }
/* */
/* */ public DataSource getDataSource()
/* */ {
/* 484 */ return this.dataSource;
/* */ }
/* */
/* */ public JDBCReadAheadMetaData getReadAhead()
/* */ {
/* 492 */ return this.metadata.getReadAhead();
/* */ }
/* */
/* */ public JDBCType getJDBCType()
/* */ {
/* 497 */ return this.jdbcType;
/* */ }
/* */
/* */ public boolean isPrimaryKeyMember()
/* */ {
/* 502 */ return false;
/* */ }
/* */
/* */ public boolean hasForeignKey()
/* */ {
/* 510 */ return this.foreignKeyFields != null;
/* */ }
/* */
/* */ public boolean allFkFieldsMappedToPkFields()
/* */ {
/* 518 */ return this.allFKFieldsMappedToPKFields;
/* */ }
/* */
/* */ public boolean isCollectionValued()
/* */ {
/* 526 */ return this.metadata.getRelatedRole().isMultiplicityMany();
/* */ }
/* */
/* */ public boolean isSingleValued()
/* */ {
/* 534 */ return this.metadata.getRelatedRole().isMultiplicityOne();
/* */ }
/* */
/* */ public JDBCFieldBridge[] getTableKeyFields()
/* */ {
/* 542 */ return this.tableKeyFields;
/* */ }
/* */
/* */ public JDBCFieldBridge[] getForeignKeyFields()
/* */ {
/* 550 */ return this.foreignKeyFields;
/* */ }
/* */
/* */ public JDBCAbstractCMRFieldBridge getRelatedCMRField()
/* */ {
/* 558 */ return this.relatedCMRField;
/* */ }
/* */
/* */ public JDBCStoreManager getRelatedManager()
/* */ {
/* 566 */ return this.relatedManager;
/* */ }
/* */
/* */ public EntityBridge getRelatedEntity()
/* */ {
/* 574 */ return this.relatedEntity;
/* */ }
/* */
/* */ public JDBCEntityBridge getRelatedJDBCEntity()
/* */ {
/* 582 */ return this.relatedEntity;
/* */ }
/* */
/* */ private final EntityContainer getRelatedContainer()
/* */ {
/* 590 */ return (EntityContainer)this.relatedContainerRef.get();
/* */ }
/* */
/* */ public final Class getRelatedLocalInterface()
/* */ {
/* 598 */ return getRelatedContainer().getLocalClass();
/* */ }
/* */
/* */ public final LocalProxyFactory getRelatedInvoker()
/* */ {
/* 606 */ return getRelatedContainer().getLocalProxyFactory();
/* */ }
/* */
/* */ public boolean isLoaded(EntityEnterpriseContext ctx)
/* */ {
/* 615 */ return getFieldState(ctx).isLoaded;
/* */ }
/* */
/* */ public void addRelatedPKsWaitedForMe(EntityEnterpriseContext ctx)
/* */ {
/* 626 */ Map relatedPKsMap = getRelatedPKsWaitingForMyPK();
/* */ Iterator waitingPKsIter;
/* 627 */ synchronized (relatedPKsMap)
/* */ {
/* 629 */ List relatedPKsWaitingForMe = (List)relatedPKsMap.get(ctx.getId());
/* 630 */ if (relatedPKsWaitingForMe != null)
/* */ {
/* 632 */ for (waitingPKsIter = relatedPKsWaitingForMe.iterator(); waitingPKsIter.hasNext(); )
/* */ {
/* 634 */ Object waitingPK = waitingPKsIter.next();
/* 635 */ waitingPKsIter.remove();
/* 636 */ if (isForeignKeyValid(waitingPK))
/* */ {
/* 638 */ createRelationLinks(ctx, waitingPK);
/* */ }
/* */ }
/* */ }
/* */ }
/* */ }
/* */
/* */ public boolean isReadOnly()
/* */ {
/* 650 */ return getRelationMetaData().isReadOnly();
/* */ }
/* */
/* */ public boolean isReadTimedOut(EntityEnterpriseContext ctx)
/* */ {
/* 659 */ if (!isReadOnly())
/* */ {
/* 661 */ return true;
/* */ }
/* */
/* 665 */ if (getRelationMetaData().getReadTimeOut() == -1)
/* */ {
/* 667 */ return false;
/* */ }
/* */
/* 670 */ long readInterval = System.currentTimeMillis() - getFieldState(ctx).getLastRead();
/* 671 */ return readInterval > getRelationMetaData().getReadTimeOut();
/* */ }
/* */
/* */ public Object getValue(EntityEnterpriseContext ctx)
/* */ {
/* 681 */ return getInstanceValue(ctx);
/* */ }
/* */
/* */ public void setValue(EntityEnterpriseContext ctx, Object value)
/* */ {
/* 692 */ if (isReadOnly())
/* */ {
/* 694 */ throw new EJBException("Field is read-only: fieldName=" + getFieldName());
/* */ }
/* */
/* 697 */ if (!JDBCEntityBridge.isEjbCreateDone(ctx))
/* */ {
/* 699 */ throw new IllegalStateException("A CMR field cannot be set in ejbCreate; this should be done in the ejbPostCreate method instead [EJB 2.0 Spec. 10.5.2].");
/* */ }
/* */
/* 704 */ if ((isCollectionValued()) && (value == null))
/* */ {
/* 706 */ throw new IllegalArgumentException("null cannot be assigned to a collection-valued cmr-field [EJB 2.0 Spec. 10.3.8].");
/* */ }
/* */
/* 720 */ setInstanceValue(ctx, value);
/* */ }
/* */
/* */ public Object getInstanceValue(EntityEnterpriseContext myCtx)
/* */ {
/* 729 */ load(myCtx);
/* */
/* 731 */ FieldState fieldState = getFieldState(myCtx);
/* 732 */ if (isCollectionValued())
/* */ {
/* 734 */ return fieldState.getRelationSet();
/* */ }
/* */
/* */ try
/* */ {
/* 740 */ List value = fieldState.getValue();
/* 741 */ if (!value.isEmpty())
/* */ {
/* 743 */ Object fk = value.get(0);
/* 744 */ return getRelatedEntityByFK(fk);
/* */ }
/* 746 */ if (this.foreignKeyFields != null)
/* */ {
/* 749 */ Object relatedId = getRelatedIdFromContext(myCtx);
/* 750 */ if (relatedId != null)
/* */ {
/* 752 */ return getRelatedEntityByFK(relatedId);
/* */ }
/* */ }
/* 755 */ return null;
/* */ }
/* */ catch (EJBException e)
/* */ {
/* 759 */ throw e;
/* */ }
/* */ catch (Exception e) {
/* */ }
/* 763 */ throw new EJBException(e);
/* */ }
/* */
/* */ public EJBLocalObject getRelatedEntityByFK(Object fk)
/* */ {
/* 779 */ EJBLocalObject relatedLocalObject = null;
/* 780 */ EntityContainer relatedContainer = getRelatedContainer();
/* */
/* 782 */ if ((this.hasFKFieldsMappedToCMPFields) && (this.relatedManager.getReadAheadCache().getPreloadDataMap(fk, false) == null))
/* */ {
/* 786 */ EJBLocalHome relatedHome = relatedContainer.getLocalProxyFactory().getEJBLocalHome();
/* */ try
/* */ {
/* 789 */ relatedLocalObject = (EJBLocalObject)this.relatedFindByPrimaryKey.invoke(relatedHome, new Object[] { fk });
/* */ }
/* */ catch (Exception ignore)
/* */ {
/* */ }
/* */
/* */ }
/* */ else
/* */ {
/* 798 */ relatedLocalObject = relatedContainer.getLocalProxyFactory().getEntityEJBLocalObject(fk);
/* */ }
/* */
/* 801 */ return relatedLocalObject;
/* */ }
/* */
/* */ public boolean isForeignKeyValid(Object fk)
/* */ {
/* */ boolean valid;
/* */ boolean valid;
/* 814 */ if (this.relatedManager.getReadAheadCache().getPreloadDataMap(fk, false) != null)
/* */ {
/* 816 */ valid = true;
/* */ }
/* */ else
/* */ {
/* 820 */ EJBLocalHome relatedHome = getRelatedContainer().getLocalProxyFactory().getEJBLocalHome();
/* */ try
/* */ {
/* 823 */ this.relatedFindByPrimaryKey.invoke(relatedHome, new Object[] { fk });
/* 824 */ valid = true;
/* */ }
/* */ catch (Exception ignore)
/* */ {
/* 829 */ valid = false;
/* */ }
/* */ }
/* 832 */ return valid;
/* */ }
/* */
/* */ public void setInstanceValue(EntityEnterpriseContext myCtx, Object newValue)
/* */ {
/* */ List newPks;
/* */ List newPks;
/* 843 */ if ((newValue instanceof Collection))
/* */ {
/* 845 */ Collection col = (Collection)newValue;
/* */ List newPks;
/* */ Iterator iter;
/* 846 */ if (!col.isEmpty())
/* */ {
/* 848 */ newPks = new ArrayList(col.size());
/* 849 */ for (iter = col.iterator(); iter.hasNext(); )
/* */ {
/* 851 */ Object localObject = iter.next();
/* 852 */ if (localObject != null)
/* */ {
/* 854 */ Object relatedId = getRelatedPrimaryKey(localObject);
/* */
/* 857 */ if (this.relatedPKFieldsByMyPKFields.size() > 0)
/* */ {
/* 859 */ checkSetForeignKey(myCtx, relatedId);
/* */ }
/* */
/* 862 */ newPks.add(relatedId);
/* */ }
/* */ }
/* */ }
/* */ else
/* */ {
/* 868 */ newPks = Collections.EMPTY_LIST;
/* */ }
/* */ }
/* */ else
/* */ {
/* */ List newPks;
/* 873 */ if (newValue != null)
/* */ {
/* 875 */ newPks = Collections.singletonList(getRelatedPrimaryKey(newValue));
/* */ }
/* */ else
/* */ {
/* 879 */ newPks = Collections.EMPTY_LIST;
/* */ }
/* */
/* */ }
/* */
/* 884 */ load(myCtx);
/* 885 */ FieldState fieldState = getFieldState(myCtx);
/* */
/* 888 */ if (newValue == fieldState.getRelationSet())
/* */ {
/* 890 */ return;
/* */ }
/* */
/* */ try
/* */ {
/* 896 */ List value = fieldState.getValue();
/* 897 */ if (!value.isEmpty())
/* */ {
/* 899 */ Object[] curPks = value.toArray(new Object[value.size()]);
/* 900 */ for (int i = 0; i < curPks.length; i++)
/* */ {
/* 902 */ destroyRelationLinks(myCtx, curPks[i]);
/* */ }
/* */
/* */ }
/* */
/* 907 */ for (int i = 0; i < newPks.size(); i++)
/* */ {
/* 909 */ createRelationLinks(myCtx, newPks.get(i));
/* */ }
/* */ }
/* */ catch (RuntimeException e)
/* */ {
/* 914 */ throw e;
/* */ }
/* */ catch (Exception e)
/* */ {
/* 918 */ throw new EJBException(e);
/* */ }
/* */ }
/* */
/* */ private void checkSetForeignKey(EntityEnterpriseContext myCtx, Object newValue)
/* */ throws IllegalStateException
/* */ {
/* 934 */ JDBCFieldBridge[] pkFields = this.entity.getPrimaryKeyFields();
/* 935 */ for (int i = 0; i < pkFields.length; i++)
/* */ {
/* 937 */ JDBCCMP2xFieldBridge pkField = (JDBCCMP2xFieldBridge)pkFields[i];
/* 938 */ JDBCCMP2xFieldBridge relatedPkField = (JDBCCMP2xFieldBridge)this.relatedPKFieldsByMyPKFields.get(pkField);
/* 939 */ if (relatedPkField == null)
/* */ continue;
/* 941 */ Object comingValue = relatedPkField.getPrimaryKeyValue(newValue);
/* 942 */ Object currentValue = pkField.getInstanceValue(myCtx);
/* */
/* 945 */ if (comingValue.equals(currentValue))
/* */ continue;
/* 947 */ throw new IllegalStateException("Can't create relationship: CMR field " + this.entity.getEntityName() + "." + getFieldName() + " has foreign key fields mapped to the primary key columns." + " Primary key may only be set once in ejbCreate [EJB 2.0 Spec. 10.3.5]." + " primary key value is " + currentValue + " overriding value is " + comingValue);
/* */ }
/* */ }
/* */
/* */ public void createRelationLinks(EntityEnterpriseContext myCtx, Object relatedId)
/* */ {
/* 973 */ createRelationLinks(myCtx, relatedId, true);
/* */ }
/* */
/* */ public void createRelationLinks(EntityEnterpriseContext myCtx, Object relatedId, boolean updateForeignKey)
/* */ {
/* 978 */ if (isReadOnly())
/* */ {
/* 980 */ throw new EJBException("Field is read-only: " + getFieldName());
/* */ }
/* */
/* 985 */ Transaction tx = getTransaction();
/* 986 */ if (this.metadata.isMultiplicityOne())
/* */ {
/* 988 */ Object oldRelatedId = this.relatedCMRField.invokeGetRelatedId(tx, relatedId);
/* 989 */ if (oldRelatedId != null)
/* */ {
/* 991 */ invokeRemoveRelation(tx, oldRelatedId, relatedId);
/* 992 */ this.relatedCMRField.invokeRemoveRelation(tx, relatedId, oldRelatedId);
/* */ }
/* */ }
/* */
/* 996 */ addRelation(myCtx, relatedId, updateForeignKey);
/* 997 */ this.relatedCMRField.invokeAddRelation(tx, relatedId, myCtx.getId());
/* */ }
/* */
/* */ public void destroyRelationLinks(EntityEnterpriseContext myCtx, Object relatedId)
/* */ {
/* 1008 */ destroyRelationLinks(myCtx, relatedId, true);
/* */ }
/* */
/* */ public void destroyRelationLinks(EntityEnterpriseContext myCtx, Object relatedId, boolean updateValueCollection)
/* */ {
/* 1024 */ destroyRelationLinks(myCtx, relatedId, updateValueCollection, true);
/* */ }
/* */
/* */ public void destroyRelationLinks(EntityEnterpriseContext myCtx, Object relatedId, boolean updateValueCollection, boolean updateForeignKey)
/* */ {
/* 1032 */ if (isReadOnly())
/* */ {
/* 1034 */ throw new EJBException("Field is read-only: " + getFieldName());
/* */ }
/* */
/* 1037 */ removeRelation(myCtx, relatedId, updateValueCollection, updateForeignKey);
/* 1038 */ this.relatedCMRField.invokeRemoveRelation(getTransaction(), relatedId, myCtx.getId());
/* */ }
/* */
/* */ public void scheduleChildrenForCascadeDelete(EntityEnterpriseContext ctx)
/* */ {
/* 1046 */ load(ctx);
/* 1047 */ FieldState fieldState = getFieldState(ctx);
/* 1048 */ List value = fieldState.getValue();
/* 1049 */ if (!value.isEmpty())
/* */ {
/* 1051 */ Transaction tx = getTransaction();
/* 1052 */ for (int i = 0; i < value.size(); i++)
/* */ {
/* 1054 */ this.relatedCMRField.invokeScheduleForCascadeDelete(tx, value.get(i));
/* */ }
/* */ }
/* */ }
/* */
/* */ public void scheduleChildrenForBatchCascadeDelete(EntityEnterpriseContext ctx)
/* */ {
/* 1064 */ load(ctx);
/* 1065 */ FieldState fieldState = getFieldState(ctx);
/* 1066 */ List value = fieldState.getValue();
/* 1067 */ if (!value.isEmpty())
/* */ {
/* 1069 */ Transaction tx = getTransaction();
/* 1070 */ for (int i = 0; i < value.size(); i++)
/* */ {
/* 1072 */ this.relatedCMRField.invokeScheduleForBatchCascadeDelete(tx, value.get(i));
/* */ }
/* */ }
/* */ }
/* */
/* */ private Object invokeScheduleForCascadeDelete(Transaction tx, Object myId)
/* */ {
/* */ try
/* */ {
/* 1084 */ EntityCache instanceCache = (EntityCache)this.manager.getContainer().getInstanceCache();
/* 1085 */ SecurityContext sc = SecurityActions.getSecurityContext();
/* */
/* 1087 */ CMRInvocation invocation = new CMRInvocation();
/* 1088 */ invocation.setCmrMessage(CMRMessage.SCHEDULE_FOR_CASCADE_DELETE);
/* 1089 */ invocation.setEntrancy(Entrancy.NON_ENTRANT);
/* 1090 */ invocation.setId(instanceCache.createCacheKey(myId));
/* 1091 */ invocation.setArguments(new Object[] { this });
/* 1092 */ invocation.setTransaction(tx);
/* 1093 */ invocation.setPrincipal(sc.getUtil().getUserPrincipal());
/* 1094 */ invocation.setCredential(sc.getUtil().getCredential());
/* 1095 */ invocation.setType(InvocationType.LOCAL);
/* 1096 */ return this.manager.getContainer().invoke(invocation);
/* */ }
/* */ catch (EJBException e)
/* */ {
/* 1100 */ throw e;
/* */ }
/* */ catch (Exception e) {
/* */ }
/* 1104 */ throw new EJBException("Error in scheduleForCascadeDelete()", e);
/* */ }
/* */
/* */ private Object invokeScheduleForBatchCascadeDelete(Transaction tx, Object myId)
/* */ {
/* */ try
/* */ {
/* 1115 */ EntityCache instanceCache = (EntityCache)this.manager.getContainer().getInstanceCache();
/* 1116 */ SecurityContext sc = SecurityActions.getSecurityContext();
/* */
/* 1118 */ CMRInvocation invocation = new CMRInvocation();
/* 1119 */ invocation.setCmrMessage(CMRMessage.SCHEDULE_FOR_BATCH_CASCADE_DELETE);
/* 1120 */ invocation.setEntrancy(Entrancy.NON_ENTRANT);
/* 1121 */ invocation.setId(instanceCache.createCacheKey(myId));
/* 1122 */ invocation.setArguments(new Object[] { this });
/* 1123 */ invocation.setTransaction(tx);
/* 1124 */ invocation.setPrincipal(sc.getUtil().getUserPrincipal());
/* 1125 */ invocation.setCredential(sc.getUtil().getCredential());
/* 1126 */ invocation.setType(InvocationType.LOCAL);
/* 1127 */ return this.manager.getContainer().invoke(invocation);
/* */ }
/* */ catch (EJBException e)
/* */ {
/* 1131 */ throw e;
/* */ }
/* */ catch (Exception e) {
/* */ }
/* 1135 */ throw new EJBException("Error in scheduleForBatchCascadeDelete()", e);
/* */ }
/* */
/* */ private Object invokeGetRelatedId(Transaction tx, Object myId)
/* */ {
/* */ try
/* */ {
/* 1147 */ EntityCache instanceCache = (EntityCache)this.manager.getContainer().getInstanceCache();
/* 1148 */ SecurityContext sc = SecurityActions.getSecurityContext();
/* */
/* 1150 */ CMRInvocation invocation = new CMRInvocation();
/* 1151 */ invocation.setCmrMessage(CMRMessage.GET_RELATED_ID);
/* 1152 */ invocation.setEntrancy(Entrancy.NON_ENTRANT);
/* 1153 */ invocation.setId(instanceCache.createCacheKey(myId));
/* 1154 */ invocation.setArguments(new Object[] { this });
/* 1155 */ invocation.setTransaction(tx);
/* 1156 */ invocation.setPrincipal(sc.getUtil().getUserPrincipal());
/* 1157 */ invocation.setCredential(sc.getUtil().getCredential());
/* 1158 */ invocation.setType(InvocationType.LOCAL);
/* 1159 */ return this.manager.getContainer().invoke(invocation);
/* */ }
/* */ catch (EJBException e)
/* */ {
/* 1163 */ throw e;
/* */ }
/* */ catch (Exception e) {
/* */ }
/* 1167 */ throw new EJBException("Error in getRelatedId", e);
/* */ }
/* */
/* */ private void invokeAddRelation(Transaction tx, Object myId, Object relatedId)
/* */ {
/* */ try
/* */ {
/* 1179 */ SecurityContext sc = SecurityActions.getSecurityContext();
/* 1180 */ EntityCache instanceCache = (EntityCache)this.manager.getContainer().getInstanceCache();
/* */
/* 1182 */ CMRInvocation invocation = new CMRInvocation();
/* 1183 */ invocation.setCmrMessage(CMRMessage.ADD_RELATION);
/* 1184 */ invocation.setEntrancy(Entrancy.NON_ENTRANT);
/* 1185 */ invocation.setId(instanceCache.createCacheKey(myId));
/* 1186 */ invocation.setArguments(new Object[] { this, relatedId });
/* 1187 */ invocation.setTransaction(tx);
/* 1188 */ invocation.setPrincipal(sc.getUtil().getUserPrincipal());
/* 1189 */ invocation.setCredential(sc.getUtil().getCredential());
/* 1190 */ invocation.setType(InvocationType.LOCAL);
/* 1191 */ this.manager.getContainer().invoke(invocation);
/* */ }
/* */ catch (EJBException e)
/* */ {
/* 1195 */ throw e;
/* */ }
/* */ catch (Exception e)
/* */ {
/* 1199 */ throw new EJBException("Error in addRelation", e);
/* */ }
/* */ }
/* */
/* */ private void invokeRemoveRelation(Transaction tx, Object myId, Object relatedId)
/* */ {
/* */ try
/* */ {
/* 1211 */ EntityCache instanceCache = (EntityCache)this.manager.getContainer().getInstanceCache();
/* 1212 */ SecurityContext sc = SecurityActions.getSecurityContext();
/* */
/* 1214 */ CMRInvocation invocation = new CMRInvocation();
/* 1215 */ invocation.setCmrMessage(CMRMessage.REMOVE_RELATION);
/* 1216 */ invocation.setEntrancy(Entrancy.NON_ENTRANT);
/* 1217 */ invocation.setId(instanceCache.createCacheKey(myId));
/* 1218 */ invocation.setArguments(new Object[] { this, relatedId });
/* 1219 */ invocation.setTransaction(tx);
/* 1220 */ invocation.setPrincipal(sc.getUtil().getUserPrincipal());
/* 1221 */ invocation.setCredential(sc.getUtil().getCredential());
/* 1222 */ invocation.setType(InvocationType.LOCAL);
/* 1223 */ this.manager.getContainer().invoke(invocation);
/* */ }
/* */ catch (EJBException e)
/* */ {
/* 1227 */ throw e;
/* */ }
/* */ catch (Exception e)
/* */ {
/* 1231 */ throw new EJBException("Error in removeRelation", e);
/* */ }
/* */ }
/* */
/* */ public Object getRelatedId(EntityEnterpriseContext myCtx)
/* */ {
/* 1240 */ if (isCollectionValued())
/* */ {
/* 1242 */ throw new EJBException("getRelatedId may only be called on a cmr-field with a multiplicity of one.");
/* */ }
/* */
/* 1245 */ load(myCtx);
/* 1246 */ List value = getFieldState(myCtx).getValue();
/* 1247 */ return value.isEmpty() ? null : value.get(0);
/* */ }
/* */
/* */ public Object getRelatedIdFromContext(EntityEnterpriseContext ctx)
/* */ {
/* 1258 */ Object relatedId = null;
/* */
/* 1260 */ for (int i = 0; i < this.foreignKeyFields.length; i++)
/* */ {
/* 1262 */ JDBCCMP2xFieldBridge fkField = this.foreignKeyFields[i];
/* 1263 */ Object fkFieldValue = fkField.getInstanceValue(ctx);
/* 1264 */ if (fkFieldValue == null)
/* */ {
/* 1266 */ return null;
/* */ }
/* 1268 */ JDBCCMP2xFieldBridge relatedPKField = (JDBCCMP2xFieldBridge)this.relatedPKFieldsByMyFKFields.get(fkField);
/* 1269 */ relatedId = relatedPKField.setPrimaryKeyValue(relatedId, fkFieldValue);
/* */ }
/* 1271 */ return relatedId;
/* */ }
/* */
/* */ public void addRelation(EntityEnterpriseContext myCtx, Object fk)
/* */ {
/* 1279 */ addRelation(myCtx, fk, true);
/* 1280 */ this.relationManager.addRelation(this, myCtx.getId(), this.relatedCMRField, fk);
/* */ }
/* */
/* */ private void addRelation(EntityEnterpriseContext myCtx, Object fk, boolean updateForeignKey)
/* */ {
/* 1285 */ checkSetForeignKey(myCtx, fk);
/* */
/* 1287 */ if (isReadOnly())
/* */ {
/* 1289 */ throw new EJBException("Field is read-only: " + getFieldName());
/* */ }
/* */
/* 1292 */ if (!JDBCEntityBridge.isEjbCreateDone(myCtx))
/* */ {
/* 1294 */ throw new IllegalStateException("A CMR field cannot be set or added to a relationship in ejbCreate; this should be done in the ejbPostCreate method instead [EJB 2.0 Spec. 10.5.2].");
/* */ }
/* */
/* 1300 */ FieldState myState = getFieldState(myCtx);
/* 1301 */ myState.addRelation(fk);
/* */
/* 1304 */ if ((hasForeignKey()) && (updateForeignKey))
/* */ {
/* 1306 */ setForeignKey(myCtx, fk);
/* */ }
/* */ }
/* */
/* */ public void removeRelation(EntityEnterpriseContext myCtx, Object fk)
/* */ {
/* 1315 */ removeRelation(myCtx, fk, true, true);
/* 1316 */ this.relationManager.removeRelation(this, myCtx.getId(), this.relatedCMRField, fk);
/* */ }
/* */
/* */ private void removeRelation(EntityEnterpriseContext myCtx, Object fk, boolean updateValueCollection, boolean updateForeignKey)
/* */ {
/* 1324 */ if (isReadOnly())
/* */ {
/* 1326 */ throw new EJBException("Field is read-only: " + getFieldName());
/* */ }
/* */
/* 1330 */ if (updateValueCollection)
/* */ {
/* 1332 */ FieldState myState = getFieldState(myCtx);
/* 1333 */ myState.removeRelation(fk);
/* */ }
/* */
/* 1337 */ if ((hasForeignKey()) && (updateForeignKey))
/* */ {
/* 1339 */ setForeignKey(myCtx, null);
/* */ }
/* */ }
/* */
/* */ private void load(EntityEnterpriseContext myCtx)
/* */ {
/* 1352 */ FieldState fieldState = getFieldState(myCtx);
/* 1353 */ if (fieldState.isLoaded())
/* */ {
/* 1355 */ return;
/* */ }
/* */
/* 1359 */ if (this.log.isTraceEnabled())
/* */ {
/* 1361 */ this.log.trace("Read ahead cahce load: cmrField=" + getFieldName() + " pk=" + myCtx.getId());
/* */ }
/* */
/* 1364 */ this.manager.getReadAheadCache().load(myCtx);
/* 1365 */ if (fieldState.isLoaded())
/* */ {
/* 1367 */ return;
/* */ }
/* */ Collection values;
/* */ Collection values;
/* 1372 */ if (hasForeignKey())
/* */ {
/* 1380 */ boolean loadWithManager = false;
/* 1381 */ Object fk = null;
/* 1382 */ for (int i = 0; i < this.foreignKeyFields.length; i++)
/* */ {
/* 1384 */ JDBCCMP2xFieldBridge fkField = this.foreignKeyFields[i];
/* */
/* 1386 */ if (!fkField.isLoaded(myCtx))
/* */ {
/* 1388 */ loadWithManager = true;
/* 1389 */ break;
/* */ }
/* */
/* 1392 */ Object fkFieldValue = fkField.getInstanceValue(myCtx);
/* */
/* 1394 */ if (fkFieldValue == null)
/* */ {
/* 1396 */ fk = null;
/* 1397 */ break;
/* */ }
/* 1399 */ JDBCCMP2xFieldBridge relatedPKField = (JDBCCMP2xFieldBridge)this.relatedPKFieldsByMyFKFields.get(fkField);
/* 1400 */ fk = relatedPKField.setPrimaryKeyValue(fk, fkFieldValue);
/* */ }
/* */ Collection values;
/* 1403 */ if (loadWithManager)
/* */ {
/* 1405 */ values = this.manager.loadRelation(this, myCtx.getId());
/* */ }
/* */ else
/* */ {
/* 1409 */ values = fk == null ? Collections.EMPTY_LIST : Collections.singletonList(fk);
/* */ }
/* */ }
/* */ else
/* */ {
/* 1414 */ values = this.manager.loadRelation(this, myCtx.getId());
/* */ }
/* 1416 */ load(myCtx, values);
/* */ }
/* */
/* */ public void load(EntityEnterpriseContext myCtx, Collection values)
/* */ {
/* 1422 */ if ((isSingleValued()) && (values.size() > 1))
/* */ {
/* 1424 */ throw new EJBException("Data contains multiple values, but this cmr field is single valued: " + values);
/* */ }
/* */
/* 1428 */ FieldState fieldState = getFieldState(myCtx);
/* 1429 */ fieldState.loadRelations(values);
/* */
/* 1432 */ if (hasForeignKey())
/* */ {
/* 1435 */ if (!values.isEmpty())
/* */ {
/* 1437 */ Object loadedValue = values.iterator().next();
/* 1438 */ for (int i = 0; i < this.foreignKeyFields.length; i++)
/* */ {
/* 1440 */ JDBCCMP2xFieldBridge fkField = this.foreignKeyFields[i];
/* 1441 */ Object fieldValue = fkField.getPrimaryKeyValue(loadedValue);
/* 1442 */ fkField.updateState(myCtx, fieldValue);
/* */ }
/* */
/* */ }
/* */
/* 1447 */ List realValue = fieldState.getValue();
/* 1448 */ Object fk = realValue.isEmpty() ? null : realValue.get(0);
/* 1449 */ setForeignKey(myCtx, fk);
/* */ }
/* */
/* 1452 */ JDBCEntityBridge.setCreated(myCtx);
/* */ }
/* */
/* */ public void setForeignKey(EntityEnterpriseContext myCtx, Object fk)
/* */ {
/* 1460 */ if (!hasForeignKey())
/* */ {
/* 1462 */ throw new EJBException(getFieldName() + " CMR field does not have a foreign key to set.");
/* */ }
/* */
/* 1465 */ for (int i = 0; i < this.foreignKeyFields.length; i++)
/* */ {
/* 1467 */ JDBCCMP2xFieldBridge fkField = this.foreignKeyFields[i];
/* 1468 */ Object fieldValue = fkField.getPrimaryKeyValue(fk);
/* 1469 */ fkField.setInstanceValue(myCtx, fieldValue);
/* */ }
/* */ }
/* */
/* */ public void initInstance(EntityEnterpriseContext ctx)
/* */ {
/* 1479 */ getFieldState(ctx).loadRelations(Collections.EMPTY_SET);
/* */
/* 1481 */ if (this.foreignKeyFields == null)
/* */ {
/* 1483 */ return;
/* */ }
/* */
/* 1486 */ for (int i = 0; i < this.foreignKeyFields.length; i++)
/* */ {
/* 1488 */ JDBCCMP2xFieldBridge foreignKeyField = this.foreignKeyFields[i];
/* 1489 */ if (foreignKeyField.isFKFieldMappedToCMPField())
/* */ continue;
/* 1491 */ foreignKeyField.setInstanceValue(ctx, null);
/* */ }
/* */ }
/* */
/* */ public void resetPersistenceContext(EntityEnterpriseContext ctx)
/* */ {
/* 1502 */ if (!isReadTimedOut(ctx))
/* */ {
/* 1504 */ return;
/* */ }
/* */
/* 1508 */ JDBCContext jdbcCtx = (JDBCContext)ctx.getPersistenceContext();
/* */
/* 1515 */ jdbcCtx.setFieldState(this.jdbcContextIndex, null);
/* */
/* 1517 */ if (this.foreignKeyFields == null)
/* */ {
/* 1519 */ return;
/* */ }
/* */
/* 1522 */ for (int i = 0; i < this.foreignKeyFields.length; i++)
/* */ {
/* 1524 */ JDBCCMP2xFieldBridge foreignKeyField = this.foreignKeyFields[i];
/* 1525 */ if (foreignKeyField.isFKFieldMappedToCMPField())
/* */ continue;
/* 1527 */ foreignKeyField.resetPersistenceContext(ctx);
/* */ }
/* */ }
/* */
/* */ public int setInstanceParameters(PreparedStatement ps, int parameterIndex, EntityEnterpriseContext ctx)
/* */ {
/* 1536 */ if (this.foreignKeyFields == null)
/* */ {
/* 1538 */ return parameterIndex;
/* */ }
/* */
/* 1541 */ List value = getFieldState(ctx).getValue();
/* 1542 */ Object fk = value.isEmpty() ? null : value.get(0);
/* */
/* 1544 */ for (int i = 0; i < this.foreignKeyFields.length; i++)
/* */ {
/* 1546 */ parameterIndex = this.foreignKeyFields[i].setPrimaryKeyParameters(ps, parameterIndex, fk);
/* */ }
/* */
/* 1549 */ return parameterIndex;
/* */ }
/* */
/* */ public int loadInstanceResults(ResultSet rs, int parameterIndex, EntityEnterpriseContext ctx)
/* */ {
/* 1556 */ if (!hasForeignKey())
/* */ {
/* 1558 */ return parameterIndex;
/* */ }
/* */
/* 1562 */ Object[] ref = new Object[1];
/* 1563 */ parameterIndex = loadArgumentResults(rs, parameterIndex, ref);
/* */
/* 1566 */ FieldState fieldState = getFieldState(ctx);
/* 1567 */ if (!fieldState.isLoaded())
/* */ {
/* 1569 */ if (ref[0] != null)
/* */ {
/* 1571 */ load(ctx, Collections.singleton(ref[0]));
/* */ }
/* */ else
/* */ {
/* 1575 */ load(ctx, Collections.EMPTY_SET);
/* */ }
/* */ }
/* 1578 */ return parameterIndex;
/* */ }
/* */
/* */ public int loadArgumentResults(ResultSet rs, int parameterIndex, Object[] fkRef)
/* */ {
/* 1583 */ if (this.foreignKeyFields == null)
/* */ {
/* 1585 */ return parameterIndex;
/* */ }
/* */
/* 1588 */ boolean fkIsNull = false;
/* */
/* 1591 */ Object[] argumentRef = new Object[1];
/* 1592 */ for (int i = 0; i < this.foreignKeyFields.length; i++)
/* */ {
/* 1594 */ JDBCCMPFieldBridge field = this.foreignKeyFields[i];
/* 1595 */ parameterIndex = field.loadArgumentResults(rs, parameterIndex, argumentRef);
/* */
/* 1597 */ if (fkIsNull)
/* */ {
/* */ continue;
/* */ }
/* 1601 */ if (field.getPrimaryKeyField() != null)
/* */ {
/* 1607 */ if (argumentRef[0] == null)
/* */ {
/* 1609 */ fkRef[0] = null;
/* 1610 */ fkIsNull = true;
/* */ }
/* */ else
/* */ {
/* 1615 */ if (fkRef[0] == null)
/* */ {
/* 1617 */ fkRef[0] = this.relatedEntity.createPrimaryKeyInstance();
/* */ }
/* */
/* */ try
/* */ {
/* 1622 */ field.getPrimaryKeyField().set(fkRef[0], argumentRef[0]);
/* */ }
/* */ catch (Exception e)
/* */ {
/* 1627 */ throw new EJBException("Internal error setting foreign-key field " + getFieldName(), e);
/* */ }
/* */ }
/* */
/* */ }
/* */ else
/* */ {
/* 1634 */ fkRef[0] = argumentRef[0];
/* */ }
/* */ }
/* 1637 */ return parameterIndex;
/* */ }
/* */
/* */ public boolean isDirty(EntityEnterpriseContext ctx)
/* */ {
/* 1646 */ return this.foreignKeyFields == null ? this.relationManager.isDirty() : false;
/* */ }
/* */
/* */ public boolean invalidateCache(EntityEnterpriseContext ctx)
/* */ {
/* 1651 */ JDBCContext jdbcCtx = (JDBCContext)ctx.getPersistenceContext();
/* 1652 */ FieldState fieldState = (FieldState)jdbcCtx.getFieldState(this.jdbcContextIndex);
/* 1653 */ return fieldState == null ? false : fieldState.isChanged();
/* */ }
/* */
/* */ public void setClean(EntityEnterpriseContext ctx)
/* */ {
/* 1665 */ throw new UnsupportedOperationException();
/* */ }
/* */
/* */ public boolean isCMPField()
/* */ {
/* 1670 */ return false;
/* */ }
/* */
/* */ public JDBCEntityPersistenceStore getManager()
/* */ {
/* 1675 */ return this.manager;
/* */ }
/* */
/* */ public boolean hasFKFieldsMappedToCMPFields()
/* */ {
/* 1680 */ return this.hasFKFieldsMappedToCMPFields;
/* */ }
/* */
/* */ public void addRelatedPKWaitingForMyPK(Object myPK, Object relatedPK)
/* */ {
/* 1685 */ Map relatedPKsWaitingForMyPK = getRelatedPKsWaitingForMyPK();
/* 1686 */ synchronized (relatedPKsWaitingForMyPK)
/* */ {
/* 1688 */ List relatedPKs = (List)relatedPKsWaitingForMyPK.get(myPK);
/* 1689 */ if (relatedPKs == null)
/* */ {
/* 1691 */ relatedPKs = new ArrayList(1);
/* 1692 */ relatedPKsWaitingForMyPK.put(myPK, relatedPKs);
/* */ }
/* 1694 */ relatedPKs.add(relatedPK);
/* */ }
/* */ }
/* */
/* */ public void removeRelatedPKWaitingForMyPK(Object myPK, Object relatedPK)
/* */ {
/* 1700 */ Map relatedPKMap = getRelatedPKsWaitingForMyPK();
/* 1701 */ synchronized (relatedPKMap)
/* */ {
/* 1703 */ List relatedPKs = (List)relatedPKMap.get(myPK);
/* 1704 */ if (relatedPKs != null)
/* */ {
/* 1706 */ relatedPKs.remove(relatedPK);
/* */ }
/* */ }
/* */ }
/* */
/* */ private FieldState getFieldState(EntityEnterpriseContext ctx)
/* */ {
/* 1716 */ JDBCContext jdbcCtx = (JDBCContext)ctx.getPersistenceContext();
/* 1717 */ FieldState fieldState = (FieldState)jdbcCtx.getFieldState(this.jdbcContextIndex);
/* 1718 */ if (fieldState == null)
/* */ {
/* 1720 */ fieldState = new FieldState(ctx);
/* 1721 */ jdbcCtx.setFieldState(this.jdbcContextIndex, fieldState);
/* */ }
/* 1723 */ return fieldState;
/* */ }
/* */
/* */ private void initializeForeignKeyFields()
/* */ throws DeploymentException
/* */ {
/* 1734 */ Collection foreignKeys = this.metadata.getRelatedRole().getKeyFields();
/* */
/* 1737 */ Map fkFieldsByRelatedPKFields = new HashMap();
/* 1738 */ for (Iterator i = foreignKeys.iterator(); i.hasNext(); )
/* */ {
/* 1740 */ JDBCCMPFieldMetaData fkFieldMetaData = (JDBCCMPFieldMetaData)i.next();
/* 1741 */ JDBCCMP2xFieldBridge relatedPKField = (JDBCCMP2xFieldBridge)this.relatedEntity.getFieldByName(fkFieldMetaData.getFieldName());
/* */
/* 1745 */ String fkColumnName = fkFieldMetaData.getColumnName();
/* 1746 */ JDBCCMP2xFieldBridge fkField = null;
/* */
/* 1749 */ JDBCFieldBridge[] tableFields = this.entity.getTableFields();
/* 1750 */ for (int tableInd = 0; (tableInd < tableFields.length) && (fkField == null); tableInd++)
/* */ {
/* 1752 */ JDBCCMP2xFieldBridge cmpField = (JDBCCMP2xFieldBridge)tableFields[tableInd];
/* 1753 */ if (!fkColumnName.equals(cmpField.getColumnName()))
/* */ continue;
/* 1755 */ this.hasFKFieldsMappedToCMPFields = true;
/* */
/* 1758 */ fkField = new JDBCCMP2xFieldBridge((JDBCStoreManager)cmpField.getManager(), relatedPKField.getFieldName(), relatedPKField.getFieldType(), cmpField.getJDBCType(), relatedPKField.isReadOnly(), relatedPKField.getReadTimeOut(), relatedPKField.getPrimaryKeyClass(), relatedPKField.getPrimaryKeyField(), cmpField, this, fkColumnName);
/* */
/* 1770 */ if (!cmpField.isPrimaryKeyMember())
/* */ continue;
/* 1772 */ this.relatedPKFieldsByMyPKFields.put(cmpField, relatedPKField);
/* */ }
/* */
/* 1778 */ if (fkField == null)
/* */ {
/* 1780 */ fkField = new JDBCCMP2xFieldBridge(this.manager, fkFieldMetaData, this.manager.getJDBCTypeFactory().getJDBCType(fkFieldMetaData));
/* */ }
/* */
/* 1785 */ fkFieldsByRelatedPKFields.put(relatedPKField, fkField);
/* 1786 */ this.relatedPKFieldsByMyFKFields.put(fkField, relatedPKField);
/* */ }
/* */
/* 1792 */ if (fkFieldsByRelatedPKFields.size() > 0)
/* */ {
/* 1794 */ JDBCFieldBridge[] relatedPKFields = this.relatedEntity.getPrimaryKeyFields();
/* 1795 */ List fkList = new ArrayList(relatedPKFields.length);
/* 1796 */ for (int i = 0; i < relatedPKFields.length; i++)
/* */ {
/* 1798 */ JDBCCMPFieldBridge fkField = (JDBCCMPFieldBridge)fkFieldsByRelatedPKFields.remove(relatedPKFields[i]);
/* 1799 */ fkList.add(fkField);
/* */ }
/* 1801 */ this.foreignKeyFields = ((JDBCCMP2xFieldBridge[])(JDBCCMP2xFieldBridge[])fkList.toArray(new JDBCCMP2xFieldBridge[fkList.size()]));
/* */ }
/* */ else
/* */ {
/* 1805 */ this.foreignKeyFields = null;
/* */ }
/* */
/* 1809 */ this.allFKFieldsMappedToPKFields = ((this.relatedPKFieldsByMyPKFields.size() > 0) && (this.relatedPKFieldsByMyPKFields.size() == this.foreignKeyFields.length));
/* */
/* 1812 */ if (this.foreignKeyFields != null)
/* */ {
/* 1814 */ this.jdbcType = new CMRJDBCType(Arrays.asList(this.foreignKeyFields), null);
/* */ }
/* */ }
/* */
/* */ private Transaction getTransaction()
/* */ {
/* */ try
/* */ {
/* 1822 */ EntityContainer container = getJDBCStoreManager().getContainer();
/* 1823 */ TransactionManager tm = container.getTransactionManager();
/* 1824 */ return tm.getTransaction();
/* */ }
/* */ catch (SystemException e) {
/* */ }
/* 1828 */ throw new EJBException("Error getting transaction from the transaction manager", e);
/* */ }
/* */
/* */ private Map getRelatedPKsWaitingForMyPK()
/* */ {
/* 1837 */ return (Map)this.relatedPKValuesWaitingForMyPK.get();
/* */ }
/* */
/* */ private RelationDataManager initRelationManager(JDBCCMRFieldBridge relatedField)
/* */ {
/* 1842 */ if (this.relationManager == null)
/* */ {
/* 1844 */ if (this.metadata.getRelationMetaData().isTableMappingStyle())
/* */ {
/* 1846 */ this.relationManager = new M2MRelationManager(this, relatedField);
/* */ }
/* */ else
/* */ {
/* 1850 */ this.relationManager = EMPTY_RELATION_MANAGER;
/* */ }
/* */ }
/* 1853 */ return this.relationManager;
/* */ }
/* */
/* */ private Object getRelatedPrimaryKey(Object localObject)
/* */ {
/* 1859 */ if (this.relatedEntity.getLocalInterface().isAssignableFrom(localObject.getClass()))
/* */ {
/* 1861 */ EJBLocalObject local = (EJBLocalObject)localObject;
/* */ try
/* */ {
/* 1864 */ relatedId = local.getPrimaryKey();
/* */ }
/* */ catch (NoSuchObjectLocalException e)
/* */ {
/* */ Object relatedId;
/* 1868 */ throw new IllegalArgumentException(e.getMessage());
/* */ }
/* */
/* */ }
/* */ else
/* */ {
/* 1880 */ throw new IllegalArgumentException("The values of this field must be of type " + this.relatedEntity.getLocalInterface().getName());
/* */ }
/* */ Object relatedId;
/* 1883 */ return relatedId;
/* */ }
/* */
/* */ public String toString()
/* */ {
/* 1888 */ return this.entity.getEntityName() + '.' + getFieldName();
/* */ }
/* */
/* */ public static class M2MRelationManager
/* */ implements JDBCCMRFieldBridge.RelationDataManager
/* */ {
/* */ private final JDBCCMRFieldBridge leftField;
/* */ private final JDBCCMRFieldBridge rightField;
/* 2287 */ private final TransactionLocal relationData = new TransactionLocal()
/* */ {
/* */ protected Object initialValue()
/* */ {
/* 2291 */ return new RelationData(JDBCCMRFieldBridge.this, JDBCCMRFieldBridge.this);
/* */ }
/* 2287 */ };
/* */
/* */ public M2MRelationManager(JDBCCMRFieldBridge leftField, JDBCCMRFieldBridge rightField)
/* */ {
/* 2297 */ this.leftField = leftField;
/* 2298 */ this.rightField = rightField;
/* */ }
/* */
/* */ public void addRelation(JDBCCMRFieldBridge field, Object id, JDBCCMRFieldBridge relatedField, Object relatedId)
/* */ {
/* 2306 */ RelationData local = getRelationData();
/* 2307 */ local.addRelation(field, id, relatedField, relatedId);
/* */ }
/* */
/* */ public void removeRelation(JDBCCMRFieldBridge field, Object id, JDBCCMRFieldBridge relatedField, Object relatedId)
/* */ {
/* 2315 */ RelationData local = getRelationData();
/* 2316 */ local.removeRelation(field, id, relatedField, relatedId);
/* */ }
/* */
/* */ public boolean isDirty()
/* */ {
/* 2321 */ RelationData local = getRelationData();
/* 2322 */ return local.isDirty();
/* */ }
/* */
/* */ public RelationData getRelationData()
/* */ {
/* 2327 */ RelationData local = (RelationData)this.relationData.get();
/* 2328 */ return local;
/* */ }
/* */ }
/* */
/* */ public static abstract interface RelationDataManager
/* */ {
/* */ public abstract void addRelation(JDBCCMRFieldBridge paramJDBCCMRFieldBridge1, Object paramObject1, JDBCCMRFieldBridge paramJDBCCMRFieldBridge2, Object paramObject2);
/* */
/* */ public abstract void removeRelation(JDBCCMRFieldBridge paramJDBCCMRFieldBridge1, Object paramObject1, JDBCCMRFieldBridge paramJDBCCMRFieldBridge2, Object paramObject2);
/* */
/* */ public abstract boolean isDirty();
/* */
/* */ public abstract RelationData getRelationData();
/* */ }
/* */
/* */ private static final class TxSynchronization
/* */ implements Synchronization
/* */ {
/* */ private final WeakReference fieldStateRef;
/* */
/* */ private TxSynchronization(JDBCCMRFieldBridge.FieldState fieldState)
/* */ {
/* 2221 */ if (fieldState == null)
/* */ {
/* 2223 */ throw new IllegalArgumentException("fieldState is null");
/* */ }
/* 2225 */ this.fieldStateRef = new WeakReference(fieldState);
/* */ }
/* */
/* */ public void beforeCompletion()
/* */ {
/* 2234 */ JDBCCMRFieldBridge.FieldState fieldState = (JDBCCMRFieldBridge.FieldState)this.fieldStateRef.get();
/* 2235 */ if (fieldState != null)
/* */ {
/* 2237 */ fieldState.invalidate();
/* */ }
/* */ }
/* */
/* */ public void afterCompletion(int status)
/* */ {
/* */ }
/* */ }
/* */
/* */ private static final class CMRJDBCType
/* */ implements JDBCType
/* */ {
/* */ private final String[] columnNames;
/* */ private final Class[] javaTypes;
/* */ private final int[] jdbcTypes;
/* */ private final String[] sqlTypes;
/* */ private final boolean[] notNull;
/* */
/* */ private CMRJDBCType(List fields)
/* */ {
/* 2117 */ List columnNamesList = new ArrayList();
/* 2118 */ List javaTypesList = new ArrayList();
/* 2119 */ List jdbcTypesList = new ArrayList();
/* 2120 */ List sqlTypesList = new ArrayList();
/* 2121 */ List notNullList = new ArrayList();
/* */
/* 2123 */ for (Iterator iter = fields.iterator(); iter.hasNext(); )
/* */ {
/* 2125 */ JDBCCMPFieldBridge field = (JDBCCMPFieldBridge)iter.next();
/* 2126 */ JDBCType type = field.getJDBCType();
/* 2127 */ for (int i = 0; i < type.getColumnNames().length; i++)
/* */ {
/* 2129 */ columnNamesList.add(type.getColumnNames()[i]);
/* 2130 */ javaTypesList.add(type.getJavaTypes()[i]);
/* 2131 */ jdbcTypesList.add(new Integer(type.getJDBCTypes()[i]));
/* 2132 */ sqlTypesList.add(type.getSQLTypes()[i]);
/* 2133 */ notNullList.add(new Boolean(type.getNotNull()[i]));
/* */ }
/* */ }
/* 2136 */ this.columnNames = ((String[])(String[])columnNamesList.toArray(new String[columnNamesList.size()]));
/* 2137 */ this.javaTypes = ((Class[])(Class[])javaTypesList.toArray(new Class[javaTypesList.size()]));
/* 2138 */ this.sqlTypes = ((String[])(String[])sqlTypesList.toArray(new String[sqlTypesList.size()]));
/* */
/* 2140 */ this.jdbcTypes = new int[jdbcTypesList.size()];
/* 2141 */ for (int i = 0; i < this.jdbcTypes.length; i++)
/* */ {
/* 2143 */ this.jdbcTypes[i] = ((Integer)jdbcTypesList.get(i)).intValue();
/* */ }
/* */
/* 2146 */ this.notNull = new boolean[notNullList.size()];
/* 2147 */ for (int i = 0; i < this.notNull.length; i++)
/* */ {
/* 2149 */ this.notNull[i] = ((Boolean)notNullList.get(i)).booleanValue();
/* */ }
/* */ }
/* */
/* */ public String[] getColumnNames()
/* */ {
/* 2155 */ return this.columnNames;
/* */ }
/* */
/* */ public Class[] getJavaTypes()
/* */ {
/* 2160 */ return this.javaTypes;
/* */ }
/* */
/* */ public int[] getJDBCTypes()
/* */ {
/* 2165 */ return this.jdbcTypes;
/* */ }
/* */
/* */ public String[] getSQLTypes()
/* */ {
/* 2170 */ return this.sqlTypes;
/* */ }
/* */
/* */ public boolean[] getNotNull()
/* */ {
/* 2175 */ return this.notNull;
/* */ }
/* */
/* */ public boolean[] getAutoIncrement()
/* */ {
/* 2180 */ return new boolean[] { false };
/* */ }
/* */
/* */ public Object getColumnValue(int index, Object value)
/* */ {
/* 2185 */ throw new UnsupportedOperationException();
/* */ }
/* */
/* */ public Object setColumnValue(int index, Object value, Object columnValue)
/* */ {
/* 2190 */ throw new UnsupportedOperationException();
/* */ }
/* */
/* */ public boolean hasMapper()
/* */ {
/* 2195 */ throw new UnsupportedOperationException("hasMapper is not implemented.");
/* */ }
/* */
/* */ public boolean isSearchable()
/* */ {
/* 2200 */ throw new UnsupportedOperationException("isSearchable is not implemented.");
/* */ }
/* */
/* */ public JDBCResultSetReader[] getResultSetReaders()
/* */ {
/* 2206 */ throw new UnsupportedOperationException();
/* */ }
/* */
/* */ public JDBCParameterSetter[] getParameterSetter()
/* */ {
/* 2211 */ throw new UnsupportedOperationException();
/* */ }
/* */ }
/* */
/* */ private final class FieldState
/* */ {
/* */ private final EntityEnterpriseContext ctx;
/* 1894 */ private List[] setHandle = new List[1];
/* */ private Set addedRelations;
/* */ private Set removedRelations;
/* */ private Set relationSet;
/* 1898 */ private boolean isLoaded = false;
/* 1899 */ private final long lastRead = -1L;
/* */ private boolean changed;
/* */
/* */ public FieldState(EntityEnterpriseContext ctx)
/* */ {
/* 1905 */ this.ctx = ctx;
/* 1906 */ this.setHandle[0] = new ArrayList();
/* */ }
/* */
/* */ public List getValue()
/* */ {
/* 1914 */ if (!this.isLoaded)
/* */ {
/* 1916 */ throw new EJBException("CMR field value not loaded yet");
/* */ }
/* 1918 */ return Collections.unmodifiableList(this.setHandle[0]);
/* */ }
/* */
/* */ public boolean isLoaded()
/* */ {
/* 1926 */ return this.isLoaded;
/* */ }
/* */
/* */ public long getLastRead()
/* */ {
/* 1934 */ return -1L;
/* */ }
/* */
/* */ public void addRelation(Object fk)
/* */ {
/* 1942 */ if (this.isLoaded)
/* */ {
/* 1944 */ this.setHandle[0].add(fk);
/* */ }
/* */ else
/* */ {
/* 1948 */ if (this.removedRelations == null)
/* */ {
/* 1950 */ this.removedRelations = new HashSet();
/* 1951 */ this.addedRelations = new HashSet();
/* */ }
/* 1953 */ this.removedRelations.remove(fk);
/* 1954 */ this.addedRelations.add(fk);
/* */ }
/* */
/* 1957 */ this.changed = true;
/* */ }
/* */
/* */ public void removeRelation(Object fk)
/* */ {
/* 1965 */ if (this.isLoaded)
/* */ {
/* 1967 */ this.setHandle[0].remove(fk);
/* */ }
/* */ else
/* */ {
/* 1971 */ if (this.removedRelations == null)
/* */ {
/* 1973 */ this.removedRelations = new HashSet();
/* 1974 */ this.addedRelations = new HashSet();
/* */ }
/* 1976 */ this.addedRelations.remove(fk);
/* 1977 */ this.removedRelations.add(fk);
/* */ }
/* */
/* 1980 */ this.changed = true;
/* */ }
/* */
/* */ public void loadRelations(Collection values)
/* */ {
/* 1989 */ if (this.isLoaded)
/* */ {
/* 1991 */ throw new EJBException("CMR field value is already loaded");
/* */ }
/* */
/* 1995 */ this.setHandle[0].clear();
/* */
/* 1998 */ this.setHandle[0].addAll(values);
/* */
/* 2000 */ if (this.removedRelations != null)
/* */ {
/* 2003 */ this.setHandle[0].removeAll(this.removedRelations);
/* 2004 */ this.removedRelations = null;
/* */ }
/* */
/* 2007 */ if (this.addedRelations != null)
/* */ {
/* 2011 */ this.setHandle[0].removeAll(this.addedRelations);
/* 2012 */ this.setHandle[0].addAll(this.addedRelations);
/* 2013 */ this.addedRelations = null;
/* */ }
/* */
/* 2017 */ this.isLoaded = true;
/* */ }
/* */
/* */ public Set getRelationSet()
/* */ {
/* 2025 */ if (!this.isLoaded)
/* */ {
/* 2027 */ throw new EJBException("CMR field value not loaded yet");
/* */ }
/* */
/* 2030 */ if (this.ctx.isReadOnly())
/* */ {
/* 2033 */ return new RelationSet(JDBCCMRFieldBridge.this, this.ctx, new List[] { new ArrayList(this.setHandle[0]) }, true);
/* */ }
/* */
/* 2040 */ if (this.relationSet != null)
/* */ {
/* 2042 */ return this.relationSet;
/* */ }
/* */
/* */ try
/* */ {
/* 2049 */ EntityContainer container = JDBCCMRFieldBridge.this.getJDBCStoreManager().getContainer();
/* 2050 */ TransactionManager tm = container.getTransactionManager();
/* 2051 */ Transaction tx = tm.getTransaction();
/* */
/* 2054 */ if ((tx != null) && ((tx.getStatus() == 0) || (tx.getStatus() == 7)))
/* */ {
/* 2057 */ this.relationSet = new RelationSet(JDBCCMRFieldBridge.this, this.ctx, this.setHandle, false);
/* 2058 */ JDBCCMRFieldBridge.TxSynchronization sync = new JDBCCMRFieldBridge.TxSynchronization(this, null);
/* 2059 */ tx.registerSynchronization(sync);
/* */ }
/* */ else
/* */ {
/* 2064 */ this.relationSet = new RelationSet(JDBCCMRFieldBridge.this, this.ctx, new List[1], false);
/* */ }
/* */
/* 2067 */ return this.relationSet;
/* */ }
/* */ catch (SystemException e)
/* */ {
/* 2071 */ throw new EJBException("Error while creating RelationSet", e);
/* */ }
/* */ catch (RollbackException e) {
/* */ }
/* 2075 */ throw new EJBException("Error while creating RelationSet", e);
/* */ }
/* */
/* */ public void invalidate()
/* */ {
/* 2088 */ List currentList = null;
/* 2089 */ if ((this.setHandle != null) && (this.setHandle.length > 0))
/* */ {
/* 2091 */ currentList = this.setHandle[0];
/* 2092 */ this.setHandle[0] = null;
/* */ }
/* 2094 */ this.setHandle = new List[1];
/* 2095 */ this.setHandle[0] = currentList;
/* */
/* 2097 */ this.relationSet = null;
/* 2098 */ this.changed = false;
/* */ }
/* */
/* */ public boolean isChanged()
/* */ {
/* 2103 */ return this.changed;
/* */ }
/* */ }
/* */ }
/* Location: /home/mnovotny/projects/EMBEDDED_JBOSS_BETA3_COMMUNITY/embedded/output/lib/embedded-jboss/lib/jboss-embedded-all.jar
* Qualified Name: org.jboss.ejb.plugins.cmp.jdbc.bridge.JDBCCMRFieldBridge
* JD-Core Version: 0.6.0
*/