package org.jboss.loom.migrators._ext;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Modifier;
import javassist.CannotCompileException;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtConstructor;
import javassist.NotFoundException;
import org.jboss.loom.conf.GlobalConfiguration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

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

    
    static Class<? extends DefinitionBasedMigrator> createClass( String fullName )
            throws NotFoundException, CannotCompileException
    {
        ClassPool pool = ClassPool.getDefault();
        
        // Create the class.
        CtClass cc = pool.makeClass( fullName );
        final CtClass superClass = pool.get( DefinitionBasedMigrator.class.getName() );
        cc.setSuperclass( superClass );
        cc.setModifiers( Modifier.PUBLIC );
        
        // Add a constructor which will call super( ... );
        CtClass[] params = new CtClass[]{
            pool.get( MigratorDefinition.class.getName() ),
            pool.get( GlobalConfiguration.class.getName()) 
        };
        final CtConstructor ctor = new CtConstructor( params, cc );
        //ctor.setBody(" super(); ");
        ctor.setBody( superClass.getDeclaredConstructor( params ), null );
        cc.addConstructor( ctor );
        
        // Add getter which will return the migrator id (e.g. "datasources")
        
        return cc.toClass();
    }


    /**
     *  Instantiates given DefinitionBasedMigrator subclass and initializes it according to given migrator definition.
     */
    static DefinitionBasedMigrator instantiate( 
            Class<? extends DefinitionBasedMigrator> migClass, 
            MigratorDefinition def, 
            GlobalConfiguration globConf 
    )
            throws NoSuchMethodException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException 
    {
        Constructor<? extends DefinitionBasedMigrator> ctor = migClass.getConstructor( MigratorDefinition.class, GlobalConfiguration.class );
        if( ctor == null)
            throw new IllegalArgumentException("Class doesn't have constructor ( MigratorDefinition, GlobalConfiguration ): "
                    + migClass.getName() );
        
        DefinitionBasedMigrator mig = ctor.newInstance( def, globConf );
        return mig;
    }
    
}// class

@@ -277,32 +277,93 @@
 .CtConstructor;%0A
+import javassist.CtField;%0Aimport javassist.CtNewConstructor;%0A
 import javassist
@@ -1046,18 +1046,24 @@
 CtClass 
-cc
+subClass
  = pool.
@@ -1177,26 +1177,32 @@
  );%0A        
-cc
+subClass
 .setSupercla
@@ -1227,18 +1227,24 @@
         
-cc
+subClass
 .setModi
@@ -1510,32 +1510,34 @@
      %7D;%0A        
+//
 final CtConstruc
@@ -1626,16 +1626,18 @@
         
+//
 ctor.set
@@ -1707,34 +1707,527 @@
     
-cc.addConstructor( ctor );
+final CtConstructor ctor = CtNewConstructor.make( params, null, CtNewConstructor.PASS_PARAMS, null, null, subClass );%0A        subClass.addConstructor( ctor );%0A        %0A        // Add a static field containing the definition. // Nonsense... probably unachievable.%0A        /*final CtClass defClass = pool.get( MigratorDefinition.class.getName() );%0A        CtField defField = new CtField( defClass, %22DEF%22, subClass );%0A        defField.setModifiers( Modifier.STATIC );%0A        subClass.addField( CtField.Initializer. );/**/
 %0A   
@@ -2333,18 +2333,24 @@
  return 
-cc
+subClass
 .toClass
@@ -2488,16 +2488,166 @@
 nition.%0A
+     *  @deprecated   Duplicates code in MigratorEngine.java.%0A     *                On the other hand, that one doesn't supply migrator definition...%0A
      */%0A

Improve MigratorSubclassMaker - add constructor which calls super( ... )