Package org.apache.muse.tools.generator

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

/*
* 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.muse.tools.generator;

import java.io.File;
import java.io.FileNotFoundException;
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.PortType;
import javax.wsdl.Types;
import javax.wsdl.WSDLException;
import javax.wsdl.extensions.schema.Schema;
import javax.wsdl.factory.WSDLFactory;
import javax.wsdl.xml.WSDLReader;
import javax.wsdl.xml.WSDLWriter;
import javax.xml.namespace.QName;

import org.apache.muse.core.Environment;
import org.apache.muse.tools.generator.util.AbstractCommandLineApp;
import org.apache.muse.tools.generator.util.DefinitionInfo;
import org.apache.muse.tools.generator.util.MuseRuntimeException;
import org.apache.muse.tools.generator.util.WsdlEnvironment;
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.resource.metadata.MetadataDescriptor;
import org.apache.muse.ws.resource.metadata.WsrmdConstants;
import org.apache.muse.ws.resource.metadata.impl.SimpleMetadataDescriptor;
import org.apache.muse.ws.resource.metadata.impl.WsrmdUtils;
import org.apache.muse.ws.wsdl.WsdlUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;


/**
* 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) {
      throw new MuseRuntimeException("NoFactory", _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) {
    try {
      CommandLine arguments = parseParameters(args);
     
      createLogger(arguments);
      checkHelpArg(arguments);
      checkVersionArg(arguments);
     
      File[] files = checkFileArgs(arguments);   
      String outputFileName = checkOutputArg(arguments);
      String outputRMDFileName = checkOutputRMDArg(arguments);
      boolean overwrite = checkOverwriteArg(arguments);
     
      String uri = checkUriArg(arguments);
      String address = checkAddressArg(arguments);
     
      run(files, outputFileName, outputRMDFileName, overwrite, uri, address);
    } catch (Exception e) {
      Object[] filler = { Wsdl2JavaConstants.VERBOSE_FLAG };
      handleErrorAndExit(_MESSAGES.get("WsdlMergeFailed", filler), e);
    }
  }

  public static void run(File[] files, String outputFileName, String outputRMDFileName, boolean overwrite, String uri, String address) throws FileNotFoundException {   
    Document[] wsdls = new Document[files.length];
    MetadataDescriptor[] metadatas = new MetadataDescriptor[files.length];

    for(int i=0; i < files.length; i++) {
      Environment env = new WsdlEnvironment(files[i].getAbsoluteFile().getParentFile());
      wsdls[i] = WsdlUtils.createWSDL(env, files[i].getName(), true);
     
      //
      // wsdl4j will get angry when it tries to resolve these because we're not
      // providing the base directory since we've already read them in. So
      // we remove the imports.
      //
      WsdlUtils.removeSchemaReferences(wsdls[i].getDocumentElement());
      WsdlUtils.removeWsdlReferences(wsdls[i].getDocumentElement());
     
      if(outputRMDFileName != null) {
        metadatas[i] = getMetadataDescriptor(files[i].getName(), env, wsdls[i]);
      }
    }
   
    Definition mergedWsdl = merge(uri, wsdls, address);
         
    if(outputRMDFileName != null) {
      MetadataDescriptor mergedMetadata = merge(outputFileName, getFirstPortType(mergedWsdl).getQName(), metadatas);
      setMetadata(mergedMetadata.getName(), outputRMDFileName, mergedWsdl);
      writeRmd(outputRMDFileName, mergedMetadata, overwrite);
    }       
   
    writeWsdl(outputFileName, mergedWsdl, overwrite)
  }

  private static void setMetadata(String metadataName, String metadataLocation, Definition mergedWsdl) {
    mergedWsdl.addNamespace(WsrmdConstants.PREFIX, WsrmdConstants.NAMESPACE_URI);
   
    PortType portType = getFirstPortType(mergedWsdl);
    portType.setExtensionAttribute(WsrmdConstants.DESCRIPTOR_ATTR_QNAME, metadataName);
    portType.setExtensionAttribute(WsrmdConstants.DESCRIPTOR_LOCATION_ATTR_QNAME, metadataLocation);   
  }

  private static PortType getFirstPortType(Definition wsdl) {
    return (PortType) wsdl.getPortTypes().values().iterator().next();
  }

  public static MetadataDescriptor merge(String wsdlLocation, QName interfaceName, MetadataDescriptor[] metadatas) {
    SimpleMetadataDescriptor mergedMetadata = new SimpleMetadataDescriptor(METADATA_NAME, wsdlLocation, interfaceName);
   
    for(int i=0; i < metadatas.length; i++) {
      copyMetadata(metadatas[i], mergedMetadata);
    }
   
    return mergedMetadata;
  }

  private static String checkOutputRMDArg(CommandLine arguments) {
    return arguments.getFlagValue(RMD_OUTPUT_FLAG);   
  }

  /**
   * Print the version and exit.
   *
   * @param arguments Command line arguments
   */
  private static void checkVersionArg(CommandLine arguments) {
    if(arguments.hasFlag(WsdlMergeConstants.VERSION_FLAG)) {
      handleMessage(getVersion());
      handleExit();
    }
  }

  /**
   * 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, Document[] wsdlFragments, String address) {
    DefinitionInfo targetDefinition = new DefinitionInfo(namespaceURI);

    DefinitionInfo definition = null;
    for (int i = 0; i < wsdlFragments.length; i++) { 
      try {
        definition = new DefinitionInfo(load(wsdlFragments[i]));
      } catch (WSDLException e) {
        Object[] filler = { new Integer(i) };
        throw new MuseRuntimeException("WsdlFragmentParseFailed", _MESSAGES.get("WsdlFragmentParseFailed", filler), e);
      }

      copyOperations(definition, targetDefinition);
      copyProperties(definition, targetDefinition);
    }
   
    targetDefinition.createBinding();
    targetDefinition.createService(address);
    return targetDefinition.getDefinition();
  }

  private static void copyMetadata(MetadataDescriptor sourceMetadata, MetadataDescriptor targetMetadata) {
    if(sourceMetadata == null) {
      return;
    }

    for(Iterator i=sourceMetadata.getPropertyNames().iterator(); i.hasNext();) {
      QName nextProperty = (QName)i.next();
      if(targetMetadata.hasProperty(nextProperty)) {
        Object[] filler = { nextProperty };
        throw new MuseRuntimeException("DuplicateProperty", _MESSAGES.get("DuplicateProperty", filler));
      }
     
      try {
        addProperty(nextProperty, sourceMetadata, targetMetadata);
      } catch (Exception e) {
        Object[] filler = { nextProperty };
        throw new MuseRuntimeException("FailedCopyingProperty", _MESSAGES.get("FailedCopyingProperty", filler), e);
      }
    }
  }   

    /**
     * Copies one propert from a source MetadataDescriptor to a destination MetadataDescriptor.
     * Performs a deep-copy.
     *
     * @param name
     * @param source
     * @param target
     * @throws Exception
     */
    public static void addProperty(QName name, MetadataDescriptor source, MetadataDescriptor target) throws Exception {
      if(name == null) {
        throw new NullPointerException();
      }
     
      if(source == null) {
        throw new NullPointerException();
      }
     
      if(target == null) {
        throw new NullPointerException();
      }
     
        String mutability = source.getMutability(name);
        String modifiability = source.getModifiability(name);
        Collection initialValues = new ArrayList(source.getInitialValues(name));
        Collection staticValues = new ArrayList(source.getStaticValues(name));
        Collection validValues = new ArrayList(source.getValidValues(name));
 
        target.addProperty(name, modifiability, mutability);
        target.setInitialValues(name, initialValues);
        target.setStaticValues(name, staticValues);
        target.setValidValues(name, validValues);
       
        //
        // ValidValueRange will only exist if ValidValues was empty
        //
        if (validValues.isEmpty())
        {
            target.setLowerBound(name, source.getLowerBound(name));
            target.setUpperBound(name, source.getUpperBound(name));
        }
       
        Iterator j = source.getExtendedMetadataNames(name).iterator();
       
        while (j.hasNext())
        {
            QName metadataName = (QName)j.next();
            String metadataValue = source.getExtendedMetadata(name, metadataName);
            target.setExtendedMetadata(name, metadataName, metadataValue);
        }
    }

  /**
   * 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,
          RMD_OUTPUT_FLAG,

          OVERWRITE_FLAG,
          VERSION_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
        };
      throw new MuseRuntimeException("NoAddressFlag", _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
      };
      throw new MuseRuntimeException("NoURIFlag", _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
        };
      throw new MuseRuntimeException("NoOutputFlag", _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 array of <code>Document</code> objects representing the parsed WSDLs.
   */
  private static File[] checkFileArgs(CommandLine arguments) {   
    String[] argFiles = arguments.getArguments();
    File[] files = new File[argFiles.length];
    for(int i=0; i < argFiles.length; i++) {
      files[i] = new File(argFiles[i])
      if(!files[i].exists()) {
        Object[] filler = { files[i] };
        throw new MuseRuntimeException("NonExistant", _MESSAGES.get("NonExistant", filler));
      }
    }
   
    if(files.length  == 0) {
      Object filler[] = { HELP_FLAG };
      throw new MuseRuntimeException("NoWSDLs", _MESSAGES.get("NoWSDLs", filler));
    }
   
    return files;
  }

  /**
   * 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
   * @param environment
   *
   * @return
   *       A <code>Defintion</code> if parsing was successful
   * @throws WSDLException
   */
  private static Definition load(Document document) throws WSDLException {
    String parent = null;
    return _reader.readWSDL(parent, document);                 
  }
 
  private static void writeRmd(String fileName, MetadataDescriptor metadata, boolean overwrite) {
    File metadataDestination = new File(fileName);
    if(!metadataDestination.exists() || overwrite) {
      try {
        checkParentDirectory(metadataDestination.getAbsoluteFile().getParentFile());
        Element rmdDoc = WsrmdUtils.createMetadataDocument(metadata);
       
        FileWriter fileWriter = new FileWriter(metadataDestination);
        fileWriter.write(XmlUtils.toString(rmdDoc));
        fileWriter.close();     
      } catch (Exception e) {
        Object[] filler = {metadataDestination.getAbsolutePath()};
        throw new MuseRuntimeException("FailedWritingRmd", _MESSAGES.get("FailedWritingRmd", filler), e);
      }
    } else {
      handleMessage(_MESSAGES.get("NotOverwriting", new String[] {metadataDestination.getPath()}));
    }
  }

  private static void writeWsdl(String fileName, Definition mergedDefinition, boolean overwrite) {
    File wsdlDestination = new File(fileName);   
   
    if (!wsdlDestination.exists() || overwrite) {
      try {
        checkParentDirectory(wsdlDestination.getAbsoluteFile().getParentFile());
        Document wsdlDoc = _writer.getDocument(mergedDefinition);
 
        FileWriter fileWriter = new FileWriter(wsdlDestination);
        fileWriter.write(XmlUtils.toString(wsdlDoc));
        fileWriter.close();     
      } catch (Exception e) {
        Object[] filler = {wsdlDestination.getAbsolutePath()};
        throw new MuseRuntimeException("FailedWritingWsdl", _MESSAGES.get("FailedWritingWsdl", filler), e);
      }
    } else {
      handleMessage(_MESSAGES.get("NotOverwriting", new String[] {wsdlDestination.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.saveFlagValue(RMD_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.