Source Code Cross Referenced for BrokerHelper.java in  » Database-ORM » db-ojb » org » apache » ojb » broker » util » 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 » Database ORM » db ojb » org.apache.ojb.broker.util 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        package org.apache.ojb.broker.util;
0002:
0003:        /* Copyright 2002-2005 The Apache Software Foundation
0004:         *
0005:         * Licensed under the Apache License, Version 2.0 (the "License");
0006:         * you may not use this file except in compliance with the License.
0007:         * You may obtain a copy of the License at
0008:         *
0009:         *     http://www.apache.org/licenses/LICENSE-2.0
0010:         *
0011:         * Unless required by applicable law or agreed to in writing, software
0012:         * distributed under the License is distributed on an "AS IS" BASIS,
0013:         * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0014:         * See the License for the specific language governing permissions and
0015:         * limitations under the License.
0016:         */
0017:
0018:        import java.sql.PreparedStatement;
0019:        import java.sql.ResultSet;
0020:        import java.sql.SQLException;
0021:        import java.util.ArrayList;
0022:        import java.util.Collection;
0023:        import java.util.Iterator;
0024:        import java.util.List;
0025:        import java.util.Map;
0026:        import java.util.StringTokenizer;
0027:
0028:        import org.apache.commons.collections.CollectionUtils;
0029:        import org.apache.commons.collections.iterators.ArrayIterator;
0030:        import org.apache.commons.collections.map.ReferenceIdentityMap;
0031:        import org.apache.ojb.broker.Identity;
0032:        import org.apache.ojb.broker.ManageableCollection;
0033:        import org.apache.ojb.broker.MtoNImplementor;
0034:        import org.apache.ojb.broker.OJBRuntimeException;
0035:        import org.apache.ojb.broker.PBKey;
0036:        import org.apache.ojb.broker.PersistenceBrokerException;
0037:        import org.apache.ojb.broker.accesslayer.StatementManagerIF;
0038:        import org.apache.ojb.broker.accesslayer.sql.SqlExistStatement;
0039:        import org.apache.ojb.broker.core.PersistenceBrokerImpl;
0040:        import org.apache.ojb.broker.core.ValueContainer;
0041:        import org.apache.ojb.broker.core.proxy.IndirectionHandler;
0042:        import org.apache.ojb.broker.core.proxy.ProxyHelper;
0043:        import org.apache.ojb.broker.metadata.ClassDescriptor;
0044:        import org.apache.ojb.broker.metadata.CollectionDescriptor;
0045:        import org.apache.ojb.broker.metadata.FieldDescriptor;
0046:        import org.apache.ojb.broker.metadata.FieldHelper;
0047:        import org.apache.ojb.broker.metadata.MetadataException;
0048:        import org.apache.ojb.broker.metadata.MetadataManager;
0049:        import org.apache.ojb.broker.metadata.ObjectReferenceDescriptor;
0050:        import org.apache.ojb.broker.metadata.fieldaccess.PersistentField;
0051:        import org.apache.ojb.broker.platforms.Platform;
0052:        import org.apache.ojb.broker.query.Criteria;
0053:        import org.apache.ojb.broker.query.MtoNQuery;
0054:        import org.apache.ojb.broker.query.Query;
0055:        import org.apache.ojb.broker.query.QueryByCriteria;
0056:        import org.apache.ojb.broker.query.QueryBySQL;
0057:        import org.apache.ojb.broker.query.ReportQueryByCriteria;
0058:        import org.apache.ojb.broker.query.ReportQueryByMtoNCriteria;
0059:        import org.apache.ojb.broker.util.logging.LoggerFactory;
0060:        import org.apache.ojb.broker.util.sequence.SequenceManagerException;
0061:
0062:        /**
0063:         * This class contains helper methods primarily used by the {@link org.apache.ojb.broker.PersistenceBroker}
0064:         * implementation (e.g. contains methods to assign the the values of 'autoincrement' fields).
0065:         * <br/>
0066:         * Furthermore it was used to introduce new features related to {@link org.apache.ojb.broker.PersistenceBroker} - these
0067:         * new features and services (if they stand the test of time) will be moved to separate services in future.
0068:         *
0069:         * @author <a href="mailto:armin@codeAuLait.de">Armin Waibel</a>
0070:         * @version $Id: BrokerHelper.java,v 1.57.2.23 2005/12/21 22:27:47 tomdz Exp $
0071:         */
0072:        public class BrokerHelper {
0073:            public static final String REPOSITORY_NAME_SEPARATOR = "#";
0074:            private PersistenceBrokerImpl m_broker;
0075:
0076:            public BrokerHelper(PersistenceBrokerImpl broker) {
0077:                this .m_broker = broker;
0078:            }
0079:
0080:            /**
0081:             * splits up the name string and extract db url,
0082:             * user name and password and build a new PBKey
0083:             * instance - the token '#' is used to separate
0084:             * the substrings.
0085:             * @throws PersistenceBrokerException if given name was <code>null</code>
0086:             */
0087:            public static PBKey extractAllTokens(String name) {
0088:                if (name == null) {
0089:                    throw new PersistenceBrokerException(
0090:                            "Could not extract PBKey, given argument is 'null'");
0091:                }
0092:                String user = null;
0093:                String passwd = null;
0094:                StringTokenizer tok = new StringTokenizer(name,
0095:                        REPOSITORY_NAME_SEPARATOR);
0096:                String dbName = tok.nextToken();
0097:                if (tok.hasMoreTokens()) {
0098:                    user = tok.nextToken();
0099:                    if (user != null && user.trim().equals("")) {
0100:                        user = null;
0101:                    }
0102:                }
0103:                if (tok.hasMoreTokens()) {
0104:                    if (user != null)
0105:                        passwd = tok.nextToken();
0106:                }
0107:                if (user != null && passwd == null) {
0108:                    passwd = "";
0109:                }
0110:                return new PBKey(dbName, user, passwd);
0111:            }
0112:
0113:            /**
0114:             * Check if the user of the given PBKey was <code>null</code>, if so we try to
0115:             * get user/password from the jdbc-connection-descriptor matching the given
0116:             * PBKey.getAlias().
0117:             */
0118:            public static PBKey crossCheckPBKey(PBKey key) {
0119:                if (key.getUser() == null) {
0120:                    PBKey defKey = MetadataManager.getInstance()
0121:                            .connectionRepository()
0122:                            .getStandardPBKeyForJcdAlias(key.getAlias());
0123:                    if (defKey != null) {
0124:                        return defKey;
0125:                    }
0126:                }
0127:                return key;
0128:            }
0129:
0130:            /**
0131:             * Answer the real ClassDescriptor for anObj
0132:             * ie. aCld may be an Interface of anObj, so the cld for anObj is returned
0133:             */
0134:            private ClassDescriptor getRealClassDescriptor(
0135:                    ClassDescriptor aCld, Object anObj) {
0136:                ClassDescriptor result;
0137:
0138:                if (aCld.getClassOfObject() == ProxyHelper.getRealClass(anObj)) {
0139:                    result = aCld;
0140:                } else {
0141:                    result = aCld.getRepository().getDescriptorFor(
0142:                            anObj.getClass());
0143:                }
0144:
0145:                return result;
0146:            }
0147:
0148:            /**
0149:             * Returns an Array with an Objects PK VALUES if convertToSql is true, any
0150:             * associated java-to-sql conversions are applied. If the Object is a Proxy
0151:             * or a VirtualProxy NO conversion is necessary.
0152:             *
0153:             * @param objectOrProxy
0154:             * @param convertToSql
0155:             * @return Object[]
0156:             * @throws PersistenceBrokerException
0157:             */
0158:            public ValueContainer[] getKeyValues(ClassDescriptor cld,
0159:                    Object objectOrProxy, boolean convertToSql)
0160:                    throws PersistenceBrokerException {
0161:                IndirectionHandler handler = ProxyHelper
0162:                        .getIndirectionHandler(objectOrProxy);
0163:
0164:                if (handler != null) {
0165:                    return getKeyValues(cld, handler.getIdentity(),
0166:                            convertToSql); //BRJ: convert Identity
0167:                } else {
0168:                    ClassDescriptor realCld = getRealClassDescriptor(cld,
0169:                            objectOrProxy);
0170:                    return getValuesForObject(realCld.getPkFields(),
0171:                            objectOrProxy, convertToSql);
0172:                }
0173:            }
0174:
0175:            /**
0176:             * Return primary key values of given Identity object.
0177:             *
0178:             * @param cld
0179:             * @param oid
0180:             * @return Object[]
0181:             * @throws PersistenceBrokerException
0182:             */
0183:            public ValueContainer[] getKeyValues(ClassDescriptor cld,
0184:                    Identity oid) throws PersistenceBrokerException {
0185:                return getKeyValues(cld, oid, true);
0186:            }
0187:
0188:            /**
0189:             * Return key Values of an Identity
0190:             * @param cld
0191:             * @param oid
0192:             * @param convertToSql
0193:             * @return Object[]
0194:             * @throws PersistenceBrokerException
0195:             */
0196:            public ValueContainer[] getKeyValues(ClassDescriptor cld,
0197:                    Identity oid, boolean convertToSql)
0198:                    throws PersistenceBrokerException {
0199:                FieldDescriptor[] pkFields = cld.getPkFields();
0200:                ValueContainer[] result = new ValueContainer[pkFields.length];
0201:                Object[] pkValues = oid.getPrimaryKeyValues();
0202:
0203:                try {
0204:                    for (int i = 0; i < result.length; i++) {
0205:                        FieldDescriptor fd = pkFields[i];
0206:                        Object cv = pkValues[i];
0207:                        if (convertToSql) {
0208:                            // BRJ : apply type and value mapping
0209:                            cv = fd.getFieldConversion().javaToSql(cv);
0210:                        }
0211:                        result[i] = new ValueContainer(cv, fd.getJdbcType());
0212:                    }
0213:                } catch (Exception e) {
0214:                    throw new PersistenceBrokerException(
0215:                            "Can't generate primary key values for given Identity "
0216:                                    + oid, e);
0217:                }
0218:                return result;
0219:            }
0220:
0221:            /**
0222:             * returns an Array with an Objects PK VALUES, with any java-to-sql
0223:             * FieldConversion applied. If the Object is a Proxy or a VirtualProxy NO
0224:             * conversion is necessary.
0225:             *
0226:             * @param objectOrProxy
0227:             * @return Object[]
0228:             * @throws PersistenceBrokerException
0229:             */
0230:            public ValueContainer[] getKeyValues(ClassDescriptor cld,
0231:                    Object objectOrProxy) throws PersistenceBrokerException {
0232:                return getKeyValues(cld, objectOrProxy, true);
0233:            }
0234:
0235:            /**
0236:             * Decide if the given object value represents 'null'.<br/>
0237:             *
0238:             * - If given value is 'null' itself, true will be returned<br/>
0239:             *
0240:             * - If given value is instance of Number with value 0 and the field-descriptor
0241:             * represents a primitive field, true will be returned<br/>
0242:             *
0243:             * - If given value is instance of String with length 0 and the field-descriptor
0244:             * is a primary key, true will be returned<br/>
0245:             */
0246:            public boolean representsNull(FieldDescriptor fld, Object aValue) {
0247:                if (aValue == null)
0248:                    return true;
0249:
0250:                boolean result = false;
0251:                if (((aValue instanceof  Number) && (((Number) aValue)
0252:                        .longValue() == 0))) {
0253:                    Class type = fld.getPersistentField().getType();
0254:                    /*
0255:                    AnonymousPersistentFields will *always* have a null type according to the
0256:                    javadoc comments in AnonymousPersistentField.getType() and never represents
0257:                    a primitve java field with value 0, thus we return always 'false' in this case.
0258:                    (If the value object is null, the first check above return true)
0259:                     */
0260:                    if (type != null) {
0261:                        result = type.isPrimitive();
0262:                    }
0263:                }
0264:                // TODO: Do we need this check?? String could be nullified, why should we assume
0265:                // it's 'null' on empty string?
0266:                else if ((aValue instanceof  String)
0267:                        && (((String) aValue).length() == 0)) {
0268:                    result = fld.isPrimaryKey();
0269:                }
0270:                return result;
0271:            }
0272:
0273:            /**
0274:             * Detect if the given object has a PK field represents a 'null' value.
0275:             */
0276:            public boolean hasNullPKField(ClassDescriptor cld, Object obj) {
0277:                FieldDescriptor[] fields = cld.getPkFields();
0278:                boolean hasNull = false;
0279:                // an unmaterialized proxy object can never have nullified PK's
0280:                IndirectionHandler handler = ProxyHelper
0281:                        .getIndirectionHandler(obj);
0282:                if (handler == null || handler.alreadyMaterialized()) {
0283:                    if (handler != null)
0284:                        obj = handler.getRealSubject();
0285:                    FieldDescriptor fld;
0286:                    for (int i = 0; i < fields.length; i++) {
0287:                        fld = fields[i];
0288:                        hasNull = representsNull(fld, fld.getPersistentField()
0289:                                .get(obj));
0290:                        if (hasNull)
0291:                            break;
0292:                    }
0293:                }
0294:                return hasNull;
0295:            }
0296:
0297:            /**
0298:             * Set an autoincremented value in given object field that has already
0299:             * had a field conversion run on it, if an value for the given field is
0300:             * already set, it will be overridden - no further checks are done.
0301:             * <p>
0302:             * The data type of the value that is returned by this method is
0303:             * compatible with the java-world.  The return value has <b>NOT</b>
0304:             * been run through a field conversion and converted to a corresponding
0305:             * sql-type.
0306:             *
0307:             * @return the autoincremented value set on given object
0308:             * @throws PersistenceBrokerException if there is an erros accessing obj field values
0309:             */
0310:            private Object setAutoIncrementValue(FieldDescriptor fd, Object obj) {
0311:                PersistentField f = fd.getPersistentField();
0312:                try {
0313:                    // lookup SeqMan for a value matching db column an
0314:                    Object result = m_broker.serviceSequenceManager()
0315:                            .getUniqueValue(fd);
0316:                    // reflect autoincrement value back into object
0317:                    f.set(obj, result);
0318:                    return result;
0319:                } catch (MetadataException e) {
0320:                    throw new PersistenceBrokerException(
0321:                            "Error while trying to autoincrement field "
0322:                                    + f.getDeclaringClass() + "#" + f.getName(),
0323:                            e);
0324:                } catch (SequenceManagerException e) {
0325:                    throw new PersistenceBrokerException(
0326:                            "Could not get key value", e);
0327:                }
0328:            }
0329:
0330:            /**
0331:             * Get the values of the fields for an obj
0332:             * Autoincrement values are automatically set.
0333:             * @param fields
0334:             * @param obj
0335:             * @throws PersistenceBrokerException
0336:             */
0337:            public ValueContainer[] getValuesForObject(
0338:                    FieldDescriptor[] fields, Object obj, boolean convertToSql,
0339:                    boolean assignAutoincrement)
0340:                    throws PersistenceBrokerException {
0341:                ValueContainer[] result = new ValueContainer[fields.length];
0342:
0343:                for (int i = 0; i < fields.length; i++) {
0344:                    FieldDescriptor fd = fields[i];
0345:                    Object cv = fd.getPersistentField().get(obj);
0346:
0347:                    /*
0348:                    handle autoincrement attributes if
0349:                    - is a autoincrement field
0350:                    - field represents a 'null' value, is nullified
0351:                    and generate a new value
0352:                     */
0353:                    if (assignAutoincrement && fd.isAutoIncrement()
0354:                            && representsNull(fd, cv)) {
0355:                        /*
0356:                        setAutoIncrementValue returns a value that is
0357:                        properly typed for the java-world.  This value
0358:                        needs to be converted to it's corresponding
0359:                        sql type so that the entire result array contains
0360:                        objects that are properly typed for sql.
0361:                         */
0362:                        cv = setAutoIncrementValue(fd, obj);
0363:                    }
0364:                    if (convertToSql) {
0365:                        // apply type and value conversion
0366:                        cv = fd.getFieldConversion().javaToSql(cv);
0367:                    }
0368:                    // create ValueContainer
0369:                    result[i] = new ValueContainer(cv, fd.getJdbcType());
0370:                }
0371:                return result;
0372:            }
0373:
0374:            public ValueContainer[] getValuesForObject(
0375:                    FieldDescriptor[] fields, Object obj, boolean convertToSql)
0376:                    throws PersistenceBrokerException {
0377:                return getValuesForObject(fields, obj, convertToSql, false);
0378:            }
0379:
0380:            /**
0381:             * Returns an array containing values for all non PK field READ/WRITE attributes of the object
0382:             * based on the specified {@link org.apache.ojb.broker.metadata.ClassDescriptor}.
0383:             * <br/>
0384:             * NOTE: This method doesn't do any checks on the specified {@link org.apache.ojb.broker.metadata.ClassDescriptor}
0385:             * the caller is reponsible to pass a valid descriptor.
0386:             *
0387:             * @param cld The {@link org.apache.ojb.broker.metadata.ClassDescriptor} to extract the RW-fields
0388:             * @param obj The object with target fields to extract.
0389:             * @throws MetadataException if there is an erros accessing obj field values
0390:             */
0391:            public ValueContainer[] getNonKeyRwValues(ClassDescriptor cld,
0392:                    Object obj) throws PersistenceBrokerException {
0393:                return getValuesForObject(cld.getNonPkRwFields(), obj, true);
0394:            }
0395:
0396:            /**
0397:             * Returns an array containing values for all READ/WRITE attributes of the object
0398:             * based on the specified {@link org.apache.ojb.broker.metadata.ClassDescriptor}.
0399:             * <br/>
0400:             * NOTE: This method doesn't do any checks on the specified {@link org.apache.ojb.broker.metadata.ClassDescriptor}
0401:             * the caller is reponsible to pass a valid descriptor.
0402:             *
0403:             * @param cld The {@link org.apache.ojb.broker.metadata.ClassDescriptor} to extract the RW-fields
0404:             * @param obj The object with target fields to extract.
0405:             * @throws MetadataException if there is an erros accessing obj field values
0406:             */
0407:            public ValueContainer[] getAllRwValues(ClassDescriptor cld,
0408:                    Object obj) throws PersistenceBrokerException {
0409:                return getValuesForObject(cld.getAllRwFields(), obj, true);
0410:            }
0411:
0412:            /**
0413:             * Extract an value array of the given {@link ValueContainer} array.
0414:             * @param containers
0415:             * @return An object array
0416:             */
0417:            public Object[] extractValueArray(ValueContainer[] containers) {
0418:                Object[] result = new Object[containers.length];
0419:                for (int i = 0; i < containers.length; i++) {
0420:                    result[i] = containers[i].getValue();
0421:                }
0422:                return result;
0423:            }
0424:
0425:            /**
0426:             * returns true if the primary key fields are valid for store, else false.
0427:             * PK fields are valid if each of them is either an OJB managed
0428:             * attribute (autoincrement or locking) or if it contains
0429:             * a valid non-null value
0430:             * @param fieldDescriptors the array of PK fielddescriptors
0431:             * @param pkValues the array of PK values
0432:             * @return boolean
0433:             */
0434:            public boolean assertValidPksForStore(
0435:                    FieldDescriptor[] fieldDescriptors, Object[] pkValues) {
0436:                int fieldDescriptorSize = fieldDescriptors.length;
0437:                for (int i = 0; i < fieldDescriptorSize; i++) {
0438:                    FieldDescriptor fld = fieldDescriptors[i];
0439:                    /**
0440:                     * a pk field is valid if it is either managed by OJB
0441:                     * (autoincrement or locking) or if it does contain a
0442:                     * valid non-null value.
0443:                     */
0444:                    if (!(fld.isAutoIncrement() || fld.isLocking() || !representsNull(
0445:                            fld, pkValues[i]))) {
0446:                        return false;
0447:                    }
0448:                }
0449:                return true;
0450:            }
0451:
0452:            /**
0453:             * returns true if the primary key fields are valid for delete, else false.
0454:             * PK fields are valid if each of them contains a valid non-null value
0455:             * @param cld the ClassDescriptor
0456:             * @param obj the object
0457:             * @return boolean
0458:             */
0459:            public boolean assertValidPkForDelete(ClassDescriptor cld,
0460:                    Object obj) {
0461:                if (!ProxyHelper.isProxy(obj)) {
0462:                    FieldDescriptor fieldDescriptors[] = cld.getPkFields();
0463:                    int fieldDescriptorSize = fieldDescriptors.length;
0464:                    for (int i = 0; i < fieldDescriptorSize; i++) {
0465:                        FieldDescriptor fd = fieldDescriptors[i];
0466:                        Object pkValue = fd.getPersistentField().get(obj);
0467:                        if (representsNull(fd, pkValue)) {
0468:                            return false;
0469:                        }
0470:                    }
0471:                }
0472:                return true;
0473:            }
0474:
0475:            /**
0476:             * Build a Count-Query based on aQuery
0477:             * @param aQuery
0478:             * @return The count query
0479:             */
0480:            public Query getCountQuery(Query aQuery) {
0481:                if (aQuery instanceof  QueryBySQL) {
0482:                    return getQueryBySqlCount((QueryBySQL) aQuery);
0483:                } else if (aQuery instanceof  ReportQueryByCriteria) {
0484:                    return getReportQueryByCriteriaCount((ReportQueryByCriteria) aQuery);
0485:                } else {
0486:                    return getQueryByCriteriaCount((QueryByCriteria) aQuery);
0487:                }
0488:            }
0489:
0490:            /**
0491:             * Create a Count-Query for QueryBySQL
0492:             *
0493:             * @param aQuery
0494:             * @return The count query
0495:             */
0496:            private Query getQueryBySqlCount(QueryBySQL aQuery) {
0497:                String countSql = aQuery.getSql();
0498:
0499:                int fromPos = countSql.toUpperCase().indexOf(" FROM ");
0500:                if (fromPos >= 0) {
0501:                    countSql = "select count(*)" + countSql.substring(fromPos);
0502:                }
0503:
0504:                int orderPos = countSql.toUpperCase().indexOf(" ORDER BY ");
0505:                if (orderPos >= 0) {
0506:                    countSql = countSql.substring(0, orderPos);
0507:                }
0508:
0509:                return new QueryBySQL(aQuery.getSearchClass(), countSql);
0510:            }
0511:
0512:            /**
0513:             * Create a Count-Query for QueryByCriteria
0514:             */
0515:            private Query getQueryByCriteriaCount(QueryByCriteria aQuery) {
0516:                Class searchClass = aQuery.getSearchClass();
0517:                ReportQueryByCriteria countQuery = null;
0518:                Criteria countCrit = null;
0519:                String[] columns = new String[1];
0520:
0521:                // BRJ: copied Criteria without groupby, orderby, and prefetched relationships
0522:                if (aQuery.getCriteria() != null) {
0523:                    countCrit = aQuery.getCriteria().copy(false, false, false);
0524:                }
0525:
0526:                if (aQuery.isDistinct()) {
0527:                    // BRJ: Count distinct is dbms dependent
0528:                    // hsql/sapdb: select count (distinct(person_id || project_id)) from person_project
0529:                    // mysql: select count (distinct person_id,project_id) from person_project
0530:                    // [tomdz]
0531:                    // Some databases have no support for multi-column count distinct (e.g. Derby)
0532:                    // Here we use a SELECT count(*) FROM (SELECT DISTINCT ...) instead 
0533:                    //
0534:                    // concatenation of pk-columns is a simple way to obtain a single column
0535:                    // but concatenation is also dbms dependent:
0536:                    //
0537:                    // SELECT count(distinct concat(row1, row2, row3)) mysql
0538:                    // SELECT count(distinct (row1 || row2 || row3)) ansi
0539:                    // SELECT count(distinct (row1 + row2 + row3)) ms sql-server
0540:
0541:                    FieldDescriptor[] pkFields = m_broker.getClassDescriptor(
0542:                            searchClass).getPkFields();
0543:                    String[] keyColumns = new String[pkFields.length];
0544:
0545:                    if (pkFields.length > 1) {
0546:                        // TODO: Use ColumnName. This is a temporary solution because
0547:                        // we cannot yet resolve multiple columns in the same attribute.
0548:                        for (int idx = 0; idx < pkFields.length; idx++) {
0549:                            keyColumns[idx] = pkFields[idx].getColumnName();
0550:                        }
0551:                    } else {
0552:                        for (int idx = 0; idx < pkFields.length; idx++) {
0553:                            keyColumns[idx] = pkFields[idx].getAttributeName();
0554:                        }
0555:                    }
0556:                    // [tomdz]
0557:                    // TODO: Add support for databases that do not support COUNT DISTINCT over multiple columns
0558:                    //            if (getPlatform().supportsMultiColumnCountDistinct())
0559:                    //            {
0560:                    //                columns[0] = "count(distinct " + getPlatform().concatenate(keyColumns) + ")";
0561:                    //            }
0562:                    //            else
0563:                    //            {
0564:                    //                columns = keyColumns;
0565:                    //            }
0566:
0567:                    columns[0] = "count(distinct "
0568:                            + getPlatform().concatenate(keyColumns) + ")";
0569:                } else {
0570:                    columns[0] = "count(*)";
0571:                }
0572:
0573:                // BRJ: we have to preserve indirection table !
0574:                if (aQuery instanceof  MtoNQuery) {
0575:                    MtoNQuery mnQuery = (MtoNQuery) aQuery;
0576:                    ReportQueryByMtoNCriteria mnReportQuery = new ReportQueryByMtoNCriteria(
0577:                            searchClass, columns, countCrit);
0578:
0579:                    mnReportQuery.setIndirectionTable(mnQuery
0580:                            .getIndirectionTable());
0581:                    countQuery = mnReportQuery;
0582:                } else {
0583:                    countQuery = new ReportQueryByCriteria(searchClass,
0584:                            columns, countCrit);
0585:                }
0586:
0587:                // BRJ: we have to preserve outer-join-settings (by André Markwalder)
0588:                for (Iterator outerJoinPath = aQuery.getOuterJoinPaths()
0589:                        .iterator(); outerJoinPath.hasNext();) {
0590:                    String path = (String) outerJoinPath.next();
0591:
0592:                    if (aQuery.isPathOuterJoin(path)) {
0593:                        countQuery.setPathOuterJoin(path);
0594:                    }
0595:                }
0596:
0597:                //BRJ: add orderBy Columns asJoinAttributes
0598:                List orderBy = aQuery.getOrderBy();
0599:
0600:                if ((orderBy != null) && !orderBy.isEmpty()) {
0601:                    String[] joinAttributes = new String[orderBy.size()];
0602:
0603:                    for (int idx = 0; idx < orderBy.size(); idx++) {
0604:                        joinAttributes[idx] = ((FieldHelper) orderBy.get(idx)).name;
0605:                    }
0606:                    countQuery.setJoinAttributes(joinAttributes);
0607:                }
0608:
0609:                // [tomdz]
0610:                // TODO:
0611:                // For those databases that do not support COUNT DISTINCT over multiple columns
0612:                // we wrap the normal SELECT DISTINCT that we just created, into a SELECT count(*)
0613:                // For this however we need a report query that gets its data from a sub query instead
0614:                // of a table (target class)
0615:                //        if (aQuery.isDistinct() && !getPlatform().supportsMultiColumnCountDistinct())
0616:                //        {
0617:                //        }
0618:
0619:                return countQuery;
0620:            }
0621:
0622:            /**
0623:             * Create a Count-Query for ReportQueryByCriteria
0624:             */
0625:            private Query getReportQueryByCriteriaCount(
0626:                    ReportQueryByCriteria aQuery) {
0627:                ReportQueryByCriteria countQuery = (ReportQueryByCriteria) getQueryByCriteriaCount(aQuery);
0628:
0629:                // BRJ: keep the original columns to build the Join
0630:                countQuery.setJoinAttributes(aQuery.getAttributes());
0631:
0632:                // BRJ: we have to preserve groupby information
0633:                Iterator iter = aQuery.getGroupBy().iterator();
0634:                while (iter.hasNext()) {
0635:                    countQuery.addGroupBy((FieldHelper) iter.next());
0636:                }
0637:
0638:                return countQuery;
0639:            }
0640:
0641:            /**
0642:             * answer the platform
0643:             *
0644:             * @return the platform
0645:             */
0646:            private Platform getPlatform() {
0647:                return m_broker.serviceSqlGenerator().getPlatform();
0648:            }
0649:
0650:            /*
0651:            NOTE: use weak key references to allow reclaiming
0652:            of no longer used ClassDescriptor instances
0653:             */
0654:            private Map sqlSelectMap = new ReferenceIdentityMap(
0655:                    ReferenceIdentityMap.WEAK, ReferenceIdentityMap.HARD);
0656:
0657:            /**
0658:             * TODO: This method should be moved to {@link org.apache.ojb.broker.accesslayer.JdbcAccess}
0659:             * before 1.1 release.
0660:             *
0661:             * This method checks if the requested object can be
0662:             * found in database (without object materialization).
0663:             *
0664:             * @param cld The {@link org.apache.ojb.broker.metadata.ClassDescriptor} of the
0665:             * object/{@link org.apache.ojb.broker.Identity} to check.
0666:             * @param obj The <em>object</em> to check.
0667:             * @param oid The associated {@link org.apache.ojb.broker.Identity}.
0668:             * {@link org.apache.ojb.broker.Identity} of the object
0669:             * @return Return <em>true</em> if the object is already persisted, <em>false</em> if the object is transient.
0670:             */
0671:            public boolean doesExist(ClassDescriptor cld, Identity oid,
0672:                    Object obj) {
0673:                boolean result = false;
0674:                String sql = (String) sqlSelectMap.get(cld);
0675:                if (sql == null) {
0676:                    sql = new SqlExistStatement(cld, LoggerFactory
0677:                            .getDefaultLogger()).getStatement();
0678:                    sqlSelectMap.put(cld, sql);
0679:                }
0680:                ValueContainer[] pkValues;
0681:                if (oid == null) {
0682:                    pkValues = getKeyValues(cld, obj, true);
0683:                } else {
0684:                    pkValues = getKeyValues(cld, oid);
0685:                }
0686:                StatementManagerIF sm = m_broker.serviceStatementManager();
0687:                PreparedStatement stmt = null;
0688:                ResultSet rs = null;
0689:                try {
0690:                    stmt = sm.getPreparedStatement(cld, sql, false, 1, false);
0691:                    sm.bindValues(stmt, pkValues, 1);
0692:                    rs = stmt.executeQuery();
0693:                    result = rs.next();
0694:                } catch (SQLException e) {
0695:                    throw ExceptionHelper.generateException(
0696:                            "[BrokerHelper#doesExist] Can't check if specified"
0697:                                    + " object is already persisted", e, sql,
0698:                            cld, pkValues, null, obj);
0699:                } finally {
0700:                    sm.closeResources(stmt, rs);
0701:                }
0702:
0703:                return result;
0704:            }
0705:
0706:            /**
0707:             * This method concatenate the main object with all reference
0708:             * objects (1:1, 1:n and m:n) by hand. This method is needed when
0709:             * in the reference metadata definitions the auto-xxx setting was disabled.
0710:             * More info see OJB doc.
0711:             */
0712:            public void link(Object obj, boolean insert) {
0713:                linkOrUnlink(true, obj, insert);
0714:            }
0715:
0716:            /**
0717:             * Unlink all references from this object.
0718:             * More info see OJB doc.
0719:             * @param obj Object with reference
0720:             */
0721:            public void unlink(Object obj) {
0722:                linkOrUnlink(false, obj, false);
0723:            }
0724:
0725:            private void linkOrUnlink(boolean doLink, Object obj, boolean insert) {
0726:                ClassDescriptor cld = m_broker.getDescriptorRepository()
0727:                        .getDescriptorFor(obj.getClass());
0728:
0729:                if (cld.getObjectReferenceDescriptors().size() > 0) {
0730:                    // never returns null, thus we can direct call iterator
0731:                    Iterator descriptors = cld.getObjectReferenceDescriptors()
0732:                            .iterator();
0733:                    while (descriptors.hasNext()) {
0734:                        ObjectReferenceDescriptor ord = (ObjectReferenceDescriptor) descriptors
0735:                                .next();
0736:                        linkOrUnlinkOneToOne(doLink, obj, ord, insert);
0737:                    }
0738:                }
0739:                if (cld.getCollectionDescriptors().size() > 0) {
0740:                    // never returns null, thus we can direct call iterator
0741:                    Iterator descriptors = cld.getCollectionDescriptors()
0742:                            .iterator();
0743:                    while (descriptors.hasNext()) {
0744:                        CollectionDescriptor cod = (CollectionDescriptor) descriptors
0745:                                .next();
0746:                        linkOrUnlinkXToMany(doLink, obj, cod, insert);
0747:                    }
0748:                }
0749:            }
0750:
0751:            /**
0752:             * This method concatenate the main object and the specified reference
0753:             * object (1:1 reference a referenced object, 1:n and m:n reference a
0754:             * collection of referenced objects) by hand. This method is needed when
0755:             * in the reference metadata definitions the auto-xxx setting was disabled.
0756:             * More info see OJB doc.
0757:             *
0758:             * @param obj Object with reference
0759:             * @param ord the ObjectReferenceDescriptor of the reference
0760:             * @param insert flag signals insert operation
0761:             */
0762:            public void link(Object obj, ObjectReferenceDescriptor ord,
0763:                    boolean insert) {
0764:                linkOrUnlink(true, obj, ord, insert);
0765:            }
0766:
0767:            /**
0768:             * This method concatenate the main object and the specified reference
0769:             * object (1:1 reference a referenced object, 1:n and m:n reference a
0770:             * collection of referenced objects) by hand. This method is needed when
0771:             * in the reference metadata definitions the auto-xxx setting was disabled.
0772:             * More info see OJB doc.
0773:             *
0774:             * @param obj Object with reference
0775:             * @param attributeName field name of the reference
0776:             * @param insert flag signals insert operation
0777:             * @return true if the specified reference was found and linking was successful
0778:             */
0779:            public boolean link(Object obj, String attributeName, boolean insert) {
0780:                return linkOrUnlink(true, obj, attributeName, insert);
0781:            }
0782:
0783:            /**
0784:             * This method concatenate the main object and the specified reference
0785:             * object (1:1 reference a referenced object, 1:n and m:n reference a
0786:             * collection of referenced objects) by hand. This method is needed when
0787:             * in the reference metadata definitions the auto-xxx setting was disabled.
0788:             * More info see OJB doc.
0789:             *
0790:             * @param obj Object with reference
0791:             * @param attributeName field name of the reference
0792:             * @param reference The referenced object
0793:             * @param insert flag signals insert operation
0794:             * @return true if the specified reference was found and linking was successful
0795:             */
0796:            public boolean link(Object obj, String attributeName,
0797:                    Object reference, boolean insert) {
0798:                ClassDescriptor cld = m_broker.getDescriptorRepository()
0799:                        .getDescriptorFor(ProxyHelper.getRealClass(obj));
0800:                ObjectReferenceDescriptor ord;
0801:                boolean match = false;
0802:                // first look for reference then for collection
0803:                ord = cld.getObjectReferenceDescriptorByName(attributeName);
0804:                if (ord != null) {
0805:                    linkOrUnlinkOneToOne(true, obj, ord, insert);
0806:                    match = true;
0807:                } else {
0808:                    CollectionDescriptor cod = cld
0809:                            .getCollectionDescriptorByName(attributeName);
0810:                    if (cod != null) {
0811:                        linkOrUnlinkXToMany(true, obj, cod, insert);
0812:                        match = true;
0813:                    }
0814:                }
0815:                return match;
0816:            }
0817:
0818:            /**
0819:             * Unlink the specified reference object.
0820:             * More info see OJB doc.
0821:             * @param source The source object with the specified reference field.
0822:             * @param attributeName The field name of the reference to unlink.
0823:             * @param target The referenced object to unlink.
0824:             */
0825:            public boolean unlink(Object source, String attributeName,
0826:                    Object target) {
0827:                return linkOrUnlink(false, source, attributeName, false);
0828:            }
0829:
0830:            /**
0831:             * Unlink all referenced objects of the specified field.
0832:             * More info see OJB doc.
0833:             * @param source The source object with the specified reference.
0834:             * @param attributeName The field name of the reference to unlink.
0835:             */
0836:            public boolean unlink(Object source, String attributeName) {
0837:                return linkOrUnlink(false, source, attributeName, false);
0838:            }
0839:
0840:            /**
0841:             * Unlink the specified reference from this object.
0842:             * More info see OJB doc.
0843:             *
0844:             * @param obj Object with reference
0845:             * @param ord the ObjectReferenceDescriptor of the reference
0846:             * @param insert flag signals insert operation
0847:             */
0848:            public void unlink(Object obj, ObjectReferenceDescriptor ord,
0849:                    boolean insert) {
0850:                linkOrUnlink(false, obj, ord, insert);
0851:            }
0852:
0853:            private boolean linkOrUnlink(boolean doLink, Object obj,
0854:                    String attributeName, boolean insert) {
0855:                boolean match = false;
0856:                ClassDescriptor cld = m_broker.getDescriptorRepository()
0857:                        .getDescriptorFor(ProxyHelper.getRealClass(obj));
0858:                ObjectReferenceDescriptor ord;
0859:
0860:                // first look for reference then for collection
0861:                ord = cld.getObjectReferenceDescriptorByName(attributeName);
0862:                if (ord != null) {
0863:                    linkOrUnlinkOneToOne(doLink, obj, ord, insert);
0864:                    match = true;
0865:                } else {
0866:                    CollectionDescriptor cod = cld
0867:                            .getCollectionDescriptorByName(attributeName);
0868:                    if (cod != null) {
0869:                        linkOrUnlinkXToMany(doLink, obj, cod, insert);
0870:                        match = true;
0871:                    }
0872:                }
0873:
0874:                return match;
0875:            }
0876:
0877:            private void linkOrUnlink(boolean doLink, Object obj,
0878:                    ObjectReferenceDescriptor ord, boolean insert) {
0879:                if (ord instanceof  CollectionDescriptor) {
0880:                    linkOrUnlinkXToMany(doLink, obj,
0881:                            (CollectionDescriptor) ord, insert);
0882:                } else {
0883:                    linkOrUnlinkOneToOne(doLink, obj, ord, insert);
0884:                }
0885:            }
0886:
0887:            private void linkOrUnlinkXToMany(boolean doLink, Object obj,
0888:                    CollectionDescriptor cod, boolean insert) {
0889:                if (doLink) {
0890:                    if (cod.isMtoNRelation()) {
0891:                        m_broker.linkMtoN(obj, cod, insert);
0892:                    } else {
0893:                        m_broker.linkOneToMany(obj, cod, insert);
0894:                    }
0895:                } else {
0896:                    m_broker.unlinkXtoN(obj, cod);
0897:                }
0898:            }
0899:
0900:            private void linkOrUnlinkOneToOne(boolean doLink, Object obj,
0901:                    ObjectReferenceDescriptor ord, boolean insert) {
0902:                /*
0903:                arminw: we need the class-descriptor where the reference is declared, thus we ask the
0904:                reference-descriptor for this, instead of using the class-descriptor of the specified
0905:                object. If the reference was declared within an interface (should never happen) we
0906:                only can use the descriptor of the real class.
0907:                 */
0908:                ClassDescriptor cld = ord.getClassDescriptor();
0909:                if (cld.isInterface()) {
0910:                    cld = m_broker.getDescriptorRepository().getDescriptorFor(
0911:                            ProxyHelper.getRealClass(obj));
0912:                }
0913:
0914:                if (doLink) {
0915:                    m_broker.linkOneToOne(obj, cld, ord, insert);
0916:                } else {
0917:                    m_broker.unlinkFK(obj, cld, ord);
0918:                    // in 1:1 relation we have to set relation to null
0919:                    ord.getPersistentField().set(obj, null);
0920:                }
0921:            }
0922:
0923:            /**
0924:             * Unlink a bunch of 1:n or m:n objects.
0925:             *
0926:             * @param source The source object with reference.
0927:             * @param cds The {@link org.apache.ojb.broker.metadata.CollectionDescriptor} of the relation.
0928:             * @param referencesToUnlink List of referenced objects to unlink.
0929:             */
0930:            public void unlink(Object source, CollectionDescriptor cds,
0931:                    List referencesToUnlink) {
0932:                for (int i = 0; i < referencesToUnlink.size(); i++) {
0933:                    unlink(source, cds, referencesToUnlink.get(i));
0934:                }
0935:            }
0936:
0937:            /**
0938:             * Unlink a single 1:n or m:n object.
0939:             *
0940:             * @param source The source object with reference.
0941:             * @param cds The {@link org.apache.ojb.broker.metadata.CollectionDescriptor} of the relation.
0942:             * @param referenceToUnlink The referenced object to link.
0943:             */
0944:            public void unlink(Object source, CollectionDescriptor cds,
0945:                    Object referenceToUnlink) {
0946:                if (cds.isMtoNRelation()) {
0947:                    m_broker.deleteMtoNImplementor(new MtoNImplementor(cds,
0948:                            source, referenceToUnlink));
0949:                } else {
0950:                    ClassDescriptor cld = m_broker
0951:                            .getClassDescriptor(referenceToUnlink.getClass());
0952:                    m_broker.unlinkFK(referenceToUnlink, cld, cds);
0953:                }
0954:            }
0955:
0956:            /**
0957:             * Link a bunch of 1:n or m:n objects.
0958:             *
0959:             * @param source The source object with reference.
0960:             * @param cds The {@link org.apache.ojb.broker.metadata.CollectionDescriptor} of the relation.
0961:             * @param referencesToLink List of referenced objects to link.
0962:             */
0963:            public void link(Object source, CollectionDescriptor cds,
0964:                    List referencesToLink) {
0965:                for (int i = 0; i < referencesToLink.size(); i++) {
0966:                    link(source, cds, referencesToLink.get(i));
0967:                }
0968:            }
0969:
0970:            /**
0971:             * Link a single 1:n or m:n object.
0972:             *
0973:             * @param source The source object with the declared reference.
0974:             * @param cds The {@link org.apache.ojb.broker.metadata.CollectionDescriptor} of the relation declared in source object.
0975:             * @param referenceToLink The referenced object to link.
0976:             */
0977:            public void link(Object source, CollectionDescriptor cds,
0978:                    Object referenceToLink) {
0979:                if (cds.isMtoNRelation()) {
0980:                    m_broker.addMtoNImplementor(new MtoNImplementor(cds,
0981:                            source, referenceToLink));
0982:                } else {
0983:                    ClassDescriptor cld = m_broker
0984:                            .getClassDescriptor(referenceToLink.getClass());
0985:                    m_broker.link(referenceToLink, cld, cds, source, false);
0986:                }
0987:            }
0988:
0989:            /**
0990:             * Returns an Iterator instance for {@link java.util.Collection}, object Array or
0991:             * {@link org.apache.ojb.broker.ManageableCollection} instances.
0992:             *
0993:             * @param collectionOrArray a none <em>null</em> object of type {@link java.util.Collection},
0994:             * Array or {@link org.apache.ojb.broker.ManageableCollection}.
0995:             * @return Iterator able to handle given collection object
0996:             */
0997:            public static Iterator getCollectionIterator(
0998:                    Object collectionOrArray) {
0999:                Iterator colIterator;
1000:                if (collectionOrArray instanceof  ManageableCollection) {
1001:                    colIterator = ((ManageableCollection) collectionOrArray)
1002:                            .ojbIterator();
1003:                } else if (collectionOrArray instanceof  Collection) {
1004:                    colIterator = ((Collection) collectionOrArray).iterator();
1005:                } else if (collectionOrArray.getClass().isArray()) {
1006:                    colIterator = new ArrayIterator(collectionOrArray);
1007:                } else {
1008:                    throw new OJBRuntimeException(
1009:                            "Given object collection of type '"
1010:                                    + (collectionOrArray != null ? collectionOrArray
1011:                                            .getClass().toString()
1012:                                            : "null")
1013:                                    + "' can not be managed by OJB. Use Array, Collection or ManageableCollection instead!");
1014:                }
1015:                return colIterator;
1016:            }
1017:
1018:            /**
1019:             * Returns an object array for {@link java.util.Collection}, array or
1020:             * {@link org.apache.ojb.broker.ManageableCollection} instances.
1021:             *
1022:             * @param collectionOrArray a none <em>null</em> object of type {@link java.util.Collection},
1023:             * Array or {@link org.apache.ojb.broker.ManageableCollection}.
1024:             * @return Object array able to handle given collection or array object
1025:             */
1026:            public static Object[] getCollectionArray(Object collectionOrArray) {
1027:                Object[] result;
1028:                if (collectionOrArray instanceof  Collection) {
1029:                    result = ((Collection) collectionOrArray).toArray();
1030:                } else if (collectionOrArray instanceof  ManageableCollection) {
1031:                    Collection newCol = new ArrayList();
1032:                    CollectionUtils.addAll(newCol,
1033:                            ((ManageableCollection) collectionOrArray)
1034:                                    .ojbIterator());
1035:                    result = newCol.toArray();
1036:                } else if (collectionOrArray.getClass().isArray()) {
1037:                    result = (Object[]) collectionOrArray;
1038:                } else {
1039:                    throw new OJBRuntimeException(
1040:                            "Given object collection of type '"
1041:                                    + (collectionOrArray != null ? collectionOrArray
1042:                                            .getClass().toString()
1043:                                            : "null")
1044:                                    + "' can not be managed by OJB. Use Array, Collection or ManageableCollection instead!");
1045:                }
1046:                return result;
1047:            }
1048:
1049:            /**
1050:             * Returns <em>true</em> if one or more anonymous FK fields are used.
1051:             * @param cld The {@link org.apache.ojb.broker.metadata.ClassDescriptor} of the main object.
1052:             * @param rds The {@link org.apache.ojb.broker.metadata.ObjectReferenceDescriptor} of the referenced object.
1053:             * @return <em>true</em> if one or more anonymous FK fields are used for specified reference.
1054:             */
1055:            public static boolean hasAnonymousKeyReference(ClassDescriptor cld,
1056:                    ObjectReferenceDescriptor rds) {
1057:                boolean result = false;
1058:                FieldDescriptor[] fkFields = rds
1059:                        .getForeignKeyFieldDescriptors(cld);
1060:                for (int i = 0; i < fkFields.length; i++) {
1061:                    FieldDescriptor fkField = fkFields[i];
1062:                    if (fkField.isAnonymous()) {
1063:                        result = true;
1064:                        break;
1065:                    }
1066:                }
1067:                return result;
1068:            }
1069:
1070:            //    /**
1071:            //     * Use this method to extract the {@link org.apache.ojb.broker.metadata.ClassDescriptor} where
1072:            //     * the {@link org.apache.ojb.broker.metadata.ObjectReferenceDescriptor reference} is declared.
1073:            //     * It's possible that the reference is declared in a super-class.
1074:            //     * @param broker
1075:            //     * @param reference
1076:            //     * @param source
1077:            //     * @return
1078:            //     */
1079:            //    public static ClassDescriptor extractDescriptorForReference(PersistenceBroker broker, ObjectReferenceDescriptor reference, Object source)
1080:            //    {
1081:            //        /*
1082:            //        arminw: we need the class-descriptor where the reference is declared, thus we ask the
1083:            //        reference-descriptor for this, instead of using the class-descriptor of the specified
1084:            //        object. If the reference was declared within an interface (should never happen) we
1085:            //        only can use the descriptor of the real class.
1086:            //        */
1087:            //        ClassDescriptor cld = reference.getClassDescriptor();
1088:            //        if(cld.isInterface())
1089:            //        {
1090:            //            cld = broker.getDescriptorRepository().getDescriptorFor(ProxyHelper.getRealClass(source));
1091:            //        }
1092:            //        return cld;
1093:            //    }
1094:
1095:            //    /**
1096:            //     * Returns a {@link java.util.List} instance of the specified object in method argument,
1097:            //     * in which the argument must be of type {@link java.util.Collection}, array or
1098:            //     * {@link org.apache.ojb.broker.ManageableCollection}.
1099:            //     *
1100:            //     * @param collectionOrArray a none <em>null</em> object of type {@link java.util.Collection},
1101:            //     * Array or {@link org.apache.ojb.broker.ManageableCollection}.
1102:            //     * @return Object array able to handle given collection or array object
1103:            //     */
1104:            //    public static List getCollectionList(Object collectionOrArray)
1105:            //    {
1106:            //        List result = null;
1107:            //        if (collectionOrArray instanceof Collection)
1108:            //        {
1109:            //            result = ((Collection) collectionOrArray).toArray();
1110:            //        }
1111:            //        else if (collectionOrArray instanceof ManageableCollection)
1112:            //        {
1113:            //            Collection newCol = new ArrayList();
1114:            //            CollectionUtils.addAll(newCol, ((ManageableCollection) collectionOrArray).ojbIterator());
1115:            //            result = newCol.toArray();
1116:            //        }
1117:            //        else if (collectionOrArray.getClass().isArray())
1118:            //        {
1119:            //            result = (Object[]) collectionOrArray;
1120:            //        }
1121:            //        else
1122:            //        {
1123:            //            throw new OJBRuntimeException( "Given object collection of type '"
1124:            //                    + (collectionOrArray != null ? collectionOrArray.getClass().toString() : "null")
1125:            //                + "' can not be managed by OJB. Use Array, Collection or ManageableCollection instead!");
1126:            //        }
1127:            //        return result;
1128:            //    }
1129:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.