Package org.apache.muse.tools.generator

Source Code of org.apache.muse.tools.generator.WsdlMerge

/*=============================================================================*
*  Copyright 2006 The Apache Software Foundation
*
*  Licensed 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.muse.tools.generator;

import java.io.File;
import java.io.FileWriter;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import javax.wsdl.Definition;
import javax.wsdl.Operation;
import javax.wsdl.Types;
import javax.wsdl.extensions.schema.Schema;
import javax.wsdl.factory.WSDLFactory;
import javax.wsdl.xml.WSDLReader;
import javax.wsdl.xml.WSDLWriter;

import org.w3c.dom.Document;

import org.apache.muse.tools.generator.util.AbstractCommandLineApp;
import org.apache.muse.tools.generator.util.DefinitionInfo;
import org.apache.muse.util.CommandLine;
import org.apache.muse.util.messages.Messages;
import org.apache.muse.util.messages.MessagesFactory;
import org.apache.muse.util.xml.XmlUtils;
import org.apache.muse.ws.wsdl.WsdlUtils;

/**
* Utility class to merge all the capability WSDLs into a single WSDL file
* to represent the resource type. This class will take all of the
* port types in the provided wsdls and make one port type. It will also
* combine the WS-RP documents into one.
*
* @author Andrew Eberbach (aeberbac)
*/
public class WsdlMerge extends AbstractCommandLineApp implements WsdlMergeConstants {

  private static Messages _MESSAGES = MessagesFactory.get(WsdlMerge.class);
 
  private static WSDLFactory _factory;
 
  private static WSDLReader _reader;
 
  private static WSDLWriter _writer;

  static {
    try {
      _factory = WSDLFactory.newInstance();
      _reader = _factory.newWSDLReader();
      _writer = _factory.newWSDLWriter();

            _reader.setFeature(WsdlUtils.WSDL4J_VERBOSE_FLAG, false);
           
    } catch (Exception e) {
      handleErrorAndExit(_MESSAGES.get("NoFactory"), e);
    }
  }
   
  /**
   * Venerable main method. Take in the arguments, make sure they're valid
   * and then try to do the WSDL merging.
   *
   * @param args The raw command line arguments
   */
  public static void main(String[] args) {
    CommandLine arguments = parseParameters(args);
   
    createLogger(arguments);
   
    checkHelpArg(arguments);
   
    String uri = checkUriArg(arguments);
    String address = checkAddressArg(arguments);
    String outputFileName = checkOutputArg(arguments);
   
    Collection wsdls = checkWsdlArgs(arguments);
   
    boolean overwrite = checkOverwriteArg(arguments);
   
    Definition def = null;
   
    try {
      def = WsdlMerge.merge(uri, wsdls, address);
    } catch (Exception e) {     
      handleErrorAndExit(_MESSAGES.get("FailedWSDLMerge"),e);
    }
   
   
    File output = new File(outputFileName);
   
    try {
      write(output, def, overwrite);
    } catch (Exception e) {
      Object[] filler = { output.getAbsolutePath() };
      handleErrorAndExit(_MESSAGES.get("FailedWSDLWrite",filler), e);
    }
  }

  /**
   * Merge the collection of WSDLs into one document. This will
   * try to take the portTypes and merge them along with the
   * WS-RP documents (if they exist).
   *
   * @param namespaceURI
   *         The target namespace URI of the generated WSDL
   *
   * @param wsdlFragments
   *         The WSDL files to merge
   *
   * @param address
   *         The address used for the location attribute on the generated
   *         service
   *    
   * @return  The <code>Definition</code> representing the newly created merged WSDL
   */
  public static Definition merge(String namespaceURI,
      Collection wsdlFragments, String address) {

    DefinitionInfo targetDefinition = new DefinitionInfo(namespaceURI);

    for (Iterator i = wsdlFragments.iterator(); i.hasNext();) {
      DefinitionInfo definition = new DefinitionInfo((Definition) i
          .next(), namespaceURI);
      copyOperations(definition, targetDefinition);
      copyProperties(definition, targetDefinition);
    }

    targetDefinition.createBinding();
    targetDefinition.createService(address);
    return targetDefinition.getDefinition();
  }

  /**
   * Copy properties (ie WS-RP Documents) from one WSDL to another.
   *
   * @param sourceDefinition
   *         The source WSDL
   *
   * @param targetDefinition
   *         The destination (merged) WSDL
   */
  private static void copyProperties(DefinitionInfo sourceDefinition,
      DefinitionInfo targetDefinition) {
    Types types = sourceDefinition.getTypes();

    for (Iterator i = types.getExtensibilityElements().iterator(); i
        .hasNext();) {
      targetDefinition.addSchema((Schema) i.next());
    }

    targetDefinition.mergeProperties(sourceDefinition);
  }

  /**
   * Copy operations (ie portType operations) from one WSDL to another.
   *
   * @param sourceDefinition
   *         The source WSDL
   *
   * @param targetDefinition
   *         The destination (merged) WSDL
   */
  private static void copyOperations(DefinitionInfo sourceDefinition,
      DefinitionInfo targetDefinition) {
    // Need to keep a map of the messages we're referencing locally
    // so that we don't try to redefine them in the target document
    Map localMessageMap = new HashMap();

    for (Iterator i = sourceDefinition.getOperations().iterator(); i
        .hasNext();) {
      Operation nextOperation = (Operation) i.next();
      targetDefinition.addOperation(nextOperation, localMessageMap);
    }
  }

