Package org.apache.tuscany.sca.implementation.bpel.ode

Source Code of org.apache.tuscany.sca.implementation.bpel.ode.TuscanyProcessConfImpl

/*
* 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: 910277 $ $Date: 2010-02-15 17:35:23 +0000 (Mon, 15 Feb 2010) $
*/
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
TOP

Related Classes of org.apache.tuscany.sca.implementation.bpel.ode.TuscanyProcessConfImpl

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