/* * (c) Copyright 2010-2011 AgileBirds * * This file is part of OpenFlexo. * * OpenFlexo is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * OpenFlexo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with OpenFlexo. If not, see <http://www.gnu.org/licenses/>. * */ package org.openflexo.foundation.wkf; /* * FlexoProcess.java * Project WorkflowEditor * * Created by benoit on Mar 3, 2004 */ import java.io.File; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.Date; import java.util.Enumeration; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import java.util.Vector; import java.util.logging.Level; import java.util.logging.Logger; import java.util.regex.Matcher; import javax.naming.InvalidNameException; import org.apache.commons.collections.BidiMap; import org.apache.commons.collections.bidimap.DualHashBidiMap; import org.openflexo.foundation.AttributeDataModification; import org.openflexo.foundation.CodeType; import org.openflexo.foundation.FlexoException; import org.openflexo.foundation.FlexoImportableObject; import org.openflexo.foundation.FlexoModelObject; import org.openflexo.foundation.Inspectors; import org.openflexo.foundation.NameChanged; import org.openflexo.foundation.TargetType; import org.openflexo.foundation.action.FlexoActionizer; import org.openflexo.foundation.bindings.Bindable; import org.openflexo.foundation.bindings.BindingModel; import org.openflexo.foundation.bindings.BindingVariable; import org.openflexo.foundation.dm.AutoGeneratedProcessBusinessDataDMEntity; import org.openflexo.foundation.dm.DMEntity; import org.openflexo.foundation.dm.DMModel; import org.openflexo.foundation.dm.DMObject; import org.openflexo.foundation.dm.DMProperty; import org.openflexo.foundation.dm.DMPropertyImplementationType; import org.openflexo.foundation.dm.DMType; import org.openflexo.foundation.dm.DuplicatePropertyNameException; import org.openflexo.foundation.dm.ProcessDMEntity; import org.openflexo.foundation.dm.ProcessInstanceRepository; import org.openflexo.foundation.dm.eo.DMEOAttribute; import org.openflexo.foundation.dm.eo.DMEOEntity; import org.openflexo.foundation.dm.eo.EOAccessException; import org.openflexo.foundation.gen.FlexoProcessImageBuilder; import org.openflexo.foundation.help.ApplicationHelpEntryPoint; import org.openflexo.foundation.ie.ComponentInstance; import org.openflexo.foundation.ie.IEWOComponent; import org.openflexo.foundation.ie.OperationComponentInstance; import org.openflexo.foundation.ie.TabComponentInstance; import org.openflexo.foundation.ie.cl.TabComponentDefinition; import org.openflexo.foundation.ie.dm.ComponentDeleteRequest; import org.openflexo.foundation.ie.dm.ComponentDeleted; import org.openflexo.foundation.ie.dm.ComponentNameChanged; import org.openflexo.foundation.ie.util.TextFieldType; import org.openflexo.foundation.ie.widget.IECheckBoxWidget; import org.openflexo.foundation.ie.widget.IEDropDownWidget; import org.openflexo.foundation.ie.widget.IEHyperlinkWidget; import org.openflexo.foundation.ie.widget.IERadioButtonWidget; import org.openflexo.foundation.ie.widget.IEStringWidget; import org.openflexo.foundation.ie.widget.IETabWidget; import org.openflexo.foundation.ie.widget.IETextAreaWidget; import org.openflexo.foundation.ie.widget.IETextFieldWidget; import org.openflexo.foundation.ie.widget.IEWidget; import org.openflexo.foundation.ie.widget.IEWidgetWithValueList; import org.openflexo.foundation.ie.widget.IEWysiwygWidget; import org.openflexo.foundation.param.DMEntityParameter; import org.openflexo.foundation.param.ParameterDefinition; import org.openflexo.foundation.param.TextFieldParameter; import org.openflexo.foundation.rm.DuplicateResourceException; import org.openflexo.foundation.rm.FlexoProcessResource; import org.openflexo.foundation.rm.FlexoProject; import org.openflexo.foundation.rm.FlexoResource; import org.openflexo.foundation.rm.FlexoWorkflowResource; import org.openflexo.foundation.rm.FlexoXMLStorageResource; import org.openflexo.foundation.rm.InvalidFileNameException; import org.openflexo.foundation.rm.ProjectRestructuration; import org.openflexo.foundation.rm.RMNotification; import org.openflexo.foundation.rm.SaveResourceException; import org.openflexo.foundation.rm.XMLStorageResourceData; import org.openflexo.foundation.stats.ProcessStatistics; import org.openflexo.foundation.utils.FlexoCSS; import org.openflexo.foundation.utils.FlexoIndexManager; import org.openflexo.foundation.utils.FlexoModelObjectReference; import org.openflexo.foundation.utils.FlexoModelObjectReference.ReferenceOwner; import org.openflexo.foundation.utils.FlexoProjectFile; import org.openflexo.foundation.validation.FixProposal; import org.openflexo.foundation.validation.ParameteredFixProposal; import org.openflexo.foundation.validation.Validable; import org.openflexo.foundation.validation.ValidationError; import org.openflexo.foundation.validation.ValidationIssue; import org.openflexo.foundation.validation.ValidationModel; import org.openflexo.foundation.validation.ValidationReport; import org.openflexo.foundation.validation.ValidationRule; import org.openflexo.foundation.validation.ValidationWarning; import org.openflexo.foundation.wkf.MetricsValue.MetricsValueOwner; import org.openflexo.foundation.wkf.action.AddProcessMetricsValue; import org.openflexo.foundation.wkf.action.AddStatus; import org.openflexo.foundation.wkf.action.DeleteMetricsValue; import org.openflexo.foundation.wkf.action.WKFDelete; import org.openflexo.foundation.wkf.dm.AssociationInserted; import org.openflexo.foundation.wkf.dm.PostInserted; import org.openflexo.foundation.wkf.dm.ProcessInserted; import org.openflexo.foundation.wkf.dm.ProcessRemoved; import org.openflexo.foundation.wkf.dm.ServiceInterfaceInserted; import org.openflexo.foundation.wkf.dm.ServiceInterfaceRemoved; import org.openflexo.foundation.wkf.dm.WKFAttributeDataModification; import org.openflexo.foundation.wkf.edge.FlexoPostCondition; import org.openflexo.foundation.wkf.edge.InternalMessageInEdge; import org.openflexo.foundation.wkf.edge.InternalMessageOutEdge; import org.openflexo.foundation.wkf.edge.InvalidEdgeException; import org.openflexo.foundation.wkf.edge.MessageEdge; import org.openflexo.foundation.wkf.edge.WKFAssociation; import org.openflexo.foundation.wkf.node.AbstractActivityNode; import org.openflexo.foundation.wkf.node.AbstractNode; import org.openflexo.foundation.wkf.node.ActionNode; import org.openflexo.foundation.wkf.node.ActivityNode; import org.openflexo.foundation.wkf.node.EventNode; import org.openflexo.foundation.wkf.node.FlexoNode; import org.openflexo.foundation.wkf.node.LOOPOperator; import org.openflexo.foundation.wkf.node.OperationNode; import org.openflexo.foundation.wkf.node.OperatorNode; import org.openflexo.foundation.wkf.node.PetriGraphNode; import org.openflexo.foundation.wkf.node.SelfExecutableNode; import org.openflexo.foundation.wkf.node.SubProcessNode; import org.openflexo.foundation.wkf.node.WKFNode; import org.openflexo.foundation.wkf.ws.DefaultServiceInterface; import org.openflexo.foundation.wkf.ws.DeletePort; import org.openflexo.foundation.wkf.ws.FlexoPort; import org.openflexo.foundation.wkf.ws.FlexoPortMap; import org.openflexo.foundation.wkf.ws.NewPort; import org.openflexo.foundation.wkf.ws.OutPort; import org.openflexo.foundation.wkf.ws.PortRegistery; import org.openflexo.foundation.wkf.ws.ServiceInterface; import org.openflexo.foundation.ws.DuplicateWSObjectException; import org.openflexo.foundation.xml.FlexoProcessBuilder; import org.openflexo.inspector.InspectableObject; import org.openflexo.localization.FlexoLocalization; import org.openflexo.toolbox.EmptyVector; import org.openflexo.toolbox.FileUtils; import org.openflexo.toolbox.JavaUtils; import org.openflexo.toolbox.ProgrammingLanguage; import org.openflexo.toolbox.ReservedKeyword; import org.openflexo.toolbox.ToolBox; import org.openflexo.ws.client.PPMWebService.PPMObject; import org.openflexo.ws.client.PPMWebService.PPMProcess; import org.openflexo.xmlcode.XMLMapping; /** * TODO: rewrite this, since it's no more up-to-date ! A FlexoProcess contains all the data needed by the <I>workflow processor</I> to * execute an instance of a process. In other words, a FlexoProcess contains all the information about the structure of a single workflow.<BR> * <B>Note : </B> The <I>process instance</I> is a running instance of a FlexoProcess. The <I>workflow processor</I> is a processor that can * run a <I>process instance</I>, so one of the most important capabilities of a <I>workflow processor</I> is the interpretation of a * FlexoProcess.<BR> * A FlexoProcess can be part of a FlexoWorkflow. In this case, there will be some links between the different flexo process inside the same * workflow. For instance, a particular node of this process can be able to start one or more process instance of another process of the * same workflow. The dual case is that the end of one or more process instances of another process can have an effect on this process. * * @author benoit, sylvain */ public final class FlexoProcess extends WKFObject implements FlexoImportableObject, ApplicationHelpEntryPoint, XMLStorageResourceData, InspectableObject, Bindable, ExecutableWorkflowElement, MetricsValueOwner, LevelledObject, ReferenceOwner { public static final String VISIBLE_ROLES = "visibleRoles"; static final Logger logger = Logger.getLogger(FlexoProcess.class.getPackage().getName()); public static final String ACTIVITY_CONTEXT = "ACTIVITY"; public static final String OPERATION_CONTEXT = "OPERATION"; public static final String ACTION_CONTEXT = "ACTION"; public static final String EXECUTION_CONTEXT = "EXECUTION"; private FlexoProcessResource _resource; private String _name; private StatusList _statusList; private Vector<FlexoProcess> _subProcesses; private FlexoCSS cssSheet; private transient FlexoProcessNode _processNode; private ActivityPetriGraph _petriGraph; private boolean _isWebService; private PortRegistery _registery; private Vector<ServiceInterface> _serviceInterfaces; private ProcessBindingModel _bindingModel; private String acronym; private Vector<SubProcessNode> _subProcessNodes; private Vector<AbstractNode> allAbstractNodes = null; private Vector<WKFNode> allNodes = null; private Date lastUpdate; /* Key: String, Value: FlexoModelObject */ private BidiMap nameForNodeMap = new DualHashBidiMap(); // Not Serialized private DefaultServiceInterface _portRegistryInterface; private transient ProcessStatistics statistics; public static FlexoActionizer<AddStatus, WKFObject, WKFObject> addStatusActionizer; public static FlexoActionizer<WKFDelete, WKFObject, WKFObject> deleteActionizer; private Vector<MetricsValue> metricsValues; private Vector<FlexoModelObjectReference<Role>> visibleRoles; public static FlexoActionizer<AddProcessMetricsValue, FlexoProcess, WKFObject> addMetricsActionizer; public static FlexoActionizer<DeleteMetricsValue, MetricsValue, MetricsValue> deleteMetricsActionizer; // ========================================================================== // ============================= Constructor // ================================ // ========================================================================== public FlexoProcess(FlexoProcessBuilder builder) { this(builder.getProject()); builder.process = this; _resource = builder.resource; _name = new String(builder.defaultProcessName); initializeDeserialization(builder); } private FlexoProcess(FlexoProject project) { super(project); setProcess(this); _subProcessNodes = new Vector<SubProcessNode>(); _serviceInterfaces = new Vector<ServiceInterface>(); metricsValues = new Vector<MetricsValue>(); visibleRoles = new Vector<FlexoModelObjectReference<Role>>(); } /** * Creates a new FlexoProcess with default values (public API outside XML serialization) * * @param workflow * @throws DuplicateResourceException */ public FlexoProcess(String processName, FlexoWorkflow workflow) throws DuplicateResourceException { this(workflow.getProject()); _name = processName; } /** * Creates and returns a newly created root process * * @return a newly created workflow * @throws InvalidFileNameException */ public static FlexoProcess createNewRootProcess(FlexoWorkflow workflow) { if (workflow.getRootProcess() == null) { try { FlexoProcess returned = createNewProcess(workflow, null, workflow.getWorkflowName(), true); workflow.setRootProcess(returned); return returned; } catch (DuplicateResourceException e) { // Warns about the exception if (logger.isLoggable(Level.WARNING)) { logger.warning("Exception raised: " + e.getClass().getName() + ". See console for details."); } e.printStackTrace(); if (logger.isLoggable(Level.WARNING)) { logger.warning("Cannot create root process !"); } return null; } catch (InvalidFileNameException e) { e.printStackTrace(); if (logger.isLoggable(Level.SEVERE)) { logger.severe("Cannot create root process because " + workflow.getWorkflowName() + " is not a valid file name"); } return null; } } else { if (logger.isLoggable(Level.WARNING)) { logger.warning("Cannot create root process: a root process is already declared"); } return null; } } /** * Creates and returns a newly created process * * @param isRoot * TODO * * @return a newly created workflow * @throws DuplicateResourceException * @throws InvalidFileNameException */ // TODO: Move that in a FlexoAction !!!! public static FlexoProcess createNewProcess(FlexoWorkflow workflow, FlexoProcess parentProcess, String processName, boolean isRoot) throws DuplicateResourceException, InvalidFileNameException { if (processWithSimilarNameExists(workflow, null, ToolBox.getJavaName(processName))) { throw new InvalidFileNameException("A process with similar name exists"); } if (logger.isLoggable(Level.FINE)) { logger.fine("BEGIN createNewProcess()"); } FlexoProject project = workflow.getProject(); if (workflow.getLocalFlexoProcessWithName(processName) != null) { throw new DuplicateResourceException("PROCESS." + processName); } FlexoProcess newProcess = new FlexoProcess(processName, workflow); ProcessDMEntity e = project.getDataModel().getProcessInstanceRepository().getProcessDMEntity(newProcess); if (e != null && logger.isLoggable(Level.SEVERE)) { logger.severe("Dm entity for process " + processName + "already exists."); } FlexoProcessResource processRes = createProcessResource(parentProcess, processName, workflow, newProcess, false); project.registerResource(processRes); if (isRoot) { workflow.setRootProcess(newProcess); } initProcessObjects(newProcess); if (logger.isLoggable(Level.FINE)) { logger.fine("END createNewProcess()"); } return newProcess; } /** * @param process */ public static void initProcessObjects(FlexoProcess process) { // TODO: Use FlexoActions !!! process.isImported = false; process.createsProcessDMEntityIfRequired(); process.createsAutoGeneratedProcessBusinessDataDMEntityIfRequired(); process.updateMetricsValues(); process.setStatusList(new StatusList(process, true)); ActivityPetriGraph.createNewActivityPetriGraph(process); NewPort _newPort = new NewPort(process, process.findNextInitialName("NEW_PORT", NewPort.getDefaultInitialName())); _newPort.setIndexValue(0); process.getPortRegistery().addToNewPorts(_newPort); DeletePort _deletePort = new DeletePort(process, process.findNextInitialName("DELETE_PORT", DeletePort.getDefaultInitialName())); _deletePort.setIndexValue(1); process.getPortRegistery().addToDeletePorts(_deletePort); OutPort _processTerminated = new OutPort(process, process.findNextInitialName("PROCESS_TERMINATED", OutPort.getDefaultInitialName())); _processTerminated.setIndexValue(2); process.getPortRegistery().addToOutPorts(_processTerminated); // ActivityNode begin = (ActivityNode) process.getActivityPetriGraph() // .getAllBeginNodes().firstElement(); // ActivityNode end = (ActivityNode) process.getActivityPetriGraph() // .getAllEndNodes().firstElement(); // new OperationPetriGraph(begin); // new OperationPetriGraph(end); EventNode begin = process.getActivityPetriGraph().getAllEventNodes().firstElement(); EventNode end = process.getActivityPetriGraph().getAllEventNodes().lastElement(); // FlexoPreCondition beginCondition = new FlexoPreCondition(begin, begin // .getOperationPetriGraph().getAllBeginNodes().firstElement()); // FlexoPreCondition endCondition = new FlexoPreCondition(end, end // .getOperationPetriGraph().getAllBeginNodes().firstElement()); try { FlexoPostCondition<?, ?> newBeginPostCondition = new InternalMessageInEdge(_newPort, begin, process); newBeginPostCondition.updateMetricsValues(); _newPort.addToOutgoingPostConditions(newBeginPostCondition); } catch (InvalidEdgeException e1) { e1.printStackTrace(); } try { FlexoPostCondition<?, ?> deleteEndPostCondition = new InternalMessageInEdge(_deletePort, end, process); deleteEndPostCondition.updateMetricsValues(); _deletePort.addToOutgoingPostConditions(deleteEndPostCondition); } catch (InvalidEdgeException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } try { FlexoPostCondition<?, ?> processTerminatedPostCondition = new InternalMessageOutEdge(end, _processTerminated); processTerminatedPostCondition.updateMetricsValues(); processTerminatedPostCondition.setName(FlexoLocalization.localizedForKey("process_terminated")); end.addToOutgoingPostConditions(processTerminatedPostCondition); } catch (InvalidEdgeException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } process.getPortRegistery().setIsVisible(false); } /** * @param workflow * @param parentProcess * @param processName * @param project * @param processResFile * @param newProcess * @return * @throws InvalidFileNameException */ private static FlexoProcessResource createProcessResource(FlexoProcess parentProcess, String processName, FlexoWorkflow workflow, FlexoProcess newProcess, boolean isImported) throws InvalidFileNameException { FlexoProject project = workflow.getProject(); FlexoWorkflowResource workflowRes = workflow.getFlexoResource(); File processFile = ProjectRestructuration.getExpectedProcessFile(project, processName); FlexoProjectFile processResFile = new FlexoProjectFile(processFile, project); if (!processResFile.nameIsValid()) { processResFile.fixName(); } FlexoProcessNode newProcessNode = new FlexoProcessNode(processName, newProcess, workflow); if (parentProcess == null) { if (isImported) { workflow.addToImportedRootNodeProcesses(newProcessNode); } else { workflow.addToTopLevelNodeProcesses(newProcessNode); } } else { if (isImported && !parentProcess.isImported()) { if (logger.isLoggable(Level.SEVERE)) { logger.severe("Trying to add an imported process to an non-imported process!"); } } else if (!isImported && parentProcess.isImported()) { if (logger.isLoggable(Level.SEVERE)) { logger.severe("Trying to add an non-imported process to an imported process!"); } } parentProcess.addToSubProcesses(newProcess); // parentProcess.getProcessNode().addToSubProcesses(newProcessNode); } FlexoProcessResource processRes = null; try { processRes = new FlexoProcessResource(project, newProcess, workflowRes, processResFile); } catch (InvalidFileNameException e1) { boolean ok = false; for (int i = 0; i < 10000 && !ok; i++) { try { processFile = ProjectRestructuration.getExpectedProcessFile(project, FileUtils.getValidFileName(processName) + i); processResFile = new FlexoProjectFile(processFile, project); processRes = new FlexoProcessResource(project, newProcess, workflowRes, processResFile); ok = true; } catch (InvalidFileNameException e2) { } } if (!ok) { processFile = ProjectRestructuration.getExpectedProcessFile(project, FileUtils.getValidFileName(processName) + newProcess.getFlexoID()); processResFile = new FlexoProjectFile(processFile, project); processResFile.setProject(project); processRes = new FlexoProcessResource(project, newProcess, workflowRes, processResFile); } } if (processRes == null) { throw new InvalidFileNameException(processResFile.getRelativePath()); } return processRes; } public static FlexoProcess createImportedProcessFromProcess(FlexoWorkflow workflow, PPMProcess process) throws InvalidFileNameException, DuplicateResourceException { FlexoProject project = workflow.getProject(); FlexoProcess newFIP = workflow.getRecursivelyImportedProcessWithURI(process.getUri()); FlexoProcess parentProcess = null; if (process.getParentProcess() != null) { parentProcess = workflow.getRecursivelyImportedProcessWithURI(process.getParentProcess().getUri()); if (parentProcess == null) { if (logger.isLoggable(Level.WARNING)) { logger.warning("Could not find parent process: " + process.getParentProcess().getName()); } } } if (newFIP != null) { if (parentProcess != null) { parentProcess.getProcessNode().addToSubProcesses(newFIP.getProcessNode()); } try { newFIP.updateFromObject(process); } catch (Exception e) { e.printStackTrace(); } return newFIP; } FlexoProcess fip = new FlexoProcess(workflow.getProject()); fip.isImported = true; try { fip.updateFromObject(process); } catch (Exception e) { // Should not happen for imported processes if (logger.isLoggable(Level.SEVERE)) { logger.severe("setName threw an exception for imported FlexoProcess!!!"); } e.printStackTrace(); } FlexoProcessResource resource = createProcessResource(parentProcess, process.getName(), workflow, fip, true); String name = resource.getName(); if (project.resourceForKey(resource.getResourceType(), name) != null) { name = name + "FromServer"; } int attempt = 1; String base = name; while (project.resourceForKey(resource.getResourceType(), name) != null) { name = base + "_" + String.valueOf(attempt); attempt++; } if (!resource.getName().equals(name)) { resource.setName(name); } project.registerResource(resource); fip.setFlexoResource(resource); if (process.getSubProcesses() != null) { for (int i = 0; i < process.getSubProcesses().length; i++) { PPMProcess sub = process.getSubProcesses()[i]; createImportedProcessFromProcess(workflow, sub); } } return fip; } // Temporary flag to prevent unuseful code from being executed. private boolean isImported = false; @Override public boolean isImported() { if (getProcessNode() != null) { return getProcessNode().isImported(); } return isImported; } @Override public Class<? extends PPMObject> getEquivalentPPMClass() { return PPMProcess.class; } public void updateFromObject(PPMProcess process) throws Exception { super.updateFromObject(process); } public PPMProcess getEquivalentPPMProcess() { return getEquivalentPPMProcess(true); } public PPMProcess getEquivalentPPMProcess(boolean includeChildren) { PPMProcess process = new PPMProcess(); copyObjectAttributesInto(process); if (includeChildren) { int i = 0; PPMProcess[] subs = new PPMProcess[getSubProcesses().size()]; for (FlexoProcess sub : getSubProcesses()) { subs[i] = sub.getEquivalentPPMProcess(includeChildren); i++; } process.setSubProcesses(subs); } return process; } public boolean isEquivalentTo(PPMProcess p) { return isEquivalentTo(p, true); } public boolean isEquivalentTo(PPMProcess p, boolean compareChildren) { if (!super.isEquivalentTo(p)) { return false; } /* * if (getParentProcess()==null && p.getParentProcess()!=null) return false; else if(getParentProcess()!=null && * p.getParentProcess()==null) return false; else if (getParentProcess()!=null && p.getParentProcess()!=null && * !(getParentProcess().getURI().equals(p.getParentProcess().getUri()))) { return false; } */ if (compareChildren) { boolean ok = getSubProcesses().size() != 0 && p.getSubProcesses() != null && p.getSubProcesses().length == getSubProcesses().size() || getSubProcesses().size() == 0 && (p.getSubProcesses() == null || p.getSubProcesses().length == 0); for (int i = 0; ok && i < getSubProcesses().size(); i++) { FlexoProcess fip = getSubProcesses().get(i); if (p.getSubProcesses() == null || p.getSubProcesses().length <= i) { ok = false; } else { ok &= fip.isEquivalentTo(p.getSubProcesses()[i], compareChildren); } ok &= fip.getParentProcess() == this; } if (!ok) { return false; } } return true; } @Override public void setIsDeletedOnServer(boolean isDeletedOnServer) { super.setIsDeletedOnServer(isDeletedOnServer); for (FlexoProcess sub : getSubProcesses()) { sub.setIsDeletedOnServer(isDeletedOnServer); } } // ========================================================================== // ===================== Resource managing // ================================== // ========================================================================== @Override public FlexoProcessResource getFlexoResource() { return _resource; } /** * Overrides getXMLMapping * * @see org.openflexo.foundation.wkf.WKFObject#getXMLMapping() */ @Override public XMLMapping getXMLMapping() { return getProject().getXmlMappings().getWKFMapping(); } @Override public FlexoXMLStorageResource getFlexoXMLFileResource() { return _resource; } @Override public void setFlexoResource(FlexoResource resource) { _resource = (FlexoProcessResource) resource; } /** * Save this object using ResourceManager scheme * * Overrides * * @see org.openflexo.foundation.rm.FlexoResourceData#save() * @see org.openflexo.foundation.rm.FlexoResourceData#save() */ @Override public void save() throws SaveResourceException { _resource.saveResourceData(); } public void clearCachedObjects() { allAbstractNodes = null; allNodes = null; } /** * Implements * * @see org.openflexo.foundation.rm.FlexoResourceData#receiveRMNotification(org.openflexo.foundation.rm.RMNotification) Receive a * notification that has been propagated by the ResourceManager scheme and coming from a modification on an other resource * * Handles ComponentNameChanged notifications * * @see org.openflexo.foundation.rm.FlexoResourceData#receiveRMNotification(org.openflexo.foundation.rm.RMNotification) */ @Override public void receiveRMNotification(RMNotification aNotification) { if (aNotification instanceof ComponentNameChanged) { ComponentNameChanged notification = (ComponentNameChanged) aNotification; for (OperationNode operation : getAllEmbeddedOperationNodes()) { if (operation.getComponentInstance() != null) { OperationComponentInstance ci = operation.getComponentInstance(); if (ci.getComponentName().equals(notification.oldValue())) { if (logger.isLoggable(Level.INFO)) { logger.info("Process " + getName() + " Updating component instance " + notification.component.getName() + " for " + operation.getName()); } ci.notifyComponentNameChanged(notification.component); } } if (operation.getTabOperationComponentInstance() != null) { TabComponentInstance ci = operation.getTabOperationComponentInstance(); if (ci.getComponentName().equals(notification.oldValue())) { if (logger.isLoggable(Level.INFO)) { logger.info("Process " + getName() + " Updating tab component instance " + notification.component.getName() + " for " + operation.getName()); } ci.notifyComponentNameChanged(notification.component); } } } for (ActionNode action : getAllEmbeddedActionNodes()) { if (action.getTabActionComponentInstance() != null) { TabComponentInstance ci = action.getTabActionComponentInstance(); if (ci.getComponentName().equals(notification.oldValue())) { if (logger.isLoggable(Level.INFO)) { logger.info("Process " + getName() + " Updating component instance " + notification.component.getName() + " for " + action.getName()); } ci.notifyComponentNameChanged(notification.component); } } } } if (aNotification instanceof ComponentDeleteRequest) { ComponentDeleteRequest notification = (ComponentDeleteRequest) aNotification; for (Enumeration<OperationNode> en = getAllEmbeddedOperationNodes().elements(); en.hasMoreElements();) { OperationNode node = en.nextElement(); if (node.getComponentInstance() != null) { OperationComponentInstance ci = node.getComponentInstance(); if (ci.getComponentName().equals(notification.component.getComponentName())) { if (logger.isLoggable(Level.INFO)) { logger.info("Receive a deletion request for " + notification.component.getComponentName() + " in " + getName()); } notification.addToWarnings(notification.component.getComponentName() + " is used by operation : " + node.getName()); } } if (node.getTabOperationComponentInstance() != null) { TabComponentInstance ci = node.getTabOperationComponentInstance(); if (ci.getComponentName().equals(notification.component.getComponentName())) { if (logger.isLoggable(Level.INFO)) { logger.info("Receive a deletion request for " + notification.component.getComponentName() + " in " + getName()); } notification.addToWarnings(notification.component.getComponentName() + " is used by operation : " + node.getName()); } } } // We don't check action nodes } if (aNotification instanceof ComponentDeleted) { ComponentDeleted notification = (ComponentDeleted) aNotification; for (Enumeration<OperationNode> en = getAllEmbeddedOperationNodes().elements(); en.hasMoreElements();) { OperationNode node = en.nextElement(); if (node.getTabOperationComponentInstance() != null) { TabComponentInstance ci = node.getTabOperationComponentInstance(); if (ci.getComponentName().equals(notification.component.getComponentName())) { if (logger.isLoggable(Level.INFO)) { logger.info("Operation named " + node.getName() + " has received a deletion request for " + notification.component.getComponentName() + " in " + getName()); } node.removeTabComponentInstance(); } } if (node.getComponentInstance() != null) { OperationComponentInstance ci = node.getComponentInstance(); if (ci.getComponentName().equals(notification.component.getComponentName())) { if (logger.isLoggable(Level.INFO)) { logger.info("Operation named " + node.getName() + " has received a deletion request for " + notification.component.getComponentName() + " in " + getName()); } node.removeComponentInstance(); } } } for (ActionNode action : getAllEmbeddedActionNodes()) { if (action.getTabActionComponentInstance() != null) { TabComponentInstance ci = action.getTabActionComponentInstance(); if (ci.getComponentName().equals(notification.oldValue())) { if (logger.isLoggable(Level.INFO)) { logger.info("Process " + getName() + " Updating component instance " + notification.component.getName() + " for " + action.getName()); } action.removeTabComponentInstance(); } } } } } // ========================================================================== // ============================= Accessors // ================================== // ========================================================================== @Override public String getFullyQualifiedName() { FlexoProcess current = this; String returned = "" + getName(); while (current.getParentProcess() != null) { returned = current.getParentProcess().getName() + "." + returned; current = current.getParentProcess(); } return returned; } /* * public FlexoPetriGraph getPetriGraph(String context) { return getActivityPetriGraph(); } * * public void setPetriGraph(FlexoPetriGraph aPetriGraph, String context) { setActivityPetriGraph((ActivityPetriGraph) aPetriGraph); } */ public ActivityPetriGraph getActivityPetriGraph() { return _petriGraph; } public void setActivityPetriGraph(ActivityPetriGraph aPetriGraph) { _petriGraph = aPetriGraph; if (_petriGraph != null) { _petriGraph.setContainer(this, ACTIVITY_CONTEXT); } } /** * @return * @deprecated use getWorkflow().getRoleList() */ @Deprecated public RoleList getRoleList() { return getWorkflow().getRoleList(); } /** * DEPRECATED: we will use this to add all roles defined in supplied role list to workflow role list * * @param list * @deprecated */ @Deprecated public void setRoleList(RoleList list) { for (Role role : list.getRoles()) { try { getRoleList().addToRoles(role, true); } catch (DuplicateRoleException e) { logger.warning("DuplicateRoleException: " + e); if (logger.isLoggable(Level.FINE)) { logger.log(Level.FINE, "Duplicate role: " + role.getName(), e); } } } } public StatusList getStatusList() { return getStatusList(!isImported()); } protected StatusList getStatusList(boolean createIfMissing) { if (_statusList == null && createIfMissing) { if (!isDeserializing()) { setStatusList(new StatusList(this, true)); } else { setStatusList(new StatusList(this, false)); } } return _statusList; } public void setStatusList(StatusList list) { _statusList = list; setChanged(); notifyAttributeModification("statusList", null, _statusList); } protected void notifyStatusListUpdated() { setChanged(); notifyObservers(new WKFAttributeDataModification("statusList.defaultStatus", null, null)); } /** * @return * @deprecated */ @Deprecated public FlexoCSS getCalculatedCssSheet() { if (cssSheet == null) { if (isTopLevelProcess()) { return getProject().getCssSheet(); } else { return getParentProcess().getCalculatedCssSheet(); } } else { return cssSheet; } } /** * @return * @deprecated */ @Deprecated public FlexoCSS getCssSheet() { return cssSheet; } /** * @deprecated */ @Deprecated public void setCssSheet(FlexoCSS cssSheet) { FlexoCSS old = this.cssSheet; this.cssSheet = cssSheet; setChanged(); notifyAttributeModification("cssSheet", old, cssSheet); } /* * public String getComponentPrefix() { return componentPrefix; } * * * public void setComponentPrefix(String componentPrefix) { this.componentPrefix = componentPrefix; } */ @Override public void updateMetricsValues() { getWorkflow().updateMetricsForProcess(this); } @Override public Vector<MetricsValue> getMetricsValues() { return metricsValues; } public void setMetricsValues(Vector<MetricsValue> metricsValues) { this.metricsValues = metricsValues; setChanged(); } @Override public void addToMetricsValues(MetricsValue value) { if (value.getMetricsDefinition() != null) { metricsValues.add(value); value.setOwner(this); setChanged(); notifyObservers(new MetricsValueAdded(value, "metricsValues")); } } @Override public void removeFromMetricsValues(MetricsValue value) { metricsValues.remove(value); value.setOwner(null); setChanged(); notifyObservers(new MetricsValueRemoved(value, "metricsValues")); } public void addMetrics() { if (addMetricsActionizer != null) { addMetricsActionizer.run(this, null); } } public void deleteMetrics(MetricsValue value) { if (deleteMetricsActionizer != null) { deleteMetricsActionizer.run(value, null); } } public Vector<FlexoModelObjectReference<Role>> getVisibleRoles() { return visibleRoles; } public void setVisibleRoles(Vector<FlexoModelObjectReference<Role>> visibleRoles) { this.visibleRoles = visibleRoles; setChanged(); } public void addToVisibleRoles(FlexoModelObjectReference<Role> value) { if (value != null) { visibleRoles.add(value); value.setOwner(this); setChanged(); notifyAttributeModification(VISIBLE_ROLES, null, value); } } public void removeFromVisibleRoles(FlexoModelObjectReference<Role> value) { visibleRoles.remove(value); value.setOwner(null); value.delete(); setChanged(); notifyAttributeModification(VISIBLE_ROLES, value, null); } @Override public void objectDeleted(FlexoModelObjectReference<?> reference) { if (visibleRoles.contains(reference)) { removeFromVisibleRoles((FlexoModelObjectReference<Role>) reference); } } @Override public void notifyObjectLoaded(FlexoModelObjectReference<?> reference) { } @Override public void objectCantBeFound(FlexoModelObjectReference<?> reference) { objectDeleted(reference); } @Override public void objectSerializationIdChanged(FlexoModelObjectReference<?> reference) { setChanged(); } @Override public String getInspectorName() { if (isImported()) { return Inspectors.WKF.IMPORTED_PROCESS; } return Inspectors.WKF.FLEXO_PROCESS_INSPECTOR; } // ========================================================================== // ============================= Instance Methods // =========================== // ========================================================================== /** * Same as getParentProcess(), but used in an interactive context (inspector) */ /* * public FlexoProcess getInteractiveParentProcess() { return getParentProcess(); } */ /** * Same as setParentProcess(), but used in an interactive context (inspector) In this case, just throw an ProcessMovingConfirmation that * will be caught by a controller which has the responsability to continue process if confirmation was given. */ /* * public void setInteractiveParentProcess(FlexoProcess aNewParentProcess) { if (aNewParentProcess != getInteractiveParentProcess()) { * throw new ProcessMovingConfirmation(this, aNewParentProcess); } } */ /** * Return the parent process of this process * * @return FlexoProcess */ public FlexoProcess getParentProcess() { if (_processNode != null) { if (_processNode.getFatherProcessNode() != null) { return _processNode.getFatherProcessNode().getProcess(); } else { // This is a top-level process return null; } } return null; } /** * Sets the parent process of this process (move) * */ public void setParentProcess(FlexoProcess aNewParentProcess) throws InvalidParentProcessException, InvalidProcessReferencesException { if (getParentProcess() != aNewParentProcess) { if (aNewParentProcess != null && this.getIsWebService()) { throw new InvalidParentProcessException(this, aNewParentProcess); } boolean isImported = isImported(); if (!isImported && !isAcceptableAsParentProcess(aNewParentProcess)) { throw new InvalidParentProcessException(this, aNewParentProcess); } if (aNewParentProcess == null) { if (logger.isLoggable(Level.INFO)) { logger.info("Making process " + this + " context free"); } } else { if (logger.isLoggable(Level.INFO)) { logger.info("Moving process " + this + " under process " + aNewParentProcess); } } FlexoProcessNode newParentProcessNode = aNewParentProcess != null ? aNewParentProcess.getProcessNode() : null; if (newParentProcessNode != null) { newParentProcessNode.addToSubProcesses(getProcessNode()); } else { if (isImported) { getWorkflow().addToImportedRootNodeProcesses(getProcessNode()); } else { getWorkflow().addToTopLevelNodeProcesses(getProcessNode()); } } if (getProcessDMEntity() != null) { getProcessDMEntity().updateParentProcessPropertyIfRequired(); } if (!isImported()) { validateAfterMoving(); } } } public boolean isAcceptableAsParentProcess(FlexoProcess aProcess) { return isProcessHierarchyValidForNewParentProcess(aProcess); } private boolean isProcessHierarchyValidForNewParentProcess(FlexoProcess aNewParentProcess) { return !isImported() && !isAncestorOf(aNewParentProcess) && (aNewParentProcess == null || !aNewParentProcess.isImported()); } private void validateAfterMoving() throws InvalidProcessReferencesException { ValidationReport report = getWorkflow().validate(getProcessMovingValidationModel()); if (report.getErrorNb() > 0) { throw new InvalidProcessReferencesException(this, report); } } private ProcessMovingValidationModel processMovingValidationModel; public ProcessMovingValidationModel getProcessMovingValidationModel() { if (processMovingValidationModel == null && getProject() != null) { processMovingValidationModel = new ProcessMovingValidationModel(getProject()); } return processMovingValidationModel; } private static class ProcessMovingValidationModel extends ValidationModel { public ProcessMovingValidationModel(FlexoProject project) { super(project, project.getTargetType()); registerRule(new FlexoProcess.ProcessHierarchyIsConsistent()); registerRule(new SubProcessNode.SubProcessReferenceMustBeValid()); registerRule(new ComponentInstance.DefinedBindingsMustBeValid()); // Notify that the validation model is complete and that inheritance // computation could be performed update(); } /** * Return a boolean indicating if validation of supplied object must be notified * * @param next * @return a boolean */ @Override protected boolean shouldNotifyValidation(Validable next) { return next instanceof FlexoWorkflow || next instanceof FlexoProcess; } /** * Overrides fixAutomaticallyIfOneFixProposal * * @see org.openflexo.foundation.validation.ValidationModel#fixAutomaticallyIfOneFixProposal() */ @Override public boolean fixAutomaticallyIfOneFixProposal() { return false; } } public boolean isTopLevelProcess() { return getParentProcess() == null; } public boolean isRootProcess() { return isTopLevelProcess() && getWorkflow().getRootProcess() == this; } public boolean isAncestorOf(FlexoProcess anOtherProcess) { FlexoProcess current = anOtherProcess; while (current != null) { if (current == this) { return true; } current = current.getParentProcess(); } return false; } /** * Return all sub-processes of this process, as a Vector of FlexoProcess * * @return a Vector of FlexoProcess */ public Vector<FlexoProcess> getSubProcesses() { if (logger.isLoggable(Level.FINE)) { logger.fine("getSubProcesses() for " + getName()); } _subProcesses = rebuildSubProcesses(); return _subProcesses; } public boolean isSingleSubProcess() { boolean hasAtLeastOne = false; for (SubProcessNode subProcessNode : getSubProcessNodes()) { if (!subProcessNode.isSingle()) { return false; } hasAtLeastOne = true; } return hasAtLeastOne; } public Vector<FlexoProcess> getSortedSubProcesses() { Vector<FlexoProcess> reply = new Vector<FlexoProcess>(); Enumeration<FlexoProcessNode> en = getProcessNode().getSortedSubprocesses(); while (en.hasMoreElements()) { reply.add(en.nextElement().getProcess()); } return reply; } public void addToSubProcesses(FlexoProcess aProcess) { if (logger.isLoggable(Level.INFO)) { logger.info("Adding process " + aProcess.getName() + " as subprocess of " + getName()); } getProcessNode().addToSubProcesses(aProcess.getProcessNode()); rebuildSubProcesses(); if (aProcess.getProcessDMEntity() != null) { aProcess.getProcessDMEntity().createParentProcessPropertyIfRequired(); } setChanged(); notifyObservers(new ProcessInserted(aProcess, this)); if (logger.isLoggable(Level.INFO)) { logger.info("DONE. Adding process " + aProcess.getName() + " as subprocess of " + getName()); } } public void removeFromSubProcesses(FlexoProcess aProcess) { getProcessNode().removeFromSubProcesses(aProcess.getProcessNode()); rebuildSubProcesses(); setChanged(); notifyObservers(new ProcessRemoved(this, getParentProcess())); } /** * Return all sub-processes of this process, as a Vector of FlexoProcess * * @return a Vector of FlexoProcess */ protected Vector<FlexoProcess> rebuildSubProcesses() { if (_subProcesses != null) { _subProcesses.clear(); } if (logger.isLoggable(Level.FINE)) { logger.fine("rebuildSubProcesses() for " + getName()); } if (getProcessNode() == null || getProcessNode().getSubProcesses() == null) { return new Vector<FlexoProcess>(); } _subProcesses = new Vector<FlexoProcess>(); Enumeration en = getProcessNode().getSubProcesses().elements(); while (en.hasMoreElements()) { FlexoProcess subProcess = ((FlexoProcessNode) en.nextElement()).getProcess(); if (subProcess != null) { _subProcesses.add(subProcess); if (logger.isLoggable(Level.FINE)) { logger.fine("Sub-process: " + subProcess.getName()); } } } return _subProcesses; } @Override public double getWidth(String context) { return getWidth(context, 1000.0); } @Override public double getHeight(String context) { return getHeight(context, 1000.0); } public double getScale(String context, double defaultValue) { return _doubleGraphicalPropertyForKey("scale_" + context, defaultValue); } public void setScale(String context, double value) { boolean wasNull = !hasGraphicalPropertyForKey("scale_" + context); double oldValue = getScale(context, value); if (logger.isLoggable(Level.FINE)) { logger.fine("setScale from " + oldValue + " to " + value + " wasNull=" + wasNull); } if (wasNull || value != oldValue) { _setGraphicalPropertyForKey(value, "scale_" + context); setChanged(); } } /** * Return all OperationNode contained in this process * * @return a Vector of OperationNode */ public Vector<OperationNode> getAllEmbeddedOperationNodes() { Vector<OperationNode> v = new Vector<OperationNode>(); if (isImported()) { return v; } if (_petriGraph != null) { for (AbstractActivityNode activity : _petriGraph.getAllEmbeddedAbstractActivityNodes()) { v.addAll(activity.getAllEmbeddedOperationNodes()); } return v; } if (logger.isLoggable(Level.WARNING)) { logger.warning("_petriGraph is null for process:" + getName()); } return v; } /** * Return all OperationNode contained in this process that are associated with a WOComponent * * @return a Vector of OperationNode */ public List<OperationNode> getAllOperationNodesWithComponent() { List<OperationNode> retval = new Vector<OperationNode>(); for (OperationNode operation : getAllEmbeddedOperationNodes()) { if (operation.hasWOComponent()) { retval.add(operation); } } return retval; } public OperationNode getOperationNodeWithFlexoID(long flexoID) { for (OperationNode operation : getAllEmbeddedOperationNodes()) { if (operation != null) { if (operation.getFlexoID() == flexoID) { return operation; } } } if (logger.isLoggable(Level.FINE)) { logger.fine("Could not find operation with flexoID " + flexoID); } return null; } /** * Return all OperationNode contained in this process * * @return a Vector of OperationNode */ public Vector<WKFArtefact> getAllEmbeddedArtefacts() { return _petriGraph.getAllEmbeddedArtefacts(); } /** * Return all WOComponents contained in this process * * @return a Vector of ComponentDefinition */ /* * public Vector<ComponentDefinition> getAllComponents() { Vector<ComponentDefinition> answer = new Vector<ComponentDefinition>(); * answer.addAll(getAllOperationComponents()); answer.addAll(getAllThumnailComponents()); return answer; } */ public Vector<OperationComponentInstance> getAllComponentInstances() { Vector<OperationComponentInstance> answer = new Vector<OperationComponentInstance>(); for (OperationNode operation : getAllEmbeddedOperationNodes()) { if (operation.getComponentInstance() != null && operation.getComponentInstance().getComponentDefinition() != null) { answer.add(operation.getComponentInstance()); } } return answer; } /** * Return all thumnail components contained in this process * * @return a Vector of ThumbnailComponentDefinition */ public Vector<TabComponentDefinition> getAllThumnailComponents() { /* * Vector answer = new Vector(); Enumeration en = getAllOperationNodes().elements(); OperationNode cur = null; * while(en.hasMoreElements()){ cur = (OperationNode)en.nextElement(); if(cur.getComponentDefinition()!=null){ * answer.addAll(cur.getComponentDefinition ().getThumbnailsComponentList()); } } */ return getProject().getFlexoComponentLibrary().getTabComponentList(); } /** * Return all ActionNode contained in this process * * @return a Vector of ActionNode */ public Vector<ActionNode> getAllEmbeddedActionNodes() { if (_petriGraph != null) { Vector<ActionNode> v = new Vector<ActionNode>(); for (AbstractActivityNode a : _petriGraph.getAllEmbeddedAbstractActivityNodes()) { for (OperationNode o : a.getAllEmbeddedOperationNodes()) { v.addAll(o.getAllEmbeddedActionNodes()); } } return v; } else { return new Vector<ActionNode>(); } } @Override public String toString() { return getName(); } @Override public String getName() { return _name; } public String getProcessInstanceEntityName() { return getProcessInstanceEntityName(_name); } public String getProcessInstanceEntityName(String aProcessName) { return beautifyName(aProcessName) + "ProcessInstance"; } public static String beautifyName(String name) { if (name == null) { return null; } if (name.matches(JavaUtils.JAVA_CLASS_NAME_REGEXP)) { return name; } Matcher m = JavaUtils.JAVA_VARIABLE_ACCEPTABLE_PATTERN.matcher(name); StringBuffer sb = new StringBuffer(); int i = 0; while (m.find()) { int n = m.start() - i; for (int j = 0; j < n; j++) { sb.append('_'); } sb.append(ToolBox.capitalize(m.group(), true)); i = m.start() + m.end(); } if (sb.length() == 0 || sb.charAt(0) >= '0' && sb.charAt(0) <= '9') { sb.insert(0, '_'); } return sb.toString(); } private static boolean processWithSimilarNameExists(FlexoWorkflow workflow, FlexoProcess thisProcess, String nameCandidate) { String javaNameCandidate = ToolBox.getJavaName(nameCandidate); for (FlexoProcess p : workflow.getAllFlexoProcesses()) { if (p != thisProcess) { String processJavaName = ToolBox.getJavaName(p.getName()); if (processJavaName.equals(javaNameCandidate)) { return true; } } } return false; } @Override public void setName(String newName) throws DuplicateResourceException, InvalidNameException { if (logger.isLoggable(Level.FINE)) { logger.fine("FlexoProcess.setName() with " + newName + " was: " + _name); } if (!newName.equals(_name) || _name == null) { if (getWorkflow() != null && processWithSimilarNameExists(getWorkflow(), this, ToolBox.getJavaName(newName))) { throw new InvalidNameException("A process with similar name exists"); } if (getProject() != null && getFlexoResource() != null && !isDeserializing()) { if (logger.isLoggable(Level.FINE)) { logger.fine("renameResource() with " + newName); } try { getProject().renameResource(getFlexoResource(), newName); } catch (DuplicateResourceException e) { if (!isImported()) { setChanged(false); notifyObserversAsReentrantModification(new NameChanged(_name, _name)); throw e; } else if (logger.isLoggable(Level.WARNING)) { logger.warning("Duplicate resource thrown on imported process: " + newName); } } if (getProcessNode() != null) { getProcessNode().setChanged();// Workflow needs to be saved // again } } if (!isDeserializing() && getProcessDMEntity() != null) { if (logger.isLoggable(Level.FINE)) { logger.fine("rename process entity with " + getProcessInstanceEntityName(newName)); } getProcessDMEntity().setName(getProcessInstanceEntityName(newName)); } String oldName = _name; _name = newName; /* * if (getProcessNode() != null) { if (logger.isLoggable(Level.FINE)) logger.fine("rename process node with " + newName); * getProcessNode().setName(newName); } */ setChanged(); notifyObservers(new NameChanged(oldName, newName)); } else { if (logger.isLoggable(Level.FINE)) { logger.fine("setName() ignored"); } } } public void createsAutoGeneratedProcessBusinessDataDMEntityIfRequired() { if (!isImported() && getBusinessDataType() == null) { getProject().getDataModel().getProcessBusinessDataRepository().getAutoGeneratedProcessBusinessDataDMEntity(this); } } public ProcessDMEntity createsProcessDMEntityIfRequired() { if (!isImported()) { return getProcessDMEntity(); } return null; } private ProcessDMEntity _processDMEntity = null; public ProcessDMEntity getProcessDMEntity() { if (_processDMEntity == null && !isImported()) { if (getProject() != null) { DMModel dmModel = getProject().getDataModel(); ProcessInstanceRepository processInstanceRepository = dmModel.getProcessInstanceRepository(); _processDMEntity = processInstanceRepository.getProcessDMEntity(this); // logger.info("************ getProcessNode()="+getProcessNode()); if (_processDMEntity == null) { if (logger.isLoggable(Level.INFO)) { logger.info("Creates entry for process " + getName() + " in ProcessInstanceRepository"); } _processDMEntity = new ProcessDMEntity(getProject().getDataModel(), this); getProject().getDataModel().getProcessInstanceRepository().registerEntity(_processDMEntity); } _processDMEntity.setProcess(this); } } return _processDMEntity; } /* * public BindingVariable getBusinessData() { if (_businessData == null) { _businessData = new * BindingVariable(this,getProject().getDataModel()); } return _businessData; } * * public void setBusinessData(BindingVariable businessData) { _businessData = businessData; } */ public DMProperty getBusinessDataProperty() { ProcessDMEntity processDMEntity = getProcessDMEntity(); if (processDMEntity != null) { return processDMEntity.getBusinessDataProperty(); } return null; } public String getBusinessDataVariableName() { if (getBusinessDataProperty() != null) { return getBusinessDataProperty().getName(); } return null; } public void setBusinessDataVariableName(String aName) throws InvalidNameException, DuplicatePropertyNameException { if (aName == null) { return; } if (ReservedKeyword.contains(aName)) { throw new InvalidNameException(); } if (getBusinessDataProperty() != null) { getBusinessDataProperty().setName(aName); } else if (getProcessDMEntity() != null) { if (!aName.trim().equals("")) { getProcessDMEntity().createBusinessDataProperty(aName); } } } public DMEntity getBusinessDataType() { if (getBusinessDataProperty() != null) { return getBusinessDataProperty().getType().getBaseEntity(); } return null; } public void setBusinessDataType(DMEntity aType) { if (getBusinessDataProperty() != null) { getBusinessDataProperty().setType(DMType.makeResolvedDMType(aType)); } else if (getProcessDMEntity() != null) { getProcessDMEntity().createBusinessDataProperty(aType); setChanged(); notifyAttributeModification("businessDataVariableName", null, getBusinessDataProperty()); } if (aType != null && !aType.hasPropertyNamed("status")) { if (aType instanceof DMEOEntity) { DMEOAttribute statusAttribute; try { statusAttribute = DMEOAttribute.createsNewDMEOAttribute(aType.getDMModel(), (DMEOEntity) aType, "status", false, true, DMPropertyImplementationType.PUBLIC_ACCESSORS_PRIVATE_FIELD); statusAttribute.setPrototype(aType.getDMModel().getPrototypeNamed("str100")); statusAttribute.setColumnName("PROCESS_STATUS"); ((DMEOEntity) aType).registerProperty(statusAttribute); } catch (EOAccessException e) { // Ok this sucks. logger.log(Level.SEVERE, "Could not create status attribute in business data class", e); } } else { aType.createDMProperty("status", DMType.makeResolvedDMType(String.class, getProject()), DMPropertyImplementationType.PUBLIC_ACCESSORS_ONLY); } } setChanged(); notifyAttributeModification("businessDataType", null, aType); } @Override public BindingModel getBindingModel() { if (_bindingModel == null) { _bindingModel = new ProcessBindingModel(); } return _bindingModel; } public class ProcessBindingModel extends BindingModel { private ProcessBindingVariable _processInstance; ProcessBindingModel() { super(); _processInstance = new ProcessBindingVariable(); } @Override public int getBindingVariablesCount() { return 1; } @Override public BindingVariable getBindingVariableAt(int index) { return getProcessInstanceBindingVariable(); } public BindingVariable getProcessInstanceBindingVariable() { return _processInstance; } @Override public boolean allowsNewBindingVariableCreation() { return false; } public class ProcessBindingVariable extends BindingVariable { private DMType _processBindingVariableType = null; ProcessBindingVariable() { super(FlexoProcess.this, FlexoProcess.this.getProject().getDataModel(), FlexoLocalization .localizedForKey("access_to_the_current_process_instance")); setVariableName("processInstance"); } @Override public DMType getType() { if (_processBindingVariableType == null || _processBindingVariableType.getKindOfType() != DMType.KindOfType.RESOLVED || _processBindingVariableType.getBaseEntity() != getProcessDMEntity()) { _processBindingVariableType = DMType.makeResolvedDMType(getProcessDMEntity()); } return _processBindingVariableType; } } } public FlexoProcessNode getProcessNode() { return _processNode; } public void setProcessNode(FlexoProcessNode processNode) { _processNode = processNode; rebuildSubProcesses(); } /** * Return all abstract node at all levels for this process * * @return a Vector of AbstractNode */ public Vector<AbstractNode> getAllAbstractNodes() { if (allAbstractNodes == null) { allAbstractNodes = new Vector<AbstractNode>(); if (getPortRegistery() != null) { allAbstractNodes.addAll(getPortRegistery().getAllPorts()); } appendAllAbstractNodesOfPetriGraph(getActivityPetriGraph(), allAbstractNodes); /* * allAbstractNodes.addAll(getAllActivities()); if (getPortRegistery() != null) { * allAbstractNodes.addAll(getPortRegistery().getAllPorts()); } for (Enumeration e = getAllSubProcessNodes().elements(); * e.hasMoreElements();) { SubProcessNode node = (SubProcessNode) e.nextElement(); if (node.getPortMapRegistery() != null) { * allAbstractNodes .addAll(node.getPortMapRegistery().getPortMaps()); } } * * // Don't do this, this will be done while adding getAllDeepOperatorNodes() // All activity-level operator nodes were recorded * twice !!!!!! * * // allAbstractNodes.addAll(getAllOperatorNodes()); * * if (_petriGraph != null) { allAbstractNodes.addAll(_petriGraph.getAllOperationNodes()); * allAbstractNodes.addAll(_petriGraph.getAllActionNodes()); allAbstractNodes.addAll(_petriGraph.getAllDeepOperatorNodes()); } */ } return allAbstractNodes; } private void appendAllAbstractNodesOfPetriGraph(FlexoPetriGraph pg, Vector<AbstractNode> returned) { for (AbstractNode n : pg.getNodes()) { appendAllAbstractNodes(n, returned); } } private void appendAllAbstractNodes(AbstractNode node, Vector<AbstractNode> returned) { returned.add(node); if (node instanceof FlexoNode) { returned.addAll(((FlexoNode) node).getPreConditions()); } if (node instanceof SubProcessNode) { if (((SubProcessNode) node).getPortMapRegistery() != null) { returned.addAll(((SubProcessNode) node).getPortMapRegistery().getPortMaps()); } } if (node instanceof AbstractActivityNode && ((AbstractActivityNode) node).hasContainedPetriGraph()) { appendAllAbstractNodesOfPetriGraph(((AbstractActivityNode) node).getContainedPetriGraph(), returned); } if (node instanceof OperationNode && ((OperationNode) node).hasContainedPetriGraph()) { appendAllAbstractNodesOfPetriGraph(((OperationNode) node).getContainedPetriGraph(), returned); } if (node instanceof SelfExecutableNode && ((SelfExecutableNode) node).hasExecutionPetriGraph()) { appendAllAbstractNodesOfPetriGraph(((SelfExecutableNode) node).getExecutionPetriGraph(), returned); } if (node instanceof LOOPOperator && ((LOOPOperator) node).hasExecutionPetriGraph()) { appendAllAbstractNodesOfPetriGraph(((LOOPOperator) node).getExecutionPetriGraph(), returned); } } /** * Return all abstract node at all levels for this process * * @return a Vector of AbstractNode */ public Vector<WKFNode> getAllNodes() { if (allNodes == null) { allNodes = new Vector<WKFNode>(); if (getPortRegistery() != null) { allNodes.addAll(getPortRegistery().getAllPorts()); } appendAllNodesOfPetriGraph(getActivityPetriGraph(), allNodes); /* * allAbstractNodes.addAll(getAllActivities()); if (getPortRegistery() != null) { * allAbstractNodes.addAll(getPortRegistery().getAllPorts()); } for (Enumeration e = getAllSubProcessNodes().elements(); * e.hasMoreElements();) { SubProcessNode node = (SubProcessNode) e.nextElement(); if (node.getPortMapRegistery() != null) { * allAbstractNodes .addAll(node.getPortMapRegistery().getPortMaps()); } } * * // Don't do this, this will be done while adding getAllDeepOperatorNodes() // All activity-level operator nodes were recorded * twice !!!!!! * * // allAbstractNodes.addAll(getAllOperatorNodes()); * * if (_petriGraph != null) { allAbstractNodes.addAll(_petriGraph.getAllOperationNodes()); * allAbstractNodes.addAll(_petriGraph.getAllActionNodes()); allAbstractNodes.addAll(_petriGraph.getAllDeepOperatorNodes()); } */ } return allNodes; } private void appendAllNodesOfPetriGraph(FlexoPetriGraph pg, Vector<WKFNode> returned) { for (AbstractNode n : pg.getNodes()) { appendAllNodes(n, returned); } returned.addAll(pg.getArtefacts()); } private void appendAllNodes(WKFNode node, Vector<WKFNode> returned) { returned.add(node); if (node instanceof FlexoNode) { returned.addAll(((FlexoNode) node).getPreConditions()); } if (node instanceof SubProcessNode) { if (((SubProcessNode) node).getPortMapRegistery() != null) { returned.addAll(((SubProcessNode) node).getPortMapRegistery().getPortMaps()); } } if (node instanceof AbstractActivityNode && ((AbstractActivityNode) node).hasContainedPetriGraph()) { appendAllNodesOfPetriGraph(((AbstractActivityNode) node).getContainedPetriGraph(), returned); } if (node instanceof OperationNode && ((OperationNode) node).hasContainedPetriGraph()) { appendAllNodesOfPetriGraph(((OperationNode) node).getContainedPetriGraph(), returned); } if (node instanceof SelfExecutableNode && ((SelfExecutableNode) node).hasExecutionPetriGraph()) { appendAllNodesOfPetriGraph(((SelfExecutableNode) node).getExecutionPetriGraph(), returned); } if (node instanceof LOOPOperator && ((LOOPOperator) node).hasExecutionPetriGraph()) { appendAllNodesOfPetriGraph(((LOOPOperator) node).getExecutionPetriGraph(), returned); } } /** * Return all activities for this process * * @return a Vector of AbstractActivityNode */ public Vector<AbstractActivityNode> getAllAbstractActivityNodes() { if (_petriGraph != null) { return _petriGraph.getAllAbstractActivityNodes(); } else { return new Vector<AbstractActivityNode>(); } } public Vector<AbstractActivityNode> getAllMeaningFullActivityNodes() { Vector<AbstractActivityNode> all = getAllAbstractActivityNodes(); Vector<AbstractActivityNode> reply = new Vector<AbstractActivityNode>(); for (AbstractActivityNode node : all) { if (!node.isBeginOrEndNode() && node.getName().trim().length() > 0) { if (!node.getDontGenerate()) { reply.add(node); } } } return reply; } public Vector<SubProcessNode> getAllMeaningSubProcessNodes() { Vector<AbstractActivityNode> all = getAllAbstractActivityNodes(); Vector<SubProcessNode> reply = new Vector<SubProcessNode>(); for (AbstractActivityNode node : all) { if (!node.isBeginOrEndNode() && node.getName().trim().length() > 0) { if (node instanceof SubProcessNode) { reply.add((SubProcessNode) node); } } } return reply; } public Vector<AbstractActivityNode> getAllEmbeddedAbstractActivityNodes() { if (_petriGraph != null) { return _petriGraph.getAllEmbeddedAbstractActivityNodes(); } else { return new Vector<AbstractActivityNode>(); } } public Vector<PetriGraphNode> getAllAbstractActivityNodesAndActivityOperators() { if (_petriGraph != null) { Vector<PetriGraphNode> v = new Vector<PetriGraphNode>(); v.addAll(_petriGraph.getAllEmbeddedAbstractActivityNodes()); v.addAll(_petriGraph.getAllEmbeddedOperatorsOfSameLevel()); return v; } else { return new Vector<PetriGraphNode>(); } } public Vector<PetriGraphNode> getAllAbstractActivityNodesAndActivityOperatorsWithEvents() { if (_petriGraph != null) { Vector<PetriGraphNode> v = new Vector<PetriGraphNode>(); v.addAll(_petriGraph.getAllEmbeddedNodesOfClass(AbstractActivityNode.class)); v.addAll(_petriGraph.getAllEmbeddedNodesOfClassOfSameLevel(OperatorNode.class)); v.addAll(_petriGraph.getAllEmbeddedNodesOfClassOfSameLevel(EventNode.class)); return v; } else { return new Vector<PetriGraphNode>(); } } /** * Return all activities of the underlying petri graph. * * @return a Vector of ActivityNode */ public Vector<ActivityNode> getAllActivityNodes() { if (_petriGraph != null) { return _petriGraph.getAllActivityNodes(); } else { return new Vector<ActivityNode>(); } } public AbstractActivityNode getAbstractActivityNodeNamed(String name) { Enumeration<AbstractActivityNode> en = getAllEmbeddedAbstractActivityNodes().elements(); while (en.hasMoreElements()) { AbstractActivityNode node = en.nextElement(); if (node.getName().equals(name)) { return node; } } if (logger.isLoggable(Level.WARNING)) { logger.warning("AbstractActivity named " + name + " could not be found in process " + getProcess().getName()); } return null; } public EventNode getEventNodeNamed(String name) { Enumeration<EventNode> en = getAllEventNodes().elements(); while (en.hasMoreElements()) { EventNode node = en.nextElement(); if (node.getName().equals(name)) { return node; } } if (logger.isLoggable(Level.WARNING)) { logger.warning("AbstractActivity named " + name + " could not be found in process " + getProcess().getName()); } return null; } /** * Return all sub-processes for this process * * @return a Vector of SubProcessNode */ public Vector<SubProcessNode> getAllSubProcessNodes() { if (_petriGraph != null) { return _petriGraph.getAllSubProcessNodes(); } else { return new Vector<SubProcessNode>(); } } public Vector<SubProcessNode> getAllProcessInstances() { return getWorkflow().getAllSubProcessNodeUsingProcess(this); } /** * Return a vector of all BEGIN_NODE of the underlying Petri Graph * * @return Vector of Begin nodes */ public Vector<FlexoNode> getAllBeginNodes() { if (_petriGraph != null) { return _petriGraph.getAllBeginNodes(); } else { return new Vector<FlexoNode>(); } } /** * Return a vector of all END_NODE of the underlying Petri Graph * * @return Vector of end nodes */ public Vector<FlexoNode> getAllEndNodes() { if (_petriGraph != null) { return _petriGraph.getAllEndNodes(); } else { return new Vector<FlexoNode>(); } } /** * Return a vector of all OPERATOR of the underlying Petri Graph * * @return Vector of ActivityNode */ public Vector<OperatorNode> getAllOperatorNodes() { if (_petriGraph != null) { return _petriGraph.getAllOperatorNodes(); } else { return new Vector<OperatorNode>(); } } public Vector<OperatorNode> getAllEmbeddedOperatorNodes() { if (_petriGraph != null) { return _petriGraph.getAllEmbeddedOperators(); } else { return new Vector<OperatorNode>(); } } /** * Return a vector of all Event nodes of the underlying Petri Graph * * @return Vector of EventNode */ public Vector<EventNode> getAllEventNodes() { // TODO: optimize me later !!! if (_petriGraph != null) { return _petriGraph.getAllEventNodes(); } else { return new Vector<EventNode>(); } } public Vector<FlexoPostCondition<?, ?>> getAllPostConditions() { Vector<FlexoPostCondition<?, ?>> returned = new Vector<FlexoPostCondition<?, ?>>() { @Override public synchronized boolean addAll(Collection<? extends FlexoPostCondition<?, ?>> c) { for (FlexoPostCondition<?, ?> edge : c) { if (!contains(edge)) { add(edge); } } return true; } }; for (AbstractNode n : getAllAbstractNodes()) { returned.addAll(n.getOutgoingPostConditions()); returned.addAll(n.getIncomingPostConditions()); } return returned; } public Vector<WKFAssociation> getAllAssociations() { Vector<WKFAssociation> returned = new Vector<WKFAssociation>() { @Override public synchronized boolean addAll(Collection<? extends WKFAssociation> c) { for (WKFAssociation edge : c) { if (!contains(edge)) { add(edge); } } return true; } }; for (WKFNode n : getAllNodes()) { returned.addAll(n.getOutgoingAssociations()); returned.addAll(n.getIncomingAssociations()); } return returned; } public Vector<MessageEdge<?, ?>> getAllMessageEdges() { // logger.info("getAllMessageEdges for process "+getName()); Vector<MessageEdge<?, ?>> returned = new Vector<MessageEdge<?, ?>>(); for (FlexoPostCondition<?, ?> e : getAllPostConditions()) { if (e instanceof MessageEdge) { returned.add((MessageEdge<?, ?>) e); // logger.info("Found "+e.getDerivedNameFromStartingObject()+" to "+e.getDerivedNameFromEndingObject()); } } return returned; } /** * Returns the level of a FlexoProcess (which is {@link FlexoLevel.PROCESS} ). * * @see org.openflexo.foundation.wkf.LevelledObject#getLevel() */ @Override public FlexoLevel getLevel() { return FlexoLevel.PROCESS; } // ========================================================================== // ================================= Delete =============================== // ========================================================================== @Override public final void delete() { if (isImported()) { isImported = true;// This is important, because it allows to do some } // tests on this deleted object if (logger.isLoggable(Level.FINE)) { logger.fine("delete: FlexoProcess " + getName()); } for (FlexoProcess p : new Vector<FlexoProcess>(getSubProcesses())) { p.delete(); } Vector<SubProcessNode> allBoundSubProcessNodes = new Vector<SubProcessNode>(getSubProcessNodes()); for (Enumeration<SubProcessNode> e = allBoundSubProcessNodes.elements(); e.hasMoreElements();) { SubProcessNode subProcessNode = e.nextElement(); subProcessNode.setSubProcess(null); if (logger.isLoggable(Level.INFO)) { logger.info("Set subprocess to null for " + subProcessNode.getName()); } } /* * FlexoProcessNode processNode = getProcessNode(); if (processNode != null) { processNode.delete(); processNode = null; } */ if (_petriGraph != null) { _petriGraph.delete(); } FlexoProcess parentProcess = getParentProcess(); if (getFlexoResource() != null) { getFlexoResource().delete(); } if (getProcessDMEntity() != null) { getProcessDMEntity().delete(); } if (getProcessNode() != null) { getProcessNode().delete(); } else { if (logger.isLoggable(Level.WARNING)) { logger.warning("Process " + getName() + " has no process node associated!"); } } FlexoProcessImageBuilder.deleteSnapshot(this); super.delete(); if (nameForNodeMap != null) { nameForNodeMap.clear(); } nameForNodeMap = null; setChanged(); notifyObservers(new ProcessRemoved(this, parentProcess)); deleteObservers(); } /** * Build and return a vector of all the objects that will be deleted during process deletion * * @param aVector * of DeletableObject */ @Override public Vector<WKFObject> getAllEmbeddedDeleted() { return getAllEmbeddedWKFObjects(); } /** * Return a Vector of all embedded WKFObjects * * @return a Vector of WKFObject instances */ @Override public Vector<WKFObject> getAllEmbeddedWKFObjects() { Vector<WKFObject> returned = new Vector<WKFObject>(); returned.add(this); if (_petriGraph != null) { returned.addAll(_petriGraph.getAllEmbeddedWKFObjects()); } if (getPortRegistery() != null) { returned.addAll(getPortRegistery().getAllEmbeddedWKFObjects()); } if (getServiceInterfaces() != null) { Enumeration en = getServiceInterfaces().elements(); while (en.hasMoreElements()) { ServiceInterface service = (ServiceInterface) en.nextElement(); returned.addAll(service.getAllEmbeddedWKFObjects()); } } if (getStatusList() != null) { returned.addAll(getStatusList().getAllEmbeddedWKFObjects()); } returned.addAll(getMetricsValues()); return returned; } /** * Return a vector of all embedded objects on which the validation will be performed * * @return a Vector of Validable objects */ @Override public Vector<Validable> getAllEmbeddedValidableObjects() { Vector<Validable> returned = new Vector<Validable>(); returned.addAll(getAllEmbeddedWKFObjects()); for (OperationNode operation : getAllEmbeddedOperationNodes()) { if (operation.getComponentInstance() != null) { returned.add(operation.getComponentInstance()); } } return returned; } /** * @param baseName * @param node * @return */ public String findNextInitialName(String baseName) { return nextInitialName(baseName, getFullyQualifiedName() + "." + baseName); } /** * @param baseName * @param node * @return */ public String findNextInitialName(String prefix, String baseName) { return nextInitialName(baseName, getFullyQualifiedName() + "." + prefix + "." + baseName); } /** * @param baseName * @param node * @return */ public String findNextNonAmbigousNameForNode(String baseName, AbstractNode aNode) { if (aNode instanceof PetriGraphNode) { if (aNode instanceof AbstractActivityNode) { return findNextInitialName(baseName); } if (aNode instanceof OperationNode) { return findNextInitialName(baseName, ((OperationNode) aNode).getAbstractActivityNode()); } if (aNode instanceof ActionNode) { return findNextInitialName(baseName, ((ActionNode) aNode).getOperationNode()); } } else if (aNode instanceof OperatorNode) { if (aNode.getLevel() == FlexoLevel.ACTIVITY) { return findNextInitialName(baseName); } if (aNode.getLevel() == FlexoLevel.OPERATION) { return findNextInitialName(baseName, ((OperatorNode) aNode).getAbstractActivityNode()); } if (aNode.getLevel() == FlexoLevel.ACTION) { return findNextInitialName(baseName, ((OperatorNode) aNode).getOperationNode()); } } else if (aNode instanceof FlexoPort) { return findNextInitialName(baseName); } else if (aNode instanceof FlexoPortMap) { return findNextInitialName(baseName, ((FlexoPortMap) aNode).getSubProcessNode()); } if (logger.isLoggable(Level.WARNING)) { logger.warning("Unexpected type " + aNode.getClass().getName()); } return null; } /** * @param baseName * @param node * @return */ public String findNextInitialName(String baseName, WKFObject node) { if (node instanceof AbstractNode) { return findNextNonAmbigousNameForNode(baseName, (AbstractNode) node); } return baseName; } /** * @param baseName * @param node * @return */ public String findNextInitialName(String baseName, AbstractActivityNode activityNode) { if (activityNode == null) { return baseName; } return nextInitialName(baseName, getFullyQualifiedName() + "." + activityNode.getName() + "." + baseName); } /** * @param baseName * @param node * @return */ public String findNextInitialName(String baseName, OperationNode operationNode) { if (operationNode == null) { return baseName; } return nextInitialName(baseName, getFullyQualifiedName() + "." + operationNode.getAbstractActivityNode().getName() + "." + operationNode.getName() + "." + baseName); } /** * @param fullQualifiedBaseName * @param node * @return */ private String nextInitialName(String baseName, String fullQualifiedBaseName) { // Scrum 1.3.2: request to remove disambiguation of node names /* * Vector allNodes = getAllAbstractNodes(); * * boolean found = false; int i = 0; String tryWith = fullQualifiedBaseName; String returnedName = baseName; * * if (logger.isLoggable(Level.FINE)) logger.fine("findNextInitialName() for " + fullQualifiedBaseName); * * while (!found) { boolean alreadyExists = false; if (logger.isLoggable(Level.FINE)) logger.fine("look " + tryWith); for * (Enumeration e = allNodes.elements(); (e.hasMoreElements() && !(alreadyExists));) { String next = ((AbstractNode) * e.nextElement()).getFullyQualifiedName(); if (logger.isLoggable(Level.FINE)) logger.fine(" > already " + next); if * (next.equalsIgnoreCase(tryWith)) { alreadyExists = true; } } alreadyExists |= getName().equalsIgnoreCase(returnedName); if * (alreadyExists) { i++; tryWith = fullQualifiedBaseName + "-" + i; returnedName = baseName + "-" + i; } else { found = true; } } * if (logger.isLoggable(Level.FINE)) logger.fine("findNextInitialName() return " + tryWith); return returnedName; */ return baseName; } public PortRegistery getPortRegistery() { if (_registery == null && !isImported()) { _registery = new PortRegistery(this); // TODO: following must be put in some finalizer /* * _registery.setX(250,WKFRepresentableObject.BASIC_PROCESS_EDITOR); * _registery.setY(60,WKFRepresentableObject.BASIC_PROCESS_EDITOR); _registery * .setWidth(80,WKFRepresentableObject.BASIC_PROCESS_EDITOR); _registery * .setHeight(20,WKFRepresentableObject.BASIC_PROCESS_EDITOR); _registery.setX(250,WKFRepresentableObject.SWIMMING_LANE_EDITOR); * _registery.setY(60,WKFRepresentableObject.SWIMMING_LANE_EDITOR); _registery * .setWidth(80,WKFRepresentableObject.SWIMMING_LANE_EDITOR); _registery * .setHeight(20,WKFRepresentableObject.SWIMMING_LANE_EDITOR); */ } return _registery; } public void setPortRegistery(PortRegistery registery) { _registery = registery; if (registery.getProcess() != this) { if (logger.isLoggable(Level.WARNING)) { logger.warning("there is a problem!"); } } _registery.setProcess(this); } public DefaultServiceInterface getPortRegisteryInterface() { if (getPortRegistery() != null && _portRegistryInterface == null) { try { _portRegistryInterface = new DefaultServiceInterface(this); _portRegistryInterface.updateFromPortRegistery(); } catch (FlexoException f) { if (logger.isLoggable(Level.WARNING)) { logger.warning("Exception should not arise"); } f.printStackTrace(); } } return _portRegistryInterface; } public Vector<ServiceInterface> getServiceInterfaces() { return _serviceInterfaces; } public void setServiceInterfaces(Vector<ServiceInterface> vector) { _serviceInterfaces = vector; } public ServiceInterface addServiceInterface(String name) throws DuplicateWKFObjectException, DuplicateWSObjectException { // will throw an exception ServiceInterface newInterface; try { ServiceInterface.checkInterfaceName(this, name, null); newInterface = new ServiceInterface(this, name); } catch (DuplicateWKFObjectException e) { if (logger.isLoggable(Level.WARNING)) { logger.warning("An interface with the same name (" + name + ") already exist"); } throw e; } catch (DuplicateWSObjectException e) { throw e; } addToServiceInterfaces(newInterface); return newInterface; } public void addToServiceInterfaces(ServiceInterface anInterface) { if (!_serviceInterfaces.contains(anInterface)) { _serviceInterfaces.add(anInterface); anInterface.setProcess(this); setChanged(); notifyObservers(new ServiceInterfaceInserted(anInterface)); } } public void removeFromServiceInterfaces(ServiceInterface anInterface) { if (_serviceInterfaces.contains(anInterface)) { _serviceInterfaces.remove(anInterface); setChanged(); notifyObservers(new ServiceInterfaceRemoved(anInterface)); anInterface.setProcess(null); } } public ServiceInterface getServiceInterfaceNamed(String interfaceName) { Enumeration<ServiceInterface> en = _serviceInterfaces.elements(); while (en.hasMoreElements()) { ServiceInterface intf = en.nextElement(); if (intf.getName().equals(interfaceName)) { return intf; } } return null; } @Deprecated public boolean getIsWebService() { return _isWebService; } @Deprecated public void setIsWebService(boolean isWebService) { boolean oldValue = _isWebService; _isWebService = isWebService; if (isWebService != oldValue) { notifyAttributeModification("isWebService", new Boolean(oldValue), new Boolean(isWebService)); } } public Vector<SubProcessNode> getSubProcessNodes() { return _subProcessNodes; } public void addToSubProcessNodes(SubProcessNode node) { if (logger.isLoggable(Level.FINE)) { logger.fine(getName() + ": addToSubProcessNodes() " + node.getName()); } if (!node.getXMLResourceData().getFlexoXMLFileResource().isConverting() && !_subProcessNodes.contains(node)) { _subProcessNodes.add(node); addObserver(node); } } public void removeFromSubProcessNodes(SubProcessNode node) { if (logger.isLoggable(Level.FINE)) { logger.fine(getName() + ": removeFromSubProcessNodes() " + node.getName()); } _subProcessNodes.remove(node); deleteObserver(node); } public void notifyPostInserted(FlexoPostCondition<?, ?> post) { setChanged(); notifyObservers(new PostInserted(post)); } public void notifyAssociationInserted(WKFAssociation association) { setChanged(); notifyObservers(new AssociationInserted(association)); } /** * We finalize here serialization since port and port registery definitions are inter-procedural ! */ public void finalizeProcessBindings() { if (logger.isLoggable(Level.FINE)) { logger.fine("finalizeProcessBindings() " + getName()); } for (Enumeration e = getAllSubProcessNodes().elements(); e.hasMoreElements();) { SubProcessNode node = (SubProcessNode) e.nextElement(); if (node.getSubProcess() != null) { if (logger.isLoggable(Level.FINE)) { logger.finer("Finalize linking " + getName() + " with " + node.getSubProcess().getName()); } if (!node.getSubProcess().isImported()) { node.getPortMapRegistery().lookupServiceInterface(); } } else if (node.getSubProcessName() != null) { if (logger.isLoggable(Level.WARNING)) { logger.warning("Undefined sub-process " + node.getSubProcessName() + " referenced in process " + getName()); } node.setSubProcessName(null); } if (node.getSubProcess() == null && node.getPortMapRegistery() != null) { if (logger.isLoggable(Level.WARNING)) { logger.warning("Inconsistent data : PortMapRegistery defined while no sub-process is defined: remove it"); } node.getPortMapRegistery().delete(); node.setSubProcessName(null); } } // Now do it with message edges // Vector<MessageEdge> unboundMessageEdgesToRemove = new // Vector<MessageEdge>(); for (MessageEdge messageEdge : getAllMessageEdges()) { messageEdge.lookupMessageDefinition(); } } @Override public synchronized void setIsModified() { if (ignoreNotifications()) { return; } if (nameForNodeMap != null) { nameForNodeMap.clear();// Any modification is capable of modify the } // names of the objects. lastUpdate = null; // Reset the last update date so that it will be // recomputed according to the new lastMemoryUpdate! super.setIsModified(); } /** * This date is use to perform fine tuning resource dependancies computing * * @return */ @Override public Date getLastUpdate() { if (lastUpdate == null) { lastUpdate = lastMemoryUpdate(); } if (lastUpdate == null) { lastUpdate = super.getLastUpdate(); } return lastUpdate; } public void setLastUpdate(Date lastUpdate) { this.lastUpdate = lastUpdate; } public String getAcronym() { return acronym; } public void setAcronym(String acronym) { this.acronym = acronym; } public static final String getTypeName() { return "PROCESS"; } private static final Vector<WKFObject> EMPTY_VECTOR = EmptyVector.EMPTY_VECTOR(WKFObject.class); public void addStatus() { if (addStatusActionizer != null) { addStatusActionizer.run(this, EMPTY_VECTOR); } } public void deleteStatus(Status object) { if (deleteActionizer != null) { deleteActionizer.run(object, EMPTY_VECTOR); } } /** * @return * @deprecated */ @Deprecated public Enumeration<Role> getSortedRoles() { return getWorkflow().getSortedRoles(); } public Enumeration<Status> getSortedStatuses() { if (getStatusList() == null) { return ToolBox.getEnumeration(new Status[0]); } disableObserving(); Status[] o = FlexoIndexManager.sortArray(getStatusList().getStatus().toArray(new Status[0])); enableObserving(); return ToolBox.getEnumeration(o); } public Enumeration<EventNode> getSortedEvents() { disableObserving(); EventNode[] o = FlexoIndexManager.sortArray(getAllEventNodes().toArray(new EventNode[0])); enableObserving(); return ToolBox.getEnumeration(o); } // ========================================================= // ============= Control graph management ================== // ========================================================= private static ControlGraphFactory<FlexoProcess> _executionComputingFactory; public static void setExecutionComputingFactory(ControlGraphFactory<FlexoProcess> factory) { _executionComputingFactory = factory; } public WorkflowControlGraph<FlexoProcess> getExecution() { if (_executionComputingFactory != null) { return _executionComputingFactory.getControlGraph(this); } return null; } @Override public void setProgrammingLanguageForControlGraphComputation(ProgrammingLanguage language) { if (getExecution() != null) { getExecution().setProgrammingLanguage(language); } } @Override public void setInterproceduralForControlGraphComputation(boolean interprocedural) { if (getExecution() != null) { getExecution().setInterprocedural(interprocedural); } } @Override public String getExecutableElementName() { return FlexoLocalization.localizedForKeyWithParams("process_($0)", getName()); } public String getExecutionClassName() { return ToolBox.capitalize(ToolBox.getJavaName(getName(), false, false) + "Processor"); } public String getExecutionGroupName() { return "org.openflexo.controlgraph." + getProject().getPrefix().toLowerCase(); } public synchronized BidiMap getNameForNodeMap() { if (nameForNodeMap.size() == 0) { buildNameForNodeMap(); } return nameForNodeMap; } public synchronized String getUniqueNameForNode(AbstractNode node) { if (getNameForNodeMap().getKey(node) != null) { return (String) getNameForNodeMap().getKey(node); } if (logger.isLoggable(Level.WARNING)) { logger.warning("Node " + node + " had no computed name meaning that it was probably not properly embedded in the FlexoProcess." + "I will compute its name now, but this can be source of instability in the names of the nodes. You should try to find why that node was not embedded."); } return computeAndStoreNameForNode(node); } private synchronized String computeAndStoreNameForNode(AbstractNode node) { String base = ToolBox.uncapitalize(node.getNiceName()); String attempt = base; if (nameForNodeMap.get(attempt) != null || ReservedKeyword.contains(attempt)) { String nodeType = node.getNodeTypeName(); if (base.toLowerCase().indexOf(nodeType.toLowerCase()) == -1) { base = base + nodeType; } base = ToolBox.uncapitalize(base); int i = 1; attempt = base; while (nameForNodeMap.get(attempt) != null || ReservedKeyword.contains(attempt)) { i++; attempt = base + String.valueOf(i); } } nameForNodeMap.put(attempt, node); return attempt; } private void buildNameForNodeMap() { Vector<AbstractNode> nodes = getActivityPetriGraph().getAllEmbeddedNodesOfClass(AbstractNode.class); nodes.addAll(getPortRegistery().getAllPorts()); Collections.sort(nodes, new Comparator<FlexoModelObject>() { @Override public int compare(FlexoModelObject o1, FlexoModelObject o2) { return o1.compareTo(o2); } }); for (FlexoProcess process : getWorkflow().getAllLocalFlexoProcesses()) { nameForNodeMap.put(ToolBox.uncapitalize(ToolBox.getJavaName(process.getName())), process); } for (FlexoProcess process : getWorkflow().getAllImportedFlexoProcesses()) { nameForNodeMap.put(ToolBox.uncapitalize(ToolBox.getJavaName(process.getName())), process); } if (getProcessDMEntity() != null) { for (DMObject obj : getProcessDMEntity().getOrderedChildren()) { nameForNodeMap.put(ToolBox.uncapitalize(ToolBox.getJavaName(obj.getName())), obj); } } for (AbstractNode node : nodes) { computeAndStoreNameForNode(node); } } // ============================================================ // ==================== Validation ============================ // ============================================================ public static class NonRootProcessShouldBeUsed extends ValidationRule<NonRootProcessShouldBeUsed, FlexoProcess> { public NonRootProcessShouldBeUsed() { super(FlexoProcess.class, "non_root_process_should_be_used"); } @Override public ValidationIssue<NonRootProcessShouldBeUsed, FlexoProcess> applyValidation(final FlexoProcess process) { if (!process.isRootProcess() && process.getSubProcessNodes().size() == 0 && (!process.isImported() || process.isTopLevelProcess())) { return new ValidationWarning<NonRootProcessShouldBeUsed, FlexoProcess>(this, process, "process_($object.name)_is_used_nowhere"); } return null; } } public static class FlexoProcessMustHaveADefaultStatus extends ValidationRule<FlexoProcessMustHaveADefaultStatus, FlexoProcess> { public FlexoProcessMustHaveADefaultStatus() { super(FlexoProcess.class, "process_must_have_a_default_status"); } @Override public ValidationIssue<FlexoProcessMustHaveADefaultStatus, FlexoProcess> applyValidation(FlexoProcess process) { if (process.getStatusList() != null && process.getStatusList().getDefaultStatus() == null) { Vector<FixProposal<FlexoProcessMustHaveADefaultStatus, FlexoProcess>> v = new Vector<FixProposal<FlexoProcessMustHaveADefaultStatus, FlexoProcess>>(); Enumeration<Status> en = process.getStatusList().getStatus().elements(); while (en.hasMoreElements()) { Status s = en.nextElement(); v.add(new SetDefaultStatus(s)); } v.add(new CreateAndSetDefaultStatus()); return new ValidationError<FlexoProcessMustHaveADefaultStatus, FlexoProcess>(this, process, "process_($object.name)_has_no_default_status", v); } return null; } protected static class CreateAndSetDefaultStatus extends FixProposal<FlexoProcessMustHaveADefaultStatus, FlexoProcess> { public CreateAndSetDefaultStatus() { super("create_and_set_default_status"); // TODO Auto-generated constructor stub } @Override protected void fixAction() { FlexoProcess p = getObject(); Status s = p.getStatusList().createNewStatus(); p.getStatusList().setDefaultStatus(s); } } protected static class SetDefaultStatus extends FixProposal<FlexoProcessMustHaveADefaultStatus, FlexoProcess> { private Status status; public SetDefaultStatus(Status status) { super("set_default_status_to_($status.name)"); this.status = status; } // Used by KVC for message public Status getStatus() { return status; } @Override protected void fixAction() { FlexoProcess p = getObject(); p.getStatusList().setDefaultStatus(status); } } } public static class ProcessHierarchyIsConsistent extends ValidationRule<ProcessHierarchyIsConsistent, FlexoProcess> { public ProcessHierarchyIsConsistent() { super(FlexoProcess.class, "process_hierarchy_must_be_consistent"); } @Override public ValidationIssue<ProcessHierarchyIsConsistent, FlexoProcess> applyValidation(final FlexoProcess process) { if (!process.isImported() && !process.isAcceptableAsParentProcess(process.getParentProcess())) { return new ValidationError<ProcessHierarchyIsConsistent, FlexoProcess>(this, process, "process_hierarchy_for_($object.name)_is_inconsistant"); } return null; } } public static class ImportedProcessShouldExistOnServer extends ValidationRule<ImportedProcessShouldExistOnServer, FlexoProcess> { public ImportedProcessShouldExistOnServer() { super(FlexoProcess.class, "imported_process_should_exist_on_server"); } @Override public ValidationIssue<ImportedProcessShouldExistOnServer, FlexoProcess> applyValidation(final FlexoProcess process) { if (process.isImported() && process.isDeletedOnServer()) { return new ValidationWarning<ImportedProcessShouldExistOnServer, FlexoProcess>(this, process, "process_($object.name)_no_longer_exists_on_server", new DeleteProcess()); } return null; } public static class DeleteProcess extends FixProposal<ImportedProcessShouldExistOnServer, FlexoProcess> { public DeleteProcess() { super("delete_process_($object.name)"); } @Override protected void fixAction() { getObject().delete(); } } } public static class ProcessMustDefineBusinessDataClass extends ValidationRule<ProcessMustDefineBusinessDataClass, FlexoProcess> { /** * @param objectType * @param ruleName */ public ProcessMustDefineBusinessDataClass() { super(FlexoProcess.class, "process_must_define_business_data_class"); } /** * Overrides applyValidation * * @see org.openflexo.foundation.validation.ValidationRule#applyValidation(org.openflexo.foundation.validation.Validable) */ @Override public ValidationIssue<ProcessMustDefineBusinessDataClass, FlexoProcess> applyValidation(FlexoProcess process) { if (process.getBusinessDataType() == null && !process.isRootProcess()) { return new ValidationError<ProcessMustDefineBusinessDataClass, FlexoProcess>(this, process, "process_must_define_a_business_data_type", new SetTypeProposal()); } if (!process.isRootProcess() && (process.getBusinessDataVariableName() == null || process.getBusinessDataVariableName().trim().length() == 0)) { return new ValidationError<ProcessMustDefineBusinessDataClass, FlexoProcess>(this, process, "process_must_define_a_business_data_variable", new SetVariableNameProposal()); } return null; } /** * Overrides isValidForTarget * * @see org.openflexo.foundation.validation.ValidationRule#isValidForTarget(TargetType) */ @Override public boolean isValidForTarget(TargetType targetType) { return targetType != CodeType.PROTOTYPE; } public static class SetTypeProposal extends ParameteredFixProposal<ProcessMustDefineBusinessDataClass, FlexoProcess> { private static final ParameterDefinition[] parameters = new ParameterDefinition[] { new DMEntityParameter("type", "type", null) }; /** * @param aMessage */ public SetTypeProposal() { super("set_type", parameters); } /** * Overrides fixAction * * @see org.openflexo.foundation.validation.FixProposal#fixAction() */ @Override protected void fixAction() { DMEntity e = (DMEntity) getValueForParameter("type"); if (e != null) { getObject().setBusinessDataType(e); } } } public static class SetVariableNameProposal extends ParameteredFixProposal<ProcessMustDefineBusinessDataClass, FlexoProcess> { private static final ParameterDefinition[] parameters = new ParameterDefinition[] { new TextFieldParameter("name", "name", null) }; /** * @param aMessage */ public SetVariableNameProposal() { super("set_variable", parameters); } /** * Overrides fixAction * * @see org.openflexo.foundation.validation.FixProposal#fixAction() */ @Override protected void fixAction() { String s = (String) getValueForParameter("name"); if (s != null && s.trim().length() == 0) { try { getObject().setBusinessDataVariableName(s); } catch (InvalidNameException e) { if (logger.isLoggable(Level.WARNING)) { logger.warning(e.getMessage()); } } catch (DuplicatePropertyNameException e) { if (logger.isLoggable(Level.WARNING)) { logger.warning(e.getMessage()); } } } } } } public static class BusinessDataClassMustHaveStatusProperty extends ValidationRule<BusinessDataClassMustHaveStatusProperty, FlexoProcess> { /** * @param objectType * @param ruleName */ public BusinessDataClassMustHaveStatusProperty() { super(FlexoProcess.class, "business_data_class_must_have_status_property"); } /** * Overrides applyValidation * * @see org.openflexo.foundation.validation.ValidationRule#applyValidation(org.openflexo.foundation.validation.Validable) */ @Override public ValidationIssue<BusinessDataClassMustHaveStatusProperty, FlexoProcess> applyValidation(FlexoProcess process) { if (process._processDMEntity != null) { if (process.getBusinessDataType().getProperty("status") == null) { return new ValidationError<BusinessDataClassMustHaveStatusProperty, FlexoProcess>(this, process, "business_data_class_must_have_status_property", process.getBusinessDataType().getIsReadOnly() ? null : new AddPropertyStatus(process.getBusinessDataType())); } } return null; } /** * Overrides isValidForTarget * * @see org.openflexo.foundation.validation.ValidationRule#isValidForTarget(TargetType) */ @Override public boolean isValidForTarget(TargetType targetType) { return targetType != CodeType.PROTOTYPE; } public static class AddPropertyStatus extends FixProposal<BusinessDataClassMustHaveStatusProperty, FlexoProcess> { private DMEntity _businessDataClass; /** * @param aMessage */ public AddPropertyStatus(DMEntity businessDataClass) { super("create_status_property"); _businessDataClass = businessDataClass; } /** * Overrides fixAction * * @see org.openflexo.foundation.validation.FixProposal#fixAction() */ @Override protected void fixAction() { if (_businessDataClass instanceof DMEOEntity) { DMEOAttribute statusAttribute; try { statusAttribute = DMEOAttribute.createsNewDMEOAttribute(_businessDataClass.getDMModel(), (DMEOEntity) _businessDataClass, "status", false, true, DMPropertyImplementationType.PUBLIC_ACCESSORS_PRIVATE_FIELD); statusAttribute.setPrototype(_businessDataClass.getDMModel().getPrototypeNamed("str100")); statusAttribute.setColumnName("PROCESS_STATUS"); ((DMEOEntity) _businessDataClass).registerProperty(statusAttribute); } catch (EOAccessException e) { // Ok this sucks. throw new RuntimeException(e); } } else { _businessDataClass.createDMProperty("status", DMType.makeResolvedDMType(String.class, getProject()), DMPropertyImplementationType.PUBLIC_ACCESSORS_ONLY); } } } } public void notifyOperationChange(OperationNode node) { setChanged(); notifyObservers(new OperationChange(node)); } /** * Overrides getClassNameKey * * @see org.openflexo.foundation.FlexoModelObject#getClassNameKey() */ @Override public String getClassNameKey() { return "flexo_process"; } /** * Wheter there is within all the operations of this process at least one operation associated to a component * * @return */ public boolean hasWOComponent() { for (AbstractActivityNode act : getAllEmbeddedAbstractActivityNodes()) { if (act.hasWOComponent()) { return true; } } return false; } public int getIndex() { if (getProcessNode() != null) { return getProcessNode().getIndex(); } logger.warning("Process node is null for flexo process " + this.getName()); return -1; } public void setIndex(int index) { if (getProcessNode() != null) { getProcessNode().setIndex(index); if (getIndex() != index) { setChanged(false); AttributeDataModification dm = new AttributeDataModification("index", null, getIndex()); dm.setReentrant(true); notifyObservers(dm); } } else { logger.warning("Process node is null for flexo process " + this.getName()); } } public int getVectorIndex() { if (getProcessNode() != null) { return getProcessNode().getVectorIndex(); } logger.warning("Process node is null for flexo process " + this.getName()); return -1; } public void setVectorIndex(int index) { if (getProcessNode() != null) { getProcessNode().setVectorIndex(index); if (getVectorIndex() != index) { setChanged(false); AttributeDataModification dm = new AttributeDataModification("vectorIndex", null, getIndex()); dm.setReentrant(true); notifyObservers(dm); } } else { logger.warning("Process node is null for flexo process " + this.getName()); } } /** * Returns a sorted vector of all the abstract activity nodes that are in the underlying activity petrigraph and the ones embedded by * LOOPOperator and SelfExecutableNode. This is done recursively on all nodes. * * @return a sorted vector of all the abstract activity nodes embedded in the petri graph. */ public Vector<AbstractActivityNode> getAllEmbeddedSortedAbstractActivityNodes() { if (_petriGraph != null) { return _petriGraph.getAllEmbeddedSortedAbstractActivityNodes(); } return new Vector<AbstractActivityNode>(); } public Enumeration<AbstractActivityNode> getSortedActivities() { disableObserving(); AbstractActivityNode[] o = FlexoIndexManager.sortArray(getAllAbstractActivityNodes().toArray(new AbstractActivityNode[0])); enableObserving(); return ToolBox.getEnumeration(o); } public Enumeration<AbstractActivityNode> getSortedMeaningFullActivities() { disableObserving(); AbstractActivityNode[] o = FlexoIndexManager.sortArray(getAllMeaningFullActivityNodes().toArray(new AbstractActivityNode[0])); enableObserving(); return ToolBox.getEnumeration(o); } public List<SubProcessNode> getSortedSubProcessNode() { disableObserving(); SubProcessNode[] o = FlexoIndexManager.sortArray(getAllMeaningSubProcessNodes().toArray(new SubProcessNode[0])); enableObserving(); return Arrays.asList(o); } public List<AbstractActivityNode> getSortedMeaningFullActivitiesAndSubProcessNode() { disableObserving(); AbstractActivityNode[] o = FlexoIndexManager.sortArray(getAllMeaningFullActivityNodes().toArray(new AbstractActivityNode[0])); enableObserving(); return Arrays.asList(o); } public Enumeration<PetriGraphNode> getSortedActivitiesAndOperators() { disableObserving(); PetriGraphNode[] o = FlexoIndexManager.sortArray(getAllAbstractActivityNodesAndActivityOperators().toArray(new PetriGraphNode[0])); enableObserving(); return ToolBox.getEnumeration(o); } public Enumeration<PetriGraphNode> getSortedActivitiesAndOperatorsWithEvents() { disableObserving(); PetriGraphNode[] o = FlexoIndexManager.sortArray(getAllAbstractActivityNodesAndActivityOperatorsWithEvents().toArray( new PetriGraphNode[0])); enableObserving(); return ToolBox.getEnumeration(o); } public Vector<Status> getSortedStatusesVector() { if (getStatusList() == null) { return new Vector<Status>(); } disableObserving(); Vector<Status> v = new Vector<Status>(getStatusList().getStatus()); Collections.sort(v, FlexoIndexManager.INDEX_COMPARATOR); enableObserving(); return v; } public boolean hasAtLeastOneStatusToDocument() { if (getStatusList() == null) { return false; } Enumeration<Status> en = getStatusList().elements(); while (en.hasMoreElements()) { if (!en.nextElement().getDontGenerate()) { return true; } } return false; } public boolean hasAtLeastOneEventToDocument() { Enumeration<EventNode> en = getAllEventNodes().elements(); while (en.hasMoreElements()) { if (!en.nextElement().getDontGenerate()) { return true; } } return false; } public ProcessStatistics getStatistics() { if (statistics == null) { statistics = new ProcessStatistics(this); } return statistics; } @Override public ApplicationHelpEntryPoint getParentHelpEntry() { return getParentProcess(); } @Override public List<ApplicationHelpEntryPoint> getChildsHelpObjects() { Vector<ApplicationHelpEntryPoint> reply = new Vector<ApplicationHelpEntryPoint>(); reply.addAll(getAllActivityNodes()); return reply; } @Override public String getShortHelpLabel() { return getName(); } @Override public String getTypedHelpLabel() { return "Process : " + getName(); } public void resolveObjectReferences() { for (ActionNode node : getAllEmbeddedActionNodes()) { node.getDisplayProcess(); node.getDisplayOperation(); } } public boolean oneAncestorIsNotGenerated() { if (getDontGenerate()) { return true; } if (getParentProcess() == null) { return getDontGenerate(); } return getParentProcess().oneAncestorIsNotGenerated(); } public String getProcessDictionaryKey() { return ToolBox.cleanStringForProcessDictionaryKey(getName()); } public String getBusinessDataDictionaryKey() { if (getBusinessDataType() != null) { return ToolBox.cleanStringForProcessDictionaryKey(getBusinessDataType().getName()); } return AutoGeneratedProcessBusinessDataDMEntity.getProcessBusinessDataEntityNameForProcess(this); } public static final String PROCESSINSTANCE_STATUS_KEY = ToolBox.cleanStringForProcessDictionaryKey("status"); public static final String PROCESSINSTANCE_CREATIONDATE_KEY = ToolBox.cleanStringForProcessDictionaryKey("creationDate"); public static final String PROCESSINSTANCE_LASTUPDATEDATE_KEY = ToolBox.cleanStringForProcessDictionaryKey("lastUpdateDate"); /** * Return a map containing the sample value list for each key used for this process (prototype). * * @return a map containing the sample value list for each key used for this process (prototype).. */ public Map<String, List<Object>> getProcessInstanceDictionaryPrototypeSamples() { Map<String, List<Object>> keysTable = new HashMap<String, List<Object>>(); for (IEWidget widget : getWidgetsForProcessInstanceDictionary()) { String key = widget.getProcessInstanceDictionaryKey(); List<Object> sampleValues = new ArrayList<Object>(); if (widget instanceof IEWidgetWithValueList) { sampleValues = ((IEWidgetWithValueList) widget).getValueList(this); } if (!keysTable.containsKey(key) || keysTable.get(key).size() < sampleValues.size()) { keysTable.put(widget.getProcessInstanceDictionaryKey(), sampleValues); } } if (getStatusList().size() > 0) { // Always add status list if any List<Object> statuses = new ArrayList<Object>(); keysTable.put(PROCESSINSTANCE_STATUS_KEY, statuses); for (Status status : getStatusList().getStatus()) { statuses.add(status.getName()); } } if (keysTable.get(PROCESSINSTANCE_CREATIONDATE_KEY) == null) { keysTable.put(PROCESSINSTANCE_CREATIONDATE_KEY, new ArrayList<Object>()); } if (keysTable.get(PROCESSINSTANCE_LASTUPDATEDATE_KEY) == null) { keysTable.put(PROCESSINSTANCE_LASTUPDATEDATE_KEY, new ArrayList<Object>()); } return keysTable; } /** * Return a map with all keys found for this process with their type. Keys are created based on the screen components. * * @return a map with all keys found for this process with their type. Keys are created based on the screen components. */ public Map<String, Class<? extends Object>> getProcessInstanceDictionaryKeys() { Map<String, Class<? extends Object>> result = new HashMap<String, Class<? extends Object>>(); for (IEWidget widget : getWidgetsForProcessInstanceDictionary()) { String key = widget.getProcessInstanceDictionaryKey(); if (key != null) { Class<? extends Object> type = getProcessInstanceDictionaryType(widget); if (result.containsKey(key) && result.get(key) != type) { type = Object.class; } result.put(key, type); } } if (getStatusList().size() > 0) { result.put(PROCESSINSTANCE_STATUS_KEY, String.class); } result.put(PROCESSINSTANCE_CREATIONDATE_KEY, Date.class); result.put(PROCESSINSTANCE_LASTUPDATEDATE_KEY, Date.class); return result; } private List<IEWidget> getWidgetsForProcessInstanceDictionary() { Map<FlexoProcess, Set<IEWOComponent>> componentsByProcess = new HashMap<FlexoProcess, Set<IEWOComponent>>(); for (OperationComponentInstance ci : getProject().getFlexoWorkflow().getAllComponentInstances()) { OperationNode operationNode = ci.getOperationNode(); if (operationNode != null && operationNode.hasWOComponent()) { if (componentsByProcess.get(operationNode.getProcess()) == null) { componentsByProcess.put(operationNode.getProcess(), new HashSet<IEWOComponent>()); } componentsByProcess.get(operationNode.getProcess()).add(operationNode.getWOComponent()); } } List<IEWidget> allWidgets = new ArrayList<IEWidget>(); for (Map.Entry<FlexoProcess, Set<IEWOComponent>> entry : componentsByProcess.entrySet()) { for (IEWOComponent woComponent : entry.getValue()) { allWidgets.addAll(getWidgetsForProcessInstanceFromComponent(woComponent, entry.getKey())); } } return allWidgets; } private List<IEWidget> getWidgetsForProcessInstanceFromComponent(IEWOComponent component, FlexoProcess componentProcess) { List<IEWidget> allWidgets = new ArrayList<IEWidget>(); for (IEWidget widget : component.getAllEmbeddedIEWidgets(IEWidget.class)) { if (widget.getIsAcceptableForProcessInstanceDictionary(componentProcess, this)) { allWidgets.add(widget); } if (widget instanceof IETabWidget) { allWidgets.addAll(getWidgetsForProcessInstanceFromComponent(((IETabWidget) widget).getTabComponent(), componentProcess)); } } return allWidgets; } /** * Return the type used in the process instance dictionary for the specified IEWidget. * * @param widget * @return the type used in the process instance dictionary for the specified IEWidget. */ public Class<? extends Object> getProcessInstanceDictionaryType(IEWidget widget) { if (widget instanceof IECheckBoxWidget) { return Boolean.class; } if (widget instanceof IEDropDownWidget) { return String.class; } if (widget instanceof IERadioButtonWidget) { return Boolean.class; } if (widget instanceof IETextAreaWidget) { return String.class; } if (widget instanceof IEWysiwygWidget) { return String.class; } TextFieldType fieldType = null; if (widget instanceof IEHyperlinkWidget) { fieldType = ((IEHyperlinkWidget) widget).getFieldType(); } else if (widget instanceof IEStringWidget) { fieldType = ((IEStringWidget) widget).getFieldType(); } else if (widget instanceof IETextFieldWidget) { fieldType = ((IETextFieldWidget) widget).getFieldType(); } if (fieldType == null) { return String.class; } switch (fieldType) { case DATE: return Date.class; case DOUBLE: return Double.class; case FLOAT: return Float.class; case INTEGER: return Integer.class; case KEYVALUE: case STATUS_LIST: case TEXT: default: return String.class; } } public boolean isRoleVisible(Role role) { for (FlexoModelObjectReference<Role> r : getVisibleRoles()) { if (r.getObject() == role) { return true; } } return false; } public void setRoleVisible(Role role, boolean visible) { if (role.isCache()) { role = role.getRole(true); if (role == null) { return; } } if (visible && !isRoleVisible(role)) { addToVisibleRoles(new FlexoModelObjectReference<Role>(role)); } else if (!visible) { boolean changed = false; Iterator<FlexoModelObjectReference<Role>> i = getVisibleRoles().iterator(); while (i.hasNext()) { FlexoModelObjectReference<org.openflexo.foundation.wkf.Role> ref = i.next(); if (ref.getObject() == role) { i.remove(); changed = true; } } if (changed) { setChanged(); notifyAttributeModification(VISIBLE_ROLES, role, null); } } } }