insert時の型チェックを可能にする。(はしりがき)

今回作成したファイル

ソースコード

サンプルコード
package example;

import net.java.ao.*;
import net.java.ao.db.*;
import java.util.logging.*;
import java.util.*;

public class InsertTest {
        public static void main( String args ) throws Exception {
            Class.forName("com.mysql.jdbc.Driver");
            EntityManager manager = new EntityManager(
                    new MySQLDatabaseProvider(
                    "jdbc:mysql://192.168.1.19:3306/ao",
                    "root", "root"));
                        Logger.getLogger("net.java.ao").setLevel(Level.FINE);

                        // *** insert START ***
                        User newUser = (User) InsertProxy.get( User.class );
                        newUser.setName( "NEW_NAME" );
                        newUser.setUser_mail( "NEW_MAIL" );
                        manager.create( User.class, (Map) newUser );
                        // *** insert END ***

                        User userList = manager.find( User.class );
                        for ( User user : userList ) {
                                System.out.println( user.getUser_id() );
                                System.out.println( user.getName() );
                                System.out.println( user.getUser_mail() );
                        }
        }
}
エンティティ
package example;

import net.java.ao.*;
import net.java.ao.schema.*;

@Preload( { "name", "user_mail" } )
public interface User extends RawEntity {
        @NotNull
        @PrimaryKey("user_id")
        @Generator(UserIdGenerator.class)
        public String getUser_id();
        public String getName();
        public String getUser_mail();

        public void setUser_id( String user_id );
        public void setName( String name );
        public void setUser_mail( String mail );
}
Proxy
package example;

import java.lang.reflect.*;
import java.util.*;

public class InsertProxy {
        public static Object get( Class klass ) {
                try {
                        InvocationHandler handler = new InsertHandler( klass );
                        Class proxyClass = Proxy.getProxyClass(
                                klass.getClassLoader(), new Class { Map.class, klass }
                        );

                        return proxyClass
                                .getConstructor( new Class { InvocationHandler.class })
                                .newInstance(new Object[] { handler });
                } catch ( Exception e ) {
                        throw new RuntimeException( e );
                }
        }
}
InvocationHandler(公開不要)
package example;

import java.lang.reflect.*;
import java.util.*;

public class InsertHandler implements InvocationHandler {

        private Class entityType;
        private HashMap map;

        public InsertHandler( Class entityType ) {
                this.entityType = entityType;
                map = new HashMap();
        }

        public Object invoke( Object proxy, Method argMethod, Object args ) {

                String argMethodName = argMethod.getName();

                // Mapクラスからメソッドを探す。
                Method mapMethods = Map.class.getMethods();
                for ( Method mapMethod : mapMethods ) {
                        // Mapクラスに該当メソッドがある。
                        if ( mapMethod.equals( argMethod ) ) {
                                // Mapクラスのメソッドを呼び出す。
                                try {
                                        return mapMethod.invoke( map, args );
                                } catch ( Exception e ) {
                                        throw new RuntimeException( e );
                                }
                        }
                }

                // メソッドがセッターであることを確認する。
                if ( argMethodName.startsWith( "set" ) ) {
                        // setterの名前から、プロパティ名を取得する。
                        String prop = toPropertyName( argMethodName );
                        // プロパティをキーとして、引数をマップに格納する。
                        map.put( prop, args[0] );

                        return null;
                }

                // メソッドがゲッターであることを確認する。
                if ( argMethodName.startsWith( "get" ) ) {
                        // getterの名前から、プロパティ名を取得する。
                        String prop = toPropertyName( argMethodName );
                        // プロパティをキーとして値を取得する。
                        return map.get( prop );
                }

                throw new RuntimeException( "no method" );
        }

        /**
         * getter/setterの名前からプロパティ名を取得する。
         */
        private String toPropertyName( String methodName ) {
                String s = methodName.substring( 3 );
                char c = s.charAt( 0 );
                return Character.toLowerCase( c ) + s.substring( 1 );
        }
}