You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by ba...@apache.org on 2002/02/16 15:26:05 UTC

cvs commit: jakarta-commons-sandbox/simplestore/src/java/org/apache/commons/simplestore/persistence/impl MetaClassImpl.java DBStorage.java PersistentProxy.java

baliuka     02/02/16 06:26:05

  Modified:    simplestore/src/java/org/apache/commons/simplestore/jdbc
                        DriverDataSource.java
               simplestore/src/java/org/apache/commons/simplestore/persistence
                        MetaClass.java
               simplestore/src/java/org/apache/commons/simplestore/persistence/impl
                        DBStorage.java PersistentProxy.java
  Added:       simplestore/src/java/org/apache/commons/simplestore/persistence/impl
                        MetaClassImpl.java
  Log:
  Added incomplete metadata implementation
  
  Revision  Changes    Path
  1.4       +5 -5      jakarta-commons-sandbox/simplestore/src/java/org/apache/commons/simplestore/jdbc/DriverDataSource.java
  
  Index: DriverDataSource.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/simplestore/src/java/org/apache/commons/simplestore/jdbc/DriverDataSource.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- DriverDataSource.java	16 Feb 2002 10:09:50 -0000	1.3
  +++ DriverDataSource.java	16 Feb 2002 14:26:05 -0000	1.4
  @@ -72,7 +72,7 @@
   /**
    *@author     Juozas Baliuka <a href="mailto:baliuka@mwm.lt">
    *      baliuka@mwm.lt</a>
  - *@version    $Id: DriverDataSource.java,v 1.3 2002/02/16 10:09:50 baliuka Exp $
  + *@version    $Id: DriverDataSource.java,v 1.4 2002/02/16 14:26:05 baliuka Exp $
    *
    */
   public class DriverDataSource implements DataSource {
  @@ -228,15 +228,15 @@
                           }
                           
                           break;
  -                    }else {
  +                    }
  +                }else {
                           connection[i] = newConnection();
                           break;
                       }
  -                }
                   i = ( i + 1 ) % maxConnections;
                   try{
                       
  -                    if( i == 0 ) wait();
  +                    if( i == 0  ) wait();
                       
                   }catch( java.lang.InterruptedException ie ){
                       
  @@ -282,7 +282,7 @@
   
   /**
    *@author     Juozas Baliuka
  - *@version    $Id: DriverDataSource.java,v 1.3 2002/02/16 10:09:50 baliuka Exp $
  + *@version    $Id: DriverDataSource.java,v 1.4 2002/02/16 14:26:05 baliuka Exp $
    */
   class ConnectionWrapper implements Connection {
       
  
  
  
  1.3       +11 -34    jakarta-commons-sandbox/simplestore/src/java/org/apache/commons/simplestore/persistence/MetaClass.java
  
  Index: MetaClass.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/simplestore/src/java/org/apache/commons/simplestore/persistence/MetaClass.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- MetaClass.java	11 Feb 2002 20:30:16 -0000	1.2
  +++ MetaClass.java	16 Feb 2002 14:26:05 -0000	1.3
  @@ -61,11 +61,13 @@
    *
    *@author     Juozas Baliuka <a href="mailto:baliuka@mwm.lt">
    *     baliuka@mwm.lt</a>
  - *@version    $Id: MetaClass.java,v 1.2 2002/02/11 20:30:16 froehlich Exp $
  + *@version    $Id: MetaClass.java,v 1.3 2002/02/16 14:26:05 baliuka Exp $
    */
   
   public interface MetaClass {
   
  +    public java.beans.PropertyDescriptor [] getProperties();
  +    
       /**
        * Returns Table name for DB storage
        *
  @@ -88,13 +90,9 @@
        */
       public Class getPersitentClass();
   
  -    /**
  -     * returns index for property
  -     *
  -     *@param  method  read or write method
  -     *@return         index
  -     */
  -    public int getPropertyIndex(Method method);
  +    
  +    public int getPropertyIndex(String field);
  +
   
       /**
        * return field name for DB storage
  @@ -113,32 +111,11 @@
       public Class getPropertyType(int index);
   
   
  -    // public boolean isNotNull( int index ); validator ?
  -
  -    // Validator getValidator( int index ); we can reuse something from commons
  -
  -    /**
  -     * Primary key fields
  -     *
  -     *@return    indexes for primary key fields
  -     */
  -    public int[] getOIDPropreties();
  -
  -    /**
  -     * All foreign classes (Tables)
  -     *
  -     *@return    array of property index
  -     */
  -    public MetaClass[] references();
  -
  -    /**
  -     * Index for foreign key property
  -     *
  -     *@param  ref  reference meta class
  -     *@return      property index
  -     */
  -    public int getReferncePropertyIndex(MetaClass ref);
  -
   
  +    public Persistent newInstance(Object oid, boolean create);
  +    
  +    
  +    public Persistent newInstance(Object oid, boolean create,java.lang.ClassLoader cl);
  +    
   }
   
  
  
  
  1.3       +147 -183  jakarta-commons-sandbox/simplestore/src/java/org/apache/commons/simplestore/persistence/impl/DBStorage.java
  
  Index: DBStorage.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/simplestore/src/java/org/apache/commons/simplestore/persistence/impl/DBStorage.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- DBStorage.java	11 Feb 2002 20:30:09 -0000	1.2
  +++ DBStorage.java	16 Feb 2002 14:26:05 -0000	1.3
  @@ -57,6 +57,7 @@
   import org.apache.commons.simplestore.cache.Cache;
   import org.apache.commons.simplestore.persistence.InternalTransaction;
   import org.apache.commons.simplestore.persistence.MetaObject;
  +import org.apache.commons.simplestore.persistence.MetaClass;
   import org.apache.commons.simplestore.persistence.ObjectNotFound;
   import org.apache.commons.simplestore.persistence.Persistent;
   import org.apache.commons.simplestore.persistence.StorageException;
  @@ -85,16 +86,16 @@
   /**
    *@author     Juozas Baliuka <a href="mailto:baliuka@mwm.lt">
    *      baliuka@mwm.lt</a>
  - *@version    $Id: DBStorage.java,v 1.2 2002/02/11 20:30:09 froehlich Exp $
  + *@version    $Id: DBStorage.java,v 1.3 2002/02/16 14:26:05 baliuka Exp $
    */
   public class DBStorage extends AbstractStorage {
  -
  +    
       private final static boolean DEBUG = true;
       private final static String CONNECTION = "org.apache.commons.simplestore.jdbc.DBStorage.connection";
       private static Properties procedures = new Properties();
       private Cache cache = null;
       private DataSource ds;
  -
  +    private MetaClass rootMetaClass = new MetaClassImpl();
       /**
        * Creates new DBStorageManager
        *
  @@ -103,10 +104,10 @@
       public DBStorage(DataSource ds) {
           this.ds = ds;
       }
  -
  +    
       // TODO must be converter interface
       public static Object toSQLType(Object object) {
  -
  +        
           if (object == null) {
               return null;
           }
  @@ -117,68 +118,19 @@
           if (object instanceof java.util.Date && !(object instanceof java.sql.Date)) {
               return new java.sql.Date(((java.util.Date) object).getTime());
           }
  -
  +        
           return object;
       }
  -
  -    // TODO must be mapping interface
  -
  -    public static String toSQLName(String clName) {
  -
  -        String result = clName.substring(clName.lastIndexOf('.') + 1, clName.length());
  -        StringBuffer sb = new StringBuffer();
  -        char cbuff[] = result.toCharArray();
  -
  -        for (int i = 0; i < cbuff.length; i++) {
  -
  -            if (Character.isUpperCase(cbuff[i])) {
  -                if (i != 0) {
  -                    sb.append("_" + cbuff[i]);
  -                } else {
  -                    sb.append(cbuff[i]);
  -                }
  -
  -            } else {
  -
  -                sb.append(Character.toUpperCase(cbuff[i]));
  -            }
  -
  -        }
  -
  -        return sb.toString();
  -    }
  -
  -    // TODO must be mapping interface
  -    public static String toPropertyName(String tblName) {
  -
  -        final String result = tblName;
  -        final StringBuffer sb = new StringBuffer();
  -        final char cbuff[] = result.toCharArray();
  -
  -        for (int i = 0; i < cbuff.length; i++) {
  -
  -            if (cbuff[i] == '_') {
  -
  -                sb.append(Character.toUpperCase(cbuff[++i]));
  -
  -            } else {
  -                if (i == 0) {
  -                    sb.append(Character.toUpperCase(cbuff[i]));
  -                } else {
  -                    sb.append(Character.toLowerCase(cbuff[i]));
  -                }
  -            }
  -
  -        }
  -
  -        return sb.toString();
  -    }
  -// TODO :  must be more simple
  +    
  +    
  +    
  +    
  +    // TODO :  must be more simple
       public static int excecute(Connection connection, String sql, Object[] args, ResultSetHandler eh) throws StorageException {
  -
  +        
           int result = 0;
           try {
  -
  +            
               final PreparedStatement statement = connection.prepareStatement(sql);
               ResultSet rs = null;
               if (DEBUG) {
  @@ -186,9 +138,9 @@
               }
               try {
                   if (args != null) {
  -
  +                    
                       for (int i = 1; i <= args.length; i++) {
  -
  +                        
                           if (args[i - 1] == null) {
                               statement.setNull(i, Types.OTHER);
                           } else {
  @@ -201,13 +153,13 @@
                   } else {
                       return statement.getUpdateCount();
                   }
  -
  +                
                   do {
                       if (rs != null && eh != null) {
  -
  +                        
                           ResultSetMetaData rsmd = rs.getMetaData();
                           int cnt = rsmd.getColumnCount();
  -
  +                        
                           while (rs.next()) {
                               result++;
                               for (int i = 1; i <= cnt; i++) {
  @@ -216,7 +168,7 @@
                                   eh.nextResult(i, name, val, rsmd.getColumnType(i));
                               }
                           }
  -
  +                        
                       }
                       if (statement.getMoreResults()) {
                           rs = statement.getResultSet();
  @@ -225,7 +177,7 @@
                       }
                   } while (rs != null);
               } finally {
  -
  +                
                   if (rs != null) {
                       rs.close();
                   }
  @@ -238,212 +190,219 @@
           }
           return result;
       }
  -
  +    
       public void setContext(Cache cache) {
           this.cache = cache;
       }
  -
  -
  +    
  +    
       public Class getReturnType(Class clasz, String name) throws Throwable {
           try {
  -
  +            
               return clasz.getMethod(name, null).getReturnType();
           } catch (NoSuchMethodException nsme) {
  -
  +            
               throw new NoSuchMethodException("Method " + name + " not found in class " + clasz.getName() + " " + nsme.getMessage());
           }
  -
  +        
       }
  -
  +    
       public void registerClass(Class clasz) {
  -
  +        
           try {
  -
  +            
               ResourceBundle bundle = ResourceBundle.getBundle(clasz.getName() + "Procedures");
               Enumeration enum = bundle.getKeys();
  -
  +            
               while (enum.hasMoreElements()) {
                   Object key = enum.nextElement();
                   procedures.setProperty(key.toString(), bundle.getString(key.toString()));
               }
  -
  +            
           } catch (Exception e) {
               e.printStackTrace();
           }
       }
  -
  +    
       public Object retrieveObject(final Class clasz, Object id) throws StorageException {
  -
  +        
           final InternalTransaction transaction = getTransaction();
           Persistent result = (Persistent) cache.get(id);
  -
  +        
           if (result != null) {
               transaction.add(result.getMetaObject());
               return result;
           }
  -
  +        
           final Connection connection = getConnection();
  +        final MetaClass mClass =  rootMetaClass.forClass(clasz);
  +        final java.beans.PropertyDescriptor[] descriptors = mClass.getProperties();
           // TODO : ID must be in some mapping
  -        final String sql = "SELECT * FROM " + toSQLName(clasz.getName()) + " WHERE ID=?";
  -        result = (Persistent) PersistentProxy.getPersitent(clasz, id, false, this);
  +        final String sql = "SELECT * FROM " + mClass.getName() + " WHERE ID=?";
  +        result = (Persistent) mClass.newInstance( id, false );
           final MetaObject pc = result.getMetaObject();
           final Map map = pc.getProperties();
  -
  +        
           ResultSetHandler rsh =
  -            new ResultSetHandler() {
  -
  -                public void nextResult(int index, String name, Object value, int type) throws StorageException {
  -
  -                    try {
  -                        if (value != null) {
  -                            String property = toPropertyName(name);
  -                            if (property.equals("Id")) {
  -                                return;
  -                            }
  -                            map.put(property, PersistentProxy.convert(value, getReturnType(clasz, "get" + property)));
  +        new ResultSetHandler() {
  +            
  +            public void nextResult(int index, String name, Object value, int type) throws StorageException {
  +                
  +                try {
  +                    int propIndex =  mClass.getPropertyIndex( name );
  +                    if (value != null) {
  +                        String property = descriptors[ propIndex ].getName();
  +                        if (property.equals("Id")) {
  +                            return;
                           }
  -                    } catch (Throwable t) {
  -                        t.printStackTrace();
  -                        throw new StorageException(t.getMessage(), t);
  +                        map.put(property, value );
                       }
  +                } catch (Throwable t) {
  +                    t.printStackTrace();
  +                    throw new StorageException(t.getMessage(), t);
                   }
  -
  -            };
  -
  +            }
  +            
  +        };
  +        
           if (excecute(connection, sql, new Object[]{id}, rsh) == 0) {
               throw new ObjectNotFound(pc.getOID().toString(), null);
           }
  -
  +        
           transaction.add(pc);
           cache.put(id, result);
  -
  +        
           return result;
       }
  -
  +    
       public Set retrieveAll(final Class clasz) throws StorageException {
  -
  +        
           final Connection connection = getConnection();
  -        // TODO : INTERNAL_OID must be in some mapping
  -        final String sql = "SELECT ID AS INTERNAL_OID, * FROM " + toSQLName(clasz.getName());
  +        final MetaClass mClass =  rootMetaClass.forClass(clasz);
  +        final String sql = "SELECT ID AS INTERNAL_OID, * FROM " + mClass.getName();
           final Set objects = new HashSet();
           final InternalTransaction transaction = getTransaction();
  -
  +        
           excecute(connection, sql, null, new QueryHandler(objects, clasz));
  -
  +        
           return objects;
       }
  -
  -
  +    
  +    
       public Set query(final Class clasz, String proc, Object[] args) throws StorageException {
  -
  +        
           final Connection connection = getConnection();
           final Set objects = new HashSet();
           final InternalTransaction transaction = getTransaction();
           proc = procedures.getProperty(proc);
  -
  +        
           excecute(connection, proc, args, new QueryHandler(objects, clasz));
  -
  +        
           return objects;
       }
  -
  -
  +    
  +    
       public void storeObject(MetaObject properties) throws StorageException {
  -
  +        
           final Connection connection = getConnection();
           final Class clasz = properties.getPersistentClass();
  -        final String name = toSQLName(clasz.getName());
  -        final Method methods[] = clasz.getMethods();
  -        final List values = new ArrayList(methods.length / 2 + 1);
  +        final MetaClass mClass =  rootMetaClass.forClass(clasz);
  +        final String name = mClass.getName();
  +        final java.beans.PropertyDescriptor[] beanProps = mClass.getProperties();
  +        final List values = new ArrayList( beanProps.length + 1);
           final Map map = properties.getProperties();
  -        final StringBuffer names = new StringBuffer(methods.length * 10);
  -
  -        for (int i = 0; i < methods.length; i++) {
  -
  -            String mName = methods[i].getName();
  -            if (mName.startsWith("set")) {
  -                mName = mName.substring(3);
  -                Object value = toSQLType(map.get(mName));
  -                names.append(toSQLName(mName));
  +        final StringBuffer names = new StringBuffer( beanProps.length * 10 );
  +        
  +        
  +        for (int i = 0; i < beanProps.length; i++) {
  +            
  +            java.beans.PropertyDescriptor descriptor = beanProps[i];
  +            if (descriptor.getWriteMethod() != null) {
  +                Object value = toSQLType(map.get(descriptor.getName()));
  +                names.append( mClass.getPropertyName(i) );
                   names.append("=?,");
                   values.add(value);
  -
  +                
               }
           }
           names.setCharAt(names.length() - 1, ' ');
           // TODO : ID must be in some mapping
           names.append("WHERE ID=?");
           values.add(properties.getOID());
  -
  +        
           final String sql = "UPDATE " + name + " SET " + names;
  -
  +        
           if (excecute(connection, sql, values.toArray(), null) == 0) {
               throw new ObjectNotFound(properties.getOID().toString(), null);
           }
       }
  -
  +    
       // TODO : mot very meanigful here
       public void close() {
  -
  +        
           try {
  -
  +            
               Connection connection = (Connection) getTransaction().getAttribute(CONNECTION);
               if (connection != null) {
                   connection.close();
               }
           } catch (Exception e) {
  -
  +            
               e.printStackTrace();
               // TODO
           }
       }
  -
  +    
       protected void createObject(MetaObject properties) throws StorageException {
  -
  +        
           final Connection connection = getConnection();
           final Class clasz = properties.getPersistentClass();
  +        final MetaClass mClass =  rootMetaClass.forClass(clasz);
  +        final String name = mClass.getName();
           final Object id = properties.getOID();
  -        final Method methods[] = clasz.getMethods();
  +        final java.beans.PropertyDescriptor[] beanProps = mClass.getProperties();
           final Map map = properties.getProperties();
  -        final List values = new ArrayList(methods.length / 2 + 1);
  -
  +        final List values = new ArrayList( beanProps.length + 1 );
  +        
           String names = "";
           String params = "";
           values.add(id);
  -
  -        for (int i = 0; i < methods.length; i++) {
  -
  -            String name = methods[i].getName();
  -            if (name.startsWith("set")) {
  -                name = name.substring(3);
  -                Object value = toSQLType(map.get(name));
  +        
  +        for (int i = 0; i < beanProps.length; i++) {
  +            
  +            java.beans.PropertyDescriptor descriptor = beanProps[i];
  +            if (descriptor.getWriteMethod() != null) {
  +                
  +                Object value = toSQLType(map.get(descriptor.getName()));
                   if (value == null) {
                       continue;
                   }
  -                names += "," + toSQLName(name);
  +                names += "," + mClass.getPropertyName(i);
                   values.add(value);
                   params += ",?";
               }
           }
           //TODO : ID !!!
  -        final String sql = "INSERT INTO " + toSQLName(clasz.getName()) + "(ID" + names + ")VALUES(?" + params + ")";
  -
  +        final String sql = "INSERT INTO " + name + "(ID" + names + ")VALUES(?" + params + ")";
  +        
           excecute(connection, sql, values.toArray(), null);
  -
  +        
       }
  -
  +    
       protected void removeObject(MetaObject obj) throws StorageException {
  -
  +        
           final Connection connection = getConnection();
  -        final String name = toSQLName(obj.getPersistentClass().getName());
  +        final MetaClass mClass =  rootMetaClass.forClass(obj.getPersistentClass());
  +        final String name = mClass.getName();
           final Object id = obj.getOID();
           // TODO : ID must be in some mapping
           final String sql = "DELETE FROM " + name + " WHERE ID=?";
  -
  +        
           if (excecute(connection, sql, new Object[]{id}, null) == 0) {
               throw new ObjectNotFound(obj.getOID().toString(), null);
           }
       }
  -
  +    
       protected void internalCommit() throws StorageException {
           try {
               Connection connection = getConnection();
  @@ -456,9 +415,9 @@
               throw new StorageException(se.getMessage(), se);
           }
       }
  -
  +    
       protected void internalRollback() throws StorageException {
  -
  +        
           try {
               Connection connection = getConnection();
               try {
  @@ -467,47 +426,50 @@
                   connection.close();
               }
           } catch (SQLException se) {
  -
  +            
               throw new StorageException(se.getMessage(), se);
           }
       }
  -
  +    
       protected void internalBegin() throws StorageException {
           try {
               Connection connection = ds.getConnection();
               getTransaction().setAttribute(CONNECTION, connection);
  -
  +            
           } catch (SQLException se) {
               throw new StorageException(se.getMessage(), se);
           }
       }
  -
  +    
       private Connection getConnection() {
  -
  +        
           Connection connection = (Connection) getTransaction().getAttribute(CONNECTION);
  -
  +        
           if (connection == null) {
               throw new IllegalStateException("Transaction not Started");
           }
  -
  +        
           return connection;
       }
  -
  +    
       class QueryHandler implements ResultSetHandler {
  +        
           Map map;
           Set objects;
  -        Class clasz;
  +        MetaClass mClass ;
           InternalTransaction transaction = getTransaction();
  -
  +        java.beans.PropertyDescriptor[] descriptors;
  +        
           QueryHandler(Set objects, Class clasz) {
               this.objects = objects;
  -            this.clasz = clasz;
  +            this.mClass =  rootMetaClass.forClass(clasz);
  +            this.descriptors = mClass.getProperties();
           }
  -
  +        
           public void nextResult(int index, String name, Object value, int type) throws StorageException {
               try {
                   if (index == 1) {
  -
  +                    
                       Persistent p = (Persistent) cache.get(value);
                       if (p != null) {
                           map = null;
  @@ -515,31 +477,33 @@
                           transaction.add(p.getMetaObject());
                           return;
                       }
  -                    p = PersistentProxy.getPersitent(clasz, value, false, DBStorage.this);
  +                    p = mClass.newInstance( value, false );
                       MetaObject pc = p.getMetaObject();
                       map = pc.getProperties();
                       objects.add(p);
                       transaction.add(pc);
                       return;
                   }
  -                String property = toPropertyName(name);
                   // TODO : ID must be in some mapping
  -                if (property.equals("Id") || map == null) {
  +                if ( name.toUpperCase().equals("ID") || map == null) {
                       return;
                   }
  -                map.put(property, PersistentProxy.convert(value, getReturnType(clasz, "get" + property)));
  -
  +                String property =  descriptors[ mClass.getPropertyIndex( name ) ].getName();
  +                Class propType  =  descriptors[ mClass.getPropertyIndex( name ) ].getPropertyType();
  +                
  +                map.put(property, value);
  +                
               } catch (Throwable t) {
                   t.printStackTrace();
                   throw new StorageException(t.getMessage(), t);
               }
           }
       }
  -
  -
  +    
  +    
       interface ResultSetHandler {
           public void nextResult(int index, String name, Object value, int type) throws StorageException;
       }
  -
  +    
   }
   
  
  
  
  1.3       +85 -81    jakarta-commons-sandbox/simplestore/src/java/org/apache/commons/simplestore/persistence/impl/PersistentProxy.java
  
  Index: PersistentProxy.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/simplestore/src/java/org/apache/commons/simplestore/persistence/impl/PersistentProxy.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- PersistentProxy.java	11 Feb 2002 20:30:09 -0000	1.2
  +++ PersistentProxy.java	16 Feb 2002 14:26:05 -0000	1.3
  @@ -70,20 +70,20 @@
   /**
    *@author     Juozas Baliuka <a href="mailto:baliuka@mwm.lt">
    *      baliuka@mwm.lt</a>
  - *@version    $Id: PersistentProxy.java,v 1.2 2002/02/11 20:30:09 froehlich Exp $
  + *@version    $Id: PersistentProxy.java,v 1.3 2002/02/16 14:26:05 baliuka Exp $
    */
   public class PersistentProxy
  -         implements MetaObject, InvocationHandler, Cloneable, Serializable {
  -
  +implements MetaObject, InvocationHandler, Cloneable, Serializable {
  +    
       private static Method HASH_CODE;
       private static Method EQUALS;
       private static Method TO_STRING;
       private static Method GET_OID;
       private static Method GET_META_OBJECT;
       private static Map defaults = new Hashtable();
  -
  +    
       Map map = new HashMap();
  -
  +    
       Object oid = null;
       Persistent object;
       Class pClass;
  @@ -91,8 +91,8 @@
       boolean dirty = false;
       boolean deleted = false;
       boolean newCreated;
  -
  -
  +    
  +    
       /**
        * Creates new ValueProxy
        *
  @@ -102,22 +102,22 @@
        *@param  transactionManager
        */
       public PersistentProxy(Class pClass, Object oid, boolean newCreated, TransactionManager transactionManager) {
  -
  +        
           this.oid = oid;
           this.newCreated = newCreated;
           this.transactionManager = transactionManager;
           this.pClass = pClass;
  -
  +        
       }
  -
  +    
       // TODO : "next" interceptor as parameter
       public static Persistent getPersitent(Class persistent, Object oid, boolean newCreated, TransactionManager transactionManager) {
           PersistentProxy handler = new PersistentProxy(persistent, oid, newCreated, transactionManager);
           Persistent p = (Persistent) Proxy.newProxyInstance(
  -                Thread.currentThread().getContextClassLoader(), new Class[]{persistent, Persistent.class}, handler);
  +        Thread.currentThread().getContextClassLoader(), new Class[]{persistent, Persistent.class}, handler);
           handler.object = p;
           if (newCreated) {
  -
  +            
               MetaObject mo = p.getMetaObject();
               transactionManager.getTransaction().add(mo);
           }
  @@ -125,7 +125,7 @@
       }
       // TODO must be converter interface
       public static Object convertNumber(Number number, Class cls) {
  -
  +        
           if (cls.equals(Byte.class)) {
               return new Byte(number.byteValue());
           } else if (cls.equals(Short.class)) {
  @@ -145,11 +145,11 @@
           } else {
               throw new UnsupportedOperationException("Number class = " + number.getClass().getName() + " Target Class " + cls.getName());
           }
  -
  +        
       }
       // TODO must be converter interface
       public static Object convertPrimityve(Number number, Class cls) {
  -
  +        
           if (cls.equals(Byte.TYPE)) {
               return new Byte(number.byteValue());
           } else if (cls.equals(Short.TYPE)) {
  @@ -169,45 +169,48 @@
           } else {
               throw new UnsupportedOperationException("Number class = " + number.getClass().getName() + " Target Class " + cls.getName());
           }
  -
  +        
       }
  -    // TODO must be converter interface
  -    public static Object convert(Object object, Class cls) {
  +    
  +    static Object convert(Object object, Class cls) {
           try {
  +            
               if (cls.isPrimitive()) {
                   if (object == null) {
                       return defaults.get(cls);
                   }
  +                
  +                if (cls.isAssignableFrom(object.getClass())) {
  +                    return object;
  +                }
  +                
                   if (object instanceof Number) {
                       return convertPrimityve((Number) object, cls);
                   }
               }
  -
  +            
               if (object == null) {
                   return null;
               }
  -
  +            
               if (cls.isAssignableFrom(object.getClass())) {
                   return object;
               }
  -
  -            // if( object instanceof String ){ ?????
  -            //     return org.apache.commons.beanutils.ConvertUtils.convert((String)object,cls);
  -            // }
  -
  -
  +            
  +            
  +            
               if (cls.isAssignableFrom(Number.class) && object instanceof Number) {
                   return convertNumber((Number) object, cls);
               }
  -
  +            
               if (cls.equals(Boolean.class) && object instanceof Number) {
                   return new Boolean(((Number) object).intValue() != 0);
               }
  -
  +            
               if (cls.equals(Character.TYPE)) {
                   return new Character(object.toString().charAt(0));
               }
  -
  +            
               throw new UnsupportedOperationException(cls.getName() + ":" + object);
           } catch (Throwable t) {
               // TODO
  @@ -215,156 +218,157 @@
               throw new RuntimeException(t.getClass().getName() + ":" + t.getMessage());
           }
       }
  -
  +    
       public void setProperty(String name, Object value) {
  -
  +        
           Object old = map.put(name, value);
           if (old == null || !old.equals(value)) {
               dirty = true;
               transactionManager.getTransaction().add(this);
           }
       }
  -
  +    
       public void setDirty(boolean dirty) {
           this.dirty = dirty;
           this.newCreated = false;
       }
  -
  -
  +    
  +    
       public boolean isDeleted() {
           return deleted;
       }
  -
  +    
       public boolean isNew() {
           return newCreated;
       }
  -
  +    
       public MetaObject getMetaObject() {
           return this;
       }
  -
  +    
       public Map getProperties() {
           return map;
       }
  -
  +    
       public Object getProperty(String name) {
           return map.get(name);
       }
  -
  +    
       public boolean isLoaded() {
           return true;
       }
  -
  +    
       public Class getPersistentClass() {
           return pClass;
       }
  -
  +    
       public Object getOID() {
           return oid;
       }
  -
  +    
       public boolean isDirty() {
           return dirty;
       }
  -
  +    
       public Persistent getObject() {
           return object;
       }
  -
  +    
       public MetaClass getMetaClass() {
           throw new UnsupportedOperationException("Not implemented");
       }
  -
  +    
       public Object handleEquals(Object obj) {
  -
  +        
           if (obj == null) {
               return new Boolean(false);
           }
  -
  +        
           if (!(obj instanceof Persistent)) {
               return new Boolean(false);
           }
  -
  +        
           Persistent object = (Persistent) obj;
  -
  +        
           if (oid == null) {
  -
  +            
               return new Boolean(oid == object.getOID());
           } else {
  -
  +            
               return new Boolean(oid.equals(object.getOID()));
           }
  -
  +        
       }
  -
  +    
       public Object invoke(Object obj, Method method, Object[] obj2) throws Throwable {
  -
  +        
           synchronized (this) {
  -
  +            
               if (GET_META_OBJECT.equals(method)) {
                   return this;
               } else if (TO_STRING.equals(method)) {
  -
  +                
                   return oid + "";
               } else if (GET_OID.equals(method)) {
  -
  +                
                   return oid;
               } else if (HASH_CODE.equals(method)) {
  -
  +                
                   if (oid == null) {
                       return new Integer(0);
                   }
                   return new Integer(oid.hashCode());
               } else if (EQUALS.equals(method)) {
  -
  +                
                   return handleEquals(obj2[0]);
               } else {
  -
  +                
                   return handleProperty(obj, method, obj2);
               }
  -
  +            
           }
       }
  -
  -
  +    
  +    
       public Object handleProperty(Object obj, Method method, Object[] obj2) throws Throwable {
  -
  +        
           String name = method.getName();
  -
  +        
           if (name.startsWith("set")) {
  -
  +            
               setProperty(name.substring(3), obj2[0]);
               return null;
           } else if (name.startsWith("get") || name.startsWith("is")) {
  -
  +            
               if (method.getName().startsWith("get")) {
                   name = method.getName().substring(3);
               } else {
                   name = method.getName().substring(2);
               }
  -            Object value = getProperty(name);
  -            if (value == null && method.getReturnType().isPrimitive()) {
  -                value = convert(value, method.getReturnType());
  -            }
  -            return value;
  +            
  +            return convert( getProperty(name) ,method.getReturnType() );
  +            
           }
  -
  +        
  +        
  +        
  +        
           throw new IllegalStateException("pure method " + method.getName());
       }
  -
  +    
       public void remove() {
           deleted = true;
       }
  -
  +    
       public Object clone() throws CloneNotSupportedException {
           PersistentProxy cln = (PersistentProxy) super.clone();
           cln.dirty = false;
           map = (Map) ((HashMap) map).clone();
           return cln;
       }
  -
  +    
       public void assign(MetaObject mo) {
  -
  +        
           map.clear();
           map.putAll(mo.getProperties());
           oid = mo.getOID();
  @@ -374,16 +378,16 @@
           deleted = mo.isDeleted();
           newCreated = mo.isNew();
       }
  -
  +    
       static {
           try {
               GET_OID = Persistent.class.getMethod("getOID", null);
               GET_META_OBJECT = Persistent.class.getMethod("getMetaObject", null);
  -
  +            
               HASH_CODE = Object.class.getMethod("hashCode", null);
               TO_STRING = Object.class.getMethod("toString", null);
               EQUALS = Object.class.getMethod("equals", new Class[]{Object.class});
  -
  +            
               defaults.put(byte.class, new Byte((byte) 0));
               defaults.put(short.class, new Short((short) 0));
               defaults.put(int.class, new Integer(0));
  @@ -392,7 +396,7 @@
               defaults.put(double.class, new Double(0));
               defaults.put(char.class, new Character('\u0000'));
               defaults.put(boolean.class, new Boolean(false));
  -
  +            
           } catch (Exception e) {
               e.printStackTrace();
               throw new Error(e.getMessage());
  
  
  
  1.1                  jakarta-commons-sandbox/simplestore/src/java/org/apache/commons/simplestore/persistence/impl/MetaClassImpl.java
  
  Index: MetaClassImpl.java
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache Cocoon" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  package org.apache.commons.simplestore.persistence.impl;
  
  import java.lang.reflect.Method;
  import org.apache.commons.simplestore.persistence.*;
  
  /**
   * Meta data
   *
   *@author     Juozas Baliuka <a href="mailto:baliuka@mwm.lt">
   *     baliuka@mwm.lt</a>
   *@version    $Id: MetaClassImpl.java,v 1.1 2002/02/16 14:26:05 baliuka Exp $
   */
  public class MetaClassImpl implements MetaClass {
      
      private static java.util.Map persitentClasses = new java.util.Hashtable();
      private Class clasz;
      private String sqlName;
      private java.util.Map properties = new java.util.Hashtable();
      private java.beans.PropertyDescriptor[] descriptors;
      private TransactionManager transactionManager;
      private int oidIndex[] = {0};
      /** Creates new MetaClassImpl */
      public MetaClassImpl(){
          
      }
      
      private MetaClassImpl(Class clasz) {
          this.clasz = clasz;
          this.sqlName = toSQLName(clasz.getName());
          indexMethods();
          if( persitentClasses.put( clasz, this ) != null )
              throw new java.lang.IllegalStateException("Dublicate MetaClass for " + clasz.getName());
          
      }
      
      /**
       * return field name for DB storage
       *
       * @param  index  property index
       * @return        field name
       */
      public String getPropertyName(int index) {
          return toSQLName(descriptors[ index ].getName());
      }
      
      
      public Persistent newInstance(Object oid, boolean create) {
          
          return PersistentProxy.getPersitent(clasz, oid , create , transactionManager );
      }
      
      /**
       * Returns Table name for DB storage
       *
       * @return    name in storage
       */
      public String getName() {
          return sqlName;
      }
      
      
      /**
       * Some jdbc type for DB storage
       *
       * @param  index  property index
       * @return        type
       */
      public Class getPropertyType(int index) {
          // TODO : must return JDBC type
          return descriptors[index].getPropertyType();
      }
      
      /**
       * Factory method
       *
       * @param  clasz  used defined interface Class
       * @return        Meta data for class
       */
      public MetaClass forClass(Class clasz) {
          MetaClass mc =  (MetaClass)persitentClasses.get(clasz);
          if( mc == null ){
              mc = new MetaClassImpl(clasz);
          }
          return mc;
          
      }
      
      public Persistent newInstance(Object oid, boolean create, java.lang.ClassLoader cl) {
          //TODO :
          return PersistentProxy.getPersitent(clasz, oid , create , transactionManager );
      }
      
      
      
      /**
       * forClass(clasz).getPersitentClass().equals(clasz) must return true
       *
       * @return    User defined persitent class
       */
      public Class getPersitentClass() {
          return clasz;
      }
      
      private void indexMethods(){
          try{
              
              descriptors = java.beans.Introspector.getBeanInfo( clasz ).getPropertyDescriptors();
              
              for( int i = 0; i < descriptors.length; i++ ){
                  
                  properties.put( toSQLName(descriptors[i].getName()),new Integer(i) );
                  
              }
          }catch( java.lang.Throwable t ){
              //TODO :
              throw new java.lang.RuntimeException(t.getLocalizedMessage());
          }
          
      }
      
      
      
      static String toSQLName(String clName) {
          
          String result = clName.substring(clName.lastIndexOf('.') + 1, clName.length());
          StringBuffer sb = new StringBuffer();
          char cbuff[] = result.toCharArray();
          
          for (int i = 0; i < cbuff.length; i++) {
              
              if (Character.isUpperCase(cbuff[i])) {
                  if (i != 0) {
                      sb.append("_" + cbuff[i]);
                  } else {
                      sb.append(cbuff[i]);
                  }
                  
              } else {
                  
                  sb.append(Character.toUpperCase(cbuff[i]));
              }
              
          }
          
          return sb.toString();
      }
      
      
      static String toPropertyName(String tblName) {
          
          final String result = tblName;
          final StringBuffer sb = new StringBuffer();
          final char cbuff[] = result.toCharArray();
          
          for (int i = 0; i < cbuff.length; i++) {
              
              if (cbuff[i] == '_') {
                  
                  sb.append(Character.toUpperCase(cbuff[++i]));
                  
              } else {
                  if (i == 0) {
                      sb.append(Character.toUpperCase(cbuff[i]));
                  } else {
                      sb.append(Character.toLowerCase(cbuff[i]));
                  }
              }
              
          }
          
          return sb.toString();
      }
      
      /**
       * returns index for property
       *
       * @param  method  read or write method
       * @return         index
       */
      public int getPropertyIndex(String field) {
          Integer index = (Integer)properties.get(field);
          return index.intValue();
          
      }
      
      public java.beans.PropertyDescriptor[] getProperties() {
          return descriptors;
      }
      
  }
  
  
  

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>