Annotation of java/classes/org/w3c/tools/jdbc/JdbcBeanSerializer.java, revision 1.16

1.1       bmahe       1: // JdbcBeanSerializer.java
1.16    ! bmahe       2: // $Id: JdbcBeanSerializer.java,v 1.15 2000/09/12 13:19:50 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;
1.9       bmahe       8: import java.beans.Beans;
1.1       bmahe       9: import java.beans.IntrospectionException;
                     10: import java.beans.Introspector;
                     11: import java.beans.PropertyChangeListener;
                     12: import java.beans.PropertyChangeEvent;
                     13: import java.beans.PropertyDescriptor;
                     14: 
1.9       bmahe      15: import java.io.IOException;
                     16: 
1.1       bmahe      17: import java.lang.reflect.Method;
                     18: import java.lang.reflect.InvocationTargetException;
                     19: 
                     20: import java.sql.ResultSet;
1.7       bmahe      21: import java.sql.ResultSetMetaData;
1.2       bmahe      22: import java.sql.SQLException;
1.1       bmahe      23: 
1.5       bmahe      24: import java.util.Enumeration;
1.1       bmahe      25: import java.util.Hashtable;
1.2       bmahe      26: import java.util.Properties;
1.1       bmahe      27: import java.util.Vector;
                     28: 
                     29: /**
1.13      bmahe      30:  * Read <a href="http://www.w3.org/Jigsaw/Doc/Programmer/jspdb.html">http://www.w3.org/Jigsaw/Doc/Programmer/jspdb.html</a> 
                     31:  * to know how to use this class.
1.16    ! bmahe      32:  * @version $Revision: 1.15 $
1.1       bmahe      33:  * @author  Beno�t Mah� (bmahe@w3.org)
                     34:  */
                     35: public class JdbcBeanSerializer implements PropertyChangeListener {
1.12      ylafon     36: 
1.1       bmahe      37:     /**
1.5       bmahe      38:      * Bean modified?
                     39:      */
1.13      bmahe      40:     private boolean modified = false;
1.5       bmahe      41: 
                     42:     /**
1.1       bmahe      43:      * Our bean.
                     44:      */
                     45:     protected JdbcBeanInterface bean = null;
                     46: 
                     47:     /**
                     48:      * The associated JdbcBean
                     49:      */
1.13      bmahe      50:     private JdbcBeanInterface beans[] = null;
1.1       bmahe      51: 
                     52:     /**
1.9       bmahe      53:      * INTERSECT, UNION, EXCEPT.
                     54:      */
                     55:     protected final static int NOTHING   = -1;
                     56:     protected final static int INTERSECT = 10;
                     57:     protected final static int UNION     = 20;
                     58:     protected final static int EXCEPT    = 30;
                     59: 
                     60:     protected int priority[] = { NOTHING, NOTHING, NOTHING };
                     61: 
                     62:     protected JdbcBeanSerializer intersect_serializer = null;
                     63:     protected JdbcBeanSerializer union_serializer     = null;
                     64:     protected JdbcBeanSerializer except_serializer    = null;
                     65: 
                     66:     /**
1.1       bmahe      67:      * The ResultSet
                     68:      */
                     69:     protected ResultSet result = null;
                     70: 
                     71:     /**
1.7       bmahe      72:      * The tables/bean used to generate the SQL request (in the correct
                     73:      * order)
                     74:      */
1.13      bmahe      75:     private Vector beantables = null;
1.7       bmahe      76: 
                     77:     /**
1.2       bmahe      78:      * The Foreign keys <(class,class), String[]>
                     79:      */
1.13      bmahe      80:     private static Hashtable foreignKeys = new Hashtable();
1.2       bmahe      81: 
1.13      bmahe      82:     private void registerForeignKeys(Class beanclass1, 
                     83:                                     Class beanclass2)
1.2       bmahe      84:     {
                     85:        Integer key = new Integer(beanclass1.hashCode() & 
                     86:                                  beanclass2.hashCode());
1.5       bmahe      87:        if (! foreignKeys.containsKey(key)) {
1.2       bmahe      88:            foreignKeys.put(key, computeForeignKeys(beanclass1, beanclass2));
                     89:        }
                     90:     }
                     91: 
1.13      bmahe      92:     private String[] getForeignKeys(Class beanclass1,
                     93:                                    Class beanclass2)
1.2       bmahe      94:     {
                     95:        Integer key = new Integer(beanclass1.hashCode() & 
                     96:                                  beanclass2.hashCode());
                     97:        String keys[] = (String[]) foreignKeys.get(key);
                     98:        if (keys == null) {
                     99:            keys = computeForeignKeys(beanclass1, beanclass2);
                    100:            foreignKeys.put(key, keys);
                    101:        }
                    102:        return keys;
                    103:     }
                    104: 
1.13      bmahe     105:     private String[] computeForeignKeys(Class beanclass1,
                    106:                                        Class beanclass2) 
1.2       bmahe     107:     {
                    108:        try {
                    109:            BeanInfo           bi1    = Introspector.getBeanInfo(beanclass1);
                    110:            PropertyDescriptor pds1[] = bi1.getPropertyDescriptors();
                    111: 
                    112:            BeanInfo           bi2    = Introspector.getBeanInfo(beanclass2);
                    113:            PropertyDescriptor pds2[] = bi2.getPropertyDescriptors();
                    114:        
                    115:            Vector foreign = new Vector();
                    116:            
                    117:            for(int cpt1 = 0 ; cpt1 < pds1.length ; cpt1++) {
                    118:                PropertyDescriptor pd1 = pds1[cpt1];
                    119:                for (int cpt2 = 0 ; cpt2 < pds2.length ; cpt2++) {
                    120:                    PropertyDescriptor pd2 = pds2[cpt2];
                    121:                    if ((! pd2.isHidden()) 
                    122:                        && (! pd1.isHidden())
1.7       bmahe     123:                        && (equalsForeignKeys(pd1.getName(),pd2.getName()))) {
1.2       bmahe     124:                        foreign.addElement(pd1.getName());
                    125:                    }
                    126:                }
                    127:            }
                    128:            String keys[] = new String[foreign.size()];
                    129:            foreign.copyInto(keys);
                    130:            return keys;
                    131:        } catch (IntrospectionException ex) {
                    132:            return new String[0];
                    133:        }
                    134:     }
                    135: 
                    136:     /**
1.7       bmahe     137:      * toto_username == username
                    138:      */
1.13      bmahe     139:     private static boolean equalsForeignKeys(String key1, String key2) {
1.7       bmahe     140:        int idx1 = key1.lastIndexOf("_");
                    141:        if (idx1 != -1) {
                    142:            key1 = key1.substring(idx1);
                    143:        }
                    144:        int idx2 = key2.lastIndexOf("_");
                    145:        if (idx2 != -1) {
                    146:            key2 = key2.substring(idx2);
                    147:        }
                    148:        return key1.equals(key2);
                    149:     }
                    150: 
1.5       bmahe     151:     protected void markModified(boolean modified) {
                    152:        this.modified = modified;
                    153:     }
                    154: 
                    155:     protected boolean isModified() {
                    156:        return modified;
                    157:     }
                    158: 
1.1       bmahe     159:     /**
                    160:      * PropertyChangeListener implementation: This method gets called when
                    161:      * a bound property is changed.
                    162:      * @param evt A PropertyChangeEvent object describing the event source 
                    163:      * and the property that has changed.
                    164:      */
                    165:     public void propertyChange(PropertyChangeEvent evt) {
                    166:        Object source = evt.getSource();
1.5       bmahe     167:        String name   = evt.getPropertyName();
                    168:        Object value  = evt.getNewValue();
1.2       bmahe     169:        if (source == bean) {
1.7       bmahe     170:            if (value == null) {
                    171:                PropertyDescriptor pd = getPropertyDescriptor(name);
                    172:                if (JdbcBeanUtil.isJdbcBean(pd.getPropertyType())) {
                    173:                    // delete cached bean descriptors
                    174:                    this.beans = null;
                    175:                    // update listeners
                    176:                    JdbcBeanInterface oldbean = 
                    177:                        (JdbcBeanInterface)evt.getOldValue();
                    178:                    if (oldbean != null) {
1.9       bmahe     179:                        PropertyCache.removeProperties(oldbean);
1.7       bmahe     180:                        oldbean.removePropertyChangeListener(this);
                    181:                    }
                    182:                }
                    183:            } else if (value instanceof JdbcBeanInterface) {
1.5       bmahe     184:                registerForeignKeys(bean.getClass(), value.getClass());
1.4       bmahe     185:                // delete cached bean descriptors
                    186:                this.beans = null;
1.5       bmahe     187:                // update listeners
                    188:                JdbcBeanInterface oldbean = 
                    189:                    (JdbcBeanInterface)evt.getOldValue();
                    190:                JdbcBeanInterface newbean = (JdbcBeanInterface)value;
                    191:                if (oldbean != null) {
1.9       bmahe     192:                    PropertyCache.removeProperties(oldbean);
1.5       bmahe     193:                    oldbean.removePropertyChangeListener(this);
                    194:                }
                    195:                newbean.addPropertyChangeListener(this);
                    196:            } else {
1.2       bmahe     197:                JdbcBeanInterface bean = (JdbcBeanInterface)source;
1.9       bmahe     198:                PropertyCache.addProperty(bean, name, evt.getNewValue());
1.5       bmahe     199:                markModified(true);
                    200:            }
                    201:        } else {
                    202:            markModified(true);
1.1       bmahe     203:        }
                    204:     }
                    205: 
1.2       bmahe     206:     /**
                    207:      * Get the raw value of the given property, split the operator and
                    208:      * the value and convert the raw value into a SQL value.<p>
                    209:      * ie "~A.*" will become { " ~ " , "'A.*'" }
                    210:      * @param bean the property holder
                    211:      * @param pd the property descriptor
                    212:      */
1.13      bmahe     213:     private String[] getSQLOperatorNValue(JdbcBeanInterface bean, 
                    214:                                          PropertyDescriptor pd) 
1.1       bmahe     215:     {
                    216:        Class  type = pd.getPropertyType();
                    217:        Method m    = pd.getReadMethod(); 
                    218:        if (m != null) { // are we authozired to read it?
1.9       bmahe     219:            // use the cache
                    220:            Object value = PropertyCache.getProperty(bean, pd); 
1.1       bmahe     221:            if (value == null) {
                    222:                return null;
                    223:            }
1.10      bmahe     224:            return SQL.getSQLOperator(value);
1.1       bmahe     225:        }
                    226:        return null;
                    227:     }
                    228: 
                    229:     /**
1.5       bmahe     230:      * Get the SQL value of the given property.
                    231:      * @param bean the property holder
                    232:      * @param pd the property descriptor
                    233:      */
1.13      bmahe     234:     private String getSQLValue(JdbcBeanInterface bean, 
                    235:                               PropertyDescriptor pd) 
1.5       bmahe     236:     {
                    237:        Class  type = pd.getPropertyType();
                    238:        Method m    = pd.getReadMethod(); 
                    239:        if (m != null) { // are we authozired to read it?
1.9       bmahe     240:            // use the cache
                    241:            Object value = PropertyCache.getProperty(bean, pd); 
1.5       bmahe     242:            if (value == null) {
                    243:                return null;
                    244:            }
1.10      bmahe     245:             return SQL.getSQLValue(value);
1.5       bmahe     246:        }
                    247:        return null;
                    248:     }
                    249: 
                    250:     /**
1.1       bmahe     251:      * @param name
                    252:      * @param value
                    253:      * @param buf
                    254:      */
1.5       bmahe     255:     private void append(String name, 
                    256:                        String operator,
                    257:                        String value, 
                    258:                        String separator,
                    259:                        StringBuffer buf)
                    260:     {
                    261:        if (buf.length() > 0) {
                    262:            buf.append(separator).append(" ");
                    263:        }
                    264:        buf.append(name).append(operator).append(value).append(" ");
                    265:     }
                    266: 
                    267:     /**
                    268:      * @param name
                    269:      * @param value
                    270:      * @param namesbuffer
                    271:      * @param valuesbuffer
                    272:      */
                    273:     private void appendInsert(String name, 
1.2       bmahe     274:                              String value, 
1.5       bmahe     275:                              StringBuffer namesbuffer,
                    276:                              StringBuffer valuesbuffer)
1.1       bmahe     277:     {
1.5       bmahe     278:        if (namesbuffer.length() > 0) {
                    279:            namesbuffer.append(", ").append(name);
                    280:            valuesbuffer.append(", ").append(value);
                    281:        } else {
                    282:            namesbuffer.append("(").append(name);
                    283:            valuesbuffer.append("(").append(value);
1.1       bmahe     284:        }
                    285:     }
                    286: 
1.13      bmahe     287:     private JdbcBeanInterface[] getJdbcBeans() {
1.1       bmahe     288:        if (beans != null) {
                    289:            return beans;
                    290:        }
                    291:        try {
                    292:            BeanInfo info = Introspector.getBeanInfo(bean.getClass());
                    293:            Vector   vb   = new Vector();
                    294:            PropertyDescriptor pds[] = info.getPropertyDescriptors();
                    295:            for (int i = 0 ; i < pds.length ; i++) {
                    296:                PropertyDescriptor pd = pds[i];
1.5       bmahe     297:                if ((! pd.isHidden()) &&  
                    298:                    (JdbcBeanUtil.isJdbcBean(pd.getPropertyType()))) {
1.1       bmahe     299:                    Method m = pd.getReadMethod();
                    300:                    if (m != null) {
                    301:                        Object value = m.invoke(bean, null);
                    302:                        if (value != null) {
                    303:                            vb.addElement(value);
                    304:                        }
                    305:                    }
                    306:                }
                    307:            }
                    308:            beans = new JdbcBeanInterface[vb.size()];
                    309:            vb.copyInto(beans);
                    310:            return beans;
                    311:        } catch (IntrospectionException ex) {
                    312:            return null;
                    313:        } catch (IllegalAccessException ex) {
                    314:            return null;
                    315:        } catch (InvocationTargetException ex) {
                    316:            return null;
                    317:        }
                    318:     }
                    319: 
1.13      bmahe     320:     private void appendForeignKeys(Vector tables,
                    321:                                   StringBuffer buffer,
                    322:                                   String properties[]) 
1.8       bmahe     323:        throws IntrospectionException
1.7       bmahe     324:     {
                    325:        BeanInfo     info   = Introspector.getBeanInfo(bean.getClass());
                    326:        PropertyDescriptor pds[] = info.getPropertyDescriptors();
1.9       bmahe     327:        appendForeignKeys(tables, buffer, pds, properties);
1.7       bmahe     328:     }
                    329: 
1.13      bmahe     330:     private void appendForeignKeys(Vector tables,
                    331:                                   StringBuffer buffer,
                    332:                                   PropertyDescriptor pds[],
                    333:                                   String properties[])
1.8       bmahe     334:        throws IntrospectionException
1.1       bmahe     335:     {
                    336:        JdbcBeanInterface jbeans[] = getJdbcBeans();
1.9       bmahe     337:        if (jbeans != null) { // FOREIGN KEYs
1.1       bmahe     338:            for (int i = 0 ; i < jbeans.length ; i++) {
                    339:                JdbcBeanInterface jbean = jbeans[i];
1.2       bmahe     340:                // foreign keys
                    341:                String keys[] = getForeignKeys(jbean.getClass(),
                    342:                                               bean.getClass());
                    343:                for (int f = 0 ; f < keys.length ; f++) {
                    344:                    String key = keys[f];
1.9       bmahe     345:                    if ((properties == null) ||
                    346:                        (JdbcBeanUtil.isIn(key, properties))) {
                    347:                        append(jbean.getJdbcTable()+"."+key,
                    348:                               " = ",
                    349:                               bean.getJdbcTable()+"."+key,
                    350:                               "AND",
                    351:                               buffer);
                    352:                    }
1.2       bmahe     353:                }
1.8       bmahe     354:                BeanInfo           bi     = null;
                    355:                PropertyDescriptor jpds[] = null;
1.2       bmahe     356:                // value now
1.8       bmahe     357:                bi   = Introspector.getBeanInfo(jbean.getClass());
                    358:                jpds = bi.getPropertyDescriptors();
1.1       bmahe     359:                for (int jpd_cpt = 0 ; jpd_cpt < jpds.length ; jpd_cpt++) {
                    360:                    PropertyDescriptor jpd = jpds[jpd_cpt];
                    361:                    if (jpd.isHidden()) {
                    362:                        continue;
                    363:                    }
                    364:                    String jname = jpd.getName();
1.9       bmahe     365:                    if ((properties == null) ||
                    366:                        (JdbcBeanUtil.isIn(jname, properties))) {
                    367:                        String split[] = getSQLOperatorNValue(jbean, jpd);
                    368:                        if (split != null) {
                    369:                            append(jbean.getJdbcTable()+"."+jname,
                    370:                                   split[0],
                    371:                                   split[1],
                    372:                                   "AND",
                    373:                                   buffer);
                    374:                        }
1.1       bmahe     375:                    }
1.2       bmahe     376:                }
1.7       bmahe     377:                tables.addElement(jbean);
                    378:                // test FIXME recursive stuff
1.9       bmahe     379:                jbean.getSerializer().appendForeignKeys(tables, 
                    380:                                                        buffer, 
                    381:                                                        properties);
1.1       bmahe     382:            }
                    383:        }
                    384:     }
                    385: 
1.9       bmahe     386:     protected String computeSQLCount(boolean all, 
                    387:                                     boolean distinct, 
                    388:                                     String properties[]) 
                    389:     {
1.11      bmahe     390:        String count = (distinct) ? "DISTINCT count(*)" : "count(*)";
1.13      bmahe     391:        return computeSQLSelect(all, count, properties);
1.7       bmahe     392:     }
                    393: 
1.13      bmahe     394:     private String computeSQLSelect(String orderby[], 
                    395:                                    boolean asc[],
                    396:                                    boolean all)
1.7       bmahe     397:     {
1.9       bmahe     398:        return computeSQLSelect(orderby, asc, all, "*", null);
1.7       bmahe     399:     }
                    400: 
1.13      bmahe     401:     private String computeSQLSelect(String orderby[], 
                    402:                                    boolean asc[],
                    403:                                    boolean all,
                    404:                                    String select)
1.7       bmahe     405:     {
1.9       bmahe     406:        return computeSQLSelect(orderby, asc, all, select, null);
                    407:     }
                    408: 
                    409:     protected String computeSQLSelect(String orderby[], 
                    410:                                      boolean asc[],
                    411:                                      boolean all,
                    412:                                      String select,
                    413:                                      String properties[])
                    414:     {
1.13      bmahe     415:        String sql = computeSQLSelect(all, select, properties);
1.11      bmahe     416:        StringBuffer buffer = new StringBuffer(sql);
                    417:        if (orderby != null) {
                    418:            buffer.append(" ORDER BY ");
                    419:            for (int j = 0 ; j < orderby.length ; j++) {
                    420:                if (j != 0) {
                    421:                    buffer.append(", ");
                    422:                }
                    423:                buffer.append(orderby[j]);
                    424:                if (! asc[j]) {
                    425:                    buffer.append(" DESC");
                    426:                }
                    427:            }
                    428:        }
                    429:        return buffer.toString();
                    430:        
                    431:     }
                    432: 
1.13      bmahe     433:     private String computeSQLSelect(boolean all,
                    434:                                    String select,
                    435:                                    String properties[])
1.11      bmahe     436:     {
1.1       bmahe     437:        try {
                    438:            BeanInfo     info   = Introspector.getBeanInfo(bean.getClass());
                    439:            StringBuffer buffer = new StringBuffer();
                    440:            String       table  = bean.getJdbcTable();
1.7       bmahe     441:            this.beantables     = new Vector();
                    442:            beantables.addElement(bean);
                    443:            
1.1       bmahe     444:            PropertyDescriptor pds[] = info.getPropertyDescriptors();
1.5       bmahe     445:            if (all) {
                    446:                // FOREIGN KEYs
1.9       bmahe     447:                appendForeignKeys(beantables, buffer, pds, properties);
1.5       bmahe     448:            }
1.1       bmahe     449:            // known values
                    450:            for (int i = 0 ; i < pds.length ; i++) { 
                    451:                PropertyDescriptor pd = pds[i];
                    452:                if (! pd.isHidden()) {
1.9       bmahe     453:                    String jname = pd.getName();
                    454:                    if ((properties == null) ||
                    455:                        (JdbcBeanUtil.isIn(jname, properties))) {
                    456:                        String split[] = getSQLOperatorNValue(bean, pd);
                    457:                        if (split != null) {
                    458:                            append(table+"."+jname, 
                    459:                                   split[0],
                    460:                                   split[1],
                    461:                                   "AND",
                    462:                                   buffer);
                    463:                        }
1.1       bmahe     464:                    }
                    465:                }
                    466:            }
                    467:            // build SQL request
                    468:            if (buffer.length() > 0) {
1.7       bmahe     469:                StringBuffer tables = new StringBuffer();
                    470:                for (int i = 0 ; i < beantables.size() ; i++) {
                    471:                    JdbcBeanInterface jbean = 
                    472:                        (JdbcBeanInterface)beantables.elementAt(i);
                    473:                    if (i != 0) {
                    474:                        tables.append(", ");
                    475:                    }
                    476:                    tables.append(jbean.getJdbcTable());
                    477:                }
1.1       bmahe     478:                tables.append(" WHERE ");
1.7       bmahe     479:                tables.insert(0, "SELECT "+select+" FROM ");
1.1       bmahe     480:                tables.append(buffer.toString());
1.2       bmahe     481:                buffer = tables;
1.1       bmahe     482:            } else {
1.8       bmahe     483:                buffer = new StringBuffer("SELECT "+select+" FROM ");
1.2       bmahe     484:                buffer.append(table);
                    485:            }
1.9       bmahe     486:            // union? intersect? except?
                    487:            for (int i = 0 ; i < priority.length ; i++) {
                    488:                int p = priority[i];
                    489:                if (p == NOTHING) {
                    490:                    break;
                    491:                }
                    492:                switch (p) 
                    493:                    {
                    494:                    case INTERSECT:
1.14      bmahe     495:                        if (intersect_serializer != null) {
                    496:                            String intersect = 
                    497:                                intersect_serializer.computeSQLSelect(all,
                    498:                                                                      select,
1.13      bmahe     499:                                                                  properties);
1.14      bmahe     500:                            buffer.append(" INTERSECT (").append(intersect);
                    501:                            buffer.append(")");
                    502:                        }
1.9       bmahe     503:                        break;
                    504:                    case UNION:
1.14      bmahe     505:                        if (union_serializer != null) {
                    506:                            String union = 
                    507:                                union_serializer.computeSQLSelect(all,
                    508:                                                                  select,
                    509:                                                                  properties);
                    510:                            buffer.append(" UNION (").append(union);
                    511:                            buffer.append(")");
                    512:                        }
1.9       bmahe     513:                        break;
                    514:                    case EXCEPT:
1.14      bmahe     515:                        if (except_serializer != null) {
                    516:                            String except =
                    517:                                except_serializer.computeSQLSelect(all,
                    518:                                                                   select,
                    519:                                                                   properties);
                    520:                            buffer.append(" EXCEPT (").append(except);
                    521:                            buffer.append(")");
                    522:                        }
1.9       bmahe     523:                        break;
                    524:                    default:
                    525:                        // unreached (I hope)
1.7       bmahe     526:                    }
1.1       bmahe     527:            }
1.2       bmahe     528:            return buffer.toString();
1.1       bmahe     529:        } catch (IntrospectionException ex) {
                    530:            return null;
                    531:        }
                    532:     }
                    533: 
1.5       bmahe     534:     /**
                    535:      * Compute the SQL request necessary to update the Database.
                    536:      * @return a String
                    537:      */
                    538:     protected String computeSQLInsert() {
                    539:        try {
                    540:            BeanInfo info = Introspector.getBeanInfo(bean.getClass());
                    541:            PropertyDescriptor pds[]  = info.getPropertyDescriptors();
                    542:            StringBuffer namesbuffer  = new StringBuffer();
                    543:            StringBuffer valuesbuffer = new StringBuffer();
                    544:            for (int i = 0 ; i < pds.length ; i++) { 
                    545:                PropertyDescriptor pd = pds[i];
                    546:                if (! pd.isHidden()) {  
                    547:                    String value = getSQLValue(bean, pd);
                    548:                    if (value != null) {
                    549:                        appendInsert(pd.getName(), 
                    550:                                     value, 
                    551:                                     namesbuffer, 
                    552:                                     valuesbuffer);
                    553:                    }
                    554:                }
                    555:            }
                    556:            if (namesbuffer.length() > 0) {
                    557:                StringBuffer request = new StringBuffer("INSERT INTO ");
                    558:                request.append(bean.getJdbcTable()).append(" ");
                    559:                request.append(namesbuffer).append(") ");
                    560:                request.append("VALUES ").append(valuesbuffer).append(")");
                    561:                return request.toString();
                    562:            } else {
                    563:                return null;
                    564:            }
                    565:        } catch (IntrospectionException ex) {
                    566:            return null;
                    567:        }
                    568:     }
                    569: 
                    570:     protected String computeSQLDelete() {
                    571:        try {
                    572:            BeanInfo     info   = Introspector.getBeanInfo(bean.getClass());
                    573:            StringBuffer buffer = new StringBuffer();
                    574:            StringBuffer table = new StringBuffer(bean.getJdbcTable());
                    575:            PropertyDescriptor pds[] = info.getPropertyDescriptors();
                    576:            // known values
                    577:            for (int i = 0 ; i < pds.length ; i++) {
                    578:                PropertyDescriptor pd = pds[i];
                    579:                if (! pd.isHidden()) {
                    580:                    String split[] = getSQLOperatorNValue(bean, pd);
                    581:                    if (split != null) {
                    582:                        append(pd.getName(), split[0], split[1],"AND", buffer);
                    583:                    }
                    584:                }
                    585:            }
                    586:            // build SQL request
                    587:            if (buffer.length() > 0) {
                    588:                table.append(" WHERE ");
                    589:                table.insert(0, "DELETE FROM ");
                    590:                table.append(buffer.toString());
                    591:                buffer = table;
                    592:            } else {
                    593:                return null;
                    594:            }
                    595:            return buffer.toString();
                    596:        } catch (IntrospectionException ex) {
                    597:            return null;
                    598:        }
                    599:     }
                    600: 
                    601:     protected String computeSQLUpdate(String primarykeys[]) {
                    602:        try {
                    603:            BeanInfo     info     = Introspector.getBeanInfo(bean.getClass());
                    604:            StringBuffer buffer   = new StringBuffer();
                    605:            StringBuffer pkbuffer = new StringBuffer();
                    606:            StringBuffer table    = new StringBuffer(bean.getJdbcTable());
                    607:            PropertyDescriptor pds[] = info.getPropertyDescriptors();
                    608:            // known values
                    609:            for (int i = 0 ; i < pds.length ; i++) {
                    610:                PropertyDescriptor pd = pds[i];
                    611:                if (! pd.isHidden()) {
                    612:                    String name = pd.getName();
                    613:                    String split[] = getSQLOperatorNValue(bean, pd);
                    614:                    if (split != null) {
                    615:                        if (JdbcBeanUtil.isIn(name, primarykeys)) {
                    616:                            append(name, split[0], split[1], "AND", pkbuffer);
                    617:                        } else {
                    618:                            append(name, split[0], split[1], ",", buffer);
                    619:                        }
                    620:                    }
                    621:                }
                    622:            }
                    623:            // build SQL request
                    624:            if (buffer.length() > 0) {
                    625:                table.append(" SET ");
                    626:                table.insert(0, "UPDATE ");
                    627:                table.append(buffer.toString());
                    628:                table.append(" WHERE ");
                    629:                table.append(pkbuffer.toString());
                    630:                buffer = table;
                    631:            } else {
                    632:                return null;
                    633:            }
                    634:            return buffer.toString();
                    635:        } catch (IntrospectionException ex) {
                    636:            return null;
                    637:        }
                    638:     }
                    639: 
1.2       bmahe     640:     protected JdbcServer getJdbcServer() {
                    641:        Properties props = new Properties();
                    642:        Jdbc.setMaxConn(props, bean.getMaxConn());
                    643:        return JdbcServer.getServer(bean.getJdbcURI(), 
                    644:                                    bean.getJdbcUser(), 
                    645:                                    bean.getJdbcPassword(), 
                    646:                                    bean.getJdbcDriver(), 
                    647:                                    props);
                    648:     }
                    649: 
1.13      bmahe     650:     private void executeSQLQuery(String sqlrequest) 
1.5       bmahe     651:        throws SQLException
                    652:     {
                    653:        result = getJdbcServer().runQuery(sqlrequest, false);
                    654:     }
                    655: 
1.13      bmahe     656:     private int executeSQLUpdate(String sqlrequest) 
1.2       bmahe     657:        throws SQLException
                    658:     {
1.5       bmahe     659:        return getJdbcServer().runUpdate(sqlrequest, false);
1.2       bmahe     660:     }
1.12      ylafon    661: 
1.9       bmahe     662:     /**
                    663:      * Count the number or row with columns matching the value of the
                    664:      * bean properties.
                    665:      * @return an int
                    666:      */
1.7       bmahe     667:     public int count() {
1.9       bmahe     668:        return count(true, false, null);
                    669:     }
                    670: 
                    671:     /**
                    672:      * Count the number or row with columns matching the value of the
                    673:      * given properties.
                    674:      * @param properties The property names
                    675:      * @return an int
                    676:      */
                    677:     public int count(String properties[]) {
                    678:        return count(true, false, properties);
1.7       bmahe     679:     }
                    680: 
1.9       bmahe     681:     /**
                    682:      * Count the number or row with columns matching the value of the
                    683:      * bean properties.
                    684:      * @param all (join with associated beans?)
                    685:      * @return an int
                    686:      */
1.7       bmahe     687:     public int count(boolean all) {
1.9       bmahe     688:        return count(all, false, null);
1.8       bmahe     689:     }
                    690: 
1.9       bmahe     691:     /**
                    692:      * Count the number or row with columns matching the value of the
                    693:      * bean properties
                    694:      * @param all (join with associated beans?)
                    695:      * @param distinct (SELECT DISTINCT?)
                    696:      * @return an int
                    697:      */
1.8       bmahe     698:     public int count(boolean all, boolean distinct) {
1.9       bmahe     699:        return count(all, distinct, null);
                    700:     }
                    701: 
                    702:     /**
                    703:      * Count the number or row with columns matching the value of the
                    704:      * given properties.
                    705:      * @param all (join with associated beans?)
                    706:      * @param distinct (SELECT DISTINCT?)
                    707:      * @param properties The property names
                    708:      * @return an int
                    709:      */
                    710:     public int count(boolean all, boolean distinct, String properties[]) {
                    711:        String sql = computeSQLCount(all, distinct, properties);
1.7       bmahe     712:        try {
                    713:            executeSQLQuery(sql);
                    714:            if (result.first()) {
                    715:                return result.getInt(1);
                    716:            } else {
                    717:                return 0;
                    718:            }
                    719:        } catch (SQLException ex) {
                    720:            System.out.println("SQL STATE: "+ex.getSQLState());
                    721:            ex.printStackTrace();
                    722:            return 0;
                    723:        } finally {
                    724:            result     = null;
                    725:            beantables = null;
                    726:        }
1.9       bmahe     727:        
1.7       bmahe     728:     }
1.9       bmahe     729: 
1.8       bmahe     730:     /**
                    731:      * Perform a sql select to update the beans properties.
                    732:      */
1.2       bmahe     733:     public void select() {
1.7       bmahe     734:        boolean array[] = { true };
1.8       bmahe     735:        select((String[])null, array, true, false);
1.5       bmahe     736:     }
                    737: 
1.8       bmahe     738:     /**
                    739:      * Perform a sql select to update the beans properties.
                    740:      * @param all join with attached beans? (default is true)
                    741:      */
1.5       bmahe     742:     public void select(boolean all) {
1.7       bmahe     743:        boolean array[] = { true };
1.8       bmahe     744:        select((String[])null, array, all, false);
1.2       bmahe     745:     }
                    746: 
1.8       bmahe     747:     /**
                    748:      * Perform a sql select to update the beans properties.
                    749:      * @param orderby orderby rule
                    750:      */
1.2       bmahe     751:     public void select(String orderby) {
                    752:        String array[] = { orderby };
1.7       bmahe     753:        boolean arrayb[] = { true };
1.8       bmahe     754:        select(array, arrayb, true, false);
1.5       bmahe     755:     }
                    756: 
1.8       bmahe     757:     /**
                    758:      * Perform a sql select to update the beans properties.
                    759:      * @param orderby orderby rule
                    760:      * @param asc boolean if true orderby is ASC if false it it
                    761:      * DESC (relative to the orderby[] parameter)
                    762:      * @param all join with attached beans? (default is true)
                    763:      */
                    764:     public void select(String orderby, 
                    765:                       boolean asc, 
                    766:                       boolean all)
                    767:     {
1.5       bmahe     768:        String array[] = { orderby };
1.7       bmahe     769:        boolean arrayb[] = { asc };
1.8       bmahe     770:        select(array, arrayb, all, false);
1.2       bmahe     771:     }
                    772: 
1.8       bmahe     773:     /**
                    774:      * Perform a sql select to update the beans properties.
                    775:      * @param orderby orderby rule
                    776:      * @param asc boolean if true orderby is ASC if false it it
                    777:      * DESC (relative to the orderby[] parameter)
                    778:      * @param all join with attached beans? (default is true)
                    779:      * @param distinct if true, result won't have duplicate row (default is 
                    780:      * false)
                    781:      */
                    782:     public void select(String orderby, 
                    783:                       boolean asc, 
                    784:                       boolean all, 
                    785:                       boolean distinct) 
                    786:     {
                    787:        String array[] = { orderby };
                    788:        boolean arrayb[] = { asc };
                    789:        select(array, arrayb, all, distinct);
                    790:     }
                    791: 
                    792:     /**
                    793:      * Perform a sql select to update the beans properties.
                    794:      * @param orderby array of orderby rules (ASC by default)
                    795:      */
1.2       bmahe     796:     public void select(String orderby[]) {
1.7       bmahe     797:        boolean array[] = { true };
1.8       bmahe     798:        select(orderby, array, true, false);
                    799:     }
                    800: 
                    801:     /**
                    802:      * Perform a sql select to update the beans properties.
                    803:      * @param orderby array of orderby rules
                    804:      * @param asc array of boolean if true orderby is ASC if false it it
                    805:      * DESC (relative to the orderby[] parameter)
                    806:      * @param all join with attached beans? (default is true)
                    807:      * @param distinct if true, result won't have duplicate row (default is 
                    808:      * false)
                    809:      */
                    810:     public void select(String orderby[],
                    811:                       boolean asc[],
                    812:                       boolean all,
                    813:                       boolean distinct) 
                    814:     {
                    815:        String select = (distinct) ? "DISTINCT *" : "*";
                    816:        String sql = computeSQLSelect(orderby, asc, all, select);
                    817:        try {
                    818:            executeSQLQuery(sql);
                    819:        } catch (SQLException ex) {
                    820:            System.out.println("SQL STATE: "+ex.getSQLState());
                    821:            ex.printStackTrace();
                    822:            result = null;
                    823:        }
1.5       bmahe     824:     }
                    825: 
1.8       bmahe     826:     /**
1.9       bmahe     827:      * Perform a sql select to update the beans properties.
                    828:      * @param orderby array of orderby rules
                    829:      * @param asc array of boolean if true orderby is ASC if false it it
                    830:      * DESC (relative to the orderby[] parameter)
                    831:      * @param all join with attached beans? (default is true)
                    832:      * @param distinct if true, result won't have duplicate row (default is 
                    833:      * @param toselect array of columns name to select
                    834:      * false)
                    835:      */
                    836:     public void select(String orderby[],
                    837:                       boolean asc[],
                    838:                       boolean all,
                    839:                       boolean distinct,
                    840:                       String toselect[]) 
                    841:     {
                    842:        String query = null;
                    843:        if (toselect != null) {
                    844:            StringBuffer buffer = new StringBuffer();
                    845:            for (int i = 0 ; i < toselect.length ; i++) { 
                    846:                if (i != 0) {
                    847:                    buffer.append(", ");
                    848:                }
                    849:                buffer.append(toselect[i]).append(" ");
                    850:            }
                    851:            query = buffer.toString();
                    852:        } else {
                    853:            query = "*";
                    854:        }
                    855:        String select = (distinct) ? "DISTINCT "+query : query;
                    856:        String sql = computeSQLSelect(orderby, asc, all, select);
                    857:        try {
                    858:            executeSQLQuery(sql);
                    859:        } catch (SQLException ex) {
                    860:            System.out.println("SQL STATE: "+ex.getSQLState());
                    861:            ex.printStackTrace();
                    862:            result = null;
                    863:        }
                    864:     }
                    865: 
                    866:     /**
1.8       bmahe     867:      * Perform a sql select to update only the given columns. (distinct flag is
                    868:      * set as true.
                    869:      * @param column the bean property to update
                    870:      */
                    871:     public void selectDistinct(String column) {
                    872:        boolean array[] = { true };
                    873:         String order[] = { column };
                    874:        String sql = computeSQLSelect(order, array, false, "DISTINCT "+column);
1.5       bmahe     875:        try {
                    876:            executeSQLQuery(sql);
1.8       bmahe     877:        } catch (SQLException ex) {
                    878:            System.out.println("SQL STATE: "+ex.getSQLState());
                    879:            ex.printStackTrace();
                    880:            result = null;
                    881:        }
                    882:     }
                    883: 
1.14      bmahe     884:     private void setPriority(int p) {
1.9       bmahe     885:        int idx = 0;
                    886:        while ((idx < priority.length) && (priority[idx] != NOTHING)) {
                    887:            if (priority[idx] == p) { // already set
                    888:                return;
                    889:            }
                    890:            idx++;
                    891:        }
                    892:        priority[idx] = p;
1.8       bmahe     893:     }
                    894: 
1.13      bmahe     895:     /**
                    896:      * USE THIS METHOD ONLY BEFORE SELECT QUERIES.
                    897:      * This will produce a select query with an INTERSECT statement in it
                    898:      * using the values of the given bean.
                    899:      * @param ibean the intersect bean
                    900:      */
1.9       bmahe     901:     public JdbcBeanSerializer intersect(JdbcBeanInterface ibean) {
                    902:        setPriority(INTERSECT);
                    903:        intersect_serializer = ibean.getSerializer();
                    904:        return intersect_serializer;
1.8       bmahe     905:     }
                    906: 
1.13      bmahe     907:     /**
                    908:      * USE THIS METHOD ONLY BEFORE QUERIES.
                    909:      * This will produce a select query with an UNION statement in it
                    910:      * using the values of the given bean.
                    911:      * @param ibean the intersect bean
                    912:      */
1.9       bmahe     913:     public JdbcBeanSerializer union(JdbcBeanInterface ubean) {
                    914:        setPriority(UNION);
                    915:        union_serializer = ubean.getSerializer();
                    916:        return union_serializer;
1.8       bmahe     917:     }
                    918: 
1.13      bmahe     919:     /**
                    920:      * USE THIS METHOD ONLY BEFORE SELECT QUERIES.
                    921:      * This will produce a select query with an EXCEPT statement in it
                    922:      * using the values of the given bean.
                    923:      * @param ibean the intersect bean
                    924:      */
1.9       bmahe     925:     public JdbcBeanSerializer except(JdbcBeanInterface ebean) {
                    926:        setPriority(EXCEPT);
                    927:        except_serializer = ebean.getSerializer();
                    928:        return except_serializer;
1.14      bmahe     929:     }
                    930: 
                    931:     /**
                    932:      * Remove the intersect bean
                    933:      */
                    934:     public void removeIntersectBean() {
                    935:        intersect_serializer = null;
                    936:        
                    937:     }
                    938: 
                    939:     /**
                    940:      * Remove the union bean
                    941:      */
                    942:     public void removeUnionBean() {
                    943:        union_serializer = null;
                    944:        
                    945:     }
                    946: 
                    947:     /**
                    948:      * Remove the except bean
                    949:      */
                    950:     public void removeExceptBean() {
                    951:        except_serializer = null;
1.5       bmahe     952:     }
                    953: 
1.13      bmahe     954:     /**
                    955:      * Insert the current bean values in the associated table.
                    956:      * @return false if the INSERT request failed.
                    957:      */
1.5       bmahe     958:     public boolean insert() {
                    959:        if (! isModified()) { // nothing new to insert
                    960:            return false;
                    961:        }
                    962:        JdbcBeanInterface beans[] = getJdbcBeans();
                    963:        for (int i = 0 ; i < beans.length ; i++) { 
                    964:            JdbcBeanInterface jbean = beans[i];
                    965:            JdbcBeanSerializer ser  = jbean.getSerializer();
                    966:            if (ser.isModified()) {
                    967:                // insert associated bean
                    968:                ser.insert();
                    969:                // update our foreign key
                    970:                updateForeignKeys(jbean); 
                    971:            }
                    972:        }
                    973:        if (! bean.getReadOnly()) {
                    974:            // ok insert ourself now
                    975:            String request = computeSQLInsert();
                    976:            try {
                    977:                // insert (could fail without being critical)
                    978:                // ie: when the row is already in the table
                    979:                executeSQLUpdate(request);
                    980:            } catch (SQLException ex) {
                    981:                System.err.println(ex.getMessage());
1.16    ! bmahe     982:                return false;
1.5       bmahe     983:            }
                    984:        }
                    985:        // update value automatically generated by the DB (index, ...)
                    986:        select(false);
                    987:        try {
                    988:            if (result == null) {
                    989:                return false;
                    990:            }
                    991:            if (result.first()) {
1.7       bmahe     992:                return updateProperties(false);
1.5       bmahe     993:            } else {
                    994:                return false;
                    995:            }
                    996:        } catch (SQLException ex) {
                    997:            ex.printStackTrace();
                    998:            return false;
                    999:        }
                   1000:     }
                   1001: 
1.13      bmahe    1002:     /**
                   1003:      * Update the row relative to our bean.
                   1004:      * @param primarykey The primary key of the SQL table
                   1005:      * @return false if the UPDATE request failed.
                   1006:      */
1.5       bmahe    1007:     public boolean update(String primarykey) {
                   1008:        String array[] = { primarykey };
                   1009:        return update(array);
                   1010:     }
                   1011: 
1.13      bmahe    1012:     /**
                   1013:      * Update the row relative to our bean.
                   1014:      * @param primarykey The primary key of the SQL table
                   1015:      * @return false if the UPDATE request failed.
                   1016:      */
1.5       bmahe    1017:     public boolean update(String primarykeys[]) {
                   1018:        if (! isModified()) { // noting to update
                   1019:            return false;
                   1020:        }
                   1021:        String sql = computeSQLUpdate(primarykeys);
                   1022:        try {
                   1023:            int nb = executeSQLUpdate(sql);
                   1024:            return (nb > 0);
                   1025:        } catch (SQLException ex) {
                   1026:            ex.printStackTrace();
                   1027:        }
                   1028:        return false;
                   1029:     }
                   1030: 
1.13      bmahe    1031:     /**
                   1032:      * Delete the row relative to the current bean.
                   1033:      * @return false if the DELETE request failed.
                   1034:      */
1.5       bmahe    1035:     public boolean delete() {
                   1036:        if (bean.getReadOnly()) {
                   1037:            return false;
                   1038:        }
                   1039:        String sql = computeSQLDelete();
1.2       bmahe    1040:        try {
1.5       bmahe    1041:            int nb = executeSQLUpdate(sql);
                   1042:            return (nb > 0);
1.2       bmahe    1043:        } catch (SQLException ex) {
1.5       bmahe    1044:            System.out.println("SQL STATE: "+ex.getSQLState());
1.2       bmahe    1045:            ex.printStackTrace();
                   1046:            result = null;
1.5       bmahe    1047:            return false; // FIXME VERIFY
1.2       bmahe    1048:        }
                   1049:     }
                   1050: 
                   1051:     /**
                   1052:      * Go to the first row
                   1053:      * @return false if there is no first row
                   1054:      */
                   1055:     public boolean first() {
                   1056:        try {
                   1057:            if (result == null) {
                   1058:                return false;
                   1059:            }
                   1060:            if (result.first()) {
1.7       bmahe    1061:                return updateProperties();
1.2       bmahe    1062:            }
                   1063:        } catch (SQLException ex) { }
                   1064:        return false;
                   1065:     }
                   1066: 
                   1067:     /**
                   1068:      * Update our bean with the value of the next row
                   1069:      * @return false if there is no more row
                   1070:      */
                   1071:     public boolean next() {
                   1072:        try {
                   1073:            if (result == null) {
                   1074:                return false;
                   1075:            }
                   1076:            if (result.next()) {
1.7       bmahe    1077:                return updateProperties();
1.2       bmahe    1078:            }
                   1079:        } catch (SQLException ex) { }
                   1080:        return false;
                   1081:     }
                   1082: 
1.13      bmahe    1083:     /**
                   1084:      * Did we reached the last row?
                   1085:      * @return true if the last row is reached
                   1086:      */
1.7       bmahe    1087:     public boolean isLast() {
                   1088:        try {
                   1089:            if (result == null) {
                   1090:                return true;
                   1091:            }
                   1092:            return result.isLast();
                   1093:        } catch (SQLException ex) { }
                   1094:        return true;
                   1095:     }
                   1096: 
1.5       bmahe    1097:     /**
                   1098:      * Clean cached properties (relative to our bean)
                   1099:      */
                   1100:     public void clean() {
1.7       bmahe    1101:        result = null;
1.9       bmahe    1102:        PropertyCache.removeProperties(bean);
                   1103:         markModified(false);
1.5       bmahe    1104:     }
                   1105: 
1.10      bmahe    1106:     /**
                   1107:      * Restore default value except for JdbcBean properties.
                   1108:      */
                   1109:     public void initBean() {
                   1110:        try {
                   1111:            BeanInfo info = Introspector.getBeanInfo(bean.getClass());
                   1112:            PropertyDescriptor pds[] = info.getPropertyDescriptors();
                   1113:            for (int i = 0 ; i < pds.length ; i++) {
                   1114:                PropertyDescriptor pd = pds[i];
                   1115:                if ((! pd.isHidden()) && 
                   1116:                    (! JdbcBeanUtil.isJdbcBean(pd.getPropertyType()))) {
                   1117:                    Method getter = pd.getReadMethod();
                   1118:                    Method setter = pd.getWriteMethod();
                   1119:                    Object value  = null;
                   1120:                    if ((getter != null) && (setter != null)) {
                   1121:                        try {
                   1122:                            value = getter.invoke(bean.getDefault(), null);
                   1123:                            Object array[] = { value };
                   1124:                            setter.invoke(bean, array);
                   1125:                        } catch (IllegalAccessException ex) {
                   1126:                            ex.printStackTrace();
                   1127:                            // nothing to do
                   1128:                        } catch (InvocationTargetException ex) {
                   1129:                            ex.printStackTrace();
                   1130:                            // still nothing to do
                   1131:                        } catch (IllegalArgumentException ex) {
                   1132:                            ex.printStackTrace();
                   1133:                            // nothing to do
                   1134:                        }
                   1135:                    }  
                   1136:                }
                   1137:            }
                   1138:            clean();
                   1139:        } catch (IntrospectionException ex) {
                   1140:        }
                   1141:     }
                   1142: 
1.13      bmahe    1143:     private int findColumn(Vector tables, ResultSet result, String colname) 
1.7       bmahe    1144:        throws SQLException
                   1145:     {
                   1146:        String            tablename = bean.getJdbcTable();
                   1147:        ResultSetMetaData metadata  = result.getMetaData();
                   1148:        int cpt = 0;
1.15      bmahe    1149:        if (metadata.getTableName(1).length() > 0) { // applicable
1.7       bmahe    1150:            for (int i = 0 ; i < metadata.getColumnCount() ; i++) {
                   1151:                String coltable = metadata.getTableName(i);
1.15      bmahe    1152:                if ((metadata.getTableName(i).equalsIgnoreCase(tablename)) &&
                   1153:                    (metadata.getColumnName(i).equalsIgnoreCase(colname))) {
1.7       bmahe    1154:                    return i;
                   1155:                }
                   1156:            }
                   1157:        } else { // not applicable
                   1158:            // search all columns matching the given name
                   1159:            Vector indexes = new Vector();
                   1160:            try {
                   1161:                for (int i = 1 ; i <= metadata.getColumnCount() ; i++) {
                   1162:                    if (metadata.getColumnName(i).equals(colname)) {
                   1163:                        indexes.addElement(new Integer(i));
                   1164:                    }
                   1165:                }
                   1166:            } catch (Exception ex) {
                   1167:                ex.printStackTrace();
                   1168:            }
                   1169:            // find the good one
                   1170:            if (indexes.size() == 0) {
                   1171:                return -1;
                   1172:            } else if (indexes.size() == 1) {
                   1173:                return ((Integer)indexes.elementAt(0)).intValue();
                   1174:            } else {
                   1175:                int idxidx = 0;
                   1176:                for (int i = 0 ; i < tables.size() ; i++) {
                   1177:                    JdbcBeanInterface jbean = 
                   1178:                        (JdbcBeanInterface)tables.elementAt(i);
                   1179:                    if (jbean == bean) {
                   1180:                        return ((Integer)indexes.elementAt(idxidx)).intValue();
                   1181:                    }
                   1182:                    if (jbean.getSerializer().getPropertyDescriptor(colname) !=
                   1183:                        null) {
                   1184:                        // exists in this table
                   1185:                        idxidx++;
                   1186:                    }
                   1187:                }
                   1188:            }
                   1189:        }
                   1190:        return -1;
1.5       bmahe    1191:     }
                   1192: 
1.13      bmahe    1193:     private boolean updateProperties() {
1.7       bmahe    1194:        return updateProperties(this.beantables, this.result, true);
                   1195:     }
                   1196: 
1.13      bmahe    1197:     private boolean updateProperties(boolean all) {
1.7       bmahe    1198:        return updateProperties(this.beantables, this.result, all);
                   1199:     }
                   1200: 
1.13      bmahe    1201:     private boolean updateProperties(Vector tables,
                   1202:                                     ResultSet result) 
1.7       bmahe    1203:     {
                   1204:        return updateProperties(tables, result, true);
                   1205:     }
                   1206: 
1.13      bmahe    1207:     private boolean updateProperties(Vector tables,
                   1208:                                     ResultSet result, 
                   1209:                                     boolean all) 
1.7       bmahe    1210:     {
1.2       bmahe    1211:        try {
                   1212:            BeanInfo info = Introspector.getBeanInfo(bean.getClass());
                   1213:            PropertyDescriptor pds[] = info.getPropertyDescriptors();
                   1214:            for (int i = 0 ; i < pds.length ; i++) {
                   1215:                PropertyDescriptor pd = pds[i];
                   1216:                if (! pd.isHidden()) {
                   1217:                    try {
1.7       bmahe    1218:                        int idx = findColumn(tables, result, pd.getName());
                   1219:                        if (idx != -1) {
                   1220:                            Object value  = result.getObject(idx);
                   1221:                            Class propertyclass = pd.getPropertyType();
                   1222:                            value = SQL.getMatchingValue(propertyclass, value);
                   1223:                            if (value != null) {
                   1224:                                Object values[] = { value };
                   1225:                                Method setter = pd.getWriteMethod();
                   1226:                                if (setter != null) {
                   1227:                                    try {
                   1228:                                        setter.invoke(bean, values);
                   1229:                                    } catch (IllegalAccessException ex) {
                   1230:                                        ex.printStackTrace();
                   1231:                                        // nothing to do
                   1232:                                    } catch (InvocationTargetException ex) {
                   1233:                                        ex.printStackTrace();
                   1234:                                        // still nothing to do
                   1235:                                    } catch (IllegalArgumentException ex) {
                   1236:                                        ex.printStackTrace();
                   1237:                                        // nothing to do
                   1238:                                    }
1.2       bmahe    1239:                                }
1.9       bmahe    1240:                            } else {
                   1241:                                // default value
                   1242:                                Method getter = pd.getReadMethod();
                   1243:                                Method setter = pd.getWriteMethod();
                   1244:                                if ((getter != null) && (setter != null)) {
                   1245:                                    try {
                   1246:                                        value = 
                   1247:                                            getter.invoke(bean.getDefault(),
                   1248:                                                          null);
                   1249:                                        Object array[] = { value };
                   1250:                                        setter.invoke(bean, array);
                   1251:                                    } catch (IllegalAccessException ex) {
                   1252:                                        ex.printStackTrace();
                   1253:                                        // nothing to do
                   1254:                                    } catch (InvocationTargetException ex) {
                   1255:                                        ex.printStackTrace();
                   1256:                                        // still nothing to do
                   1257:                                    } catch (IllegalArgumentException ex) {
                   1258:                                        ex.printStackTrace();
                   1259:                                        // nothing to do
                   1260:                                    }
                   1261:                                }
1.2       bmahe    1262:                            }
                   1263:                        }
                   1264:                    } catch (SQLException ex) { // not found
                   1265:                        // nothing to do
                   1266:                    }
                   1267:                }
                   1268:            }
1.5       bmahe    1269:            if (all) {
                   1270:                // update the associated beans
                   1271:                JdbcBeanInterface beans[] = getJdbcBeans();
                   1272:                for (int i = 0 ; i < beans.length ; i++) {
1.7       bmahe    1273:                    beans[i].getSerializer().updateProperties(tables, result);
1.5       bmahe    1274:                }
1.2       bmahe    1275:            }
1.5       bmahe    1276:            markModified(false);
1.2       bmahe    1277:            return true;
                   1278:        } catch (IntrospectionException ex) {
                   1279:            return false;
                   1280:        }
1.5       bmahe    1281:     }
                   1282: 
1.9       bmahe    1283:     /**
                   1284:      * Update our bean property with the given bean property 
                   1285:      * (must be an instance of the same class).
                   1286:      * @param ubean the bean to get new properties
                   1287:      */
                   1288:     public void updateProperties(JdbcBeanInterface ubean) {
                   1289:        if (ubean.getClass() != bean.getClass()) {
                   1290:            return;
                   1291:        }
                   1292:        try {
                   1293:            BeanInfo bi = Introspector.getBeanInfo(bean.getClass());
                   1294:            PropertyDescriptor pds[] = bi.getPropertyDescriptors();
                   1295:            for (int i = 0 ; i < pds.length ; i++) {
                   1296:                PropertyDescriptor pd = pds[i];
                   1297:                if (! pd.isHidden()) {
                   1298:                    try {
                   1299:                        Method reader = pd.getReadMethod();
                   1300:                        Method writer = pd.getWriteMethod();
                   1301:                        Object value  = reader.invoke(ubean, null);
                   1302:                        if (value != null) {
                   1303:                            Object array[] = { value };
                   1304:                            writer.invoke(bean, array);
                   1305:                        }
                   1306:                    } catch (IllegalAccessException ex) {
                   1307:                        ex.printStackTrace();
                   1308:                    } catch (InvocationTargetException ex) {
                   1309:                        ex.printStackTrace();
                   1310:                    }
                   1311:                }
                   1312:            }
                   1313:        } catch (IntrospectionException ex) {
                   1314:            // nothing to do
                   1315:        }
                   1316:     }
                   1317: 
1.13      bmahe    1318:     private PropertyDescriptor getPropertyDescriptor(String property) {
1.5       bmahe    1319:        try {
                   1320:            BeanInfo bi = Introspector.getBeanInfo(bean.getClass());
                   1321:            PropertyDescriptor pds[] = bi.getPropertyDescriptors();
                   1322:            for (int i = 0 ; i < pds.length ; i++) {
                   1323:                PropertyDescriptor pd = pds[i];
                   1324:                if (pd.getName().equals(property)) {
                   1325:                    return pd;
                   1326:                }
                   1327:            }
                   1328:            return null;
                   1329:        } catch (IntrospectionException ex) {
                   1330:            return null;
                   1331:        }
                   1332:     }
                   1333: 
1.13      bmahe    1334:     private void updateForeignKeys(JdbcBeanInterface jbean) {
1.5       bmahe    1335:        String keys[] = getForeignKeys(jbean.getClass(), bean.getClass());
                   1336:        JdbcBeanSerializer ser = jbean.getSerializer();
                   1337:        for (int i = 0 ; i < keys.length ; i++) { 
                   1338:            try {
                   1339:                String             key    = keys[i];
                   1340:                PropertyDescriptor wkeypd = getPropertyDescriptor(key);
                   1341:                PropertyDescriptor rkeypd = ser.getPropertyDescriptor(key);
                   1342:                Method             reader = rkeypd.getReadMethod();
                   1343:                Method             writer = wkeypd.getWriteMethod();
                   1344:                Object value = reader.invoke(jbean, null);
                   1345:                if (value != null) {
                   1346:                    Object array[] = { value };
                   1347:                    writer.invoke(bean, array);
                   1348:                }
                   1349:            } catch (IllegalAccessException ex) {
                   1350:                ex.printStackTrace();
                   1351:            } catch (InvocationTargetException ex) {
                   1352:                ex.printStackTrace();
                   1353:            }
                   1354:        }
                   1355:     }
                   1356: 
1.6       bmahe    1357:     /**
                   1358:      * Called by the Garbage Collector.
                   1359:      */
1.5       bmahe    1360:     protected void finalize() 
                   1361:        throws Throwable
                   1362:     {
                   1363:        // cleanup (static) cached properties
1.9       bmahe    1364:        PropertyCache.removeProperties(this.bean);
1.2       bmahe    1365:     }
                   1366: 
1.13      bmahe    1367:     /**
                   1368:      * Constructor
                   1369:      * @param bean the JdbcBean to serialize
                   1370:      */ 
1.1       bmahe    1371:     public JdbcBeanSerializer(JdbcBeanInterface bean) {
1.9       bmahe    1372:        this.bean        = bean;
1.1       bmahe    1373:        bean.addPropertyChangeListener(this);
                   1374:     }
                   1375: 
                   1376: }
                   1377: 
                   1378: 

Webmaster