Package org.uengine.kernel

Source Code of org.uengine.kernel.ProcessDefinition

package org.uengine.kernel;

import java.io.File;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Map;
import java.util.Vector;

import javax.wsdl.Definition;
import javax.wsdl.Message;
import javax.wsdl.Part;
import javax.xml.namespace.QName;

import org.uengine.kernel.GlobalContext;
import org.uengine.kernel.viewer.ViewerOptions;
import org.uengine.processdesigner.ActivityDesigner;
import org.uengine.processdesigner.ProcessDesigner;
import org.uengine.processmanager.ProcessManagerBean;
import org.uengine.processmanager.ProcessManagerFactoryBean;
import org.uengine.processmanager.ProcessManagerRemote;
import org.uengine.processmanager.ProcessTransactionContext;
import org.uengine.util.ActivityForLoop;
import org.uengine.util.UEngineUtil;

/**
* @author Jinyoung Jang
*/

public class ProcessDefinition extends ScopeActivity implements Serializable{
  private static final long serialVersionUID = org.uengine.kernel.GlobalContext.SERIALIZATION_UID;
  private transient static ActivityFilter[] defaultActivityFilters;
 
  transient public final static int VERSIONSELECTOPTION_CURRENT_PROD_VER      =0;
  transient public final static int VERSIONSELECTOPTION_PROD_VER_AT_INITIATED_TIME=2;
  transient public final static int VERSIONSELECTOPTION_PROD_VER_AT_DESIGNED_TIME  =1;

  transient public final static int VERSIONSELECTOPTION_JUST_SELECTED        =3;
 

                                  //|   in-memory instance   |  definition archive 
/*  public static final int PROCESS_TYPE_WORKFLOW = 1;        //|   X           |  O/X
  public static final int PROCESS_TYPE_INTEGRATION = 2;      //|   O           |  X
  public static final int PROCESS_TYPE_PAGEFLOW = 3;        //|   X           |  O/X*/ 
 
  public static final String PVKEY_QUEUINGMECH = "_queuingmech";
//  static Hashtable messageListenerVectors = new Hashtable();
    protected static transient Role MESSENGER_SERVICE_ROLE;
    protected static transient Role EMAIL_SERVICE_ROLE;
//  protected static Role[] defaultRoles
//    =new Role[]{
//      EMAIL_SERVICE_ROLE = Role.forName(
//        EMailActivity.MAIL_SERVICE,
//        "http://localhost/axis/services/EMailServer"
//      ),
//      MESSENGER_SERVICE_ROLE = Role.forName(
//        MessengerActivity.MESSENGER_SERVICE,
//        "http://localhost/axis/services/MSNMessengerService"
//      )
//    };
 
//  protected static ServiceDefinition[] defaultServiceDefinitions
//  = new ServiceDefinition[defaultRoles.length];
//  static{
//    String stubPkgs[] = new String[]{
//      "org.uengine.webservices.emailserver",
//      "org.uengine.webservices.msnmessenger"
//    };
//   
//    for(int i=0; i<defaultRoles.length; i++){
//      Role theRole = defaultRoles[i];
//      theRole.setAskWhenInit(false);
//      ServiceDefinition sd = new ServiceDefinition();
//     
//      sd.setName(theRole.getName());
//      sd.setWsdlLocation(theRole.getDefaultEndpoint() + "?wsdl");
//      sd.setStubPackage(stubPkgs[i]);
//           
//      defaultServiceDefinitions[i] = sd;     
//      theRole.setServiceType(sd); 
//    }   
//  }
 
  protected static transient Role[] defaultRoles;
  protected static transient ServiceDefinition[] defaultServiceDefinitions;
 
  static{
    defaultRoles = new Role[]{};   
    defaultServiceDefinitions = new ServiceDefinition[]{};
  }   

  transient Hashtable wholeChildActivities/* = new Hashtable()*/;
    public Activity getActivity(String tracingTag){
     
      if(wholeChildActivities == null){
        registerToProcessDefinition(false, false);
      }
     
      if(!wholeChildActivities.containsKey(tracingTag))
        throw new RuntimeException( new UEngineException("No such child activity where tracing tag='" + tracingTag+"' in the process definition '" + getName() + "(" + getBelongingDefinitionId() + "@" + getId() + ")'"));
     
      return (Activity)wholeChildActivities.get(tracingTag);
    }
    /*public synchronized void addChildActivity(Activity child){
      super.addChildActivity(child);
     
      registerActivity(child);
    }*/

  ServiceDefinition[] serviceDefinitions;

    public ServiceDefinition[] getServiceDefinitions(){
      return serviceDefinitions;
    }
   
