Annotation of java/classes/org/w3c/tools/jdbc/JdbcBeanSerializer.java, revision 1.6
1.1 bmahe 1: // JdbcBeanSerializer.java
1.6 ! bmahe 2: // $Id: JdbcBeanSerializer.java,v 1.5 2000/07/07 15:36:13 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.6 ! bmahe 28: * @version $Revision: 1.5 $
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:
1.6 ! bmahe 892: /**
! 893: * Called by the Garbage Collector.
! 894: */
1.5 bmahe 895: protected void finalize()
896: throws Throwable
897: {
898: // cleanup (static) cached properties
899: removeProperties(this.bean);
1.2 bmahe 900: }
901:
1.1 bmahe 902: public JdbcBeanSerializer(JdbcBeanInterface bean) {
1.2 bmahe 903: this.bean = bean;
1.1 bmahe 904: bean.addPropertyChangeListener(this);
905: }
906:
907: }
908:
909:
Webmaster