diff options
author | lresende <lresende@13f79535-47bb-0310-9956-ffa450edef68> | 2010-10-04 14:45:31 +0000 |
---|---|---|
committer | lresende <lresende@13f79535-47bb-0310-9956-ffa450edef68> | 2010-10-04 14:45:31 +0000 |
commit | fdeb31bbf8fe1d887ab47e6204952b8e118ab1ef (patch) | |
tree | e70013b67c533219aa45b2ff0a0d2bf64e24b7e7 /sca-java-2.x/tags/2.0-M5.1-RC1/modules/implementation-bpel-runtime/src/main/java/org/apache/tuscany/sca/implementation/bpel/ode/TuscanyProcessConfImpl.java | |
parent | 56f0d297c6eba38d5187431ed9319a97ff5d6094 (diff) |
Renaming 2.0-M5.1 releasi cadidate release tag
git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@1004266 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'sca-java-2.x/tags/2.0-M5.1-RC1/modules/implementation-bpel-runtime/src/main/java/org/apache/tuscany/sca/implementation/bpel/ode/TuscanyProcessConfImpl.java')
-rw-r--r-- | sca-java-2.x/tags/2.0-M5.1-RC1/modules/implementation-bpel-runtime/src/main/java/org/apache/tuscany/sca/implementation/bpel/ode/TuscanyProcessConfImpl.java | 823 |
1 files changed, 823 insertions, 0 deletions
diff --git a/sca-java-2.x/tags/2.0-M5.1-RC1/modules/implementation-bpel-runtime/src/main/java/org/apache/tuscany/sca/implementation/bpel/ode/TuscanyProcessConfImpl.java b/sca-java-2.x/tags/2.0-M5.1-RC1/modules/implementation-bpel-runtime/src/main/java/org/apache/tuscany/sca/implementation/bpel/ode/TuscanyProcessConfImpl.java new file mode 100644 index 0000000000..2c904a37f8 --- /dev/null +++ b/sca-java-2.x/tags/2.0-M5.1-RC1/modules/implementation-bpel-runtime/src/main/java/org/apache/tuscany/sca/implementation/bpel/ode/TuscanyProcessConfImpl.java @@ -0,0 +1,823 @@ +/* + * 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.tuscany.sca.implementation.bpel.ode; + + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.URI; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.Date; +import java.util.EnumSet; +import java.util.HashMap; +import java.util.Hashtable; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import javax.wsdl.Definition; +import javax.xml.namespace.QName; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.transform.Result; +import javax.xml.transform.Source; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerConfigurationException; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.ode.bpel.compiler.BpelC; +import org.apache.ode.bpel.evt.BpelEvent.TYPE; +import org.apache.ode.bpel.iapi.Endpoint; +import org.apache.ode.bpel.iapi.EndpointReference; +import org.apache.ode.bpel.iapi.ProcessConf; +import org.apache.ode.bpel.iapi.ProcessState; +import org.apache.tuscany.sca.assembly.Base; +import org.apache.tuscany.sca.assembly.ComponentProperty; +import org.apache.tuscany.sca.assembly.ComponentReference; +import org.apache.tuscany.sca.assembly.ComponentService; +import org.apache.tuscany.sca.assembly.Reference; +import org.apache.tuscany.sca.databinding.SimpleTypeMapper; +import org.apache.tuscany.sca.databinding.impl.SimpleTypeMapperImpl; +import org.apache.tuscany.sca.implementation.bpel.BPELImplementation; +import org.apache.tuscany.sca.interfacedef.wsdl.WSDLInterface; +import org.apache.tuscany.sca.runtime.RuntimeComponent; +import org.w3c.dom.Attr; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +/** + * A Tuscany implementation of the ODE Process Conf + * + * @version $Rev$ $Date$ + */ +public class TuscanyProcessConfImpl implements ProcessConf { + private final Log __log = LogFactory.getLog(getClass()); + + private BPELImplementation implementation; + private RuntimeComponent component; + private Map<String, Endpoint> invokeEndpoints = null; + private Map<String, Endpoint> provideEndpoints = null; + private Map<QName, Node> properties = null; + private ProcessState processState; + private Date deployDate; + + private File theBPELFile; + // Marks whether the BPEL file was rewritten (eg for initializer statements) + private boolean rewritten = false; + + private final SimpleTypeMapper mapper = new SimpleTypeMapperImpl(); + private final String TUSCANY_NAMESPACE = Base.SCA11_TUSCANY_NS; + + /** + * Constructor for the ProcessConf implementation + * @param theImplementation the BPEL implementation for which this is the ProcessConf + * @param component - the SCA component which uses the implementation + */ + public TuscanyProcessConfImpl( BPELImplementation theImplementation, RuntimeComponent component ) { + //System.out.println("New TuscanyProcessConfImpl..."); + this.implementation = theImplementation; + this.component = component; + + processState = ProcessState.ACTIVE; + deployDate = new Date(); + + // Compile the process + compile( getBPELFile() ); + } // end TuscanyProcessConfImpl constructor + + public void stop() { + // If the BPEL file was rewritten, destroy the rewritten version of it so that + // it is not used again. Also delete the related compiled cbp file + if( rewritten ) { + try { + String cbpName = theBPELFile.getCanonicalPath(); + // Remove the "bpel_tmp" suffix and add "cbp" + if ( cbpName.endsWith("bpel_tmp") ) { + cbpName = cbpName.substring( 0, cbpName.length() - 8) + "cbp"; + File cbpFile = new File( cbpName ); + if ( cbpFile.exists() ) cbpFile.delete(); + } // end if + } catch (Exception e ) { + // Do nothing with an exception + } // end try + theBPELFile.delete(); + } // end if + + } // end method stop + + /** + * Returns the URI for the directory containing the BPEL process + */ + public URI getBaseURI() { + //System.out.println("getBaseURI called"); + File theDir = getDirectory(); + return theDir.toURI(); + } + + /** + * Returns a String containing the (local) name of the file containing the BPEL process + */ + public String getBpelDocument() { + //System.out.println("getBPELDocument called"); + try { + String location = this.implementation.getProcessDefinition().getLocation(); + URI locationURI = new URI(null, location, null); + File processFile = new File(locationURI); + return getRelativePath( getDirectory(), processFile); + } catch (Exception e) { + if(__log.isWarnEnabled()) { + __log.warn("Unable to resolve relative path of BPEL process" + implementation.getProcessDefinition().getLocation(), e ); + } + return null; + } // end try + } // end getBpelDocument + + /** + * Returns an InputStream containing the Compiled BPEL Process (CBP) + */ + public InputStream getCBPInputStream() { + //System.out.println("getCBPInputStream called"); + + File cbpFile = getCBPFile(); + if( cbpFile == null ) return null; + + if( cbpFile.exists() ) { + // Create an InputStream from the cbp file... + try { + return new FileInputStream( cbpFile ); + } catch ( Exception e ) { + if(__log.isDebugEnabled()) { + __log.debug("Unable to open the cbp file for BPEL process: " + + implementation.getProcessDefinition().getName(), e); + } + } // end try + } else { + // Cannot find the cbp file + if(__log.isWarnEnabled()){ + __log.warn("Cannot find the cbp file for process: " + + implementation.getProcessDefinition().getName()); + } + } // end if + // TODO - need better exception handling if we can't open the cbp file for any reason + return null; + } // end getCBPInputStream + + /** + * Gets the File object for the CBP file for this BPEL Process + * @return - the File object for the CBP file + */ + private File getCBPFile() { + // Find the CBP file - it has the same name as the BPEL process and lives in the same + // directory as the process file + String cbpFileName = null; + try { + String fileName = getRelativePath( getDirectory(), getBPELFile() ); + cbpFileName = fileName.substring(0, fileName.lastIndexOf(".")) + ".cbp"; + } catch (Exception e ) { + // IOException trying to fetch the BPEL file name + if(__log.isDebugEnabled()) { + __log.debug("Unable to calculate the file name for BPEL process: " + + implementation.getProcessDefinition().getName(), e); + return null; + } // end if + } // end try + File cbpFile = new File( getDirectory(), cbpFileName ); + return cbpFile; + } // end getCBPFile + + /** + * Return the WSDL Definition for a given PortType + * @param portTypeName - the QName of the PortType + */ + public Definition getDefinitionForPortType( QName portTypeName ) { + //System.out.println("getDefinitionForPortType called for portType: " + portTypeName ); + // Find the named PortType in the list of WSDL interfaces associated with this BPEL Process + Collection<WSDLInterface> theInterfaces = implementation.getProcessDefinition().getInterfaces(); + for( WSDLInterface wsdlInterface : theInterfaces ) { + if ( wsdlInterface.getPortType().getQName().equals( portTypeName ) ) { + // Extract and return the Definition associated with the WSDLDefinition... + return wsdlInterface.getWsdlDefinition().getDefinition(); + } // end if + } // end for + return null; + } // end getDefinitionforPortType + + /** + * Returns a WSDL Definition for a given Service QName + * + * 22/05/2008 - it is very unclear what this service QName is really meant to be. + * From the handling of the deploy.xml file by the current ODE code, it seems that the key link + * is from the Service QName to the PartnerLink name (done in the deploy.xml file). + * + * The curious part about this is that the QName for the service is ONLY defined in deploy.xml file + * and does not appear to relate to anything else, except for the QName of the PartnerLink + * + * The PartnerLink name is the same as the name of the SCA service (or reference) which in turn points + * at the PartnerLinkType which in turn points at an (WSDL) interface definition. + */ + public Definition getDefinitionForService(QName serviceQName ) { + //System.out.println("getDefinitionForService called for Service: " + serviceQName ); + if(__log.isDebugEnabled()){ + __log.debug("getDefinitionforService called for service: " + serviceQName ); + } + // TODO Auto-generated method stub + return null; + } + + /** + * Returns the date of deployment of the process + * - for SCA returns the date at which this object was created + */ + public Date getDeployDate() { + //System.out.println("getDeployDate called"); + return deployDate; + } + + /** + * Returns userid of deployer + * - always "SCA Tuscany" for Tuscany... + */ + public String getDeployer() { + //System.out.println("getDeployer called"); + return "SCA Tuscany"; + } // end getDeployer + + /** + * Returns a list of the files in the directory containing the BPEL Process + */ + public List<File> getFiles() { + //System.out.println("getFiles called"); + File theDir = getDirectory(); + List<File> theFiles = Arrays.asList( (File[]) theDir.listFiles() ); + // TODO recurse into subdirectories + return theFiles; + } // end getFiles + + /** + * Returns a Map containing all the "invoke endpoints" - for which read "SCA references" + * The map is keyed by partnerLink name and holds Endpoint objects + * 0..1 multiplicity references are not included in the returned Map (it is as if the reference is not there...) + * TODO deal with multiplicity 0..n and 1..n + * TODO deal with service callbacks on bidirectional services + */ + public Map<String, Endpoint> getInvokeEndpoints() { + if( invokeEndpoints == null ) { + invokeEndpoints = new HashMap<String, Endpoint>(); + // Get a collection of the component references - note that this includes "pseudo-references" for any + // services that have a callback interface + List<ComponentReference> theReferences = component.getReferences(); + //List<Reference> theReferences = implementation.getReferences(); + // Create an endpoint for each reference, using the reference name combined with + // http://tuscany.apache.org to make a QName + // Note that the key used for this put operation MUST be the name of one of the partnerLinks of the + // BPEL process. The SCA reference MAY have an alias for the name (can be given using the sca-bpel:reference + // element, if present) and this alias must not be used + for( Reference reference : theReferences ) { + String partnerlinkName = implementation.getReferencePartnerlinkName( reference.getName() ); + // Check that there is at least 1 configured SCA endpointReference for the reference, since it is + // possible for 0..1 multiplicity references to have no SCA endpointReferences configured + List<org.apache.tuscany.sca.assembly.EndpointReference> eprs = reference.getEndpointReferences(); + String eprCount = Integer.toString( eprs.size() ); + invokeEndpoints.put( partnerlinkName, + new Endpoint( new QName( TUSCANY_NAMESPACE, reference.getName() ), eprCount)); + } // end for + } // end if + return invokeEndpoints; + } // end getInvokeEndpoints + + /** + * Returns the name of the directory containing the BPEL files + */ + public String getPackage() { + //System.out.println("getPackage called"); + File theDir = getDirectory(); + return theDir.getName(); + } // end getPackage + + /** + * Return the BPEL Process ID - which is the Process QName appended "-versionnumber" + */ + public QName getProcessId() { + //System.out.println("getProcessId called"); + QName processType = getType(); + QName processID = new QName( processType.getNamespaceURI(), + processType.getLocalPart() + "-" + getVersion() ); + return processID; + } // end getProcessID + + /** + * TODO - What are properties? + */ + public Map<QName, Node> getProperties() { + //System.out.println("getProperties called"); + if ( properties == null ) { + properties = new HashMap<QName, Node>(); + } // end if + return properties; + } // end getProperties + + /** + * Returns a Map containing all the "provide endpoints" - for which read "SCA services" + * The map is keyed by partnerLink name and holds Endpoint objects + * + * TODO deal with reference callbacks on bidirectional references + */ + public Map<String, Endpoint> getProvideEndpoints() { + //System.out.println("getProvideEndpoints called"); + if( provideEndpoints == null ) { + provideEndpoints = new HashMap<String, Endpoint>(); + String componentURI = component.getURI(); + // Get a collection of the services - note that the Component services include additional + // "pseudo-services" for each reference that has a callback... + + List<ComponentService> theServices = component.getServices(); + // Create an endpoint for each service, using the service name combined with + // http://tuscany.apache.org to make a QName + // Note that the key used for this put operation MUST be the name of one of the partnerLinks of the + // BPEL process. The SCA service MAY have an alias for the name (can be given using the sca-bpel:service + // element, if present) and this alias must not be used + for( ComponentService service : theServices ) { + String partnerlinkName = implementation.getServicePartnerlinkName( service.getName() ); + // MJE 14/07/2009 - added componentURI to the service name to get unique service name + provideEndpoints.put( partnerlinkName, + new Endpoint( new QName( TUSCANY_NAMESPACE, componentURI + service.getName() ), + "ServicePort")); + } // end for + } // end if + return provideEndpoints; + } // end getProvideEndpoints + + /** + * Return the process state + */ + public ProcessState getState() { + //System.out.println("getState called"); + return processState; + } + + /** + * Returns the QName of the BPEL process + */ + public QName getType() { + //System.out.println("getType called"); + return implementation.getProcess(); + } + + /** + * Gets the process Version number + * - current code does not have versions for BPEL processes and always returns "1" + */ + public long getVersion() { + //System.out.println("getVersion called"); + return 1; + } + + /** + * Returns true if the supplied event type is enabled for any of the scopes in the provided + * List. These events are "ODE Execution Events" and there is a definition of them on this + * page: http://ode.apache.org/user-guide.html#UserGuide-ProcessDeployment + * + * Tuscany currently uses: + * - instanceLifecycle events in order to establish the relationship of MessageExchange objects + * to the BPEL Process instances + * @param scopeNames - list of BPEL process Scope names + * @param type - the event type + */ + public boolean isEventEnabled(List<String> scopeNames, TYPE type) { + if( type == TYPE.dataHandling ) return false; + if( type == TYPE.activityLifecycle ) return false; + if( type == TYPE.scopeHandling ) return true; + if( type == TYPE.instanceLifecycle ) return true; + if( type == TYPE.correlation ) return true; + return false; + } // end isEventEnabled + + /** + * Returns whether the process is persisted in the store + * + * Returns false for SCA configuration + * - returning true causes problems in communicating with the BPEL process + */ + public boolean isTransient() { + return false; + } // end isTransient + + /** + * Compiles a BPEL process file into a compiled form CBP file in the main directory + * (ie same directory as the BPEL process file) + * @param bpelFile - the BPEL process file + */ + private void compile( File bpelFile ) { + // Set up the compiler + BpelC compiler = BpelC.newBpelCompiler(); + // Provide a null set of initial properties for now + Map<QName, Node> processProps = new HashMap<QName, Node>(); + Map<String, Object> compileProps = new HashMap<String, Object>(); + compileProps.put( BpelC.PROCESS_CUSTOM_PROPERTIES, processProps ); + compiler.setCompileProperties( compileProps ); + compiler.setBaseDirectory( getDirectory() ); + + // Inject any property values + bpelFile = injectPropertyValues( bpelFile ); + + // Run the compiler and generate the CBP file into the given directory + try { + compiler.compile( bpelFile ); + } catch (IOException e) { + if(__log.isDebugEnabled()) { + __log.debug("Compile error in " + bpelFile, e); + } + // TODO - need better exception handling here + } // end try + } // end compile + + /** + * Adds the values for SCA declared properties to the BPEL process. + * The values for the properties are held in the SCA RuntimeComponent supplied to this + * TuscanyProcessConfImpl. + * The properties map to <variable/> declarations in the BPEL process that are specifically + * marked with @sca-bpel:property="yes" + * @param bpelFile the file containing the BPEL process + * @return the (updated) file containing the BPEL process + */ + private File injectPropertyValues( File bpelFile ) { + // Get the properties + List<ComponentProperty> properties = component.getProperties(); + + // If there are no properties, we're done! + if( properties.size() == 0 ) return bpelFile; + + Document bpelDOM = readDOMFromProcess( bpelFile ); + + for( ComponentProperty property : properties ) { + //System.out.println("BPEL: Property - name = " + property.getName() ); + insertSCAPropertyInitializer( bpelDOM, property ); + } // end for + + File bpelFile2 = writeProcessFromDOM( bpelDOM, + getTransformedBPELFile( bpelFile) ); + if( bpelFile2 != null ) { + theBPELFile = bpelFile2; + rewritten = true; + return bpelFile2; + } // end if + + return bpelFile; + } // end injectPropertyValues + + /** + * Insert an initializer which supplies the value of an SCA property as specified by the + * SCA Component using the BPEL process + * @param bpelDOM - a DOM model representation of the BPEL process + * @param property - an SCA ComponentProperty element for the property + * This DOM model is updated, with an initializer being added for the BPEL variable + * corresponding to the SCA property + */ + private void insertSCAPropertyInitializer( Document bpelDOM, ComponentProperty property ) { + // Only insert a Property initializer where there is a value for the Property + if( property.getValue() == null ) return; + + Element insertionElement = findInitializerInsertionPoint( bpelDOM ); + if( insertionElement == null ) return; + + Element initializer = getInitializerSequence( bpelDOM, property ); + if( initializer == null ) return; + + // Insert the initializer sequence as the next sibling element of the insertion point + Element parent = (Element)insertionElement.getParentNode(); + // Get the next sibling element, if there is one + Node sibling = insertionElement.getNextSibling(); + while( sibling != null && sibling.getNodeType() != Node.ELEMENT_NODE ) { + sibling = sibling.getNextSibling(); + } // end while + // Either insert at the end or before the next element + if ( sibling == null ) { + parent.appendChild( initializer ); + } else { + parent.insertBefore( initializer, sibling ); + } // end if + + } // end insertSCAPropertyInitializer + + /** + * Gets the variable initializer DOM sequence for a given property, in the context of a supplied + * DOM model of the BPEL process + * @param bpelDOM - DOM representation of the BPEL process + * @param property - SCA Property which relates to one of the variables in the BPEL process + * @return - a DOM model representation of the XML statements required to initialize the + * BPEL variable with the value of the SCA property. + */ + private Element getInitializerSequence( Document bpelDOM, ComponentProperty property ) { + // For an XML simple type (string, int, etc), the BPEL initializer sequence is: + // <assign><copy><from><literal>value</literal></from><to variable="variableName"/></copy></assign> + QName type = property.getXSDType(); + if( type != null ) { + if( mapper.isSimpleXSDType( type ) ) { + // Simple types + String NS_URI = bpelDOM.getDocumentElement().getNamespaceURI(); + String valueText = getPropertyValueText( property.getValue() ); + Element literalElement = bpelDOM.createElementNS(NS_URI, "literal"); + literalElement.setTextContent(valueText); + Element fromElement = bpelDOM.createElementNS(NS_URI, "from"); + fromElement.appendChild(literalElement); + Element toElement = bpelDOM.createElementNS(NS_URI, "to"); + Attr variableAttribute = bpelDOM.createAttribute("variable"); + variableAttribute.setValue( property.getName() ); + toElement.setAttributeNode( variableAttribute ); + Element copyElement = bpelDOM.createElementNS(NS_URI, "copy"); + copyElement.appendChild(fromElement); + copyElement.appendChild(toElement); + Element assignElement = bpelDOM.createElementNS(NS_URI, "assign"); + assignElement.appendChild(copyElement); + return assignElement; + } // end if + // TODO Deal with Properties which have a non-simple type + } else { + // TODO Deal with Properties which have an element as the type + } // end if + + return null; + } // end method getInitializerSequence + + /** + * Gets the text value of a property that is a simple type + * @param propValue - the SCA Property value + * @return - the text content of the Property value, as a String + */ + private String getPropertyValueText( Object propValue ) { + String text = null; + if( propValue instanceof Document ) { + Element docElement = ((Document)propValue).getDocumentElement(); + if( docElement != null ){ + Element valueElement = (Element)docElement.getFirstChild(); + if( valueElement != null ) { + text = valueElement.getTextContent(); + } // end if + } // end if + } // end if + + return text; + } // end method getPropertyValueText + + private Element findInitializerInsertionPoint( Document bpelDOM ) { + // The concept is to find the first Activity child element of the BPEL process document + Element docElement = bpelDOM.getDocumentElement(); + NodeList elements = docElement.getElementsByTagName("*"); + + Element element; + for ( int i = 0 ; i < elements.getLength() ; i++ ) { + element = (Element)elements.item(i); + if( isInsertableActivityElement( element ) ) { + return element; + } // end if + } // end for + + return null; + } // end method findInitializerInsertionPoint + + /** + * A WS-BPEL activity can be any of the following: + * <receive> + * <reply> + * <invoke> + * <assign> + * <throw> + * <exit> + * <wait> + * <empty> + * <sequence> + * <if> + * <while> + * <repeatUntil> + * <forEach> + * <pick> + * <flow> + * <scope> + * <compensate> + * <compensateScope> + * <rethrow> + * <validate> + * <extensionActivity> + * A WS-BPEL start activity is a <receive> or <pick> with @create_instance="yes" + */ + private static String SEQUENCE_ELEMENT = "sequence"; + private static String REPLY_ELEMENT = "reply"; + private static String INVOKE_ELEMENT = "invoke"; + private static String ASSIGN_ELEMENT = "assign"; + private static String PICK_ELEMENT = "pick"; + private static String RECEIVE_ELEMENT = "receive"; + private static String FLOW_ELEMENT = "flow"; + private static String SCOPE_ELEMENT = "scope"; + /** + * Determine if an Element is a BPEL start activity element which can have an Assign + * inserted following it + * @param element - a DOM Element containing the BPEL activity + * @return - true if the Element is a BPEL Activity element, false otherwise + */ + private boolean isInsertableActivityElement( Element element ) { + String name = element.getTagName(); + // For the present, only <receive/> and <pick/> elements with create_instance="yes" count + // if( SEQUENCE_ELEMENT.equalsIgnoreCase(name) ) return true; + String start = element.getAttribute("createInstance"); + if( start == null ) return false; + if( !"yes".equals(start) ) return false; + if( RECEIVE_ELEMENT.equalsIgnoreCase(name) ) return true; + if( PICK_ELEMENT.equalsIgnoreCase(name) ) return true; + return false; + } // end method isActivityElement + + /** + * Reads a BPEL Process file into a DOM Document structure + * @param bpelFile - a File object referencing the BPEL process document + * @return - a DOM Document structure representing the same BPEL process + */ + private Document readDOMFromProcess( File bpelFile ) { + try { + DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance(); + docFactory.setNamespaceAware(true); + docFactory.setXIncludeAware(true); + DocumentBuilder docBuilder = docFactory.newDocumentBuilder(); + + Document bpelDOM = docBuilder.parse( bpelFile ); + return bpelDOM; + } catch (Exception e) { + return null; + } // end try + } // end method + + /** + * Writes a BPEL Process file from a DOM Document structure representing the Process + * @param bpelDOM - the DOM Document representation of the BPEL process + * @param file - a File object to which the BPEL Process is to be written + * @return + */ + private File writeProcessFromDOM( Document bpelDOM, File file ) { + try { + // Prepare the DOM document for writing + Source source = new DOMSource( bpelDOM ); + + // Prepare the output file + Result result = new StreamResult(file); + + // Write the DOM document to the file + Transformer xformer = TransformerFactory.newInstance().newTransformer(); + xformer.transform(source, result); + } catch (TransformerConfigurationException e) { + } catch (TransformerException e) { + return null; + } + return file; + } // end writeProcessFromDOM + + private File getTransformedBPELFile( File bpelFile ) { + String name = bpelFile.getName(); + File parent = bpelFile.getParentFile(); + File bpelFile2 = null; + try { + bpelFile2 = File.createTempFile(name, ".bpel_tmp", parent); + } catch (Exception e ){ + + } // end try + return bpelFile2; + } // end getTransformedBPELFile + + /** + * Gets the directory containing the BPEL process + * @return + */ + private File getDirectory() { + File theDir = getBPELFile().getParentFile(); + return theDir; + } // end getDirectory + + /** + * Gets the File containing the BPEL process definition + * @return - the File object containing the BPEL process + */ + private File getBPELFile() { + if( theBPELFile != null ) return theBPELFile; + try { + String location = this.implementation.getProcessDefinition().getLocation(); + URI locationURI; + if (location.indexOf('%') != -1) { + locationURI = URI.create(location); + } else { + locationURI = new URI(null, location, null); + } + File theProcess = new File(locationURI); + theBPELFile = theProcess; + return theProcess; + } catch( Exception e ) { + if(__log.isDebugEnabled()) { + __log.debug("Exception converting BPEL file URL to an URI: " + e ); + } + } // end try + return null; + } // end getBPELFile + + /** + * Gets the relative path of a file against a directory in its hierarchy + * @param base - the base directory + * @param path - the file + * @return + * @throws IOException + */ + private String getRelativePath(File base, File path) throws IOException { + String basePath = base.getCanonicalPath(); + String filePath = path.getCanonicalPath(); + if (!filePath.startsWith(basePath)) { + throw new IOException("Invalid relative path: base=" + base + " path=" + path); + } + String relative = filePath.substring(basePath.length()); + if (relative.startsWith(File.separator)) { + relative = relative.substring(1); + } + return relative; + } // end getRelativePath + + //----------------------------------------------------------------------------- + // other public APIs which ProcessConfImpl displays which are not in ProcessConf interface + + public List<String> getMexInterceptors(QName processId) { +// System.out.println("getMexInterceptors for processID: " + processId ); + return null; + } + + public void setTransient(boolean t) { +// System.out.println("setTransient called with boolean: " + t ); + } + + public List<Element> getExtensionElement(QName arg0) { + return Collections.emptyList(); + } + // end of other public APIs + //----------------------------------------------------------------------------- + + /** + * Get the size in bytes of the CBP file + * @return - this size in bytes of the CBP file, 0 if the file cannot be found + */ + public long getCBPFileSize() { + File cbpFile = getCBPFile(); + if( cbpFile == null ) return 0; + + return cbpFile.length(); + } // end getCBPFileSize + + private final Set<CLEANUP_CATEGORY> successCategories = EnumSet.noneOf(CLEANUP_CATEGORY.class); + private final Set<CLEANUP_CATEGORY> failureCategories = EnumSet.noneOf(CLEANUP_CATEGORY.class); + + public Set<CLEANUP_CATEGORY> getCleanupCategories(boolean instanceSucceeded) { + if( instanceSucceeded ) return successCategories; + else return failureCategories; + } + + private final Map<String, String> emptyPropertyMap = new Hashtable<String, String>(); + public Map<String, String> getEndpointProperties(EndpointReference epr) { + return emptyPropertyMap; + } + + private final Map<QName, Node> emptyProcessProperties = new Hashtable<QName, Node>(); + public Map<QName, Node> getProcessProperties() { + return emptyProcessProperties; + } + + public boolean isCleanupCategoryEnabled(boolean instanceSucceeded, + CLEANUP_CATEGORY category) { + // TODO Currently returns false - should this be changed for some categories? + return false; + } + + public boolean isSharedService(QName serviceName) { + // Tuscany does not share the service + return false; + } + +} // end class TuscanyProcessConfImpl |