    public void setServiceDefinitions(ServiceDefinition[] sds){
      serviceDefinitions = sds;
     
      bXmlTypesNeedToBeRefreshed = true;
    }
    // this method will be seldom called
    public void addServiceDefinition(ServiceDefinition sd){
      ServiceDefinition[] sds = getServiceDefinitions();
      ServiceDefinition[] newSDs = new ServiceDefinition[sds.length+1]
       
      for(int i=0; i<sds.length; i++){
        if(sds[i].equals(sd)) return;
        newSDs[i] = sds[i];
      }
       
      newSDs[sds.length] = sd;
      setServiceDefinitions(newSDs);     
    }
   
  String defaultFlowchartViewType = ViewerOptions.SWIMLANE;
    public String getDefaultFlowchartViewType() {
      return defaultFlowchartViewType;
    }
 
    public void setDefaultFlowchartViewType(String viewType) {
      this.defaultFlowchartViewType = viewType;
    }
 
  String defaultFlowchartViewOption = ViewerOptions.VERTICAL;
    public String getDefaultFlowchartOption() {
      return defaultFlowchartViewOption;
    }
 
    public void setDefaultFlowchartViewOption(String viewOption) {
      this.defaultFlowchartViewOption = viewOption;
    }

  boolean isAbstract;
    public boolean isAbstract() {
      return isAbstract;
    }
    public void setAbstract(boolean isAbstract) {
      this.isAbstract = isAbstract;
    }

  int duration = 10;
    public int getDuration() {
      return duration;
    }
    public void setDuration(int duration) {
      this.duration = duration;
    }
 
  int simulationInstanceCount = 10;
    public int getSimulationInstanceCount() {
      return simulationInstanceCount;
    }
    public void setSimulationInstanceCount(int simultationInstanceCount) {
      this.simulationInstanceCount = simultationInstanceCount;
    }

  int simulationInputFrequency = 10;
    public int getSimulationInputFrequency() {
      return simulationInputFrequency;
    }
    public void setSimulationInputFrequency(int simulationInputFrequency) {
      this.simulationInputFrequency = simulationInputFrequency;
    }
 
  int simulationInputFrequencyDeviation;
    public int getSimulationInputFrequencyDeviation() {
      return simulationInputFrequencyDeviation;
    }
    public void setSimulationInputFrequencyDeviation(
        int simulationInputFrequencyDeviation) {
      this.simulationInputFrequencyDeviation = simulationInputFrequencyDeviation;
    }
   
  SimulationResource[] simulationResources;
    public SimulationResource[] getSimulationResources() {
      return simulationResources;
    }
    public void setSimulationResources(SimulationResource[] simulationResources) {
      this.simulationResources = simulationResources;
    }

   
  transient boolean bXmlTypesNeedToBeRefreshed = true;

  transient QName[] reservedXmlTypes;
    public QName[] getReservedXmlTypes() {
      if (bXmlTypesNeedToBeRefreshed) {
        ServiceDefinition[] sds = getServiceDefinitions();
        if (sds == null)
          return new QName[] {};

        Hashtable bizDocs = new Hashtable();
        try {
          for (int i = 0; i < sds.length; i++) {
            Definition def = sds[i].getDefinition();
            Collection messages = def.getMessages().values();
           
            for (Iterator iter = messages.iterator(); iter.hasNext();) {
              Message message = (Message) iter.next();
              Collection parts = message.getParts().values();
             
              for (Iterator iter2 = parts.iterator(); iter2.hasNext();) {
                Part part = (Part) iter2.next();
                QName docType = part.getTypeName();
                bizDocs.put(docType, docType);
              }
            }
          }

          QName[] bizDocsArr = new QName[bizDocs.size()];
          bizDocs.values().toArray(bizDocsArr);

          setReservedXmlTypes(bizDocsArr);

          bXmlTypesNeedToBeRefreshed = false;

        } catch (Exception e) {
          //  e.printStackTrace();
        }
      }

      return reservedXmlTypes;
    }

    public void setReservedXmlTypes(QName[] names) {
      reservedXmlTypes = names;
    }
   
  MessageDefinition[] messageDefinitions;
    public MessageDefinition[] getMessageDefinitions() {
      return messageDefinitions;
    }
 
    public void setMessageDefinitions(MessageDefinition[] definitions) {
      messageDefinitions = definitions;
    }
   
  ArrayList revisionInfoList; 
 
    public ArrayList getRevisionInfoList() {
      return revisionInfoList;
    }
 
    public void setRevisionInfoList(ArrayList revisionInfoList) {
      this.revisionInfoList = revisionInfoList;
    }
   
    public void addRevisionInfo(RevisionInfo revisionInfo){
      if(revisionInfoList==null) revisionInfoList = new ArrayList();
      revisionInfoList.add(revisionInfo);
    }