  /**
   * Check to see if the user provided the help parameters
   * and display the appropriate help message (basic or advanced).
   *
   * @param arguments Command line arguments
   */
  private static void checkHelpArg(CommandLine arguments) {
    if(arguments.hasFlag(HELP_FLAG) || hasNoArguments(arguments)) {
      Object[] filler = new Object[] {
          URI_FLAG,
          ADDRESS_FLAG,
          OUTPUT_FLAG,
          URI_FLAG,
          ADDRESS_FLAG,
          OUTPUT_FLAG,
          OVERWRITE_FLAG,
          HELP_FLAG
      };
      handleMessage(_MESSAGES.get("WsdlMergeHelp",filler,false));
      handleExit();
    }
  }

  /**
   * Check to make sure an address flag and value were provided.
   *
   * @param arguments The command line arguments
   * @return The address provided
   */
  private static String checkAddressArg(CommandLine arguments) {
    String addressArg = arguments.getFlagValue(ADDRESS_FLAG);

    if (addressArg == null) {
      Object filler[] = new Object[] {
          ADDRESS_FLAG,
          HELP_FLAG
        };
      handleErrorAndExit(_MESSAGES.get("NoAddressFlag",filler));
    }
   
    return addressArg;
  }

  /**
   * Check to make sure a URI flag and value were provided.
   *
   * @param arguments The command line arguments
   * @return The URI provided
   */
  private static String checkUriArg(CommandLine arguments) {
    String uriArg = arguments.getFlagValue(URI_FLAG);

    if (uriArg == null) {
      Object filler[] = new Object[] {
        URI_FLAG,
        HELP_FLAG
      };
      handleErrorAndExit(_MESSAGES.get("NoURIFlag",filler));
    }
   
    return uriArg;
  }

  /**
   * Check to make sure an ouptut document flag and value were provided.
   *
   * @param arguments The command line arguments
   * @return The output document
   */
  private static String checkOutputArg(CommandLine arguments) {
    String outputArg = arguments.getFlagValue(OUTPUT_FLAG);

    if (outputArg == null) {
      Object filler[] = new Object[] {
          OUTPUT_FLAG,
          HELP_FLAG
        };
      handleErrorAndExit(_MESSAGES.get("NoOutputFlag",filler));
    }
   
    return outputArg;
  }

  /**
   * Go through all of the parameters that are not flags and
   * are not used and assume they are all WSDL documents. Make sure
   * all of the documents exist and parse.
   *
   * @param arguments The command line arguments
   * @return A <code>Collection</code> of <code>Definition</code> objects representing the parsed WSDLs.
   */
  private static Collection checkWsdlArgs(CommandLine arguments) {
    ArrayList wsdls = new ArrayList();
    String[] argWsdls = arguments.getArguments();
    for(int i=0; i < argWsdls.length; i++) {
      File wsdl = new File(argWsdls[i]);
      if(!wsdl.exists()) {
        Object[] filler = new Object[] {
              wsdl.getAbsoluteFile()
        };
        handleErrorAndExit(_MESSAGES.get("NonExistantWSDL", filler));
      }
           
      wsdls.add(load(wsdl));
    }
   
    if(wsdls.size() == 0) {
      handleErrorAndExit(_MESSAGES.get("NoWSDLs"));
    }
   
    return wsdls;
  }

  /**
   * Given a <code>File</code> try to parse it and turn it into a
   * <code>Definition</code>.
   *
   * @param wsdl
   *       The <code>File</code> to parse
   *
   * @return
   *       A <code>Defintion</code> if parsing was successful
   */
  private static Definition load(File wsdl) {
    Document document = null;
    Definition definition = null;
    try {
      document = getWSDLDocument(wsdl);
      definition = _reader.readWSDL(null, document);
    } catch (Exception e) {
      Object[] filler = new Object[] {
          wsdl
      };
      handleErrorAndExit(_MESSAGES.get("FailedWSDLParse", filler),e);
    }
   
    return definition;
  }

  /**
   * Write a <code>Definition</code> to a file.
   *
   * @param destination
   *       The file where the definition will be written
   * @param def
   *       The definition we're writing
   * @param overwrite
   *       Should we overwrite existing files
   *
   * @throws Exception
   *       If anything goes wrong
   */
  private static void write(File destination, Definition def, boolean overwrite) throws Exception {
    if (!destination.exists() || overwrite) {
      File parent = destination.getAbsoluteFile().getParentFile();
      if(!parent.exists()) {
        if(!parent.mkdirs()) {
          Object[] filler = { parent } ;
          throw new Exception(_MESSAGES.get("CouldNotMakeDir",filler));
        }
      }
     
      Document wsdlDoc = _writer.getDocument(def);
     
      FileWriter fileWriter = new FileWriter(destination);
      fileWriter.write(XmlUtils.toString(wsdlDoc));
      fileWriter.close();     
    } else {
      handleMessage(_MESSAGES.get("NotOverwriting", new String[] {destination.getPath()}));
    }
  }
 
  /**
   * Wraps the raw command line parameters into a <code>CommandLine</code>
   * which will manage finding the flags passed in on the command line.
   *
   * @param args Raw command line parameters
   * @return Wrapped <code>CommandLine</code> of the given parameters.
   */
  private static CommandLine parseParameters(String[] args) {
    CommandLine arguments = new CommandLine();

    arguments.saveFlagValue(URI_FLAG);
    arguments.saveFlagValue(ADDRESS_FLAG);
    arguments.saveFlagValue(OUTPUT_FLAG);
   
    arguments.parse(args);
    return arguments;
  }
}
TOP

Related Classes of org.apache.muse.tools.generator.WsdlMerge

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.