
import uk.ac.ic.doc.automed.*;
import uk.ac.ic.doc.automed.reps.*;
import uk.ac.ic.doc.automed.templates.*;


/**
	An application that defines the "Table-Field Basic Equivalence" template transformation.
	This transformation should be applied on a schema of the "sql92" model.
	It creates a new table and a field for this table. The new field is the primary key of the 
	new table and a foreign key to an existing table, field.   
 
	The arguments for this transformation are:
	1. initial schema ID
	2. existing table ID
	3. existing field ID (field of table in the 2nd argument)
	4. new table name
	5. new field name
	6. new PK name
	7. new FK name
	8. new table ID (returned value)
	9. new field ID (returned value)
	10. new PK ID (returned value)
	11. new FK ID (returned value)
	12. final schema ID (returned value)
*/
public class FieldToTableBasic{
  private static String modelName="sql92";
  private static String tableConstructName="table";
  private static String fieldConstructName="field";
  private static String primaryKeyConstructName="primary_key";
  private static String foreignKeyConstructName="foreign_key";

	private static String templateName = "Table-Field Basic Equivalence";

	public static void defineTemplate()
		throws TemplateTransformationRepositoryException, RepositoryAccessException, TemplateTransformationSyntaxRepositoryException, AutoRepException, AutoMedException
	{
		try{
			CompositeTransformation.removeCompositeTransformation(templateName);
		}
		catch(TemplateTransformationRepositoryException exc){
			System.out.println("new transformation "+templateName);
		}

		Model rel = Model.getModel(modelName);
		Construct table = rel.getConstruct(tableConstructName);
		Construct field = rel.getConstruct(fieldConstructName);
		Construct pk = rel.getConstruct(primaryKeyConstructName);
		Construct fk = rel.getConstruct(foreignKeyConstructName);

		TemplateArgumentSequence newTableArgs = new TemplateArgumentSequence();	
		newTableArgs.createArgument(CompositeTransformation.ARG_CID_IN_NEWOBJECT, String.valueOf(table.getCID()));
		newTableArgs.createArgument(CompositeTransformation.ARG_VALUE_IN_NEWOBJECT, 4);
		newTableArgs.createArgument(CompositeTransformation.ARG_ISTEMP_IN_NEWOBJECT, "0");	
		TemplateArgumentSequence newTableScheme = new TemplateArgumentSequence();
		newTableScheme.createArgument(1, newTableArgs, CompositeTransformation.ARG_OBID_IN_NEWOBJECT);
		newTableArgs.createArgument(CompositeTransformation.ARG_SCHEME_IN_NEWOBJECT, String.valueOf(newTableScheme.getSequenceId()));

		TemplateArgumentSequence addNewTableArgs = new TemplateArgumentSequence();
		addNewTableArgs.createArgument(CompositeTransformation.ARG_ACTION_IN_PRIMITIVE, "add");
		addNewTableArgs.createArgument(CompositeTransformation.ARG_FROMOBJ_IN_PRIMITIVE, "-1");		
		addNewTableArgs.createArgument(CompositeTransformation.ARG_TOOBJ_IN_PRIMITIVE, newTableArgs, CompositeTransformation.ARG_OBID_IN_NEWOBJECT);
		addNewTableArgs.createArgument(CompositeTransformation.ARG_FROMSCHEMA_IN_PRIMITIVE, CompositeTransformation.ARG_SID_IN_NEWOBJECT);
		addNewTableArgs.createArgument(CompositeTransformation.ARG_TOSCHEMA_IN_PRIMITIVE, newTableArgs, CompositeTransformation.ARG_SID_IN_NEWOBJECT);
		addNewTableArgs.createArgument(CompositeTransformation.ARG_FUNCTION_IN_PRIMITIVE, "");
		addNewTableArgs.createArgument(CompositeTransformation.ARG_CONSTRAINTS_IN_PRIMITIVE, "");

		TemplateArgumentSequence newFieldArgs = new TemplateArgumentSequence();
		newFieldArgs.createArgument(CompositeTransformation.ARG_CID_IN_NEWOBJECT, String.valueOf(field.getCID()));
		newFieldArgs.createArgument(CompositeTransformation.ARG_VALUE_IN_NEWOBJECT, 5);
		newFieldArgs.createArgument(CompositeTransformation.ARG_ISTEMP_IN_NEWOBJECT, "0");
		TemplateArgumentSequence newFieldScheme = new TemplateArgumentSequence();
		newFieldScheme.createArgument(1, newTableArgs, CompositeTransformation.ARG_OBID_IN_NEWOBJECT);
		newFieldScheme.createArgument(2, newFieldArgs, CompositeTransformation.ARG_OBID_IN_NEWOBJECT);
		newFieldArgs.createArgument(CompositeTransformation.ARG_SCHEME_IN_NEWOBJECT, String.valueOf(newFieldScheme.getSequenceId())); 

		TemplateArgumentSequence addNewFieldArgs = new TemplateArgumentSequence();
		addNewFieldArgs.createArgument(CompositeTransformation.ARG_ACTION_IN_PRIMITIVE, "add");
		addNewFieldArgs.createArgument(CompositeTransformation.ARG_FROMOBJ_IN_PRIMITIVE, "-1");
		addNewFieldArgs.createArgument(CompositeTransformation.ARG_TOOBJ_IN_PRIMITIVE, newFieldArgs, CompositeTransformation.ARG_OBID_IN_NEWOBJECT);
		addNewFieldArgs.createArgument(CompositeTransformation.ARG_FROMSCHEMA_IN_PRIMITIVE, newTableArgs, CompositeTransformation.ARG_SID_IN_NEWOBJECT);
		addNewFieldArgs.createArgument(CompositeTransformation.ARG_TOSCHEMA_IN_PRIMITIVE, newFieldArgs, CompositeTransformation.ARG_SID_IN_NEWOBJECT);
		addNewFieldArgs.createArgument(CompositeTransformation.ARG_FUNCTION_IN_PRIMITIVE, "");
		addNewFieldArgs.createArgument(CompositeTransformation.ARG_CONSTRAINTS_IN_PRIMITIVE, "");

		TemplateArgumentSequence newPrimaryKeyArgs = new TemplateArgumentSequence();
		newPrimaryKeyArgs.createArgument(CompositeTransformation.ARG_CID_IN_NEWOBJECT, String.valueOf(pk.getCID()));
		newPrimaryKeyArgs.createArgument(CompositeTransformation.ARG_VALUE_IN_NEWOBJECT, 6);
		newPrimaryKeyArgs.createArgument(CompositeTransformation.ARG_ISTEMP_IN_NEWOBJECT, "0");
		TemplateArgumentSequence newPrimaryKeyScheme = new TemplateArgumentSequence();
		newPrimaryKeyScheme.createArgument(1, newPrimaryKeyArgs, CompositeTransformation.ARG_OBID_IN_NEWOBJECT);
		newPrimaryKeyScheme.createArgument(2, newTableArgs, CompositeTransformation.ARG_OBID_IN_NEWOBJECT);
		newPrimaryKeyScheme.createArgument(3, newFieldArgs, CompositeTransformation.ARG_OBID_IN_NEWOBJECT);
		newPrimaryKeyArgs.createArgument(CompositeTransformation.ARG_SCHEME_IN_NEWOBJECT, String.valueOf(newPrimaryKeyScheme.getSequenceId())); 

		TemplateArgumentSequence addNewPrimaryKeyArgs = new TemplateArgumentSequence();
		addNewPrimaryKeyArgs.createArgument(CompositeTransformation.ARG_ACTION_IN_PRIMITIVE, "add");
		addNewPrimaryKeyArgs.createArgument(CompositeTransformation.ARG_FROMOBJ_IN_PRIMITIVE, "-1");
		addNewPrimaryKeyArgs.createArgument(CompositeTransformation.ARG_TOOBJ_IN_PRIMITIVE, newPrimaryKeyArgs, CompositeTransformation.ARG_OBID_IN_NEWOBJECT);
		addNewPrimaryKeyArgs.createArgument(CompositeTransformation.ARG_FROMSCHEMA_IN_PRIMITIVE, newFieldArgs, CompositeTransformation.ARG_SID_IN_NEWOBJECT);
		addNewPrimaryKeyArgs.createArgument(CompositeTransformation.ARG_TOSCHEMA_IN_PRIMITIVE, newPrimaryKeyArgs, CompositeTransformation.ARG_SID_IN_NEWOBJECT);
		addNewPrimaryKeyArgs.createArgument(CompositeTransformation.ARG_FUNCTION_IN_PRIMITIVE, "");
		addNewPrimaryKeyArgs.createArgument(CompositeTransformation.ARG_CONSTRAINTS_IN_PRIMITIVE, "");


		TemplateArgumentSequence newForeignKeyArgs = new TemplateArgumentSequence();
		newForeignKeyArgs.createArgument(CompositeTransformation.ARG_CID_IN_NEWOBJECT, String.valueOf(fk.getCID()));
		newForeignKeyArgs.createArgument(CompositeTransformation.ARG_VALUE_IN_NEWOBJECT, 7);
		newForeignKeyArgs.createArgument(CompositeTransformation.ARG_ISTEMP_IN_NEWOBJECT, "0");
		TemplateArgumentSequence newForeignKeyScheme = new TemplateArgumentSequence();
		newForeignKeyScheme.createArgument(1, newForeignKeyArgs, CompositeTransformation.ARG_OBID_IN_NEWOBJECT);
		newForeignKeyScheme.createArgument(2, 2);
		newForeignKeyScheme.createArgument(3, 3); 
		newForeignKeyScheme.createArgument(4, newTableArgs, CompositeTransformation.ARG_OBID_IN_NEWOBJECT); 
		newForeignKeyScheme.createArgument(5, newFieldArgs, CompositeTransformation.ARG_OBID_IN_NEWOBJECT); 
		newForeignKeyArgs.createArgument(CompositeTransformation.ARG_SCHEME_IN_NEWOBJECT, String.valueOf(newForeignKeyScheme.getSequenceId()));

		TemplateArgumentSequence addNewForeignKeyArgs = new TemplateArgumentSequence();
		addNewForeignKeyArgs.createArgument(CompositeTransformation.ARG_ACTION_IN_PRIMITIVE, "add");
		addNewForeignKeyArgs.createArgument(CompositeTransformation.ARG_FROMOBJ_IN_PRIMITIVE, "-1");
		addNewForeignKeyArgs.createArgument(CompositeTransformation.ARG_TOOBJ_IN_PRIMITIVE, newForeignKeyArgs, CompositeTransformation.ARG_OBID_IN_NEWOBJECT);
		addNewForeignKeyArgs.createArgument(CompositeTransformation.ARG_FROMSCHEMA_IN_PRIMITIVE, newPrimaryKeyArgs, CompositeTransformation.ARG_SID_IN_NEWOBJECT);
		addNewForeignKeyArgs.createArgument(CompositeTransformation.ARG_TOSCHEMA_IN_PRIMITIVE, newForeignKeyArgs, CompositeTransformation.ARG_SID_IN_NEWOBJECT);
		addNewForeignKeyArgs.createArgument(CompositeTransformation.ARG_FUNCTION_IN_PRIMITIVE, "");
		addNewForeignKeyArgs.createArgument(CompositeTransformation.ARG_CONSTRAINTS_IN_PRIMITIVE, "");
	

		TemplateArgumentSequence returnedArgs = new TemplateArgumentSequence();
		returnedArgs.createArgument(8, newTableArgs, CompositeTransformation.ARG_OBID_IN_NEWOBJECT);
		returnedArgs.createArgument(9, newFieldArgs, CompositeTransformation.ARG_OBID_IN_NEWOBJECT);
		returnedArgs.createArgument(10, newPrimaryKeyArgs, CompositeTransformation.ARG_OBID_IN_NEWOBJECT);
		returnedArgs.createArgument(11, newForeignKeyArgs, CompositeTransformation.ARG_OBID_IN_NEWOBJECT);
		returnedArgs.createArgument(12, addNewForeignKeyArgs, CompositeTransformation.ARG_TOSCHEMA_IN_PRIMITIVE);
		

		CompositeTransformation trans = new CompositeTransformation(templateName, "For the existing field a table is created associated with a foreign key relationship with the previously existing entity", true);

		trans.createArgumentDefinition(1, "schema", "SID", "initial schema", false);
		trans.createArgumentDefinition(2, "object", "OBID", "existing table", false);
		trans.createArgumentDefinition(3, "object", "OBID", "existing field in table", false);
		trans.createArgumentDefinition(4, "object", "value", "new table name", false);
		trans.createArgumentDefinition(5, "object", "value", "new field name", false);
		trans.createArgumentDefinition(6, "object", "value", "new primary key name", false);
		trans.createArgumentDefinition(7, "object", "value", "new foreign key name", false);
		trans.createArgumentDefinition(8, "object", "OBID", "new table ID", true);
		trans.createArgumentDefinition(9, "object", "OBID", "new field ID", true);
		trans.createArgumentDefinition(10, "object", "OBID", "new primary key ID", true);
		trans.createArgumentDefinition(11, "object", "OBID", "new foreign key ID", true);
		trans.createArgumentDefinition(12, "schema", "SID", "final schema ID", true);

		trans.createReturnedArgumentsDefinition(returnedArgs);


		trans.createStatementExecution(1, Statement.getStatement(CompositeTransformation.NEW_OBJECT_STATEMENT), newTableArgs);
		trans.createStatementExecution(2, Statement.getStatement(CompositeTransformation.PRIMITIVE_TRANSFORMATION_STATEMENT), addNewTableArgs);
		trans.createStatementExecution(3, Statement.getStatement(CompositeTransformation.NEW_OBJECT_STATEMENT), newFieldArgs);
		trans.createStatementExecution(4, Statement.getStatement(CompositeTransformation.PRIMITIVE_TRANSFORMATION_STATEMENT), addNewFieldArgs);
		trans.createStatementExecution(5, Statement.getStatement(CompositeTransformation.NEW_OBJECT_STATEMENT), newPrimaryKeyArgs);
		trans.createStatementExecution(6, Statement.getStatement(CompositeTransformation.PRIMITIVE_TRANSFORMATION_STATEMENT), addNewPrimaryKeyArgs);
		trans.createStatementExecution(7, Statement.getStatement(CompositeTransformation.NEW_OBJECT_STATEMENT), newForeignKeyArgs);
		trans.createStatementExecution(8, Statement.getStatement(CompositeTransformation.PRIMITIVE_TRANSFORMATION_STATEMENT), addNewForeignKeyArgs);
	}

	public static void main(String[] args){
		try{
			System.out.println("Re-creating template transformation Table-Field Basic Equivalence...");
			defineTemplate();	
		}
		catch(Exception e){
			e.printStackTrace();
		}	 
	} 
}