  String wsdlLocation;
    public String getWsdlLocation() {
      return wsdlLocation;
    }
    public void setWsdlLocation(String string) {
      wsdlLocation = string;
    }

  String endpoint;
    public String getEndpoint() {
      return endpoint;
    }
    public void setEndpoint(String string) {
      endpoint = string;
    }

  boolean archive = true;
    public boolean isArchive() {
      return archive;
    }
    public void setArchive(boolean boolean1) {
      archive = boolean1;
    }

  int uEngineVersion; //for backward compatibility
    public int getUEngineVersion() {
      return uEngineVersion;
    }
    public void setUEngineVersion(int i) {
      uEngineVersion = i;
    }
   
  String id;
    public String getId() {
      return id;
    }
    public void setId(String string) {
      id = string;
    }
   
  int version;
    public int getVersion() {
      return version;
    }
    public void setVersion(int i) {
      version = i;
    }
 
  String belongingDefinitionId;
    public String getBelongingDefinitionId() {
      return belongingDefinitionId;
    }
    public void setBelongingDefinitionId(String string) {
      belongingDefinitionId = string;
    }

  ActivityFilter[] activityFilters;
    public ActivityFilter[] getActivityFilters() {
     
      if(!GlobalContext.isDesignTime() && defaultActivityFilters == null){
        String defaultActivityFilterClsNames = GlobalContext.getPropertyString("defaultactivityfilters");
       
        if(org.uengine.util.UEngineUtil.isNotEmpty(defaultActivityFilterClsNames)){
          String [] filterClsNames = defaultActivityFilterClsNames.split(",");
          defaultActivityFilters = new ActivityFilter[filterClsNames.length];
         
          int j=0;
          for(int i=0; i<filterClsNames.length; i++){
            String filterClsName = filterClsNames[i].trim();
           
            try{
//              defaultActivityFilters[j] = (ActivityFilter)Class.forName(filterClsName).newInstance();
              defaultActivityFilters[j] = (ActivityFilter)GlobalContext.loadClass(filterClsName).newInstance();
              j++;
            }catch(Exception e){
              new RuntimeException("Failed to load Activity Filter ["+filterClsName+"]: ", e);
            }
          }
         
        }else{
          defaultActivityFilters = new ActivityFilter[]{};
        }
       
      }
     
      if(defaultActivityFilters==null) defaultActivityFilters = new ActivityFilter[]{};
      if(activityFilters==null) return defaultActivityFilters;
     
      ActivityFilter[] result = new ActivityFilter[defaultActivityFilters.length + activityFilters.length];
      System.arraycopy(defaultActivityFilters, 0, result, 0, defaultActivityFilters.length);
      System.arraycopy(activityFilters, 0, result, defaultActivityFilters.length, activityFilters.length);
     
      return result;
     
      //return activityFilters;
    }
    public void setActivityFilters(ActivityFilter[] filters) {
      activityFilters = filters;
    }

