Source Code Cross Referenced for JDBCCMRFieldBridge2.java in  » EJB-Server-JBoss-4.2.1 » server » org » jboss » ejb » plugins » cmp » jdbc2 » bridge » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » EJB Server JBoss 4.2.1 » server » org.jboss.ejb.plugins.cmp.jdbc2.bridge 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * JBoss, Home of Professional Open Source.
0003:         * Copyright 2006, Red Hat Middleware LLC, and individual contributors
0004:         * as indicated by the @author tags. See the copyright.txt file in the
0005:         * distribution for a full listing of individual contributors.
0006:         *
0007:         * This is free software; you can redistribute it and/or modify it
0008:         * under the terms of the GNU Lesser General Public License as
0009:         * published by the Free Software Foundation; either version 2.1 of
0010:         * the License, or (at your option) any later version.
0011:         *
0012:         * This software is distributed in the hope that it will be useful,
0013:         * but WITHOUT ANY WARRANTY; without even the implied warranty of
0014:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
0015:         * Lesser General Public License for more details.
0016:         *
0017:         * You should have received a copy of the GNU Lesser General Public
0018:         * License along with this software; if not, write to the Free
0019:         * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
0020:         * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
0021:         */
0022:        package org.jboss.ejb.plugins.cmp.jdbc2.bridge;
0023:
0024:        import org.jboss.ejb.plugins.cmp.bridge.EntityBridge;
0025:        import org.jboss.ejb.plugins.cmp.bridge.FieldBridge;
0026:        import org.jboss.ejb.plugins.cmp.jdbc2.JDBCStoreManager2;
0027:        import org.jboss.ejb.plugins.cmp.jdbc2.schema.EntityTable;
0028:        import org.jboss.ejb.plugins.cmp.jdbc2.schema.RelationTable;
0029:        import org.jboss.ejb.plugins.cmp.jdbc2.schema.Cache;
0030:        import org.jboss.ejb.plugins.cmp.jdbc2.PersistentContext;
0031:        import org.jboss.ejb.plugins.cmp.jdbc.metadata.JDBCRelationshipRoleMetaData;
0032:        import org.jboss.ejb.plugins.cmp.jdbc.metadata.JDBCCMPFieldMetaData;
0033:        import org.jboss.ejb.plugins.cmp.jdbc.JDBCUtil;
0034:        import org.jboss.ejb.plugins.cmp.jdbc.JDBCType;
0035:        import org.jboss.ejb.plugins.cmp.jdbc.JDBCEntityPersistenceStore;
0036:        import org.jboss.ejb.plugins.cmp.jdbc.bridge.JDBCFieldBridge;
0037:        import org.jboss.ejb.plugins.cmp.jdbc.bridge.JDBCAbstractCMRFieldBridge;
0038:        import org.jboss.ejb.plugins.cmp.jdbc.bridge.JDBCAbstractEntityBridge;
0039:        import org.jboss.ejb.plugins.cmp.jdbc.bridge.CMRInvocation;
0040:        import org.jboss.ejb.plugins.cmp.jdbc.bridge.CMRMessage;
0041:        import org.jboss.ejb.plugins.cmp.ejbql.Catalog;
0042:        import org.jboss.ejb.plugins.lock.Entrancy;
0043:        import org.jboss.ejb.EntityEnterpriseContext;
0044:        import org.jboss.ejb.EntityContainer;
0045:        import org.jboss.ejb.EntityCache;
0046:        import org.jboss.ejb.LocalProxyFactory;
0047:        import org.jboss.deployment.DeploymentException;
0048:        import org.jboss.logging.Logger;
0049:        import org.jboss.security.SecurityAssociation;
0050:        import org.jboss.invocation.InvocationType;
0051:
0052:        import javax.ejb.EJBException;
0053:        import javax.ejb.EJBLocalObject;
0054:        import javax.ejb.RemoveException;
0055:        import javax.ejb.NoSuchObjectLocalException;
0056:        import javax.transaction.Transaction;
0057:        import javax.transaction.TransactionManager;
0058:        import javax.transaction.SystemException;
0059:        import java.util.Collection;
0060:        import java.util.List;
0061:        import java.util.ArrayList;
0062:        import java.util.Map;
0063:        import java.util.HashMap;
0064:        import java.util.Iterator;
0065:        import java.util.Set;
0066:        import java.util.Collections;
0067:        import java.util.HashSet;
0068:        import java.util.ConcurrentModificationException;
0069:        import java.sql.PreparedStatement;
0070:        import java.sql.Connection;
0071:        import java.sql.ResultSet;
0072:        import java.sql.SQLException;
0073:        import java.lang.reflect.Array;
0074:        import java.security.AccessController;
0075:        import java.security.PrivilegedAction;
0076:        import java.security.Principal;
0077:
0078:        /**
0079:         * @author <a href="mailto:alex@jboss.org">Alexey Loubyansky</a>
0080:         * @version <tt>$Revision: 62071 $</tt>
0081:         */
0082:        public class JDBCCMRFieldBridge2 extends JDBCAbstractCMRFieldBridge {
0083:            private final JDBCRelationshipRoleMetaData metadata;
0084:            private final JDBCStoreManager2 manager;
0085:            private final JDBCEntityBridge2 entity;
0086:            private final int cmrIndex;
0087:            private final Logger log;
0088:
0089:            private JDBCEntityBridge2 relatedEntity;
0090:            private JDBCCMRFieldBridge2 relatedCMRField;
0091:            private EntityContainer relatedContainer;
0092:
0093:            private JDBCCMPFieldBridge2[] tableKeyFields;
0094:            private JDBCCMPFieldBridge2[] foreignKeyFields;
0095:            private JDBCCMPFieldBridge2[] relatedPKFields;
0096:
0097:            private CMRFieldLoader loader;
0098:            private RelationTable relationTable;
0099:
0100:            private EntityTable.ForeignKeyConstraint fkConstraint;
0101:
0102:            private final TransactionManager tm;
0103:
0104:            public JDBCCMRFieldBridge2(JDBCEntityBridge2 entityBridge,
0105:                    JDBCStoreManager2 manager,
0106:                    JDBCRelationshipRoleMetaData metadata) {
0107:                this .manager = manager;
0108:                this .entity = entityBridge;
0109:                this .metadata = metadata;
0110:                cmrIndex = entity.getNextCMRIndex();
0111:                tm = manager.getContainer().getTransactionManager();
0112:
0113:                log = Logger.getLogger(getClass().getName() + "."
0114:                        + entity.getEntityName() + "#" + getFieldName());
0115:            }
0116:
0117:            // Public
0118:
0119:            public void resolveRelationship() throws DeploymentException {
0120:                //
0121:                // Set handles to the related entity's container, cache, manager, and invoker
0122:                //
0123:
0124:                // Related Entity Name
0125:                String relatedEntityName = metadata.getRelatedRole()
0126:                        .getEntity().getName();
0127:
0128:                // Related Entity
0129:                Catalog catalog = (Catalog) manager
0130:                        .getApplicationData("CATALOG");
0131:                relatedEntity = (JDBCEntityBridge2) catalog
0132:                        .getEntityByEJBName(relatedEntityName);
0133:                if (relatedEntity == null) {
0134:                    throw new DeploymentException("Related entity not found: "
0135:                            + "entity=" + entity.getEntityName() + ", "
0136:                            + "cmrField=" + getFieldName() + ", "
0137:                            + "relatedEntity=" + relatedEntityName);
0138:                }
0139:
0140:                // Related CMR Field
0141:                JDBCCMRFieldBridge2[] cmrFields = (JDBCCMRFieldBridge2[]) relatedEntity
0142:                        .getCMRFields();
0143:                for (int i = 0; i < cmrFields.length; ++i) {
0144:                    JDBCCMRFieldBridge2 cmrField = cmrFields[i];
0145:                    if (metadata.getRelatedRole() == cmrField.getMetaData()) {
0146:                        relatedCMRField = cmrField;
0147:                        break;
0148:                    }
0149:                }
0150:
0151:                // if we didn't find the related CMR field throw an exception with a detailed message
0152:                if (relatedCMRField == null) {
0153:                    String message = "Related CMR field not found in "
0154:                            + relatedEntity.getEntityName()
0155:                            + " for relationship from ";
0156:
0157:                    message += entity.getEntityName() + ".";
0158:                    if (getFieldName() != null) {
0159:                        message += getFieldName();
0160:                    } else {
0161:                        message += "<no-field>";
0162:                    }
0163:
0164:                    message += " to ";
0165:                    message += relatedEntityName + ".";
0166:                    if (metadata.getRelatedRole().getCMRFieldName() != null) {
0167:                        message += metadata.getRelatedRole().getCMRFieldName();
0168:                    } else {
0169:                        message += "<no-field>";
0170:                    }
0171:
0172:                    throw new DeploymentException(message);
0173:                }
0174:
0175:                // Related Container
0176:                relatedContainer = relatedEntity.getContainer();
0177:
0178:                //
0179:                // Initialize the key fields
0180:                //
0181:                if (metadata.getRelationMetaData().isTableMappingStyle()) {
0182:                    // initialize relation table key fields
0183:                    Collection tableKeys = metadata.getKeyFields();
0184:                    List keyFieldsList = new ArrayList(tableKeys.size());
0185:
0186:                    // first phase is to create fk fields
0187:                    Map pkFieldsToFKFields = new HashMap(tableKeys.size());
0188:                    for (Iterator i = tableKeys.iterator(); i.hasNext();) {
0189:                        JDBCCMPFieldMetaData cmpFieldMetaData = (JDBCCMPFieldMetaData) i
0190:                                .next();
0191:                        FieldBridge pkField = entity
0192:                                .getFieldByName(cmpFieldMetaData.getFieldName());
0193:                        if (pkField == null) {
0194:                            throw new DeploymentException(
0195:                                    "Primary key not found for key-field "
0196:                                            + cmpFieldMetaData.getFieldName());
0197:                        }
0198:                        pkFieldsToFKFields.put(pkField,
0199:                                new JDBCCMPFieldBridge2(manager, entity,
0200:                                        cmpFieldMetaData, -1));
0201:                    }
0202:
0203:                    // second step is to order fk fields to match the order of pk fields
0204:                    JDBCFieldBridge[] pkFields = entity.getPrimaryKeyFields();
0205:                    for (int i = 0; i < pkFields.length; ++i) {
0206:                        Object fkField = pkFieldsToFKFields.get(pkFields[i]);
0207:                        if (fkField == null) {
0208:                            throw new DeploymentException("Primary key "
0209:                                    + pkFields[i].getFieldName()
0210:                                    + " is not mapped.");
0211:                        }
0212:                        keyFieldsList.add(fkField);
0213:                    }
0214:                    tableKeyFields = (JDBCCMPFieldBridge2[]) keyFieldsList
0215:                            .toArray(new JDBCCMPFieldBridge2[keyFieldsList
0216:                                    .size()]);
0217:                } else {
0218:                    initializeForeignKeyFields();
0219:                }
0220:            }
0221:
0222:            public void initLoader() throws DeploymentException {
0223:                if (metadata.getRelationMetaData().isTableMappingStyle()) {
0224:                    relationTable = relatedCMRField.getRelationTable();
0225:                    loader = new RelationTableLoader();
0226:                } else {
0227:                    if (foreignKeyFields != null) {
0228:                        loader = new ContextForeignKeyLoader();
0229:                    } else {
0230:                        loader = new ForeignKeyLoader();
0231:                    }
0232:                }
0233:            }
0234:
0235:            public JDBCRelationshipRoleMetaData getMetaData() {
0236:                return metadata;
0237:            }
0238:
0239:            public boolean removeRelatedId(EntityEnterpriseContext ctx,
0240:                    Object relatedId) {
0241:                FieldState state = getFieldState(ctx);
0242:                return state.removeRelatedId(ctx, relatedId);
0243:            }
0244:
0245:            public boolean addRelatedId(EntityEnterpriseContext ctx,
0246:                    Object relatedId) {
0247:                FieldState state = getFieldState(ctx);
0248:                return state.addRelatedId(ctx, relatedId);
0249:            }
0250:
0251:            public void remove(EntityEnterpriseContext ctx)
0252:                    throws RemoveException {
0253:                if (metadata.getRelatedRole().isCascadeDelete()) {
0254:                    FieldState state = getFieldState(ctx);
0255:                    state.cascadeDelete(ctx);
0256:                } else {
0257:                    destroyExistingRelationships(ctx);
0258:                }
0259:            }
0260:
0261:            public void destroyExistingRelationships(EntityEnterpriseContext ctx) {
0262:                FieldState state = getFieldState(ctx);
0263:                state.destroyExistingRelationships(ctx);
0264:            }
0265:
0266:            public JDBCFieldBridge[] getTableKeyFields() {
0267:                return tableKeyFields;
0268:            }
0269:
0270:            public JDBCEntityPersistenceStore getManager() {
0271:                return manager;
0272:            }
0273:
0274:            public boolean hasForeignKey() {
0275:                return foreignKeyFields != null;
0276:            }
0277:
0278:            public JDBCAbstractCMRFieldBridge getRelatedCMRField() {
0279:                return this .relatedCMRField;
0280:            }
0281:
0282:            public JDBCFieldBridge[] getForeignKeyFields() {
0283:                return foreignKeyFields;
0284:            }
0285:
0286:            public JDBCCMRFieldBridge2 getRelatedField() {
0287:                return relatedCMRField;
0288:            }
0289:
0290:            public JDBCAbstractEntityBridge getEntity() {
0291:                return entity;
0292:            }
0293:
0294:            public String getQualifiedTableName() {
0295:                return relationTable.getTableName();
0296:            }
0297:
0298:            public String getTableName() {
0299:                throw new UnsupportedOperationException();
0300:            }
0301:
0302:            // JDBCFieldBridge implementation
0303:
0304:            public JDBCType getJDBCType() {
0305:                throw new UnsupportedOperationException();
0306:            }
0307:
0308:            public boolean isPrimaryKeyMember() {
0309:                throw new UnsupportedOperationException();
0310:            }
0311:
0312:            public boolean isReadOnly() {
0313:                throw new UnsupportedOperationException();
0314:            }
0315:
0316:            public boolean isReadTimedOut(EntityEnterpriseContext ctx) {
0317:                throw new UnsupportedOperationException();
0318:            }
0319:
0320:            public boolean isLoaded(EntityEnterpriseContext ctx) {
0321:                throw new UnsupportedOperationException();
0322:            }
0323:
0324:            public void initInstance(EntityEnterpriseContext ctx) {
0325:                getFieldState(ctx).init();
0326:            }
0327:
0328:            public void resetPersistenceContext(EntityEnterpriseContext ctx) {
0329:                throw new UnsupportedOperationException();
0330:            }
0331:
0332:            public int setInstanceParameters(PreparedStatement ps,
0333:                    int parameterIndex, EntityEnterpriseContext ctx) {
0334:                throw new UnsupportedOperationException();
0335:            }
0336:
0337:            public Object getInstanceValue(EntityEnterpriseContext ctx) {
0338:                throw new UnsupportedOperationException();
0339:            }
0340:
0341:            public void setInstanceValue(EntityEnterpriseContext ctx,
0342:                    Object value) {
0343:                throw new UnsupportedOperationException();
0344:            }
0345:
0346:            public int loadInstanceResults(ResultSet rs, int parameterIndex,
0347:                    EntityEnterpriseContext ctx) {
0348:                throw new UnsupportedOperationException();
0349:            }
0350:
0351:            public int loadArgumentResults(ResultSet rs, int parameterIndex,
0352:                    Object[] argumentRef) {
0353:                throw new UnsupportedOperationException();
0354:            }
0355:
0356:            public boolean isDirty(EntityEnterpriseContext ctx) {
0357:                return getFieldState(ctx).isModified();
0358:            }
0359:
0360:            public void setClean(EntityEnterpriseContext ctx) {
0361:                throw new UnsupportedOperationException();
0362:            }
0363:
0364:            public boolean isCMPField() {
0365:                return false;
0366:            }
0367:
0368:            // CMRFieldBridge implementation
0369:
0370:            public String getFieldName() {
0371:                return metadata.getCMRFieldName();
0372:            }
0373:
0374:            public Object getValue(EntityEnterpriseContext ctx) {
0375:                FieldState state = getFieldState(ctx);
0376:                return state.getValue(ctx);
0377:            }
0378:
0379:            public void setValue(EntityEnterpriseContext ctx, Object value) {
0380:                FieldState state = getFieldState(ctx);
0381:                state.setValue(ctx, value);
0382:                state.cacheValue(ctx);
0383:            }
0384:
0385:            public boolean isSingleValued() {
0386:                return metadata.getRelatedRole().isMultiplicityOne();
0387:            }
0388:
0389:            public EntityBridge getRelatedEntity() {
0390:                return relatedEntity;
0391:            }
0392:
0393:            // Private
0394:
0395:            private void initializeForeignKeyFields()
0396:                    throws DeploymentException {
0397:                Collection foreignKeys = metadata.getRelatedRole()
0398:                        .getKeyFields();
0399:
0400:                // temporary map used later to write fk fields in special order
0401:                Map fkFieldsByRelatedPKFields = new HashMap();
0402:                for (Iterator i = foreignKeys.iterator(); i.hasNext();) {
0403:                    JDBCCMPFieldMetaData fkFieldMetaData = (JDBCCMPFieldMetaData) i
0404:                            .next();
0405:                    JDBCCMPFieldBridge2 relatedPKField = (JDBCCMPFieldBridge2) relatedEntity
0406:                            .getFieldByName(fkFieldMetaData.getFieldName());
0407:
0408:                    // now determine whether the fk is mapped to a pk column
0409:                    String fkColumnName = fkFieldMetaData.getColumnName();
0410:                    JDBCCMPFieldBridge2 fkField = null;
0411:
0412:                    // look among the CMP fields for the field with the same column name
0413:                    JDBCCMPFieldBridge2[] tableFields = (JDBCCMPFieldBridge2[]) entity
0414:                            .getTableFields();
0415:                    for (int tableInd = 0; tableInd < tableFields.length
0416:                            && fkField == null; ++tableInd) {
0417:                        JDBCCMPFieldBridge2 cmpField = tableFields[tableInd];
0418:                        if (fkColumnName.equals(cmpField.getColumnName())) {
0419:                            // construct the foreign key field
0420:                            fkField = new JDBCCMPFieldBridge2(cmpField,
0421:                                    relatedPKField);
0422:                            /*
0423:                               cmpField.getManager(), // this cmpField's manager
0424:                               relatedPKField.getFieldName(),
0425:                               relatedPKField.getFieldType(),
0426:                               cmpField.getJDBCType(), // this cmpField's jdbc type
0427:                               relatedPKField.isReadOnly(),
0428:                               relatedPKField.getReadTimeOut(),
0429:                               relatedPKField.getPrimaryKeyClass(),
0430:                               relatedPKField.getPrimaryKeyField(),
0431:                               cmpField, // CMP field I am mapped to
0432:                               this,
0433:                               fkColumnName
0434:                            );
0435:                             */
0436:                        }
0437:                    }
0438:
0439:                    // if the fk is not a part of pk then create a new field
0440:                    if (fkField == null) {
0441:                        fkField = entity.addTableField(fkFieldMetaData);
0442:                    }
0443:                    fkFieldsByRelatedPKFields.put(relatedPKField, fkField); // temporary map
0444:                }
0445:
0446:                // Note: this important to order the foreign key fields so that their order matches
0447:                // the order of related entity's pk fields in case of complex primary keys.
0448:                // The order is important in fk-constraint generation and in SELECT when loading
0449:                if (fkFieldsByRelatedPKFields.size() > 0) {
0450:                    JDBCFieldBridge[] pkFields = relatedEntity
0451:                            .getPrimaryKeyFields();
0452:                    List fkList = new ArrayList(pkFields.length);
0453:                    List relatedPKList = new ArrayList(pkFields.length);
0454:                    for (int i = 0; i < pkFields.length; ++i) {
0455:                        JDBCFieldBridge relatedPKField = pkFields[i];
0456:                        JDBCFieldBridge fkField = (JDBCCMPFieldBridge2) fkFieldsByRelatedPKFields
0457:                                .remove(relatedPKField);
0458:                        fkList.add(fkField);
0459:                        relatedPKList.add(relatedPKField);
0460:                    }
0461:                    foreignKeyFields = (JDBCCMPFieldBridge2[]) fkList
0462:                            .toArray(new JDBCCMPFieldBridge2[fkList.size()]);
0463:                    relatedPKFields = (JDBCCMPFieldBridge2[]) relatedPKList
0464:                            .toArray(new JDBCCMPFieldBridge2[relatedPKList
0465:                                    .size()]);
0466:
0467:                    if (metadata.hasForeignKeyConstraint()) {
0468:                        fkConstraint = entity.getTable().addFkConstraint(
0469:                                foreignKeyFields, relatedEntity.getTable());
0470:                    }
0471:                } else {
0472:                    foreignKeyFields = null;
0473:                    relatedPKFields = null;
0474:                }
0475:            }
0476:
0477:            private FieldState getFieldState(EntityEnterpriseContext ctx) {
0478:                PersistentContext pctx = (PersistentContext) ctx
0479:                        .getPersistenceContext();
0480:                FieldState state = pctx.getCMRState(cmrIndex);
0481:                if (state == null) {
0482:                    if (isSingleValued()) {
0483:                        state = new SingleValuedFieldState();
0484:                    } else {
0485:                        state = new CollectionValuedFieldState();
0486:                    }
0487:                    pctx.setCMRState(cmrIndex, state);
0488:                }
0489:                return state;
0490:            }
0491:
0492:            private void invokeRemoveRelatedId(Object myId, Object relatedId) {
0493:                try {
0494:                    Transaction tx = getTransaction();
0495:                    EntityCache instanceCache = (EntityCache) manager
0496:                            .getContainer().getInstanceCache();
0497:
0498:                    /*
0499:                    RelationInterceptor.RelationInvocation invocation =
0500:                       new RelationInterceptor.RelationInvocation(RelationInterceptor.CMRMessage.REMOVE_RELATED_ID);
0501:                    invocation.setId(instanceCache.createCacheKey(myId));
0502:                    invocation.setArguments(new Object[]{this, relatedId});
0503:                    invocation.setTransaction(tx);
0504:                    invocation.setPrincipal(SecurityAssociation.getPrincipal());
0505:                    invocation.setCredential(SecurityAssociation.getCredential());
0506:                    invocation.setType(InvocationType.LOCAL);
0507:                     */
0508:
0509:                    SecurityActions actions = SecurityActions.UTIL
0510:                            .getSecurityActions();
0511:
0512:                    CMRInvocation invocation = new CMRInvocation();
0513:                    invocation.setCmrMessage(CMRMessage.REMOVE_RELATION);
0514:                    invocation.setEntrancy(Entrancy.NON_ENTRANT);
0515:                    invocation.setId(instanceCache.createCacheKey(myId));
0516:                    invocation.setArguments(new Object[] { this , relatedId });
0517:                    invocation.setTransaction(tx);
0518:                    invocation.setPrincipal(actions.getPrincipal());
0519:                    invocation.setCredential(actions.getCredential());
0520:                    invocation.setType(InvocationType.LOCAL);
0521:
0522:                    manager.getContainer().invoke(invocation);
0523:                } catch (EJBException e) {
0524:                    throw e;
0525:                } catch (Exception e) {
0526:                    throw new EJBException("Error in invokeRemoveRelatedId()",
0527:                            e);
0528:                }
0529:            }
0530:
0531:            private void invokeAddRelatedId(Object myId, Object relatedId) {
0532:                try {
0533:                    Transaction tx = getTransaction();
0534:                    EntityCache instanceCache = (EntityCache) manager
0535:                            .getContainer().getInstanceCache();
0536:                    /*
0537:                    RelationInterceptor.RelationInvocation invocation =
0538:                       new RelationInterceptor.RelationInvocation(RelationInterceptor.CMRMessage.ADD_RELATED_ID);
0539:                    invocation.setId(instanceCache.createCacheKey(myId));
0540:                    invocation.setArguments(new Object[]{this, relatedId});
0541:                    invocation.setTransaction(tx);
0542:                    invocation.setPrincipal(SecurityAssociation.getPrincipal());
0543:                    invocation.setCredential(SecurityAssociation.getCredential());
0544:                    invocation.setType(InvocationType.LOCAL);
0545:                     */
0546:                    SecurityActions actions = SecurityActions.UTIL
0547:                            .getSecurityActions();
0548:
0549:                    CMRInvocation invocation = new CMRInvocation();
0550:                    invocation.setCmrMessage(CMRMessage.ADD_RELATION);
0551:                    invocation.setEntrancy(Entrancy.NON_ENTRANT);
0552:                    invocation.setId(instanceCache.createCacheKey(myId));
0553:                    invocation.setArguments(new Object[] { this , relatedId });
0554:                    invocation.setTransaction(tx);
0555:                    invocation.setPrincipal(actions.getPrincipal());
0556:                    invocation.setCredential(actions.getCredential());
0557:                    invocation.setType(InvocationType.LOCAL);
0558:
0559:                    manager.getContainer().invoke(invocation);
0560:                } catch (EJBException e) {
0561:                    throw e;
0562:                } catch (Exception e) {
0563:                    throw new EJBException("Error in invokeAddRelatedId()", e);
0564:                }
0565:            }
0566:
0567:            private Transaction getTransaction() throws SystemException {
0568:                return tm.getTransaction();
0569:            }
0570:
0571:            private RelationTable getRelationTable() throws DeploymentException {
0572:                if (relationTable == null) {
0573:                    relationTable = manager.getSchema().createRelationTable(
0574:                            this , relatedCMRField);
0575:                }
0576:                return relationTable;
0577:            }
0578:
0579:            private Object getPrimaryKey(Object o) {
0580:                if (o == null) {
0581:                    throw new IllegalArgumentException(
0582:                            "This implementation does not support null members.");
0583:                }
0584:
0585:                if (!relatedEntity.getLocalInterface().isInstance(o)) {
0586:                    throw new IllegalArgumentException(
0587:                            "Argument must be of type "
0588:                                    + entity.getLocalInterface().getName());
0589:                }
0590:
0591:                EJBLocalObject local = (EJBLocalObject) o;
0592:                try {
0593:                    return local.getPrimaryKey();
0594:                } catch (NoSuchObjectLocalException e) {
0595:                    throw new IllegalArgumentException(e.getMessage());
0596:                }
0597:            }
0598:
0599:            // Inner
0600:
0601:            public class SingleValuedFieldState implements  FieldState {
0602:                private boolean loaded;
0603:                private Object value;
0604:                private EJBLocalObject localObject;
0605:                private boolean modified;
0606:
0607:                public void init() {
0608:                    loaded = true;
0609:                }
0610:
0611:                public Object getValue(EntityEnterpriseContext ctx) {
0612:                    Object value = getLoadedValue(ctx);
0613:                    if (value == null) {
0614:                        localObject = null;
0615:                    } else if (localObject == null) {
0616:                        localObject = relatedContainer.getLocalProxyFactory()
0617:                                .getEntityEJBLocalObject(value);
0618:                    }
0619:                    return localObject;
0620:                }
0621:
0622:                public void setValue(EntityEnterpriseContext ctx, Object value) {
0623:                    if (value != null) {
0624:                        Object relatedId = getPrimaryKey(value);
0625:                        addRelatedId(ctx, relatedId);
0626:                        relatedCMRField.invokeAddRelatedId(relatedId, ctx
0627:                                .getId());
0628:                        localObject = (EJBLocalObject) value;
0629:                    } else {
0630:                        destroyExistingRelationships(ctx);
0631:                    }
0632:                }
0633:
0634:                public void cascadeDelete(EntityEnterpriseContext ctx)
0635:                        throws RemoveException {
0636:                    if (manager.registerCascadeDelete(ctx.getId(), ctx.getId())) {
0637:                        EJBLocalObject value = (EJBLocalObject) getValue(ctx);
0638:                        if (value != null) {
0639:                            changeValue(null);
0640:
0641:                            final Object relatedId = value.getPrimaryKey();
0642:                            final JDBCStoreManager2 relatedManager = (JDBCStoreManager2) relatedEntity
0643:                                    .getManager();
0644:
0645:                            if (!relatedManager.isCascadeDeleted(relatedId)) {
0646:                                value.remove();
0647:                            }
0648:                        }
0649:
0650:                        manager.unregisterCascadeDelete(ctx.getId());
0651:                    }
0652:                }
0653:
0654:                public void destroyExistingRelationships(
0655:                        EntityEnterpriseContext ctx) {
0656:                    Object value = getLoadedValue(ctx);
0657:                    if (value != null) {
0658:                        removeRelatedId(ctx, value);
0659:                        relatedCMRField.invokeRemoveRelatedId(value, ctx
0660:                                .getId());
0661:                    }
0662:                }
0663:
0664:                public boolean removeRelatedId(EntityEnterpriseContext ctx,
0665:                        Object relatedId) {
0666:                    if (hasForeignKey()) {
0667:                        getLoadedValue(ctx);
0668:                    }
0669:
0670:                    changeValue(null);
0671:                    loader.removeRelatedId(ctx, relatedId);
0672:
0673:                    cacheValue(ctx);
0674:
0675:                    modified = true;
0676:
0677:                    return true;
0678:                }
0679:
0680:                public boolean addRelatedId(EntityEnterpriseContext ctx,
0681:                        Object relatedId) {
0682:                    Object value = getLoadedValue(ctx);
0683:                    if (value != null) {
0684:                        relatedCMRField.invokeRemoveRelatedId(value, ctx
0685:                                .getId());
0686:                    }
0687:
0688:                    changeValue(relatedId);
0689:                    loader.addRelatedId(ctx, relatedId);
0690:
0691:                    cacheValue(ctx);
0692:
0693:                    modified = true;
0694:
0695:                    return true;
0696:                }
0697:
0698:                public void addLoadedPk(Object pk) {
0699:                    if (loaded) {
0700:                        throw new IllegalStateException(
0701:                                entity.getEntityName()
0702:                                        + "."
0703:                                        + getFieldName()
0704:                                        + " single-valued CMR field is already loaded. Check the database for consistancy. "
0705:                                        + " current value=" + value
0706:                                        + ", loaded value=" + pk);
0707:                    }
0708:
0709:                    changeValue(pk);
0710:                }
0711:
0712:                public Object loadFromCache(Object value) {
0713:                    if (value != null) {
0714:                        changeValue(NULL_VALUE == value ? null : value);
0715:                    }
0716:                    return value;
0717:                }
0718:
0719:                public Object getCachedValue() {
0720:                    return value == null ? NULL_VALUE : value;
0721:                }
0722:
0723:                public void cacheValue(EntityEnterpriseContext ctx) {
0724:                    PersistentContext pctx = (PersistentContext) ctx
0725:                            .getPersistenceContext();
0726:                    pctx.cacheRelations(cmrIndex, this );
0727:                }
0728:
0729:                public boolean isModified() {
0730:                    return modified;
0731:                }
0732:
0733:                // Private
0734:
0735:                private void changeValue(Object newValue) {
0736:                    this .value = newValue;
0737:                    this .localObject = null;
0738:                    loaded = true;
0739:                }
0740:
0741:                private Object getLoadedValue(EntityEnterpriseContext ctx) {
0742:                    if (!loaded) {
0743:                        PersistentContext pctx = (PersistentContext) ctx
0744:                                .getPersistenceContext();
0745:                        pctx.loadCachedRelations(cmrIndex, this );
0746:                        if (!loaded) {
0747:                            loader.load(ctx, this );
0748:                            loaded = true;
0749:                            cacheValue(ctx);
0750:                        }
0751:                    }
0752:                    return value;
0753:                }
0754:            }
0755:
0756:            public class CollectionValuedFieldState implements  FieldState {
0757:                private boolean loaded;
0758:                private Set value;
0759:                private CMRSet cmrSet;
0760:
0761:                private Set removedWhileNotLoaded;
0762:                private Set addedWhileNotLoaded;
0763:
0764:                private boolean modified;
0765:
0766:                public void init() {
0767:                    loaded = true;
0768:                    value = new HashSet();
0769:                }
0770:
0771:                public Object getValue(EntityEnterpriseContext ctx) {
0772:                    if (cmrSet == null) {
0773:                        cmrSet = new CMRSet(ctx, this );
0774:                    }
0775:                    return cmrSet;
0776:                }
0777:
0778:                public void setValue(EntityEnterpriseContext ctx, Object value) {
0779:                    if (value == null) {
0780:                        throw new IllegalArgumentException(
0781:                                "Can't set collection-valued CMR field to null: "
0782:                                        + entity.getEntityName() + "."
0783:                                        + getFieldName());
0784:                    }
0785:
0786:                    destroyExistingRelationships(ctx);
0787:
0788:                    Collection newValue = (Collection) value;
0789:                    if (!newValue.isEmpty()) {
0790:                        Set copy = new HashSet(newValue);
0791:                        for (Iterator iter = copy.iterator(); iter.hasNext();) {
0792:                            Object relatedId = getPrimaryKey(iter.next());
0793:                            addRelatedId(ctx, relatedId);
0794:                            relatedCMRField.invokeAddRelatedId(relatedId, ctx
0795:                                    .getId());
0796:                            loader.addRelatedId(ctx, relatedId);
0797:                        }
0798:                    }
0799:                }
0800:
0801:                public void cascadeDelete(EntityEnterpriseContext ctx)
0802:                        throws RemoveException {
0803:                    Collection value = (Collection) getValue(ctx);
0804:                    if (!value.isEmpty()) {
0805:                        EJBLocalObject[] locals = (EJBLocalObject[]) value
0806:                                .toArray();
0807:                        for (int i = 0; i < locals.length; ++i) {
0808:                            locals[i].remove();
0809:                        }
0810:                    }
0811:                }
0812:
0813:                public void destroyExistingRelationships(
0814:                        EntityEnterpriseContext ctx) {
0815:                    Set value = getLoadedValue(ctx);
0816:                    if (!value.isEmpty()) {
0817:                        Object[] copy = value.toArray();
0818:                        for (int i = 0; i < copy.length; ++i) {
0819:                            Object relatedId = copy[i];
0820:                            removeRelatedId(ctx, relatedId);
0821:                            relatedCMRField.invokeRemoveRelatedId(relatedId,
0822:                                    ctx.getId());
0823:                            loader.removeRelatedId(ctx, relatedId);
0824:                        }
0825:                    }
0826:                }
0827:
0828:                public boolean removeRelatedId(EntityEnterpriseContext ctx,
0829:                        Object relatedId) {
0830:                    boolean removed = false;
0831:                    if (loaded) {
0832:                        Set value = getLoadedValue(ctx);
0833:                        if (!value.isEmpty()) {
0834:                            removed = value.remove(relatedId);
0835:                        }
0836:                    } else {
0837:                        loadOnlyFromCache(ctx);
0838:                        if (loaded) {
0839:                            Set value = getLoadedValue(ctx);
0840:                            if (!value.isEmpty()) {
0841:                                removed = value.remove(relatedId);
0842:                            }
0843:                        } else {
0844:                            removed = removeWhileNotLoaded(relatedId);
0845:                        }
0846:                    }
0847:
0848:                    modified = true;
0849:
0850:                    if (removed) {
0851:                        ((PersistentContext) ctx.getPersistenceContext())
0852:                                .setDirtyRelations();
0853:                    }
0854:
0855:                    return removed;
0856:                }
0857:
0858:                public boolean addRelatedId(EntityEnterpriseContext ctx,
0859:                        Object relatedId) {
0860:                    boolean added;
0861:                    if (loaded) {
0862:                        Set value = getLoadedValue(ctx);
0863:                        added = value.add(relatedId);
0864:                    } else {
0865:                        loadOnlyFromCache(ctx);
0866:                        if (loaded) {
0867:                            Set value = getLoadedValue(ctx);
0868:                            added = value.add(relatedId);
0869:                        } else {
0870:                            added = addWhileNotLoaded(relatedId);
0871:                        }
0872:                    }
0873:
0874:                    modified = true;
0875:
0876:                    if (added) {
0877:                        ((PersistentContext) ctx.getPersistenceContext())
0878:                                .setDirtyRelations();
0879:                    }
0880:
0881:                    return added;
0882:                }
0883:
0884:                public void addLoadedPk(Object pk) {
0885:                    if (loaded) {
0886:                        throw new IllegalStateException(
0887:                                entity.getEntityName()
0888:                                        + "."
0889:                                        + getFieldName()
0890:                                        + " collection-valued CMR field is already loaded. Check the database for consistancy. "
0891:                                        + " current value=" + value
0892:                                        + ", loaded value=" + pk);
0893:                    }
0894:
0895:                    if (pk != null) {
0896:                        value.add(pk);
0897:                    }
0898:                }
0899:
0900:                public Object loadFromCache(Object value) {
0901:                    if (value != null) {
0902:                        value = this .value = new HashSet((Set) value);
0903:                        loaded = true;
0904:                    }
0905:                    return value;
0906:                }
0907:
0908:                public Object getCachedValue() {
0909:                    return value;
0910:                }
0911:
0912:                public void cacheValue(EntityEnterpriseContext ctx) {
0913:                    PersistentContext pctx = (PersistentContext) ctx
0914:                            .getPersistenceContext();
0915:                    pctx.cacheRelations(cmrIndex, this );
0916:                }
0917:
0918:                public boolean isModified() {
0919:                    return modified;
0920:                }
0921:
0922:                // Private
0923:
0924:                private Set getLoadedValue(EntityEnterpriseContext ctx) {
0925:                    if (!loaded) {
0926:                        loadOnlyFromCache(ctx);
0927:
0928:                        if (!loaded) {
0929:                            if (value == null || value == Collections.EMPTY_SET) {
0930:                                value = new HashSet();
0931:                            }
0932:
0933:                            loader.load(ctx, this );
0934:                            cacheValue(ctx);
0935:
0936:                            loaded = true;
0937:                        }
0938:
0939:                        if (addedWhileNotLoaded != null) {
0940:                            value.addAll(addedWhileNotLoaded);
0941:                            addedWhileNotLoaded = null;
0942:                        }
0943:
0944:                        if (removedWhileNotLoaded != null) {
0945:                            value.removeAll(removedWhileNotLoaded);
0946:                            removedWhileNotLoaded = null;
0947:                        }
0948:                    }
0949:                    return value;
0950:                }
0951:
0952:                private void loadOnlyFromCache(EntityEnterpriseContext ctx) {
0953:                    PersistentContext pctx = (PersistentContext) ctx
0954:                            .getPersistenceContext();
0955:                    if (pctx == null) {
0956:                        throw new EJBException(
0957:                                "Persistence context is not available! Make sure the CMR collection is accessed in the transaction it was obtained.");
0958:                    }
0959:                    pctx.loadCachedRelations(cmrIndex, this );
0960:                }
0961:
0962:                private boolean removeWhileNotLoaded(Object relatedId) {
0963:                    boolean removed = false;
0964:                    if (addedWhileNotLoaded != null) {
0965:                        removed = addedWhileNotLoaded.remove(relatedId);
0966:                    }
0967:
0968:                    if (!removed) {
0969:                        if (removedWhileNotLoaded == null) {
0970:                            removedWhileNotLoaded = new HashSet();
0971:                        }
0972:                        removed = removedWhileNotLoaded.add(relatedId);
0973:                    }
0974:
0975:                    if (log.isTraceEnabled() && removed) {
0976:                        log.trace("removed while not loaded: relatedId="
0977:                                + relatedId);
0978:                    }
0979:
0980:                    return removed;
0981:                }
0982:
0983:                private boolean addWhileNotLoaded(Object relatedId) {
0984:                    boolean added = false;
0985:                    if (removedWhileNotLoaded != null) {
0986:                        added = removedWhileNotLoaded.remove(relatedId);
0987:                    }
0988:
0989:                    if (!added) {
0990:                        if (addedWhileNotLoaded == null) {
0991:                            addedWhileNotLoaded = new HashSet();
0992:                        }
0993:                        added = addedWhileNotLoaded.add(relatedId);
0994:                    }
0995:
0996:                    if (log.isTraceEnabled() && added) {
0997:                        log.trace("added while not loaded: relatedId="
0998:                                + relatedId);
0999:                    }
1000:
1001:                    return added;
1002:                }
1003:            }
1004:
1005:            public interface FieldState extends Cache.CacheLoader {
1006:                Object NULL_VALUE = new Object();
1007:
1008:                void init();
1009:
1010:                Object getValue(EntityEnterpriseContext ctx);
1011:
1012:                void cascadeDelete(EntityEnterpriseContext ctx)
1013:                        throws RemoveException;
1014:
1015:                void destroyExistingRelationships(EntityEnterpriseContext ctx);
1016:
1017:                void setValue(EntityEnterpriseContext ctx, Object value);
1018:
1019:                boolean removeRelatedId(EntityEnterpriseContext ctx,
1020:                        Object relatedId);
1021:
1022:                boolean addRelatedId(EntityEnterpriseContext ctx, Object value);
1023:
1024:                void addLoadedPk(Object pk);
1025:
1026:                void cacheValue(EntityEnterpriseContext ctx);
1027:
1028:                boolean isModified();
1029:            }
1030:
1031:            private class RelationTableLoader implements  CMRFieldLoader {
1032:                private final String loadSql;
1033:
1034:                public RelationTableLoader() {
1035:                    StringBuffer sql = new StringBuffer();
1036:                    sql.append("select ");
1037:
1038:                    String relatedTable = relatedEntity.getQualifiedTableName();
1039:                    String relationTable = metadata.getRelationMetaData()
1040:                            .getDefaultTableName();
1041:
1042:                    relatedEntity.getTable().appendColumnNames(
1043:                            (JDBCCMPFieldBridge2[]) relatedEntity
1044:                                    .getTableFields(), relatedTable, sql);
1045:                    sql.append(" from ").append(relatedTable).append(
1046:                            " inner join ").append(relationTable)
1047:                            .append(" on ");
1048:
1049:                    JDBCCMPFieldBridge2[] pkFields = (JDBCCMPFieldBridge2[]) relatedEntity
1050:                            .getPrimaryKeyFields();
1051:                    for (int i = 0; i < pkFields.length; ++i) {
1052:                        if (i > 0) {
1053:                            sql.append(" and ");
1054:                        }
1055:
1056:                        sql.append(relatedTable).append('.').append(
1057:                                pkFields[i].getColumnName()).append('=')
1058:                                .append(relationTable).append('.').append(
1059:                                        relatedCMRField.tableKeyFields[i]
1060:                                                .getColumnName());
1061:                    }
1062:
1063:                    /*
1064:                    sql.append(" inner join ")
1065:                       .append(myTable)
1066:                       .append(" on ");
1067:
1068:                    String myTable = entity.getQualifiedTableName();
1069:                    pkFields = entity.getPrimaryKeyFields();
1070:                    for(int i = 0; i < pkFields.length; ++i)
1071:                    {
1072:                       if(i > 0)
1073:                       {
1074:                          sql.append(", ");
1075:                       }
1076:
1077:                       sql.append(myTable).append('.').append(pkFields[i].getColumnName())
1078:                          .append('=')
1079:                          .append(relationTable).append('.').append(tableKeyFields[i].getColumnName());
1080:                    }
1081:                     */
1082:
1083:                    sql.append(" where ");
1084:                    for (int i = 0; i < tableKeyFields.length; ++i) {
1085:                        if (i > 0) {
1086:                            sql.append(" and ");
1087:                        }
1088:
1089:                        sql.append(relationTable).append('.').append(
1090:                                tableKeyFields[i].getColumnName()).append("=?");
1091:                    }
1092:
1093:                    loadSql = sql.toString();
1094:
1095:                    if (log.isTraceEnabled()) {
1096:                        log.trace("load sql: " + loadSql);
1097:                    }
1098:                }
1099:
1100:                public void load(EntityEnterpriseContext ctx, FieldState state) {
1101:                    Object value;
1102:                    EntityTable relatedTable = relatedEntity.getTable();
1103:
1104:                    Connection con = null;
1105:                    PreparedStatement ps = null;
1106:                    ResultSet rs = null;
1107:                    try {
1108:                        if (log.isDebugEnabled()) {
1109:                            log.debug("executing: " + loadSql);
1110:                        }
1111:
1112:                        con = relatedTable.getDataSource().getConnection();
1113:                        ps = con.prepareStatement(loadSql);
1114:
1115:                        JDBCCMPFieldBridge2[] pkFields = (JDBCCMPFieldBridge2[]) entity
1116:                                .getPrimaryKeyFields();
1117:
1118:                        Object myPk = ctx.getId();
1119:                        int paramInd = 1;
1120:                        for (int i = 0; i < pkFields.length; ++i) {
1121:                            JDBCCMPFieldBridge2 pkField = pkFields[i];
1122:                            Object fieldValue = pkField
1123:                                    .getPrimaryKeyValue(myPk);
1124:
1125:                            JDBCCMPFieldBridge2 relatedFkField = tableKeyFields[i];
1126:                            relatedFkField.setArgumentParameters(ps,
1127:                                    paramInd++, fieldValue);
1128:                        }
1129:
1130:                        rs = ps.executeQuery();
1131:
1132:                        while (rs.next()) {
1133:                            value = relatedTable.loadRow(rs, false);
1134:                            state.addLoadedPk(value);
1135:                        }
1136:                    } catch (SQLException e) {
1137:                        log.error("Failed to load related role: ejb-name="
1138:                                + entity.getEntityName() + ", cmr-field="
1139:                                + getFieldName() + ": " + e.getMessage(), e);
1140:                        throw new EJBException(
1141:                                "Failed to load related role: ejb-name="
1142:                                        + entity.getEntityName()
1143:                                        + ", cmr-field=" + getFieldName()
1144:                                        + ": " + e.getMessage(), e);
1145:                    } finally {
1146:                        JDBCUtil.safeClose(rs);
1147:                        JDBCUtil.safeClose(ps);
1148:                        JDBCUtil.safeClose(con);
1149:                    }
1150:                }
1151:
1152:                public void removeRelatedId(EntityEnterpriseContext ctx,
1153:                        Object relatedId) {
1154:                    relationTable.removeRelation(JDBCCMRFieldBridge2.this , ctx
1155:                            .getId(), relatedCMRField, relatedId);
1156:                }
1157:
1158:                public void addRelatedId(EntityEnterpriseContext ctx,
1159:                        Object relatedId) {
1160:                    relationTable.addRelation(JDBCCMRFieldBridge2.this , ctx
1161:                            .getId(), relatedCMRField, relatedId);
1162:                }
1163:            }
1164:
1165:            private class ForeignKeyLoader implements  CMRFieldLoader {
1166:                private final String loadSql;
1167:
1168:                public ForeignKeyLoader() {
1169:                    StringBuffer sql = new StringBuffer();
1170:                    sql.append("select ");
1171:                    relatedEntity.getTable().appendColumnNames(
1172:                            (JDBCCMPFieldBridge2[]) relatedEntity
1173:                                    .getTableFields(), null, sql);
1174:                    sql.append(" from ").append(
1175:                            relatedEntity.getQualifiedTableName()).append(
1176:                            " where ");
1177:
1178:                    JDBCCMPFieldBridge2[] relatedFkFields = relatedCMRField.foreignKeyFields;
1179:                    sql.append(relatedFkFields[0].getColumnName()).append("=?");
1180:                    for (int i = 1; i < relatedFkFields.length; ++i) {
1181:                        JDBCCMPFieldBridge2 relatedFkField = relatedFkFields[i];
1182:                        sql.append(" and ").append(
1183:                                relatedFkField.getColumnName()).append("=?");
1184:                    }
1185:
1186:                    loadSql = sql.toString();
1187:
1188:                    if (log.isTraceEnabled()) {
1189:                        log.trace("load sql: " + loadSql);
1190:                    }
1191:                }
1192:
1193:                public void load(EntityEnterpriseContext ctx, FieldState state) {
1194:                    Object value;
1195:                    EntityTable relatedTable = relatedEntity.getTable();
1196:
1197:                    Connection con = null;
1198:                    PreparedStatement ps = null;
1199:                    ResultSet rs = null;
1200:                    try {
1201:                        if (log.isDebugEnabled()) {
1202:                            log.debug("executing: " + loadSql);
1203:                        }
1204:
1205:                        con = relatedTable.getDataSource().getConnection();
1206:                        ps = con.prepareStatement(loadSql);
1207:
1208:                        JDBCCMPFieldBridge2[] relatedFkFields = relatedCMRField.foreignKeyFields;
1209:                        JDBCCMPFieldBridge2[] myPkFields = relatedCMRField.relatedPKFields;
1210:
1211:                        Object myPk = ctx.getId();
1212:                        int paramInd = 1;
1213:                        for (int i = 0; i < relatedFkFields.length; ++i) {
1214:                            JDBCCMPFieldBridge2 myPkField = myPkFields[i];
1215:                            Object fieldValue = myPkField
1216:                                    .getPrimaryKeyValue(myPk);
1217:
1218:                            JDBCCMPFieldBridge2 relatedFkField = relatedFkFields[i];
1219:                            relatedFkField.setArgumentParameters(ps,
1220:                                    paramInd++, fieldValue);
1221:                        }
1222:
1223:                        rs = ps.executeQuery();
1224:
1225:                        while (rs.next()) {
1226:                            value = relatedTable.loadRow(rs, false);
1227:                            state.addLoadedPk(value);
1228:                        }
1229:                    } catch (SQLException e) {
1230:                        log.error("Failed to load related role: ejb-name="
1231:                                + entity.getEntityName() + ", cmr-field="
1232:                                + getFieldName() + ": " + e.getMessage(), e);
1233:                        throw new EJBException(
1234:                                "Failed to load related role: ejb-name="
1235:                                        + entity.getEntityName()
1236:                                        + ", cmr-field=" + getFieldName()
1237:                                        + ": " + e.getMessage(), e);
1238:                    } finally {
1239:                        JDBCUtil.safeClose(rs);
1240:                        JDBCUtil.safeClose(ps);
1241:                        JDBCUtil.safeClose(con);
1242:                    }
1243:                }
1244:
1245:                public void removeRelatedId(EntityEnterpriseContext ctx,
1246:                        Object relatedId) {
1247:                }
1248:
1249:                public void addRelatedId(EntityEnterpriseContext ctx,
1250:                        Object relatedId) {
1251:                }
1252:            }
1253:
1254:            private class ContextForeignKeyLoader implements  CMRFieldLoader {
1255:                public void load(EntityEnterpriseContext ctx, FieldState state) {
1256:                    Object relatedId = null;
1257:                    for (int i = 0; i < foreignKeyFields.length; ++i) {
1258:                        JDBCCMPFieldBridge2 fkField = foreignKeyFields[i];
1259:                        Object fkFieldValue = fkField.getValue(ctx);
1260:                        if (fkFieldValue == null) {
1261:                            break;
1262:                        }
1263:
1264:                        JDBCCMPFieldBridge2 relatedPKField = relatedPKFields[i];
1265:                        relatedId = relatedPKField.setPrimaryKeyValue(
1266:                                relatedId, fkFieldValue);
1267:                    }
1268:
1269:                    state.addLoadedPk(relatedId);
1270:                }
1271:
1272:                public void removeRelatedId(EntityEnterpriseContext ctx,
1273:                        Object relatedId) {
1274:                    for (int i = 0; i < foreignKeyFields.length; ++i) {
1275:                        foreignKeyFields[i].setValueInternal(ctx, null,
1276:                                fkConstraint == null);
1277:                    }
1278:
1279:                    if (fkConstraint != null) {
1280:                        PersistentContext pctx = (PersistentContext) ctx
1281:                                .getPersistenceContext();
1282:                        pctx.nullForeignKey(fkConstraint);
1283:                    }
1284:                }
1285:
1286:                public void addRelatedId(EntityEnterpriseContext ctx,
1287:                        Object relatedId) {
1288:                    final boolean markDirty = relatedId != null
1289:                            || fkConstraint == null;
1290:                    for (int i = 0; i < foreignKeyFields.length; ++i) {
1291:                        JDBCCMPFieldBridge2 relatedPKField = relatedPKFields[i];
1292:                        Object fieldValue = relatedPKField
1293:                                .getPrimaryKeyValue(relatedId);
1294:                        foreignKeyFields[i].setValueInternal(ctx, fieldValue,
1295:                                markDirty);
1296:                    }
1297:
1298:                    if (fkConstraint != null) {
1299:                        PersistentContext pctx = (PersistentContext) ctx
1300:                                .getPersistenceContext();
1301:                        if (relatedId == null) {
1302:                            pctx.nullForeignKey(fkConstraint);
1303:                        } else {
1304:                            pctx.nonNullForeignKey(fkConstraint);
1305:                        }
1306:                    }
1307:                }
1308:            }
1309:
1310:            private interface CMRFieldLoader {
1311:                void load(EntityEnterpriseContext ctx, FieldState state);
1312:
1313:                void removeRelatedId(EntityEnterpriseContext ctx,
1314:                        Object relatedId);
1315:
1316:                void addRelatedId(EntityEnterpriseContext ctx, Object relatedId);
1317:            }
1318:
1319:            private class CMRSet implements  Set {
1320:                private final EntityEnterpriseContext ctx;
1321:                private final CollectionValuedFieldState state;
1322:
1323:                public CMRSet(EntityEnterpriseContext ctx,
1324:                        CollectionValuedFieldState state) {
1325:                    this .ctx = ctx;
1326:                    this .state = state;
1327:                }
1328:
1329:                public int size() {
1330:                    return state.getLoadedValue(ctx).size();
1331:                }
1332:
1333:                public void clear() {
1334:                    destroyExistingRelationships(ctx);
1335:                }
1336:
1337:                public boolean isEmpty() {
1338:                    return size() == 0;
1339:                }
1340:
1341:                public boolean add(Object o) {
1342:                    Object relatedId = getPrimaryKey(o);
1343:                    boolean modified = addRelatedId(ctx, relatedId);
1344:
1345:                    if (modified) {
1346:                        relatedCMRField.invokeAddRelatedId(relatedId, ctx
1347:                                .getId());
1348:                        loader.addRelatedId(ctx, relatedId);
1349:                    }
1350:
1351:                    return modified;
1352:                }
1353:
1354:                public boolean contains(Object o) {
1355:                    Object pk = getPrimaryKey(o);
1356:                    return state.getLoadedValue(ctx).contains(pk);
1357:                }
1358:
1359:                public boolean remove(Object o) {
1360:                    Object relatedId = getPrimaryKey(o);
1361:                    return removeById(relatedId);
1362:                }
1363:
1364:                public boolean addAll(Collection c) {
1365:                    if (c == null || c.isEmpty()) {
1366:                        return false;
1367:                    }
1368:
1369:                    boolean modified = false;
1370:                    Object[] copy = c.toArray();
1371:                    for (int i = 0; i < copy.length; ++i) {
1372:                        // not modified || add()
1373:                        modified = add(copy[i]) || modified;
1374:                    }
1375:
1376:                    return modified;
1377:                }
1378:
1379:                public boolean containsAll(Collection c) {
1380:                    if (c == null || c.isEmpty()) {
1381:                        return true;
1382:                    }
1383:
1384:                    Set ids = argumentToIdSet(c);
1385:                    return state.getLoadedValue(ctx).containsAll(ids);
1386:                }
1387:
1388:                public boolean removeAll(Collection c) {
1389:                    if (c == null || c.isEmpty()) {
1390:                        return false;
1391:                    }
1392:
1393:                    boolean modified = false;
1394:                    Object[] copy = c.toArray();
1395:                    for (int i = 0; i < copy.length; ++i) {
1396:                        modified = remove(copy[i]) || modified;
1397:                    }
1398:
1399:                    return modified;
1400:                }
1401:
1402:                public boolean retainAll(Collection c) {
1403:                    Set value = state.getLoadedValue(ctx);
1404:                    if (c == null || c.isEmpty()) {
1405:                        if (value.isEmpty()) {
1406:                            return false;
1407:                        } else {
1408:                            clear();
1409:                        }
1410:                    }
1411:
1412:                    boolean modified = false;
1413:                    Set idSet = argumentToIdSet(c);
1414:                    Object[] valueCopy = value.toArray();
1415:                    for (int i = 0; i < valueCopy.length; ++i) {
1416:                        Object id = valueCopy[i];
1417:                        if (!idSet.contains(id)) {
1418:                            removeById(id);
1419:                            modified = true;
1420:                        }
1421:                    }
1422:
1423:                    return modified;
1424:                }
1425:
1426:                public Iterator iterator() {
1427:                    return new Iterator() {
1428:                        // todo get rid of copying
1429:                        private final Iterator idIter = new HashSet(state
1430:                                .getLoadedValue(ctx)).iterator();
1431:                        private Object curId;
1432:
1433:                        public void remove() {
1434:                            try {
1435:                                idIter.remove();
1436:                            } catch (ConcurrentModificationException e) {
1437:                                throw new IllegalStateException(e.getMessage());
1438:                            }
1439:
1440:                            removeById(curId);
1441:                        }
1442:
1443:                        public boolean hasNext() {
1444:                            try {
1445:                                return idIter.hasNext();
1446:                            } catch (ConcurrentModificationException e) {
1447:                                throw new IllegalStateException(e.getMessage());
1448:                            }
1449:                        }
1450:
1451:                        public Object next() {
1452:                            try {
1453:                                curId = idIter.next();
1454:                            } catch (ConcurrentModificationException e) {
1455:                                throw new IllegalStateException(e.getMessage());
1456:                            }
1457:
1458:                            return relatedContainer.getLocalProxyFactory()
1459:                                    .getEntityEJBLocalObject(curId);
1460:                        }
1461:                    };
1462:                }
1463:
1464:                public Object[] toArray() {
1465:                    Set value = state.getLoadedValue(ctx);
1466:
1467:                    Object[] result = (Object[]) Array.newInstance(
1468:                            relatedEntity.getLocalInterface(), value.size());
1469:
1470:                    LocalProxyFactory relatedPF = relatedContainer
1471:                            .getLocalProxyFactory();
1472:                    int i = 0;
1473:                    for (Iterator iter = value.iterator(); iter.hasNext();) {
1474:                        Object id = iter.next();
1475:                        result[i++] = relatedPF.getEntityEJBLocalObject(id);
1476:                    }
1477:
1478:                    return result;
1479:                }
1480:
1481:                public Object[] toArray(Object a[]) {
1482:                    Set value = state.getLoadedValue(ctx);
1483:                    if (a == null || a.length < value.size()) {
1484:                        a = (Object[]) Array.newInstance(entity
1485:                                .getLocalInterface(), value.size());
1486:                    }
1487:
1488:                    LocalProxyFactory relatedPF = relatedContainer
1489:                            .getLocalProxyFactory();
1490:                    int i = 0;
1491:                    for (Iterator iter = value.iterator(); iter.hasNext();) {
1492:                        Object id = iter.next();
1493:                        a[i++] = relatedPF.getEntityEJBLocalObject(id);
1494:                    }
1495:
1496:                    return a;
1497:                }
1498:
1499:                public String toString() {
1500:                    return state.getLoadedValue(ctx).toString();
1501:                }
1502:
1503:                // Private
1504:
1505:                private boolean removeById(Object relatedId) {
1506:                    boolean modified = removeRelatedId(ctx, relatedId);
1507:                    if (modified) {
1508:                        relatedCMRField.invokeRemoveRelatedId(relatedId, ctx
1509:                                .getId());
1510:                        loader.removeRelatedId(ctx, relatedId);
1511:                    }
1512:                    return modified;
1513:                }
1514:
1515:                private Set argumentToIdSet(Collection c) {
1516:                    Set ids = new HashSet();
1517:                    for (Iterator iter = c.iterator(); iter.hasNext();) {
1518:                        Object pk = getPrimaryKey(iter.next());
1519:                        ids.add(pk);
1520:                    }
1521:                    return ids;
1522:                }
1523:            }
1524:
1525:            interface SecurityActions {
1526:                class UTIL {
1527:                    static SecurityActions getSecurityActions() {
1528:                        return System.getSecurityManager() == null ? NON_PRIVILEGED
1529:                                : PRIVILEGED;
1530:                    }
1531:                }
1532:
1533:                SecurityActions NON_PRIVILEGED = new SecurityActions() {
1534:                    public Principal getPrincipal() {
1535:                        return SecurityAssociation.getPrincipal();
1536:                    }
1537:
1538:                    public Object getCredential() {
1539:                        return SecurityAssociation.getCredential();
1540:                    }
1541:                };
1542:
1543:                SecurityActions PRIVILEGED = new SecurityActions() {
1544:                    private final PrivilegedAction getPrincipalAction = new PrivilegedAction() {
1545:                        public Object run() {
1546:                            return SecurityAssociation.getPrincipal();
1547:                        }
1548:                    };
1549:
1550:                    private final PrivilegedAction getCredentialAction = new PrivilegedAction() {
1551:                        public Object run() {
1552:                            return SecurityAssociation.getCredential();
1553:                        }
1554:                    };
1555:
1556:                    public Principal getPrincipal() {
1557:                        return (Principal) AccessController
1558:                                .doPrivileged(getPrincipalAction);
1559:                    }
1560:
1561:                    public Object getCredential() {
1562:                        return AccessController
1563:                                .doPrivileged(getCredentialAction);
1564:                    }
1565:                };
1566:
1567:                Principal getPrincipal();
1568:
1569:                Object getCredential();
1570:            }
1571:        }
w___w__w_.__ja___v_a_2___s__.___c__o_m___ | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.