Java tutorial
/* * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * */ package org.apache.airavata.workflow.model.wf; import java.awt.image.BufferedImage; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import javax.imageio.ImageIO; import javax.xml.namespace.QName; import org.apache.airavata.common.exception.UtilsException; import org.apache.airavata.common.utils.StringUtil; import org.apache.airavata.common.utils.WSDLUtil; import org.apache.airavata.common.utils.XMLUtil; import org.apache.airavata.workflow.model.component.Component; import org.apache.airavata.workflow.model.component.ComponentException; import org.apache.airavata.workflow.model.component.ws.WSComponent; import org.apache.airavata.workflow.model.component.ws.WSComponentFactory; import org.apache.airavata.workflow.model.component.ws.WSComponentKey; import org.apache.airavata.workflow.model.component.ws.WSComponentPort; import org.apache.airavata.workflow.model.exceptions.WorkflowException; import org.apache.airavata.workflow.model.exceptions.WorkflowRuntimeException; import org.apache.airavata.workflow.model.gpel.script.BPELScript; import org.apache.airavata.workflow.model.gpel.script.BPELScriptType; import org.apache.airavata.workflow.model.graph.GraphException; import org.apache.airavata.workflow.model.graph.GraphSchema; import org.apache.airavata.workflow.model.graph.Node; import org.apache.airavata.workflow.model.graph.impl.NodeImpl; import org.apache.airavata.workflow.model.graph.system.InputNode; import org.apache.airavata.workflow.model.graph.util.GraphUtil; import org.apache.airavata.workflow.model.graph.ws.WSGraph; import org.apache.airavata.workflow.model.graph.ws.WSGraphFactory; import org.apache.airavata.workflow.model.graph.ws.WSNode; import org.apache.airavata.workflow.model.ode.ODEBPELTransformer; import org.apache.airavata.workflow.model.ode.ODEDeploymentDescriptor; import org.apache.airavata.workflow.model.ode.ODEWSDLTransformer; import org.apache.airavata.workflow.model.ode.WSDLCleaner; import org.apache.airavata.workflow.model.utils.ApplicationVersion; import org.apache.airavata.workflow.model.utils.WorkflowConstants; import org.apache.commons.codec.binary.Base64; import org.gpel.GpelConstants; import org.gpel.model.GpelProcess; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.xmlpull.infoset.XmlElement; import org.xmlpull.infoset.XmlInfosetBuilder; import org.xmlpull.infoset.XmlNamespace; import xsul5.XmlConstants; import xsul5.wsdl.WsdlDefinitions; public class Workflow implements Cloneable { /** * Namespace prefix */ public static final String NS_PREFIX_XWF = "xwf"; /** * Namespace URI */ public static final String NS_URI_XWF = WorkflowConstants.NS_URI_XBAYA + "xwf"; /** * Namespace */ public static final XmlNamespace NS_XWF = XMLUtil.BUILDER.newNamespace(NS_PREFIX_XWF, NS_URI_XWF); /** * WORKFLOW_TAG */ public static final String WORKFLOW_TAG = "workflow"; private static final String VERSION_ATTRIBUTE = "version"; private static final String WSDLS_TAG = "wsdls"; private static final String WSDL_TAG = "wsdl"; private static final String BPEL_TAG = "bpel"; private static final String WORKFLOW_WSDL_TAG = "workflowWSDL"; private static final String IMAGE_TAG = "image"; private static final String ID_ATTRIBUTE = "id"; private static final Logger logger = LoggerFactory.getLogger(Workflow.class); private WSGraph graph; private BufferedImage image; private URI gpelTemplateID; private URI gpelInstanceID; private GpelProcess gpelProcess; private WsdlDefinitions workflowWSDL; private WsdlDefinitions odeInvokableWSDL; private WsdlDefinitions odeWorkflowWSDL; private GpelProcess odeProcess; private Map<String, WsdlDefinitions> odeWsdlMap; private boolean editable = true; /** * used only during the parsing xwf or loading from GPEL. */ private Map<String, WsdlDefinitions> wsdlMap; private XmlElement odeDeploymentDiscriptor; private volatile WorkflowExecutionState executionState = WorkflowExecutionState.NONE; private WsdlDefinitions tridentWSDL; /** * Constructs a Workflow. */ public Workflow() { this.wsdlMap = new HashMap<String, WsdlDefinitions>(); // Create a empty graph here to avoid null checks. this.graph = WSGraphFactory.createGraph(); } /** * Constructs a Workflow. * * @param workflowString * Workflow XML in String. * @throws GraphException * @throws ComponentException */ public Workflow(String workflowString) throws GraphException, ComponentException { this(); try { XmlElement workflowElement = XMLUtil.stringToXmlElement(workflowString); parse(workflowElement); } catch (RuntimeException e) { throw new GraphException(e); } } /** * Constructs a workflow from a given URI. * @param workflowFilePath The workflow URI path. * @throws GraphException If an error occurred while creating workflow. * @throws ComponentException If an error occurred while parsing the workflow content. */ public Workflow(URI workflowFilePath) throws GraphException, ComponentException { this(); try { XmlElement workflowElement = XMLUtil.loadXML(workflowFilePath.toURL().openStream()); parse(workflowElement); } catch (RuntimeException e) { throw new GraphException(e); } catch (IOException e) { throw new GraphException(e); } } /** * Constructs a Workflow. * * @param workflowElement * @throws GraphException * @throws ComponentException */ public Workflow(XmlElement workflowElement) throws GraphException, ComponentException { this(); parse(workflowElement); } /** * This is used for ODE * * @return The Template ID like id */ public URI getUniqueWorkflowName() { try { return new URI(WorkflowConstants.LEAD_NS + "/" + this.getName()); } catch (URISyntaxException e) { throw new WorkflowRuntimeException(e); } } public URI getNameSpace() { try { return new URI(WorkflowConstants.LEAD_NS); } catch (URISyntaxException e) { throw new WorkflowRuntimeException(e); } } /** * Returns the gpelInstanceID. * * @return The gpelInstanceID */ public URI getGPELInstanceID() { return this.gpelInstanceID; } /** * Sets gpelInstanceID. * * @param gpelInstanceID * The gpelInstanceID to set. */ public void setGPELInstanceID(URI gpelInstanceID) { this.gpelInstanceID = gpelInstanceID; } /** * Returns the name. * * @return The name */ public String getName() { return this.graph.getName(); } /** * Sets name. * * @param name * The name to set. */ public void setName(String name) { this.graph.setName(name); } /** * Returns the description. * * @return The description */ public String getDescription() { return this.graph.getDescription(); } /** * Sets description. * * @param description * The description to set. */ public void setDescription(String description) { this.graph.setDescription(description); } /** * @return The metadata, appinfo. */ public XmlElement getMetadata() { return this.graph.getMetadata(); } /** * @param metadata */ public void setMetadata(XmlElement metadata) { this.graph.setMetadata(metadata); } /** * @return The output metadata, appinfo. */ public XmlElement getInputMetadata() { return this.graph.getInputMetadata(); } /** * @return The input metadata, appinfo. */ public XmlElement getOutputMetadata() { return this.graph.getOutputMetadata(); } /** * Returns the graph. * * @return The graph */ public WSGraph getGraph() { return this.graph; } /** * Sets graph. * * @param graph * The graph to set. */ public void setGraph(WSGraph graph) { this.graph = graph; } /** * Returns the image. * * @return The image */ public BufferedImage getImage() { return this.image; } /** * Sets image. * * @param image * The image to set. */ public void setImage(BufferedImage image) { this.image = image; } /** * Returns the gpelProcess. * * @return The gpelProcess */ public GpelProcess getGpelProcess() { return this.gpelProcess; } /** * Sets gpelProcess. * * @param gpelProcess * The gpelProcess to set. */ public void setGpelProcess(GpelProcess gpelProcess) { this.gpelProcess = gpelProcess; } /** * Returns the workflowWSDL. * * @return The workflowWSDL */ public WsdlDefinitions getWorkflowWSDL() { return this.workflowWSDL; } /** * Sets workflowWSDL. * * @param workflowWSDL * The workflowWSDL to set. */ public void setWorkflowWSDL(WsdlDefinitions workflowWSDL) { this.workflowWSDL = workflowWSDL; } /** * @return The set of WSDLs */ public Map<String, WsdlDefinitions> getWSDLs() { Map<String, WsdlDefinitions> wsdls = new LinkedHashMap<String, WsdlDefinitions>(); Map<WsdlDefinitions, String> ids = new HashMap<WsdlDefinitions, String>(); // Use LinkedHashMap to preserve the order of WSDLs, which is useful for // some unit tests. for (WSNode node : GraphUtil.getNodes(this.graph, WSNode.class)) { WsdlDefinitions wsdl = node.getComponent().getWSDL(); if (wsdls.containsValue(wsdl)) { String id = ids.get(wsdl); node.setWSDLID(id); } else { // Assign unique key String name = WSDLUtil.getWSDLName(wsdl); String id = StringUtil.convertToJavaIdentifier(name); while (wsdls.containsKey(id)) { id = StringUtil.incrementName(id); } wsdls.put(id, wsdl); ids.put(wsdl, id); node.setWSDLID(id); } } return wsdls; } /** * This method is called by GPELClient during loading a workflow. * * @param id * @param wsdl */ public void addWSDL(String id, WsdlDefinitions wsdl) { logger.debug("id: " + id); this.wsdlMap.put(id, wsdl); } /** * Creates a node from a specified component and adds it to the graph. * * @param component * The specified component * @return The node added */ public Node addNode(Component component) { Node node = component.createNode(this.graph); return node; } /** * Removes a specified node from the graph. * * @param node * The specified node * @throws GraphException */ public void removeNode(Node node) throws GraphException { this.graph.removeNode(node); } /** * Imports a specified workflow to the current workflow. * * @param workflow * The specified workflow to import * @throws GraphException */ public void importWorkflow(Workflow workflow) throws GraphException { this.graph.importGraph(workflow.getGraph()); } /** * Returns the inputs of the workflow. * * @return The inputs of the workflow. * @throws ComponentException */ public List<WSComponentPort> getInputs() throws ComponentException { if (this.workflowWSDL == null) { try { this.createScript(); } catch (GraphException e) { throw new IllegalStateException(e.getMessage()); } } WSComponent component = WSComponentFactory.createComponent(this.workflowWSDL); return component.getInputPorts(); } public List<WorkflowInput> getWorkflowInputs() throws Exception { List<InputNode> inputNodes = GraphUtil.getInputNodes(getGraph()); List<WorkflowInput> results = new ArrayList<WorkflowInput>(); for (InputNode port : inputNodes) { results.add(new WorkflowInput(port.getID(), port.getParameterType().getLocalPart(), port.getDefaultValue(), port.getDefaultValue(), !port.isVisibility())); } return results; } /** * Returns the outputs of the workflow. * * @return The outputs of the workflow. * @throws ComponentException */ public List<WSComponentPort> getOutputs() throws ComponentException { if (this.workflowWSDL == null) { throw new IllegalStateException(); } WSComponent component = WSComponentFactory.createComponent(this.workflowWSDL); return component.getOutputPorts(); } /** * Returns the XML Text of the workflow. * * @return The XML Text of the workflow */ @Deprecated public String toXMLText() { return XMLUtil.xmlElementToString(toXML()); } public void setGraphID(String id) { getGraph().setID(id); } /** * Returns the XmlElement of the workflow. * * @return The XmlElement of the workflow */ public XmlElement toXML() { // This must be before graph.toXML() to set WSDL ID to each node. Map<String, WsdlDefinitions> wsdls = getWSDLs(); XmlElement workflowElement = XMLUtil.BUILDER.newFragment(NS_XWF, WORKFLOW_TAG); // Version workflowElement.setAttributeValue(NS_XWF, VERSION_ATTRIBUTE, ApplicationVersion.VERSION.getVersion()); // Date // TODO add modification time // XmlElement modifiedTimeElement = graphElement.addElement( // XgraphSchema.NS, "modifiedTime"); // modifiedTimeElement.addChild(new GregorianCalendar().toString()); // Graph workflowElement.addElement(this.graph.toXML()); // WSDLs XmlElement wsdlsElement = workflowElement.addElement(NS_XWF, WSDLS_TAG); for (String id : wsdls.keySet()) { WsdlDefinitions wsdl = wsdls.get(id); XmlElement wsdlElement = wsdlsElement.addElement(NS_XWF, WSDL_TAG); wsdlElement.setAttributeValue(NS_XWF, ID_ATTRIBUTE, id); wsdlElement.setText(XMLUtil.xmlElementToString(wsdl.xml())); } // Image if (this.image != null) { try { ByteArrayOutputStream outStream = new ByteArrayOutputStream(); ImageIO.write(this.image, WorkflowConstants.PNG_FORMAT_NAME, outStream); byte[] bytes = outStream.toByteArray(); byte[] base64 = Base64.encodeBase64Chunked(bytes); XmlElement imageElement = workflowElement.addElement(NS_XWF, IMAGE_TAG); imageElement.setText(new String(base64)); } catch (IOException e) { // No image logger.error(e.getMessage(), e); } } // BPEL if (this.gpelProcess != null) { XmlElement bpelElement = workflowElement.addElement(NS_XWF, BPEL_TAG); bpelElement.setText(this.gpelProcess.xmlStringPretty()); } // Workflow WSDL if (this.workflowWSDL != null) { XmlElement workflowWSDLElement = workflowElement.addElement(NS_XWF, WORKFLOW_WSDL_TAG); workflowWSDLElement.setText(this.workflowWSDL.xmlStringPretty()); } return workflowElement; } /** * Binds WSNodes to components * * @throws ComponentException * @throws GraphException */ public void bindComponents() throws ComponentException, GraphException { // This map is to avoid creating multiple instances for the a component Map<WSComponentKey, WSComponent> components = new HashMap<WSComponentKey, WSComponent>(); for (WSNode node : GraphUtil.getWSNodes(this.graph)) { String id = node.getWSDLID(); logger.debug("id: " + id); WsdlDefinitions wsdl = this.wsdlMap.get(id); if (wsdl == null) { // XXX This happens while loading a workflow that is created by // the version 2.2.6_2 or below from GPEL. // Need to look for wsdl manually. // id should be look like // {http://www.extreme.indiana.edu/math/}Adder for (WsdlDefinitions w : this.wsdlMap.values()) { QName name = WSDLUtil.getWSDLQName(w); if (name.toString().equals(id)) { wsdl = w; break; } } } if (wsdl == null) { continue; } try { QName portType = node.getPortTypeQName(); if (portType == null) { // XXX This happens while parsing xwf created by the version // 2.2.6_1 or below. portType = WSDLUtil.getFirstPortTypeQName(wsdl); } String operation = node.getOperationName(); if (operation == null) { // XXX This happens while parsing xwf created by the version // 2.2.6_1 or below. operation = WSDLUtil.getFirstOperationName(wsdl, portType); } WSComponentKey key = new WSComponentKey(id, portType, operation); WSComponent component; if (components.containsKey(key)) { component = components.get(key); } else { component = WSComponentFactory.createComponent(wsdl, portType, operation); components.put(key, component); } node.setComponent(component); } catch (UtilsException e) { logger.error(e.getMessage(), e); } } this.graph.fixParameterNodes(); GraphUtil.propagateTypes(this.graph); } /** * @see java.lang.Object#clone() */ @Override public Workflow clone() { XmlElement originalXML = toXML(); try { XmlElement newXML = XMLUtil.deepClone(originalXML); Workflow newWorkflow = new Workflow(newXML); return newWorkflow; } catch (GraphException e) { // This should not happen. throw new WorkflowRuntimeException(e); } catch (WorkflowException e) { // This should not happen. throw new WorkflowRuntimeException(e); } catch (UtilsException e) { // This should not happen. throw new WorkflowRuntimeException(e); } } /** * @param graph * @return The workflow */ public static Workflow graphToWorkflow(WSGraph graph) { Workflow workflow = new Workflow(); workflow.setGraph(graph); workflow.setName(graph.getName()); workflow.setDescription(graph.getDescription()); return workflow; } /** * @param workflowElement * @throws GraphException * @throws ComponentException */ private void parse(XmlElement workflowElement) throws GraphException, ComponentException { // Graph XmlElement graphElement = workflowElement.element(GraphSchema.GRAPH_TAG); this.graph = WSGraphFactory.createGraph(graphElement); WsdlDefinitions wsdl = null; XmlElement wsdlsElement = workflowElement.element(WSDLS_TAG); for (XmlElement wsdlElement : wsdlsElement.elements(null, WSDL_TAG)) { String wsdlText = wsdlElement.requiredText(); try { wsdl = WSDLUtil.stringToWSDL(wsdlText); } catch (UtilsException e) { logger.error(e.getMessage(), e); } String id = wsdlElement.attributeValue(NS_XWF, ID_ATTRIBUTE); if (id == null || id.length() == 0) { // xwf up to 2.2.6_2 doesn't have ID. id = WSDLUtil.getWSDLQName(wsdl).toString(); } addWSDL(id, wsdl); } bindComponents(); // Image XmlElement imageElement = workflowElement.element(IMAGE_TAG); if (imageElement != null) { String base64 = imageElement.requiredText(); byte[] bytes = Base64.decodeBase64(base64.getBytes()); try { this.image = ImageIO.read(new ByteArrayInputStream(bytes)); } catch (IOException e) { // This should not happen and it's OK that image is broken. We // can reproduce it anytime. logger.error(e.getMessage(), e); } } XmlElement bpelElement = workflowElement.element(BPEL_TAG); if (bpelElement != null) { try { String bpelString = bpelElement.requiredText(); XmlNamespace gpelNS = XmlInfosetBuilder.newInstance().newNamespace(BPELScript.GPEL, BPELScript.GPELNS); GpelConstants.GPEL_NS = gpelNS; this.gpelProcess = new GpelProcess(XMLUtil.stringToXmlElement(bpelString)); } catch (RuntimeException e) { String error = "Failed to parse the BPEL document."; throw new GraphException(error, e); } } XmlElement workflowWSDLElement = workflowElement.element(WORKFLOW_WSDL_TAG); if (workflowWSDLElement != null) { try { String wsdlText = workflowWSDLElement.requiredText(); this.workflowWSDL = new WsdlDefinitions(XMLUtil.stringToXmlElement(wsdlText)); } catch (RuntimeException e) { String error = "Failed to parse the workflow WSDL."; throw new GraphException(error, e); } } } public XmlElement getODEDeploymentDescriptor(URI dscUrl, String odeEprEndingWithPort) throws GraphException, ComponentException { if (this.odeDeploymentDiscriptor == null) { this.odeDeploymentDiscriptor = new ODEDeploymentDescriptor().generate(this.getName(), getOdeWorkflowWSDL(dscUrl, odeEprEndingWithPort), getOdeProcess(dscUrl, odeEprEndingWithPort), getOdeServiceWSDLs(dscUrl, odeEprEndingWithPort)); } return this.odeDeploymentDiscriptor; } /** * Returns the odeWorkflowWSDL. * * @return The odeWorkflowWSDL * @throws GraphException * @throws ComponentException */ public WsdlDefinitions getOdeInvokableWSDL(URI dscUrl, String odeEprEndingWithPort) throws GraphException, ComponentException { if (this.odeInvokableWSDL == null) { generateODEScripts(dscUrl, odeEprEndingWithPort); } return this.odeInvokableWSDL; } /** * Returns the odeProcess. * * @return The odeProcess * @throws ComponentException * @throws GraphException */ public GpelProcess getOdeProcess(URI dscUrl, String odeEprEndingWithPort) throws GraphException, ComponentException { if (this.odeProcess == null) { generateODEScripts(dscUrl, odeEprEndingWithPort); } return this.odeProcess; } /** * Returns the odeWsdlMap. * * @return The odeWsdlMap * @throws ComponentException * @throws GraphException */ public Map<String, WsdlDefinitions> getOdeServiceWSDLs(URI dscUrl, String odeEprEndingWithPort) throws GraphException, ComponentException { if (this.odeWsdlMap == null) { generateODEScripts(dscUrl, odeEprEndingWithPort); } return this.odeWsdlMap; } /** * Returns the odeWorkflowWSDL. * * @return The odeWorkflowWSDL * @throws ComponentException * @throws GraphException */ public WsdlDefinitions getOdeWorkflowWSDL(URI dscUrl, String odeEprEndingWithPort) throws GraphException, ComponentException { if (this.odeWorkflowWSDL == null) { generateODEScripts(dscUrl, odeEprEndingWithPort); } return this.odeWorkflowWSDL; } public WsdlDefinitions getTridentWorkflowWSDL(URI dscUrl, String odeEprEndingWithPort) throws GraphException, ComponentException { if (this.tridentWSDL == null) { generateODEScripts(dscUrl, odeEprEndingWithPort); } return this.tridentWSDL; } private void generateODEScripts(URI dscUrl, String odeEprEndingWithPort) throws GraphException, ComponentException { this.getGraph().setID(this.getName()); BPELScript script = null; script = new BPELScript(this); ODEWSDLTransformer wsdlTransformer = new ODEWSDLTransformer(); script.create(BPELScriptType.BPEL2); this.odeProcess = script.getGpelProcess(); this.odeProcess.setTargetNamespace(WorkflowConstants.LEAD_NS); WsdlDefinitions abstractWorkflowWsdl = script.getWorkflowWSDL().getWsdlDefinitions(); this.odeWorkflowWSDL = abstractWorkflowWsdl; try { this.odeInvokableWSDL = WSDLUtil.stringToWSDL(abstractWorkflowWsdl.xmlString()); wsdlTransformer.makeWorkflowWSDLConcrete(this.odeInvokableWSDL, this.getName(), dscUrl); wsdlTransformer.setOdeLocation(odeEprEndingWithPort, this.getName(), this.odeInvokableWSDL); this.odeWsdlMap = new HashMap<String, WsdlDefinitions>(); Collection<XmlElement> itr = script.getWSDLs(); for (XmlElement xmlElement : itr) { WsdlDefinitions wsdl = WSDLUtil.stringToWSDL(XmlConstants.BUILDER.serializeToString(xmlElement)); String id = xmlElement.attributeValue(NS_XWF, ID_ATTRIBUTE); if (id == null || id.length() == 0) { // xwf up to 2.2.6_2 doesn't have ID. id = WSDLUtil.getWSDLQName(wsdl).toString(); if (null == id || "".equals(id) || (id.startsWith("{") && id.endsWith("}"))) { QName wsdlQname = new QName(NS_XWF.getName(), WSDLUtil.getFirstOperationName(wsdl, WSDLUtil.getFirstPortTypeQName(wsdl))); id = wsdlQname.toString(); wsdl.xml().setAttributeValue("name", wsdlQname.getLocalPart()); } } WSDLCleaner.cleanWSDL(wsdl); this.odeWsdlMap.put(id, wsdl); } } catch (Exception e) { logger.error(e.getMessage(), e); } new ODEBPELTransformer().generateODEBPEL(this.odeProcess, this.getName(), this.odeWorkflowWSDL, this.odeWsdlMap); wsdlTransformer.trasnformToODEWsdls(this.getName(), dscUrl, this.odeWorkflowWSDL, this.odeWsdlMap); String wsdlString = XMLUtil.xmlElementToString(this.odeWorkflowWSDL.xml()); this.tridentWSDL = new WsdlDefinitions(XMLUtil.stringToXmlElement(wsdlString)); new TridentTransformer().process(this.tridentWSDL); } /** * @return */ public QName getQname() { return new QName(WorkflowConstants.LEAD_NS, this.getName()); } /** * @param templateID */ public void setGPELTemplateID(URI templateID) { this.gpelTemplateID = templateID; } /** * @return */ public URI getGPELTemplateID() { return this.gpelTemplateID; } public boolean equals(Workflow workflow) { return this.graph.equals(workflow.getGraph()); } private Object executionStateLock = new Object(); /** * @return */ public synchronized WorkflowExecutionState getExecutionState() { WorkflowExecutionState result; synchronized (executionStateLock) { result = this.executionState; } return result; } /** * @param state */ public synchronized void setExecutionState(WorkflowExecutionState state) { synchronized (executionStateLock) { this.executionState = state; } } public boolean isEditable() { return editable; } public void setEditable(boolean editable) { this.editable = editable; getGraph().setEditable(isEditable()); } public void createScript() throws GraphException { // Generate a BPEL process. BPELScript script = new BPELScript(this); script.create(BPELScriptType.GPEL); this.setGpelProcess(script.getGpelProcess()); this.setWorkflowWSDL(script.getWorkflowWSDL().getWsdlDefinitions()); } public List<String> getWorkflowServiceNodeIDs() { List<NodeImpl> nodes = getGraph().getNodes(); ArrayList<String> nodeIDs = new ArrayList<String>(); for (Node node : nodes) { if (node instanceof WSNode) { nodeIDs.add(node.getID()); } } return nodeIDs; } }