Source Code Cross Referenced for AbstractGenericQueryManager.java in  » Web-Framework » rife-1.6.1 » com » uwyn » rife » database » querymanagers » generic » 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 » Web Framework » rife 1.6.1 » com.uwyn.rife.database.querymanagers.generic 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * Copyright 2001-2007 Geert Bevin <gbevin[remove] at uwyn dot com> and
0003:         * JR Boyens <gnu-jrb[remove] at gmx dot net>
0004:         * Distributed under the terms of either:
0005:         * - the common development and distribution license (CDDL), v1.0; or
0006:         * - the GNU Lesser General Public License, v2.1 or later
0007:         * $Id: AbstractGenericQueryManager.java 3760 2007-05-14 13:37:33Z gbevin $
0008:         */
0009:        package com.uwyn.rife.database.querymanagers.generic;
0010:
0011:        import com.uwyn.rife.database.*;
0012:        import com.uwyn.rife.database.queries.*;
0013:        import com.uwyn.rife.site.*;
0014:        import java.util.*;
0015:
0016:        import com.uwyn.rife.database.exceptions.DatabaseException;
0017:        import com.uwyn.rife.database.exceptions.ExecutionErrorException;
0018:        import com.uwyn.rife.database.exceptions.MissingManyToOneColumnException;
0019:        import com.uwyn.rife.database.exceptions.MissingManyToOneTableException;
0020:        import com.uwyn.rife.database.querymanagers.generic.exceptions.IncompatibleValidationTypeException;
0021:        import com.uwyn.rife.database.querymanagers.generic.exceptions.UnsupportedManyToManyValueTypeException;
0022:        import com.uwyn.rife.database.querymanagers.generic.instrument.LazyLoadAccessorsBytecodeTransformer;
0023:        import com.uwyn.rife.tools.BeanUtils;
0024:        import com.uwyn.rife.tools.ClassUtils;
0025:        import com.uwyn.rife.tools.InnerClassException;
0026:        import com.uwyn.rife.tools.StringUtils;
0027:        import com.uwyn.rife.tools.TerracottaUtils;
0028:        import com.uwyn.rife.tools.exceptions.BeanUtilsException;
0029:        import java.lang.reflect.Field;
0030:        import java.lang.reflect.Method;
0031:
0032:        import static com.uwyn.rife.database.querymanagers.generic.GenericQueryManagerRelationalUtils.ensureSupportedManyToManyPropertyValueType;
0033:        import static com.uwyn.rife.database.querymanagers.generic.GenericQueryManagerRelationalUtils.ensureSupportedManyToOneAssociationPropertyValueType;
0034:        import static com.uwyn.rife.database.querymanagers.generic.GenericQueryManagerRelationalUtils.generateManyToManyJoinColumnName;
0035:        import static com.uwyn.rife.database.querymanagers.generic.GenericQueryManagerRelationalUtils.generateManyToManyJoinTableName;
0036:        import static com.uwyn.rife.database.querymanagers.generic.GenericQueryManagerRelationalUtils.generateManyToOneJoinColumnName;
0037:        import static com.uwyn.rife.database.querymanagers.generic.GenericQueryManagerRelationalUtils.obtainManyToManyDeclarations;
0038:        import static com.uwyn.rife.database.querymanagers.generic.GenericQueryManagerRelationalUtils.obtainManyToOneAssociationDeclarations;
0039:        import static com.uwyn.rife.database.querymanagers.generic.GenericQueryManagerRelationalUtils.obtainManyToOneDeclarations;
0040:        import static com.uwyn.rife.database.querymanagers.generic.GenericQueryManagerRelationalUtils.processManyToOneJoinColumns;
0041:        import static com.uwyn.rife.database.querymanagers.generic.GenericQueryManagerRelationalUtils.restoreManyToOneProperty;
0042:
0043:        public abstract class AbstractGenericQueryManager<BeanType> extends
0044:                DbQueryManager implements  GenericQueryManager<BeanType> {
0045:            protected Class<BeanType> mBaseClass = null;
0046:            protected String mPrimaryKey = null;
0047:            protected Method mGetPrimaryKeyMethod = null;
0048:            protected Method mSetPrimaryKeyMethod = null;
0049:            protected boolean mSparseIdentifier = false;
0050:
0051:            protected List<GenericQueryManagerListener> mListeners = null;
0052:
0053:            public AbstractGenericQueryManager(Datasource datasource,
0054:                    Class<BeanType> beanClass, String primaryKey)
0055:                    throws DatabaseException {
0056:                super (datasource);
0057:
0058:                mBaseClass = beanClass;
0059:                mPrimaryKey = primaryKey;
0060:                try {
0061:                    String capitalized_primary_key = StringUtils
0062:                            .capitalize(mPrimaryKey);
0063:                    mGetPrimaryKeyMethod = mBaseClass.getMethod("get"
0064:                            + capitalized_primary_key, (Class[]) null);
0065:                    try {
0066:                        mSetPrimaryKeyMethod = mBaseClass.getMethod("set"
0067:                                + capitalized_primary_key,
0068:                                new Class[] { int.class });
0069:                    } catch (NoSuchMethodException e) {
0070:                        try {
0071:                            mSetPrimaryKeyMethod = mBaseClass.getMethod("set"
0072:                                    + capitalized_primary_key,
0073:                                    new Class[] { Integer.class });
0074:                        } catch (NoSuchMethodException e2) {
0075:                            throw e;
0076:                        }
0077:                    }
0078:                } catch (Throwable e) {
0079:                    throw new DatabaseException(e);
0080:                }
0081:
0082:                Constrained constrained_bean = ConstrainedUtils
0083:                        .getConstrainedInstance(getBaseClass());
0084:                if (constrained_bean != null) {
0085:                    ConstrainedProperty constrained_property = constrained_bean
0086:                            .getConstrainedProperty(primaryKey);
0087:                    if (constrained_property != null) {
0088:                        mSparseIdentifier = constrained_property.isSparse();
0089:                    }
0090:                }
0091:            }
0092:
0093:            public Class getBaseClass() {
0094:                return mBaseClass;
0095:            }
0096:
0097:            public String getIdentifierName() {
0098:                return mPrimaryKey;
0099:            }
0100:
0101:            public int getIdentifierValue(BeanType bean)
0102:                    throws DatabaseException {
0103:                try {
0104:                    Integer id = (Integer) mGetPrimaryKeyMethod.invoke(bean,
0105:                            (Object[]) null);
0106:                    if (null == id) {
0107:                        return -1;
0108:                    }
0109:
0110:                    return id.intValue();
0111:                } catch (Throwable e) {
0112:                    throw new DatabaseException(e);
0113:                }
0114:            }
0115:
0116:            public boolean isIdentifierSparse() {
0117:                return mSparseIdentifier;
0118:            }
0119:
0120:            public void validate(Validated validated) {
0121:                // perform validation
0122:                if (validated != null && !(validated.getClass() == mBaseClass)) {
0123:                    throw new IncompatibleValidationTypeException(validated
0124:                            .getClass(), mBaseClass);
0125:                }
0126:
0127:                BeanType bean = (BeanType) validated;
0128:
0129:                // handle before callback
0130:                Callbacks callbacks = getCallbacks(bean);
0131:                if (callbacks != null && !callbacks.beforeValidate(bean)) {
0132:                    return;
0133:                }
0134:                _validateWithoutCallbacks(validated);
0135:
0136:                // handle after callback
0137:                if (callbacks != null) {
0138:                    callbacks.afterValidate(bean);
0139:                }
0140:            }
0141:
0142:            private static int getIdentifierValue(Object bean,
0143:                    String propertyName) throws DatabaseException {
0144:                try {
0145:                    Integer id = (Integer) BeanUtils.getPropertyValue(bean,
0146:                            propertyName);
0147:                    if (null == id) {
0148:                        return -1;
0149:                    }
0150:
0151:                    return id.intValue();
0152:                } catch (Throwable e) {
0153:                    throw new DatabaseException(e);
0154:                }
0155:            }
0156:
0157:            protected void _validateWithoutCallbacks(final Validated validated) {
0158:                if (null == validated) {
0159:                    return;
0160:                }
0161:
0162:                // handle constrained beans
0163:                final Constrained constrained = ConstrainedUtils
0164:                        .makeConstrainedInstance(validated);
0165:
0166:                if (constrained != null) {
0167:                    // check if the identifier exists or is still undefined (existing or
0168:                    // new entry)
0169:                    boolean identifier_exists = false;
0170:                    int identifier_value = getIdentifierValue((BeanType) validated);
0171:                    if (identifier_value >= 0) {
0172:                        identifier_exists = true;
0173:                    }
0174:
0175:                    // validate the many-to-one entities
0176:                    processManyToOneJoinColumns(this ,
0177:                            new ManyToOneJoinColumnProcessor() {
0178:                                public boolean processJoinColumn(
0179:                                        String columnName, String propertyName,
0180:                                        ManyToOneDeclaration declaration) {
0181:                                    Object property_value = null;
0182:                                    try {
0183:                                        property_value = BeanUtils
0184:                                                .getPropertyValue(constrained,
0185:                                                        propertyName);
0186:                                    } catch (BeanUtilsException e) {
0187:                                        throw new DatabaseException(e);
0188:                                    }
0189:
0190:                                    if (property_value != null) {
0191:                                        int identifier_value = getIdentifierValue(
0192:                                                property_value, declaration
0193:                                                        .getAssociationColumn());
0194:                                        if (identifier_value >= 0) {
0195:                                            if (!executeHasResultRows(declaration
0196:                                                    .getAssociationManager()
0197:                                                    .getRestoreQuery(
0198:                                                            identifier_value))) {
0199:                                                validated
0200:                                                        .addValidationError(new ValidationError.INVALID(
0201:                                                                propertyName));
0202:                                            }
0203:                                        }
0204:                                    }
0205:
0206:                                    return true;
0207:                                }
0208:                            });
0209:
0210:                    Map<String, ManyToOneAssociationDeclaration> manytoone_association_declarations = null;
0211:                    Map<String, Object> manytoone_association_property_values = null;
0212:                    boolean obtained_manytoone_association_declarations = false;
0213:
0214:                    Map<String, ManyToManyDeclaration> manytomany_declarations = null;
0215:                    Map<String, Object> manytomany_property_values = null;
0216:                    boolean obtained_manytomany_declarations = false;
0217:
0218:                    // handle invididual properties
0219:                    for (ConstrainedProperty property : (Collection<ConstrainedProperty>) constrained
0220:                            .getConstrainedProperties()) {
0221:                        // handle the uniqueness of invididual properties
0222:                        if (property.isUnique()) {
0223:                            Object property_value = null;
0224:                            try {
0225:                                property_value = BeanUtils
0226:                                        .getPropertyValue(constrained, property
0227:                                                .getPropertyName());
0228:                            } catch (BeanUtilsException e) {
0229:                                throw new DatabaseException(e);
0230:                            }
0231:
0232:                            if (property_value != null) {
0233:                                CountQuery count_query = getCountQuery().where(
0234:                                        property.getPropertyName(), "=",
0235:                                        property_value);
0236:                                if (identifier_exists) {
0237:                                    count_query.whereAnd(mPrimaryKey, "!=",
0238:                                            identifier_value);
0239:                                }
0240:
0241:                                if (count(count_query) > 0) {
0242:                                    validated
0243:                                            .addValidationError(new ValidationError.UNICITY(
0244:                                                    property.getPropertyName()));
0245:                                }
0246:                            }
0247:                        }
0248:
0249:                        // handle the manyToOne constraint that contain the identifier values
0250:                        if (property.hasManyToOne()) {
0251:                            Object property_value = null;
0252:                            try {
0253:                                property_value = BeanUtils
0254:                                        .getPropertyValue(constrained, property
0255:                                                .getPropertyName());
0256:                            } catch (BeanUtilsException e) {
0257:                                throw new DatabaseException(e);
0258:                            }
0259:
0260:                            if (property_value != null
0261:                                    && ClassUtils.isBasic(property_value
0262:                                            .getClass())) {
0263:                                ConstrainedProperty.ManyToOne many_to_one = property
0264:                                        .getManyToOne();
0265:
0266:                                if (null == many_to_one.getDerivedTable()) {
0267:                                    throw new MissingManyToOneTableException(
0268:                                            constrained.getClass(), property
0269:                                                    .getPropertyName());
0270:                                }
0271:
0272:                                if (null == many_to_one.getColumn()) {
0273:                                    throw new MissingManyToOneColumnException(
0274:                                            constrained.getClass(), property
0275:                                                    .getPropertyName());
0276:                                }
0277:
0278:                                if (!executeHasResultRows(new Select(
0279:                                        getDatasource()).from(
0280:                                        many_to_one.getDerivedTable()).where(
0281:                                        many_to_one.getColumn(), "=",
0282:                                        property_value))) {
0283:                                    validated
0284:                                            .addValidationError(new ValidationError.INVALID(
0285:                                                    property.getPropertyName()));
0286:                                }
0287:                            }
0288:                        }
0289:
0290:                        // handle the manyToOneAssociation constraint
0291:                        if (property.hasManyToOneAssociation()) {
0292:                            // make sure that the many to one association declarations have been obtained
0293:                            if (!obtained_manytoone_association_declarations) {
0294:                                manytoone_association_declarations = obtainManyToOneAssociationDeclarations(
0295:                                        this , constrained);
0296:
0297:                                if (manytoone_association_declarations != null) {
0298:                                    // get the property values of those that contain many-to-one association relationships
0299:                                    String[] manytoone_association_property_names = new String[manytoone_association_declarations
0300:                                            .size()];
0301:                                    manytoone_association_declarations
0302:                                            .keySet()
0303:                                            .toArray(
0304:                                                    manytoone_association_property_names);
0305:                                    try {
0306:                                        manytoone_association_property_values = BeanUtils
0307:                                                .getPropertyValues(
0308:                                                        constrained,
0309:                                                        manytoone_association_property_names,
0310:                                                        null, null);
0311:                                    } catch (BeanUtilsException e) {
0312:                                        throw new DatabaseException(e);
0313:                                    }
0314:                                }
0315:
0316:                                obtained_manytoone_association_declarations = true;
0317:                            }
0318:
0319:                            ManyToOneAssociationDeclaration declaration = manytoone_association_declarations
0320:                                    .get(property.getPropertyName());
0321:                            if (declaration != null) {
0322:                                Object value = manytoone_association_property_values
0323:                                        .get(property.getPropertyName());
0324:                                Class type = declaration.getMainType();
0325:                                try {
0326:                                    checkCollectionRelationshipValidity(
0327:                                            validated, property, value, type);
0328:                                } catch (ClassCastException e) {
0329:                                    throw new UnsupportedManyToManyValueTypeException(
0330:                                            validated.getClass(), property
0331:                                                    .getName(), e);
0332:                                }
0333:                            }
0334:                        }
0335:
0336:                        // handle the manyToMany constraint
0337:                        if (property.hasManyToMany()
0338:                                || property.hasManyToManyAssociation()) {
0339:                            // make sure that the many to many declarations have been obtained
0340:                            if (!obtained_manytomany_declarations) {
0341:                                manytomany_declarations = obtainManyToManyDeclarations(
0342:                                        this , constrained, true);
0343:
0344:                                if (manytomany_declarations != null) {
0345:                                    // get the property values of those that contain many-to-many relationships
0346:                                    String[] manytomany_property_names = new String[manytomany_declarations
0347:                                            .size()];
0348:                                    manytomany_declarations.keySet().toArray(
0349:                                            manytomany_property_names);
0350:                                    try {
0351:                                        manytomany_property_values = BeanUtils
0352:                                                .getPropertyValues(
0353:                                                        constrained,
0354:                                                        manytomany_property_names,
0355:                                                        null, null);
0356:                                    } catch (BeanUtilsException e) {
0357:                                        throw new DatabaseException(e);
0358:                                    }
0359:                                }
0360:
0361:                                obtained_manytomany_declarations = true;
0362:                            }
0363:
0364:                            ManyToManyDeclaration declaration = manytomany_declarations
0365:                                    .get(property.getPropertyName());
0366:                            if (declaration != null) {
0367:                                Object value = manytomany_property_values
0368:                                        .get(property.getPropertyName());
0369:                                try {
0370:                                    checkCollectionRelationshipValidity(
0371:                                            validated, property, value,
0372:                                            declaration.getAssociationType());
0373:                                } catch (ClassCastException e) {
0374:                                    throw new UnsupportedManyToManyValueTypeException(
0375:                                            validated.getClass(), property
0376:                                                    .getName(), e);
0377:                                }
0378:                            }
0379:
0380:                        }
0381:                    }
0382:
0383:                    // handle the bean-wide uniqueness
0384:                    ConstrainedBean constrained_bean = constrained
0385:                            .getConstrainedBean();
0386:                    if (constrained_bean != null
0387:                            && constrained_bean.hasUniques()) {
0388:                        for (String[] uniques : (List<String[]>) constrained_bean
0389:                                .getUniques()) {
0390:                            CountQuery count_query = getCountQuery();
0391:                            if (identifier_exists) {
0392:                                count_query.where(mPrimaryKey, "!=",
0393:                                        identifier_value);
0394:                            }
0395:
0396:                            for (String unique : uniques) {
0397:                                Object property_value = null;
0398:                                try {
0399:                                    property_value = BeanUtils
0400:                                            .getPropertyValue(constrained,
0401:                                                    unique);
0402:                                } catch (BeanUtilsException e) {
0403:                                    throw new DatabaseException(e);
0404:                                }
0405:
0406:                                if (null == property_value) {
0407:                                    count_query = null;
0408:                                    break;
0409:                                } else {
0410:                                    count_query.where(unique, "=",
0411:                                            property_value);
0412:                                }
0413:                            }
0414:
0415:                            if (count_query != null && count(count_query) > 0) {
0416:                                for (String unique : uniques) {
0417:                                    validated
0418:                                            .addValidationError(new ValidationError.UNICITY(
0419:                                                    unique));
0420:                                }
0421:                            }
0422:                        }
0423:                    }
0424:                }
0425:            }
0426:
0427:            private void checkCollectionRelationshipValidity(
0428:                    final Validated validated,
0429:                    final ConstrainedProperty property,
0430:                    final Object propertyValue, final Class elementType)
0431:                    throws ClassCastException {
0432:                if (elementType != null && propertyValue != null) {
0433:                    // cast the property value to a collection
0434:                    Collection value_collection = (Collection) propertyValue;
0435:
0436:                    // iterate over all the collection elements to obtain the identifier values
0437:                    Set<Integer> identifiers = new HashSet<Integer>();
0438:                    GenericQueryManager element_manager = createNewManager(elementType);
0439:                    for (Object entity : value_collection) {
0440:                        int identifier_value = element_manager
0441:                                .getIdentifierValue(entity);
0442:                        // only add the identifiers that have a value
0443:                        if (identifier_value != -1) {
0444:                            identifiers.add(identifier_value);
0445:                        }
0446:                    }
0447:
0448:                    // check if the many-to-one associations exist
0449:                    CountQuery count_query = element_manager.getCountQuery()
0450:                            .where(
0451:                                    element_manager.getIdentifierName()
0452:                                            + " IN ("
0453:                                            + StringUtils
0454:                                                    .join(identifiers, ",")
0455:                                            + ")");
0456:                    int count = element_manager.count(count_query);
0457:                    if (count != identifiers.size()) {
0458:                        validated
0459:                                .addValidationError(new ValidationError.INVALID(
0460:                                        property.getPropertyName()));
0461:                    }
0462:                }
0463:            }
0464:
0465:            protected Callbacks getCallbacks(BeanType bean) {
0466:                if (null == bean)
0467:                    return null;
0468:
0469:                Callbacks callbacks = null;
0470:                if (bean instanceof  CallbacksProvider) {
0471:                    callbacks = ((CallbacksProvider) bean).getCallbacks();
0472:                } else if (bean instanceof  Callbacks) {
0473:                    callbacks = (Callbacks) bean;
0474:                }
0475:                return callbacks;
0476:            }
0477:
0478:            protected int _update(final Update saveUpdate, final BeanType bean) {
0479:                // handle before callback
0480:                Callbacks callbacks = getCallbacks(bean);
0481:                if (callbacks != null && !callbacks.beforeUpdate(bean)) {
0482:                    return -1;
0483:                }
0484:
0485:                // perform update
0486:                int result = _updateWithoutCallbacks(saveUpdate, bean);
0487:
0488:                // handle after callback
0489:                if (callbacks != null) {
0490:                    callbacks.afterUpdate(bean, result != -1);
0491:                }
0492:
0493:                return result;
0494:            }
0495:
0496:            protected int _updateWithoutCallbacks(final Update saveUpdate,
0497:                    final BeanType bean) {
0498:                assert saveUpdate != null;
0499:
0500:                final int identifier_value = getIdentifierValue(bean);
0501:                int result = (Integer) inTransaction(new DbTransactionUser() {
0502:                    public Integer useTransaction() throws InnerClassException {
0503:                        int result = identifier_value;
0504:
0505:                        storeManyToOne(bean);
0506:
0507:                        if (0 == executeUpdate(saveUpdate,
0508:                                new DbPreparedStatementHandler() {
0509:                                    public void setParameters(
0510:                                            final DbPreparedStatement statement) {
0511:                                        statement.setBean(bean);
0512:
0513:                                        setManyToOneJoinParameters(statement,
0514:                                                bean);
0515:                                    }
0516:                                })) {
0517:                            result = -1;
0518:                        } else {
0519:                            storeManyToOneAssociations(bean, identifier_value);
0520:                            storeManyToMany(bean, identifier_value);
0521:                        }
0522:
0523:                        return result;
0524:                    }
0525:                });
0526:
0527:                // handle listeners
0528:                if (result != -1) {
0529:                    fireUpdated(bean);
0530:                }
0531:
0532:                return result;
0533:            }
0534:
0535:            protected int _insert(final SequenceValue nextId,
0536:                    final Insert save, final BeanType bean) {
0537:                // handle before callback
0538:                Callbacks callbacks = getCallbacks(bean);
0539:                if (callbacks != null && !callbacks.beforeInsert(bean)) {
0540:                    return -1;
0541:                }
0542:
0543:                // perform insert
0544:                int result = _insertWithoutCallbacks(nextId, save, bean);
0545:
0546:                // handle after callback
0547:                if (callbacks != null) {
0548:                    callbacks.afterInsert(bean, result != -1);
0549:                }
0550:
0551:                return result;
0552:            }
0553:
0554:            protected int _insertWithoutCallbacks(final SequenceValue nextId,
0555:                    final Insert save, final BeanType bean) {
0556:                assert nextId != null;
0557:                assert save != null;
0558:
0559:                int value = -1;
0560:
0561:                value = (Integer) inTransaction(new DbTransactionUser() {
0562:                    public Integer useTransaction() throws InnerClassException {
0563:                        storeManyToOne(bean);
0564:
0565:                        int result = getIdentifierValue(bean);
0566:                        if (!isIdentifierSparse()) {
0567:                            result = executeGetFirstInt(nextId);
0568:                        }
0569:
0570:                        final int primary_key_id = result;
0571:                        executeUpdate(save, new DbPreparedStatementHandler() {
0572:                            public void setParameters(
0573:                                    final DbPreparedStatement statement) {
0574:                                statement.setBean(bean).setInt(mPrimaryKey,
0575:                                        primary_key_id);
0576:
0577:                                setManyToOneJoinParameters(statement, bean);
0578:                            }
0579:                        });
0580:
0581:                        storeManyToOneAssociations(bean, primary_key_id);
0582:                        storeManyToMany(bean, primary_key_id);
0583:
0584:                        return result;
0585:                    }
0586:                });
0587:
0588:                try {
0589:                    mSetPrimaryKeyMethod.invoke(bean,
0590:                            new Object[] { new Integer(value) });
0591:                } catch (Throwable e) {
0592:                    throw new DatabaseException(e);
0593:                }
0594:
0595:                // handle listeners
0596:                if (value != -1) {
0597:                    fireInserted(bean);
0598:                }
0599:
0600:                return value;
0601:            }
0602:
0603:            protected void setManyToOneJoinParameters(
0604:                    final DbPreparedStatement statement, final BeanType bean) {
0605:                final Constrained constrained = ConstrainedUtils
0606:                        .makeConstrainedInstance(bean);
0607:
0608:                // handle many-to-one join column parameters
0609:                processManyToOneJoinColumns(this ,
0610:                        new ManyToOneJoinColumnProcessor() {
0611:                            public boolean processJoinColumn(String columnName,
0612:                                    String propertyName,
0613:                                    ManyToOneDeclaration declaration) {
0614:                                try {
0615:                                    Object join_column_property = BeanUtils
0616:                                            .getPropertyValue(bean,
0617:                                                    propertyName);
0618:                                    Object identifier_value = null;
0619:                                    if (join_column_property != null) {
0620:                                        identifier_value = BeanUtils
0621:                                                .getPropertyValue(
0622:                                                        join_column_property,
0623:                                                        declaration
0624:                                                                .getAssociationColumn());
0625:                                    }
0626:                                    Class identifier_type = BeanUtils
0627:                                            .getPropertyType(
0628:                                                    declaration
0629:                                                            .getAssociationType(),
0630:                                                    declaration
0631:                                                            .getAssociationColumn());
0632:
0633:                                    int[] indices = statement
0634:                                            .getParameterIndices(columnName);
0635:                                    for (int index : indices) {
0636:                                        getDatasource().getSqlConversion()
0637:                                                .setTypedParameter(statement,
0638:                                                        index, identifier_type,
0639:                                                        columnName,
0640:                                                        identifier_value,
0641:                                                        constrained);
0642:                                    }
0643:                                } catch (BeanUtilsException e) {
0644:                                    throw new DatabaseException(e);
0645:                                }
0646:
0647:                                return true;
0648:                            }
0649:                        });
0650:            }
0651:
0652:            protected void storeManyToOne(final BeanType bean) {
0653:                final Constrained constrained = ConstrainedUtils
0654:                        .makeConstrainedInstance(bean);
0655:                final Map<String, ManyToOneDeclaration> declarations = obtainManyToOneDeclarations(
0656:                        this , constrained, null, null);
0657:                if (declarations != null) {
0658:                    // get the property values of those that contain many-to-one relationships
0659:                    String[] property_names = new String[declarations.size()];
0660:                    declarations.keySet().toArray(property_names);
0661:                    final Map<String, Object> values;
0662:                    try {
0663:                        values = BeanUtils.getPropertyValues(bean,
0664:                                property_names, null, null);
0665:                    } catch (BeanUtilsException e) {
0666:                        throw new DatabaseException(e);
0667:                    }
0668:
0669:                    // iterate over all the many-to-one relationships that have associated classes and instance values
0670:                    for (Map.Entry<String, ManyToOneDeclaration> entry : declarations
0671:                            .entrySet()) {
0672:                        ManyToOneDeclaration declaration = entry.getValue();
0673:                        if (!declaration.isBasic()) {
0674:                            GenericQueryManager association_manager = declaration
0675:                                    .getAssociationManager();
0676:                            String property_name = entry.getKey();
0677:
0678:                            // obtain the property value
0679:                            Object value = values.get(property_name);
0680:                            if (value != null) {
0681:                                int identifier_value = association_manager
0682:                                        .getIdentifierValue(value);
0683:                                // insert the collection entries that have no identifier value
0684:                                if (identifier_value < 0) {
0685:                                    identifier_value = association_manager
0686:                                            .insert(value);
0687:                                }
0688:                            }
0689:                        }
0690:                    }
0691:                }
0692:            }
0693:
0694:            protected void storeManyToOneAssociations(final BeanType bean,
0695:                    final int objectId) {
0696:                final Constrained constrained = ConstrainedUtils
0697:                        .makeConstrainedInstance(bean);
0698:                final Map<String, ManyToOneAssociationDeclaration> declarations = obtainManyToOneAssociationDeclarations(
0699:                        this , constrained);
0700:                if (declarations != null) {
0701:                    // get the property values of those that contain many-to-one relationships
0702:                    String[] property_names = new String[declarations.size()];
0703:                    declarations.keySet().toArray(property_names);
0704:                    final Map<String, Object> values;
0705:                    try {
0706:                        values = BeanUtils.getPropertyValues(bean,
0707:                                property_names, null, null);
0708:                    } catch (BeanUtilsException e) {
0709:                        throw new DatabaseException(e);
0710:                    }
0711:
0712:                    // iterate over all the many-to-one relationships that have associated classes and instance values
0713:                    for (Map.Entry<String, ManyToOneAssociationDeclaration> entry : declarations
0714:                            .entrySet()) {
0715:                        ManyToOneAssociationDeclaration declaration = entry
0716:                                .getValue();
0717:                        GenericQueryManager main_manager = createNewManager(declaration
0718:                                .getMainType());
0719:                        String property_name = entry.getKey();
0720:
0721:                        // obtain the property value
0722:                        Object value = values.get(property_name);
0723:
0724:                        final String main_table = main_manager.getTable();
0725:                        final String main_identify_column = main_manager
0726:                                .getIdentifierName();
0727:                        final String main_join_column = generateManyToOneJoinColumnName(
0728:                                declaration.getMainProperty(), declaration
0729:                                        .getMainDeclaration());
0730:                        Update clear_previous_mappings = new Update(
0731:                                getDatasource()).table(main_table).fieldCustom(
0732:                                main_join_column, "NULL");
0733:                        executeUpdate(clear_previous_mappings);
0734:
0735:                        if (value != null) {
0736:                            ensureSupportedManyToOneAssociationPropertyValueType(
0737:                                    mBaseClass, property_name, value);
0738:
0739:                            Collection value_collection = (Collection) value;
0740:
0741:                            Update update_mapping = new Update(getDatasource())
0742:                                    .table(main_table).fieldParameter(
0743:                                            main_join_column).whereParameter(
0744:                                            main_identify_column, "=");
0745:                            // store the collection entries
0746:                            for (Object many_to_one_entity : value_collection) {
0747:                                int identifier_value = main_manager
0748:                                        .getIdentifierValue(many_to_one_entity);
0749:                                // insert the collection entries that have no identifier value
0750:                                if (identifier_value < 0) {
0751:                                    identifier_value = main_manager
0752:                                            .insert(many_to_one_entity);
0753:                                }
0754:                                // store the many-to-one mappings
0755:                                executeUpdate(
0756:                                        update_mapping,
0757:                                        new DbPreparedStatementHandler<Integer>(
0758:                                                identifier_value) {
0759:                                            public void setParameters(
0760:                                                    DbPreparedStatement statement) {
0761:                                                statement.setInt(
0762:                                                        main_join_column,
0763:                                                        objectId).setInt(
0764:                                                        main_identify_column,
0765:                                                        getData());
0766:                                            }
0767:                                        });
0768:                            }
0769:                        }
0770:                    }
0771:                }
0772:            }
0773:
0774:            protected void storeManyToMany(final BeanType bean,
0775:                    final int objectId) {
0776:                final Constrained constrained = ConstrainedUtils
0777:                        .makeConstrainedInstance(bean);
0778:                final Map<String, ManyToManyDeclaration> declarations = obtainManyToManyDeclarations(
0779:                        this , constrained, true);
0780:                if (declarations != null) {
0781:                    // get the property values of those that contain many-to-many relationships
0782:                    String[] property_names = new String[declarations.size()];
0783:                    declarations.keySet().toArray(property_names);
0784:                    final Map<String, Object> values;
0785:                    try {
0786:                        values = BeanUtils.getPropertyValues(bean,
0787:                                property_names, null, null);
0788:                    } catch (BeanUtilsException e) {
0789:                        throw new DatabaseException(e);
0790:                    }
0791:
0792:                    // iterate over all the many to many relationships
0793:                    final String column1_name = generateManyToManyJoinColumnName(AbstractGenericQueryManager.this );
0794:                    for (Map.Entry<String, ManyToManyDeclaration> entry : declarations
0795:                            .entrySet()) {
0796:                        ManyToManyDeclaration declaration = entry.getValue();
0797:                        GenericQueryManager association_manager = createNewManager(declaration
0798:                                .getAssociationType());
0799:                        String join_table = generateManyToManyJoinTableName(
0800:                                declaration, AbstractGenericQueryManager.this ,
0801:                                association_manager);
0802:                        final String column2_name = generateManyToManyJoinColumnName(association_manager);
0803:                        String property_name = entry.getKey();
0804:
0805:                        // obtain the property value
0806:                        Object value = values.get(property_name);
0807:
0808:                        // create the delete statement to remove all the possible previous
0809:                        // mappings in the join table for this primary key ID
0810:                        Delete delete_previous_mappings = new Delete(
0811:                                getDatasource()).from(join_table).where(
0812:                                column1_name, "=", objectId);
0813:                        executeUpdate(delete_previous_mappings);
0814:
0815:                        if (value != null) {
0816:                            ensureSupportedManyToManyPropertyValueType(
0817:                                    mBaseClass, property_name, value);
0818:
0819:                            Collection value_collection = (Collection) value;
0820:
0821:                            Insert insert_mapping = new Insert(getDatasource())
0822:                                    .into(join_table).fieldParameter(
0823:                                            column1_name).fieldParameter(
0824:                                            column2_name);
0825:                            // store the collection entries
0826:                            for (Object many_to_many_entity : value_collection) {
0827:                                int identifier_value = association_manager
0828:                                        .getIdentifierValue(many_to_many_entity);
0829:                                // insert the collection entries that have no identifier value
0830:                                if (identifier_value < 0) {
0831:                                    identifier_value = association_manager
0832:                                            .insert(many_to_many_entity);
0833:                                }
0834:                                // store the many-to_many mappings
0835:                                executeUpdate(
0836:                                        insert_mapping,
0837:                                        new DbPreparedStatementHandler<Integer>(
0838:                                                identifier_value) {
0839:                                            public void setParameters(
0840:                                                    DbPreparedStatement statement) {
0841:                                                statement.setInt(column1_name,
0842:                                                        objectId)
0843:                                                        .setInt(column2_name,
0844:                                                                getData());
0845:                                            }
0846:                                        });
0847:                            }
0848:                        }
0849:                    }
0850:                }
0851:            }
0852:
0853:            protected int _save(final SequenceValue nextId, final Insert save,
0854:                    final Update saveUpdate, final BeanType bean)
0855:                    throws DatabaseException {
0856:                assert nextId != null;
0857:                assert save != null;
0858:                assert saveUpdate != null;
0859:
0860:                int value = -1;
0861:
0862:                // handle before callback
0863:                final Callbacks callbacks = getCallbacks(bean);
0864:                if (callbacks != null && !callbacks.beforeSave(bean)) {
0865:                    return -1;
0866:                }
0867:
0868:                // cancel indicator
0869:                final boolean[] is_cancelled = new boolean[] { false };
0870:
0871:                // perform save
0872:                value = (Integer) inTransaction(new DbTransactionUser() {
0873:                    public Integer useTransaction() throws InnerClassException {
0874:                        int result = getIdentifierValue(bean);
0875:                        if (isIdentifierSparse()) {
0876:                            // handle before callback
0877:                            if (callbacks != null
0878:                                    && !callbacks.beforeInsert(bean)) {
0879:                                is_cancelled[0] = true;
0880:                                return -1;
0881:                            }
0882:
0883:                            // try to perform the insert
0884:                            try {
0885:                                result = _insertWithoutCallbacks(nextId, save,
0886:                                        bean);
0887:                            } catch (ExecutionErrorException e) {
0888:                                result = -1;
0889:                            }
0890:
0891:                            // handle after callback
0892:                            if (callbacks != null
0893:                                    && !callbacks.afterInsert(bean,
0894:                                            result != -1)) {
0895:                                is_cancelled[0] = true;
0896:                                return result;
0897:                            }
0898:
0899:                            // perform update if insert failed
0900:                            if (-1 == result) {
0901:                                // handle before callback
0902:                                if (callbacks != null
0903:                                        && !callbacks.beforeUpdate(bean)) {
0904:                                    is_cancelled[0] = true;
0905:                                    return -1;
0906:                                }
0907:
0908:                                result = _updateWithoutCallbacks(saveUpdate,
0909:                                        bean);
0910:
0911:                                // handle after callback
0912:                                if (callbacks != null
0913:                                        && !callbacks.afterUpdate(bean,
0914:                                                result != -1)) {
0915:                                    is_cancelled[0] = true;
0916:                                    return result;
0917:                                }
0918:                            }
0919:                        } else {
0920:                            // try to update
0921:                            if (result >= 0) {
0922:                                // handle before callback
0923:                                if (callbacks != null
0924:                                        && !callbacks.beforeUpdate(bean)) {
0925:                                    is_cancelled[0] = true;
0926:                                    return -1;
0927:                                }
0928:
0929:                                result = _updateWithoutCallbacks(saveUpdate,
0930:                                        bean);
0931:
0932:                                // handle after callback
0933:                                if (callbacks != null
0934:                                        && !callbacks.afterUpdate(bean,
0935:                                                result != -1)) {
0936:                                    is_cancelled[0] = true;
0937:                                    return result;
0938:                                }
0939:                            }
0940:
0941:                            // perform insert if update failed or wasn't appropriate
0942:                            if (-1 == result) {
0943:                                // handle before callback
0944:                                if (callbacks != null
0945:                                        && !callbacks.beforeInsert(bean)) {
0946:                                    is_cancelled[0] = true;
0947:                                    return -1;
0948:                                }
0949:
0950:                                result = _insertWithoutCallbacks(nextId, save,
0951:                                        bean);
0952:
0953:                                // handle after callback
0954:                                if (callbacks != null
0955:                                        && !callbacks.afterInsert(bean,
0956:                                                result != -1)) {
0957:                                    is_cancelled[0] = true;
0958:                                    return result;
0959:                                }
0960:                            }
0961:                        }
0962:
0963:                        return result;
0964:                    }
0965:                });
0966:
0967:                // handle after callback
0968:                if (!is_cancelled[0] && callbacks != null) {
0969:                    callbacks.afterSave(bean, value != -1);
0970:                }
0971:
0972:                return value;
0973:            }
0974:
0975:            protected boolean _delete(Delete delete) throws DatabaseException {
0976:                assert delete != null;
0977:
0978:                boolean result = true;
0979:
0980:                if (0 == executeUpdate(delete)) {
0981:                    result = false;
0982:                }
0983:
0984:                return result;
0985:            }
0986:
0987:            protected boolean _delete(final Delete delete, final int objectId)
0988:                    throws DatabaseException {
0989:                assert delete != null;
0990:
0991:                // handle before callback
0992:                Callbacks callbacks = null;
0993:                if (CallbacksProvider.class.isAssignableFrom(mBaseClass)) {
0994:                    try {
0995:                        callbacks = ((CallbacksProvider) mBaseClass
0996:                                .newInstance()).getCallbacks();
0997:                    } catch (IllegalAccessException e) {
0998:                        callbacks = null;
0999:                    } catch (InstantiationException e) {
1000:                        callbacks = null;
1001:                    }
1002:                } else if (Callbacks.class.isAssignableFrom(mBaseClass)) {
1003:                    try {
1004:                        callbacks = (Callbacks) mBaseClass.newInstance();
1005:                    } catch (IllegalAccessException e) {
1006:                        callbacks = null;
1007:                    } catch (InstantiationException e) {
1008:                        callbacks = null;
1009:                    }
1010:                }
1011:                if (callbacks != null && !callbacks.beforeDelete(objectId)) {
1012:                    return false;
1013:                }
1014:
1015:                // perform delete
1016:                Boolean result = inTransaction(new DbTransactionUser() {
1017:                    public Boolean useTransaction() throws InnerClassException {
1018:                        // remove all many-to-one mappings for this object ID
1019:                        deleteManyToOne(objectId);
1020:
1021:                        // remove all many-to-many mappings for this object ID
1022:                        deleteManyToMany(objectId);
1023:
1024:                        // perform the actual deletion of the object from the database
1025:                        if (0 == executeUpdate(delete,
1026:                                new DbPreparedStatementHandler() {
1027:                                    public void setParameters(
1028:                                            DbPreparedStatement statement) {
1029:                                        statement.setInt(mPrimaryKey, objectId);
1030:                                    }
1031:                                })) {
1032:                            return false;
1033:                        }
1034:
1035:                        return true;
1036:                    }
1037:                });
1038:
1039:                // handle listeners
1040:                if (result) {
1041:                    fireDeleted(objectId);
1042:                }
1043:
1044:                // handle after callback
1045:                if (callbacks != null) {
1046:                    callbacks.afterDelete(objectId, result);
1047:                }
1048:
1049:                return result;
1050:            }
1051:
1052:            protected void deleteManyToOne(final int objectId) {
1053:                final Constrained constrained = ConstrainedUtils
1054:                        .getConstrainedInstance(getBaseClass());
1055:                final Map<String, ManyToOneAssociationDeclaration> declarations = obtainManyToOneAssociationDeclarations(
1056:                        this , constrained);
1057:                if (declarations != null) {
1058:                    // iterate over all the many to one assocation relationships
1059:                    for (Map.Entry<String, ManyToOneAssociationDeclaration> entry : declarations
1060:                            .entrySet()) {
1061:                        ManyToOneAssociationDeclaration declaration = entry
1062:                                .getValue();
1063:                        String column_name = generateManyToOneJoinColumnName(
1064:                                declaration.getMainProperty(), declaration
1065:                                        .getMainDeclaration());
1066:                        GenericQueryManager main_manager = createNewManager(declaration
1067:                                .getMainType());
1068:
1069:                        // create an update statement that will set all the columns that
1070:                        // point to the deleted entity to NULL
1071:                        Update clear_references = new Update(getDatasource())
1072:                                .table(main_manager.getTable()).fieldCustom(
1073:                                        column_name, "NULL").where(column_name,
1074:                                        "=", objectId);
1075:                        executeUpdate(clear_references);
1076:                    }
1077:                }
1078:            }
1079:
1080:            protected void deleteManyToMany(final int objectId) {
1081:                final Constrained constrained = ConstrainedUtils
1082:                        .getConstrainedInstance(getBaseClass());
1083:                final Map<String, ManyToManyDeclaration> declarations = obtainManyToManyDeclarations(
1084:                        this , constrained, true);
1085:                if (declarations != null) {
1086:                    // iterate over all the many to many relationships
1087:                    final String column1_name = generateManyToManyJoinColumnName(AbstractGenericQueryManager.this );
1088:                    for (Map.Entry<String, ManyToManyDeclaration> entry : declarations
1089:                            .entrySet()) {
1090:                        ManyToManyDeclaration declaration = entry.getValue();
1091:                        GenericQueryManager association_manager = createNewManager(declaration
1092:                                .getAssociationType());
1093:                        String join_table = generateManyToManyJoinTableName(
1094:                                declaration, AbstractGenericQueryManager.this ,
1095:                                association_manager);
1096:
1097:                        // create the delete statement to remove all the possible previous
1098:                        // mappings in the join table for this primary key ID
1099:                        Delete delete_previous_mappings = new Delete(
1100:                                getDatasource()).from(join_table).where(
1101:                                column1_name, "=", objectId);
1102:                        executeUpdate(delete_previous_mappings);
1103:                    }
1104:                }
1105:            }
1106:
1107:            protected BeanType _restore(Select restore, final int objectId)
1108:                    throws DatabaseException {
1109:                assert restore != null;
1110:
1111:                BeanType result = null;
1112:
1113:                result = executeFetchFirstBean(restore, mBaseClass,
1114:                        new DbPreparedStatementHandler() {
1115:                            public void setParameters(
1116:                                    DbPreparedStatement statement) {
1117:                                statement.setInt(mPrimaryKey, objectId);
1118:                            }
1119:                        });
1120:
1121:                // handle listeners
1122:                if (result != null) {
1123:                    restoreManyToOne(result);
1124:                    restoreManyToOneAssociations(result, objectId);
1125:                    restoreManyToMany(result, objectId);
1126:
1127:                    fireRestored(result);
1128:                }
1129:
1130:                // handle after callback
1131:                Callbacks callbacks = getCallbacks(result);
1132:                if (callbacks != null && !callbacks.afterRestore(result)) {
1133:                    return null;
1134:                }
1135:
1136:                return result;
1137:            }
1138:
1139:            protected BeanType _restoreFirst(Select restore)
1140:                    throws DatabaseException {
1141:                assert restore != null;
1142:
1143:                BeanType result = executeFetchFirstBean(restore, mBaseClass);
1144:
1145:                // handle listeners
1146:                if (result != null) {
1147:                    restoreManyToOne(result);
1148:                    int identifier_value = getIdentifierValue(result);
1149:                    restoreManyToOneAssociations(result, identifier_value);
1150:                    restoreManyToMany(result, identifier_value);
1151:
1152:                    fireRestored(result);
1153:                }
1154:
1155:                // handle after callback
1156:                Callbacks callbacks = getCallbacks(result);
1157:                if (callbacks != null && !callbacks.afterRestore(result)) {
1158:                    return null;
1159:                }
1160:
1161:                return result;
1162:            }
1163:
1164:            protected List<BeanType> _restore(Select restore)
1165:                    throws DatabaseException {
1166:                assert restore != null;
1167:
1168:                DbBeanFetcher<BeanType> bean_fetcher = new DbBeanFetcher<BeanType>(
1169:                        getDatasource(), mBaseClass, true) {
1170:                    public boolean gotBeanInstance(BeanType instance) {
1171:                        // handle listeners
1172:                        if (instance != null) {
1173:                            restoreManyToOne(instance);
1174:                            int identifier_value = getIdentifierValue(instance);
1175:                            restoreManyToOneAssociations(instance,
1176:                                    identifier_value);
1177:                            restoreManyToMany(instance, identifier_value);
1178:
1179:                            fireRestored(instance);
1180:                        }
1181:
1182:                        // handle after callback
1183:                        Callbacks callbacks = getCallbacks(instance);
1184:                        return !(callbacks != null && !callbacks
1185:                                .afterRestore(instance));
1186:                    }
1187:                };
1188:
1189:                executeFetchAll(restore, bean_fetcher, null);
1190:
1191:                return bean_fetcher.getCollectedInstances();
1192:            }
1193:
1194:            protected boolean _restore(Select restore,
1195:                    DbRowProcessor rowProcessor) throws DatabaseException {
1196:                assert restore != null;
1197:
1198:                return executeFetchAll(restore, rowProcessor);
1199:            }
1200:
1201:            protected void restoreManyToMany(final BeanType bean,
1202:                    final int objectId) {
1203:                // handle many-to-many associations
1204:                final Constrained constrained = ConstrainedUtils
1205:                        .makeConstrainedInstance(bean);
1206:                final Map<String, ManyToManyDeclaration> declarations = obtainManyToManyDeclarations(
1207:                        this , constrained, true);
1208:                if (declarations != null) {
1209:                    // iterate over all the many to many relationships
1210:                    final String column1_name = generateManyToManyJoinColumnName(AbstractGenericQueryManager.this );
1211:                    for (Map.Entry<String, ManyToManyDeclaration> entry : declarations
1212:                            .entrySet()) {
1213:                        ManyToManyDeclaration declaration = entry.getValue();
1214:
1215:                        // create the associations collection
1216:                        Object association_collection;
1217:                        if (Set.class == declaration.getCollectionType()) {
1218:                            association_collection = new ManyToManySet(
1219:                                    AbstractGenericQueryManager.this ,
1220:                                    column1_name, objectId, declaration);
1221:                        } else {
1222:                            association_collection = new ManyToManyList(
1223:                                    AbstractGenericQueryManager.this ,
1224:                                    column1_name, objectId, declaration);
1225:                        }
1226:
1227:                        // set the restore mappings as the property value
1228:                        try {
1229:                            BeanUtils.setPropertyValue(bean, entry.getKey(),
1230:                                    association_collection);
1231:                        } catch (BeanUtilsException e) {
1232:                            throw new DatabaseException(e);
1233:                        }
1234:                    }
1235:                }
1236:            }
1237:
1238:            protected void restoreManyToOne(final BeanType bean) {
1239:                Field gqm_field = null;
1240:                Field lazyloaded_field = null;
1241:                try {
1242:                    gqm_field = bean.getClass().getDeclaredField(
1243:                            LazyLoadAccessorsBytecodeTransformer.GQM_VAR_NAME);
1244:                    lazyloaded_field = bean
1245:                            .getClass()
1246:                            .getDeclaredField(
1247:                                    LazyLoadAccessorsBytecodeTransformer.LAZYLOADED_VAR_NAME);
1248:                } catch (Exception e) {
1249:                    // if the synthetic fields don't exist in the class, just set them to null
1250:                    // since this means that bytecode enhancement hasn't been performed to provide
1251:                    // lazy-load functionalities
1252:                    gqm_field = null;
1253:                    lazyloaded_field = null;
1254:                }
1255:
1256:                // if the class has been enhanced for lazy loading capabilities, add a reference
1257:                // to this GQM and create a new map for storing the already loaded property values
1258:                if (gqm_field != null && lazyloaded_field != null) {
1259:                    gqm_field.setAccessible(true);
1260:                    lazyloaded_field.setAccessible(true);
1261:                    try {
1262:                        gqm_field.set(bean, this );
1263:                        if (TerracottaUtils.isTcPresent()) {
1264:                            lazyloaded_field.set(bean, new HashMap());
1265:                        } else {
1266:                            lazyloaded_field.set(bean, new WeakHashMap());
1267:                        }
1268:                    } catch (Exception e) {
1269:                        throw new DatabaseException(e);
1270:                    }
1271:                }
1272:                // otherwise eargerly load all many-to-one properties
1273:                else {
1274:                    processManyToOneJoinColumns(this ,
1275:                            new ManyToOneJoinColumnProcessor() {
1276:                                public boolean processJoinColumn(
1277:                                        String columnName, String propertyName,
1278:                                        ManyToOneDeclaration declaration) {
1279:                                    Object property_value = restoreManyToOneProperty(
1280:                                            AbstractGenericQueryManager.this ,
1281:                                            declaration.getAssociationManager(),
1282:                                            columnName, declaration
1283:                                                    .getAssociationType());
1284:
1285:                                    // set the many-to-one mapping as the property value
1286:                                    try {
1287:                                        BeanUtils.setPropertyValue(bean,
1288:                                                propertyName, property_value);
1289:                                    } catch (BeanUtilsException e) {
1290:                                        throw new DatabaseException(e);
1291:                                    }
1292:
1293:                                    return true;
1294:                                }
1295:                            });
1296:                }
1297:            }
1298:
1299:            protected void restoreManyToOneAssociations(final BeanType bean,
1300:                    final int objectId) {
1301:                // handle many-to-one associations
1302:                final Constrained constrained = ConstrainedUtils
1303:                        .makeConstrainedInstance(bean);
1304:                final Map<String, ManyToOneAssociationDeclaration> declarations = obtainManyToOneAssociationDeclarations(
1305:                        this , constrained);
1306:                if (declarations != null) {
1307:                    // iterate over all the many to one association relationships
1308:                    for (Map.Entry<String, ManyToOneAssociationDeclaration> entry : declarations
1309:                            .entrySet()) {
1310:                        ManyToOneAssociationDeclaration declaration = entry
1311:                                .getValue();
1312:
1313:                        // create the associations collection
1314:                        Object association_collection;
1315:                        if (Set.class == declaration.getCollectionType()) {
1316:                            association_collection = new ManyToOneAssociationSet(
1317:                                    AbstractGenericQueryManager.this , objectId,
1318:                                    declaration);
1319:                        } else {
1320:                            association_collection = new ManyToOneAssociationList(
1321:                                    AbstractGenericQueryManager.this , objectId,
1322:                                    declaration);
1323:                        }
1324:
1325:                        // set the restore mappings as the property value
1326:                        try {
1327:                            BeanUtils.setPropertyValue(bean, entry.getKey(),
1328:                                    association_collection);
1329:                        } catch (BeanUtilsException e) {
1330:                            throw new DatabaseException(e);
1331:                        }
1332:                    }
1333:                }
1334:            }
1335:
1336:            protected int _count(Select count) throws DatabaseException {
1337:                return executeGetFirstInt(count);
1338:            }
1339:
1340:            protected void _install(final CreateSequence createSequence,
1341:                    final CreateTable createTable) throws DatabaseException {
1342:                assert createSequence != null;
1343:                assert createTable != null;
1344:
1345:                inTransaction(new DbTransactionUserWithoutResult() {
1346:                    public void useTransactionWithoutResult()
1347:                            throws InnerClassException {
1348:                        if (!isIdentifierSparse()) {
1349:                            executeUpdate(createSequence);
1350:                        }
1351:                        executeUpdate(createTable);
1352:
1353:                        installManyToMany();
1354:                    }
1355:                });
1356:                fireInstalled();
1357:            }
1358:
1359:            protected void installManyToMany() {
1360:                // create many-to-many join tables
1361:                Constrained constrained = ConstrainedUtils
1362:                        .getConstrainedInstance(mBaseClass);
1363:                Map<String, ManyToManyDeclaration> manytomany_declarations = obtainManyToManyDeclarations(
1364:                        this , constrained, false);
1365:                if (manytomany_declarations != null) {
1366:                    String column1 = generateManyToManyJoinColumnName(AbstractGenericQueryManager.this );
1367:                    for (Map.Entry<String, ManyToManyDeclaration> entry : manytomany_declarations
1368:                            .entrySet()) {
1369:                        ManyToManyDeclaration declaration = entry.getValue();
1370:                        GenericQueryManager association_manager = createNewManager(declaration
1371:                                .getAssociationType());
1372:                        String table = generateManyToManyJoinTableName(
1373:                                declaration, AbstractGenericQueryManager.this ,
1374:                                association_manager);
1375:                        String column2 = generateManyToManyJoinColumnName(association_manager);
1376:
1377:                        // obtain the violation actions
1378:                        CreateTable.ViolationAction onupdate = null;
1379:                        CreateTable.ViolationAction ondelete = null;
1380:                        ConstrainedProperty property = constrained
1381:                                .getConstrainedProperty(entry.getKey());
1382:                        if (property != null && property.hasManyToMany()) {
1383:                            onupdate = property.getManyToMany().getOnUpdate();
1384:                            ondelete = property.getManyToMany().getOnDelete();
1385:                        }
1386:
1387:                        // build the table creation query
1388:                        CreateTable create_join_table = new CreateTable(
1389:                                getDatasource()).table(table).column(column1,
1390:                                int.class, CreateTable.NOTNULL).column(column2,
1391:                                int.class, CreateTable.NOTNULL).foreignKey(
1392:                                getTable(), column1, getIdentifierName(),
1393:                                onupdate, ondelete).foreignKey(
1394:                                association_manager.getTable(), column2,
1395:                                association_manager.getIdentifierName(),
1396:                                onupdate, ondelete);
1397:                        executeUpdate(create_join_table);
1398:                    }
1399:                }
1400:            }
1401:
1402:            protected void _remove(final DropSequence dropSequence,
1403:                    final DropTable dropTable) throws DatabaseException {
1404:                assert dropTable != null;
1405:                assert dropSequence != null;
1406:
1407:                inTransaction(new DbTransactionUserWithoutResult() {
1408:                    public void useTransactionWithoutResult()
1409:                            throws InnerClassException {
1410:                        removeManyToMany();
1411:
1412:                        // drop the table itself and optionally the sequence
1413:                        executeUpdate(dropTable);
1414:                        if (!isIdentifierSparse()) {
1415:                            executeUpdate(dropSequence);
1416:                        }
1417:                    }
1418:                });
1419:                fireRemoved();
1420:            }
1421:
1422:            protected void removeManyToMany() {
1423:                // drop many-to-many join tables
1424:                Constrained constrained = ConstrainedUtils
1425:                        .getConstrainedInstance(mBaseClass);
1426:                Map<String, ManyToManyDeclaration> manytomany_declarations = obtainManyToManyDeclarations(
1427:                        this , constrained, false);
1428:                if (manytomany_declarations != null) {
1429:                    for (Map.Entry<String, ManyToManyDeclaration> entry : manytomany_declarations
1430:                            .entrySet()) {
1431:                        ManyToManyDeclaration declaration = entry.getValue();
1432:                        GenericQueryManager association_manager = createNewManager(declaration
1433:                                .getAssociationType());
1434:                        String table = generateManyToManyJoinTableName(
1435:                                declaration, AbstractGenericQueryManager.this ,
1436:                                association_manager);
1437:
1438:                        // build the table removal query
1439:                        DropTable drop_join_table = new DropTable(
1440:                                getDatasource()).table(table);
1441:                        executeUpdate(drop_join_table);
1442:                    }
1443:                }
1444:            }
1445:
1446:            public void addListener(GenericQueryManagerListener listener) {
1447:                if (null == listener) {
1448:                    return;
1449:                }
1450:
1451:                if (null == mListeners) {
1452:                    mListeners = new ArrayList<GenericQueryManagerListener>();
1453:                }
1454:
1455:                mListeners.add(listener);
1456:            }
1457:
1458:            public void removeListeners() {
1459:                if (null == mListeners) {
1460:                    return;
1461:                }
1462:
1463:                mListeners.clear();
1464:            }
1465:
1466:            public <OtherBeanType> GenericQueryManager<OtherBeanType> createNewManager(
1467:                    Class<OtherBeanType> beanClass) {
1468:                return GenericQueryManagerFactory.getInstance(getDatasource(),
1469:                        beanClass);
1470:            }
1471:
1472:            protected void fireInstalled() {
1473:                if (null == mListeners) {
1474:                    return;
1475:                }
1476:
1477:                for (GenericQueryManagerListener listener : mListeners) {
1478:                    listener.installed();
1479:                }
1480:            }
1481:
1482:            protected void fireRemoved() {
1483:                if (null == mListeners) {
1484:                    return;
1485:                }
1486:
1487:                for (GenericQueryManagerListener listener : mListeners) {
1488:                    listener.removed();
1489:                }
1490:            }
1491:
1492:            protected void fireInserted(BeanType bean) {
1493:                if (null == mListeners) {
1494:                    return;
1495:                }
1496:
1497:                for (GenericQueryManagerListener listener : mListeners) {
1498:                    listener.inserted(bean);
1499:                }
1500:            }
1501:
1502:            protected void fireUpdated(BeanType bean) {
1503:                if (null == mListeners) {
1504:                    return;
1505:                }
1506:
1507:                for (GenericQueryManagerListener listener : mListeners) {
1508:                    listener.updated(bean);
1509:                }
1510:            }
1511:
1512:            protected void fireRestored(BeanType bean) {
1513:                if (null == mListeners) {
1514:                    return;
1515:                }
1516:
1517:                for (GenericQueryManagerListener listener : mListeners) {
1518:                    listener.restored(bean);
1519:                }
1520:            }
1521:
1522:            protected void fireDeleted(int objectId) {
1523:                if (null == mListeners) {
1524:                    return;
1525:                }
1526:
1527:                for (GenericQueryManagerListener listener : mListeners) {
1528:                    listener.deleted(objectId);
1529:                }
1530:            }
1531:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.