org.apache.tuscany.sca.implementation.bpel.ode.BPELODEDeployFile.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.tuscany.sca.implementation.bpel.ode.BPELODEDeployFile.java

Source

/*
 * 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.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.net.URI;
import java.util.List;

import javax.xml.namespace.QName;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.tuscany.sca.assembly.ComponentType;
import org.apache.tuscany.sca.assembly.Reference;
import org.apache.tuscany.sca.assembly.Service;
import org.apache.tuscany.sca.implementation.bpel.BPELImplementation;

/**
 * A class that handles the deploy.xml file required for each BPEL process by the ODE runtime
 * @author Mike Edwards
 * 
 * An explanation of the structure of the ODE deploy file:
 * 
 * <deploy xmlns="http://www.apache.org/ode/schemas/dd/2007/03"
 *  xmlns:tns="http://helloworld"
 *  xmlns:tus="http://tuscany.apache.org/xmlns/sca/1.1">
 *
 *  <process name="tns:HelloWorld">
 *      <active>true</active>
 *      <provide partnerLink="helloPartnerLink">
 *          <service name="tus:helloPartnerLink" port="HelloWorld"/>
 *      </provide>
 *      <invoke partnerLink="greetingsPartnerLink">
 *          <service name="tus:greetingsPartnerLink" port="Greetings"/>
 *      </invoke>
 *  </process>
 * </deploy> 
 * 
 * For SCA purposes:
 * 
 * a) Each partner link in the BPEL process is declared using either a <provide.../> 
 * (for a service) or using a <invoke.../> (for a reference).
 * 
 * b) Each <provide/> and <invoke/> must use the partnerLink name, as declared in the
 * BPEL process.
 * 
 * c) The <provide/> and <invoke/> elements each have a single child <service/> element.  
 * The <service/> elements have name and port attributes.  The NAME attribute MUST be set 
 * to the same name as the partnerLink and MUST be prefixed by a prefix which references 
 * the namespace "http://tuscany.apache.org" ("tus" in the example above).  
 * The port attribute can be set to any name (it must be present but it is not actually 
 * used for anything significant).
 * 
 * When SCA loads a BPEL process to the ODE server, this file is read by the ODE server to
 * characterize the process.  When SCA interacts with ODE at later points - either when a
 * service is being invoked or the process invokes a reference - it is the service @name
 * attribute that identifies the service or reference involved.
 *
 * @version 
 */
public class BPELODEDeployFile {
    private final Log __log = LogFactory.getLog(getClass());

    static final String DEPLOY_ELEMENT_START = "<deploy xmlns=\"http://www.apache.org/ode/schemas/dd/2007/03\"";
    static final String DEPLOY_ENDELEMENT = "</deploy>";
    static final String PROCESS_NAMESPACE_DECL = "xmlns:tns=";
    static final String SERVICE_NAMESPACE = "xmlns:tus=\"http://tuscany.apache.org\"";
    static final String PROCESS_ELEMENT_START = "<process name=\"tns:";
    static final String PROCESS_ELEMENT_END = "\">";
    static final String PROCESS_ENDELEMENT = "</process>";
    static final String ACTIVE_ELEMENT = "<active>true</active>";
    static final String PROVIDE_ELEMENT_START = "<provide partnerLink=\"";
    static final String PROVIDE_ELEMENT_END = "\">";
    static final String PROVIDE_ENDELEMENT = "</provide>";
    static final String SERVICE_ELEMENT_START = "<service name=\"tus:";
    static final String SERVICE_ELEMENT_PORT = "\" port=\"";
    static final String SERVICE_ELEMENT_END = "Port\"/>";
    static final String INVOKE_ELEMENT_START = "<invoke partnerLink=\"";
    static final String INVOKE_ELEMENT_END = "\">";
    static final String INVOKE_ENDELEMENT = "</invoke>";

    static final String DEPLOY_FILENAME = "deploy.xml";

    private BPELImplementation implementation;

    /**
     * Constructor - requires a BPELImplementation as a parameter
     * The ODE deploy.xml file is for this supplied BPELImplementation
     * @param theImplementation
     */
    public BPELODEDeployFile(BPELImplementation theImplementation) {

        implementation = theImplementation;

    } // end BPELODEDeployFile constructor

    /**
     * Writes the deploy file into the same directory as the BPEL process file, with the name
     * "deploy.xml"
     */
    public void writeDeployfile() throws IOException {

        File theDirectory = getDirectory();

        File deployFile = new File(theDirectory, DEPLOY_FILENAME);
        new FileOutputStream(deployFile);
        //if( !deployFile.canWrite() ) throw new IOException( "Unable to write to deploy file" +
        //                                                   deployFile.getPath() );

        // Create a stream for the data and write the data to the file
        PrintStream theStream = new PrintStream(new FileOutputStream(deployFile));
        try {
            constructDeployXML(theStream);
            if (theStream.checkError())
                throw new IOException();
        } catch (Exception e) {
            throw new IOException("Unable to write data to deploy file" + deployFile.getPath());
        } finally {
            theStream.close();
        } // end try

    } // end writeDeployFile

    /**
     * Creates the deploy.xml data and writes it to a supplied PrintStream
     * @param stream
     */
    public void constructDeployXML(PrintStream stream) {

        // <deploy + namespace...
        stream.println(DEPLOY_ELEMENT_START);
        // namespace of the BPEL process
        QName process = implementation.getProcess();
        String processNamespace = process.getNamespaceURI();
        stream.println(PROCESS_NAMESPACE_DECL + "\"" + processNamespace + "\"");
        // namespace for the service name elements
        stream.println(SERVICE_NAMESPACE + ">");

        // <process> element
        stream.println(PROCESS_ELEMENT_START + process.getLocalPart() + PROCESS_ELEMENT_END);

        // <active/> element
        stream.println(ACTIVE_ELEMENT);

        ComponentType componentType = implementation.getComponentType();
        List<Service> theServices = componentType.getServices();
        // Loop over the <provide/> elements - one per service
        for (Service service : theServices) {
            String serviceName = service.getName();
            // Provide element...
            stream.println(PROVIDE_ELEMENT_START + serviceName + PROVIDE_ELEMENT_END);
            // Child service element...
            stream.println(
                    SERVICE_ELEMENT_START + serviceName + SERVICE_ELEMENT_PORT + serviceName + SERVICE_ELEMENT_END);
            stream.println(PROVIDE_ENDELEMENT);
        } // end for

        // Loop over the <invoke/> elements - one per reference
        List<Reference> theReferences = componentType.getReferences();
        for (Reference reference : theReferences) {
            String referenceName = reference.getName();
            stream.println(INVOKE_ELEMENT_START + referenceName + INVOKE_ELEMENT_END);
            // Child service element...
            stream.println(SERVICE_ELEMENT_START + referenceName + SERVICE_ELEMENT_PORT + referenceName
                    + SERVICE_ELEMENT_END);
            stream.println(INVOKE_ENDELEMENT);

        } // end for

        // </process> element
        stream.println(PROCESS_ENDELEMENT);

        // </deploy>
        stream.println(DEPLOY_ENDELEMENT);

    } // end constructDeployXML

    /** 
     * 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() {
        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);
            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

} // end class BPELODEDeployFile