Annotation of java/classes/org/w3c/tools/jdbc/JdbcBeanSerializer.java, revision 1.5
1.1 bmahe 1: // JdbcBeanSerializer.java
1.5 ! bmahe 2: // $Id: JdbcBeanSerializer.java,v 1.4 2000/07/06 16:04:22 bmahe Exp $
1.1 bmahe 3: // (c) COPYRIGHT MIT, INRIA and Keio, 2000.
4: // Please first read the full copyright statement in file COPYRIGHT.html
5: package org.w3c.tools.jdbc;
6:
7: import java.beans.BeanInfo;
8: import java.beans.IntrospectionException;
9: import java.beans.Introspector;
10: import java.beans.PropertyChangeListener;
11: import java.beans.PropertyChangeEvent;
12: import java.beans.PropertyDescriptor;
13:
14: import java.lang.reflect.Method;
15: import java.lang.reflect.InvocationTargetException;
16:
17: import java.sql.ResultSet;
1.2 bmahe 18: import java.sql.SQLException;
1.1 bmahe 19:
1.5 ! bmahe 20: import java.util.Enumeration;
1.1 bmahe 21: import java.util.Hashtable;
1.2 bmahe 22: import java.util.Properties;
1.1 bmahe 23: import java.util.Vector;
24:
1.2 bmahe 25: import org.w3c.tools.jdbc.JdbcServer;
26:
1.1 bmahe 27: /**
1.5 ! bmahe 28: * @version $Revision: 1.4 $
1.1 bmahe 29: * @author Beno�t Mah� (bmahe@w3.org)
30: */
31: public class JdbcBeanSerializer implements PropertyChangeListener {
32:
33: /**
1.5 ! bmahe 34: * Bean modified?
! 35: */
! 36: protected boolean modified = false;
! 37:
! 38: /**
1.1 bmahe 39: * Our bean.
40: */
41: protected JdbcBeanInterface bean = null;
42:
43: /**
44: * The associated JdbcBean
45: */
46: protected JdbcBeanInterface beans[] = null;
47:
48: /**
49: * The ResultSet
50: */
51: protected ResultSet result = null;
52:
53: /**
1.2 bmahe 54: * The Foreign keys <(class,class), String[]>
55: */
56: protected static Hashtable foreignKeys = new Hashtable();
57:
58: public static void registerForeignKeys(Class beanclass1, Class beanclass2)
59: {
60: Integer key = new Integer(beanclass1.hashCode() &
61: beanclass2.hashCode());
1.5 ! bmahe 62: if (! foreignKeys.containsKey(key)) {
1.2 bmahe 63: foreignKeys.put(key, computeForeignKeys(beanclass1, beanclass2));
64: }
65: }
66:
67: public static String[] getForeignKeys(Class beanclass1,
68: Class beanclass2)
69: {
70: Integer key = new Integer(beanclass1.hashCode() &
71: beanclass2.hashCode());
72: String keys[] = (String[]) foreignKeys.get(key);
73: if (keys == null) {
74: keys = computeForeignKeys(beanclass1, beanclass2);
75: foreignKeys.put(key, keys);
76: }
77: return keys;
78: }
79:
80: protected static String[] computeForeignKeys(Class beanclass1,
81: Class beanclass2)
82: {
83: try {
84: BeanInfo bi1 = Introspector.getBeanInfo(beanclass1);
85: PropertyDescriptor pds1[] = bi1.getPropertyDescriptors();
86:
87: BeanInfo bi2 = Introspector.getBeanInfo(beanclass2);
88: PropertyDescriptor pds2[] = bi2.getPropertyDescriptors();
89:
90: Vector foreign = new Vector();
91:
92: for(int cpt1 = 0 ; cpt1 < pds1.length ; cpt1++) {
93: PropertyDescriptor pd1 = pds1[cpt1];
94: for (int cpt2 = 0 ; cpt2 < pds2.length ; cpt2++) {
95: PropertyDescriptor pd2 = pds2[cpt2];
96: if ((! pd2.isHidden())
97: && (! pd1.isHidden())
98: && (pd1.getName().equals(pd2.getName()))) {
99: foreign.addElement(pd1.getName());
100: }
101: }
102: }
103: String keys[] = new String[foreign.size()];
104: foreign.copyInto(keys);
105: return keys;
106: } catch (IntrospectionException ex) {
107: return new String[0];
108: }
109: }
110:
111: /**
1.1 bmahe 112: * The modified properties
113: */
1.2 bmahe 114: protected static Hashtable properties = new Hashtable();
115:
116: protected static String getId(JdbcBeanInterface bean, String property) {
117: StringBuffer buffer =
118: new StringBuffer(String.valueOf(bean.hashCode()));
119: buffer.append(".").append(property);
120: return buffer.toString();
121: }
1.1 bmahe 122:
1.2 bmahe 123: protected static void addProperty(JdbcBeanInterface bean,
124: String property,
125: Object value)
1.1 bmahe 126: {
1.2 bmahe 127: String id = getId(bean, property);
128: if (id != null) {
129: properties.put(id, value);
1.1 bmahe 130: }
131: }
132:
1.2 bmahe 133: protected static Object getProperty(JdbcBeanInterface bean,
134: PropertyDescriptor pd)
1.1 bmahe 135: {
1.2 bmahe 136: String id = getId(bean, pd.getName());
137: if (id != null) {
138: return properties.get(id);
1.1 bmahe 139: }
1.2 bmahe 140: return null;
1.1 bmahe 141: }
142:
1.5 ! bmahe 143: protected static void removeProperties(JdbcBeanInterface bean) {
! 144: Enumeration keys = properties.keys();
! 145: StringBuffer buffer =
! 146: new StringBuffer(String.valueOf(bean.hashCode()));
! 147: buffer.append(".");
! 148: String beankey = buffer.toString();
! 149: while (keys.hasMoreElements()) {
! 150: String key = (String)keys.nextElement();
! 151: if (key.startsWith(beankey)) {
! 152: properties.remove(key);
! 153: }
! 154: }
! 155: }
! 156:
! 157: protected void markModified(boolean modified) {
! 158: this.modified = modified;
! 159: }
! 160:
! 161: protected boolean isModified() {
! 162: return modified;
! 163: }
! 164:
1.1 bmahe 165: /**
166: * PropertyChangeListener implementation: This method gets called when
167: * a bound property is changed.
168: * @param evt A PropertyChangeEvent object describing the event source
169: * and the property that has changed.
170: */
171: public void propertyChange(PropertyChangeEvent evt) {
172: Object source = evt.getSource();
1.5 ! bmahe 173: String name = evt.getPropertyName();
! 174: Object value = evt.getNewValue();
1.2 bmahe 175: if (source == bean) {
1.5 ! bmahe 176: if (value instanceof JdbcBeanInterface) {
! 177: registerForeignKeys(bean.getClass(), value.getClass());
1.4 bmahe 178: // delete cached bean descriptors
179: this.beans = null;
1.5 ! bmahe 180: // update listeners
! 181: JdbcBeanInterface oldbean =
! 182: (JdbcBeanInterface)evt.getOldValue();
! 183: JdbcBeanInterface newbean = (JdbcBeanInterface)value;
! 184: if (oldbean != null) {
! 185: removeProperties(oldbean);
! 186: oldbean.removePropertyChangeListener(this);
! 187: }
! 188: newbean.addPropertyChangeListener(this);
! 189: } else {
1.2 bmahe 190: JdbcBeanInterface bean = (JdbcBeanInterface)source;
191: addProperty(bean, name, evt.getNewValue());
1.5 ! bmahe 192: markModified(true);
! 193: }
! 194: } else {
! 195: markModified(true);
1.1 bmahe 196: }
197: }
198:
1.2 bmahe 199: /**
200: * Get the raw value of the given property, split the operator and
201: * the value and convert the raw value into a SQL value.<p>
202: * ie "~A.*" will become { " ~ " , "'A.*'" }
203: * @param bean the property holder
204: * @param pd the property descriptor
205: */
206: protected String[] getSQLOperatorNValue(JdbcBeanInterface bean,
207: PropertyDescriptor pd)
1.1 bmahe 208: {
209: Class type = pd.getPropertyType();
210: Method m = pd.getReadMethod();
211: if (m != null) { // are we authozired to read it?
212: Object value = getProperty(bean, pd); // use the cache
213: if (value == null) {
214: return null;
215: }
216: if (type == String.class) {
1.2 bmahe 217: String split[] = getSQLOperator((String)value);
1.1 bmahe 218: StringBuffer buffer = new StringBuffer("'");
1.2 bmahe 219: buffer.append(SQL.encode(split[1])).append("'");
220: split[1] = buffer.toString();
221: return split;
222: } else { // operator always '='
223: String split[] = { " = ", String.valueOf(value) };
224: return split;
1.1 bmahe 225: }
226: }
227: return null;
228: }
229:
230: /**
1.5 ! bmahe 231: * Get the SQL value of the given property.
! 232: * @param bean the property holder
! 233: * @param pd the property descriptor
! 234: */
! 235: protected String getSQLValue(JdbcBeanInterface bean,
! 236: PropertyDescriptor pd)
! 237: {
! 238: Class type = pd.getPropertyType();
! 239: Method m = pd.getReadMethod();
! 240: if (m != null) { // are we authozired to read it?
! 241: Object value = getProperty(bean, pd); // use the cache
! 242: if (value == null) {
! 243: return null;
! 244: }
! 245: if (type == String.class) { // String => quote
! 246: String split[] = getSQLOperator((String)value);
! 247: StringBuffer buffer = new StringBuffer("'");
! 248: buffer.append(SQL.encode((String)value)).append("'");
! 249: return buffer.toString();
! 250: } else { // not a String => no quote
! 251: return String.valueOf(value);
! 252: }
! 253: }
! 254: return null;
! 255: }
! 256:
! 257: /**
1.2 bmahe 258: * Split the SQL operator and the value, (default operator is '=')
259: * example:<br>
260: * "~*.*toto.*" will become { "~*", ".*toto.*" }<br>
261: * but "\~*.*toto.*" will become { "=", "~*.*toto.*" }
262: * <p>possible operators are:
263: * <table border=0>
264: * <tr><td> < </td><td>Less than?</td></tr>
265: * <tr><td> <= </td><td>Less than or equals?</td></tr>
266: * <tr><td> <> </td><td>Not equal?</td></tr>
267: * <tr><td> = </td><td>Equals?</td></tr>
268: * <tr><td> > </td><td>Greater than?</td></tr>
269: * <tr><td> >= </td><td>Greater than or equals?</td></tr>
270: * <tr><td> ~~ </td><td>LIKE</td></tr>
271: * <tr><td> !~~ </td><td>NOT LIKE</td></tr>
272: * <tr><td> ~ </td><td>Match (regex), case sensitive</td></tr>
273: * <tr><td> ~* </td><td>Match (regex), case insensitive</td></tr>
274: * <tr><td> !~ </td><td>Does not match (regex), case sensitive </td></tr>
275: * <tr><td> !~* </td><td>Does not match (regex), case insensitive</td></tr>
276: * </table>
277: */
278: protected String[] getSQLOperator(String value) {
279: String result[] = new String[2];
280: char c = value.charAt(0);
281: switch (c)
282: {
283: case '~':
284: c = value.charAt(1);
285: if (c == '*') { // ~*
286: result[0] = " ~* ";
287: result[1] = value.substring(2);
288: } else if (c == '~') { // ~~
289: result[0] = " ~~ ";
290: result[1] = value.substring(2);
291: } else { // ~
292: result[0] = " ~ ";
293: result[1] = value.substring(1);
294: }
295: break;
296: case '<':
297: c = value.charAt(1);
298: if (c == '=') { // <=
299: result[0] = " <= ";
300: result[1] = value.substring(2);
301: } else if (c == '>') { // <>
302: result[0] = " <> ";
303: result[1] = value.substring(2);
304: } else { // <
305: result[0] = " < ";
306: result[1] = value.substring(1);
307: }
308: break;
309: case '>':
310: c = value.charAt(1);
311: if (c == '=') { // >=
312: result[0] = " >= ";
313: result[1] = value.substring(2);
314: } else { // >
315: result[0] = " > ";
316: result[1] = value.substring(1);
317: }
318: break;
319: case '!':
320: if (c == '~') {
321: c = value.charAt(2);
322: if (c == '~') { // !~~
323: result[0] = " !~~ ";
324: result[1] = value.substring(3);
325: } else if (c == '*') { // !~*
326: result[0] = " !~* ";
327: result[1] = value.substring(3);
328: } else { // !~
329: result[0] = " !~ ";
330: result[1] = value.substring(2);
331: }
332: break;
333: }
334: case '\\':
335: value = value.substring(1);
336: case '=': // =
337: default:
338: result[0] = " = ";
339: result[1] = value;
340: }
341: return result;
342: }
343:
344: /**
1.1 bmahe 345: * @param name
346: * @param value
347: * @param buf
348: */
1.5 ! bmahe 349: private void append(String name,
! 350: String operator,
! 351: String value,
! 352: String separator,
! 353: StringBuffer buf)
! 354: {
! 355: if (buf.length() > 0) {
! 356: buf.append(separator).append(" ");
! 357: }
! 358: buf.append(name).append(operator).append(value).append(" ");
! 359: }
! 360:
! 361: /**
! 362: * @param name
! 363: * @param value
! 364: * @param namesbuffer
! 365: * @param valuesbuffer
! 366: */
! 367: private void appendInsert(String name,
1.2 bmahe 368: String value,
1.5 ! bmahe 369: StringBuffer namesbuffer,
! 370: StringBuffer valuesbuffer)
1.1 bmahe 371: {
1.5 ! bmahe 372: if (namesbuffer.length() > 0) {
! 373: namesbuffer.append(", ").append(name);
! 374: valuesbuffer.append(", ").append(value);
! 375: } else {
! 376: namesbuffer.append("(").append(name);
! 377: valuesbuffer.append("(").append(value);
1.1 bmahe 378: }
379: }
380:
381: protected JdbcBeanInterface[] getJdbcBeans() {
382: if (beans != null) {
383: return beans;
384: }
385: try {
386: BeanInfo info = Introspector.getBeanInfo(bean.getClass());
387: Vector vb = new Vector();
388: PropertyDescriptor pds[] = info.getPropertyDescriptors();
389: for (int i = 0 ; i < pds.length ; i++) {
390: PropertyDescriptor pd = pds[i];
1.5 ! bmahe 391: if ((! pd.isHidden()) &&
! 392: (JdbcBeanUtil.isJdbcBean(pd.getPropertyType()))) {
1.1 bmahe 393: Method m = pd.getReadMethod();
394: if (m != null) {
395: Object value = m.invoke(bean, null);
396: if (value != null) {
397: vb.addElement(value);
398: }
399: }
400: }
401: }
402: beans = new JdbcBeanInterface[vb.size()];
403: vb.copyInto(beans);
404: return beans;
405: } catch (IntrospectionException ex) {
406: return null;
407: } catch (IllegalAccessException ex) {
408: return null;
409: } catch (InvocationTargetException ex) {
410: return null;
411: }
412: }
413:
414: protected void appendForeignKeys(StringBuffer tables,
415: StringBuffer buffer,
416: PropertyDescriptor pds[])
1.2 bmahe 417: throws IntrospectionException //FIXME
1.1 bmahe 418: {
419: JdbcBeanInterface jbeans[] = getJdbcBeans();
420: if (jbeans != null) { // FORGEIGN KEYs
421: for (int i = 0 ; i < jbeans.length ; i++) {
422: JdbcBeanInterface jbean = jbeans[i];
1.2 bmahe 423: // foreign keys
424: String keys[] = getForeignKeys(jbean.getClass(),
425: bean.getClass());
426: for (int f = 0 ; f < keys.length ; f++) {
427: String key = keys[f];
1.5 ! bmahe 428: append(jbean.getJdbcTable()+"."+key,
! 429: " = ",
! 430: bean.getJdbcTable()+"."+key,
! 431: "AND",
! 432: buffer);
1.2 bmahe 433: }
434: // value now
1.1 bmahe 435: BeanInfo bi = Introspector.getBeanInfo(jbean.getClass());
436: PropertyDescriptor jpds[] = bi.getPropertyDescriptors();
437: for (int jpd_cpt = 0 ; jpd_cpt < jpds.length ; jpd_cpt++) {
438: PropertyDescriptor jpd = jpds[jpd_cpt];
439: if (jpd.isHidden()) {
440: continue;
441: }
442: String jname = jpd.getName();
1.2 bmahe 443: String split[] = getSQLOperatorNValue(jbean, jpd);
444: if (split != null) {
1.5 ! bmahe 445: append(jbean.getJdbcTable()+"."+jname,
! 446: split[0],
! 447: split[1],
! 448: "AND",
! 449: buffer);
1.1 bmahe 450: }
1.2 bmahe 451: }
452: if (tables.length() > 0) {
453: tables.append(", "+jbean.getJdbcTable());
454: } else {
455: tables.append(jbean.getJdbcTable());
1.1 bmahe 456: }
457: }
458: }
459: }
460:
1.5 ! bmahe 461: protected String computeSQLSelect(String orderby[], boolean all) {
1.1 bmahe 462: try {
463: BeanInfo info = Introspector.getBeanInfo(bean.getClass());
464: StringBuffer buffer = new StringBuffer();
465: String table = bean.getJdbcTable();
466: StringBuffer tables = new StringBuffer(table);
467: PropertyDescriptor pds[] = info.getPropertyDescriptors();
1.5 ! bmahe 468: if (all) {
! 469: // FOREIGN KEYs
! 470: appendForeignKeys(tables, buffer, pds);
! 471: }
1.1 bmahe 472: // known values
473: for (int i = 0 ; i < pds.length ; i++) {
474: PropertyDescriptor pd = pds[i];
475: if (! pd.isHidden()) {
1.2 bmahe 476: String split[] = getSQLOperatorNValue(bean, pd);
477: if (split != null) {
1.5 ! bmahe 478: append(table+"."+pd.getName(),
! 479: split[0],
! 480: split[1],
! 481: "AND",
! 482: buffer);
1.1 bmahe 483: }
484: }
485: }
486: // build SQL request
487: if (buffer.length() > 0) {
488: tables.append(" WHERE ");
489: tables.insert(0, "SELECT * FROM ");
490: tables.append(buffer.toString());
1.2 bmahe 491: buffer = tables;
1.1 bmahe 492: } else {
1.2 bmahe 493: buffer = new StringBuffer("SELECT * FROM ");
494: buffer.append(table);
495: }
496: if (orderby != null) {
497: buffer.append(" ORDER BY ");
498: for (int i = 0 ; i < orderby.length ; i++) {
499: if (i != 0) {
500: buffer.append(", ");
501: }
502: buffer.append(orderby[i]);
503: }
1.1 bmahe 504: }
1.2 bmahe 505: return buffer.toString();
1.1 bmahe 506: } catch (IntrospectionException ex) {
507: return null;
508: }
509: }
510:
1.5 ! bmahe 511: /**
! 512: * Compute the SQL request necessary to update the Database.
! 513: * @return a String
! 514: */
! 515: protected String computeSQLInsert() {
! 516: try {
! 517: BeanInfo info = Introspector.getBeanInfo(bean.getClass());
! 518: PropertyDescriptor pds[] = info.getPropertyDescriptors();
! 519: StringBuffer namesbuffer = new StringBuffer();
! 520: StringBuffer valuesbuffer = new StringBuffer();
! 521: for (int i = 0 ; i < pds.length ; i++) {
! 522: PropertyDescriptor pd = pds[i];
! 523: if (! pd.isHidden()) {
! 524: String value = getSQLValue(bean, pd);
! 525: if (value != null) {
! 526: appendInsert(pd.getName(),
! 527: value,
! 528: namesbuffer,
! 529: valuesbuffer);
! 530: }
! 531: }
! 532: }
! 533: if (namesbuffer.length() > 0) {
! 534: StringBuffer request = new StringBuffer("INSERT INTO ");
! 535: request.append(bean.getJdbcTable()).append(" ");
! 536: request.append(namesbuffer).append(") ");
! 537: request.append("VALUES ").append(valuesbuffer).append(")");
! 538: return request.toString();
! 539: } else {
! 540: return null;
! 541: }
! 542: } catch (IntrospectionException ex) {
! 543: return null;
! 544: }
! 545: }
! 546:
! 547: protected String computeSQLDelete() {
! 548: try {
! 549: BeanInfo info = Introspector.getBeanInfo(bean.getClass());
! 550: StringBuffer buffer = new StringBuffer();
! 551: StringBuffer table = new StringBuffer(bean.getJdbcTable());
! 552: PropertyDescriptor pds[] = info.getPropertyDescriptors();
! 553: // known values
! 554: for (int i = 0 ; i < pds.length ; i++) {
! 555: PropertyDescriptor pd = pds[i];
! 556: if (! pd.isHidden()) {
! 557: String split[] = getSQLOperatorNValue(bean, pd);
! 558: if (split != null) {
! 559: append(pd.getName(), split[0], split[1],"AND", buffer);
! 560: }
! 561: }
! 562: }
! 563: // build SQL request
! 564: if (buffer.length() > 0) {
! 565: table.append(" WHERE ");
! 566: table.insert(0, "DELETE FROM ");
! 567: table.append(buffer.toString());
! 568: buffer = table;
! 569: } else {
! 570: return null;
! 571: }
! 572: return buffer.toString();
! 573: } catch (IntrospectionException ex) {
! 574: return null;
! 575: }
! 576: }
! 577:
! 578: protected String computeSQLUpdate(String primarykeys[]) {
! 579: try {
! 580: BeanInfo info = Introspector.getBeanInfo(bean.getClass());
! 581: StringBuffer buffer = new StringBuffer();
! 582: StringBuffer pkbuffer = new StringBuffer();
! 583: StringBuffer table = new StringBuffer(bean.getJdbcTable());
! 584: PropertyDescriptor pds[] = info.getPropertyDescriptors();
! 585: // known values
! 586: for (int i = 0 ; i < pds.length ; i++) {
! 587: PropertyDescriptor pd = pds[i];
! 588: if (! pd.isHidden()) {
! 589: String name = pd.getName();
! 590: String split[] = getSQLOperatorNValue(bean, pd);
! 591: if (split != null) {
! 592: if (JdbcBeanUtil.isIn(name, primarykeys)) {
! 593: append(name, split[0], split[1], "AND", pkbuffer);
! 594: } else {
! 595: append(name, split[0], split[1], ",", buffer);
! 596: }
! 597: }
! 598: }
! 599: }
! 600: // build SQL request
! 601: if (buffer.length() > 0) {
! 602: table.append(" SET ");
! 603: table.insert(0, "UPDATE ");
! 604: table.append(buffer.toString());
! 605: table.append(" WHERE ");
! 606: table.append(pkbuffer.toString());
! 607: buffer = table;
! 608: } else {
! 609: return null;
! 610: }
! 611: return buffer.toString();
! 612: } catch (IntrospectionException ex) {
! 613: return null;
! 614: }
! 615: }
! 616:
1.2 bmahe 617: protected JdbcServer getJdbcServer() {
618: Properties props = new Properties();
619: Jdbc.setMaxConn(props, bean.getMaxConn());
620: return JdbcServer.getServer(bean.getJdbcURI(),
621: bean.getJdbcUser(),
622: bean.getJdbcPassword(),
623: bean.getJdbcDriver(),
624: props);
625: }
626:
1.5 ! bmahe 627: protected void executeSQLQuery(String sqlrequest)
! 628: throws SQLException
! 629: {
! 630: result = getJdbcServer().runQuery(sqlrequest, false);
! 631: }
! 632:
! 633: protected int executeSQLUpdate(String sqlrequest)
1.2 bmahe 634: throws SQLException
635: {
1.5 ! bmahe 636: return getJdbcServer().runUpdate(sqlrequest, false);
1.2 bmahe 637: }
638:
639: public void select() {
1.5 ! bmahe 640: select((String[])null, true);
! 641: }
! 642:
! 643: public void select(boolean all) {
! 644: select((String[])null, all);
1.2 bmahe 645: }
646:
647: public void select(String orderby) {
648: String array[] = { orderby };
1.5 ! bmahe 649: select(array, true);
! 650: }
! 651:
! 652: public void select(String orderby, boolean all) {
! 653: String array[] = { orderby };
! 654: select(array, all);
1.2 bmahe 655: }
656:
657: public void select(String orderby[]) {
1.5 ! bmahe 658: select(orderby, true);
! 659: }
! 660:
! 661: public void select(String orderby[], boolean all) {
! 662: String sql = computeSQLSelect(orderby, all);
! 663: try {
! 664: executeSQLQuery(sql);
! 665: } catch (SQLException ex) {
! 666: System.out.println("SQL STATE: "+ex.getSQLState());
! 667: ex.printStackTrace();
! 668: result = null;
! 669: }
! 670: }
! 671:
! 672: public boolean insert() {
! 673: if (! isModified()) { // nothing new to insert
! 674: return false;
! 675: }
! 676: JdbcBeanInterface beans[] = getJdbcBeans();
! 677: for (int i = 0 ; i < beans.length ; i++) {
! 678: JdbcBeanInterface jbean = beans[i];
! 679: JdbcBeanSerializer ser = jbean.getSerializer();
! 680: if (ser.isModified()) {
! 681: // insert associated bean
! 682: ser.insert();
! 683: // update our foreign key
! 684: updateForeignKeys(jbean);
! 685: }
! 686: }
! 687: if (! bean.getReadOnly()) {
! 688: // ok insert ourself now
! 689: String request = computeSQLInsert();
! 690: try {
! 691: // insert (could fail without being critical)
! 692: // ie: when the row is already in the table
! 693: executeSQLUpdate(request);
! 694: } catch (SQLException ex) {
! 695: System.err.println(ex.getMessage());
! 696: }
! 697: }
! 698: // update value automatically generated by the DB (index, ...)
! 699: select(false);
! 700: try {
! 701: if (result == null) {
! 702: return false;
! 703: }
! 704: if (result.first()) {
! 705: return updateProperties(result, false);
! 706: } else {
! 707: return false;
! 708: }
! 709: } catch (SQLException ex) {
! 710: ex.printStackTrace();
! 711: return false;
! 712: }
! 713: }
! 714:
! 715: public boolean update(String primarykey) {
! 716: String array[] = { primarykey };
! 717: return update(array);
! 718: }
! 719:
! 720: public boolean update(String primarykeys[]) {
! 721: if (! isModified()) { // noting to update
! 722: return false;
! 723: }
! 724: JdbcBeanInterface beans[] = getJdbcBeans();
! 725: for (int i = 0 ; i < beans.length ; i++) {
! 726: JdbcBeanInterface jbean = beans[i];
! 727: JdbcBeanSerializer ser = jbean.getSerializer();
! 728: if (ser.isModified()) {
! 729: // insert associated bean
! 730: ser.insert();
! 731: // update our foreign key
! 732: updateForeignKeys(jbean);
! 733: }
! 734: }
! 735: String sql = computeSQLUpdate(primarykeys);
! 736: try {
! 737: int nb = executeSQLUpdate(sql);
! 738: return (nb > 0);
! 739: } catch (SQLException ex) {
! 740: ex.printStackTrace();
! 741: }
! 742: return false;
! 743: }
! 744:
! 745: public boolean delete() {
! 746: if (bean.getReadOnly()) {
! 747: return false;
! 748: }
! 749: String sql = computeSQLDelete();
1.2 bmahe 750: try {
1.5 ! bmahe 751: int nb = executeSQLUpdate(sql);
! 752: System.err.println("NB : "+nb);
! 753: return (nb > 0);
1.2 bmahe 754: } catch (SQLException ex) {
1.5 ! bmahe 755: System.out.println("SQL STATE: "+ex.getSQLState());
1.2 bmahe 756: ex.printStackTrace();
757: result = null;
1.5 ! bmahe 758: return false; // FIXME VERIFY
1.2 bmahe 759: }
760: }
761:
762: /**
763: * Go to the first row
764: * @return false if there is no first row
765: */
766: public boolean first() {
767: try {
768: if (result == null) {
769: return false;
770: }
771: if (result.first()) {
1.5 ! bmahe 772: return updateProperties(result);
1.2 bmahe 773: }
774: } catch (SQLException ex) { }
775: return false;
776: }
777:
778: /**
779: * Update our bean with the value of the next row
780: * @return false if there is no more row
781: */
782: public boolean next() {
783: try {
784: if (result == null) {
785: return false;
786: }
787: if (result.next()) {
1.5 ! bmahe 788: return updateProperties(result);
1.2 bmahe 789: }
790: } catch (SQLException ex) { }
791: return false;
792: }
793:
1.5 ! bmahe 794: /**
! 795: * Clean cached properties (relative to our bean)
! 796: */
! 797: public void clean() {
! 798: removeProperties(bean);
! 799: }
! 800:
! 801: protected boolean updateProperties(ResultSet result) {
! 802: return updateProperties(result, true);
! 803: }
! 804:
! 805: protected boolean updateProperties(ResultSet result, boolean all) {
1.2 bmahe 806: try {
807: BeanInfo info = Introspector.getBeanInfo(bean.getClass());
808: PropertyDescriptor pds[] = info.getPropertyDescriptors();
809: for (int i = 0 ; i < pds.length ; i++) {
810: PropertyDescriptor pd = pds[i];
811: if (! pd.isHidden()) {
812: try {
813: Object value = result.getObject(pd.getName());
814: Class propertyclass = pd.getPropertyType();
815: value = SQL.getMatchingValue(propertyclass, value);
816: if (value != null) {
817: Object values[] = { value };
818: Method setter = pd.getWriteMethod();
819: if (setter != null) {
820: try {
821: setter.invoke(bean, values);
822: } catch (IllegalAccessException ex) {
823: ex.printStackTrace();
824: // nothing to do
825: } catch (InvocationTargetException ex) {
826: ex.printStackTrace();
827: // still nothing to do
828: } catch (IllegalArgumentException ex) {
829: ex.printStackTrace();
830: // nothing to do
831: }
832: }
833: }
834: } catch (SQLException ex) { // not found
835: // nothing to do
836: }
837: }
838: }
1.5 ! bmahe 839: if (all) {
! 840: // update the associated beans
! 841: JdbcBeanInterface beans[] = getJdbcBeans();
! 842: for (int i = 0 ; i < beans.length ; i++) {
! 843: beans[i].getSerializer().updateProperties(result);
! 844: }
1.2 bmahe 845: }
1.5 ! bmahe 846: markModified(false);
1.2 bmahe 847: return true;
848: } catch (IntrospectionException ex) {
849: return false;
850: }
1.5 ! bmahe 851: }
! 852:
! 853: protected PropertyDescriptor getPropertyDescriptor(String property) {
! 854: try {
! 855: BeanInfo bi = Introspector.getBeanInfo(bean.getClass());
! 856: PropertyDescriptor pds[] = bi.getPropertyDescriptors();
! 857: for (int i = 0 ; i < pds.length ; i++) {
! 858: PropertyDescriptor pd = pds[i];
! 859: if (pd.getName().equals(property)) {
! 860: return pd;
! 861: }
! 862: }
! 863: return null;
! 864: } catch (IntrospectionException ex) {
! 865: return null;
! 866: }
! 867: }
! 868:
! 869: protected void updateForeignKeys(JdbcBeanInterface jbean) {
! 870: String keys[] = getForeignKeys(jbean.getClass(), bean.getClass());
! 871: JdbcBeanSerializer ser = jbean.getSerializer();
! 872: for (int i = 0 ; i < keys.length ; i++) {
! 873: try {
! 874: String key = keys[i];
! 875: PropertyDescriptor wkeypd = getPropertyDescriptor(key);
! 876: PropertyDescriptor rkeypd = ser.getPropertyDescriptor(key);
! 877: Method reader = rkeypd.getReadMethod();
! 878: Method writer = wkeypd.getWriteMethod();
! 879: Object value = reader.invoke(jbean, null);
! 880: if (value != null) {
! 881: Object array[] = { value };
! 882: writer.invoke(bean, array);
! 883: }
! 884: } catch (IllegalAccessException ex) {
! 885: ex.printStackTrace();
! 886: } catch (InvocationTargetException ex) {
! 887: ex.printStackTrace();
! 888: }
! 889: }
! 890: }
! 891:
! 892: protected void finalize()
! 893: throws Throwable
! 894: {
! 895: // cleanup (static) cached properties
! 896: removeProperties(this.bean);
1.2 bmahe 897: }
898:
1.1 bmahe 899: public JdbcBeanSerializer(JdbcBeanInterface bean) {
1.2 bmahe 900: this.bean = bean;
1.1 bmahe 901: bean.addPropertyChangeListener(this);
902: }
903:
904: }
905:
906:
Webmaster