package org.jboss.loom.migrators._ext;

import java.lang.reflect.Modifier;
import javassist.CannotCompileException;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.NotFoundException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 *  Programatically creates subclasses of DefinitionBasedMigrator.
 * 
 *  @author Ondrej Zizka, ozizka at redhat.com
 */
public class MigratorSubclassMaker {
    private static final Logger log = LoggerFactory.getLogger( MigratorSubclassMaker.class );

    public static Class<? extends DefinitionBasedMigrator> createClass( String fullName )
            throws NotFoundException, CannotCompileException
    {
        ClassPool pool = ClassPool.getDefault();
        
        // Create the class.
        CtClass cc = pool.makeClass( fullName );
        cc.setSuperclass( pool.get(DefinitionBasedMigrator.class.getName()) );
        cc.setModifiers( Modifier.PUBLIC );
        
        // Add getter which will return the migrator id (e.g. "datasources")
        
        return cc.toClass();
    }
    

}// class

@@ -33,16 +33,106 @@
 ._ext;%0A%0A
+import java.lang.reflect.Constructor;%0Aimport java.lang.reflect.InvocationTargetException;%0A
 import j
@@ -253,16 +253,48 @@
 tClass;%0A
+import javassist.CtConstructor;%0A
 import j
@@ -317,24 +317,72 @@
 dException;%0A
+import org.jboss.loom.conf.GlobalConfiguration;%0A
 import org.s
@@ -549,16 +549,58 @@
 hat.com%0A
+ * %0A *  TODO: Perhaps extend ClassLoader?%0A
  */%0Apubl
@@ -731,22 +731,20 @@
 );%0A%0A    
-public
+%0A   
  static 
@@ -1030,25 +1030,34 @@
     
-cc.setS
+final CtClass s
 uper
-c
+C
 lass
-(
+ =
  poo
@@ -1062,16 +1062,17 @@
 ool.get(
+ 
 Definiti
@@ -1102,17 +1102,56 @@
 etName()
-)
+ );%0A        cc.setSuperclass( superClass
  );%0A    
@@ -1191,32 +1191,489 @@
 LIC );%0A        %0A
+        // Add a constructor which will call super( ... );%0A        CtClass%5B%5D params = new CtClass%5B%5D%7B%0A            pool.get( MigratorDefinition.class.getName() ),%0A            pool.get( GlobalConfiguration.class.getName()) %0A        %7D;%0A        final CtConstructor ctor = new CtConstructor( params, cc );%0A        //ctor.setBody(%22 super(); %22);%0A        ctor.setBody( superClass.getDeclaredConstructor( params ), null );%0A        cc.addConstructor( ctor );%0A        %0A
         // Add g
@@ -1777,21 +1777,950 @@
 ;%0A    %7D%0A
+%0A%0A
     
-%0A
+/**%0A     *  Instantiates given DefinitionBasedMigrator subclass and initializes it according to given migrator definition.%0A     */%0A    static DefinitionBasedMigrator instantiate( %0A            Class%3C? extends DefinitionBasedMigrator%3E migClass, %0A            MigratorDefinition def, %0A            GlobalConfiguration globConf %0A    )%0A            throws NoSuchMethodException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException %0A    %7B%0A        Constructor%3C? extends DefinitionBasedMigrator%3E ctor = migClass.getConstructor( MigratorDefinition.class, GlobalConfiguration.class );%0A        if( ctor == null)%0A            throw new IllegalArgumentException(%22Class doesn't have constructor ( MigratorDefinition, GlobalConfiguration ): %22%0A                    + migClass.getName() );%0A        %0A        DefinitionBasedMigrator mig = ctor.newInstance( def, globConf );%0A        return mig;%0A    %7D%0A    
 %0A%7D// cla

Improve MigratorSubclassMaker