Source Code Cross Referenced for CachedRowSetDataProvider.java in  » IDE-Netbeans » visualweb.api.designer » com » sun » data » provider » impl » 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 » IDE Netbeans » visualweb.api.designer » com.sun.data.provider.impl 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
0003:         *
0004:         * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
0005:         *
0006:         * The contents of this file are subject to the terms of either the GNU
0007:         * General Public License Version 2 only ("GPL") or the Common
0008:         * Development and Distribution License("CDDL") (collectively, the
0009:         * "License"). You may not use this file except in compliance with the
0010:         * License. You can obtain a copy of the License at
0011:         * http://www.netbeans.org/cddl-gplv2.html
0012:         * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
0013:         * specific language governing permissions and limitations under the
0014:         * License.  When distributing the software, include this License Header
0015:         * Notice in each file and include the License file at
0016:         * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
0017:         * particular file as subject to the "Classpath" exception as provided
0018:         * by Sun in the GPL Version 2 section of the License file that
0019:         * accompanied this code. If applicable, add the following below the
0020:         * License Header, with the fields enclosed by brackets [] replaced by
0021:         * your own identifying information:
0022:         * "Portions Copyrighted [year] [name of copyright owner]"
0023:         *
0024:         * Contributor(s):
0025:         *
0026:         * The Original Software is NetBeans. The Initial Developer of the Original
0027:         * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
0028:         * Microsystems, Inc. All Rights Reserved.
0029:         *
0030:         * If you wish your version of this file to be governed by only the CDDL
0031:         * or only the GPL Version 2, indicate your decision by adding
0032:         * "[Contributor] elects to include this software in this distribution
0033:         * under the [CDDL or GPL Version 2] license." If you do not indicate a
0034:         * single choice of license, a recipient has the option to distribute
0035:         * your version of this file under either the CDDL, the GPL Version 2 or
0036:         * to extend the choice of license to its licensees as provided above.
0037:         * However, if you add GPL Version 2 code and therefore, elected the GPL
0038:         * Version 2 license, then the option applies only if the new code is
0039:         * made subject to such option by the copyright holder.
0040:         */
0041:
0042:        package com.sun.data.provider.impl;
0043:
0044:        import java.beans.Beans;
0045:        import java.beans.PropertyChangeListener;
0046:        import java.beans.PropertyChangeEvent;
0047:        import java.io.Serializable;
0048:        import java.lang.reflect.Method;
0049:        import java.math.BigDecimal;
0050:        import java.math.BigInteger;
0051:        import java.sql.Date;
0052:        import java.sql.ResultSet;
0053:        import java.sql.ResultSetMetaData;
0054:        import java.sql.SQLException;
0055:        import java.sql.Time;
0056:        import java.sql.Timestamp;
0057:        import java.sql.Types;
0058:        import java.text.MessageFormat;
0059:        import java.util.ArrayList;
0060:        import java.util.Iterator;
0061:        import java.util.List;
0062:        import java.util.Locale;
0063:        import java.util.Map;
0064:        import java.util.ResourceBundle;
0065:        import java.util.TreeMap;
0066:        import java.net.MalformedURLException;
0067:        import java.net.URL;
0068:        import java.net.URLClassLoader;
0069:        import java.io.File;
0070:        import java.io.FileFilter;
0071:        import javax.sql.RowSet;
0072:        import javax.sql.RowSetEvent;
0073:        import javax.sql.RowSetListener;
0074:        import javax.sql.rowset.CachedRowSet;
0075:        import javax.sql.rowset.spi.SyncResolver;
0076:        import javax.sql.rowset.spi.SyncProviderException;
0077:        import com.sun.data.provider.DataProviderException;
0078:        import com.sun.data.provider.FieldKey;
0079:        import com.sun.data.provider.RowKey;
0080:        import com.sun.data.provider.RefreshableDataProvider;
0081:        import com.sun.data.provider.RefreshableDataListener;
0082:        import com.sun.data.provider.TableCursorVetoException;
0083:        import com.sun.data.provider.TableDataProvider;
0084:        import com.sun.data.provider.TransactionalDataListener;
0085:        import com.sun.data.provider.TransactionalDataProvider;
0086:        import com.sun.sql.rowset.CachedRowSetX;
0087:        import com.sun.sql.rowset.SyncResolverX;
0088:        import java.util.logging.Level;
0089:        import java.util.logging.Logger;
0090:
0091:        /**
0092:         * <p>{@link TableDataProvider} implementation that wraps a <code>CachedRowSet</code>.
0093:         * </p>
0094:         *
0095:         * <p>Note: valueChanged events will only fire for column changes made via the
0096:         * CachedRowSetDataProvider</p>
0097:         *
0098:         * <p>Note: The lifetime of the <code>RowKey</code>s handed out
0099:         * <code>CachedRowSetDataProvider</code> is until the underlying <code>CachedRowSet</code>
0100:         * is closed or reexecuted.</p>
0101:         */
0102:        public class CachedRowSetDataProvider extends AbstractTableDataProvider
0103:                implements  TableDataProvider, TransactionalDataProvider,
0104:                RefreshableDataProvider {
0105:
0106:            private static Logger LOGGER = Logger
0107:                    .getLogger(CachedRowSetDataProvider.class.getName());
0108:
0109:            // ----------------------------------------------------------- Constructors
0110:
0111:            /**
0112:             * <p>Construct an unconfigured {@link CachedRowSetDataProvider}.</p>
0113:             */
0114:            public CachedRowSetDataProvider() {
0115:            }
0116:
0117:            /**
0118:             * <p>Construct a {@link CachedRowSetDataProvider} that wraps the
0119:             * specified <code>CachedRowSet</code>.</p>
0120:             *
0121:             * @param cachedRowSet The <code>CachedRowSet</code> to be wrapped
0122:             */
0123:            public CachedRowSetDataProvider(CachedRowSet cachedRowSet) {
0124:                setCachedRowSet(cachedRowSet);
0125:            }
0126:
0127:            // ------------------------------------------------------- Static Variables
0128:
0129:            /**
0130:             * <p>Localized resources for this implementation.</p>
0131:             */
0132:            private static ResourceBundle bundle = ResourceBundle.getBundle(
0133:                    "com.sun.data.provider.impl.Bundle", //NOI18N
0134:                    Locale.getDefault(), CachedRowSetDataProvider.class
0135:                            .getClassLoader());
0136:
0137:            // ----------------------------------------------------- Instance Variables
0138:
0139:            /**
0140:             * <p>The array of {@link FieldKey}s that correspond to the columns
0141:             * represented in the <code>ResultSetMetaData</code> for this
0142:             * request.</p>
0143:             */
0144:            private FieldKey fieldKeys[] = null;
0145:
0146:            /**
0147:             * <p>Map of the {@link FieldKey}s that correspond to the columns
0148:             * represented in the <code>ResultSetMetaData</code> for this
0149:             * request, keyed (case-insensitive) by column name.</p>
0150:             */
0151:            private Map fieldKeysMap = null;
0152:
0153:            /**
0154:             * <p>The <code>ResultSetMetaData</code> associated with the
0155:             * <code>CachedRowSet</code> that we are wrapping.</p>
0156:             */
0157:            private transient ResultSetMetaData metaData = null;
0158:
0159:            /**
0160:             * <p>The <code>CachedRowSet</code> that we are wrapping.</p>
0161:             */
0162:            private CachedRowSet cachedRowSet = null;
0163:
0164:            /**
0165:             * <p>indicator if we are on the inserted row.
0166:             * Note: in the semantics of dataprovider, this
0167:             * would be called onAppendRow.
0168:             * FIXME: It seems like there should be a CachedRowSet
0169:             * method to detect this, but I don't see it.</p>
0170:             */
0171:            private boolean onInsertRow = false;
0172:
0173:            /**
0174:             * Set to true if the rowset has been executed
0175:             */
0176:            private boolean executed = false;
0177:
0178:            /**
0179:             * Set to true when rowset command had changed
0180:             */
0181:            private boolean refreshMetaDataFile = false;
0182:
0183:            /**
0184:             * Store filename for deletion when rowset command changes
0185:             */
0186:            private String metaDataFilename;
0187:
0188:            /**
0189:             * <p>{@link PropertyChangeListener} registered with the {@link CachedRowSetX}.</p>
0190:             */
0191:            private RowSetPropertyChangeListener propertyChangeListener = null;
0192:
0193:            /**
0194:             * <p>{@link PropertyChangeListener} registered with the {@link CachedRowSetX}.</p>
0195:             */
0196:            private RowSetListener rowSetListener = null;
0197:
0198:            // ------------------------------------------------------------ Properties
0199:
0200:            /**
0201:             * <p>Return the <code>CachedRowSet</code> that we are wrapping.</p>
0202:             */
0203:            public CachedRowSet getCachedRowSet() {
0204:                return cachedRowSet;
0205:            }
0206:
0207:            /**
0208:             * <p>Set the <code>CachedRowSet</code> that we are wrapping.  In addition,
0209:             * ensure that the <code>CachedRowSet</code> has been executed so that
0210:             * subseuqent calls accessing it will work.</p>
0211:             *
0212:             * @param cachedRowSet The new <code>CachedRowSet</code>
0213:             */
0214:            public void setCachedRowSet(CachedRowSet cachedRowSet) {
0215:
0216:                // Initialize our internal state information
0217:                if (this .cachedRowSet != null
0218:                        && this .cachedRowSet instanceof  CachedRowSetX
0219:                        && this .propertyChangeListener != null) {
0220:                    ((CachedRowSetX) this .cachedRowSet)
0221:                            .removePropertyChangeListener(propertyChangeListener);
0222:                    propertyChangeListener = null;
0223:                }
0224:                if (this .cachedRowSet != null && this .rowSetListener != null) {
0225:                    this .cachedRowSet.removeRowSetListener(rowSetListener);
0226:                    rowSetListener = null;
0227:                }
0228:                try {
0229:                    cursorFirst();
0230:                } catch (Exception e) {
0231:                }
0232:                this .cachedRowSet = cachedRowSet;
0233:                metaData = null;
0234:                fieldKeys = null;
0235:                fieldKeysMap = null;
0236:                if (cachedRowSet != null
0237:                        && cachedRowSet instanceof  CachedRowSetX) {
0238:                    propertyChangeListener = new RowSetPropertyChangeListener();
0239:                    ((CachedRowSetX) cachedRowSet)
0240:                            .addPropertyChangeListener(propertyChangeListener);
0241:
0242:                    if (!Beans.isDesignTime()) {
0243:                        try {
0244:                            executed = ((CachedRowSetX) cachedRowSet)
0245:                                    .isExecuted();
0246:                        } catch (SQLException e) {
0247:                            LOGGER.log(Level.WARNING, null, e);
0248:                            executed = false;
0249:                        }
0250:                    } else {
0251:                        // Assume the row set has not yet been executed yet.  The worse
0252:                        // that could happen is the row set was executed before it was
0253:                        // passed in to the data provider, and we end up executing it
0254:                        // one more time.  Note that this particular branch of logic
0255:                        // is unlikely because almost always the rowset is a CachedRowSetX
0256:                        executed = false;
0257:                    }
0258:                }
0259:                if (cachedRowSet != null) {
0260:                    rowSetListener = new CachedRowSetListener();
0261:                    cachedRowSet.addRowSetListener(rowSetListener);
0262:                }
0263:                fireProviderChanged();
0264:            }
0265:
0266:            // --------------------------------------- CachedRowSetDataProvider Methods
0267:
0268:            /**
0269:             * free resources used by this instance
0270:             *
0271:             * Close is guaranteed  not to throw an exception.
0272:             */
0273:            public void close() {
0274:                if (!Beans.isDesignTime()) {
0275:                    try {
0276:                        setCachedRowSet(null);
0277:                    } catch (Exception e) {
0278:                        // attempted to cleanup, contract is close() will silently fail
0279:                    }
0280:                }
0281:            }
0282:
0283:            // ---------------------------------------------------------- RowKey Methods
0284:
0285:            /** {@inheritDoc} */
0286:            public RowKey[] getRowKeys(int count, RowKey afterRow)
0287:                    throws DataProviderException {
0288:
0289:                /*
0290:                 * Only hand out RowKeys for rows that have not been deleted
0291:                 */
0292:                if (getCachedRowSet() == null) {
0293:                    return new CachedRowSetRowKey[0];
0294:                }
0295:                int cursorIndexSave = getCursorIndex();
0296:                List keys = new ArrayList();
0297:                try {
0298:                    int startIndex = 0;
0299:                    if (afterRow instanceof  CachedRowSetRowKey) {
0300:                        startIndex = ((CachedRowSetRowKey) afterRow).getIndex() + 1;
0301:                    }
0302:                    while (absolute(startIndex + 1) && keys.size() < count) {
0303:                        try {
0304:                            if (!(isUpdatable() && getCachedRowSet()
0305:                                    .rowDeleted())) {
0306:                                keys.add(new CachedRowSetRowKey(startIndex));
0307:                            }
0308:                        } catch (SQLException e) {
0309:                            // if sqlexception, we can't hand out a rowkey for this row
0310:                        }
0311:                        startIndex++;
0312:                    }
0313:                    return (RowKey[]) keys.toArray(new CachedRowSetRowKey[0]);
0314:                } finally {
0315:                    try {
0316:                        setCursorIndex(cursorIndexSave);
0317:                    } catch (IllegalArgumentException e) {
0318:                        // This can happen if the row at the cursorIndex was deleted
0319:                    }
0320:                }
0321:            }
0322:
0323:            /** {@inheritDoc} */
0324:            public RowKey[] getAllRows() throws DataProviderException {
0325:                return getRowKeys(Integer.MAX_VALUE, null);
0326:            }
0327:
0328:            public RowKey getRowKey(String rowId) throws DataProviderException {
0329:                return CachedRowSetRowKey.create(rowId);
0330:            }
0331:
0332:            // ---------------------------------------------------------- Cursor Methods
0333:
0334:            /**
0335:             * storage for the current cursor row
0336:             */
0337:            protected RowKey cursorRow = new CachedRowSetRowKey(0);
0338:
0339:            protected int getCursorIndex() {
0340:                if (cursorRow instanceof  CachedRowSetRowKey) {
0341:                    return ((CachedRowSetRowKey) cursorRow).getIndex();
0342:                }
0343:                return -1;
0344:            }
0345:
0346:            private boolean absolute(int index) {
0347:                if (getCachedRowSet() == null) {
0348:                    return false;
0349:                }
0350:                if (Beans.isDesignTime()) {
0351:                    return index >= 1 && index <= 3;
0352:                }
0353:                try {
0354:                    checkExecute();
0355:                    boolean saveShowDeleted = getCachedRowSet()
0356:                            .getShowDeleted();
0357:                    try {
0358:                        getCachedRowSet().setShowDeleted(true);
0359:                        return getCachedRowSet().absolute(index);
0360:                    } catch (SQLException e) {
0361:                        return false;
0362:                    } finally {
0363:                        getCachedRowSet().setShowDeleted(saveShowDeleted);
0364:                    }
0365:                } catch (SQLException e) {
0366:                    return false;
0367:                }
0368:            }
0369:
0370:            protected boolean setCursorIndex(int index) {
0371:                try {
0372:                    setCursorRow(new CachedRowSetRowKey(index));
0373:                    return true;
0374:                } catch (TableCursorVetoException tcvx) {
0375:                    return false;
0376:                }
0377:            }
0378:
0379:            /** {@inheritDoc} */
0380:            public RowKey getCursorRow() throws DataProviderException {
0381:                return cursorRow;
0382:            }
0383:
0384:            /** {@inheritDoc} */
0385:            public void setCursorRow(RowKey row)
0386:                    throws TableCursorVetoException {
0387:
0388:                if (Beans.isDesignTime()) {
0389:                    if (!isRowAvailable(row)) {
0390:                        throw new IllegalArgumentException(bundle
0391:                                .getString("ROW_NOT_AVAILABLE")); //NOI18N
0392:                    }
0393:                    RowKey oldRow = this .cursorRow;
0394:                    fireCursorChanging(oldRow, row);
0395:                    this .cursorRow = row;
0396:                    fireCursorChanged(oldRow, cursorRow);
0397:                    return;
0398:                }
0399:
0400:                if (getCachedRowSet() != null
0401:                        && row instanceof  CachedRowSetRowKey) {
0402:                    try {
0403:                        checkExecute();
0404:                        if (absolute(((CachedRowSetRowKey) row).getIndex() + 1)) {
0405:                            if (isUpdatable() && getCachedRowSet().rowDeleted()) {
0406:                                throw new IllegalArgumentException("" + row); //NOI18N
0407:                            }
0408:                            RowKey oldRow = this .cursorRow;
0409:                            fireCursorChanging(oldRow, row);
0410:                            this .cursorRow = row;
0411:                            fireCursorChanged(oldRow, cursorRow);
0412:                            return;
0413:                        } else {
0414:                            throw new IllegalArgumentException("" + row); //NOI18N
0415:                        }
0416:                    } catch (SQLException e) {
0417:                        throw new RuntimeException(e);
0418:                    }
0419:                }
0420:
0421:            }
0422:
0423:            /** {@inheritDoc} */
0424:            public boolean cursorFirst() throws DataProviderException {
0425:
0426:                RowKey[] keys = getRowKeys(1, null);
0427:                if (keys.length == 0) {
0428:                    return false;
0429:                }
0430:                try {
0431:                    setCursorRow((CachedRowSetRowKey) keys[0]);
0432:                    return true;
0433:                } catch (IllegalArgumentException e) {
0434:                    return false;
0435:                }
0436:            }
0437:
0438:            /** {@inheritDoc} */
0439:            public boolean cursorNext() throws DataProviderException {
0440:                RowKey[] keys = getRowKeys(1, getCursorRow());
0441:                if (keys.length == 0) {
0442:                    return false;
0443:                }
0444:                try {
0445:                    setCursorRow((CachedRowSetRowKey) keys[0]);
0446:                    return true;
0447:                } catch (IllegalArgumentException e) {
0448:                    return false;
0449:                }
0450:            }
0451:
0452:            /** {@inheritDoc} */
0453:            public boolean cursorPrevious() throws DataProviderException {
0454:                // attempt to set cursor index until sucessfull or < 0
0455:                int idx = getCursorIndex() - 1;
0456:                while (idx >= 0) {
0457:                    try {
0458:                        setCursorIndex(idx);
0459:                        return true;
0460:                    } catch (IllegalArgumentException e) {
0461:                    }
0462:                    idx--;
0463:                }
0464:                return false;
0465:            }
0466:
0467:            /** {@inheritDoc} */
0468:            public boolean cursorLast() throws DataProviderException {
0469:                if (Beans.isDesignTime()) {
0470:                    setCursorIndex(2);
0471:                    return true;
0472:                }
0473:                boolean saveShowDeleted = false;
0474:                try {
0475:                    saveShowDeleted = getCachedRowSet().getShowDeleted();
0476:                    getCachedRowSet().setShowDeleted(true);
0477:                    try {
0478:                        getCachedRowSet().last();
0479:                        do {
0480:                            int key = getCachedRowSet().getRow() - 1;
0481:                            if (!(isUpdatable() && getCachedRowSet()
0482:                                    .rowDeleted())) {
0483:                                setCursorRow(new CachedRowSetRowKey(key));
0484:                                return true;
0485:                            }
0486:                        } while (getCachedRowSet().previous());
0487:                        return false;
0488:                    } catch (SQLException e2) {
0489:                        return false;
0490:                    }
0491:                } catch (SQLException e) {
0492:                    return false;
0493:                } finally {
0494:                    try {
0495:                        getCachedRowSet().setShowDeleted(saveShowDeleted);
0496:                    } catch (SQLException e) {
0497:                    }
0498:                }
0499:            }
0500:
0501:            // --------------------------------------------------- DataProvider Methods
0502:
0503:            /** {@inheritDoc} */
0504:            public FieldKey getFieldKey(String fieldId)
0505:                    throws DataProviderException {
0506:
0507:                /*
0508:                 * Bug 6275441: mssqlserver is handing back different metadata based on whether
0509:                 * the query has been executed or not.
0510:                 *
0511:                 */
0512:                try {
0513:                    return getFieldKeyInternal(fieldId);
0514:                } catch (IllegalArgumentException e) {
0515:                    /*
0516:                     * let's see if we hit bug #6275441
0517:                     */
0518:                    if (fieldId.indexOf('.') == -1) {
0519:                        // fieldId is not prepended with a table, so we may have hit 6275441
0520:                        if (fieldKeysMap != null) {
0521:                            for (Iterator i = fieldKeysMap.values().iterator(); i
0522:                                    .hasNext();) {
0523:                                FieldKey fieldKey = (FieldKey) i.next();
0524:                                String val = fieldKey.getFieldId();
0525:                                int loc = val.lastIndexOf('.');
0526:                                if (loc >= 0 && loc + 1 < val.length()) {
0527:                                    val = val.substring(loc + 1);
0528:                                }
0529:                                if (val.equalsIgnoreCase(fieldId)) {
0530:                                    return fieldKey;
0531:                                }
0532:                            }
0533:                        }
0534:                    }
0535:                    throw e;
0536:                }
0537:            }
0538:
0539:            private FieldKey getFieldKeyInternal(String fieldId)
0540:                    throws DataProviderException {
0541:                if (fieldKeysMap == null) {
0542:                    if (fieldKeys == null) {
0543:                        getFieldKeys();
0544:                        if (fieldKeys == null) {
0545:                            return null;
0546:                        }
0547:                    }
0548:                    fieldKeysMap = new TreeMap(String.CASE_INSENSITIVE_ORDER);
0549:                    for (int i = 0; i < fieldKeys.length; i++) {
0550:                        fieldKeysMap.put(fieldKeys[i].getFieldId(),
0551:                                fieldKeys[i]);
0552:                    }
0553:                }
0554:                FieldKey fieldKey = (FieldKey) fieldKeysMap.get(fieldId);
0555:                if (fieldKey != null) {
0556:                    return fieldKey;
0557:                } else {
0558:                    throw new IllegalArgumentException(fieldId);
0559:                }
0560:            }
0561:
0562:            /** {@inheritDoc} */
0563:            public FieldKey[] getFieldKeys() throws DataProviderException {
0564:                if (fieldKeys == null) {
0565:                    ResultSetMetaData metaData = getMetaData();
0566:                    if (metaData == null) {
0567:                        return FieldKey.EMPTY_ARRAY;
0568:                    }
0569:                    try {
0570:                        fieldKeys = new FieldKey[metaData.getColumnCount()];
0571:                        for (int i = 0; i < fieldKeys.length; i++) {
0572:                            String tableName = "";
0573:                            if (metaData.getTableName(i + 1) != null
0574:                                    && !metaData.getTableName(i + 1).equals("")) {
0575:                                tableName = metaData.getTableName(i + 1) + ".";
0576:                            }
0577:                            fieldKeys[i] = new FieldKey(tableName
0578:                                    + metaData.getColumnName(i + 1));
0579:                        }
0580:                    } catch (SQLException e) {
0581:                        fieldKeys = null;
0582:                        throw new RuntimeException(e);
0583:                    }
0584:                }
0585:                if (fieldKeys != null) {
0586:                    return fieldKeys;
0587:                }
0588:                return FieldKey.EMPTY_ARRAY;
0589:            }
0590:
0591:            /** {@inheritDoc} */
0592:            public Class getType(FieldKey fieldKey)
0593:                    throws DataProviderException {
0594:
0595:                ResultSetMetaData metaData = getMetaData();
0596:                if (metaData != null) {
0597:                    try {
0598:                        int column = column(fieldKey);
0599:                        if (column > 0) {
0600:                            String className = metaData
0601:                                    .getColumnClassName(column);
0602:                            // System.out.println("column: "+column + "   className: "+className + "   type: "+metaData.getColumnType(column));
0603:
0604:                            if (Beans.isDesignTime()
0605:                                    && (className
0606:                                            .equals("oracle.sql.TIMESTAMP"))) {
0607:                                // Special processing for non-standard Oracle classes @ design time
0608:                                // return Class.forName(className,
0609:                                //                      true,
0610:                                //                      getDriverClassLoader(getClass().getClassLoader()));
0611:                                // Return the appropriate Java class instead
0612:                                return java.sql.Timestamp.class;
0613:                            } else if (Beans.isDesignTime()
0614:                                    && (className.equals("oracle.sql.CLOB"))) {
0615:                                // Convert Oracle class into standard Java class. Note that no oracle.sql.CLOB extends java.sql.Clob, so only the
0616:                                // type needs to be converted, not the value.
0617:                                return java.sql.Clob.class;
0618:                            } else {
0619:                                return Class.forName(className);
0620:                            }
0621:                        } else {
0622:                            throw new IllegalArgumentException(fieldKey
0623:                                    .getFieldId());
0624:                        }
0625:                    } catch (ClassNotFoundException e) {
0626:                        throw new RuntimeException(e);
0627:                    } catch (SQLException e) {
0628:                        throw new RuntimeException(e);
0629:                    }
0630:                }
0631:                return null;
0632:
0633:            }
0634:
0635:            // ---------------------------------------------- TableDataProvider Methods
0636:
0637:            /** {@inheritDoc} */
0638:            public RowKey appendRow() throws DataProviderException {
0639:                if (!canAppendRow()) {
0640:                    return null; // spec silent on what to do here
0641:                }
0642:                boolean saveShowDeleted = false;
0643:                try {
0644:                    saveShowDeleted = getCachedRowSet().getShowDeleted();
0645:                    getCachedRowSet().setShowDeleted(true);
0646:                    try {
0647:                        getCachedRowSet().last();
0648:                        int newRow = getCachedRowSet().getRow(); // will be correct for new row (zero-based)
0649:                        getCachedRowSet().moveToInsertRow();
0650:                        ResultSetMetaData rsmd = getMetaData();
0651:                        for (int i = 1; i <= rsmd.getColumnCount(); i++) {
0652:                            if (rsmd.isNullable(i) == ResultSetMetaData.columnNoNulls
0653:                                    && rsmd.isWritable(i) == true) {
0654:                                getCachedRowSet().updateObject(
0655:                                        i,
0656:                                        manufacturePlaceholder(rsmd
0657:                                                .getColumnClassName(i), false,
0658:                                                rsmd.getColumnType(i)));
0659:                            }
0660:                        }
0661:                        getCachedRowSet().insertRow();
0662:                        return new CachedRowSetRowKey(newRow); // zero based
0663:                    } catch (SQLException e2) {
0664:                        throw new RuntimeException(e2);
0665:                    }
0666:                } catch (SQLException e) {
0667:                    throw new RuntimeException(e);
0668:                } finally {
0669:                    try {
0670:                        getCachedRowSet().setShowDeleted(saveShowDeleted);
0671:                    } catch (SQLException e) {
0672:                    }
0673:                }
0674:            }
0675:
0676:            /** {@inheritDoc} */
0677:            public boolean canInsertRow(RowKey beforeRow)
0678:                    throws DataProviderException {
0679:                return false;
0680:
0681:            }
0682:
0683:            /** {@inheritDoc} */
0684:            public boolean canAppendRow() throws DataProviderException {
0685:                try {
0686:                    return isUpdatable();
0687:                } catch (SQLException e) {
0688:                    return false;
0689:                }
0690:            }
0691:
0692:            /** {@inheritDoc} */
0693:            public boolean canRemoveRow(RowKey row)
0694:                    throws DataProviderException {
0695:                try {
0696:                    return isUpdatable() && isRowAvailable(row);
0697:                } catch (SQLException e) {
0698:                    return false;
0699:                }
0700:            }
0701:
0702:            /** {@inheritDoc} */
0703:            public int getRowCount() throws DataProviderException {
0704:                if (getCachedRowSet() == null) {
0705:                    return 0;
0706:                }
0707:                int rowCount = 0;
0708:                int cursorIndexSave = getCursorIndex();
0709:                try {
0710:                    int startIndex = 0;
0711:                    while (absolute(startIndex + 1)) {
0712:                        try {
0713:                            if (!(isUpdatable() && getCachedRowSet()
0714:                                    .rowDeleted())) {
0715:                                rowCount++;
0716:                            }
0717:                        } catch (SQLException e) {
0718:                            return -1;
0719:                        }
0720:                        startIndex++;
0721:                    }
0722:                    return rowCount;
0723:                } finally {
0724:                    try {
0725:                        setCursorIndex(cursorIndexSave);
0726:                    } catch (IllegalArgumentException e) {
0727:                        // This can happen if the row at the cursorIndex was deleted
0728:                    }
0729:                }
0730:            }
0731:
0732:            /** {@inheritDoc} */
0733:            public Object getValue(FieldKey fieldKey, RowKey row)
0734:                    throws DataProviderException {
0735:
0736:                // try {
0737:                //      System.out.println("Entering CRSDP.getValue, fieldKey: " + fieldKey + "  rowKey: " + row +
0738:                //                         "colClassName: " + getMetaData().getColumnClassName(column(fieldKey)) +
0739:                //                         "  colType: " + getMetaData().getColumnType(column(fieldKey)));
0740:                // } catch (java.sql.SQLException e) {}
0741:
0742:                if (Beans.isDesignTime()) {
0743:                    try {
0744:                        return manufacturePlaceholder(getMetaData()
0745:                                .getColumnClassName(column(fieldKey)), true,
0746:                                getMetaData().getColumnType(column(fieldKey)));
0747:                    } catch (SQLException e) {
0748:                        throw new RuntimeException(e);
0749:                    }
0750:                }
0751:
0752:                if (getCachedRowSet() != null
0753:                        && row instanceof  CachedRowSetRowKey) {
0754:                    try {
0755:                        checkExecute();
0756:                        if (absolute(((CachedRowSetRowKey) row).getIndex() + 1)) {
0757:
0758:                            Object obj = getCachedRowSet().getObject(
0759:                                    column(fieldKey));
0760:                            if (getMetaData().getColumnClassName(
0761:                                    column(fieldKey)).equals(
0762:                                    "oracle.sql.TIMESTAMP")) {
0763:                                try {
0764:                                    // If we have an Oracle TIMESTAMP object, convert to standard JDBC class
0765:                                    // Use reflection to avoid runtime dependency
0766:                                    Class c = Class
0767:                                            .forName("oracle.sql.TIMESTAMP");
0768:                                    if (obj.getClass().getName().equals(
0769:                                            "oracle.sql.TIMESTAMP")) {
0770:                                        Method m = c.getMethod("toJdbc",
0771:                                                (Class[]) null);
0772:                                        Object newObj = m.invoke(obj,
0773:                                                (Object[]) null);
0774:                                        return newObj;
0775:                                    } else {
0776:                                        return obj;
0777:                                    }
0778:                                } catch (Exception e) {
0779:                                    // ClassNotFoundException, NoSuchMethodException, IllegalAccessException
0780:                                    return obj;
0781:                                }
0782:
0783:                            } else {
0784:                                return obj;
0785:                            }
0786:                        } else {
0787:                            throw new IndexOutOfBoundsException("" + row);
0788:                        }
0789:                    } catch (SQLException e) {
0790:                        throw new RuntimeException(e);
0791:                    }
0792:                }
0793:                return null;
0794:
0795:            }
0796:
0797:            /** {@inheritDoc} */
0798:            public RowKey insertRow(RowKey beforeRow)
0799:                    throws DataProviderException {
0800:                return null; // spec is silent on what to do here
0801:
0802:            }
0803:
0804:            /** {@inheritDoc} */
0805:            public boolean isReadOnly(FieldKey fieldKey)
0806:                    throws DataProviderException {
0807:
0808:                try {
0809:                    if (!isUpdatable()) {
0810:                        return true;
0811:                    }
0812:                    ResultSetMetaData metaData = getMetaData();
0813:                    if (metaData.isReadOnly(column(fieldKey))) {
0814:                        return true;
0815:                    }
0816:                } catch (SQLException e) {
0817:                    return false;
0818:                }
0819:                return false;
0820:            }
0821:
0822:            /** {@inheritDoc} */
0823:            public boolean isRowAvailable(RowKey row)
0824:                    throws DataProviderException {
0825:                if (!(row instanceof  CachedRowSetRowKey)) {
0826:                    return false;
0827:                }
0828:                int index = ((CachedRowSetRowKey) row).getIndex();
0829:                if (Beans.isDesignTime()) {
0830:                    return (index >= 0) && (index <= 2);
0831:                }
0832:                if (getCachedRowSet() != null) {
0833:                    try {
0834:                        checkExecute();
0835:                        if (absolute(index + 1)) {
0836:                            if (isUpdatable() && getCachedRowSet().rowDeleted()) {
0837:                                return false;
0838:                            } else {
0839:                                return true;
0840:                            }
0841:                        }
0842:                    } catch (SQLException e) {
0843:                        return false;
0844:                    }
0845:                }
0846:                return false;
0847:
0848:            }
0849:
0850:            /** {@inheritDoc} */
0851:            public void removeRow(RowKey row) throws DataProviderException {
0852:                int index = ((CachedRowSetRowKey) row).getIndex();
0853:                if (getCachedRowSet() != null) {
0854:                    try {
0855:                        if (!isUpdatable()) {
0856:                            throw new IllegalArgumentException("" + row); // What should we throw?
0857:                        }
0858:                        if (absolute(index + 1)) {
0859:                            if (!getCachedRowSet().rowDeleted()) {
0860:                                getCachedRowSet().deleteRow();
0861:                            } // FIXME: else do we throw an exception if already deleted?
0862:                        } else {
0863:                            throw new IllegalArgumentException("" + row);
0864:                        }
0865:                    } catch (SQLException e) {
0866:                        throw new RuntimeException(e);
0867:                    }
0868:                } else {
0869:                    throw new IllegalStateException();
0870:                }
0871:
0872:            }
0873:
0874:            /** {@inheritDoc} */
0875:            public void setValue(FieldKey fieldKey, RowKey row, Object value)
0876:                    throws DataProviderException {
0877:
0878:                if (getCachedRowSet() != null
0879:                        && row instanceof  CachedRowSetRowKey) {
0880:                    try {
0881:                        if (!isUpdatable()) {
0882:                            throw new IllegalStateException(""
0883:                                    + fieldKey.getFieldId());
0884:                        }
0885:                        if (absolute(((CachedRowSetRowKey) row).getIndex() + 1)) {
0886:                            if (getCachedRowSet().rowDeleted()) {
0887:                                throw new IllegalStateException(""
0888:                                        + fieldKey.getFieldId());
0889:                            }
0890:                            if (isReadOnly(fieldKey)) {
0891:                                throw new IllegalStateException(""
0892:                                        + fieldKey.getFieldId());
0893:                            }
0894:                            int column = column(fieldKey);
0895:
0896:                            //                      if (getMetaData().getColumnClassName(column(fieldKey)).equals("oracle.sql.TIMESTAMP")) {
0897:                            //                          // Extra code to create oracle.sql.TIMESTAMP objects from java.sql.Timestamp
0898:                            //                          // May not be required
0899:                            //                      }
0900:
0901:                            Object old = getCachedRowSet().getObject(column);
0902:                            boolean changed = false;
0903:                            if (old == null) {
0904:                                changed = value != null;
0905:                            } else if (value == null) {
0906:                                changed = true;
0907:                            } else {
0908:                                changed = !old.equals(value);
0909:                            }
0910:
0911:                            if (changed) {
0912:                                getCachedRowSet().updateObject(column, value);
0913:                                getCachedRowSet().updateRow();
0914:                                fireValueChanged(fieldKey, row, old, value);
0915:                                if (row != null && row.equals(getCursorRow())) {
0916:                                    fireValueChanged(fieldKey, old, value);
0917:                                }
0918:                            }
0919:                        } else {
0920:                            throw new IndexOutOfBoundsException("" + row);
0921:                        }
0922:                    } catch (SQLException e) {
0923:                        throw new RuntimeException(e);
0924:                    }
0925:                }
0926:
0927:            }
0928:
0929:            // -------------------------------------- RefreshableDataProvider Methods
0930:
0931:            /** {@inheritDoc} */
0932:            public void addRefreshableDataListener(
0933:                    RefreshableDataListener listener) {
0934:                super .addDataListener(listener);
0935:            }
0936:
0937:            /** {@inheritDoc} */
0938:            public void removeRefreshableDataListener(
0939:                    RefreshableDataListener listener) {
0940:                super .removeDataListener(listener);
0941:            }
0942:
0943:            /** {@inheritDoc} */
0944:            public RefreshableDataListener[] getRefreshableDataListeners() {
0945:                if (dpListeners == null) {
0946:                    return new RefreshableDataListener[0];
0947:                } else {
0948:                    ArrayList rdList = new ArrayList();
0949:                    for (int i = 0; i < dpListeners.length; i++) {
0950:                        if (dpListeners[i] instanceof  RefreshableDataListener) {
0951:                            rdList.add(dpListeners[i]);
0952:                        }
0953:                    }
0954:                    return (RefreshableDataListener[]) rdList
0955:                            .toArray(new RefreshableDataListener[rdList.size()]);
0956:                }
0957:            }
0958:
0959:            /** {@inheritDoc} */
0960:            public void refresh() throws DataProviderException {
0961:                if (getCachedRowSet() != null
0962:                        && getCachedRowSet() instanceof  CachedRowSet) {
0963:                    try {
0964:                        ((CachedRowSet) getCachedRowSet()).release();
0965:                        executed = false; // reset -executed- so refetch occurs
0966:                        fireRefreshed();
0967:                    } catch (SQLException e) {
0968:                        throw new RuntimeException(e);
0969:                    }
0970:                }
0971:            }
0972:
0973:            // -------------------------------------- TransactionalDataProvider Methods
0974:
0975:            /** {@inheritDoc} */
0976:            public void commitChanges() throws DataProviderException {
0977:                if (getCachedRowSet() != null) {
0978:                    try {
0979:                        checkExecute();
0980:                        try {
0981:                            getCachedRowSet().acceptChanges();
0982:                            fireChangesCommitted();
0983:                        } catch (SyncProviderException spe) {
0984:                            SyncResolver resolver = spe.getSyncResolver();
0985:                            String message = null;
0986:                            if (resolver == null) {
0987:                                message = spe.getMessage();
0988:                            } else {
0989:                                while (resolver.nextConflict()) {
0990:                                    int row = resolver.getRow();
0991:
0992:                                    //TODO: use MessageFormat for these error strings
0993:                                    String pattern = "{0} {1} {2}"; // NOI18N
0994:                                    switch (resolver.getStatus()) {
0995:                                    case SyncResolver.DELETE_ROW_CONFLICT:
0996:                                        pattern = bundle
0997:                                                .getString("DELETE_ROW_CONFLICT"); //NOI18N
0998:                                        break;
0999:                                    case SyncResolver.INSERT_ROW_CONFLICT:
1000:                                        pattern = bundle
1001:                                                .getString("INSERT_ROW_CONFLICT"); // NOI18N
1002:                                        break;
1003:                                    case SyncResolver.UPDATE_ROW_CONFLICT:
1004:                                        pattern = bundle
1005:                                                .getString("UPDATE_ROW_CONFLICT"); // NOI18N
1006:                                        break;
1007:                                    }
1008:                                    String sqlExceptionText = "";
1009:                                    if (resolver instanceof  SyncResolverX) {
1010:                                        sqlExceptionText = ((SyncResolverX) resolver)
1011:                                                .getSQLException()
1012:                                                .getLocalizedMessage();
1013:                                    }
1014:                                    String[] args = new String[] {
1015:                                            spe.getMessage(),
1016:                                            Integer.toString(row - 1),
1017:                                            sqlExceptionText };
1018:                                    message = MessageFormat.format(pattern,
1019:                                            args);
1020:                                    absolute(row);
1021:                                    int colCount = getCachedRowSet()
1022:                                            .getMetaData().getColumnCount();
1023:                                    for (int i = 1; i <= colCount; i++) {
1024:                                        try {
1025:                                            if (resolver.getConflictValue(i) != null) {
1026:                                                message += ": "
1027:                                                        + resolver
1028:                                                                .getConflictValue( //NOI18N
1029:                                                                getCachedRowSet()
1030:                                                                        .getMetaData()
1031:                                                                        .getColumnName(
1032:                                                                                i));
1033:                                            }
1034:                                        } catch (SQLException se) {
1035:                                            // should never be here.
1036:                                            message += ": <unknown>"; // NOI18N
1037:                                        }
1038:                                    }
1039:                                }
1040:                            }
1041:                            throw new RuntimeException(message, spe);
1042:                        }
1043:                    } catch (SQLException sqle) {
1044:                        throw new RuntimeException(sqle);
1045:
1046:                    }
1047:                }
1048:            }
1049:
1050:            /** {@inheritDoc} */
1051:            public void revertChanges() throws DataProviderException {
1052:                if (getCachedRowSet() != null) {
1053:                    try {
1054:                        checkExecute();
1055:                        ((CachedRowSet) getCachedRowSet()).restoreOriginal();
1056:                        fireChangesReverted();
1057:                    } catch (SQLException e) {
1058:                        throw new RuntimeException(e);
1059:                    }
1060:                }
1061:            }
1062:
1063:            /** {@inheritDoc} */
1064:            public void addTransactionalDataListener(
1065:                    TransactionalDataListener listener) {
1066:                super .addDataListener(listener);
1067:            }
1068:
1069:            /** {@inheritDoc} */
1070:            public void removeTransactionalDataListener(
1071:                    TransactionalDataListener listener) {
1072:                super .removeDataListener(listener);
1073:            }
1074:
1075:            /** {@inheritDoc} */
1076:            public TransactionalDataListener[] getTransactionalDataListeners() {
1077:                if (dpListeners == null) {
1078:                    return new TransactionalDataListener[0];
1079:                } else {
1080:                    ArrayList tdList = new ArrayList();
1081:                    for (int i = 0; i < dpListeners.length; i++) {
1082:                        if (dpListeners[i] instanceof  TransactionalDataListener) {
1083:                            tdList.add(dpListeners[i]);
1084:                        }
1085:                    }
1086:                    return (TransactionalDataListener[]) tdList
1087:                            .toArray(new TransactionalDataListener[tdList
1088:                                    .size()]);
1089:                }
1090:            }
1091:
1092:            // -------------------------------------------------------- Private Classes
1093:
1094:            /**
1095:             * <p>CachedRowSetDataProvider's private RowKey class
1096:             */
1097:            static private class CachedRowSetRowKey extends RowKey implements 
1098:                    Serializable {
1099:
1100:                /**
1101:                 * Constructs a new CachedRowSetRowKey from the passed rowId String, or returns
1102:                 * null if the passed rowId cannot be parsed into an int index.
1103:                 *
1104:                 * @param rowId The canonical row ID string to parse into an int
1105:                 * @return An CachedRowSetRowKey representing the passed rowId, or null if one
1106:                 *         could not be created.
1107:                 */
1108:                public static CachedRowSetRowKey create(String rowId) {
1109:                    try {
1110:                        return new CachedRowSetRowKey(Integer.parseInt(rowId));
1111:                    } catch (NumberFormatException nfx) {
1112:                        return null;
1113:                    }
1114:                }
1115:
1116:                /**
1117:                 * Constructs an CachedRowSetRowKey using the specified index
1118:                 *
1119:                 * @param index The desired index
1120:                 */
1121:                CachedRowSetRowKey(int index) {
1122:                    super (String.valueOf(index));
1123:                    this .index = index;
1124:                }
1125:
1126:                /**
1127:                 * Returns the index of this CachedRowSetRowKey
1128:                 *
1129:                 * @return This CachedRowSetRowKey's index value
1130:                 */
1131:                int getIndex() {
1132:                    return index;
1133:                }
1134:
1135:                /**
1136:                 * Standard equals implementation.  This method compares the CachedRowSetRowKey
1137:                 * index values for == equality.  If the passed Object is not an
1138:                 * CachedRowSetRowKey instance, the superclass (RowKey) gets a chance to evaluate
1139:                 * the Object for equality.
1140:                 *
1141:                 * @param o the Object to check equality
1142:                 * @return true if equal, false if not
1143:                 * @see Object#equals(Object)
1144:                 */
1145:                public boolean equals(Object o) {
1146:                    if (o instanceof  CachedRowSetRowKey) {
1147:                        return ((CachedRowSetRowKey) o).getIndex() == getIndex();
1148:                    }
1149:                    return super .equals(o);
1150:                }
1151:
1152:                private int index;
1153:
1154:                /**
1155:                 * <p>Return a printable version of this instance.</p>
1156:                 */
1157:                public String toString() {
1158:                    return "CachedRowSetRowKey[" + index + "]";
1159:                }
1160:            }
1161:
1162:            static private class ColumnNotSet implements  Serializable {
1163:                public String toString() {
1164:                    return null;
1165:                }
1166:            }
1167:
1168:            private class RowSetPropertyChangeListener implements 
1169:                    PropertyChangeListener, Serializable {
1170:                public void propertyChange(PropertyChangeEvent event) {
1171:                    if (event.getPropertyName().equals("command") || //NOI18N
1172:                            event.getPropertyName().equals("dataSourceName") || //NOI18N
1173:                            event.getPropertyName().equals("url") || //NOI18N
1174:                            event.getPropertyName().equals("username")) { //NOI18N
1175:                        try {
1176:                            setCursorIndex(0);
1177:                        } catch (Exception e) {
1178:                        }
1179:                        metaData = null;
1180:                        fieldKeys = null;
1181:                        fieldKeysMap = null;
1182:                        executed = false;
1183:                        refreshMetaDataFile = true;
1184:                        fireProviderChanged();
1185:                    }
1186:                }
1187:            }
1188:
1189:            private class CachedRowSetListener implements  RowSetListener,
1190:                    Serializable {
1191:                public void cursorMoved(RowSetEvent event) {
1192:                }
1193:
1194:                public void rowChanged(RowSetEvent event) {
1195:                    try {
1196:                        int row = ((RowSet) event.getSource()).getRow();
1197:                        //Don't know what column changed
1198:                        //fireValueChanged(fieldKey, new CachedRowSetRowKey(row+1), old, value);
1199:                    } catch (SQLException e) {
1200:                        //FIXME: What to do?
1201:                    }
1202:                }
1203:
1204:                public void rowSetChanged(RowSetEvent event) {
1205:                    fireProviderChanged();
1206:                }
1207:            }
1208:
1209:            // -------------------------------------------------------- Private Methods
1210:
1211:            private void fireRefreshed() {
1212:                RefreshableDataListener[] rdList = getRefreshableDataListeners();
1213:                for (int i = 0; i < rdList.length; i++) {
1214:                    rdList[i].refreshed(this );
1215:                }
1216:            }
1217:
1218:            /**
1219:             * <p>Manufacture an empty (or as close to empty as we can get) instance
1220:             * of class className (to be used a placeholder when inserting a row)</p>
1221:             */
1222:            static private Object manufacturePlaceholder(String className,
1223:                    boolean fakeData, int columnType) throws SQLException {
1224:                // System.out.println("Entering manufacturePlaceholder, className: "+className + "  columnType: "+columnType+"  fakeData: "+fakeData);
1225:                /* 
1226:                 * for classes we know don't have null constructors, we'll create them explicitly.
1227:                 */
1228:                if (className.equals("java.sql.Date")) { // NOI18N
1229:                    return new Date(new java.util.Date().getTime());
1230:                } else if (className.equals("java.sql.Time")) { // NOI18N
1231:                    return new Time(new java.util.Date().getTime());
1232:                } else if (className.equals("java.sql.Timestamp")) { // NOI18N
1233:                    return new Timestamp(new java.util.Date().getTime());
1234:                } else if (className.equals("java.math.BigDecimal")) { // NOI18N
1235:                    return new BigDecimal(fakeData ? BigInteger.ONE
1236:                            : BigInteger.ZERO);
1237:                } else if (className.equals("java.math.BigInteger")) { // NOI18N
1238:                    return fakeData ? BigInteger.ONE : BigInteger.ZERO;
1239:                } else if (className.equals("java.lang.Boolean")) { // NOI18N
1240:                    return fakeData ? Boolean.TRUE : Boolean.FALSE;
1241:                } else if (className.equals("java.lang.Byte")) { // NOI18N
1242:                    return new Byte(fakeData ? (byte) 123 : (byte) 0);
1243:                } else if (className.equals("java.lang.Character")) { // NOI18N
1244:                    return new Character(fakeData ? 'c' : ' '); // NOI18N
1245:                } else if (className.equals("java.lang.Double")) { // NOI18N
1246:                    return new Double(fakeData ? 123.0 : 0.0);
1247:                } else if (className.equals("java.lang.Float")) { // NOI18N
1248:                    return new Float(fakeData ? 123.0 : 0.0);
1249:                } else if (className.equals("java.lang.Integer")) { // NOI18N
1250:                    return new Integer(fakeData ? 123 : 0);
1251:                } else if (className.equals("java.lang.Long")) { // NOI18N
1252:                    return new Long(fakeData ? 123 : 0);
1253:                } else if (className.equals("java.lang.Short")) { // NOI18N
1254:                    return new Short((short) (fakeData ? 123 : 0));
1255:                } else if (className.equals("java.lang.String")) { // NOI18N
1256:                    return fakeData ? bundle.getString("arbitraryCharData")
1257:                            : ""; //NOI18N
1258:                } else if (className.equals("java.sql.Blob")) { // NOI18N
1259:                    try {
1260:                        return new javax.sql.rowset.serial.SerialBlob(
1261:                                fakeData ? (new byte[] { 1, 2, 3, 4, 5 })
1262:                                        : (new byte[0]));
1263:                    } catch (SQLException e) {
1264:                        return new Object();
1265:                    }
1266:                } else if (className.equals("javax.sql.SerialClob")) { // NOI18N
1267:                    try {
1268:                        return new javax.sql.rowset.serial.SerialClob(
1269:                                fakeData ? (bundle
1270:                                        .getString("arbitraryClobData")
1271:                                        .toCharArray()) : //NOI18N
1272:                                        new char[0]);
1273:                    } catch (SQLException e) {
1274:                        return new Object();
1275:                    }
1276:                } else if (className.equals("java.net.URL")) { // NOI18N
1277:                    try {
1278:                        if (fakeData) {
1279:                            return new java.net.URL("http://www.sun.com"); //NOI18N
1280:                        } else {
1281:                            return new java.net.URL(""); // NOI18N
1282:                        }
1283:                    } catch (java.net.MalformedURLException e) {
1284:                        return new Object();
1285:                    }
1286:                } else if (className.equals("java.sql.Array")) { // NOI18N
1287:                    return new java.sql.Array() {
1288:                        public Object getArray() {
1289:                            return null;
1290:                        }
1291:
1292:                        public Object getArray(long index, int count) {
1293:                            return null;
1294:                        }
1295:
1296:                        public Object getArray(long index, int count, Map map) {
1297:                            return null;
1298:                        }
1299:
1300:                        public Object getArray(Map map) {
1301:                            return null;
1302:                        }
1303:
1304:                        public int getBaseType() {
1305:                            return Types.CHAR;
1306:                        }
1307:
1308:                        public String getBaseTypeName() {
1309:                            return "CHAR"; //NOI18N
1310:                        }
1311:
1312:                        public ResultSet getResultSet() {
1313:                            return null;
1314:                        }
1315:
1316:                        public ResultSet getResultSet(long index, int count) {
1317:                            return null;
1318:                        }
1319:
1320:                        public ResultSet getResultSet(long index, int count,
1321:                                Map map) {
1322:                            return null;
1323:                        }
1324:
1325:                        public ResultSet getResultSet(Map map) {
1326:                            return null;
1327:                        }
1328:
1329:                        public void free() {
1330:                        }
1331:                    };
1332:                } else if (className.equals("char[]")) { // NOI18N
1333:                    return fakeData ? new char[] { 'a', 'b', 'c', 'd', 'e' }
1334:                            : new char[0];
1335:                } else if (className.equals("byte[]")) { // NOI18N
1336:                    return fakeData ? new byte[] { 1, 2, 3, 4, 5 }
1337:                            : new byte[0];
1338:                } else if (className.equals("java.sql.Ref")) { // NOI18N
1339:                    return new java.sql.Ref() {
1340:                        private Object data = bundle
1341:                                .getString("arbitraryCharData"); //NOI18N
1342:
1343:                        public String getBaseTypeName() {
1344:                            return "CHAR"; //NOI18N
1345:                        }
1346:
1347:                        public Object getObject() {
1348:                            return data;
1349:                        }
1350:
1351:                        public Object getObject(Map map) {
1352:                            return data;
1353:                        }
1354:
1355:                        public void setObject(Object value) {
1356:                            data = value;
1357:                        }
1358:                    };
1359:                } else if (className.equals("java.sql.Struct")) { // NOI18N
1360:                    return new java.sql.Struct() {
1361:                        private String[] data = {
1362:                                bundle.getString("arbitraryCharData"), //NOI18N
1363:                                bundle.getString("arbitraryCharData2"), //NOI18N
1364:                                bundle.getString("arbitraryCharData3") }; //NOI18N
1365:
1366:                        public Object[] getAttributes() {
1367:                            return data;
1368:                        }
1369:
1370:                        public Object[] getAttributes(Map map) {
1371:                            return data;
1372:                        }
1373:
1374:                        public String getSQLTypeName() {
1375:                            return "CHAR"; //NOI18N
1376:                        }
1377:                    };
1378:                }
1379:
1380:                if (fakeData) {
1381:                    // At least for now, let's try to use the old getFakeData
1382:                    //System.out.println("JK: temporary: fell through to use getFakeData()");
1383:                    return getFakeData(columnType);
1384:                }
1385:
1386:                try {
1387:                    return Class.forName(className).newInstance();
1388:                } catch (ClassNotFoundException e) {
1389:                    return new ColumnNotSet();
1390:                } catch (InstantiationException e) {
1391:                    return new ColumnNotSet();
1392:                } catch (IllegalAccessException e) {
1393:                    return new ColumnNotSet();
1394:                }
1395:            }
1396:
1397:            /**
1398:             * <p>Check if rowset, if so, execute if necessary.</p>
1399:             */
1400:            protected void checkExecute() throws SQLException {
1401:                if (!Beans.isDesignTime() && !executed) {
1402:                    getCachedRowSet().execute();
1403:                    getCachedRowSet().first();
1404:                    executed = true;
1405:                }
1406:            }
1407:
1408:            /**
1409:             * <p>Check whether resultset is updatable or not.</p>
1410:             */
1411:            private boolean isUpdatable() throws SQLException {
1412:                if (Beans.isDesignTime() || getCachedRowSet() == null) {
1413:                    return false;
1414:                }
1415:                checkExecute();
1416:                if (getCachedRowSet().getConcurrency() == ResultSet.CONCUR_READ_ONLY) {
1417:                    return false;
1418:                } else {
1419:                    return true;
1420:                }
1421:            }
1422:
1423:            /**
1424:             * <p>Return the one-relative column number corresponding to the
1425:             * specified {@link FieldKey}, or zero if there is no such column
1426:             * available.</p>
1427:             *
1428:             * @param fieldKey {@link FieldKey} representing this column
1429:             */
1430:            private int column(FieldKey fieldKey) throws DataProviderException {
1431:
1432:                if (fieldKeys == null) {
1433:                    getFieldKeys();
1434:                }
1435:                if (fieldKeys != null) {
1436:                    for (int i = 0; i < fieldKeys.length; i++) {
1437:                        if (fieldKey.getFieldId().equals(
1438:                                fieldKeys[i].getFieldId())) {
1439:                            return i + 1;
1440:                        }
1441:                    }
1442:                    /*
1443:                     * Here we are also matching on fieldKey,
1444:                     * so bug #6275441 workaround applies here too.
1445:                     * let's see if we hit bug #6275441
1446:                     */
1447:                    if (fieldKey.getFieldId().indexOf('.') == -1) {
1448:                        // fieldId is not prepended with a table (and schema), 
1449:                        // so we may have hit 6275441
1450:                        for (int i = 0; i < fieldKeys.length; i++) {
1451:                            String val = fieldKeys[i].getFieldId();
1452:                            int loc = val.lastIndexOf('.');
1453:                            if (loc >= 0 && loc + 1 < val.length()) {
1454:                                val = val.substring(loc + 1);
1455:                            }
1456:                            if (val.equalsIgnoreCase(fieldKey.getFieldId())) {
1457:                                return i + 1;
1458:                            }
1459:                        }
1460:                    }
1461:                }
1462:                return 0;
1463:            }
1464:
1465:            /**
1466:             * <p>Fires a changesCommtted event to each registered {@link
1467:             * TransactionalDataListener}.</p>
1468:             */
1469:            protected void fireChangesCommitted() {
1470:                TransactionalDataListener[] tdList = getTransactionalDataListeners();
1471:                for (int i = 0; i < tdList.length; i++) {
1472:                    tdList[i].changesCommitted(this );
1473:                }
1474:            }
1475:
1476:            /**
1477:             * <p>Fires a changesReverted event to each registered {@link
1478:             * TransactionalDataListener}.</p>
1479:             */
1480:            protected void fireChangesReverted() {
1481:                TransactionalDataListener[] tdList = getTransactionalDataListeners();
1482:                for (int i = 0; i < tdList.length; i++) {
1483:                    tdList[i].changesReverted(this );
1484:                }
1485:            }
1486:
1487:            /**
1488:             * <p>Return the <code>ResultSetMetaData</code> instance for the
1489:             * <code>ResultSet</code> we are wrapping, caching it the first
1490:             * time it is requested.</p>
1491:             */
1492:            private ResultSetMetaData getMetaData() {
1493:
1494:                if (metaData == null) {
1495:                    if (getCachedRowSet() != null) {
1496:                        try {
1497:                            // Generate filename for serialized result set metadata
1498:                            MetaDataSerializer mdSerializer = new MetaDataSerializer();
1499:                            String filename = mdSerializer
1500:                                    .generateMetaDataName(generateFilename());
1501:
1502:                            // the filename path begins with NetBeans userdir which is underdetermined at runtime
1503:                            if (filename.startsWith("null")) { // NOI18N
1504:                                metaData = getCachedRowSet().getMetaData();
1505:                            } else {
1506:                                // if it's the first time using a rowset then need to get live data prior to serializing
1507:                                if (!mdSerializer.mdFileNameExists(filename)) {
1508:                                    metaData = getCachedRowSet().getMetaData();
1509:                                    mdSerializer.serialize(metaData, filename);
1510:                                    metaDataFilename = filename;
1511:                                } else {
1512:                                    // create metadata file if refresh flag is true
1513:                                    if (refreshMetaDataFile) {
1514:                                        if (metaDataFilename != null) {
1515:                                            File metaDataFile = new File(
1516:                                                    metaDataFilename);
1517:                                            if (metaDataFile.exists()) {
1518:                                                metaDataFile.delete();
1519:                                            }
1520:                                        }
1521:
1522:                                        metaDataFilename = filename;
1523:                                        metaData = getCachedRowSet()
1524:                                                .getMetaData();
1525:                                        mdSerializer.serialize(metaData,
1526:                                                filename);
1527:                                        refreshMetaDataFile = false;
1528:                                    } else {
1529:                                        // Deserialize file now that it is available                                                    
1530:                                        metaData = new MetaDataDeserializer()
1531:                                                .deserialize(filename);
1532:                                    }
1533:                                }
1534:                            }
1535:                        } catch (SQLException e) {
1536:                            throw new RuntimeException(e);
1537:                        }
1538:                    }
1539:                }
1540:
1541:                return metaData;
1542:            }
1543:
1544:            private static URLClassLoader getDriverClassLoader(
1545:                    ClassLoader parent) {
1546:
1547:                File libDir = new File(System.getProperty("netbeans.user"),
1548:                        "jdbc-drivers"); // NOI18N
1549:
1550:                File[] files = libDir.listFiles(new FileFilter() {
1551:                    public boolean accept(File f) {
1552:                        return f.isDirectory()
1553:                                || f.getName().toLowerCase().endsWith("jar") // NOI18N
1554:                                || f.getName().toLowerCase().endsWith("zip"); // NOI18N
1555:                    }
1556:                });
1557:
1558:                int len = (files == null) ? 0 : files.length;
1559:
1560:                URL[] urls = new URL[len];
1561:
1562:                for (int i = 0; i < len; i++) {
1563:                    try {
1564:                        urls[i] = files[i].toURL();
1565:                    } catch (MalformedURLException e) {
1566:                        // ignore
1567:                    }
1568:                }
1569:                return URLClassLoader.newInstance(urls, parent);
1570:            }
1571:
1572:            // --------------------------------------------- Design Time Related Methods
1573:
1574:            /**
1575:             * <p>Return design time data of a type corresponding to that of the
1576:             * specified column.</p>
1577:             *
1578:             * @param rsmd <code>ResultSetMetaData</code> for this result set
1579:             * @param columnName Name of the requested column
1580:             */
1581:            private static Object getFakeData(int columnType)
1582:                    throws SQLException {
1583:
1584:                switch (columnType) {
1585:
1586:                case Types.ARRAY:
1587:                    return new java.sql.Array() {
1588:                        public Object getArray() {
1589:                            return null;
1590:                        }
1591:
1592:                        public Object getArray(long index, int count) {
1593:                            return null;
1594:                        }
1595:
1596:                        public Object getArray(long index, int count, Map map) {
1597:                            return null;
1598:                        }
1599:
1600:                        public Object getArray(Map map) {
1601:                            return null;
1602:                        }
1603:
1604:                        public int getBaseType() {
1605:                            return Types.CHAR;
1606:                        }
1607:
1608:                        public String getBaseTypeName() {
1609:                            return "CHAR"; //NOI18N
1610:                        }
1611:
1612:                        public ResultSet getResultSet() {
1613:                            return null;
1614:                        }
1615:
1616:                        public ResultSet getResultSet(long index, int count) {
1617:                            return null;
1618:                        }
1619:
1620:                        public ResultSet getResultSet(long index, int count,
1621:                                Map map) {
1622:                            return null;
1623:                        }
1624:
1625:                        public ResultSet getResultSet(Map map) {
1626:                            return null;
1627:                        }
1628:
1629:                        public void free() {
1630:                        }
1631:                    };
1632:
1633:                case Types.BIGINT:
1634:                    return new Long(123);
1635:
1636:                case Types.BINARY:
1637:                    return new byte[] { 1, 2, 3, 4, 5 };
1638:
1639:                case Types.BIT:
1640:                    return new Boolean(true);
1641:
1642:                case Types.BLOB:
1643:                    return new javax.sql.rowset.serial.SerialBlob(new byte[] {
1644:                            1, 2, 3, 4, 5 });
1645:
1646:                case Types.BOOLEAN:
1647:                    return new Boolean(true);
1648:
1649:                case Types.CHAR:
1650:                    return bundle.getString("arbitraryCharData"); //NOI18N
1651:
1652:                case Types.CLOB:
1653:                    return new javax.sql.rowset.serial.SerialClob(bundle
1654:                            .getString("arbitraryClobData").toCharArray()); //NOI18N
1655:
1656:                case Types.DATALINK:
1657:                    try {
1658:                        return new java.net.URL("http://www.sun.com"); //NOI18N
1659:                    } catch (java.net.MalformedURLException e) {
1660:                        return null;
1661:                    }
1662:
1663:                case Types.DATE:
1664:                    return new java.sql.Date(new java.util.Date().getTime());
1665:
1666:                case Types.DECIMAL:
1667:                    return new java.math.BigDecimal(java.math.BigInteger.ONE);
1668:
1669:                case Types.DISTINCT:
1670:                    return null;
1671:
1672:                case Types.DOUBLE:
1673:                    return new Double(123);
1674:
1675:                case Types.FLOAT:
1676:                    return new Double(123);
1677:
1678:                case Types.INTEGER:
1679:                    return new Integer(123);
1680:
1681:                case Types.JAVA_OBJECT:
1682:                    return bundle.getString("arbitraryCharData"); //NOI18N
1683:
1684:                case Types.LONGVARBINARY:
1685:                    return new byte[] { 1, 2, 3, 4, 5 };
1686:
1687:                case Types.LONGVARCHAR:
1688:                    return bundle.getString("arbitraryCharData"); //NOI18N
1689:
1690:                case Types.NULL:
1691:                    return null;
1692:
1693:                case Types.NUMERIC:
1694:                    return new java.math.BigDecimal(java.math.BigInteger.ONE);
1695:
1696:                case Types.OTHER:
1697:                    return null;
1698:
1699:                case Types.REAL:
1700:                    return new Float(123);
1701:
1702:                case Types.REF:
1703:                    return new java.sql.Ref() {
1704:
1705:                        private Object data = bundle
1706:                                .getString("arbitraryCharData"); //NOI18N
1707:
1708:                        public String getBaseTypeName() {
1709:                            return "CHAR"; //NOI18N
1710:                        }
1711:
1712:                        public Object getObject() {
1713:                            return data;
1714:                        }
1715:
1716:                        public Object getObject(Map map) {
1717:                            return data;
1718:                        }
1719:
1720:                        public void setObject(Object value) {
1721:                            data = value;
1722:                        }
1723:                    };
1724:                case Types.SMALLINT:
1725:                    return new Short((short) 123);
1726:
1727:                case Types.STRUCT:
1728:                    return new java.sql.Struct() {
1729:
1730:                        private String[] data = {
1731:                                bundle.getString("arbitraryCharData"), //NOI18N
1732:                                bundle.getString("arbitraryCharData2"), //NOI18N
1733:                                bundle.getString("arbitraryCharData3") }; //NOI18N
1734:
1735:                        public Object[] getAttributes() {
1736:                            return data;
1737:                        }
1738:
1739:                        public Object[] getAttributes(Map map) {
1740:                            return data;
1741:                        }
1742:
1743:                        public String getSQLTypeName() {
1744:                            return "CHAR"; //NOI18N
1745:                        }
1746:                    };
1747:
1748:                case Types.TIME:
1749:                    return new java.sql.Time(new java.util.Date().getTime());
1750:
1751:                case Types.TIMESTAMP:
1752:                    return new java.sql.Timestamp(new java.util.Date()
1753:                            .getTime());
1754:
1755:                case Types.TINYINT:
1756:                    return new Byte((byte) 123);
1757:
1758:                case Types.VARBINARY:
1759:                    return new byte[] { 1, 2, 3, 4, 5 };
1760:
1761:                case Types.VARCHAR:
1762:                    return bundle.getString("arbitraryCharData"); //NOI18N
1763:
1764:                default:
1765:                    return null;
1766:
1767:                }
1768:
1769:            }
1770:
1771:            private String generateFilename() {
1772:                // Serialize ResultSetMetaData for improved design-time performance
1773:
1774:                String dataSourceName = getCachedRowSet().getDataSourceName()
1775:                        .replaceFirst("java:comp/env/jdbc/", ""); // NOI18N   
1776:                String commandName = getCachedRowSet().getCommand().replaceAll(
1777:                        " ", "").replaceAll("\\p{Punct}+", ""); // NOI18N
1778:                commandName = commandName.toLowerCase();
1779:                commandName = commandName.replaceFirst("selectfrom", ""); // NOI18N
1780:                commandName = commandName.replaceFirst("selectall", ""); // NOI18N
1781:
1782:                if (commandName.length() > 200) {
1783:                    commandName = commandName.substring(0, 200);
1784:                }
1785:
1786:                return dataSourceName + "_" + "_" + commandName; // NOI18N
1787:            }
1788:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.