/*
* 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.util;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
import java.util.logging.ConsoleHandler;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.xml.namespace.QName;
import org.apache.muse.core.Environment;
import org.apache.muse.tools.generator.Wsdl2JavaConstants;
import org.apache.muse.util.CommandLine;
import org.apache.muse.util.FileUtils;
import org.apache.muse.util.messages.Messages;
import org.apache.muse.util.messages.MessagesFactory;
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;
/**
* Assorted utility methods that are shared by the command line apps (wsdl2java and wsdlmerge).
* Logging is handled here for the org.apache.muse.tools.generator package using
* java.util.logging classes.
*
*
* @author Andrew Eberbach (aeberbac)
*/
public class AbstractCommandLineApp {
public static final String TOP_LEVEL_PACKAGE = "org.apache.muse.tools";
public static final String PATH_TO_POM_PROPERTIES = "/META-INF/maven/muse/muse-tools/pom.properties";
public static final String VERSION_PROPERTY = "version";
private static Messages _MESSAGES = MessagesFactory.get(AbstractCommandLineApp.class);
protected static Logger _logger = Logger.getLogger(AbstractCommandLineApp.class.getPackage().getName());
/**
* Tell the logger to info() this message.
*
* @param message The message to log.
*/
public static void handleMessage(String message) {
_logger.info(message);
}
/**
* Something bad happened, log the message and exit
* with status 1. Log this as severe().
*
* @param message The error message
*/
public static void handleErrorAndExit(String message) {
_logger.severe(message);
System.exit(1);
}
/**
* Something bad happened, log the message and
* associated exception. Log this as severe().
*
* @param message
* @param exception
*/
public static void handleErrorAndExit(String message, Exception exception) {
_logger.log(Level.SEVERE, message, exception);
System.exit(1);
}
/**
* For cleanliness wrap System.exit(0) exiting
* normally.
*
*/
public static void handleExit() {
System.exit(0);
}
/**
* Check an exception to see if it has a message and
* if it has one then make it into the standard
* Messages filler object and return it.
*
* @param e
* The exception we're interest in
* @return
* A filler for Messages with either an empty string or the
* message from the exception
*
* @see Messages
*/
public static Object[] getFiller(Exception e) {
String message = e.getMessage();
Object[] filler = new Object[] {
message == null?new String():message
};
return filler;
}
/**
* Tries to parse the WSDL Document from the given file. Throws an IllegalArgumentException
* if the file is null or doesn't exist.
*
* @param deploymentDescriptorFile
* @param deploymentDescriptorDocument
* @return A Document representing the parsed WSDL
*/
public static Document[] getWSDLDocuments(File deploymentDescriptorFile, Document deploymentDescriptorDocument) throws Exception {
WsdlEnvironment env = null;
File[] wsdlFiles = DeploymentDescriptorHelper.getWsdls(deploymentDescriptorFile, deploymentDescriptorDocument);
Document[] wsdlDocuments = new Document[wsdlFiles.length];
for(int i=0; i < wsdlFiles.length; i++) {
env = new WsdlEnvironment(wsdlFiles[i].getAbsoluteFile().getParentFile());
wsdlDocuments[i] = getWSDLDocument(wsdlFiles[i].getName(), env);
}
return wsdlDocuments;
}
public static MetadataDescriptor[] getMetadataDescriptors(File descriptorFile, Document descriptorDocument) throws Exception {
WsdlEnvironment env = null;
File[] wsdlFiles = DeploymentDescriptorHelper.getWsdls(descriptorFile, descriptorDocument);
MetadataDescriptor[] metadatas = new MetadataDescriptor[wsdlFiles.length];
for(int i=0; i < wsdlFiles.length; i++) {
env = new WsdlEnvironment(wsdlFiles[i].getAbsoluteFile().getParentFile());
metadatas[i] = getMetadataDescriptor(wsdlFiles[i].getName(), env);
}
return metadatas;
}
/**
* Convenience method that will get the document from the environment.
*
* @param wsdlPath
* @param env
*/
public static MetadataDescriptor getMetadataDescriptor(String wsdlPath, WsdlEnvironment env) {
return getMetadataDescriptor(wsdlPath, env, env.getDocument(wsdlPath));
}
/**
* Given a WSDL document, extract the metadata descriptor (if any) and return it.
*
* @param wsdlPath
* @param env
* @param wsdlDocument
* @return A metadata descriptor or null if one could not be found.
*/
public static MetadataDescriptor getMetadataDescriptor(String wsdlPath, Environment env, Document wsdlDocument) {
MetadataDescriptor metadata = null;
Element portType = WsdlUtils.getFirstPortType(wsdlDocument);
if(portType != null) {
QName descQname = WsrmdConstants.DESCRIPTOR_ATTR_QNAME;
String descName = portType.getAttributeNS(descQname.getNamespaceURI(), descQname.getLocalPart());
QName locationQname = WsrmdConstants.DESCRIPTOR_LOCATION_ATTR_QNAME;
String locationName = portType.getAttributeNS(locationQname.getNamespaceURI(), locationQname.getLocalPart());
if(descName.length() != 0 && locationName.length() != 0) {
String relativePath = env.createRelativePath(wsdlPath, locationName);
Document doc = env.getDocument(relativePath);
Element rmdDoc = WsrmdUtils.getMetadataDescriptor(doc, descName);
if(rmdDoc == null) {
Object[] filler = {descName, relativePath, getEnvFile(env, wsdlPath)};
throw new MuseRuntimeException("BadRMDName",_MESSAGES.get("BadRMDName", filler));
}
metadata = new SimpleMetadataDescriptor(rmdDoc);
}
}
return metadata;
}
private static Object getEnvFile(Environment env, String wsdlPath) {
return new File(env.getRealDirectory(), wsdlPath);
}
/**
* Given a <code>File</code> try to load it into a <code>Definition</code>
* throwing an Exception if something is amiss. The wsdl document is inlined in
* that all referenced schema and wsdl documents are copied into this document. The
* references to the locations of the imported/include documents are stripped.
*
* @param wsdlPath
* The WSDL file we're parsing
*
* @return
* A <code>Definition</code> of the parsed WSDL
*
* @throws Exception
*/
public static Document getWSDLDocument(String wsdlPath, Environment env) throws Exception {
if (wsdlPath == null) {
throw new IllegalArgumentException(_MESSAGES.get("NullWSDL"));
}
try {
Document wsdl = WsdlUtils.createWSDL(env, wsdlPath, true);
WsdlUtils.removeSchemaReferences(wsdl.getDocumentElement());
WsdlUtils.removeWsdlReferences(wsdl.getDocumentElement());
return wsdl;
} catch (Exception e) {
Object[] filler = getFiller(e);
throw new RuntimeException(_MESSAGES.get("FailedLoadingWSDL", filler), e);
}
}
/**
* Check to see if the given arguments object has no arguments in it.
* This is true if the number of arguments (read: number of arguments that
* are not flags and are not associated with flags) plus the number
* of flags is 0.
*
* @param arguments
* The arguments we're checking
* @return
* true if there are no arguments in the object
*/
public static boolean hasNoArguments(CommandLine arguments) {
return (arguments.getNumberOfArguments() + arguments.getNumberOfFlags()) == 0;
}
/**
* Set up the java.util.Logger that this class (and the descendants
* in the Logger heirarchy) will use. Handles command line parameters
* for increasing verbosity or for turning off logging entirely.
*
* @param arguments Command line arguments
*/
protected static void createLogger(CommandLine arguments) {
ConsoleHandler handler = new ConsoleHandler();
handler.setFormatter(new SimpleLogFormatter());
_logger = Logger.getLogger(TOP_LEVEL_PACKAGE);
_logger.setLevel(Level.INFO);
_logger.setUseParentHandlers(false);
_logger.addHandler(handler);
if(arguments.hasFlag(Wsdl2JavaConstants.VERBOSE_FLAG)) {
_logger.setLevel(Level.ALL);
} else if (arguments.hasFlag(Wsdl2JavaConstants.QUIET_FLAG)) {
_logger.setLevel(Level.OFF);
} else {
_logger.setLevel(Level.FINE);
}
}
/**
* Check to see if the overwrite flag was specified. This
* is just a call to see if the arguments contain the flag.
*
* @param arguments Command line arguments
* @return true if the arguments contain the flag, false otherwise
*/
protected static boolean checkOverwriteArg(CommandLine arguments) {
return arguments.hasFlag(Wsdl2JavaConstants.OVERWRITE_FLAG);
}
/**
* Get the version out of maven metadata that's left
* from the build. If it isn't available or something else
* goes wrong it will return a default message.
*
* @return The version of this code
*/
public static String getVersion() {
String version = _MESSAGES.get("DefaultVersion");
InputStream versionIS = FileUtils.loadFromContext(AbstractCommandLineApp.class, PATH_TO_POM_PROPERTIES);
if(versionIS != null) {
Properties properties = new Properties();
try {
properties.load(versionIS);
return properties.getProperty(VERSION_PROPERTY);
} catch (IOException e) {
//fall through to return
}
}
return version;
}
/**
* Check to make sure that the parent directory of a given file exists
* or can be created. If it can be created, then try to make the directory.
*
* @param destination Target file to check
*
* @throws Exception
*/
public static void checkParentDirectory(File destination) throws Exception {
File parent = destination.getAbsoluteFile().getParentFile();
if(!parent.exists()) {
if(!parent.mkdirs()) {
Object[] filler = { parent } ;
throw new Exception(_MESSAGES.get("CouldNotMakeDir",filler));
}
}
}
}