//Source file: H:\\temp\\mdaTransf-v3\\mdaTransf\\src\\share\\modTransf\\rules\\core\\CoreRule.java
//Source file: H:\\temp\\generated\\modTransf\\rules\\core\\CoreRule.java
package modTransf.rules.core;
import modTransf.engine.Rule;
import modTransf.engine.EngineLifeCycle;
import modTransf.engine.RuleContext;
import modTransf.engine.Arguments;
import java.util.List;
import java.util.Iterator;
import modTransf.engine.TransformationException;
import java.util.ArrayList;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import modTransf.engine.EngineException;
import modTransf.engine.Member;
import modTransf.engine.UnsatisfiedGuardException;
public class CoreRule implements Rule, EngineLifeCycle, Member
{
/**
* Log for Transformation.
* This log is used during rules development.
* It logs rules processing.
*/
protected static Log log = LogFactory.getLog("modTransf.rules.core.CoreLog");
protected static Log ruleLog = LogFactory.getLog("modTransf.engine.RuleLog");
protected String ruleName;
/**
* The domains associated to this rule.
*/
protected TemplateDescriptorList domains = new TemplateDescriptorList();
protected GuardClauseList enterGuard;
protected GuardClauseList exitGuard;
/**
* List of preActions. PreActions are executed before the creation of dst objects.
*/
protected ActionClauseList action;
/**
* List of preActions. PreActions are executed before the creation of dst objects.
*/
protected ActionClauseList postAction;
protected ActionClause createAction;
public CoreRule()
{
}
/**
* Add the domain to the rule.
* Also initialize the domain.
* @param domain Domain
*/
public void addDomain(Domain domain)
{
if(log.isTraceEnabled())
{
log.trace( (ruleName!=null?ruleName:"unnamedRule")+".addDomain( "+domain+" )");
}
int index = domains.size();
domain.setArgIndex(index);
domains.add(domain);
}
/**
* Add a enter guard.
* @param action ActionClause
*/
public void addEnterGuard( GuardClause guard )
{
if(this.enterGuard == null )
this.enterGuard = new GuardClauseList();
this.enterGuard.add(guard);
}
/**
* Add a enter guard.
* @param action ActionClause
*/
public void addExitGuard( GuardClause guard )
{
if(this.exitGuard == null )
this.exitGuard = new GuardClauseList();
this.exitGuard.add(guard);
}
/**
* Add a preAction.
* PreAction are executed before object creations.
* @param action ActionClause
*/
public void addAction( ActionClause action )
{
if(this.action == null )
this.action = new ActionClauseList();
this.action.add(action);
}
/**
* Add a preAction.
* PreAction are executed before object creations.
* @param action ActionClause
*/
public void addPostAction( ActionClause action )
{
if(this.postAction == null )
this.postAction = new ActionClauseList();
this.postAction.add(action);
}
/**
* Setup the context attribute required by the execution of the rule.
* @param args Arguments
* @param context RuleContext
*/
protected void setUpContextVariables( Arguments args, RuleContext context )
{
context.setArguments(args);
context.setRule(this);
}
/**
* Init the local variable. The local variable are initialized and stored in the
* local context.
* The arguments are also put in the local context.
* @param args
* @param context
*/
public void setUpLocalVariables(Arguments args, RuleContext context)
throws TransformationException
{
Iterator iter = domains.iterator();
while(iter.hasNext())
{
Domain domain = (Domain)iter.next();
if(domain.isSourceDomain(context))
{
//System.out.println("process source domain '" + domain.getModelName() + "'" );
domain.setUpLocalVariables(this, context);
}
}
}
/**
* Compute the enter guard.
* The local variables should have been initialized.
* @param context
* @return boolean
*/
public boolean isConformToEnterGuard(Arguments args, RuleContext context)
throws TransformationException
{
//System.out.println("CoreRule("+ ruleName +").isConformToEnterGuard()");
// Check number of arguments
if(args.size()!=domains.size())
{
return false;
}
//System.out.println("cont ...");
// Check domains guards
Iterator domainIter = domains.iterator();
Iterator argsIter = args.iterator();
while(domainIter.hasNext()&&argsIter.hasNext())
{
Domain domain = (Domain)domainIter.next();
if(!domain.isConformToEnterGuard(argsIter.next(), context))
{
return false;
}
}
// Check rule guards
if(enterGuard!=null)
{
return enterGuard.isAllowed(args, context);
}
return true;
}
/**
* Execute the actions associated to the rule.
* @param context
* @return boolean
*/
public boolean executeSequence(RuleContext context)
throws TransformationException
{
// Execute the rule preActions
executeAction(context);
// Execute create actions
executeCreateActions(context);
// Execute the rule postctions
executePostAction(context);
return true;
}
/**
* @param context
*/
public void executeCreateActions(RuleContext context)
throws TransformationException
{
// Execute create actions
Iterator iter = domains.iterator();
while(iter.hasNext())
{
Domain domain = (Domain)iter.next();
if(domain.isTargetDomain(context) ) // target model
{
Object res = domain.create(context);
// Add the created object to the result arguments
domain.setPropertyValue( null, res, context);
}
}
}
/**
* @param context
*/
public void executeAction(RuleContext context)
throws TransformationException
{
// Execute domains actions
Iterator domainIter = domains.iterator();
while(domainIter.hasNext())
{
Domain domain = (Domain)domainIter.next();
if(domain.isTargetDomain( context))
{
domain.executeAction( domain.getPropertyValue(context), context);
}
}
// Execute the rule preActions
if( action != null )
action.execute( this, context);
}
/**
* @param context
*/
public void executePostAction(RuleContext context)
throws TransformationException
{
// Execute domains actions
Iterator domainIter = domains.iterator();
while(domainIter.hasNext())
{
Domain domain = (Domain)domainIter.next();
if(domain.isTargetDomain( context))
{
domain.executePostAction( domain.getPropertyValue(context), context);
}
}
// Execute the rule postctions
if( postAction != null )
postAction.execute( this, context);
}
/**
* Compute the exit guard.
* @param context
* @return boolean
*/
public boolean isConformToExitGuard(Arguments args, RuleContext context)
{
return true;
}
/**
* Check the exitGuard. Throw appropriate exception is the exit guard is not
* fulfil.
* @param request
*/
public void checkExitGuard(Arguments args, RuleContext request)
throws TransformationException
{
if( exitGuard == null )
return;
if(!exitGuard.isAllowed( args, request) )
throw new UnsatisfiedGuardException("Exit guard not satisfied for rule '"
+ ruleName + "'.");
}
/**
* @return String
*/
public String getRuleName()
{
return ruleName;
}
/**
* @return String
*/
public void setRuleName(String name)
{
this.ruleName = name;
}
/**
* getMemberName
*
* @return String
*/
public String getMemberName()
{
return getRuleName();
}
/**
* setMemberName
*
* @param name String
*/
public void setMemberName(String name)
{
setRuleName(name);
}
/**
* @param args
* @param context
* @return boolean
*/
public boolean isAllowed(Arguments args, RuleContext context)
throws TransformationException
{
setUpLocalVariables(args, context);
return isConformToEnterGuard(args, context);
}
/**
* Execute the rule in the provided context.
* Setup some local attributes in the context (rule, args, ...). These attributes
* are not cleared at the end of the execution. Normally, the context should
* be dedicated for the execution of this rule, and disguarded after the execution.
* @param args
* @param context
* @return boolean
*/
public boolean execute(Arguments args, RuleContext context)
throws TransformationException
{
try
{
setUpContextVariables(args, context);
setUpLocalVariables(args, context);
// Check the enter guard
if(!isConformToEnterGuard(args, context))
{
if( ruleLog.isDebugEnabled() )
ruleLog.debug( "rejected rule '" + ruleName + "' for ( " + args + " " );
return false;
}
if( ruleLog.isInfoEnabled() )
ruleLog.info( "call rule '" + ruleName + "' ( " + args + " " );
// Execute the sequence
executeSequence(context);
// Check the exit guard if needed
checkExitGuard(args, context);
// Return the value of the enter guard
return true;
}
catch(TransformationException ex)
{ // Add trace
ex.fillInStackTrace( this, args, "rule" );
throw ex;
}
catch(Exception ex)
{ // Add trace
TransformationException tex = new TransformationException(ex);
tex.fillInStackTrace( this, args, "rule" );
throw tex;
}
}
/**
* @param context
*/
public void engineStart(RuleContext context)
throws EngineException
{
//System.out.println("CoreRule.engineStart()");
domains.engineStart(context);
if(enterGuard!=null)
{
enterGuard.engineStart(context);
}
if(createAction!=null)
{
createAction.engineStart(context);
}
if(action!=null)
{
action.engineStart(context);
}
if(postAction!=null)
{
postAction.engineStart(context);
}
}
/**
* @param context
*/
public void engineFinish(RuleContext context)
throws EngineException
{
domains.engineFinish(context);
if(enterGuard!=null)
{
enterGuard.engineFinish(context);
}
if(createAction!=null)
{
createAction.engineFinish(context);
}
if(action!=null)
{
action.engineFinish(context);
}
if(postAction!=null)
{
postAction.engineFinish(context);
}
}
/**
* getParameterDescriptors
*
* @return List
*/
public List getParameterDescriptors()
{
return domains;
}
}