0001: //** Copyright Statement ***************************************************
0002: //The Salmon Open Framework for Internet Applications (SOFIA)
0003: // Copyright (C) 1999 - 2002, Salmon LLC
0004: //
0005: // This program is free software; you can redistribute it and/or
0006: // modify it under the terms of the GNU General Public License version 2
0007: // as published by the Free Software Foundation;
0008: //
0009: // This program is distributed in the hope that it will be useful,
0010: // but WITHOUT ANY WARRANTY; without even the implied warranty of
0011: // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
0012: // GNU General Public License for more details.
0013: //
0014: // You should have received a copy of the GNU General Public License
0015: // along with this program; if not, write to the Free Software
0016: // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
0017: //
0018: // For more information please visit http://www.salmonllc.com
0019: //** End Copyright Statement ***************************************************
0020: package com.salmonllc.sql;
0021:
0022: /////////////////////////
0023: //$Archive: /SOFIA/SourceCode/com/salmonllc/sql/DSDataRow.java $
0024: //$Author: Dan $
0025: //$Revision: 50 $
0026: //$Modtime: 11/08/04 10:20a $
0027: /////////////////////////
0028:
0029: import java.sql.*;
0030: import java.lang.reflect.*;
0031: import java.math.BigDecimal;
0032: import java.io.InputStream;
0033:
0034: import com.salmonllc.util.*;
0035:
0036: /**
0037: * This class should not be used outside the framework. It was made public as an
0038: * implemetation detail. To access the contents of a row in a DataStore, use the
0039: * DataStoreRow object.
0040: */
0041: public class DSDataRow implements java.io.Serializable {
0042: private Object[] _currentData;
0043: private Object[] _origData;
0044: private String[] _tempData;
0045: private int _tempCount = 0;
0046: private int _rowStatus = DataStoreBuffer.STATUS_NOT_MODIFIED;
0047: private boolean _pKeyMod = false;
0048: private byte _columnStatus[];
0049: private Object _bean;
0050: private boolean _bucketsModified = false;
0051: private transient ResultSetMetaData _rsmd;
0052: private int _proxyRow = -1;
0053:
0054: public int getProxyRow() {
0055: return _proxyRow;
0056: }
0057:
0058: public void setProxyRow(int proxyRow) {
0059: _proxyRow = proxyRow;
0060: }
0061:
0062: public DSDataRow(DSDataStoreDescriptor d) {
0063: _currentData = new Object[d.getColumnCount()];
0064: _columnStatus = new byte[d.getColumnCount()];
0065: _rowStatus = DataStoreBuffer.STATUS_NEW;
0066: if (d.areNullDefaultsDefined()) {
0067: for (int i = 0; i < d.getColumnCount(); i++)
0068: _currentData[i] = d.getNullDefault(d.getColumn(i)
0069: .getType());
0070: }
0071: }
0072:
0073: public DSDataRow(DSDataStoreDescriptor d, Object bean)
0074: throws Exception {
0075: this (d);
0076: populateFromBean(d, bean, DataStoreBuffer.STATUS_MODIFIED);
0077: }
0078:
0079: public DSDataRow(DSDataStoreDescriptor d, ResultSet r) {
0080: this (d);
0081: try {
0082: _rsmd = r.getMetaData();
0083: } catch (Exception e) {
0084: MessageLog.writeErrorMessage("DSDataRow", e, this );
0085: }
0086: populateFromResultSet(d, r);
0087: }
0088:
0089: public void clearOrigData() {
0090: _origData = null;
0091: }
0092:
0093: private Object cloneData(Object data) {
0094: Object retVal = null;
0095:
0096: if (data == null)
0097: retVal = null;
0098: else if (data instanceof String)
0099: retVal = new String((String) data);
0100: else if (data instanceof Integer)
0101: retVal = new Integer(((Integer) data).intValue());
0102: else if (data instanceof Timestamp)
0103: retVal = Timestamp.valueOf(data.toString());
0104: else if (data instanceof java.sql.Date)
0105: retVal = java.sql.Date.valueOf(data.toString());
0106: else if (data instanceof java.sql.Time)
0107: retVal = java.sql.Time.valueOf(data.toString());
0108: else if (data instanceof Double)
0109: retVal = new Double(((Double) data).doubleValue());
0110: else if (data instanceof byte[]) {
0111: retVal = new byte[((byte[]) data).length];
0112: System
0113: .arraycopy(data, 0, retVal, 0,
0114: ((byte[]) data).length);
0115: } else if (data instanceof Short)
0116: retVal = new Short(((Short) data).shortValue());
0117: else if (data instanceof Long)
0118: retVal = new Long(((Long) data).longValue());
0119: else if (data instanceof Float)
0120: retVal = new Float(((Float) data).floatValue());
0121:
0122: return retVal;
0123: }
0124:
0125: private int compareByteArrays(byte[] v1, byte[] v2) {
0126: int len1 = v1.length;
0127: int len2 = v2.length;
0128:
0129: for (int i = 0; i < len1 && i < len2; i++) {
0130: if (v1[i] == v2[i])
0131: continue;
0132: else if (v1[i] < v2[i])
0133: return -1;
0134: else
0135: return 1;
0136: }
0137:
0138: if (len1 == len2)
0139: return 0;
0140: else if (len1 < len2)
0141: return -1;
0142: else
0143: return 1;
0144: }
0145:
0146: public boolean compareExpressions(DataStoreEvaluator dsEval,
0147: int row1, int row2, int d) {
0148: try {
0149: Object com1 = dsEval.evaluateRow(row1);
0150: Object com2 = dsEval.evaluateRow(row2);
0151: boolean dir = (d == DataStoreBuffer.SORT_DES);
0152:
0153: if ((com1 == null) && (com2 == null)) {
0154: return !dir;
0155: } else if ((com1 == null) && (com2 != null)) {
0156: return !dir;
0157: } else if ((com1 != null) && (com2 == null)) {
0158: return dir;
0159: } else if (com1 instanceof String) {
0160: int comp = ((String) com1).toUpperCase().compareTo(
0161: ((String) com2).toUpperCase());
0162: if (comp == 0)
0163: return !dir;
0164: else if (comp < 0)
0165: return !dir;
0166: else
0167: return dir;
0168: } else if (com1 instanceof Number) {
0169: double v1 = ((Number) com1).doubleValue();
0170: double v2 = ((Number) com2).doubleValue();
0171: if (v1 == v2)
0172: return !dir;
0173: else if (v1 < v2)
0174: return !dir;
0175: else
0176: return dir;
0177: } else if (com1 instanceof Timestamp) {
0178: if (((Timestamp) com1).equals((Timestamp) com2))
0179: return !dir;
0180: else if (((Timestamp) com1).before((Timestamp) com2))
0181: return !dir;
0182: else
0183: return dir;
0184: } else if (com1 instanceof java.sql.Date) {
0185: if (com1.equals(com2))
0186: return !dir;
0187: else if (((java.sql.Date) com1)
0188: .before((java.sql.Date) com2))
0189: return !dir;
0190: else
0191: return dir;
0192: } else if (com1 instanceof java.sql.Time) {
0193: if (com1.equals(com2))
0194: return false;
0195: else if (((java.sql.Time) com1)
0196: .before((java.sql.Time) com2))
0197: return !dir;
0198: else
0199: return dir;
0200: } else
0201: return false;
0202: } catch (Exception e) {
0203: return false;
0204: }
0205:
0206: }
0207:
0208: public boolean equalExpressions(DataStoreEvaluator dsEval,
0209: int row1, int row2) {
0210: try {
0211: Object com1 = dsEval.evaluateRow(row1);
0212: Object com2 = dsEval.evaluateRow(row2);
0213:
0214: if ((com1 == null) && (com2 == null)) {
0215: return true;
0216: } else if ((com1 == null) && (com2 != null)) {
0217: return false;
0218: } else if ((com1 != null) && (com2 == null)) {
0219: return false;
0220: } else if (com1 instanceof String) {
0221: int comp = ((String) com1).toUpperCase().compareTo(
0222: ((String) com2).toUpperCase());
0223: if (comp == 0)
0224: return true;
0225: else
0226: return false;
0227: } else if (com1 instanceof Number) {
0228: double v1 = ((Number) com1).doubleValue();
0229: double v2 = ((Number) com2).doubleValue();
0230: if (v1 == v2)
0231: return true;
0232: else
0233: return false;
0234: } else if (com1 instanceof Timestamp) {
0235: if (((Timestamp) com1).equals((Timestamp) com2))
0236: return true;
0237: else
0238: return false;
0239: } else if (com1 instanceof java.sql.Date) {
0240: if (com1.equals(com2))
0241: return true;
0242: else
0243: return false;
0244: } else if (com1 instanceof java.sql.Time) {
0245: if (com1.equals(com2))
0246: return true;
0247: else
0248: return false;
0249: } else
0250: return false;
0251: } catch (Exception e) {
0252: return false;
0253: }
0254:
0255: }
0256:
0257: /**
0258: * Returns true if the d is greater than this row
0259: *
0260: * @return boolean
0261: * @param d
0262: * com.salmonllc.sql.DSDataRow
0263: * @param cols
0264: * int[]
0265: * @param dirs
0266: * short[]
0267: */
0268: public boolean compareRows(int row1, int row2, DSDataRow d,
0269: Object[] cols, int[] dirs) {
0270: for (int i = 0; i < cols.length; i++) {
0271: Object com1;
0272: Object com2;
0273:
0274: if (cols[i] instanceof DataStoreEvaluator) {
0275: DataStoreEvaluator de = (DataStoreEvaluator) cols[i];
0276: try {
0277: com1 = de.evaluateRow(row1);
0278: } catch (Exception e) {
0279: com1 = null;
0280: }
0281:
0282: try {
0283: com2 = de.evaluateRow(row2);
0284: } catch (Exception e) {
0285: com2 = null;
0286: }
0287: } else {
0288: com1 = getData(((Integer) cols[i]).intValue());
0289: com2 = d.getData(((Integer) cols[i]).intValue());
0290: }
0291:
0292: boolean dir = (dirs[i] == DataStoreBuffer.SORT_DES);
0293:
0294: if (com1 == null) {
0295: if (com2 == null)
0296: continue;
0297: else
0298: return !dir;
0299: } else if (com2 == null)
0300: return dir;
0301:
0302: if (com1 instanceof String) {
0303: int comp = ((String) com1)
0304: .compareToIgnoreCase(((String) com2));
0305: if (comp == 0)
0306: continue;
0307: else if (comp < 0)
0308: return !dir;
0309: else
0310: return dir;
0311: } else if (com1 instanceof Number) {
0312: double v1 = ((Number) com1).doubleValue();
0313: double v2 = ((Number) com2).doubleValue();
0314: if (v1 == v2)
0315: continue;
0316: else if (v1 < v2)
0317: return !dir;
0318: else
0319: return dir;
0320: } else if (com1 instanceof Timestamp) {
0321: if (((Timestamp) com1).equals((Timestamp) com2))
0322: continue;
0323: else if (((Timestamp) com1).before((Timestamp) com2))
0324: return !dir;
0325: else
0326: return dir;
0327: } else if (com1 instanceof java.sql.Date) {
0328: if (com1.equals(com2))
0329: continue;
0330: else if (((java.sql.Date) com1)
0331: .before((java.sql.Date) com2))
0332: return !dir;
0333: else
0334: return dir;
0335: } else if (com1 instanceof java.sql.Time) {
0336: if (com1.equals(com2))
0337: continue;
0338: else if (((java.sql.Time) com1)
0339: .before((java.sql.Time) com2))
0340: return !dir;
0341: else
0342: return dir;
0343: } else if (com1 instanceof byte[]) {
0344: int comp = compareByteArrays((byte[]) com1,
0345: (byte[]) com2);
0346: if (comp == 0)
0347: continue;
0348: else if (comp < 0)
0349: return !dir;
0350: else
0351: return dir;
0352: }
0353: }
0354: return false;
0355: }
0356:
0357: /**
0358: * Returns true if the rows are equals
0359: *
0360: * @return boolean
0361: * @param d
0362: * com.salmonllc.sql.DSDataRow
0363: * @param cols
0364: * int[]
0365: */
0366: public boolean equalRows(int row1, int row2, DSDataRow d,
0367: Object[] cols) {
0368: for (int i = 0; i < cols.length; i++) {
0369: Object com1;
0370: Object com2;
0371:
0372: if (cols[i] instanceof DataStoreEvaluator) {
0373: DataStoreEvaluator de = (DataStoreEvaluator) cols[i];
0374: try {
0375: com1 = de.evaluateRow(row1);
0376: } catch (Exception e) {
0377: com1 = null;
0378: }
0379:
0380: try {
0381: com2 = de.evaluateRow(row2);
0382: } catch (Exception e) {
0383: com2 = null;
0384: }
0385: } else {
0386: com1 = getData(((Integer) cols[i]).intValue());
0387: com2 = d.getData(((Integer) cols[i]).intValue());
0388: }
0389:
0390: if (com1 == null) {
0391: if (com2 == null)
0392: continue;
0393: else
0394: return false;
0395: } else if (com2 == null)
0396: return false;
0397:
0398: if (com1 instanceof String) {
0399: int comp = ((String) com1)
0400: .compareToIgnoreCase(((String) com2));
0401: if (comp == 0)
0402: continue;
0403: else
0404: return false;
0405: } else if (com1 instanceof Number) {
0406: double v1 = ((Number) com1).doubleValue();
0407: double v2 = ((Number) com2).doubleValue();
0408: if (v1 == v2)
0409: continue;
0410: else
0411: return !false;
0412: } else if (com1 instanceof Timestamp) {
0413: if (((Timestamp) com1).equals((Timestamp) com2))
0414: continue;
0415: else
0416: return false;
0417: } else if (com1 instanceof java.sql.Date) {
0418: if (com1.equals(com2))
0419: continue;
0420: else
0421: return false;
0422: } else if (com1 instanceof java.sql.Time) {
0423: if (com1.equals(com2))
0424: continue;
0425: else
0426: return false;
0427: } else if (com1 instanceof byte[]) {
0428: int comp = compareByteArrays((byte[]) com1,
0429: (byte[]) com2);
0430: if (comp == 0)
0431: continue;
0432: else if (comp < 0)
0433: return false;
0434: }
0435: }
0436: return true;
0437: }
0438:
0439: /**
0440: * Returns true if the d is greater than this row
0441: *
0442: * @return boolean
0443: * @param d
0444: * com.salmonllc.sql.DSDataRow
0445: * @param cols
0446: * int[]
0447: */
0448: public int compareRows(DSDataRow d, int[] cols) {
0449: for (int i = 0; i < cols.length; i++) {
0450: Object com1 = getData(cols[i]);
0451: Object com2 = d.getData(cols[i]);
0452:
0453: if (com1 == null) {
0454: if (com2 == null)
0455: continue;
0456: else
0457: return -1;
0458: } else if (com2 == null)
0459: return 0;
0460:
0461: if (com1 instanceof String) {
0462: //fc: 12/17/02 A bug fix where Strings Compare value was just
0463: // returned, should have been checking for 0.
0464: int iCompare = ((String) com1).toUpperCase().compareTo(
0465: ((String) com2).toUpperCase());
0466: if (iCompare == 0)
0467: continue;
0468: return iCompare;
0469: } else if (com1 instanceof Number) {
0470: double v1 = ((Number) com1).doubleValue();
0471: double v2 = ((Number) com2).doubleValue();
0472: if (v1 == v2)
0473: continue;
0474: else if (v1 < v2)
0475: return -1;
0476: else
0477: return 1;
0478: } else if (com1 instanceof Timestamp) {
0479: if (((Timestamp) com1).equals((Timestamp) com2))
0480: continue;
0481: else if (((Timestamp) com1).before((Timestamp) com2))
0482: return -1;
0483: else
0484: return 1;
0485: } else if (com1 instanceof java.sql.Date) {
0486: if (com1.equals(com2))
0487: continue;
0488: else if (((java.sql.Date) com1)
0489: .before((java.sql.Date) com2))
0490: return -1;
0491: else
0492: return 1;
0493: } else if (com1 instanceof java.sql.Time) {
0494: if (com1.equals(com2))
0495: continue;
0496: else if (((java.sql.Time) com1)
0497: .before((java.sql.Time) com2))
0498: return -1;
0499: else
0500: return 1;
0501: } else if (com1 instanceof byte[]) {
0502: //fc: 12/17/02 A bug fix where byte[] Compare value was just
0503: // returned, should have been checking for 0.
0504: int iCompare = compareByteArrays((byte[]) com1,
0505: (byte[]) com2);
0506: if (iCompare == 0)
0507: continue;
0508: return iCompare;
0509: }
0510: }
0511: return 0;
0512: }
0513:
0514: /**
0515: * Returns true if the d row is equal to the current row
0516: *
0517: * @return boolean
0518: * @param d
0519: * com.salmonllc.sql.DSDataRow
0520: * @param cols
0521: * int[]
0522: */
0523: public boolean equalRows(DSDataRow d, int[] cols) {
0524: for (int i = 0; i < cols.length; i++) {
0525: Object com1 = getData(cols[i]);
0526: Object com2 = d.getData(cols[i]);
0527:
0528: if (com1 == null) {
0529: if (com2 == null)
0530: continue;
0531: else
0532: return false;
0533: } else if (com2 == null)
0534: return false;
0535:
0536: if (com1 instanceof String) {
0537: //fc: 12/17/02 A bug fix where Strings Compare value was just
0538: // returned, should have been checking for 0.
0539: int iCompare = ((String) com1).toUpperCase().compareTo(
0540: ((String) com2).toUpperCase());
0541: if (iCompare == 0)
0542: continue;
0543: return false;
0544: } else if (com1 instanceof Number) {
0545: double v1 = ((Number) com1).doubleValue();
0546: double v2 = ((Number) com2).doubleValue();
0547: if (v1 == v2)
0548: continue;
0549: else
0550: return false;
0551: } else if (com1 instanceof Timestamp) {
0552: if (((Timestamp) com1).equals((Timestamp) com2))
0553: continue;
0554: else
0555: return false;
0556: } else if (com1 instanceof java.sql.Date) {
0557: if (com1.equals(com2))
0558: continue;
0559: else
0560: return false;
0561: } else if (com1 instanceof java.sql.Time) {
0562: if (com1.equals(com2))
0563: continue;
0564: else
0565: return false;
0566: } else if (com1 instanceof byte[]) {
0567: //fc: 12/17/02 A bug fix where byte[] Compare value was just
0568: // returned, should have been checking for 0.
0569: int iCompare = compareByteArrays((byte[]) com1,
0570: (byte[]) com2);
0571: if (iCompare == 0)
0572: continue;
0573: return false;
0574: }
0575: }
0576: return true;
0577: }
0578:
0579: /**
0580: * Returns true if the d is greater than this row
0581: *
0582: * @return boolean
0583: * @param d
0584: * com.salmonllc.sql.DSDataRow
0585: * @param cols
0586: * int[]
0587: * @param dirs
0588: * short[]
0589: */
0590: public boolean compareRows(DSDataRow d, int[] cols, int[] dirs) {
0591: for (int i = 0; i < cols.length; i++) {
0592: Object com1 = getData(cols[i]);
0593: Object com2 = d.getData(cols[i]);
0594: boolean dir = (dirs[i] == DataStoreBuffer.SORT_DES);
0595:
0596: if (com1 == null) {
0597: if (com2 == null)
0598: continue;
0599: else
0600: return !dir;
0601: } else if (com2 == null)
0602: return dir;
0603:
0604: if (com1 instanceof String) {
0605: int comp = ((String) com1)
0606: .compareToIgnoreCase(((String) com2));
0607: if (comp == 0)
0608: continue;
0609: else if (comp < 0)
0610: return !dir;
0611: else
0612: return dir;
0613: } else if (com1 instanceof Number) {
0614: double v1 = ((Number) com1).doubleValue();
0615: double v2 = ((Number) com2).doubleValue();
0616: if (v1 == v2)
0617: continue;
0618: else if (v1 < v2)
0619: return !dir;
0620: else
0621: return dir;
0622: } else if (com1 instanceof Timestamp) {
0623: if (((Timestamp) com1).equals((Timestamp) com2))
0624: continue;
0625: else if (((Timestamp) com1).before((Timestamp) com2))
0626: return !dir;
0627: else
0628: return dir;
0629: } else if (com1 instanceof java.sql.Date) {
0630: if (com1.equals(com2))
0631: continue;
0632: else if (((java.sql.Date) com1)
0633: .before((java.sql.Date) com2))
0634: return !dir;
0635: else
0636: return dir;
0637: } else if (com1 instanceof java.sql.Time) {
0638: if (com1.equals(com2))
0639: continue;
0640: else if (((java.sql.Time) com1)
0641: .before((java.sql.Time) com2))
0642: return !dir;
0643: else
0644: return dir;
0645: } else if (com1 instanceof byte[]) {
0646: int comp = compareByteArrays((byte[]) com1,
0647: (byte[]) com2);
0648: if (comp == 0)
0649: continue;
0650: else if (comp < 0)
0651: return !dir;
0652: else
0653: return dir;
0654: }
0655: }
0656: return false;
0657: }
0658:
0659: /**
0660: * Copy data back to the bean
0661: *
0662: * @param d
0663: */
0664: public boolean copyDataToBean(DSDataStoreDescriptor d,
0665: boolean resetStatus) throws DataStoreException {
0666: try {
0667: return copyBeanData(d, resetStatus);
0668: } catch (Exception e) {
0669: e.printStackTrace();
0670: throw new DataStoreException("Can not copy data to Bean",
0671: getCause(e));
0672: }
0673: }
0674:
0675: /**
0676: * Copy data back to the bean
0677: *
0678: * @param d
0679: */
0680:
0681: public boolean copyDataToBean(DSDataStoreDescriptor d)
0682: throws DataStoreException {
0683: try {
0684: return copyBeanData(d, true);
0685: } catch (Exception e) {
0686: throw new DataStoreException("Can not copy data to Bean",
0687: getCause(e));
0688: }
0689: }
0690:
0691: /**
0692: * Utility method to retrieve an error cause.
0693: *
0694: * @param e
0695: * @return
0696: */
0697: public static Throwable getCause(Exception e) {
0698: if (e instanceof InvocationTargetException)
0699: return Util.getCause(e);
0700: else
0701: return e;
0702: }
0703:
0704: private boolean copyBeanData(DSDataStoreDescriptor d,
0705: boolean resetStatus) throws Exception {
0706: if (_rowStatus == DataStoreBuffer.STATUS_NOT_MODIFIED
0707: || _rowStatus == DataStoreBuffer.STATUS_NEW)
0708: return false;
0709:
0710: boolean retVal = false;
0711: Object getParms[] = new Object[0];
0712: Object setParms[] = new Object[1];
0713: for (int i = 0; i < d.getColumnCount(); i++) {
0714: int status = getColumnStatus(i);
0715: if (status == DataStoreBuffer.STATUS_NOT_MODIFIED)
0716: continue;
0717:
0718: DSColumnDescriptor col = d.getColumn(i);
0719:
0720: if (!col.isUpdateable()) {
0721: setColumnStatus(i, DataStoreBuffer.STATUS_NOT_MODIFIED);
0722: continue;
0723: }
0724:
0725: retVal = true;
0726: int type = col.getType();
0727: Method setMethod = col.getSetMethod();
0728: Object o = _currentData[i];
0729: Class propertyClass = col.getPropertyClass();
0730:
0731: if (propertyClass == Boolean.TYPE) {
0732: if (o == null)
0733: o = new Boolean(false);
0734: else if (o.equals(d.getBooleanTrueValue()))
0735: o = new Boolean(true);
0736: else
0737: o = new Boolean(false);
0738: } else {
0739: if (type == DataStoreBuffer.DATATYPE_STRING) {
0740: if (propertyClass == Character.TYPE) {
0741: if (o == null)
0742: o = new Character(' ');
0743: else {
0744: String s = (String) o;
0745: if (s.length() == 0)
0746: o = new Character(' ');
0747: else
0748: o = new Character(s.charAt(0));
0749: }
0750: }
0751: } else if (o == null && propertyClass.isPrimitive()) {
0752: if (type == DataStoreBuffer.DATATYPE_INT)
0753: o = new Integer(0);
0754: else if (type == DataStoreBuffer.DATATYPE_DOUBLE)
0755: o = new Double(0);
0756: else if (type == DataStoreBuffer.DATATYPE_FLOAT)
0757: o = new Float(0);
0758: else if (type == DataStoreBuffer.DATATYPE_LONG)
0759: o = new Long(0);
0760: else if (type == DataStoreBuffer.DATATYPE_SHORT)
0761: o = new Short((short) 0);
0762: } else if (Util.instanceOf(BigDecimal.class,
0763: propertyClass)) {
0764: if (o != null)
0765: o = new BigDecimal(((Double) o).doubleValue());
0766: }
0767: }
0768: setParms[0] = o;
0769: Object bean = getBean(_bean, col.getParentGetMethods(),
0770: getParms, col, o != null);
0771: if (bean != null)
0772: setMethod.invoke(bean, setParms);
0773: if (resetStatus)
0774: setColumnStatus(i, DataStoreBuffer.STATUS_NOT_MODIFIED);
0775: }
0776: return retVal;
0777: }
0778:
0779: public void undoChanges() {
0780: if (_origData != null) {
0781: _currentData = new Object[_origData.length];
0782: for (int i = 0; i < _origData.length; i++)
0783: _currentData[i] = cloneData(_origData[i]);
0784: }
0785: resetStatus();
0786: }
0787:
0788: public void copyDataToOrig() {
0789: if (_origData == null)
0790: _origData = new Object[_currentData.length];
0791:
0792: for (int i = 0; i < _currentData.length; i++)
0793: _origData[i] = cloneData(_currentData[i]);
0794:
0795: }
0796:
0797: public Object getBean() {
0798: return _bean;
0799: }
0800:
0801: public int getColumnStatus(int columnNo) {
0802: if (columnNo >= _columnStatus.length)
0803: return DataStoreBuffer.STATUS_NOT_MODIFIED;
0804:
0805: return _columnStatus[columnNo];
0806: }
0807:
0808: public Object getData(int columnNo) {
0809: if (columnNo < 0)
0810: return null;
0811:
0812: if (columnNo >= _currentData.length) {
0813: Object[] temp = new Object[columnNo + 1];
0814: System.arraycopy(_currentData, 0, temp, 0,
0815: _currentData.length);
0816: _currentData = temp;
0817: }
0818:
0819: return _currentData[columnNo];
0820: }
0821:
0822: public Object getOrigData(int columnNo) {
0823: if (columnNo < 0)
0824: return null;
0825:
0826: if (columnNo >= _origData.length) {
0827: Object[] temp = new Object[columnNo + 1];
0828: System.arraycopy(_origData, 0, temp, 0, _origData.length);
0829: _origData = temp;
0830: }
0831:
0832: if (_origData == null)
0833: return null;
0834: else if (columnNo >= _origData.length)
0835: return null;
0836: else
0837: return _origData[columnNo];
0838:
0839: }
0840:
0841: public int getRowStatus() {
0842: return _rowStatus;
0843: }
0844:
0845: public boolean getBucketsModified() {
0846: return _bucketsModified;
0847: }
0848:
0849: public void setBucketsModified(boolean modified) {
0850: _bucketsModified = modified;
0851: }
0852:
0853: public boolean isPrimaryKeyModified() {
0854: return _pKeyMod;
0855: }
0856:
0857: public void populateFromBean(DSDataStoreDescriptor d, Object bean,
0858: int initialRowStatus) throws DataStoreException {
0859: populateFromBean(d, bean, initialRowStatus, null);
0860: }
0861:
0862: public void populateFromBean(DSDataStoreDescriptor d, Object bean,
0863: int initialRowStatus, String prefix)
0864: throws DataStoreException {
0865: Object getParms[] = new Object[0];
0866: for (int i = 0; i < d.getColumnCount(); i++) {
0867: try {
0868: DSColumnDescriptor col = d.getColumn(i);
0869: if (col.getGetMethod() == null) {
0870: continue;
0871: }
0872: if (prefix != null) {
0873: if (!col.getInternalName().startsWith(prefix))
0874: continue;
0875: }
0876: int type = col.getType();
0877: Method getMethod = col.getGetMethod();
0878: Object beanToInvoke = getBean(bean, col
0879: .getParentGetMethods(), getParms, col, false);
0880: if (beanToInvoke == null)
0881: continue;
0882: Object o = getMethod.invoke(beanToInvoke, getParms);
0883: if (o instanceof Boolean) {
0884: if (o != null)
0885: o = ((Boolean) o).booleanValue() ? d
0886: .getBooleanTrueValue() : d
0887: .getBooleanFalseValue();
0888: else
0889: o = d.getBooleanFalseValue();
0890: _currentData[i] = o;
0891: } else if (type == DataStoreBuffer.DATATYPE_STRING) {
0892: if (o != null) {
0893: o = o.toString();
0894: if (d.getTrimStrings())
0895: o = ((String) o).trim();
0896: }
0897: _currentData[i] = o;
0898: } else
0899: _currentData[i] = o;
0900: _columnStatus[i] = (byte) DataStoreBuffer.STATUS_NOT_MODIFIED;
0901: } catch (Exception e) {
0902: e.printStackTrace();
0903: throw new DataStoreException(e.getMessage(), -1, d
0904: .getColumn(i).getColumn());
0905: }
0906: }
0907:
0908: _bean = bean;
0909: _rowStatus = initialRowStatus;
0910: }
0911:
0912: private Object getBean(Object bean, Method parentGetters[],
0913: Object getParms[], DSColumnDescriptor columnDesc,
0914: boolean setValues) throws IllegalArgumentException,
0915: IllegalAccessException, InvocationTargetException {
0916: Object ret = bean;
0917: Object topNotNull = bean;
0918: if (ret instanceof Object[]) {
0919: Object[] work = (Object[]) ret;
0920: BeanDataStore.BeanClassInfo inf = columnDesc.getBeanInfo();
0921: ret = work[inf.getIndex()];
0922: }
0923: for (int i = 0; i < parentGetters.length; i++) {
0924: topNotNull = ret;
0925: ret = parentGetters[i].invoke(ret, getParms);
0926: if (ret == null) {
0927: if (setValues) {
0928: Class c = parentGetters[i].getReturnType();
0929: try {
0930: ret = c.newInstance();
0931: String setMethodName = parentGetters[i]
0932: .getName();
0933: if (setMethodName.startsWith("get"))
0934: setMethodName = "set"
0935: + setMethodName.substring(3);
0936: else
0937: setMethodName = "set"
0938: + setMethodName.substring(2);
0939: Class types[] = { c };
0940: Object parms[] = { ret };
0941: Method setMethod = topNotNull.getClass()
0942: .getMethod(setMethodName, types);
0943: setMethod.invoke(topNotNull, parms);
0944:
0945: } catch (Exception e) {
0946: return null;
0947: }
0948: } else
0949: return null;
0950: }
0951: }
0952: return ret;
0953:
0954: }
0955:
0956: public void populateFromResultSet(DSDataStoreDescriptor d,
0957: ResultSet r) {
0958: int rsRow = 0;
0959: try {
0960: if (_rsmd == null)
0961: _rsmd = r.getMetaData();
0962: for (int i = 0; i < d.getColumnCount(); i++) {
0963: DSColumnDescriptor col = d.getColumn(i);
0964: if (col.getColumn() == null) {
0965: _currentData[i] = null;
0966: } else {
0967: rsRow++;
0968: int type = col.getType();
0969: Object o = r.getObject(rsRow);
0970: switch (type) {
0971: case DataStoreBuffer.DATATYPE_STRING:
0972: if (o instanceof byte[]) {
0973: String sDataType = _rsmd
0974: .getColumnTypeName(rsRow);
0975: if (sDataType.equals("TEXT")) {
0976: InputStream is = r
0977: .getUnicodeStream(rsRow);
0978: if (is != null) {
0979: byte[] baData = new byte[is
0980: .available()];
0981: is.read(baData);
0982: is.close();
0983: o = new String(baData);
0984: } else
0985: o = null;
0986: } else {
0987: // MySql special case in aggregate functions
0988: o = r.getString(rsRow);
0989: }
0990: }
0991: if (d.getTrimStrings() && o != null)
0992: o = o.toString().trim();
0993: _currentData[i] = o;
0994: break;
0995: case DataStoreBuffer.DATATYPE_DATETIME:
0996: // MySql special case in aggregate functions
0997: if (o instanceof byte[])
0998: o = r.getDate(rsRow);
0999: _currentData[i] = o;
1000: case DataStoreBuffer.DATATYPE_BYTEARRAY:
1001: _currentData[i] = o;
1002: break;
1003: case DataStoreBuffer.DATATYPE_DATE:
1004: // MySql special case in aggregate functions
1005: if (o instanceof byte[])
1006: o = r.getDate(rsRow);
1007: _currentData[i] = o;
1008: break;
1009: case DataStoreBuffer.DATATYPE_TIME:
1010: // MySql special case in aggregate functions
1011: if (o instanceof byte[])
1012: o = r.getTimestamp(rsRow);
1013: _currentData[i] = o;
1014: break;
1015: case DataStoreBuffer.DATATYPE_INT:
1016: if (o == null)
1017: _currentData[i] = null;
1018: else
1019: _currentData[i] = new Integer(((Number) o)
1020: .intValue());
1021: break;
1022: case DataStoreBuffer.DATATYPE_DOUBLE:
1023: if (o == null)
1024: _currentData[i] = null;
1025: else
1026: _currentData[i] = new Double(((Number) o)
1027: .doubleValue());
1028: break;
1029: case DataStoreBuffer.DATATYPE_SHORT:
1030: if (o == null) {
1031: _currentData[i] = null;
1032: } else {
1033: if (o instanceof Boolean) {
1034: if (((Boolean) o).booleanValue()) {
1035: _currentData[i] = new Short(
1036: (short) 1);
1037: } else {
1038: _currentData[i] = new Short(
1039: (short) 0);
1040: }
1041: } else {
1042: _currentData[i] = new Short(
1043: ((Number) o).shortValue());
1044: }
1045: }
1046: break;
1047: case DataStoreBuffer.DATATYPE_LONG:
1048: if (o == null)
1049: _currentData[i] = null;
1050: else
1051: _currentData[i] = new Long(((Number) o)
1052: .longValue());
1053: break;
1054: case DataStoreBuffer.DATATYPE_FLOAT:
1055: if (o == null)
1056: _currentData[i] = null;
1057: else
1058: _currentData[i] = new Float(((Number) o)
1059: .floatValue());
1060: break;
1061: default:
1062: if (o instanceof byte[]
1063: && ((byte[]) o).length == 4) {
1064: String sDataType = _rsmd
1065: .getColumnTypeName(rsRow);
1066: if (sDataType.equals("TEXT")) {
1067: InputStream is = r
1068: .getUnicodeStream(rsRow);
1069: if (is != null) {
1070: byte[] baData = new byte[is
1071: .available()];
1072: is.read(baData);
1073: is.close();
1074: o = new String(baData);
1075: } else
1076: o = null;
1077: }
1078: }
1079: _currentData[i] = o;
1080: break;
1081: }
1082:
1083: }
1084: }
1085: } catch (Exception e) {
1086: System.err.println("DSDataRow.populateFromResultSet:" + e);
1087: MessageLog.writeErrorMessage(
1088: "DSDataRow.populateFromResultSet:", e, this );
1089: }
1090: _rowStatus = DataStoreBuffer.STATUS_NOT_MODIFIED;
1091:
1092: }
1093:
1094: public void resetStatus() {
1095: setRowStatus(DataStoreBuffer.STATUS_NOT_MODIFIED);
1096: _bucketsModified = false;
1097: for (int i = 0; i < _columnStatus.length; i++)
1098: _columnStatus[i] = (byte) DataStoreBuffer.STATUS_NOT_MODIFIED;
1099: }
1100:
1101: public void setColumnStatus(int columnNo, int status) {
1102: if (columnNo >= _columnStatus.length) {
1103: byte[] temp = new byte[columnNo + 1];
1104: System.arraycopy(_columnStatus, 0, temp, 0,
1105: _columnStatus.length);
1106: _columnStatus = temp;
1107: }
1108:
1109: _columnStatus[columnNo] = (byte) status;
1110:
1111: }
1112:
1113: public void setRowStatus(int status) {
1114:
1115: if (_rowStatus == DataStoreBuffer.STATUS_NOT_MODIFIED
1116: && status == DataStoreBuffer.STATUS_MODIFIED) {
1117: if (_origData == null) {
1118: _origData = new Object[_currentData.length];
1119: for (int i = 0; i < _currentData.length; i++) {
1120: _origData[i] = cloneData(_currentData[i]);
1121: }
1122: }
1123: }
1124: _rowStatus = status;
1125: }
1126:
1127: public void setTempValue(int columnNo, String value,
1128: DSDataStoreDescriptor d) {
1129: if (columnNo < 0)
1130: return;
1131: if (value == null && _tempCount == 0)
1132: return;
1133: if (value == null && columnNo >= _tempData.length)
1134: return;
1135:
1136: if (_tempData == null)
1137: _tempData = new String[columnNo + 1];
1138: else if (columnNo >= _tempData.length) {
1139: String[] temp = new String[columnNo + 1];
1140: System.arraycopy(_tempData, 0, temp, 0, _tempData.length);
1141: _tempData = temp;
1142: }
1143: if (value == null && _tempData[columnNo] != null)
1144: _tempCount--;
1145: else if (value != null && _tempData[columnNo] == null)
1146: _tempCount++;
1147: _tempData[columnNo] = value;
1148: updateStatus(d.getColumn(columnNo), columnNo);
1149: }
1150:
1151: public String getTempValue(int columnNo) {
1152: if (_tempData == null)
1153: return null;
1154:
1155: if (columnNo < 0)
1156: return null;
1157:
1158: if (columnNo >= _tempData.length)
1159: return null;
1160:
1161: return _tempData[columnNo];
1162: }
1163:
1164: public void clearTempValue(int columnNo, DSDataStoreDescriptor desc) {
1165: setTempValue(columnNo, null, desc);
1166: }
1167:
1168: public void clearTempValues() {
1169: _tempCount = 0;
1170: _tempData = null;
1171: }
1172:
1173: public boolean hasTempValues() {
1174: return _tempCount > 0;
1175: }
1176:
1177: public void setValue(int columnNo, Object value,
1178: DSDataStoreDescriptor d) {
1179: if (columnNo < 0)
1180: return;
1181:
1182: if (columnNo >= _currentData.length) {
1183: Object[] temp = new Object[columnNo + 1];
1184: System.arraycopy(_currentData, 0, temp, 0,
1185: _currentData.length);
1186: _currentData = temp;
1187: }
1188:
1189: DSColumnDescriptor c = d.getColumn(columnNo);
1190: updateStatus(c, columnNo);
1191:
1192: if (value == null)
1193: value = d.getNullDefault(d.getColumn(columnNo).getType());
1194:
1195: _currentData[columnNo] = value;
1196: clearTempValue(columnNo, d);
1197:
1198: }
1199:
1200: private void updateStatus(DSColumnDescriptor c, int columnNo) {
1201: if (c.getTable() != null || c.getColumn() != null) {
1202: if (_rowStatus == DataStoreBuffer.STATUS_NOT_MODIFIED) {
1203: if (_origData == null) {
1204: _origData = new Object[_currentData.length];
1205: for (int i = 0; i < _currentData.length; i++) {
1206: _origData[i] = cloneData(_currentData[i]);
1207: }
1208: } else if (columnNo >= _origData.length) {
1209: Object[] temp = new Object[columnNo];
1210: System.arraycopy(_origData, 0, temp, 0,
1211: _origData.length);
1212: _origData = temp;
1213: for (int i = 0; i < _currentData.length; i++) {
1214: _origData[i] = cloneData(_currentData[i]);
1215: }
1216: }
1217: _rowStatus = DataStoreBuffer.STATUS_MODIFIED;
1218: } else if (_rowStatus == DataStoreBuffer.STATUS_NEW) {
1219: _rowStatus = DataStoreBuffer.STATUS_NEW_MODIFIED;
1220: }
1221: setColumnStatus(columnNo, DataStoreBuffer.STATUS_MODIFIED);
1222:
1223: if (c.isPrimaryKey())
1224: _pKeyMod = true;
1225: } else {
1226: _bucketsModified = true;
1227: if (_bean != null) {
1228: if (_rowStatus == DataStoreBuffer.STATUS_NEW)
1229: _rowStatus = DataStoreBuffer.STATUS_NEW_MODIFIED;
1230: else if (_rowStatus != DataStoreBuffer.STATUS_NEW_MODIFIED)
1231: _rowStatus = DataStoreBuffer.STATUS_MODIFIED;
1232: setColumnStatus(columnNo,
1233: DataStoreBuffer.STATUS_MODIFIED);
1234: }
1235: }
1236:
1237: }
1238:
1239: /**
1240: * Returns a string representation of the data in the row
1241: */
1242: public String toString() {
1243: StringBuffer sBuff = new StringBuffer("[");
1244: int compSize = _currentData.length;
1245:
1246: boolean commaFlag = false;
1247:
1248: for (int i = 0; i < compSize; i++) {
1249:
1250: if (commaFlag == true) {
1251: sBuff.append(",");
1252: }
1253:
1254: if (Util.isNull(_currentData[i])) {
1255: //break;
1256: sBuff.append("nullval");
1257: continue;
1258: }
1259:
1260: if (Util.isEmpty(_currentData[i].toString())) {
1261: sBuff.append("EMPTY_DATA");
1262: } else {
1263: sBuff.append(_currentData[i].toString());
1264: commaFlag = true;
1265:
1266: }
1267:
1268: }
1269: sBuff.append("]");
1270: return sBuff.toString();
1271:
1272: }
1273:
1274: public void copyTo(DSDataRow target,
1275: DSDataStoreDescriptor sourceDescriptor,
1276: DSDataStoreDescriptor targetDescriptor) {
1277: for (int i = 0; i < sourceDescriptor.getColumnCount(); i++) {
1278: DSColumnDescriptor sourceCol = sourceDescriptor
1279: .getColumn(i);
1280: for (int j = 0; j < targetDescriptor.getColumnCount(); j++) {
1281: DSColumnDescriptor targetCol = targetDescriptor
1282: .getColumn(j);
1283: if (sourceCol.getType() != targetCol.getType())
1284: continue;
1285:
1286: String sourceTable = sourceCol.getTable();
1287: String targetTable = targetCol.getTable();
1288: if (sourceTable == null && targetTable != null)
1289: continue;
1290: if (targetTable == null && sourceTable != null)
1291: continue;
1292: if (!sourceTable.equals(targetTable))
1293: continue;
1294:
1295: String sourceColName = sourceCol.getColumn();
1296: String targetColName = targetCol.getColumn();
1297:
1298: if (sourceColName == null && targetColName != null)
1299: continue;
1300: if (targetColName == null && sourceColName != null)
1301: continue;
1302: if (!sourceColName.equals(targetColName))
1303: continue;
1304:
1305: //table, column and datatype match so copy the data from the
1306: // source to the target
1307: Object o = getData(i);
1308: target.setValue(j, o, targetDescriptor);
1309:
1310: }
1311: }
1312: }
1313:
1314: protected Object[] getCurrentData() {
1315: return _currentData;
1316: }
1317: }
|