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


/**
	An application that defines the "Entity-Attribute Equivalence, Adding Attribute" template transformation
	based on the "Entity-Attribute Basic Equivalence" template transformation.
	This transformation should be applied on a schema of the "er" model.
	It creates a new entity and a relationship between an existing entity and the new one. It finally
	adds an attribute to the created entity. 
 
	The arguments for this transformation are:
	1. initial schema ID
	2. existing entity ID
	3. new entity name
	4. new relationship name
	5. new attribute name
	6. new entity ID (returned value) 
	7. new relationship ID (returned value)
	8. new attribute ID (returned value)
	9. final schema ID (returned value)
*/
public class AttributeToEntityBasicAndAddAttribute{
  private static String modelName="er";
  private static String entityConstructName="erEntity";
  private static String attributeConstructName="erAttribute";
  private static String relationshipConstructName="erRelationship";
  private static String generalizationConstructName="erGeneralization";

	private static String templateName = "Entity-Attribute Equivalence, Adding Attribute";
	private static String templateInvoked = "Entity-Attribute 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 er = Model.getModel(modelName);
		Construct erAttribute = er.getConstruct(attributeConstructName);

		TemplateArgumentSequence transformationArgs = new TemplateArgumentSequence();
		transformationArgs.createArgument(1, 1);
		transformationArgs.createArgument(2, 2);
		transformationArgs.createArgument(3, 3);
		transformationArgs.createArgument(4, 4);

		TemplateArgumentSequence invokeArgs = new TemplateArgumentSequence();
		invokeArgs.createArgument(CompositeTransformation.ARG_TRANSFORMATION_IN_INVOCATION, String.valueOf(CompositeTransformation.getCompositeTransformation(templateInvoked).getTransId()));
		invokeArgs.createArgument(CompositeTransformation.ARG_ARGUMENTS_IN_INVOCATION, String.valueOf(transformationArgs.getSequenceId()));


		TemplateArgumentSequence newAttributeArgs = new TemplateArgumentSequence();
		newAttributeArgs.createArgument(CompositeTransformation.ARG_CID_IN_NEWOBJECT, String.valueOf(erAttribute.getCID()));
		newAttributeArgs.createArgument(CompositeTransformation.ARG_VALUE_IN_NEWOBJECT, 5);
		newAttributeArgs.createArgument(CompositeTransformation.ARG_ISTEMP_IN_NEWOBJECT, "0");
		TemplateArgumentSequence newAttributeScheme = new TemplateArgumentSequence();
		newAttributeScheme.createArgument(1, transformationArgs, 5);
		newAttributeScheme.createArgument(2, newAttributeArgs, CompositeTransformation.ARG_OBID_IN_NEWOBJECT);
		newAttributeArgs.createArgument(CompositeTransformation.ARG_SCHEME_IN_NEWOBJECT, String.valueOf(newAttributeScheme.getSequenceId())); 

		TemplateArgumentSequence addNewAttributeArgs = new TemplateArgumentSequence();
		addNewAttributeArgs.createArgument(CompositeTransformation.ARG_ACTION_IN_PRIMITIVE, "add");
		addNewAttributeArgs.createArgument(CompositeTransformation.ARG_FROMOBJ_IN_PRIMITIVE, "-1");
		addNewAttributeArgs.createArgument(CompositeTransformation.ARG_TOOBJ_IN_PRIMITIVE, newAttributeArgs, CompositeTransformation.ARG_OBID_IN_NEWOBJECT);
		addNewAttributeArgs.createArgument(CompositeTransformation.ARG_FROMSCHEMA_IN_PRIMITIVE, transformationArgs, 7);
		addNewAttributeArgs.createArgument(CompositeTransformation.ARG_TOSCHEMA_IN_PRIMITIVE, newAttributeArgs, CompositeTransformation.ARG_SID_IN_NEWOBJECT);
		addNewAttributeArgs.createArgument(CompositeTransformation.ARG_FUNCTION_IN_PRIMITIVE, "");
		addNewAttributeArgs.createArgument(CompositeTransformation.ARG_CONSTRAINTS_IN_PRIMITIVE, "");


		TemplateArgumentSequence returnedArgs = new TemplateArgumentSequence();
		returnedArgs.createArgument(6, transformationArgs, 5);
		returnedArgs.createArgument(7, transformationArgs, 6);
		returnedArgs.createArgument(8, newAttributeArgs, CompositeTransformation.ARG_OBID_IN_NEWOBJECT);
		returnedArgs.createArgument(9, addNewAttributeArgs, CompositeTransformation.ARG_TOSCHEMA_IN_PRIMITIVE);

		CompositeTransformation trans = new CompositeTransformation(templateName, "Same as Basic Equivalence, but now another attribute is added to the new entity", true);

		trans.createArgumentDefinition(1, "schema", "SID", "initial schema", false);
		trans.createArgumentDefinition(2, "object", "OBID", "existing entity", false);
		trans.createArgumentDefinition(3, "object", "value", "new entity name", false);
		trans.createArgumentDefinition(4, "object", "value", "new relationship name", false);
		trans.createArgumentDefinition(5, "object", "value", "new attribute name", false);
		trans.createArgumentDefinition(6, "object", "OBID", "new entity ID", true);
		trans.createArgumentDefinition(7, "object", "OBID", "new relationship ID", true);
		trans.createArgumentDefinition(8, "object", "OBID", "new attribute ID", true);
		trans.createArgumentDefinition(9, "schema", "SID", "final schema ID", true);

		trans.createReturnedArgumentsDefinition(returnedArgs);


		trans.createStatementExecution(1, Statement.getStatement(CompositeTransformation.INVOCATION_STATEMENT), invokeArgs);
		trans.createStatementExecution(2, Statement.getStatement(CompositeTransformation.NEW_OBJECT_STATEMENT), newAttributeArgs);
		trans.createStatementExecution(3, Statement.getStatement(CompositeTransformation.PRIMITIVE_TRANSFORMATION_STATEMENT), addNewAttributeArgs);
	}

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