Source Code Cross Referenced for JDBCExecutor.java in  » J2EE » Expresso » com » jcorporate » expresso » core » dataobjects » jdbc » 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 » J2EE » Expresso » com.jcorporate.expresso.core.dataobjects.jdbc 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /* ====================================================================
0002:         * The Jcorporate Apache Style Software License, Version 1.2 05-07-2002
0003:         *
0004:         * Copyright (c) 1995-2002 Jcorporate Ltd. All rights reserved.
0005:         *
0006:         * Redistribution and use in source and binary forms, with or without
0007:         * modification, are permitted provided that the following conditions
0008:         * are met:
0009:         *
0010:         * 1. Redistributions of source code must retain the above copyright
0011:         *    notice, this list of conditions and the following disclaimer.
0012:         *
0013:         * 2. Redistributions in binary form must reproduce the above copyright
0014:         *    notice, this list of conditions and the following disclaimer in
0015:         *    the documentation and/or other materials provided with the
0016:         *    distribution.
0017:         *
0018:         * 3. The end-user documentation included with the redistribution,
0019:         *    if any, must include the following acknowledgment:
0020:         *       "This product includes software developed by Jcorporate Ltd.
0021:         *        (http://www.jcorporate.com/)."
0022:         *    Alternately, this acknowledgment may appear in the software itself,
0023:         *    if and wherever such third-party acknowledgments normally appear.
0024:         *
0025:         * 4. "Jcorporate" and product names such as "Expresso" must
0026:         *    not be used to endorse or promote products derived from this
0027:         *    software without prior written permission. For written permission,
0028:         *    please contact info@jcorporate.com.
0029:         *
0030:         * 5. Products derived from this software may not be called "Expresso",
0031:         *    or other Jcorporate product names; nor may "Expresso" or other
0032:         *    Jcorporate product names appear in their name, without prior
0033:         *    written permission of Jcorporate Ltd.
0034:         *
0035:         * 6. No product derived from this software may compete in the same
0036:         *    market space, i.e. framework, without prior written permission
0037:         *    of Jcorporate Ltd. For written permission, please contact
0038:         *    partners@jcorporate.com.
0039:         *
0040:         * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
0041:         * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
0042:         * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
0043:         * DISCLAIMED.  IN NO EVENT SHALL JCORPORATE LTD OR ITS CONTRIBUTORS
0044:         * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
0045:         * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
0046:         * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
0047:         * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
0048:         * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
0049:         * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
0050:         * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
0051:         * SUCH DAMAGE.
0052:         * ====================================================================
0053:         *
0054:         * This software consists of voluntary contributions made by many
0055:         * individuals on behalf of the Jcorporate Ltd. Contributions back
0056:         * to the project(s) are encouraged when you make modifications.
0057:         * Please send them to support@jcorporate.com. For more information
0058:         * on Jcorporate Ltd. and its products, please see
0059:         * <http://www.jcorporate.com/>.
0060:         *
0061:         * Portions of this software are based upon other open source
0062:         * products and are subject to their respective licenses.
0063:         */
0064:
0065:        package com.jcorporate.expresso.core.dataobjects.jdbc;
0066:
0067:        import com.jcorporate.expresso.core.dataobjects.DataException;
0068:        import com.jcorporate.expresso.core.dataobjects.DataExecutorInterface;
0069:        import com.jcorporate.expresso.core.dataobjects.DataField;
0070:        import com.jcorporate.expresso.core.dataobjects.DataFieldMetaData;
0071:        import com.jcorporate.expresso.core.dataobjects.DataObject;
0072:        import com.jcorporate.expresso.core.dataobjects.DataObjectMetaData;
0073:        import com.jcorporate.expresso.core.dataobjects.DuplicateKeyException;
0074:        import com.jcorporate.expresso.core.db.DBConnection;
0075:        import com.jcorporate.expresso.core.db.DBConnectionPool;
0076:        import com.jcorporate.expresso.core.db.DBException;
0077:        import com.jcorporate.expresso.core.db.TypeMapper;
0078:        import com.jcorporate.expresso.core.dbobj.DBField;
0079:        import com.jcorporate.expresso.core.dbobj.DBObject;
0080:        import com.jcorporate.expresso.core.dbobj.NextNumber;
0081:        import com.jcorporate.expresso.core.misc.ConfigJdbc;
0082:        import com.jcorporate.expresso.core.misc.ConfigManager;
0083:        import com.jcorporate.expresso.core.misc.ConfigurationException;
0084:        import com.jcorporate.expresso.core.misc.StringUtil;
0085:        import com.jcorporate.expresso.kernel.util.FastStringBuffer;
0086:        import org.apache.log4j.Logger;
0087:
0088:        import java.io.ByteArrayInputStream;
0089:        import java.io.InputStream;
0090:        import java.io.StringReader;
0091:        import java.sql.BatchUpdateException;
0092:        import java.sql.CallableStatement;
0093:        import java.sql.Date;
0094:        import java.sql.SQLException;
0095:        import java.sql.SQLWarning;
0096:        import java.sql.Timestamp;
0097:        import java.util.ArrayList;
0098:        import java.util.HashMap;
0099:        import java.util.Iterator;
0100:        import java.util.List;
0101:        import java.util.Map;
0102:
0103:        /**
0104:         * Initial separation of DBObjects from the underlying JDBC code that gets executed.  This is
0105:         * part number 1 where we move a lot of the JDBC code over to this helper class.  For round
0106:         * #1 iteration, we're assuming that the valueObject is actually a DBObject that implements
0107:         * the DataObject interface (which it does).  This is because we're interested in
0108:         * getting something working and demonstratable, and then slowly flesh out the DataObject
0109:         * interface so that we can eventually completely prune this class completely
0110:         * away from the DBObject class and work strictly with the DataObject Interface.
0111:         *
0112:         * @author Michael Rimov
0113:         * @author Yves Henri AMAIZO <amy_amaizo@compuserve.com>
0114:         * @since Expresso 5.0
0115:         */
0116:
0117:        public class JDBCExecutor implements  DataExecutorInterface {
0118:            private static final String myName = JDBCExecutor.class.getName()
0119:                    + ".";
0120:            private static Logger log = Logger.getLogger(JDBCExecutor.class);
0121:
0122:            transient public static final String LONGVARBINARY_TYPE = "longvarbinary";
0123:            transient public static final String VARBINARY_TYPE = "varbinary";
0124:            transient public static final String LONGVARCHAR_TYPE = "longvarchar";
0125:
0126:            public static int LONGBINARY_READ_DEFAULT_SIZE = 262144;
0127:
0128:            public JDBCExecutor() {
0129:            }
0130:
0131:            /**
0132:             * Takes a <code>DataObject</code> and adds it to the underlying data source
0133:             *
0134:             * @param valueObject the <code>DataObject</code> to add.
0135:             * @throws DataException         upon error adding the object to the data source
0136:             * @throws DuplicateKeyException if the object already existed in the data
0137:             *                               source.
0138:             *                               <p/>
0139:             *                               Modify by Yves Henri AMAIZO <amy_amaizo@compuserve.com>
0140:             * @since $DatabaseSchema  $Date: 2004/11/18 02:03:27 $
0141:             */
0142:            public void add(DataObject valueObject) throws DataException,
0143:                    DuplicateKeyException {
0144:                DBConnection myConnection = null;
0145:                DBConnectionPool myPool = null;
0146:                DBConnection localConnection = null;
0147:
0148:                try {
0149:                    if (valueObject == null) {
0150:                        throw new IllegalArgumentException(myName
0151:                                + "add(DataObject):  valueObject was null");
0152:                    }
0153:
0154:                    DBObject theObject = (DBObject) valueObject;
0155:                    JDBCObjectMetaData metadata = (JDBCObjectMetaData) valueObject
0156:                            .getMetaData();
0157:
0158:                    boolean needComma = false;
0159:
0160:                    //
0161:                    //The names of the database fiels that require prepared statements
0162:                    //to Add
0163:                    //
0164:                    List lobFieldOrder = null;
0165:                    List lobFieldType = null;
0166:
0167:                    //
0168:                    //The list of Strings to add to the file
0169:                    //
0170:                    List lobAdds = null;
0171:
0172:                    if (!haveAllKeysExceptAutoInc(theObject)) {
0173:                        throw new DataException("All key fields not present - "
0174:                                + "cannot add new record");
0175:                    }
0176:
0177:                    //
0178:                    //If myPool isn't set yet, then we need to use getDBName to
0179:                    //reset.  FIXME:  Have the system throw exceptions if DBName isn't
0180:                    //set instead.
0181:                    //
0182:                    myPool = DBConnectionPool.getInstance(theObject
0183:                            .getMappedDataContext());
0184:                    localConnection = theObject.getLocalConnection();
0185:
0186:                    theObject.checkAllRefsPublic();
0187:
0188:                    DBField oneField = null;
0189:
0190:                    /**
0191:                     * sqlCommand will eventually = sqlCommand + valuesCommand.  The two
0192:                     * are assembled in parallel in the loop below.
0193:                     */
0194:                    FastStringBuffer sqlCommand = FastStringBuffer
0195:                            .getInstance();
0196:                    FastStringBuffer valuesCommand = FastStringBuffer
0197:                            .getInstance();
0198:                    String theSqlCommand = null;
0199:                    try {
0200:
0201:                        sqlCommand.append("INSERT INTO ");
0202:                        sqlCommand.append(metadata.getTargetSQLTable(theObject
0203:                                .getDataContext()));
0204:                        sqlCommand.append(" (");
0205:
0206:                        valuesCommand.append(") VALUES (");
0207:
0208:                        boolean needCommaValues = false;
0209:                        for (Iterator i = metadata.getAllFieldsMap().values()
0210:                                .iterator(); i.hasNext();) {
0211:                            oneField = (DBField) i.next();
0212:
0213:                            if (!oneField.isVirtual()) {
0214:                                theObject.checkField(oneField.getName(),
0215:                                        theObject.getField(oneField.getName()));
0216:
0217:                                if (oneField.isBinaryObjectType()) {
0218:                                    if (log.isDebugEnabled()) {
0219:                                        log.debug("Skipping BINARY Object: "
0220:                                                + oneField.getName());
0221:                                    }
0222:                                    continue;
0223:                                }
0224:
0225:                                if (needComma) {
0226:                                    sqlCommand.append(", ");
0227:                                }
0228:
0229:                                sqlCommand.append(oneField.getName());
0230:                                needComma = true;
0231:
0232:                                if (needCommaValues) {
0233:                                    valuesCommand.append(", ");
0234:                                }
0235:                                if (oneField.isDateType()) {
0236:                                    Object tmpData = valueObject.get(oneField
0237:                                            .getName());
0238:                                    String data;
0239:                                    //
0240:                                    //FIXME allow for appropriate support of other data types.
0241:                                    //
0242:                                    if (tmpData == null) {
0243:                                        data = null;
0244:                                    } else if (tmpData instanceof  String) {
0245:                                        data = (String) tmpData;
0246:                                    } else {
0247:                                        data = tmpData.toString();
0248:                                    }
0249:
0250:                                    if (data == null || (data.length() == 0)) {
0251:                                        valuesCommand.append("null");
0252:                                    } else {
0253:                                        valuesCommand.append(JDBCUtil
0254:                                                .getInstance().formatDateTime(
0255:                                                        valueObject,
0256:                                                        oneField.getName()));
0257:                                    }
0258:                                } else if (oneField.isAutoIncremented()) {
0259:                                    String nextNumValue = Long
0260:                                            .toString(NextNumber
0261:                                                    .getInstance()
0262:                                                    .getNext(
0263:                                                            theObject
0264:                                                                    .getDataContext(),
0265:                                                            theObject,
0266:                                                            oneField.getName()));
0267:                                    valueObject.set(oneField.getName(),
0268:                                            nextNumValue);
0269:                                    valuesCommand.append(theObject
0270:                                            .quoteIfNeeded(oneField.getName(),
0271:                                                    null));
0272:                                } else if (oneField.isCharacterLongObjectType()
0273:                                        || oneField.isLongBinaryType()) {
0274:                                    Object tmpData = valueObject.get(oneField
0275:                                            .getName());
0276:                                    String data;
0277:                                    //
0278:                                    //FIXME allow for appropriate support of other data types.
0279:                                    //
0280:                                    if (tmpData == null) {
0281:                                        data = null;
0282:                                    } else if (tmpData instanceof  String) {
0283:                                        data = (String) tmpData;
0284:                                    } else {
0285:                                        data = tmpData.toString();
0286:                                    }
0287:                                    if (data != null) {
0288:                                        if (lobAdds == null) {
0289:                                            lobAdds = new ArrayList();
0290:                                            lobFieldOrder = new ArrayList();
0291:                                            lobFieldType = new ArrayList();
0292:                                        }
0293:                                        lobAdds.add(tmpData);
0294:                                        lobFieldOrder.add(oneField.getName());
0295:                                        lobFieldType.add(oneField
0296:                                                .getTypeString());
0297:                                        valuesCommand.append("?");
0298:                                    } else {
0299:                                        valuesCommand.append("null");
0300:                                    }
0301:                                } else {
0302:                                    valuesCommand.append(theObject
0303:                                            .quoteIfNeeded(oneField.getName(),
0304:                                                    null));
0305:                                }
0306:
0307:                                needCommaValues = true;
0308:                            } /* if field is not virtual */
0309:
0310:                        } /* for each field */
0311:
0312:                        //Now we merge the values of the parallel loops
0313:                        sqlCommand.append(valuesCommand);
0314:                        sqlCommand.append(")");
0315:                        theSqlCommand = sqlCommand.toString();
0316:                    } catch (NullPointerException npe) {
0317:                        log.error("NPE", npe);
0318:                        throw new DataException("Null Pointer Exception", npe);
0319:                    } catch (DBException dbe) {
0320:                        log.error("DBException", dbe);
0321:                        throw dbe;
0322:                    } finally {
0323:                        sqlCommand.release();
0324:                        sqlCommand = null;
0325:                        valuesCommand.release();
0326:                        valuesCommand = null;
0327:                    }
0328:
0329:                    if (localConnection != null) {
0330:                        myConnection = localConnection;
0331:                    } else {
0332:                        try {
0333:                            myConnection = myPool.getConnection(getClass()
0334:                                    .getName());
0335:                        } catch (java.util.ConcurrentModificationException cme) {
0336:                            cme.printStackTrace();
0337:                            log.error(cme);
0338:                            throw new DataException(
0339:                                    "JDBCExecutor.add() ConcurrentModificationException",
0340:                                    cme);
0341:                        }
0342:                    }
0343:
0344:                    if (lobAdds != null) {
0345:                        java.sql.PreparedStatement prepStatement = myConnection
0346:                                .createPreparedStatement(theSqlCommand);
0347:                        if (prepStatement == null) {
0348:                            try {
0349:                                SQLWarning sqlWarnings = myConnection
0350:                                        .getConnection().getWarnings();
0351:                                while (sqlWarnings != null) {
0352:                                    log
0353:                                            .warn("SQL Warning creating prepared statement: "
0354:                                                    + sqlWarnings.toString());
0355:                                    sqlWarnings = sqlWarnings.getNextWarning();
0356:                                }
0357:                            } catch (SQLException ex) {
0358:                                log
0359:                                        .debug("Error getting warnings when prepared statement was null");
0360:                            }
0361:
0362:                            throw new DataException(
0363:                                    "Returned Prepared Statement for "
0364:                                            + theSqlCommand + " was null");
0365:                        }
0366:
0367:                        int size = lobFieldOrder.size();
0368:                        TypeMapper typeMapper = TypeMapper
0369:                                .getInstance(myConnection.getDataContext());
0370:                        for (int i = 0; i < size; i++) {
0371:                            String fieldName = (String) lobFieldOrder.get(i);
0372:                            DataFieldMetaData metaData = valueObject
0373:                                    .getFieldMetaData(fieldName);
0374:                            Object nullValue = lobAdds.get(i);
0375:                            String myType = (String) lobFieldType.get(i);
0376:                            if (nullValue == null
0377:                                    || "null".equals(nullValue)
0378:                                    || (nullValue.toString().length() == 0 && (metaData
0379:                                            .isNumericType() || metaData
0380:                                            .isDateType()))) {
0381:                                int typeCode = typeMapper
0382:                                        .getJavaSQLType(metaData
0383:                                                .getTypeString());
0384:                                prepStatement.setNull(i + 1, typeCode);
0385:                            } else {
0386:                                if (!myType
0387:                                        .equalsIgnoreCase(LONGVARBINARY_TYPE)
0388:                                        && !myType
0389:                                                .equalsIgnoreCase(VARBINARY_TYPE)
0390:                                        && !myType
0391:                                                .equalsIgnoreCase(LONGVARCHAR_TYPE)) {
0392:                                    String value = (String) lobAdds.get(i);
0393:                                    prepStatement.setString(i + 1, value);
0394:                                } else {
0395:                                    if (myType
0396:                                            .equalsIgnoreCase(LONGVARBINARY_TYPE)
0397:                                            || myType
0398:                                                    .equalsIgnoreCase(VARBINARY_TYPE)) {
0399:                                        byte[] data = (byte[]) lobAdds.get(i);
0400:                                        ByteArrayInputStream theData = new ByteArrayInputStream(
0401:                                                data);
0402:                                        prepStatement.setBinaryStream(i + 1,
0403:                                                theData, data.length);
0404:                                    } else {
0405:                                        if (myType
0406:                                                .equalsIgnoreCase(LONGVARCHAR_TYPE)) {
0407:                                            if (("oracle.jdbc.driver.OracleDriver"
0408:                                                    .equals(myConnection
0409:                                                            .getDBDriver()))) {
0410:                                                String value = (String) lobAdds
0411:                                                        .get(i);
0412:                                                java.io.Reader theData = new StringReader(
0413:                                                        value);
0414:                                                prepStatement
0415:                                                        .setCharacterStream(
0416:                                                                i + 1, theData,
0417:                                                                value.length());
0418:                                            } else {
0419:                                                if ("interbase.interclient.Driver"
0420:                                                        .equals(myConnection
0421:                                                                .getDBDriver())) {
0422:                                                    String value = (String) lobAdds
0423:                                                            .get(i);
0424:                                                    byte[] data = value
0425:                                                            .getBytes();
0426:                                                    java.io.ByteArrayInputStream theData = new java.io.ByteArrayInputStream(
0427:                                                            data);
0428:                                                    prepStatement
0429:                                                            .setAsciiStream(
0430:                                                                    i + 1,
0431:                                                                    theData,
0432:                                                                    data.length);
0433:                                                } else {
0434:                                                    String value = (String) lobAdds
0435:                                                            .get(i);
0436:                                                    prepStatement.setString(
0437:                                                            i + 1, value);
0438:                                                }
0439:                                            }
0440:                                        } else {
0441:                                            String value = (String) lobAdds
0442:                                                    .get(i);
0443:                                            prepStatement.setString(i + 1,
0444:                                                    value);
0445:                                        }
0446:                                    }
0447:                                }
0448:
0449:                            }
0450:                            //                    if ("interbase.interclient.Driver".equals(myConnection.getDBDriver())) {
0451:                            //
0452:                            //Workaround, interclient 2 doesn't support setCharacterStream()
0453:                            //
0454:                            //                        byte[] data = value.getBytes();
0455:                            //                        java.io.ByteArrayInputStream bis = new java.io.ByteArrayInputStream(data);
0456:                            //                        prepStatement.setAsciiStream(1,bis,data.length);
0457:                            //                    } else {
0458:                            //                        java.io.Reader r = new java.io.StringReader(value);
0459:                            //                        prepStatement.setCharacterStream(i + 1,r, value.length());
0460:                            //                    }
0461:
0462:                        }
0463:                        myConnection.executeUpdate(null);
0464:                        myConnection.clearPreparedStatement();
0465:
0466:                    } else {
0467:                        myConnection.executeUpdate(theSqlCommand);
0468:                    }
0469:
0470:                } catch (NullPointerException npe) {
0471:                    log.error("NPE", npe);
0472:                    throw new DataException("Null Pointer Exception", npe);
0473:                } catch (SQLException ex) {
0474:                    log.error("Error executing LOB set Character Stream", ex);
0475:                    throw new DataException(
0476:                            "Error setting character stream for for DBObject: "
0477:                                    + getClass().getName(), ex);
0478:                } catch (DBException ex) {
0479:                    String msg = myName + "add(DataObject) error: ";
0480:                    log.error(msg, ex);
0481:                    throw new DataException(ex.getMessage());
0482:                } finally {
0483:                    if (localConnection == null) {
0484:                        if (myPool != null && myConnection != null) {
0485:                            myPool.release(myConnection);
0486:                        }
0487:                    }
0488:                }
0489:
0490:            }
0491:
0492:            /**
0493:             * Takes a <code>DataObject</code> and deletes it from the underlying data source.
0494:             * <b>Note:</b> The current implementation only expects a <code>DBObject</code>
0495:             * and actually routes the call back to that object.  Will be fixed in the future
0496:             * as the interface becomes more rich.
0497:             *
0498:             * @param valueObject the <code>DataObject</code> to delete.
0499:             * @throws DataException upon error deleting the object to the data source
0500:             */
0501:            public void delete(DataObject valueObject) throws DataException {
0502:                if (valueObject == null) {
0503:                    throw new IllegalArgumentException(myName
0504:                            + "delete(DataObject):  valueObject was null");
0505:                }
0506:                DBObject theObject = (DBObject) valueObject;
0507:                try {
0508:                    theObject.delete(true);
0509:                } catch (DBException ex) {
0510:                    String msg = myName + "delete(DataObject) error";
0511:                    log.error(msg, ex);
0512:                    throw new DataException(msg, ex);
0513:                }
0514:            }
0515:
0516:            /**
0517:             * Takes a <code>DataObject</code> and updates it to the underlying data source
0518:             *
0519:             * @param valueObject             the <code>DataObject</code> to update.
0520:             * @param updateChangedFieldsOnly if true only modified fields (isChanged = true)
0521:             *                                will be included in the update
0522:             * @throws DataException upon error updating the object to the data source
0523:             *                       <p/>
0524:             *                       Modify by Yves Henri AMAIZO <amy_amaizo@compuserve.com>
0525:             * @since $DatabaseSchema  $Date: 2004/11/18 02:03:27 $
0526:             */
0527:            public void update(DataObject valueObject,
0528:                    boolean updateChangedFieldsOnly) throws DataException {
0529:                if (valueObject == null) {
0530:                    throw new IllegalArgumentException(myName
0531:                            + "update(DataObject):  valueObject was null");
0532:                }
0533:                DBObject theObject = (DBObject) valueObject;
0534:
0535:                boolean needComma = false;
0536:
0537:                try {
0538:                    //
0539:                    //If myPool isn't set yet, then we need to use getDBName to
0540:                    //reset.  FIXME:  Have the system throw exceptions if DBName isn't
0541:                    //set instead.
0542:                    //
0543:                    DBConnectionPool myPool = DBConnectionPool
0544:                            .getInstance(theObject.getMappedDataContext());
0545:                    DBConnection localConnection = theObject
0546:                            .getLocalConnection();
0547:
0548:                    /* build an update statement - be sure we have all of the keys */
0549:                    if (!theObject.haveAllKeys()) {
0550:                        throw new DataException(
0551:                                "("
0552:                                        + getClass().getName()
0553:                                        + ") All key fields not present - cannot update record");
0554:                    }
0555:
0556:                    theObject.checkAllRefsPublic();
0557:
0558:                    List lobFieldOrder = null;
0559:                    List lobFieldType = null;
0560:                    List lobUpdates = null;
0561:                    DataFieldMetaData oneField = null;
0562:                    FastStringBuffer sqlCommand = FastStringBuffer
0563:                            .getInstance();
0564:                    String theSqlString = null;
0565:                    boolean fieldsUpdated = false;
0566:                    try {
0567:                        sqlCommand.append("UPDATE ");
0568:                        sqlCommand.append(theObject.getJDBCMetaData()
0569:                                .getTargetSQLTable(theObject.getDataContext()));
0570:                        sqlCommand.append(" SET ");
0571:
0572:                        for (Iterator i = valueObject.getMetaData()
0573:                                .getFieldListArray().iterator(); i.hasNext();) {
0574:                            String oneFieldName = (String) i.next();
0575:                            oneField = theObject.getFieldMetaData(oneFieldName);
0576:
0577:                            /* We skip any key fields in the update part (not allowed to */
0578:                            /* update them). Also skip any virtual fields */
0579:                            if ((!oneField.isKey()) && (!oneField.isVirtual())
0580:                                    && (!oneField.isAutoIncremented())
0581:                                    && (!oneField.isBinaryObjectType())) {
0582:
0583:                                if (updateChangedFieldsOnly) {
0584:                                    // Only include changed fields in the update if required
0585:                                    if (valueObject.getDataField(oneFieldName)
0586:                                            .isValueSet()
0587:                                            && theObject.getStatus().equals(
0588:                                                    DataObject.STATUS_NEW)) {
0589:                                        ; // noop
0590:                                    } else {
0591:                                        if (!valueObject.getDataField(
0592:                                                oneFieldName).isChanged()) {
0593:                                            continue;
0594:                                        }
0595:                                    }
0596:                                }
0597:                                theObject.checkField(oneFieldName, theObject
0598:                                        .getField(oneFieldName));
0599:
0600:                                if (needComma) {
0601:                                    sqlCommand.append(", ");
0602:                                }
0603:                                if (!oneField.isKey()) {
0604:                                    fieldsUpdated = true;
0605:                                    sqlCommand.append(oneField.getName());
0606:                                    sqlCommand.append(" = ");
0607:
0608:                                    if (oneField.isDateType()) {
0609:                                        Object tmpData = valueObject
0610:                                                .get(oneField.getName());
0611:                                        String data;
0612:                                        //
0613:                                        //FIXME allow for appropriate support of other data types.
0614:                                        //
0615:                                        if (tmpData == null) {
0616:                                            data = null;
0617:                                        } else if (tmpData instanceof  String) {
0618:                                            data = (String) tmpData;
0619:                                        } else {
0620:                                            data = tmpData.toString();
0621:                                        }
0622:                                        if (data == null || data.length() == 0) {
0623:                                            sqlCommand.append("null");
0624:                                        } else {
0625:                                            sqlCommand
0626:                                                    .append(JDBCUtil
0627:                                                            .getInstance()
0628:                                                            .formatDateTime(
0629:                                                                    theObject,
0630:                                                                    oneField
0631:                                                                            .getName()));
0632:                                        }
0633:                                    } else if (oneField
0634:                                            .isCharacterLongObjectType()
0635:                                            || oneField.isLongObjectType()) {
0636:                                        //
0637:                                        //If we have a CLOB object, then we will go ahead and process
0638:                                        //it, but we execute it in a separate update
0639:                                        //
0640:                                        if (lobUpdates == null) {
0641:                                            lobUpdates = new ArrayList();
0642:                                            lobFieldOrder = new ArrayList();
0643:                                            lobFieldType = new ArrayList();
0644:                                        }
0645:                                        Object tmpData = valueObject
0646:                                                .get(oneField.getName());
0647:                                        String data;
0648:                                        //
0649:                                        //FIXME allow for appropriate support of other data types.
0650:                                        //
0651:                                        if (tmpData == null) {
0652:                                            data = null;
0653:                                        } else if (tmpData instanceof  String) {
0654:                                            data = (String) tmpData;
0655:                                        } else {
0656:                                            data = tmpData.toString();
0657:                                        }
0658:
0659:                                        lobUpdates.add(tmpData);
0660:                                        lobFieldOrder.add(oneFieldName);
0661:                                        lobFieldType.add(oneField
0662:                                                .getTypeString());
0663:
0664:                                        sqlCommand.append("?");
0665:
0666:                                    } else {
0667:                                        sqlCommand.append(theObject
0668:                                                .quoteIfNeeded(oneField
0669:                                                        .getName(), null));
0670:                                    }
0671:
0672:                                    sqlCommand.append(" ");
0673:                                    needComma = true;
0674:                                }
0675:                            } /* if it's not a key field */
0676:
0677:                        }
0678:
0679:                        if (!fieldsUpdated) {
0680:                            return;
0681:                        }
0682:                        sqlCommand.append(theObject.buildWhereClause(false));
0683:                        theSqlString = sqlCommand.toString();
0684:                    } finally {
0685:                        sqlCommand.release();
0686:                        sqlCommand = null;
0687:                    }
0688:
0689:                    DBConnection myConnection = null;
0690:
0691:                    try {
0692:                        if (localConnection != null) {
0693:                            myConnection = localConnection;
0694:                        } else {
0695:                            myConnection = myPool.getConnection(getClass()
0696:                                    .getName());
0697:                        }
0698:
0699:                        if (lobUpdates != null) {
0700:
0701:                            java.sql.PreparedStatement prepStatement = null;
0702:                            try {
0703:                                prepStatement = myConnection
0704:                                        .createPreparedStatement(theSqlString);
0705:
0706:                                int size = lobFieldOrder.size();
0707:                                String value = "";
0708:                                for (int i = 0; i < size; i++) {
0709:                                    String myType = (String) lobFieldType
0710:                                            .get(i);
0711:                                    try {
0712:                                        if (!myType
0713:                                                .equalsIgnoreCase(LONGVARBINARY_TYPE)
0714:                                                && !myType
0715:                                                        .equalsIgnoreCase(VARBINARY_TYPE)
0716:                                                && !myType
0717:                                                        .equalsIgnoreCase(LONGVARCHAR_TYPE)) {
0718:                                            value = (String) lobUpdates.get(i);
0719:                                            prepStatement.setString(i + 1,
0720:                                                    value);
0721:                                        } else {
0722:                                            if (myType
0723:                                                    .equalsIgnoreCase(LONGVARBINARY_TYPE)
0724:                                                    || myType
0725:                                                            .equalsIgnoreCase(VARBINARY_TYPE)) {
0726:                                                byte[] data = (byte[]) lobUpdates
0727:                                                        .get(i);
0728:                                                ByteArrayInputStream theData = new ByteArrayInputStream(
0729:                                                        data);
0730:                                                prepStatement.setBinaryStream(
0731:                                                        i + 1, theData,
0732:                                                        data.length);
0733:                                            } else {
0734:                                                value = (String) lobUpdates
0735:                                                        .get(i);
0736:                                                if (myType
0737:                                                        .equalsIgnoreCase(LONGVARCHAR_TYPE)) {
0738:                                                    if (("oracle.jdbc.driver.OracleDriver"
0739:                                                            .equals(myConnection
0740:                                                                    .getDBDriver()))) {
0741:                                                        java.io.Reader theData = new StringReader(
0742:                                                                value);
0743:                                                        prepStatement
0744:                                                                .setCharacterStream(
0745:                                                                        i + 1,
0746:                                                                        theData,
0747:                                                                        value
0748:                                                                                .length());
0749:                                                    } else {
0750:                                                        if ("interbase.interclient.Driver"
0751:                                                                .equals(myConnection
0752:                                                                        .getDBDriver())) {
0753:                                                            byte[] data = value
0754:                                                                    .getBytes();
0755:                                                            java.io.ByteArrayInputStream theData = new java.io.ByteArrayInputStream(
0756:                                                                    data);
0757:                                                            prepStatement
0758:                                                                    .setAsciiStream(
0759:                                                                            i + 1,
0760:                                                                            theData,
0761:                                                                            data.length);
0762:                                                        } else {
0763:                                                            prepStatement
0764:                                                                    .setString(
0765:                                                                            i + 1,
0766:                                                                            value);
0767:                                                        }
0768:                                                    }
0769:                                                } else {
0770:                                                    prepStatement.setString(
0771:                                                            i + 1, value);
0772:                                                }
0773:                                            }
0774:                                        }
0775:
0776:                                    } catch (SQLException ex) {
0777:                                        String key = (String) lobFieldOrder
0778:                                                .get(i);
0779:                                        log
0780:                                                .error(
0781:                                                        "Error executing LOB set Character Stream",
0782:                                                        ex);
0783:                                        throw new DataException(
0784:                                                "Error setting character stream for field: "
0785:                                                        + key + " with value: "
0786:                                                        + value
0787:                                                        + " for DBObject: "
0788:                                                        + getClass().getName(),
0789:                                                ex);
0790:                                    } catch (Throwable t) {
0791:                                        String key = (String) lobFieldOrder
0792:                                                .get(i);
0793:                                        log.error(
0794:                                                "Error executing LOB set Character Stream. SQL="
0795:                                                        + theSqlString, t);
0796:                                        throw new DataException(
0797:                                                "Error setting character stream for field: "
0798:                                                        + key + " with value: "
0799:                                                        + value
0800:                                                        + " for DBObject: "
0801:                                                        + getClass().getName()
0802:                                                        + " SQL="
0803:                                                        + theSqlString, t);
0804:                                    }
0805:                                }
0806:                                myConnection.executeUpdate(null);
0807:                            } finally {
0808:                                myConnection.clearPreparedStatement();
0809:                            }
0810:                        } else {
0811:                            myConnection.executeUpdate(theSqlString);
0812:                        }
0813:
0814:                        if ((myConnection.getUpdateCount() == 0)
0815:                                && (theObject.checkZeroUpdate())) {
0816:                            log.error("No record updated for SQL '"
0817:                                    + theSqlString + "'");
0818:                            throw new DataException("(" + getClass().getName()
0819:                                    + ") No records updated for"
0820:                                    + theObject.forKey());
0821:                        }
0822:                        if (theObject.isCached()) {
0823:                            theObject.removeFromCache(theObject);
0824:                        }
0825:                    } catch (NullPointerException npe) {
0826:                        npe.printStackTrace();
0827:                        throw new DataException(npe);
0828:                    } finally {
0829:                        if (localConnection == null) {
0830:                            if (myPool != null && myConnection != null) {
0831:                                myPool.release(myConnection);
0832:                            }
0833:                        }
0834:                    }
0835:                } catch (DBException ex) {
0836:                    String msg = myName + "update(DataObject) error";
0837:                    log.error(msg, ex);
0838:                    throw new DataException(ex.getMessage());
0839:                }
0840:            }
0841:
0842:            /**
0843:             * Retrieves the object with keys specified by the valueObject parameter.
0844:             * This has the same semantics as <code>DBObject</code>'s  retrieve method.
0845:             *
0846:             * @param valueObject the DataObject who's keys are already set to retrieve
0847:             * @return true if the data object was successfully retrieved
0848:             * @throws DataException Modify by Yves Henri AMAIZO <amy_amaizo@compuserve.com>
0849:             * @since $DatabaseSchema  $Date: 2004/11/18 02:03:27 $
0850:             */
0851:            public boolean retrieve(DataObject valueObject)
0852:                    throws DataException {
0853:                if (valueObject == null) {
0854:                    throw new IllegalArgumentException(myName
0855:                            + "retrieve(DataObject):  valueObject was null");
0856:                }
0857:                DBObject theObject = (DBObject) valueObject;
0858:                JDBCObjectMetaData metadata = (JDBCObjectMetaData) valueObject
0859:                        .getMetaData();
0860:
0861:                boolean needComma = false;
0862:                DataFieldMetaData oneField = null;
0863:
0864:                boolean anyFieldsDistinct = false;
0865:                try {
0866:                    ArrayList distinctFields = theObject
0867:                            .getDistinctFieldArrayList();
0868:                    anyFieldsDistinct = (distinctFields.size() > 0);
0869:                    if (!theObject.haveAllKeys() && !anyFieldsDistinct) {
0870:                        throw new DataException(
0871:                                "("
0872:                                        + getClass().getName()
0873:                                        + ") All key fields not present - cannot retrieve record");
0874:                    }
0875:                    if (theObject.retrieveFromCache()) {
0876:                        return true;
0877:                    }
0878:
0879:                    //            FastStringBuffer myStatement = new FastStringBuffer(128);
0880:                    FastStringBuffer myStatement = FastStringBuffer
0881:                            .getInstance();
0882:                    String theSqlStatement = null;
0883:                    try {
0884:                        myStatement.append("SELECT ");
0885:
0886:                        if (theObject.getFieldsToRetrieveCount() > 0) {
0887:                            String oneFieldName = null;
0888:                            Map retrieveFieldNames = new HashMap(10);
0889:
0890:                            for (Iterator i = theObject
0891:                                    .getFieldsToRetrieveIterator(); i.hasNext();) {
0892:                                oneFieldName = (String) i.next();
0893:                                retrieveFieldNames.put(oneFieldName, null);
0894:
0895:                                if (needComma) {
0896:                                    myStatement.append(", ");
0897:                                }
0898:
0899:                                myStatement.append(theObject
0900:                                        .selectFieldString(oneFieldName));
0901:                                needComma = true;
0902:                            } /* for each field */
0903:
0904:                            for (Iterator i = theObject.getMetaData()
0905:                                    .getKeyFieldListArray().iterator(); i
0906:                                    .hasNext();) {
0907:                                String curFieldName = (String) i.next();
0908:                                oneField = theObject
0909:                                        .getFieldMetaData(curFieldName);
0910:
0911:                                if (!retrieveFieldNames
0912:                                        .containsKey(curFieldName)) {
0913:                                    if (needComma) {
0914:                                        myStatement.append(", ");
0915:                                    }
0916:
0917:                                    myStatement.append(theObject
0918:                                            .selectFieldString(curFieldName));
0919:                                    needComma = true;
0920:                                }
0921:                            }
0922:                        } else { /* for each key field */
0923:                            for (Iterator i = metadata.getAllFieldsMap()
0924:                                    .values().iterator(); i.hasNext();) {
0925:                                oneField = (DBField) i.next();
0926:                                //We aren't retrieving long objects
0927:                                if (oneField.isBinaryObjectType()) {
0928:                                    continue;
0929:                                }
0930:
0931:                                if (!oneField.isVirtual()) {
0932:                                    if (needComma) {
0933:                                        myStatement.append(", ");
0934:                                    }
0935:
0936:                                    myStatement.append(theObject
0937:                                            .selectFieldString(oneField
0938:                                                    .getName()));
0939:                                    needComma = true;
0940:                                } /* if field is not virtual */
0941:
0942:                            } /* for */
0943:
0944:                        } /* if anyFieldsToRetrieve */
0945:
0946:                        myStatement.append(" FROM ");
0947:                        myStatement.append(theObject.getJDBCMetaData()
0948:                                .getTargetSQLTable(theObject.getDataContext()));
0949:
0950:                        String customWhereClause = theObject
0951:                                .getCustomWhereClause();
0952:
0953:                        if (customWhereClause != null) {
0954:                            log
0955:                                    .warn("Custom Where clauses don't make sense for "
0956:                                            + "DataObject.retrieve(), since it's based upon key fields.  Ignoring:"
0957:                                            + customWhereClause);
0958:                        }
0959:
0960:                        myStatement.append(theObject.buildWhereClause(false));
0961:                        theSqlStatement = myStatement.toString();
0962:                    } finally {
0963:                        myStatement.release();
0964:                        myStatement = null;
0965:                    }
0966:
0967:                    DBConnection myConnection = null;
0968:
0969:                    //
0970:                    //If myPool isn't set yet, then we need to use getDBName to
0971:                    //reset.  FIXME:  Have the system throw exceptions if DBName isn't
0972:                    //set instead.
0973:                    //
0974:                    DBConnectionPool myPool = DBConnectionPool
0975:                            .getInstance(theObject.getMappedDataContext());
0976:                    DBConnection localConnection = theObject
0977:                            .getLocalConnection();
0978:                    if (localConnection != null) {
0979:                        myConnection = localConnection;
0980:                    } else {
0981:                        myConnection = myPool.getConnection(getClass()
0982:                                .getName());
0983:                    }
0984:
0985:                    try {
0986:
0987:                        myConnection.execute(theSqlStatement);
0988:
0989:                        FastStringBuffer oneKeyString = FastStringBuffer
0990:                                .getInstance();
0991:                        try {
0992:                            String oneFieldValue = "";
0993:                            Object tmpData = null;
0994:                            if (myConnection.next()) {
0995:                                //Clear all non-key fields
0996:                                for (Iterator allFields = theObject
0997:                                        .getMetaData().getFieldListArray()
0998:                                        .iterator(); allFields.hasNext();) {
0999:                                    String oneFieldName = (String) allFields
1000:                                            .next();
1001:                                    DataFieldMetaData fieldMetaData = theObject
1002:                                            .getFieldMetaData(oneFieldName);
1003:                                    if (!fieldMetaData.isKey()
1004:                                            && !fieldMetaData
1005:                                                    .isBinaryObjectType()
1006:                                            && !fieldMetaData.isVirtual()) {
1007:                                        theObject.set(oneFieldName, null);
1008:                                    }
1009:                                }
1010:
1011:                                int i = 1;
1012:
1013:                                Iterator it;
1014:                                if (theObject.getFieldsToRetrieveCount() > 0) {
1015:                                    //
1016:                                    //We have to load up a metadata array based upon the
1017:                                    //order of the field names as specified in the the
1018:                                    //getFieldsToRetrieveIterator() function.
1019:                                    //
1020:                                    ArrayList dbFieldArray = new ArrayList(
1021:                                            theObject
1022:                                                    .getFieldsToRetrieveCount());
1023:                                    for (Iterator j = theObject
1024:                                            .getFieldsToRetrieveIterator(); j
1025:                                            .hasNext();) {
1026:                                        String theFieldName = (String) j.next();
1027:                                        dbFieldArray
1028:                                                .add(theObject
1029:                                                        .getFieldMetaData(theFieldName));
1030:                                    }
1031:
1032:                                    it = dbFieldArray.iterator();
1033:
1034:                                } else {
1035:                                    it = metadata.getAllFieldsMap().values()
1036:                                            .iterator();
1037:                                }
1038:
1039:                                while (it.hasNext()) {
1040:                                    oneField = (DBField) it.next();
1041:
1042:                                    if (!oneField.isVirtual()) {
1043:                                        if (oneField.isBinaryObjectType()) {
1044:                                            continue;
1045:                                        }
1046:
1047:                                        try {
1048:                                            //   * @author	  Yves Henri AMAIZO
1049:                                            //   Handle correctly date from resultSet data retrieve from Database
1050:                                            if (oneField.isDateType()) {
1051:                                                tmpData = theObject
1052:                                                        .getCustomStringFieldValue(
1053:                                                                myConnection,
1054:                                                                oneField
1055:                                                                        .getName());
1056:                                            } else {
1057:                                                if (!oneField
1058:                                                        .isLongBinaryType()
1059:                                                        && !oneField
1060:                                                                .isLongCharacterType()) {
1061:                                                    if (myConnection
1062:                                                            .isStringNotTrim()) {
1063:                                                        tmpData = myConnection
1064:                                                                .getStringNoTrim(i);
1065:                                                    } else {
1066:                                                        tmpData = myConnection
1067:                                                                .getString(i);
1068:                                                    }
1069:                                                } else {
1070:                                                    if (oneField
1071:                                                            .isLongBinaryType()) {
1072:                                                        tmpData = null;
1073:                                                        InputStream is = myConnection
1074:                                                                .getBinaryStream(i);
1075:                                                        if (is != null) {
1076:                                                            byte[] bstr = new byte[LONGBINARY_READ_DEFAULT_SIZE];
1077:                                                            int j = is
1078:                                                                    .read(bstr);
1079:                                                            if (j > 0) {
1080:                                                                byte[] content = new byte[j];
1081:                                                                System
1082:                                                                        .arraycopy(
1083:                                                                                bstr,
1084:                                                                                0,
1085:                                                                                content,
1086:                                                                                0,
1087:                                                                                j);
1088:                                                                tmpData = content;
1089:                                                            }
1090:                                                        }
1091:                                                    } else {
1092:                                                        tmpData = myConnection
1093:                                                                .getStringNoTrim(i);
1094:                                                    }
1095:
1096:                                                }
1097:                                            }
1098:                                        } catch (DBException de1) {
1099:                                            throw new DataException(
1100:                                                    "("
1101:                                                            + getClass()
1102:                                                                    .getName()
1103:                                                            + ") Error retrieving field '"
1104:                                                            + oneField
1105:                                                                    .getName()
1106:                                                            + "' index " + i
1107:                                                            + ":"
1108:                                                            + de1.getMessage(),
1109:                                                    de1.getDBMessage());
1110:                                        } catch (Exception de1) {
1111:                                            throw new DataException(
1112:                                                    "Not DBException("
1113:                                                            + getClass()
1114:                                                                    .getName()
1115:                                                            + ") Error retrieving field '"
1116:                                                            + oneField
1117:                                                                    .getName()
1118:                                                            + "' index " + i
1119:                                                            + ":"
1120:                                                            + de1.getMessage(),
1121:                                                    de1.getMessage());
1122:                                        }
1123:
1124:                                        i++;
1125:                                        //								theObject.set(oneField.getName(), oneFieldValue);
1126:                                        theObject.set(oneField.getName(),
1127:                                                tmpData);
1128:                                    }
1129:
1130:                                    if (oneField.isKey()) {
1131:                                        if (i > 1) {
1132:                                            oneKeyString.append("/");
1133:                                        }
1134:
1135:                                        oneKeyString.append(oneFieldValue);
1136:                                    }
1137:                                }
1138:                                theObject.addFoundKeys(oneKeyString.toString());
1139:                            } else {
1140:                                //There were zero results returned by the retrieve() call.
1141:                                return false;
1142:                            }
1143:                        } finally {
1144:                            oneKeyString.release();
1145:                            oneKeyString = null;
1146:                        }
1147:
1148:                    } finally {
1149:                        if (localConnection == null) {
1150:                            if (myPool != null && myConnection != null) {
1151:                                myPool.release(myConnection);
1152:                            }
1153:                        }
1154:                    }
1155:                } catch (DBException ex) {
1156:                    String msg = myName + "retrieve(DataObject) error";
1157:                    log.error(msg, ex);
1158:                    throw new DataException(msg, ex);
1159:                }
1160:
1161:                return true;
1162:            }
1163:
1164:            /**
1165:             * Adds an entire batch of <code>DataObject</code>s to the underlying JDBC data source
1166:             *
1167:             * @param valueObjectList A list of <code>DataObject</code>s to add to the underlying
1168:             *                        data source <b>NOTE:</b> you will get best performance if valueObjectList is
1169:             *                        all one dataobject underneath.
1170:             *                        <p/>
1171:             *                        WARNING: I DON'T UNDERSTAND WHY LOOP VAR ISN'T USED BELOW, AND SUSPECT THIS METHOD ISN'T DOING ALL IT PURPORTS TO DO; SEE "todo"  (Larry Hamel, 3/03)
1172:             * @throws DataException         upon error communicating with the underlying data source
1173:             * @throws DuplicateKeyException if one of the records was already in the
1174:             *                               data source
1175:             */
1176:            public void addBatch(List valueObjectList) throws DataException,
1177:                    DuplicateKeyException {
1178:                if (valueObjectList == null) {
1179:                    throw new IllegalArgumentException(myName
1180:                            + "addBatch(List):  valueObjectArray was null");
1181:                }
1182:                addBatch(valueObjectList, false);
1183:            }
1184:
1185:            /**
1186:             * Updates an entire batch of <code>DataObject</code>s
1187:             *
1188:             * @param valueObjectList A list of <code>DataObject</code>s to update to the underlying
1189:             *                        data source
1190:             * @throws DataException upon error updating the data source
1191:             */
1192:            public void updateBatch(List valueObjectList) throws DataException {
1193:                if (valueObjectList == null) {
1194:                    throw new IllegalArgumentException(myName
1195:                            + "updateBatch(List):  valueObjectArray was null");
1196:                }
1197:                updateBatch(valueObjectList, false);
1198:
1199:            }
1200:
1201:            /**
1202:             * Helper function to build a prepared update statement for batch updates.
1203:             *
1204:             * @param oneObjectType           A single <code>DataObject</code> that is used to model the prepared
1205:             *                                statement.  Only metadata about the <code>DataObject</code>  is used.
1206:             * @param updateChangedFieldsOnly true if the changed fields should be the
1207:             *                                only ones sent through the SQL query.
1208:             * @return A <code>FastStringBuffer</code> containing the proper SQL to create
1209:             *         a preparedStatement
1210:             * @throws DBException upon error
1211:             *                     <p/>
1212:             *                     Modify by Yves Henri AMAIZO <amy_amaizo@compuserve.com>
1213:             * @since $DatabaseSchema  $Date: 2004/11/18 02:03:27 $
1214:             */
1215:            protected String buildPreparedUpdateSQL(DataObject oneObjectType,
1216:                    boolean updateChangedFieldsOnly) throws DBException {
1217:                DBObject theObject = (DBObject) oneObjectType;
1218:
1219:                FastStringBuffer sqlCommand = FastStringBuffer.getInstance();
1220:                FastStringBuffer whereClause = FastStringBuffer.getInstance();
1221:                String returnValue = null;
1222:                try {
1223:                    sqlCommand.append("UPDATE ");
1224:                    sqlCommand.append(theObject.getJDBCMetaData()
1225:                            .getTargetSQLTable(theObject.getDataContext()));
1226:                    sqlCommand.append(" SET ");
1227:
1228:                    whereClause.append(" WHERE ");
1229:
1230:                    DataFieldMetaData oneField = null;
1231:                    boolean needComma = false;
1232:                    boolean needWhereComma = false;
1233:
1234:                    for (Iterator i = theObject.getMetaData()
1235:                            .getFieldListArray().iterator(); i.hasNext();) {
1236:                        String oneFieldName = (String) i.next();
1237:                        oneField = theObject.getFieldMetaData(oneFieldName);
1238:
1239:                        // Only include changed fields in the update if required
1240:                        if (updateChangedFieldsOnly) {
1241:                            if (theObject.getDataField(oneFieldName)
1242:                                    .isValueSet()
1243:                                    && theObject.getStatus().equals(
1244:                                            DataObject.STATUS_NEW)) {
1245:                                ;
1246:                            } else {
1247:                                if (!theObject.getDataField(oneFieldName)
1248:                                        .isChanged()) {
1249:                                    continue;
1250:                                }
1251:                            }
1252:                        }
1253:
1254:                        /* We skip any key fields in the update part (not allowed to */
1255:                        /* upate them). Also skip any virtual fields */
1256:                        if ((!oneField.isKey()) && (!oneField.isVirtual())
1257:                                && (!oneField.isAutoIncremented())
1258:                                && (!oneField.isBinaryObjectType())) {
1259:
1260:                            if (needComma) {
1261:                                sqlCommand.append(", ");
1262:                            }
1263:
1264:                            sqlCommand.append(oneField.getName());
1265:                            sqlCommand.append(" = ? ");
1266:                            needComma = true;
1267:                        } else if (oneField.isKey()) {
1268:                            if (needWhereComma) {
1269:                                //                        whereClause.append(", ");
1270:                                whereClause.append(" AND ");
1271:                            }
1272:
1273:                            whereClause.append(oneField.getName());
1274:                            whereClause.append(" = ? ");
1275:                            needWhereComma = true;
1276:                        }
1277:
1278:                    }
1279:
1280:                    sqlCommand.append(whereClause);
1281:                    returnValue = sqlCommand.toString();
1282:                } finally {
1283:                    whereClause.release();
1284:                    sqlCommand.release();
1285:                    whereClause = null;
1286:                    sqlCommand = null;
1287:                }
1288:
1289:                return returnValue;
1290:            }
1291:
1292:            /**
1293:             * Helper function to build a prepared delete statement for batch deletes.
1294:             *
1295:             * @param oneObjectType A single <code>DataObject</code> that is used to model the prepared
1296:             *                      statement.  Only metadata about the <code>DataObject</code>  is used.
1297:             * @return A <code>FastStringBuffer</code> containing the proper SQL to create
1298:             *         a preparedStatement
1299:             * @throws DBException upon error
1300:             *                     <p/>
1301:             *                     Modify by Yves Henri AMAIZO <amy_amaizo@compuserve.com>
1302:             * @since $DatabaseSchema  $Date: 2004/11/18 02:03:27 $
1303:             */
1304:            protected String buildPreparedDeleteSQL(DataObject oneObjectType,
1305:                    boolean deleteWithSetFieldsOnly) throws DBException {
1306:                DBObject theObject = (DBObject) oneObjectType;
1307:
1308:                FastStringBuffer sqlCommand = FastStringBuffer.getInstance();
1309:                FastStringBuffer whereClause = FastStringBuffer.getInstance();
1310:                String returnValue = null;
1311:                try {
1312:                    sqlCommand.append("DELETE FROM ");
1313:                    sqlCommand.append(theObject.getJDBCMetaData()
1314:                            .getTargetSQLTable(theObject.getDataContext()));
1315:
1316:                    whereClause.append(" WHERE ");
1317:
1318:                    DataFieldMetaData oneField = null;
1319:                    boolean needComma = false;
1320:                    boolean needWhereComma = false;
1321:
1322:                    for (Iterator i = theObject.getMetaData()
1323:                            .getFieldListArray().iterator(); i.hasNext();) {
1324:                        String oneFieldName = (String) i.next();
1325:                        oneField = theObject.getFieldMetaData(oneFieldName);
1326:
1327:                        // Only include changed fields in the update if required
1328:                        if (deleteWithSetFieldsOnly) {
1329:                            if (theObject.getDataField(oneFieldName)
1330:                                    .isValueSet()
1331:                                    && theObject.getStatus().equals(
1332:                                            DataObject.STATUS_NEW)) {
1333:                                ;
1334:                            } else {
1335:                                if (!theObject.getDataField(oneFieldName)
1336:                                        .isChanged()) {
1337:                                    continue;
1338:                                }
1339:                            }
1340:                        }
1341:
1342:                        /* We skip any key fields in the update part (not allowed to */
1343:                        /* upate them). Also skip any virtual fields */
1344:                        if ((!oneField.isKey()) && (!oneField.isVirtual())
1345:                                && (!oneField.isAutoIncremented())
1346:                                && (!oneField.isBinaryObjectType())) {
1347:
1348:                            if (needComma) {
1349:                                sqlCommand.append(", ");
1350:                            }
1351:
1352:                            sqlCommand.append(oneField.getName());
1353:                            sqlCommand.append(" = ? ");
1354:                            needComma = true;
1355:                        } else if (oneField.isKey()) {
1356:                            if (needWhereComma) {
1357:                                whereClause.append(" AND ");
1358:                            }
1359:
1360:                            whereClause.append(oneField.getName());
1361:                            whereClause.append(" = ? ");
1362:                            needWhereComma = true;
1363:                        }
1364:
1365:                    }
1366:
1367:                    sqlCommand.append(whereClause);
1368:                    returnValue = sqlCommand.toString();
1369:                } finally {
1370:                    whereClause.release();
1371:                    sqlCommand.release();
1372:                    whereClause = null;
1373:                    sqlCommand = null;
1374:                }
1375:
1376:                return returnValue;
1377:            }
1378:
1379:            /**
1380:             * Helper Function to build a prepared statement's SQL for an ADD statement.
1381:             *
1382:             * @param oneObjectType        A single <code>DataObject</code> that is used to model the prepared
1383:             *                             statement.  Only metadata about the <code>DataObject</code>  is used.
1384:             * @param addChangedFieldsOnly flag to signify if only fields whose value
1385:             *                             has changed should be included in the add.
1386:             * @return a FastStringBuffer containing the build sql statement
1387:             * @throws DBException upon error
1388:             *                     <p/>
1389:             *                     Modify by Yves Henri AMAIZO <amy_amaizo@compuserve.com>
1390:             * @since $DatabaseSchema  $Date: 2004/11/18 02:03:27 $
1391:             */
1392:            protected String buildPreparedAddSQL(DataObject oneObjectType,
1393:                    boolean addChangedFieldsOnly) throws DBException {
1394:                DBObject theObject = (DBObject) oneObjectType;
1395:                /**
1396:                 * sqlCommand will eventually = sqlCommand + valuesCommand.  The two
1397:                 * are assembled in parallel in the loop below.
1398:                 */
1399:                FastStringBuffer sqlCommand = FastStringBuffer.getInstance();
1400:                FastStringBuffer valuesCommand = FastStringBuffer.getInstance();
1401:                String returnValue = null;
1402:                try {
1403:                    sqlCommand.append("INSERT INTO ");
1404:                    sqlCommand.append(theObject.getJDBCMetaData()
1405:                            .getTargetSQLTable(theObject.getDataContext()));
1406:                    sqlCommand.append(" (");
1407:
1408:                    valuesCommand.append(") VALUES (");
1409:
1410:                    DataFieldMetaData oneField = null;
1411:                    boolean needCommaValues = false;
1412:                    for (Iterator i = theObject.getMetaData()
1413:                            .getFieldListArray().iterator(); i.hasNext();) {
1414:                        String oneFieldName = (String) i.next();
1415:                        oneField = theObject.getFieldMetaData(oneFieldName);
1416:
1417:                        // Only include changed fields in the add if required
1418:                        if (addChangedFieldsOnly) {
1419:                            if (theObject.getDataField(oneFieldName)
1420:                                    .isValueSet()
1421:                                    && theObject.getStatus().equals(
1422:                                            DataObject.STATUS_NEW)) {
1423:                                ;
1424:                            } else {
1425:                                if (!theObject.getDataField(oneFieldName)
1426:                                        .isChanged()) {
1427:                                    continue;
1428:                                }
1429:                            }
1430:                        }
1431:
1432:                        if (!oneField.isVirtual()
1433:                                && !oneField.isBinaryObjectType()) {
1434:                            if (needCommaValues) {
1435:                                sqlCommand.append(", ");
1436:                                valuesCommand.append(", ");
1437:                            }
1438:                            sqlCommand.append(oneField.getName());
1439:                            valuesCommand.append(" ? ");
1440:                            needCommaValues = true;
1441:                        }
1442:
1443:                    } /* for each field */
1444:
1445:                    //Now we merge the values of the parallel loops
1446:                    sqlCommand.append(valuesCommand);
1447:                    sqlCommand.append(")");
1448:                    returnValue = sqlCommand.toString();
1449:                } finally {
1450:                    sqlCommand.release();
1451:                    valuesCommand.release();
1452:                    sqlCommand = null;
1453:                    valuesCommand = null;
1454:                }
1455:
1456:                return returnValue;
1457:
1458:            }
1459:
1460:            /**
1461:             * Format the field for storage into a prepared statement.  This is similar
1462:             * to the old <code>DBObject.quoteIfNeeded()</code> but it does not insert
1463:             * quotes around the values since the prepared statements will take care
1464:             * of special characters like that
1465:             *
1466:             * @param oneField The metadata of the field to retrieve
1467:             * @param theObj   The <code>DBObject</code> that contains the data to store.
1468:             * @return java.lang.String for the appropriate data value.
1469:             */
1470:            protected String prepareForStorage(DataFieldMetaData oneField,
1471:                    DBObject theObj) throws DBException {
1472:                return prepareForStorage(oneField, theObj, true);
1473:            }
1474:
1475:            /**
1476:             * Format the field for storage into a prepared statement.  This is similar
1477:             * to the old <code>DBObject.quoteIfNeeded()</code> but it does not insert
1478:             * quotes around the values since the prepared statements will take care
1479:             * of special characters like that
1480:             *
1481:             * @param oneField The metadata of the field to retrieve
1482:             * @param theObj   The <code>DBObject</code> that contains the data to store.
1483:             * @return java.lang.String for the appropriate data value.
1484:             */
1485:            protected String prepareForStorage(DataFieldMetaData oneField,
1486:                    DBObject theObj, boolean dateFormatted) throws DBException {
1487:                //String fieldName = oneField.getName();
1488:                String fieldValue = theObj
1489:                        .getSerializedForm((DBField) oneField);
1490:
1491:                /* if the field is null, we don't need to worry about quotes */
1492:                if (fieldValue == null) {
1493:                    return null;
1494:                }
1495:
1496:                if (oneField.isNumericType()) {
1497:                    if (fieldValue.equals("")) {
1498:                        return "0";
1499:                    }
1500:
1501:                    return fieldValue.trim();
1502:                } /* if a numeric type */
1503:
1504:                if (oneField.isDateType()) {
1505:                    if (dateFormatted) {
1506:                        return JDBCUtil.getInstance().formatDateTime(theObj,
1507:                                oneField.getName(), false);
1508:                    }
1509:                    return fieldValue.trim();
1510:                } else if (oneField.isBooleanType()) {
1511:                    try {
1512:                        boolean nativeBoolean = ConfigManager.getContext(
1513:                                theObj.getDataContext()).getJdbc()
1514:                                .isNativeBool();
1515:
1516:                        if (!nativeBoolean) {
1517:                            FastStringBuffer returnValue = FastStringBuffer
1518:                                    .getInstance();
1519:                            String returnString = null;
1520:                            try {
1521:                                returnValue.append(fieldValue.trim());
1522:                                returnString = returnValue.toString();
1523:                            } finally {
1524:                                returnValue.release();
1525:                                returnValue = null;
1526:                            }
1527:                            return returnString;
1528:                        }
1529:                    } catch (ConfigurationException ce) {
1530:                        throw new DBException(ce);
1531:                    }
1532:                }
1533:
1534:                return fieldValue.trim();
1535:            } /* quoteIfNeeded(String) */
1536:
1537:            private boolean haveAllKeysExceptAutoInc(DBObject valueObject)
1538:                    throws DBException {
1539:                DBField oneField = null;
1540:
1541:                for (Iterator i = valueObject.getJDBCMetaData().getAllKeysMap()
1542:                        .values().iterator(); i.hasNext();) {
1543:                    oneField = (DBField) i.next();
1544:                    DataField df = valueObject.getDataField(oneField.getName());
1545:                    if (df == null
1546:                            || (df.isNull() && !df.getFieldMetaData()
1547:                                    .isAutoIncremented())) {
1548:                        return false;
1549:                    }
1550:                }
1551:
1552:                return true;
1553:            }
1554:
1555:            /**
1556:             * Takes a <code>DataObject</code> and updates all to the underlying data source
1557:             *
1558:             * @param valueObject        the <code>DataObject</code> to update.
1559:             * @param updateChangedCache if true only modified fields (isChanged = true)
1560:             *                           will be included in the update
1561:             * @throws DataException upon error updating the object to the data source
1562:             *                       <p/>
1563:             *                       Modify by Yves Henri AMAIZO <amy_amaizo@compuserve.com>
1564:             * @since $DatabaseSchema  $Date: 2004/11/18 02:03:27 $
1565:             */
1566:            public void updateAll(DataObject valueObject,
1567:                    boolean updateChangedCache) throws DataException {
1568:                if (valueObject == null) {
1569:                    throw new IllegalArgumentException(myName
1570:                            + "updateAll(DataObject):  valueObject was null");
1571:                }
1572:                DBObject theObject = (DBObject) valueObject;
1573:
1574:                try {
1575:                    theObject.updateAll(false);
1576:                } catch (DBException ex) {
1577:                    String msg = myName + "updateAll(DataObject) error";
1578:                    log.error(msg, ex);
1579:                    throw new DataException(msg, ex);
1580:                }
1581:
1582:            }
1583:
1584:            /**
1585:             * Takes a <code>DataObject</code> and deletes it from the underlying data source.
1586:             * <b>Note:</b> The current implementation only expects a <code>DBObject</code>
1587:             * and actually routes the call back to that object.  Will be fixed in the future
1588:             * as the interface becomes more rich.
1589:             *
1590:             * @param valueObject the <code>DataObject</code> to delete.
1591:             * @throws DataException upon error deleting the object to the data source
1592:             */
1593:            public void deleteAll(DataObject valueObject,
1594:                    boolean deleteChangedCache) throws DataException {
1595:                if (valueObject == null) {
1596:                    throw new IllegalArgumentException(myName
1597:                            + "deleteAll(DataObject):  valueObject was null");
1598:                }
1599:                DBObject theObject = (DBObject) valueObject;
1600:                try {
1601:                    theObject.deleteAll(false);
1602:                } catch (DBException ex) {
1603:                    String msg = myName + "deleteAll(DataObject) error";
1604:                    log.error(msg, ex);
1605:                    throw new DataException(msg, ex);
1606:                }
1607:
1608:            }
1609:
1610:            /**
1611:             * Helper Function to build a prepared statement's SQL for running STore Procedure statement.
1612:             *
1613:             * @param oneObjectType A single <code>DataObject</code> that is used to model the prepared
1614:             *                      statement.  Only metadata about the <code>DataObject</code>  is used.
1615:             * @return a FastStringBuffer containing the build sql statement
1616:             * @throws DBException upon error
1617:             */
1618:            protected String buildPreparedStoreProcedureSQL(
1619:                    DataObject oneObjectType) throws DBException {
1620:                DBObject theObject = (DBObject) oneObjectType;
1621:                /**
1622:                 * sqlCommand
1623:                 *
1624:                 */
1625:                FastStringBuffer sqlCommand = FastStringBuffer.getInstance();
1626:                FastStringBuffer valuesCommand = FastStringBuffer.getInstance();
1627:                String returnValue = null;
1628:                try {
1629:                    int nbParams = theObject.getDef().getFieldListArray()
1630:                            .size();
1631:
1632:                    if (theObject.getDef().isReturningValue()) {
1633:                        sqlCommand.append("{? = call ");
1634:                        nbParams--;
1635:                    } else {
1636:                        sqlCommand.append("{call ");
1637:                    }
1638:                    sqlCommand.append(theObject.getJDBCMetaData()
1639:                            .getTargetTable());
1640:
1641:                    if (nbParams > 0) {
1642:                        sqlCommand.append("(?");
1643:                        for (int i = 1; i < nbParams; i++) {
1644:                            sqlCommand.append(", ?");
1645:                        }
1646:                        sqlCommand.append(")");
1647:                    }
1648:                    sqlCommand.append("}");
1649:
1650:                    returnValue = sqlCommand.toString();
1651:                } finally {
1652:                    sqlCommand.release();
1653:                    valuesCommand.release();
1654:                    sqlCommand = null;
1655:                    valuesCommand = null;
1656:                }
1657:
1658:                return returnValue;
1659:
1660:            }
1661:
1662:            /**
1663:             * Build and return a FastStringBuffer ring consisting of an SQL 'where' clause
1664:             * using the current field values as criteria for the search. See
1665:             * setCustomWhereClause for information on specifying a more complex where clause.
1666:             *
1667:             * @param criteria            the JDBCDataObject to build from
1668:             * @param myCallableStatement the statement
1669:             * @return A FastStringBuffer containing the "where" clause for the SQL statement
1670:             * @throws DataException upon error
1671:             */
1672:            protected void buildStoreProcedureCallableStatement(
1673:                    DBObject criteria, CallableStatement myCallableStatement)
1674:                    throws DataException {
1675:                Iterator fieldsToUse = null;
1676:                FastStringBuffer myStatement = FastStringBuffer.getInstance();
1677:
1678:                fieldsToUse = criteria.getMetaData().getFieldListArray()
1679:                        .iterator();
1680:
1681:                /* Now go thru each field - if it is non-empty, add it's criteria */
1682:
1683:                DataFieldMetaData oneField = null;
1684:                String oneFieldName = null;
1685:                String oneFieldValue = null;
1686:                boolean postgresql = false;
1687:                boolean skipText = false;
1688:                boolean skipField = false;
1689:                boolean inField = false;
1690:                boolean outField = false;
1691:                TypeMapper typeMapper = null;
1692:
1693:                try {
1694:                    ConfigJdbc myConfig = ConfigManager
1695:                            .getJdbcRequired(criteria.getMappedDataContext());
1696:                    skipText = myConfig.skipText();
1697:                    //We have to do this because postgres won't be smart enough to
1698:                    //cast floating point literals to truly a floating point value. :(
1699:                    if ("org.postgresql.Driver".equals(myConfig.getDriver())) {
1700:                        postgresql = true;
1701:                    }
1702:                    typeMapper = TypeMapper.getInstance(criteria
1703:                            .getDataContext());
1704:                } catch (ConfigurationException ce) {
1705:                    throw new DataException(ce);
1706:                } catch (DBException de) {
1707:                    throw new DataException(de);
1708:                }
1709:
1710:                try {
1711:                    while (fieldsToUse.hasNext()) {
1712:                        oneFieldName = (String) fieldsToUse.next();
1713:                        oneField = criteria.getFieldMetaData(oneFieldName);
1714:                        skipField = false;
1715:                        skipText = false;
1716:                        inField = false;
1717:                        outField = false;
1718:                        if (oneField.isVirtual()) {
1719:                            skipField = true;
1720:                        }
1721:                        if (criteria.getDef().isInField(oneField.getName())) {
1722:                            inField = true;
1723:                        }
1724:                        if (criteria.getDef().isOutField(oneField.getName())) {
1725:                            outField = true;
1726:                        }
1727:                        try {
1728:                            oneFieldValue = StringUtil.notNull(criteria
1729:                                    .getDataField(oneField.getName())
1730:                                    .asString());
1731:                        } catch (DBException ex) {
1732:                            if (ex instanceof  DataException) {
1733:                                throw ((DataException) ex);
1734:                            } else {
1735:                                throw new DataException(
1736:                                        "Error getting field value", ex);
1737:                            }
1738:                        }
1739:
1740:                        if (oneField.isNumericType()
1741:                                || oneField.isFloatingPointType()
1742:                                || oneField.isDateType()) {
1743:                            if ((oneFieldValue == null
1744:                                    || "null".equals(oneFieldValue) || oneFieldValue
1745:                                    .length() == 0)
1746:                                    && inField) {
1747:                                myCallableStatement.setNull(Integer
1748:                                        .parseInt(oneFieldName), typeMapper
1749:                                        .getJavaSQLType(oneField
1750:                                                .getTypeString()));
1751:                            } else {
1752:                                if (oneField.isNumericType()) {
1753:                                    if (inField) {
1754:                                        //								myCallableStatement.setInt(Integer.parseInt(oneFieldName), Integer.parseInt(oneFieldValue));
1755:                                        if (oneField.getTypeString()
1756:                                                .equalsIgnoreCase("integer")
1757:                                                || oneField.getTypeString()
1758:                                                        .equalsIgnoreCase(
1759:                                                                "numeric")
1760:                                                || oneField.getTypeString()
1761:                                                        .equalsIgnoreCase(
1762:                                                                "tinyint")
1763:                                                || oneField.getTypeString()
1764:                                                        .equalsIgnoreCase(
1765:                                                                "smallint")) {
1766:                                            myCallableStatement
1767:                                                    .setInt(
1768:                                                            Integer
1769:                                                                    .parseInt(oneFieldName),
1770:                                                            Integer
1771:                                                                    .parseInt(oneFieldValue));
1772:                                        } else if (oneField.getTypeString()
1773:                                                .equalsIgnoreCase("float")
1774:                                                || oneField.getTypeString()
1775:                                                        .equalsIgnoreCase(
1776:                                                                "real")) {
1777:                                            myCallableStatement
1778:                                                    .setFloat(
1779:                                                            Integer
1780:                                                                    .parseInt(oneFieldName),
1781:                                                            Float
1782:                                                                    .parseFloat(oneFieldValue));
1783:                                        } else if (oneField.getTypeString()
1784:                                                .equalsIgnoreCase("bigint")
1785:                                                || oneField.getTypeString()
1786:                                                        .equalsIgnoreCase(
1787:                                                                "decimal")) {
1788:                                            myCallableStatement
1789:                                                    .setLong(
1790:                                                            Integer
1791:                                                                    .parseInt(oneFieldName),
1792:                                                            Long
1793:                                                                    .parseLong(oneFieldValue));
1794:                                        } else if (oneField.getTypeString()
1795:                                                .equalsIgnoreCase("double")) {
1796:                                            myCallableStatement
1797:                                                    .setDouble(
1798:                                                            Integer
1799:                                                                    .parseInt(oneFieldName),
1800:                                                            Double
1801:                                                                    .parseDouble(oneFieldValue));
1802:                                        }
1803:                                    } else {
1804:                                        myCallableStatement
1805:                                                .registerOutParameter(
1806:                                                        Integer
1807:                                                                .parseInt(oneFieldName),
1808:                                                        typeMapper
1809:                                                                .getJavaSQLType(oneField
1810:                                                                        .getTypeString()));
1811:                                    }
1812:                                } else if (oneField.isDateTimeType()) {
1813:                                    if (inField) {
1814:                                        if (oneField.isDateOnlyType()) {
1815:                                            myCallableStatement
1816:                                                    .setDate(
1817:                                                            Integer
1818:                                                                    .parseInt(oneFieldName),
1819:                                                            java.sql.Date
1820:                                                                    .valueOf(oneFieldValue));
1821:                                        }
1822:                                        if (oneField.isDateTimeType()) {
1823:                                            myCallableStatement
1824:                                                    .setTimestamp(
1825:                                                            Integer
1826:                                                                    .parseInt(oneFieldName),
1827:                                                            java.sql.Timestamp
1828:                                                                    .valueOf(oneFieldValue));
1829:                                        }
1830:                                    } else {
1831:                                        myCallableStatement
1832:                                                .registerOutParameter(
1833:                                                        Integer
1834:                                                                .parseInt(oneFieldName),
1835:                                                        typeMapper
1836:                                                                .getJavaSQLType(oneField
1837:                                                                        .getTypeString()));
1838:                                    }
1839:                                } else if (oneField.isFloatingPointType()) {
1840:                                    if (inField) {
1841:                                        myCallableStatement.setFloat(Integer
1842:                                                .parseInt(oneFieldName), Float
1843:                                                .parseFloat(oneFieldValue));
1844:                                    } else {
1845:                                        myCallableStatement
1846:                                                .registerOutParameter(
1847:                                                        Integer
1848:                                                                .parseInt(oneFieldName),
1849:                                                        typeMapper
1850:                                                                .getJavaSQLType(oneField
1851:                                                                        .getTypeString()),
1852:                                                        oneField.getPrecision());
1853:                                    }
1854:                                }
1855:                            }
1856:                        } else if (oneField.isBooleanType()) {
1857:                            ;
1858:                        } else {
1859:                            if (oneField.getTypeString().equalsIgnoreCase(
1860:                                    "text")) {
1861:                                if (oneFieldValue.indexOf("\n") > 0) {
1862:                                    oneFieldValue = StringUtil.replace(
1863:                                            oneFieldValue, "\n", "");
1864:                                }
1865:                                if (oneFieldValue.indexOf("\r") > 0) {
1866:                                    oneFieldValue = StringUtil.replace(
1867:                                            oneFieldValue, "\r", "");
1868:                                }
1869:                            }
1870:                            if (inField) {
1871:                                myCallableStatement.setString(Integer
1872:                                        .parseInt(oneFieldName), oneFieldValue);
1873:                            }
1874:                            if (outField) {
1875:                                myCallableStatement.registerOutParameter(
1876:                                        Integer.parseInt(oneFieldName),
1877:                                        typeMapper.getJavaSQLType(oneField
1878:                                                .getTypeString()));
1879:                            }
1880:                        }
1881:                    } /* end of while(fieldsToUse.hasNext() */
1882:                    /* for each field */
1883:                } catch (DBException e) {
1884:                    throw new DataException(e);
1885:                } catch (SQLException ce) {
1886:                    throw new DataException(ce);
1887:                } finally {
1888:                    myStatement.release();
1889:                    myStatement = null;
1890:                }
1891:                if (log.isDebugEnabled()) {
1892:                    log.debug("Built callable statement for store procedure ");
1893:                }
1894:            } /* buildStoreProcedureCallableStatement(DBObject, boolean, CallableStatement) */
1895:
1896:            /**
1897:             * Run a store procedure identify by the object with keys specified by the
1898:             * valueObject parameter.
1899:             *
1900:             * @param valueObject the DataObject who's keys are already set to retrieve
1901:             * @return true if the data object was successfully retrieved
1902:             */
1903:            public void runStoreProcedure(DataObject valueObject)
1904:                    throws DataException {
1905:                if (valueObject == null) {
1906:                    throw new IllegalArgumentException(myName
1907:                            + "run(DataObject):  valueObject was null");
1908:                }
1909:                DBObject theObject = (DBObject) valueObject;
1910:                DataFieldMetaData oneField = null;
1911:
1912:                try {
1913:                    String theSqlStatement = buildPreparedStoreProcedureSQL(valueObject);
1914:
1915:                    DBConnection myConnection = null;
1916:
1917:                    DBConnectionPool myPool = DBConnectionPool
1918:                            .getInstance(theObject.getMappedDataContext());
1919:                    DBConnection localConnection = theObject
1920:                            .getLocalConnection();
1921:                    if (localConnection != null) {
1922:                        myConnection = localConnection;
1923:                    } else {
1924:                        myConnection = myPool.getConnection(getClass()
1925:                                .getName());
1926:                    }
1927:
1928:                    try {
1929:                        CallableStatement myStatement = myConnection
1930:                                .createCallableStatement(theSqlStatement);
1931:                        buildStoreProcedureCallableStatement(theObject,
1932:                                myStatement);
1933:                        String oneFieldValue = null;
1934:                        String oneFieldName = null;
1935:                        myConnection.executeProcedure();
1936:                        try {
1937:                            if (myConnection.getResultSet() != null) {
1938:                                //Clear all non-key fields
1939:                                for (Iterator allFields = theObject
1940:                                        .getMetaData().getFieldListArray()
1941:                                        .iterator(); allFields.hasNext();) {
1942:                                    oneFieldName = (String) allFields.next();
1943:                                    DataFieldMetaData fieldMetaData = theObject
1944:                                            .getFieldMetaData(oneFieldName);
1945:                                    if (!fieldMetaData.isKey()
1946:                                            && !fieldMetaData
1947:                                                    .isBinaryObjectType()
1948:                                            && !fieldMetaData.isVirtual()) {
1949:                                        theObject.set(oneFieldName, null);
1950:                                    }
1951:                                }
1952:                                int fieldNum = 0;
1953:                                Iterator it;
1954:                                if (theObject.getDef().getOutParamFieldsCount() > 0) {
1955:                                    //
1956:                                    //We have to load up a metadata array based upon the
1957:                                    //order of the field names as specified in the the
1958:                                    //getOutParamFieldsIterator() function.
1959:                                    //
1960:                                    ArrayList dbFieldArray = new ArrayList(
1961:                                            theObject.getDef()
1962:                                                    .getOutParamFieldsCount());
1963:                                    for (Iterator j = theObject.getDef()
1964:                                            .getOutParamFieldListIterator(); j
1965:                                            .hasNext();) {
1966:                                        String theFieldName = (String) j.next();
1967:                                        dbFieldArray
1968:                                                .add(theObject
1969:                                                        .getFieldMetaData(theFieldName));
1970:                                    }
1971:                                    it = dbFieldArray.iterator();
1972:                                    while (it.hasNext()) {
1973:                                        oneField = (DBField) it.next();
1974:                                        fieldNum = Integer.parseInt(oneField
1975:                                                .getName());
1976:                                        if (!oneField.isVirtual()) {
1977:                                            if (oneField.isBinaryObjectType()) {
1978:                                                continue;
1979:                                            }
1980:                                            try {
1981:                                                //   * @author	  Yves Henri AMAIZO
1982:                                                //   Handle correctly date from resultSet data retrieve from Database
1983:                                                if (oneField.isDateType()) {
1984:                                                    oneFieldValue = theObject
1985:                                                            .getCustomStringFieldValue(
1986:                                                                    myConnection,
1987:                                                                    oneField
1988:                                                                            .getName());
1989:                                                } else {
1990:                                                    if (myConnection
1991:                                                            .isStringNotTrim()) {
1992:                                                        oneFieldValue = myConnection
1993:                                                                .getStringNoTrim(fieldNum);
1994:                                                    } else {
1995:                                                        oneFieldValue = myConnection
1996:                                                                .getString(fieldNum);
1997:                                                    }
1998:                                                }
1999:                                            } catch (DBException de1) {
2000:                                                throw new DataException(
2001:                                                        "("
2002:                                                                + getClass()
2003:                                                                        .getName()
2004:                                                                + ") Error retrieving field '"
2005:                                                                + oneField
2006:                                                                        .getName()
2007:                                                                + "' index "
2008:                                                                + fieldNum
2009:                                                                + ":"
2010:                                                                + de1
2011:                                                                        .getMessage(),
2012:                                                        de1.getDBMessage());
2013:                                            }
2014:                                            theObject.set(oneField.getName(),
2015:                                                    oneFieldValue);
2016:                                        }
2017:                                    }
2018:                                }
2019:                            } else {
2020:                                //There were zero results returned by the retrieve() call.
2021:                                return;
2022:                            }
2023:                        } finally {
2024:                            ;
2025:                        }
2026:                    } finally {
2027:                        if (localConnection == null) {
2028:                            if (myPool != null && myConnection != null) {
2029:                                myPool.release(myConnection);
2030:                            }
2031:                        }
2032:                    }
2033:                } catch (DBException ex) {
2034:                    String msg = myName + "run(DataObject) error";
2035:                    log.error(msg, ex);
2036:                    throw new DataException(msg, ex);
2037:                }
2038:            } /* runStoreProcedure(DataObject) */
2039:
2040:            /**
2041:             * Adds an entire batch of <code>DataObject</code>s to the underlying JDBC data source
2042:             *
2043:             * @param valueObjectList      A list of <code>DataObject</code>s to add to the underlying
2044:             *                             data source <b>NOTE:</b> you will get best performance if valueObjectList is
2045:             *                             all one dataobject underneath.
2046:             * @param addChangedFieldsOnly flag to signify if only fields whose value
2047:             *                             has changed should be included in the add.
2048:             *                             <p/>
2049:             *                             WARNING: I DON'T UNDERSTAND WHY LOOP VAR ISN'T USED BELOW, AND SUSPECT THIS METHOD ISN'T DOING ALL IT PURPORTS TO DO; SEE "todo"  (Larry Hamel, 3/03)
2050:             * @throws DataException         upon error communicating with the underlying data source
2051:             * @throws DuplicateKeyException if one of the records was already in the
2052:             *                               data source
2053:             */
2054:            public void addBatch(List valueObjectList,
2055:                    boolean addChangedFieldsOnly) throws DataException,
2056:                    DuplicateKeyException {
2057:                if (valueObjectList == null) {
2058:                    throw new IllegalArgumentException(myName
2059:                            + "addBatch(List):  valueObjectArray was null");
2060:                }
2061:
2062:                DBObject checkObject = null;
2063:                DBConnectionPool myPool = null;
2064:                DBConnection localConnection = null;
2065:                java.sql.PreparedStatement prepStatement = null;
2066:                DataObjectMetaData metadata = null;
2067:
2068:                ArrayList fieldData = new ArrayList(6);
2069:                ArrayList fieldDataMetaData = new ArrayList(6);
2070:                ArrayList keyData = new ArrayList(3);
2071:                ArrayList keyDataMetaData = new ArrayList(3);
2072:                FastStringBuffer valuesCommand = FastStringBuffer.getInstance();
2073:                String theStatementString = "";
2074:
2075:                try {
2076:                    for (Iterator i = valueObjectList.iterator(); i.hasNext();) {
2077:                        DBObject oneObj = (DBObject) i.next();
2078:                        //
2079:                        //If we're on the first object, then we need to build the prepared statement
2080:                        //
2081:                        if (checkObject == null) {
2082:                            localConnection = oneObj.getLocalConnection();
2083:                            if (localConnection == null) {
2084:                                myPool = DBConnectionPool.getInstance(oneObj
2085:                                        .getMappedDataContext());
2086:                                localConnection = myPool
2087:                                        .getConnection("Batch Add");
2088:                            }
2089:                            localConnection.clear();
2090:                            if (localConnection.supportsTransactions()) {
2091:                                if (!localConnection.getImmortal()) {
2092:                                    localConnection.setAutoCommit(false);
2093:                                }
2094:                            }
2095:
2096:                            //
2097:                            //If the database doesn't explicitly support batch updates,
2098:                            //then we call add multiple times.
2099:                            //
2100:                            java.sql.DatabaseMetaData md = localConnection
2101:                                    .getConnection().getMetaData();
2102:                            if (!md.supportsBatchUpdates()) {
2103:                                for (Iterator l = valueObjectList.iterator(); l
2104:                                        .hasNext();) {
2105:                                    DataObject oneDataObject = (DataObject) l
2106:                                            .next();
2107:                                    oneDataObject.add();
2108:                                }
2109:                                if (localConnection.supportsTransactions()) {
2110:                                    if (!localConnection.getImmortal()) {
2111:                                        localConnection.commit();
2112:                                        localConnection.setAutoCommit(true);
2113:                                    }
2114:                                }
2115:                                return;
2116:                            }
2117:                            theStatementString = buildPreparedAddSQL(oneObj,
2118:                                    addChangedFieldsOnly);
2119:                            prepStatement = localConnection
2120:                                    .createPreparedStatement(theStatementString);
2121:                            checkObject = oneObj;
2122:                            metadata = checkObject.getMetaData();
2123:                        }
2124:
2125:                        boolean needCommaValues = false;
2126:                        valuesCommand.append(" VALUES (");
2127:
2128:                        //
2129:                        //we have to make sure that the classes are the same time or
2130:                        //we're in trouble.
2131:                        //
2132:                        if (!(checkObject.getClass().getName().equals(oneObj
2133:                                .getClass().getName()))) {
2134:                            throw new IllegalArgumentException(
2135:                                    "JDBC Excecutor.addBatch()"
2136:                                            + " all objects in the valueObjectList must be the same type.");
2137:                        }
2138:
2139:                        //
2140:                        //Now we iterate through and set all the parameters
2141:                        //
2142:                        for (Iterator j = metadata.getFieldListArray()
2143:                                .iterator(); j.hasNext();) {
2144:                            String oneFieldName = (String) j.next();
2145:
2146:                            // Only include changed fields in the update if required
2147:                            if (addChangedFieldsOnly) {
2148:                                if (oneObj.getDataField(oneFieldName)
2149:                                        .isValueSet()
2150:                                        && oneObj.getStatus().equals(
2151:                                                DataObject.STATUS_NEW)) {
2152:                                    ;
2153:                                } else {
2154:                                    if (!oneObj.getDataField(oneFieldName)
2155:                                            .isChanged()) {
2156:                                        continue;
2157:                                    }
2158:                                }
2159:                            }
2160:
2161:                            DataFieldMetaData oneField = oneObj
2162:                                    .getFieldMetaData(oneFieldName);
2163:                            oneObj.checkField(oneField.getName(), oneObj
2164:                                    .getField(oneField.getName()));
2165:
2166:                            //Sematics . if oneStringValue == null then
2167:                            //we skip the field.
2168:                            //if oneStringValue.equals("null"); then we add a nullable
2169:                            //section to the PreparedStatement.
2170:                            String oneStringValue = null;
2171:
2172:                            oneStringValue = prepareForStorage(oneField,
2173:                                    oneObj, false);
2174:
2175:                            if (oneStringValue == null) {
2176:                                oneStringValue = "null";
2177:                            }
2178:
2179:                            if (log.isDebugEnabled()) {
2180:                                if (needCommaValues) {
2181:                                    valuesCommand.append(", ");
2182:                                }
2183:                                valuesCommand.append(oneStringValue);
2184:                                needCommaValues = true;
2185:                            }
2186:
2187:                            if (oneField.isKey()) {
2188:                                keyDataMetaData.add(oneField);
2189:                                keyData.add(oneStringValue);
2190:                            } else {
2191:                                //We don't mess with auto-inc fields, virtual fields, or
2192:                                //binary fields.
2193:                                if (oneField.isVirtual()
2194:                                        || oneField.isBinaryObjectType()
2195:                                        || oneField.isAutoIncremented()) {
2196:                                    continue;
2197:                                }
2198:                            }
2199:                            fieldDataMetaData.add(oneField);
2200:                            fieldData.add(oneStringValue);
2201:                        }
2202:
2203:                        //We're done iterating through paramters/
2204:
2205:                        int size = fieldData.size();
2206:                        //				try {
2207:                        //					prepStatement.clearParameters();
2208:                        //				} catch (NullPointerException ex) {
2209:                        //					//
2210:                        //					//Workaround for known Oracle bug. Clear parameters
2211:                        //					//throws NPE's
2212:                        //					//
2213:                        //					if (log.isDebugEnabled()) {
2214:                        //						log.debug("NPE.  Oracle Driver?", ex);
2215:                        //					}
2216:                        //				}
2217:
2218:                        TypeMapper typeMapper = TypeMapper
2219:                                .getInstance(localConnection.getDataContext());
2220:                        for (int j = 0; j < size; j++) {
2221:                            String stringValue = (String) fieldData.get(j);
2222:
2223:                            DBField singleFieldMeta = (DBField) fieldDataMetaData
2224:                                    .get(j);
2225:
2226:                            int typeCode = typeMapper
2227:                                    .getJavaSQLType(singleFieldMeta
2228:                                            .getTypeString());
2229:                            if ("null".equals(stringValue)) {
2230:                                prepStatement.setNull(j + 1, typeCode);
2231:                            } else if (singleFieldMeta.isNumericType()) {
2232:                                if (singleFieldMeta.getTypeString()
2233:                                        .equalsIgnoreCase("integer")
2234:                                        || singleFieldMeta.getTypeString()
2235:                                                .equalsIgnoreCase("tinyint")
2236:                                        || singleFieldMeta.getTypeString()
2237:                                                .equalsIgnoreCase("smallint")) {
2238:                                    prepStatement.setInt(j + 1, Integer
2239:                                            .parseInt(stringValue));
2240:                                } else if (singleFieldMeta.getTypeString()
2241:                                        .equalsIgnoreCase("float")
2242:                                        || singleFieldMeta.getTypeString()
2243:                                                .equalsIgnoreCase("real")) {
2244:                                    prepStatement.setFloat(j + 1, Float
2245:                                            .parseFloat(stringValue));
2246:                                } else if (singleFieldMeta.getTypeString()
2247:                                        .equalsIgnoreCase("bigint")
2248:                                        || singleFieldMeta.getTypeString()
2249:                                                .equalsIgnoreCase("numeric")
2250:                                        || singleFieldMeta.getTypeString()
2251:                                                .equalsIgnoreCase("decimal")) {
2252:                                    prepStatement.setLong(j + 1, Long
2253:                                            .parseLong(stringValue));
2254:                                } else if (singleFieldMeta.getTypeString()
2255:                                        .equalsIgnoreCase("double")) {
2256:                                    prepStatement.setDouble(j + 1, Double
2257:                                            .parseDouble(stringValue));
2258:                                }
2259:                            } else if (singleFieldMeta.isDateType()) {
2260:                                if (singleFieldMeta.isDateOnlyType()) {
2261:                                    Date dtOnly = java.sql.Date
2262:                                            .valueOf(stringValue);
2263:                                    prepStatement.setDate(j + 1, dtOnly);
2264:                                }
2265:                                if (singleFieldMeta.isDateTimeType()) {
2266:                                    Timestamp dts = Timestamp
2267:                                            .valueOf(stringValue);
2268:                                    prepStatement.setTimestamp(j + 1, dts);
2269:                                }
2270:                            } else if (singleFieldMeta.isFloatingPointType()) {
2271:                                prepStatement.setFloat(j + 1, Float
2272:                                        .parseFloat(stringValue));
2273:                            } else {
2274:                                if (singleFieldMeta.getTypeString()
2275:                                        .equalsIgnoreCase("text")) {
2276:                                    if (stringValue.indexOf("\n") > 0) {
2277:                                        stringValue = StringUtil.replace(
2278:                                                stringValue, "\n", "");
2279:                                    }
2280:                                    if (stringValue.indexOf("\r") > 0) {
2281:                                        stringValue = StringUtil.replace(
2282:                                                stringValue, "\r", "");
2283:                                    }
2284:                                }
2285:                                prepStatement.setString(j + 1, stringValue);
2286:
2287:                            }
2288:                        }
2289:
2290:                        //Ok, we're set, now it's time to add the batch
2291:
2292:                        prepStatement.addBatch();
2293:                        if (log.isDebugEnabled()) {
2294:                            valuesCommand.append(") ");
2295:                            log.debug("Batch Add '" + theStatementString + "  "
2296:                                    + valuesCommand + "   request in ("
2297:                                    + localConnection.getDescription()
2298:                                    + ", db/context '"
2299:                                    + localConnection.getDataContext() + "')");
2300:                            valuesCommand.clear();
2301:                        }
2302:                        fieldData.clear();
2303:                        fieldDataMetaData.clear();
2304:                        keyData.clear();
2305:                        keyDataMetaData.clear();
2306:                    }
2307:
2308:                    prepStatement.executeBatch();
2309:                    localConnection.clearPreparedStatement();
2310:                    if (!localConnection.getImmortal()) {
2311:                        localConnection.commit();
2312:                    }
2313:                    valuesCommand.release();
2314:                } catch (BatchUpdateException ex) {
2315:                    log.error("Batch Add Exception", ex);
2316:                    try {
2317:                        if (!localConnection.getImmortal()) {
2318:                            localConnection.rollback();
2319:                        }
2320:                    } catch (DBException ex1) {
2321:                        log
2322:                                .error(
2323:                                        "Error rolling back transaction on local connection",
2324:                                        ex1);
2325:                    }
2326:                    String msg = myName
2327:                            + "addBatch(DataObject) BatchUpdateException.  ";
2328:                    log.error(msg, ex);
2329:                    throw new DataException(msg, ex);
2330:                } catch (java.lang.ClassCastException cce) {
2331:                    cce.printStackTrace();
2332:                    throw cce;
2333:                } catch (NullPointerException npe) {
2334:                    npe.printStackTrace();
2335:                    throw npe;
2336:                } catch (SQLException ex) {
2337:                    ex.printStackTrace();
2338:                    try {
2339:                        if (!localConnection.getImmortal()) {
2340:                            localConnection.rollback();
2341:                        }
2342:                    } catch (DBException ex1) {
2343:                        log
2344:                                .error(
2345:                                        "Error rolling back transaction on local connection",
2346:                                        ex1);
2347:                    }
2348:                    String msg = myName
2349:                            + "addBatch(DataObject) SQLException.  ";
2350:                    log.error(msg, ex);
2351:                    throw new DataException(msg, ex);
2352:                } catch (DBException ex) {
2353:                    try {
2354:                        if (!localConnection.getImmortal()) {
2355:                            localConnection.rollback();
2356:                        }
2357:                    } catch (DBException ex1) {
2358:                        log
2359:                                .error(
2360:                                        "Error rolling back transaction on local connection",
2361:                                        ex1);
2362:                    }
2363:                    String msg = myName + "addBatch(DataObject) error";
2364:                    log.error(msg, ex);
2365:                    throw new DataException(msg, ex);
2366:                } finally {
2367:                    if (prepStatement != null) {
2368:                        try {
2369:                            if (!localConnection.getImmortal()) {
2370:                                prepStatement.close();
2371:                            }
2372:                        } catch (SQLException ex) {
2373:                            log.error("Error closing prepared statement", ex);
2374:                        }
2375:                    }
2376:
2377:                    if (localConnection != null) {
2378:                        localConnection.clearPreparedStatement();
2379:                    }
2380:
2381:                    if (myPool != null) {
2382:                        if (localConnection != null) {
2383:                            //Auto-commit is automatically turned back on by
2384:                            //release
2385:                            if (!localConnection.getImmortal()) {
2386:                                myPool.release(localConnection);
2387:                            }
2388:                        }
2389:                    }
2390:                }
2391:            }
2392:
2393:            /**
2394:             * Updates an entire batch of <code>DataObject</code>s
2395:             *
2396:             * @param valueObjectList         A list of <code>DataObject</code>s to update to the underlying
2397:             *                                data source
2398:             * @param updateChangedFieldsOnly flag to signify if only fields whose value
2399:             *                                has changed should be included in the update.
2400:             * @throws DataException upon error updating the data source
2401:             */
2402:            public void updateBatch(List valueObjectList,
2403:                    boolean updateChangedFieldsOnly) throws DataException {
2404:                if (valueObjectList == null) {
2405:                    throw new IllegalArgumentException(
2406:                            myName
2407:                                    + "updateBatch(List, boolean):  valueObjectArray was null");
2408:                }
2409:
2410:                DBObject checkObject = null;
2411:                DBConnectionPool myPool = null;
2412:                DBConnection localConnection = null;
2413:                DataObjectMetaData metadata = null;
2414:                java.sql.PreparedStatement prepStatement = null;
2415:                ArrayList fieldData = new ArrayList(6);
2416:                ArrayList fieldDataMetaData = new ArrayList(6);
2417:                ArrayList keyData = new ArrayList(3);
2418:                ArrayList keyDataMetaData = new ArrayList(3);
2419:                FastStringBuffer valuesCommand = FastStringBuffer.getInstance();
2420:                String theStatementString = "";
2421:
2422:                try {
2423:                    for (Iterator i = valueObjectList.iterator(); i.hasNext();) {
2424:                        DBObject oneObj = (DBObject) i.next();
2425:                        fieldData.clear();
2426:                        fieldDataMetaData.clear();
2427:                        keyData.clear();
2428:                        keyDataMetaData.clear();
2429:
2430:                        //
2431:                        //If we're on the first object, then we need to build the prepared statement
2432:                        //
2433:                        if (checkObject == null) {
2434:                            localConnection = oneObj.getLocalConnection();
2435:                            if (localConnection == null) {
2436:                                myPool = DBConnectionPool.getInstance(oneObj
2437:                                        .getMappedDataContext());
2438:                                localConnection = myPool
2439:                                        .getConnection("Batch Update");
2440:                            }
2441:                            localConnection.clear();
2442:                            if (localConnection.supportsTransactions()) {
2443:                                if (!localConnection.getImmortal()) {
2444:                                    localConnection.setAutoCommit(false);
2445:                                }
2446:                            }
2447:                            //
2448:                            //If the database doesn't explicitly support batch updates,
2449:                            //then we call add multiple times.
2450:                            //
2451:                            java.sql.DatabaseMetaData md = localConnection
2452:                                    .getConnection().getMetaData();
2453:                            if (!md.supportsBatchUpdates()) {
2454:                                for (Iterator l = valueObjectList.iterator(); l
2455:                                        .hasNext();) {
2456:                                    DataObject oneDataObject = (DataObject) l
2457:                                            .next();
2458:                                    oneDataObject.update();
2459:                                }
2460:                                if (localConnection.supportsTransactions()) {
2461:                                    if (!localConnection.getImmortal()) {
2462:                                        localConnection.commit();
2463:                                        localConnection.setAutoCommit(true);
2464:                                    }
2465:                                }
2466:                                return;
2467:                            }
2468:
2469:                            theStatementString = buildPreparedUpdateSQL(oneObj,
2470:                                    updateChangedFieldsOnly);
2471:                            prepStatement = localConnection
2472:                                    .createPreparedStatement(theStatementString);
2473:                            checkObject = oneObj;
2474:                            metadata = checkObject.getMetaData();
2475:                        }
2476:
2477:                        boolean needCommaValues = false;
2478:                        valuesCommand.append(" VALUES (");
2479:
2480:                        //
2481:                        //we have to make sure that the classes are the same time or
2482:                        //we're in trouble.
2483:                        //
2484:                        if (!(checkObject.getClass().getName().equals(oneObj
2485:                                .getClass().getName()))) {
2486:                            throw new IllegalArgumentException(
2487:                                    "JDBC Excecutor.updateBatch(List, boolean)"
2488:                                            + " all objects in the valueObjectList must be the same type.");
2489:                        }
2490:
2491:                        //
2492:                        //Now we iterate through and set all the parameters
2493:                        //
2494:                        for (Iterator j = metadata.getFieldListArray()
2495:                                .iterator(); j.hasNext();) {
2496:                            String oneFieldName = (String) j.next();
2497:
2498:                            // Only include changed fields in the update if required
2499:                            if (updateChangedFieldsOnly) {
2500:                                if (oneObj.getDataField(oneFieldName)
2501:                                        .isValueSet()
2502:                                        && oneObj.getStatus().equals(
2503:                                                DataObject.STATUS_NEW)) {
2504:                                    ;
2505:                                } else {
2506:                                    if (!oneObj.getDataField(oneFieldName)
2507:                                            .isChanged()) {
2508:                                        continue;
2509:                                    }
2510:                                }
2511:                            }
2512:
2513:                            DataFieldMetaData oneField = oneObj
2514:                                    .getFieldMetaData(oneFieldName);
2515:                            oneObj.checkField(oneField.getName(), oneObj
2516:                                    .getField(oneField.getName()));
2517:
2518:                            //Sematics . if oneStringValue == null then
2519:                            //we skip the field.
2520:                            //if oneStringValue.equals("null"); then we add a nullable
2521:                            //section to the PreparedStatement.
2522:                            String oneStringValue = null;
2523:
2524:                            oneStringValue = prepareForStorage(oneField,
2525:                                    oneObj, false);
2526:
2527:                            if (oneStringValue == null) {
2528:                                oneStringValue = "null";
2529:                            }
2530:
2531:                            if (log.isDebugEnabled()) {
2532:                                if (needCommaValues) {
2533:                                    valuesCommand.append(", ");
2534:                                }
2535:                                valuesCommand.append(oneStringValue);
2536:                                needCommaValues = true;
2537:                            }
2538:
2539:                            if (oneField.isKey()) {
2540:                                keyDataMetaData.add(oneField);
2541:                                keyData.add(oneStringValue);
2542:                            } else {
2543:                                //We don't mess with auto-inc fields, virtual fields, or
2544:                                //binary fields.
2545:                                if (oneField.isVirtual()
2546:                                        || oneField.isBinaryObjectType()
2547:                                        || oneField.isAutoIncremented()) {
2548:                                    continue;
2549:                                }
2550:
2551:                                fieldDataMetaData.add(oneField);
2552:                                fieldData.add(oneStringValue);
2553:                            }
2554:                        }
2555:                        //
2556:                        //Ok, order of prepared statement is: data fields first, then
2557:                        //key fields  so we concatenate to make things easier to cope
2558:                        //with logic-wise
2559:                        //
2560:                        fieldData.addAll(keyData);
2561:                        fieldDataMetaData.addAll(keyDataMetaData);
2562:
2563:                        int size = fieldData.size();
2564:                        //				try {
2565:                        //					prepStatement.clearParameters();
2566:                        //				} catch (NullPointerException ex) {
2567:                        //					//
2568:                        //					//Workaround for known Oracle bug. Clear parameters
2569:                        //					//throws NPE's
2570:                        //					//
2571:                        //					if (log.isDebugEnabled()) {
2572:                        //						log.debug("NPE.  Oracle Driver?", ex);
2573:                        //					}
2574:                        //				}
2575:                        TypeMapper typeMapper = TypeMapper
2576:                                .getInstance(localConnection.getDataContext());
2577:                        for (int j = 0; j < size; j++) {
2578:                            String stringValue = (String) fieldData.get(j);
2579:
2580:                            DBField singleFieldMeta = (DBField) fieldDataMetaData
2581:                                    .get(j);
2582:
2583:                            int typeCode = typeMapper
2584:                                    .getJavaSQLType(singleFieldMeta
2585:                                            .getTypeString());
2586:                            if ("null".equals(stringValue)) {
2587:                                prepStatement.setNull(j + 1, typeCode);
2588:                            } else if (singleFieldMeta.isNumericType()) {
2589:                                if (singleFieldMeta.getTypeString()
2590:                                        .equalsIgnoreCase("integer")
2591:                                        || singleFieldMeta.getTypeString()
2592:                                                .equalsIgnoreCase("numeric")
2593:                                        || singleFieldMeta.getTypeString()
2594:                                                .equalsIgnoreCase("tinyint")
2595:                                        || singleFieldMeta.getTypeString()
2596:                                                .equalsIgnoreCase("smallint")) {
2597:                                    prepStatement.setInt(j + 1, Integer
2598:                                            .parseInt(stringValue));
2599:                                } else if (singleFieldMeta.getTypeString()
2600:                                        .equalsIgnoreCase("float")
2601:                                        || singleFieldMeta.getTypeString()
2602:                                                .equalsIgnoreCase("real")) {
2603:                                    prepStatement.setFloat(j + 1, Float
2604:                                            .parseFloat(stringValue));
2605:                                } else if (singleFieldMeta.getTypeString()
2606:                                        .equalsIgnoreCase("bigint")
2607:                                        || singleFieldMeta.getTypeString()
2608:                                                .equalsIgnoreCase("decimal")) {
2609:                                    prepStatement.setLong(j + 1, Long
2610:                                            .parseLong(stringValue));
2611:                                } else if (singleFieldMeta.getTypeString()
2612:                                        .equalsIgnoreCase("double")) {
2613:                                    prepStatement.setDouble(j + 1, Double
2614:                                            .parseDouble(stringValue));
2615:                                }
2616:                            } else if (singleFieldMeta.isDateType()) {
2617:                                if (singleFieldMeta.isDateOnlyType()) {
2618:                                    Date dtOnly = java.sql.Date
2619:                                            .valueOf(stringValue);
2620:                                    prepStatement.setDate(j + 1, dtOnly);
2621:                                }
2622:                                if (singleFieldMeta.isDateTimeType()) {
2623:                                    Timestamp dts = Timestamp
2624:                                            .valueOf(stringValue);
2625:                                    prepStatement.setTimestamp(j + 1, dts);
2626:                                }
2627:                            } else if (singleFieldMeta.isFloatingPointType()) {
2628:                                prepStatement.setFloat(j + 1, Float
2629:                                        .parseFloat(stringValue));
2630:                            } else {
2631:                                if (singleFieldMeta.getTypeString()
2632:                                        .equalsIgnoreCase("text")) {
2633:                                    if (stringValue.indexOf("\n") > 0) {
2634:                                        stringValue = StringUtil.replace(
2635:                                                stringValue, "\n", "");
2636:                                    }
2637:                                    if (stringValue.indexOf("\r") > 0) {
2638:                                        stringValue = StringUtil.replace(
2639:                                                stringValue, "\r", "");
2640:                                    }
2641:                                }
2642:                                prepStatement.setString(j + 1, stringValue);
2643:
2644:                            }
2645:                        }
2646:
2647:                        //Ok, we're set, now it's time to add the batch
2648:                        prepStatement.addBatch();
2649:                        if (oneObj.isCached()) {
2650:                            oneObj.removeFromCache(oneObj);
2651:                        }
2652:                        if (log.isDebugEnabled()) {
2653:                            valuesCommand.append(") ");
2654:                            log.debug("Batch Update '" + theStatementString
2655:                                    + "  " + valuesCommand + "   request in ("
2656:                                    + localConnection.getDescription()
2657:                                    + ", db/context '"
2658:                                    + localConnection.getDataContext() + "')");
2659:                            valuesCommand.clear();
2660:                        }
2661:                        fieldData.clear();
2662:                        fieldDataMetaData.clear();
2663:                        keyData.clear();
2664:                        keyDataMetaData.clear();
2665:                    }
2666:
2667:                    prepStatement.executeBatch();
2668:                    localConnection.clearPreparedStatement();
2669:                    if (!localConnection.getImmortal()) {
2670:                        localConnection.commit();
2671:                    }
2672:                    valuesCommand.release();
2673:                } catch (NullPointerException npe) {
2674:                    log.error("NPE Error performing batch update", npe);
2675:                    throw npe;
2676:                } catch (NumberFormatException nfe) {
2677:                    log
2678:                            .error(
2679:                                    "NumberFormatException Error performing batch update",
2680:                                    nfe);
2681:                    throw nfe;
2682:                } catch (java.lang.ArrayIndexOutOfBoundsException ex) {
2683:                    log
2684:                            .error(
2685:                                    "ArrayIndexOutOfBoundsException performing batch update",
2686:                                    ex);
2687:                    throw ex;
2688:                } catch (ClassCastException cce) {
2689:                    log.error("Class Cast Exception performing batch update",
2690:                            cce);
2691:                    throw cce;
2692:                } catch (SQLException ex) {
2693:                    try {
2694:                        if (!localConnection.getImmortal()) {
2695:                            localConnection.rollback();
2696:                        }
2697:                    } catch (DBException ex1) {
2698:                        log.error(
2699:                                "Error rolling back update batch transaction",
2700:                                ex1);
2701:                    }
2702:                    ex.printStackTrace();
2703:                    String msg = myName
2704:                            + "updateBatch(DataObject, updateChangedFieldsOnly) SQLException.  ";
2705:                    log.error(msg, ex);
2706:                    throw new DataException(msg, ex);
2707:                } catch (DBException ex) {
2708:                    try {
2709:                        if (!localConnection.getImmortal()) {
2710:                            localConnection.rollback();
2711:                        }
2712:                    } catch (DBException ex1) {
2713:                        log.error(
2714:                                "Error rolling back update batch transaction",
2715:                                ex1);
2716:                    }
2717:                    String msg = myName
2718:                            + "updateBatch(DataObject, updateChangedFieldsOnly) error";
2719:                    log.error(msg, ex);
2720:                    throw new DataException(msg, ex);
2721:                } catch (Throwable t) {
2722:                    log.error("Caught Throwable performing batch update", t);
2723:                    throw new DataException(t);
2724:                } finally {
2725:                    if (prepStatement != null) {
2726:                        try {
2727:                            prepStatement.close();
2728:                        } catch (SQLException ex) {
2729:                            log
2730:                                    .error(
2731:                                            "Error closing prepared statement for batch update",
2732:                                            ex);
2733:                        }
2734:                    }
2735:                    if (localConnection != null) {
2736:                        localConnection.clearPreparedStatement();
2737:                    }
2738:
2739:                    if (myPool != null) {
2740:                        if (localConnection != null) {
2741:                            //Auto-commit is automatically turned back on by
2742:                            //release
2743:                            if (!localConnection.getImmortal()) {
2744:                                myPool.release(localConnection);
2745:                            }
2746:                        }
2747:                    }
2748:                }
2749:            }
2750:
2751:            /**
2752:             * Updates an entire batch of <code>DataObject</code>s
2753:             *
2754:             * @param valueObjectList         A list of <code>DataObject</code>s to update to the underlying
2755:             *                                data source
2756:             * @param deleteWithSetFieldsOnly Only include changed fields in the update
2757:             * @throws DataException upon error updating the data source
2758:             */
2759:            public void deleteBatch(List valueObjectList,
2760:                    boolean deleteWithSetFieldsOnly) throws DataException {
2761:                if (valueObjectList == null) {
2762:                    throw new IllegalArgumentException(
2763:                            myName
2764:                                    + "updateBatch(List, boolean):  valueObjectArray was null");
2765:                }
2766:
2767:                DBObject checkObject = null;
2768:                DBConnectionPool myPool = null;
2769:                DBConnection localConnection = null;
2770:                DataObjectMetaData metadata = null;
2771:                java.sql.PreparedStatement prepStatement = null;
2772:                ArrayList fieldData = new ArrayList(6);
2773:                ArrayList fieldDataMetaData = new ArrayList(6);
2774:                ArrayList keyData = new ArrayList(3);
2775:                ArrayList keyDataMetaData = new ArrayList(3);
2776:                FastStringBuffer valuesCommand = FastStringBuffer.getInstance();
2777:                String theStatementString = "";
2778:
2779:                try {
2780:                    for (Iterator i = valueObjectList.iterator(); i.hasNext();) {
2781:                        DBObject oneObj = (DBObject) i.next();
2782:                        fieldData.clear();
2783:                        fieldDataMetaData.clear();
2784:                        keyData.clear();
2785:                        keyDataMetaData.clear();
2786:
2787:                        //
2788:                        //If we're on the first object, then we need to build the prepared statement
2789:                        //
2790:                        if (checkObject == null) {
2791:                            localConnection = oneObj.getLocalConnection();
2792:                            if (localConnection == null) {
2793:                                myPool = DBConnectionPool.getInstance(oneObj
2794:                                        .getMappedDataContext());
2795:                                localConnection = myPool
2796:                                        .getConnection("Batch Delete");
2797:                            }
2798:                            localConnection.clear();
2799:                            if (localConnection.supportsTransactions()) {
2800:                                if (!localConnection.getImmortal()) {
2801:                                    localConnection.setAutoCommit(false);
2802:                                }
2803:                            }
2804:                            //
2805:                            //If the database doesn't explicitly support batch updates,
2806:                            //then we call add multiple times.
2807:                            //
2808:                            java.sql.DatabaseMetaData md = localConnection
2809:                                    .getConnection().getMetaData();
2810:                            if (!md.supportsBatchUpdates()) {
2811:                                for (Iterator l = valueObjectList.iterator(); l
2812:                                        .hasNext();) {
2813:                                    DataObject oneDataObject = (DataObject) l
2814:                                            .next();
2815:                                    oneDataObject.update();
2816:                                }
2817:                                if (localConnection.supportsTransactions()) {
2818:                                    if (!localConnection.getImmortal()) {
2819:                                        localConnection.commit();
2820:                                        localConnection.setAutoCommit(true);
2821:                                    }
2822:                                }
2823:                                return;
2824:                            }
2825:
2826:                            theStatementString = buildPreparedDeleteSQL(oneObj,
2827:                                    deleteWithSetFieldsOnly);
2828:                            prepStatement = localConnection
2829:                                    .createPreparedStatement(theStatementString);
2830:                            checkObject = oneObj;
2831:                            metadata = checkObject.getMetaData();
2832:                        }
2833:
2834:                        boolean needCommaValues = false;
2835:                        valuesCommand.append(" VALUES (");
2836:
2837:                        //
2838:                        //we have to make sure that the classes are the same time or
2839:                        //we're in trouble.
2840:                        //
2841:                        if (!(checkObject.getClass().getName().equals(oneObj
2842:                                .getClass().getName()))) {
2843:                            throw new IllegalArgumentException(
2844:                                    "JDBC Excecutor.deleteBatch(List, boolean)"
2845:                                            + " all objects in the valueObjectList must be the same type.");
2846:                        }
2847:
2848:                        //
2849:                        //Now we iterate through and set all the parameters
2850:                        //
2851:                        for (Iterator j = metadata.getFieldListArray()
2852:                                .iterator(); j.hasNext();) {
2853:                            String oneFieldName = (String) j.next();
2854:
2855:                            // Only include changed fields in the update if required
2856:                            if (deleteWithSetFieldsOnly) {
2857:                                if (oneObj.getDataField(oneFieldName)
2858:                                        .isValueSet()
2859:                                        && oneObj.getStatus().equals(
2860:                                                DataObject.STATUS_NEW)) {
2861:                                    ;
2862:                                } else {
2863:                                    if (!oneObj.getDataField(oneFieldName)
2864:                                            .isChanged()) {
2865:                                        continue;
2866:                                    }
2867:                                }
2868:                            }
2869:
2870:                            DataFieldMetaData oneField = oneObj
2871:                                    .getFieldMetaData(oneFieldName);
2872:                            oneObj.checkField(oneField.getName(), oneObj
2873:                                    .getField(oneField.getName()));
2874:
2875:                            //Sematics . if oneStringValue == null then
2876:                            //we skip the field.
2877:                            //if oneStringValue.equals("null"); then we add a nullable
2878:                            //section to the PreparedStatement.
2879:                            String oneStringValue = null;
2880:
2881:                            oneStringValue = prepareForStorage(oneField,
2882:                                    oneObj, false);
2883:
2884:                            if (oneStringValue == null) {
2885:                                oneStringValue = "null";
2886:                            }
2887:
2888:                            if (log.isDebugEnabled()) {
2889:                                if (needCommaValues) {
2890:                                    valuesCommand.append(", ");
2891:                                }
2892:                                valuesCommand.append(oneStringValue);
2893:                                needCommaValues = true;
2894:                            }
2895:
2896:                            if (oneField.isKey()) {
2897:                                keyDataMetaData.add(oneField);
2898:                                keyData.add(oneStringValue);
2899:                            } else {
2900:                                //We don't mess with auto-inc fields, virtual fields, or
2901:                                //binary fields.
2902:                                if (oneField.isVirtual()
2903:                                        || oneField.isBinaryObjectType()
2904:                                        || oneField.isAutoIncremented()) {
2905:                                    continue;
2906:                                }
2907:
2908:                                //						fieldDataMetaData.add(oneField);
2909:                                //						fieldData.add(oneStringValue);
2910:                            }
2911:                        }
2912:                        //
2913:                        //Ok, order of prepared statement is: data fields first, then
2914:                        //key fields  so we concatenate to make things easier to cope
2915:                        //with logic-wise
2916:                        //
2917:                        fieldData.addAll(keyData);
2918:                        fieldDataMetaData.addAll(keyDataMetaData);
2919:
2920:                        int size = fieldData.size();
2921:                        //				try {
2922:                        //					prepStatement.clearParameters();
2923:                        //				} catch (NullPointerException ex) {
2924:                        //					//
2925:                        //					//Workaround for known Oracle bug. Clear parameters
2926:                        //					//throws NPE's
2927:                        //					//
2928:                        //					if (log.isDebugEnabled()) {
2929:                        //						log.debug("NPE.  Oracle Driver?", ex);
2930:                        //					}
2931:                        //				}
2932:                        TypeMapper typeMapper = TypeMapper
2933:                                .getInstance(localConnection.getDataContext());
2934:                        for (int j = 0; j < size; j++) {
2935:                            String stringValue = (String) fieldData.get(j);
2936:
2937:                            DBField singleFieldMeta = (DBField) fieldDataMetaData
2938:                                    .get(j);
2939:
2940:                            int typeCode = typeMapper
2941:                                    .getJavaSQLType(singleFieldMeta
2942:                                            .getTypeString());
2943:                            if ("null".equals(stringValue)) {
2944:                                prepStatement.setNull(j + 1, typeCode);
2945:                            } else if (singleFieldMeta.isNumericType()) {
2946:                                if (singleFieldMeta.getTypeString()
2947:                                        .equalsIgnoreCase("integer")
2948:                                        || singleFieldMeta.getTypeString()
2949:                                                .equalsIgnoreCase("numeric")
2950:                                        || singleFieldMeta.getTypeString()
2951:                                                .equalsIgnoreCase("tinyint")
2952:                                        || singleFieldMeta.getTypeString()
2953:                                                .equalsIgnoreCase("smallint")) {
2954:                                    prepStatement.setInt(j + 1, Integer
2955:                                            .parseInt(stringValue));
2956:                                } else if (singleFieldMeta.getTypeString()
2957:                                        .equalsIgnoreCase("float")
2958:                                        || singleFieldMeta.getTypeString()
2959:                                                .equalsIgnoreCase("real")) {
2960:                                    prepStatement.setFloat(j + 1, Float
2961:                                            .parseFloat(stringValue));
2962:                                } else if (singleFieldMeta.getTypeString()
2963:                                        .equalsIgnoreCase("bigint")
2964:                                        || singleFieldMeta.getTypeString()
2965:                                                .equalsIgnoreCase("decimal")) {
2966:                                    prepStatement.setLong(j + 1, Long
2967:                                            .parseLong(stringValue));
2968:                                } else if (singleFieldMeta.getTypeString()
2969:                                        .equalsIgnoreCase("double")) {
2970:                                    prepStatement.setDouble(j + 1, Double
2971:                                            .parseDouble(stringValue));
2972:                                }
2973:                            } else if (singleFieldMeta.isDateType()) {
2974:                                if (singleFieldMeta.isDateOnlyType()) {
2975:                                    Date dtOnly = java.sql.Date
2976:                                            .valueOf(stringValue);
2977:                                    prepStatement.setDate(j + 1, dtOnly);
2978:                                }
2979:                                if (singleFieldMeta.isDateTimeType()) {
2980:                                    Timestamp dts = Timestamp
2981:                                            .valueOf(stringValue);
2982:                                    prepStatement.setTimestamp(j + 1, dts);
2983:                                }
2984:                            } else if (singleFieldMeta.isFloatingPointType()) {
2985:                                prepStatement.setFloat(j + 1, Float
2986:                                        .parseFloat(stringValue));
2987:                            } else {
2988:                                if (singleFieldMeta.getTypeString()
2989:                                        .equalsIgnoreCase("text")) {
2990:                                    if (stringValue.indexOf("\n") > 0) {
2991:                                        stringValue = StringUtil.replace(
2992:                                                stringValue, "\n", "");
2993:                                    }
2994:                                    if (stringValue.indexOf("\r") > 0) {
2995:                                        stringValue = StringUtil.replace(
2996:                                                stringValue, "\r", "");
2997:                                    }
2998:                                }
2999:                                prepStatement.setString(j + 1, stringValue);
3000:
3001:                            }
3002:                        }
3003:
3004:                        //Ok, we're set, now it's time to add the batch
3005:                        prepStatement.addBatch();
3006:                        if (oneObj.isCached()) {
3007:                            oneObj.removeFromCache(oneObj);
3008:                        }
3009:                        if (log.isDebugEnabled()) {
3010:                            valuesCommand.append(") ");
3011:                            log.debug("Batch Delete '" + theStatementString
3012:                                    + "  " + valuesCommand + "   request in ("
3013:                                    + localConnection.getDescription()
3014:                                    + ", db/context '"
3015:                                    + localConnection.getDataContext() + "')");
3016:                            valuesCommand.clear();
3017:                        }
3018:                        fieldData.clear();
3019:                        fieldDataMetaData.clear();
3020:                        keyData.clear();
3021:                        keyDataMetaData.clear();
3022:                    }
3023:
3024:                    prepStatement.executeBatch();
3025:                    localConnection.clearPreparedStatement();
3026:                    if (!localConnection.getImmortal()) {
3027:                        localConnection.commit();
3028:                    }
3029:                    valuesCommand.release();
3030:                } catch (NullPointerException npe) {
3031:                    log.error("NPE Error performing batch delete", npe);
3032:                    throw npe;
3033:                } catch (NumberFormatException nfe) {
3034:                    log
3035:                            .error(
3036:                                    "NumberFormatException Error performing batch delete",
3037:                                    nfe);
3038:                    throw nfe;
3039:                } catch (java.lang.ArrayIndexOutOfBoundsException ex) {
3040:                    log
3041:                            .error(
3042:                                    "ArrayIndexOutOfBoundsException performing batch delete",
3043:                                    ex);
3044:                    throw ex;
3045:                } catch (ClassCastException cce) {
3046:                    log.error("Class Cast Exception performing batch delete",
3047:                            cce);
3048:                    throw cce;
3049:                } catch (SQLException ex) {
3050:                    try {
3051:                        if (!localConnection.getImmortal()) {
3052:                            localConnection.rollback();
3053:                        }
3054:                    } catch (DBException ex1) {
3055:                        log.error(
3056:                                "Error rolling back delete batch transaction",
3057:                                ex1);
3058:                    }
3059:                    ex.printStackTrace();
3060:                    String msg = myName
3061:                            + "deleteBatch(DataObject, deleteWithSetFieldsOnly) SQLException.  ";
3062:                    log.error(msg, ex);
3063:                    throw new DataException(msg, ex);
3064:                } catch (DBException ex) {
3065:                    try {
3066:                        if (!localConnection.getImmortal()) {
3067:                            localConnection.rollback();
3068:                        }
3069:                    } catch (DBException ex1) {
3070:                        log.error(
3071:                                "Error rolling back delete batch transaction",
3072:                                ex1);
3073:                    }
3074:                    String msg = myName
3075:                            + "deleteBatch(DataObject, deleteWithSetFieldsOnly) error";
3076:                    log.error(msg, ex);
3077:                    throw new DataException(msg, ex);
3078:                } catch (Throwable t) {
3079:                    log.error("Caught Throwable performing batch delete", t);
3080:                    throw new DataException(t);
3081:                } finally {
3082:                    if (prepStatement != null) {
3083:                        try {
3084:                            prepStatement.close();
3085:                        } catch (SQLException ex) {
3086:                            log
3087:                                    .error(
3088:                                            "Error closing prepared statement for batch delete",
3089:                                            ex);
3090:                        }
3091:                    }
3092:                    if (localConnection != null) {
3093:                        localConnection.clearPreparedStatement();
3094:                    }
3095:
3096:                    if (myPool != null) {
3097:                        if (localConnection != null) {
3098:                            //Auto-commit is automatically turned back on by
3099:                            //release
3100:                            if (!localConnection.getImmortal()) {
3101:                                myPool.release(localConnection);
3102:                            }
3103:                        }
3104:                    }
3105:                }
3106:
3107:            }
3108:
3109:            /**
3110:             * Deletes an entire batch of <code>DataObject</code>s
3111:             *
3112:             * @param valueObjectList A list of <code>DataObject</code>s to delete to the underlying
3113:             *                        data source
3114:             * @throws DataException upon error deleting the data source
3115:             */
3116:            public void deleteBatch(List valueObjectList) throws DataException {
3117:                if (valueObjectList == null) {
3118:                    throw new IllegalArgumentException(myName
3119:                            + "deleteBatch(List):  valueObjectArray was null");
3120:                }
3121:                deleteBatch(valueObjectList, false);
3122:
3123:            }
3124:
3125:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.