  /*tring title;
    public String getTitle() {
      if(title==null)
        setTitle(getName());
     
      return title;
    }
    public void setTitle(String string) {
      title = string;
    }
*/
  boolean isAdhoc;
    public boolean isAdhoc() {
      return isAdhoc;
   
    public void setAdhoc(boolean b) {
      isAdhoc = b;
    }
   
  String shortDescription;
    public String getShortDescription() {
      return shortDescription;
    }
    public void setShortDescription(String string) {
      shortDescription = string;
    }

  boolean initiateByFirstWorkitem = false;
    public boolean isInitiateByFirstWorkitem() {
      return initiateByFirstWorkitem;
    }
    public void setInitiateByFirstWorkitem(boolean b) {
      initiateByFirstWorkitem = b;
    }
   
//  ListField [] worklistFields;
//    public ListField[] getWorklistFields() {
//      return worklistFields;
//    }
//    public void setWorklistFields(ListField[] worklistFields) {
//      this.worklistFields = worklistFields;
//    }

  transient HumanActivity initiatorHumanActivity;
  /*public HumanActivity getInitiatorHumanActivity(){
    if(initiatorHumanActivity!=null)
      return initiatorHumanActivity;
   
    if(!isInitiateByFirstWorkitem())
      throw new RuntimeException("this process definition is not allowed to be initiated by the first workitem.");
   
    final Vector willCache = new Vector();
   
    ActivityFor findingLoop = new ActivityFor(){
      public void logic(Activity activity){
        if(activity instanceof HumanActivity){
          stop(activity);
        }else if(activity instanceof SubProcessActivity){
         

          if(getProcessTransactionContext()==null) stop(null);
         
          SubProcessActivity spAct = (SubProcessActivity)activity;
         
          try{
            ProcessManager pm = ProcessManagerFactory.create(getProcessTransactionContext());         
            String versionId = pm.getProductionVersionId(spAct.getDefinitionId());   
            ProcessDefinition spDef = ProcessDefinitionFactory.getDefinitionWithVersionId(versionId, getProcessTransactionContext());
           
            if(spDef.isInitiateByFirstWorkitem()){
              willCache.add("no");
              stop(spDef.getInitiatorHumanActivity());
            }
          }catch(Exception e){
            throw new RuntimeException(e);
          } 
        }
      }
    };
   
    findingLoop.run(this);

    if(willCache.size()==0)
      this.initiatorHumanActivity = (HumanActivity)findingLoop.getReturnValue();
   
    return initiatorHumanActivity;
  }*/
 
  ListField instanceListFields[];
    public ListField[] getInstanceListFields() {
      return instanceListFields;
    }
    public void setInstanceListFields(ListField[] instanceListFields) {
      this.instanceListFields = instanceListFields;
    }
 
  ListField workListFields[];
    public ListField[] getWorkListFields() {
      return workListFields;
    }
    public void setWorkListFields(ListField[] workListFields) {
      this.workListFields = workListFields;
    }
 
  transient String currentLocale;
    public String getCurrentLocale() {
      return currentLocale;
    }
    public void setCurrentLocale(String currentLocale) {
      this.currentLocale = currentLocale;
    }
   
  boolean isVolatile;
    public boolean isVolatile() {
      return isVolatile;
    }
    public void setVolatile(boolean isVolatile) {
      this.isVolatile = isVolatile;
    }

  public ActivityReference getInitiatorHumanActivityReference(final ProcessTransactionContext ptc){
    if(initiatorHumanActivity!=null){
      ActivityReference ref = new ActivityReference();
      ref.setActivity(initiatorHumanActivity);
      ref.setAbsoluteTracingTag(initiatorHumanActivity.getTracingTag());
     
      return ref;
    }
 
    ActivityReference activityReference = super.getInitiatorHumanActivityReference(ptc);

    //this.initiatorHumanActivity = (activityReference==null ? null : (HumanActivity)activityReference.getActivity());

    return activityReference;
  }
   
  Calendar modifiedDate;
    public Calendar getModifiedDate() {
      return modifiedDate;
    }
    public void setModifiedDate(Calendar calendar) {
      modifiedDate = calendar;
    }
   
/*  int processType;
    public int getProcessType() {
      return processType;
    }
    public void setProcessType(int i) {
      processType = i;
    }*/
   
  long activitySequence;
    public long getNextActivitySequence() {
      return (++activitySequence);
    }
    public long getActivitySequence() {
      return activitySequence;
    }
    public void setActivitySequence(long l) {
      activitySequence = l;
    }

  public Calendar getDueDate(ProcessInstance instance) throws Exception{
    //Calendar dueDate = (Calendar)instance.get(getTracingTag(), HumanActivity.PVKEY_DUEDATE);
    return instance.getDueDate();
  }
 
  public void setDueDate(ProcessInstance instance, Calendar dueDate) throws Exception{
    //instance.set(getTracingTag(), HumanActivity.PVKEY_DUEDATE, dueDate);
    instance.setDueDate(dueDate);
  }
 

////////////////////////////

  public ProcessDefinition(){
    super();
//    setName("noname");
   
//    setRoles(defaultRoles);
    setServiceDefinitions(defaultServiceDefinitions);
   
   
    setName(GlobalContext.getLocalizedMessage("activitytypes.org.uengine.kernel.processdefinition.untitled", "Noname"));
   
    setDuration(10);

    setInitiateByFirstWorkitem(true);
    setAdhoc(true);
   
    //role   
    if(GlobalContext.isDesignTime()){
      Role drafter = new Role();
      drafter.setName("Initiator");
      drafter.setAskWhenInit(false);
 
      setRoles(new Role[]{drafter});
    }
   
    //filter   
//    DefaultActivityFilter filter = new DefaultActivityFilter();

//    filter.setUseScript(false);
//    filter.setFilterClass("hanwha.bpm.activityfilters.AlarmActivityFilter");
//    setActivityFilters(new ActivityFilter[]{filter});   
   
  }
 
  public ProcessInstance createInstance(String name, Map options) throws Exception{   
    ProcessInstance activityInstance = ProcessInstance.create(this, name, options);
    //activityInstance.setProcessDefinition(this);
    //activityInstance.create();
       
    createInstance(activityInstance);
   
    return activityInstance;
  }

//-------------- private method -----------------------

  protected boolean registerActivity(Activity act, boolean autoTagging){
    return registerActivity(act, autoTagging, false);
  }
 
  protected boolean registerActivity(Activity act, boolean autoTagging, boolean checkCollision){
   
    if(wholeChildActivities==null) wholeChildActivities = new Hashtable();
   
    String tracingTagOfAct = act.getTracingTag();
    if(tracingTagOfAct==null){
      if(autoTagging){
        act.setTracingTag(""+getNextActivitySequence());
      }else
        throw new RuntimeException(new UEngineException("This definition is corrupt. One of child activity's tracingtag is null."));
    }
   
    if(checkCollision && wholeChildActivities.containsKey(act.getTracingTag())){
      return false;
    }
   
    wholeChildActivities.put(act.getTracingTag(), act);
    //TODO: tracingtag
//    if(act instanceof ComplexActivity){
//      int i=0;
//      for(Enumeration enum = ((ComplexActivity)act).getChildActivities().elements(); enum.hasMoreElements(); ){
//        Activity childAct = (Activity)enum.nextElement();
//         
//        /*if(autoTagging)
//          childAct.setTracingTag(act.getTracingTag() + "_" + (i++));*/
//       
//        //TODO: removable
//        childAct.setParentActivity(act);
//         
//        boolean ok = registerActivity(childAct, autoTagging, checkCollision);
//        if(checkCollision && !ok) return false;
//      }
//    }
   
    return true;
  }
   
  protected void registerActivity(Activity act){
    registerActivity(act, true);
  }
 
  static public ProcessDefinition getDefinition(String defVerId, ProcessTransactionContext ptc) throws Exception{
   
    //if not cached, find in files
/*    if(!processDefinitions.containsKey(processDefinition)){
      try{
        java.io.FileInputStream fi = new java.io.FileInputStream(processDefinition + ".Bean" );       
        Serializer ser = new org.uengine.components.serializers.BeanSerializer();                  
        ProcessDefinition pd = (ProcessDefinition)ser.deserialize(fi);
       
        processDefinitions.put(processDefinition, pd);
System.out.println("found and deserialized. process definition will be used is from a file.");

System.out.println("length of childs : " + pd.getChildActivities().size());
      }catch(Exception e){System.out.println("Although tried to find process in files, failed");}
    }
   
    return (ProcessDefinition)processDefinitions.get(processDefinition);*/
       
    return ProcessDefinitionFactory.getInstance(ptc).getDefinition(defVerId);
  }
 
  public static String[] getDefinitionNames() throws Exception{
    Vector nameVector = new Vector();
   
    File f = new File(".");     
    File[] fs = f.listFiles();
   
    if(fs!=null)
    for( int i=0; i< fs.length; i++){     
   
      //The filename itself is the name of process
     
      if( fs[i].getName().endsWith(".Bean")){
        nameVector.add(
          fs[i].getName().substring(0, fs[i].getName().indexOf("."))
        );
      }
    }
   
    String[] names = new String[nameVector.size()];
    nameVector.toArray(names);
   
    return names;
  }

  protected void addMessageListener(ProcessInstance instance, MessageListener ml) throws Exception{
    addMessageListener(ml.getMessage(), instance, ml.getTracingTag());
  }

  protected void addMessageListener(String message, ProcessInstance instance, String scope) throws Exception{
    //review: change to JMS subscriber
   
//    instance.set("", VAR_PENDING_MESSAGE, new Boolean(false));
    instance.addMessageListener(message, scope);
/*    if (!messageListenerVectors.containsKey(message))
      messageListenerVectors.put(message, new Vector());
    else
      removeMessageListener(message, instance, scope); //void duplicated subscription
     
System.out.println("ProcessDefinition::addMessageListener.message = " + message);
   
    Vector listeners = (Vector)messageListenerVectors.get(message);
   
    listeners.add(new Object[]{instance, scope});*/
   
  }
 
  protected void removeMessageListener(String message, ProcessInstance instance, String scope) throws Exception{
    /*    if (!messageListenerVectors.containsKey(message)) return;
         
        Vector listeners = (Vector)messageListenerVectors.get(message);
       
        Vector removeTargets = new Vector();
        for(Enumeration enum = listeners.elements(); enum.hasMoreElements(); ){
          Object[] context = (Object[]) enum.nextElement();
          ActivityInstance subscriber = (ActivityInstance)context[0];           
          String contextScope = (String)context[1];
         
          if(subscriber.getInstanceId().equals(instance.getInstanceId()) && contextScope.equals(scope)){
            removeTargets.add(context);
    System.out.println("found duplicated message subscription!: message=" +  message +", instanceid=" + instance.getInstanceId() + ", scope=" + scope);
          }
        }
       
        listeners.removeAll(removeTargets);*/
       
    instance.removeMessageListener(message, scope);
  }
 
  protected void removeMessageListener(ProcessInstance instance, MessageListener ml) throws Exception{
    removeMessageListener(ml.getMessage(), instance, ml.getTracingTag());
  }
 
  //TODO: hotspot
  protected Object fireMessage(String message, final ProcessInstance instance, Object payload, boolean payloadIsXML) throws Exception{
    //review: use JMS or wake-up mechanism in turn
    boolean ack = false;
//    for(int i=0; !ack && i<10; i++){
      System.out.println("ProcessDefinition::fireMessage.message = " + message);
//      if (!messageListenerVectors.containsKey(message)) return;
      Vector subscribedScopes = (Vector)instance.getMessageListeners(message);
     
      if(subscribedScopes!=null)
      for(Enumeration enumeration = subscribedScopes.elements(); enumeration.hasMoreElements(); ){
        String scope = (String) enumeration.nextElement();
        System.out.println("   distribute message to " + scope);     
  /*      if(payloadIsXML){
          Activity receiveAct = getActivity(scope);
   
          if(receiveAct instanceof ReceiveActivity){
            ProcessVariable outPV = ((ReceiveActivity)receiveAct).getOut();         
            ProcessVariableDescriptor pvd = getProcessVariableDescriptor(outPV.getName());         
            QName qname = pvd.getQName();
     
            Serializer ser = GlobalContext.getSerializer(qname);         
            Object objPayload = ser.deserialize(new java.io.StringBufferInputStream((String)payload));
            payload = objPayload;
          }
        }*/

        Activity targetActivity = getActivity(scope);       
        if(!(targetActivity instanceof MessageListener)) continue;
       
        MessageListener activityAsMessageListener = (MessageListener)targetActivity;
        if(message.equals(activityAsMessageListener.getMessage())){
          try{
            if(activityAsMessageListener.onMessage(instance, payload))
              ack = true;
          }catch(Exception e){
           
            targetActivity.fireFault(instance, e);
           
            //TODO: what's happening?
            throw e;
          }
        }
      }
     
/*      if(!ack)
        Thread.sleep(1000*i);   
    }*/

    /*if(!ack){
      fireMessage(message, instance, payload, payloadIsXML);
    }*/
   
    if(!ack)
      throw new UEngineException("There is no subscribed listener for the message", "Try again or check your message");
     
    //review: if there is a synchronized receiver, it should return a value.
    return null;
  }
 
  public Object fireMessage(String message, ProcessInstance instance, Object payload) throws Exception{
    return fireMessage(message, instance, payload, false);
  }
 
  public Object fireMessageXML(String message, ProcessInstance instance, String payload) throws Exception{
    return fireMessage(message, instance, payload, true);
  }
 
  protected void onEvent(String command, ProcessInstance instance, Object payload) throws Exception{
    if(command.equals(ACTIVITY_DONE) || command.equals(ACTIVITY_SKIPPED)){
      returnToMainProcess(instance, command.equals(ACTIVITY_SKIPPED));
    }
   
    super.onEvent(command, instance, payload);
  }

  protected void returnToMainProcess(ProcessInstance instance) throws Exception{
    returnToMainProcess(instance, false);
  }
 
 
  protected void returnToMainProcess(ProcessInstance instance, boolean skipped) throws Exception{
    //if this process is subprocess, notify that it is completed to the main process.
    String returningProcess = (String)instance.getMainProcessInstanceId();
    if(returningProcess!=null && !returningProcess.equals("null")){
     
      String returningTracingTag = (String)instance.getMainActivityTracingTag();
     
      Hashtable options = new Hashtable();
      options.put("ptc", instance.getProcessTransactionContext());
     
      ProcessInstance returningInstance = ProcessInstance.create().getInstance(returningProcess, options);
      ProcessDefinition returningDefinition = returningInstance.getProcessDefinition();
             
      SubProcessActivity returningActivity = (SubProcessActivity)returningDefinition.getActivity(returningTracingTag);
      if(returningActivity == null)
        throw new UEngineException("subprocess activity is not found. maybe event handling subprocess is set having to returned.");
       
      returningActivity.onSubProcessReturn(returningInstance, instance, skipped);
     
    }
  }
   
  public void afterDeserialization(){
   
//      EventHandler[] eventHandlers = super.getEventHandlers();    //anyhow now there's no process definition having its event handlers since the process designer isn't allowed to add event handlers.


    super.afterDeserialization()
    //TODO: tuning point : does it need to load the hashmap again? 
    registerToProcessDefinition(false, false);
   
    //TODO: tempororaly disabled
    /*
    for(int i=0; i<defaultRoles.length; i++)
      addRole(defaultRoles[i]);   
    for(int i=0; i<defaultServiceDefinitions.length; i++)
      addServiceDefinition(defaultServiceDefinitions[i]);*/   

/*    for(int i=0; i<processVariableDescriptors.length; i++)
      ProcessVariable.declareProcessVariable(processVariableDescriptors[i]);*/   
   
  }
 
  public void flowControl(String command, ProcessInstance instance, String tracingTag) throws Exception{
    String status = instance.getStatus(tracingTag);
   
    //TODO: dirty read might be possible
    if(command.equals("resume")){
      if(isResumable(status))
        getActivity(tracingTag).resume(instance);
      else System.out.println("resume cancelled...");
    }
    else if(command.equals("suspend")){
      if(isSuspendable(status))
        getActivity(tracingTag).suspend(instance);
      else System.out.println("suspend cancelled...");
    }
    else if(command.equals("skip")){
      if(isSkippable(status))
        getActivity(tracingTag).skip(instance);
      else System.out.println("skip cancelled...");
    }
    else if(command.equals("compensate")){
      if(isCompensatable(status))
        getActivity(tracingTag).compensate(instance)
      else System.out.println("compensate cancelled...");
    }
    else if(command.equals("compensateTo")){
      if(status.equals(STATUS_COMPLETED) || status.equals(STATUS_SKIPPED))
        getActivity(tracingTag).compensateToThis(instance)
      else System.out.println("compensateTo cancelled...");
    }
  }

  public String getTracingTag() {
    return ""; //a process definition should be the root
  }
 
  public void beforeSerialization() {
    super.beforeSerialization();
   
    if(GlobalContext.isDesignTime()){
      //cache the initiator human activity
      if(isInitiateByFirstWorkitem()){
        getInitiatorHumanActivityReference(null);
      }
   
      registerToProcessDefinition(true, false);
    }
  }
 


  public ValidationContext validate(Map options) {
    final ValidationContext ctx = super.validate(options);
   
    /*if(isInitiateByFirstWorkitem()){
      HumanActivity initiatorHumanActivity = getInitiatorHumanActivity();
      if(initiatorHumanActivity==null)
        ctx.add("Although this definition is set to be initiated by the first workitem, there's no initiating human activity.");
    }*/
   
    if(wholeChildActivities!=null)
      wholeChildActivities.clear();
   
    if(!registerActivity(this, true, true)){
      ctx.add("Activity id (tracingtag) collision is detected.");
    }
   
    final HashMap tracingTagMap = new HashMap();
    ActivityForLoop findingLoopForTracingTagCollision = new ActivityForLoop(){

      public void logic(Activity activity) {
        if(tracingTagMap.containsKey(activity.getTracingTag())){
          Activity originalTTUser = (Activity)tracingTagMap.get(activity.getTracingTag());
          ctx.add(activity.getActivityLabel() + " TracingTag collision with " + originalTTUser.getActivityLabel() + ". You should choose another tag number for this activity (Change the definition source directly code in the 'XPD' Tab).");
        }else
          tracingTagMap.put(activity.getTracingTag(), activity);
      }     
     
    };
   
    findingLoopForTracingTagCollision.run(this);
   
   
    if(getRoles()!=null) {
      Role[] roles = getRoles();
      for(int i=0; i<roles.length; i++){
        if(!UEngineUtil.isNotEmpty(roles[i].getName())){
          ctx.add("Role Id for ["+ roles[i] + "] should be provided.");
        }
      }
    }
   
    if(processVariableDescriptors!=null)
    for(int i=0; i<processVariableDescriptors.length; i++){
      if(!UEngineUtil.isNotEmpty(processVariableDescriptors[i].getName())){
        ctx.add("Process Variable Id for ["+ processVariableDescriptors[i] + "] should be provided.");
      }
    }

    return ctx;
  }

  public ActivityDesigner createDesigner() {
    setUEngineVersion(GlobalContext.UENGINE_VER);

    return super.createDesigner();
  }

  public void reset(ProcessInstance instance) throws Exception {
    super.reset(instance);
    instance.setStatus(Activity.STATUS_READY);
  }

  public void stop(ProcessInstance instance) throws Exception {
    stop(instance, Activity.STATUS_STOPPED);
  }
 
  public void stop(ProcessInstance instance,String status) throws Exception {
    super.stop(instance,status);
  }
 
  public static ProcessDefinition create(){
    try{
   
      return (ProcessDefinition) Class.forName(GlobalContext.getPropertyString("processdefinition.class", "org.uengine.kernel.ProcessDefinition")).newInstance();
     
    }catch(Exception e){
      return new ProcessDefinition();
    }
  }
 
//  public String getQueuingMechanism(ProcessInstance instance){
//    try{
//      return (String)instance.get("", PVKEY_QUEUINGMECH);
//    }catch(Exception e){
//      return null;
//    }
//  }
//
//  public void setQueuingMechanism(ProcessInstance instance, String val){
//    try{
//      instance.set("", PVKEY_QUEUINGMECH, val);
//    }catch(Exception e){
//      e.printStackTrace();
//    }
//  } 
 
  public String getQueuingMechanism(ProcessInstance instance) {
    return QUEUINGMECH_SYNC;
  }

  public void setQueuingMechanism(ProcessInstance instance, String val) {
  }
 
  private String alias;
    public String getAlias() {
      return alias;
    }
    public void setAlias(String value) {
      this.alias = value;
    }

  public static String[] splitDefinitionAndVersionId(String fullDefinitionId){
    String versionId = null;
    String definitionId = null;
    if(fullDefinitionId!=null && fullDefinitionId.indexOf("@") > -1){
      String [] defIdAndVersionId = fullDefinitionId.split("@");
      definitionId = defIdAndVersionId[0];
      versionId = defIdAndVersionId[1];
    }else{
      definitionId = fullDefinitionId;
    }
   
    return new String[]{definitionId, versionId};
  }

  public static String getDefinitionVersionId(ProcessInstance instance, String definitionId, int versionSelectionOption, ProcessDefinition definition) throws Exception{
    ProcessManagerRemote pm = null;

    if(instance!=null)
      pm = instance.getProcessTransactionContext().getProcessManager();
    else
      pm = (new ProcessManagerFactoryBean()).getProcessManagerForReadOnly();

    return getDefinitionVersionId(instance, pm, definitionId, versionSelectionOption, definition);
  }

  public static String getDefinitionVersionId(ProcessManagerRemote pm, String definitionId, int versionSelectionOption, ProcessDefinition definition) throws Exception{
    return getDefinitionVersionId(null, pm, definitionId, versionSelectionOption, definition);
  }

  public static String getDefinitionVersionId(ProcessInstance instance, ProcessManagerRemote pm, String definitionId, int versionSelectionOption, ProcessDefinition definition) throws Exception{
    String versionId = null;

    String [] defIdAndVersionId = splitDefinitionAndVersionId(definitionId);
    definitionId = defIdAndVersionId[0];
    versionId = defIdAndVersionId[1];
   
    try{
      //need re-resolution for definition id if the definition id is an alias
      if(definitionId.startsWith("[") && definitionId.endsWith("]")){
        String definitionAlias = definitionId.substring(1, definitionId.length()-1);
        definitionId = pm.getProcessDefinitionIdByAlias(definitionAlias);
      }

      switch(versionSelectionOption){
      case VERSIONSELECTOPTION_CURRENT_PROD_VER:
        versionId = pm.getProcessDefinitionProductionVersion(definitionId);
        break;
      case VERSIONSELECTOPTION_PROD_VER_AT_DESIGNED_TIME:
        //if(instance==null) throw new UEngineException("")
        versionId = pm.getProductionVersionIdAtThatTime(definitionId, instance.getRootProcessInstance().getProcessDefinition().getModifiedDate().getTime());
        break;
      case VERSIONSELECTOPTION_PROD_VER_AT_INITIATED_TIME:
        versionId = pm.getProductionVersionIdAtThatTime(definitionId, definition.getStartedTime(instance).getTime());
        break;
      case VERSIONSELECTOPTION_JUST_SELECTED:
        if(versionId==null)
          throw new UEngineException("Even though the sub process activity is set to use the sub processes' definition version with the just selected one, the version is not explicitly set.");
        break;
      }

      if(versionId == null){
        versionId = pm.getProcessDefinitionProductionVersion(definitionId);
      }
     
    }catch(Exception e){
      e.printStackTrace();
     
      try{
        versionId = pm.getFirstProductionVersionId(definitionId);
      }catch(Exception ex){
        ex.printStackTrace();
        versionId = pm.getProcessDefinitionProductionVersion(definitionId);
      }
    }finally{
      try{
        if(instance==null) pm.remove();
      }catch(Exception e){};
    }
   
    return versionId;
  }

  protected void beforeExecute(ProcessInstance instance) throws Exception {
    super.beforeExecute(instance);
    Calendar dueDate = getDueDate(instance);
    if(dueDate==null)
      setDueDate(instance, instance.calculateDueDate(GlobalContext.getNow(instance.getProcessTransactionContext()), getDuration()));
 
  }

 

}

TOP

Related Classes of org.uengine.kernel.ProcessDefinition

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.