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

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

Webmaster