// ============================================================================
//
// Copyright (C) 2006-2012 Talend Inc. - www.talend.com
//
// This source code is available under agreement available at
// %InstallDIR%\features\org.talend.rcp.branding.%PRODUCTNAME%\%PRODUCTNAME%license.txt
//
// You should have received a copy of the agreement
// along with this program; if not, write to Talend SA
// 9 rue Pages 92150 Suresnes, France
//
// ============================================================================
package org.talend.repository.ui.wizards.exportjob.scriptsmanager;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.jar.Attributes;
import java.util.jar.Manifest;
import org.apache.axis.encoding.TypeMappingRegistryImpl;
import org.apache.axis.utils.CLArgsParser;
import org.apache.axis.utils.CLOption;
import org.apache.axis.utils.Messages;
import org.apache.axis.wsdl.Java2WSDL;
import org.apache.axis.wsdl.fromJava.Emitter;
import org.apache.log4j.Logger;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.osgi.framework.Bundle;
import org.talend.commons.ui.runtime.exception.ExceptionHandler;
import org.talend.commons.utils.io.FilesUtils;
import org.talend.core.model.process.JobInfo;
import org.talend.core.model.properties.ProcessItem;
import org.talend.core.model.utils.JavaResourcesHelper;
import org.talend.designer.runprocess.IProcessor;
import org.talend.designer.runprocess.ProcessorException;
import org.talend.designer.runprocess.ProcessorUtilities;
import org.talend.repository.RepositoryPlugin;
import org.talend.repository.documentation.ExportFileResource;
/**
* DOC x class global comment. Detailled comment <br/>
*
*/
public class JobJavaScriptsWSManager extends JobJavaScriptsManager {
private String outputSuffix;
public JobJavaScriptsWSManager(Map<ExportChoice, Object> exportChoiceMap, String contextName, String launcher,
int statisticPort, int tracePort, String suffix) {
super(exportChoiceMap, contextName, launcher, statisticPort, tracePort);
this.outputSuffix = suffix;
}
private static Logger log = Logger.getLogger(ExceptionHandler.class);
public static final String EXPORT_METHOD = "runJob"; //$NON-NLS-1$
private static List<String> axisLib = new ArrayList<String>();
static {
axisLib.add("axis.jar"); //$NON-NLS-1$
axisLib.add("jaxrpc.jar"); //$NON-NLS-1$
axisLib.add("saaj.jar"); //$NON-NLS-1$
axisLib.add("wsdl4j-1.6.2.jar"); //$NON-NLS-1$
axisLib.add("commons-discovery-0.2.jar"); //$NON-NLS-1$
axisLib.add("commons-logging-1.1.jar"); //$NON-NLS-1$
axisLib.add("mail.jar"); //$NON-NLS-1$
axisLib.add("activation.jar"); //$NON-NLS-1$
}
/*
* (non-Javadoc)
*
* @see org.talend.repository.ui.wizards.exportjob.scriptsmanager.JobJavaScriptsManager#getExportResources
* (org.talend.repository.ui.wizards.exportjob.ExportFileResource[], java.util.Map, java.lang.String,
* java.lang.String, int, int, java.lang.String[])
*/
@Override
public List<ExportFileResource> getExportResources(ExportFileResource[] process, String... codeOptions)
throws ProcessorException {
List<ExportFileResource> list = new ArrayList<ExportFileResource>();
boolean needJob = true;
boolean needSource = isOptionChoosed(ExportChoice.needSourceCode);
boolean needContext = isOptionChoosed(ExportChoice.needContext);
ExportFileResource libResource = new ExportFileResource(null, "WEB-INF/lib"); //$NON-NLS-1$
ExportFileResource contextResource = new ExportFileResource(null, "WEB-INF/classes"); //$NON-NLS-1$
ExportFileResource srcResource = new ExportFileResource(null, "WEB-INF"); //$NON-NLS-1$
if (needJob) {
list.add(libResource);
}
if (needContext) {
list.add(contextResource);
}
if (needSource) {
list.add(srcResource);
}
copyServerConfigFileToTempDir();
// set export config mode now only to be sure that the libraries will be setup for an export mode, and not
// editor mode.
ProcessorUtilities.setExportConfig("java", "", ""); //$NON-NLS-1$
// Gets talend libraries
List<URL> talendLibraries = getExternalLibraries(true, process);
libResource.addResources(talendLibraries);
for (int i = 0; i < process.length; i++) {
ProcessItem processItem = (ProcessItem) process[i].getItem();
String selectedJobVersion = processItem.getProperty().getVersion();
if (!isMultiNodes() && this.getSelectedJobVersion() != null) {
selectedJobVersion = this.getSelectedJobVersion();
}
// generate the source files
String libPath = calculateLibraryPathFromDirectory(process[i].getDirectoryName());
// use character @ as temporary classpath separator, this one will be replaced during the export.
String standardJars = libPath + PATH_SEPARATOR + SYSTEMROUTINE_JAR + ProcessorUtilities.TEMP_JAVA_CLASSPATH_SEPARATOR
+ libPath + PATH_SEPARATOR + USERROUTINE_JAR + ProcessorUtilities.TEMP_JAVA_CLASSPATH_SEPARATOR + "."; //$NON-NLS-1$
ProcessorUtilities.setExportConfig("java", standardJars, libPath); //$NON-NLS-1$
if (!isOptionChoosed(ExportChoice.doNotCompileCode)) {
generateJobFiles(processItem, contextName, selectedJobVersion, statisticPort != IProcessor.NO_STATISTICS,
tracePort != IProcessor.NO_TRACES, isOptionChoosed(ExportChoice.applyToChildren), progressMonitor);
}
// generate the WSDL file
ExportFileResource wsdlFile = getWSDLFile(processItem, isOptionChoosed(ExportChoice.needWSDL), talendLibraries);
list.add(wsdlFile);
// edit the WSDD file
editWSDDFile(processItem);
// add children jobs
boolean needChildren = true;
addSubJobResources(process, processItem, needChildren, exportChoice, libResource, contextResource, srcResource,
selectedJobVersion);
// generate the context file
getContextScripts(processItem, needContext, contextResource, selectedJobVersion);
// generate jar file for job
libResource.addResources(getJobScripts(processItem, selectedJobVersion, needJob));
// dynamic db xml mapping
addXmlMapping(process[i], isOptionChoosed(ExportChoice.needSourceCode));
}
// generate Server Config file
ExportFileResource serverConfigFile = getServerConfigFile(isOptionChoosed(ExportChoice.needCONFIGFILE));
list.add(serverConfigFile);
// generate the WSDD file
ExportFileResource wsddFile = getWSDDFile(isOptionChoosed(ExportChoice.needWSDD));
list.add(wsddFile);
// generate the WEB-INFO folder
ExportFileResource webInfoFolder = getWebXMLFile(isOptionChoosed(ExportChoice.needWEBXML));
list.add(webInfoFolder);
// generate the META-INFO folder
ExportFileResource metaInfoFolder = genMetaInfoFolder(isOptionChoosed(ExportChoice.needMetaInfo));
list.add(metaInfoFolder);
// Gets system routines
List<URL> systemRoutineList = getSystemRoutine(process, true);
libResource.addResources(systemRoutineList);
// Gets user routines
List<URL> userRoutineList = getUserRoutine(process, true);
libResource.addResources(userRoutineList);
// Gets axis libraries
List<String> newAxisLib = new ArrayList<String>(axisLib);
for (URL libUrl : talendLibraries) {
if (libUrl.getFile() != null) {
newAxisLib.remove(new File(libUrl.getFile()).getName());
}
}
List<URL> axisLibList = getLib(newAxisLib, isOptionChoosed(ExportChoice.needAXISLIB));
libResource.addResources(axisLibList);
// check the list avoid duplication
return list;
}
private void addSubJobResources(ExportFileResource[] allResources, ProcessItem process, boolean needChildren,
Map<ExportChoice, Object> exportChoice, ExportFileResource libResource, ExportFileResource contextResource,
ExportFileResource srcResource, String selectedJobVersion) {
List<JobInfo> list = new ArrayList<JobInfo>();
String projectName = getCorrespondingProjectName(process);
if (needChildren) {
try {
List<ProcessItem> processedJob = new ArrayList<ProcessItem>();
getChildrenJobAndContextName(allResources, process.getProperty().getLabel(), list, process, projectName,
processedJob, srcResource, exportChoice, selectedJobVersion);
} catch (Exception e) {
ExceptionHandler.process(e);
}
}
for (Iterator<JobInfo> iter = list.iterator(); iter.hasNext();) {
JobInfo jobInfo = iter.next();
libResource.addResources(getJobScripts(projectName, jobInfo.getJobName(), jobInfo.getJobVersion(),
isOptionChoosed(ExportChoice.needJobScript)));
addContextScripts(jobInfo.getProcessItem(), jobInfo.getJobName(), jobInfo.getJobVersion(), contextResource,
isOptionChoosed(ExportChoice.needContext));
}
}
private void copyServerConfigFileToTempDir() {
final Bundle b = Platform.getBundle(RepositoryPlugin.PLUGIN_ID);
String sourceFileName;
try {
sourceFileName = FileLocator.toFileURL(FileLocator.find(b, new Path("resources/server-config.wsdd"), null)) //$NON-NLS-1$
.getFile();
String targetFileName = getTmpFolder() + PATH_SEPARATOR + "server-config.wsdd"; //$NON-NLS-1$
FilesUtils.copyFile(new File(sourceFileName), new File(targetFileName));
} catch (IOException e) {
ExceptionHandler.process(e);
}
}
protected void getContextScripts(ProcessItem processItem, Boolean needContext, ExportFileResource contextResource,
String version) {
String jobName = processItem.getProperty().getLabel();
addContextScripts(processItem, jobName, version, contextResource, needContext);
}
/**
* DOC x Comment method "genWSDLFolder".
*
* @param list
*/
private ExportFileResource getWSDLFile(ProcessItem processItem, Boolean needWSDL, List<URL> externalLibs) {
ExportFileResource wsdl = new ExportFileResource(null, "wsdl"); //$NON-NLS-1$
List<URL> wsdlUrlList = new ArrayList<URL>();
try {
String projectName = getCorrespondingProjectName(processItem);
String jobName = processItem.getProperty().getLabel();
String selectedProcessVersion = processItem.getProperty().getVersion();
if (!isMultiNodes() && this.getSelectedJobVersion() != null) {
selectedProcessVersion = this.getSelectedJobVersion();
}
String jobFolderName = JavaResourcesHelper.getJobFolderName(escapeFileNameSpace(processItem), selectedProcessVersion);
String classRoot = getClassRootLocation();
String wsdlFilePath = getTmpFolder() + PATH_SEPARATOR + jobName + ".wsdl"; //$NON-NLS-1$
String classFileName = classRoot + PATH_SEPARATOR + projectName + PATH_SEPARATOR + jobFolderName + PATH_SEPARATOR
+ jobName + ".class"; //$NON-NLS-1$
File classFile = new File(classFileName);
if (!classFile.exists()) {
return wsdl;
}
StringBuffer libPaths = new StringBuffer();
char pathSeparator = System.getProperty("path.separator").charAt(0); //$NON-NLS-1$
if (externalLibs != null) {
for (URL libUrl : externalLibs) {
libPaths.append(libUrl.getFile());
libPaths.append(pathSeparator);
}
}
TalendJava2WSDL.generateWSDL(new String[] { "-T1.2", "-yDOCUMENT", "-uLITERAL", "-o" + wsdlFilePath, "-d", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
"-lhttp://localhost:8080/" + jobName, "-nhttp://talend.org", "-X" + classRoot + pathSeparator + libPaths, //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
"-m" + EXPORT_METHOD, projectName + "." + jobFolderName + "." + jobName }); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
wsdlUrlList.add(new File(wsdlFilePath).toURL());
if (!needWSDL) {
return wsdl;
}
} catch (Throwable e) {
ExceptionHandler.process(e);
}
wsdl.addResources(wsdlUrlList);
return wsdl;
}
private ExportFileResource getWSDDFile(Boolean needWSDD) {
ExportFileResource wsdd = new ExportFileResource(null, "wsdd"); //$NON-NLS-1$
if (!needWSDD) {
return wsdd;
}
List<URL> wsddUrlList = new ArrayList<URL>();
try {
// String projectName = getCorrespondingProjectName(nullxxx);
String projectName = JavaResourcesHelper.getCurrentProjectName();
String deployFile = getTmpFolder() + PATH_SEPARATOR + projectName;
File file = new File(deployFile);
if (file.exists()) {
wsddUrlList.add(file.toURL());
}
} catch (Exception e) {
ExceptionHandler.process(e);
}
wsdd.addResources(wsddUrlList);
return wsdd;
}
private ExportFileResource getWebXMLFile(Boolean needWebXMLFile) {
// generate the web.xml file
ExportFileResource webInfo = new ExportFileResource(null, "WEB-INF"); //$NON-NLS-1$
if (!needWebXMLFile) {
return webInfo;
}
List<URL> urlList = new ArrayList<URL>();
final Bundle b = Platform.getBundle(RepositoryPlugin.PLUGIN_ID);
try {
URL webFileUrl = FileLocator.toFileURL(FileLocator.find(b, new Path("resources/web.xml"), null)); //$NON-NLS-1$
urlList.add(webFileUrl);
} catch (MalformedURLException e) {
ExceptionHandler.process(e);
} catch (IOException e) {
ExceptionHandler.process(e);
}
webInfo.addResources(urlList);
return webInfo;
}
/**
* DOC x Comment method "genWebInfoForder".
*
* @param list
*/
private void editWSDDFile(ProcessItem processItem) {
String projectName = getCorrespondingProjectName(processItem);
String selectedProcessVersion = processItem.getProperty().getVersion();
if (!isMultiNodes() && this.getSelectedJobVersion() != null) {
selectedProcessVersion = this.getSelectedJobVersion();
}
String jobFolderName = JavaResourcesHelper.getJobFolderName(escapeFileNameSpace(processItem), selectedProcessVersion);
String deployFileName = getTmpFolder() + PATH_SEPARATOR + projectName + PATH_SEPARATOR + jobFolderName + PATH_SEPARATOR
+ "deploy.wsdd"; //$NON-NLS-1$
String serverConfigFile = getTmpFolder() + PATH_SEPARATOR + "server-config.wsdd"; //$NON-NLS-1$
File deployFile = new File(deployFileName);
if (!deployFile.exists()) {
log.error(org.talend.repository.i18n.Messages.getString("JobJavaScriptsWSManager.errorMessage")); //$NON-NLS-1$
return;
}
// edit the server-config.wsdd file
try {
File wsddFile = new File(serverConfigFile);
BufferedReader reader = new BufferedReader(new FileReader(wsddFile));
SAXReader saxReader = new SAXReader();
Document doc = saxReader.read(reader);
BufferedReader wsdlreader = new BufferedReader(new FileReader(deployFile));
SAXReader wsdlsaxReader = new SAXReader();
Document wsdldoc = wsdlsaxReader.read(wsdlreader);
Element wsdlroot = wsdldoc.getRootElement();
Element element = wsdlroot.element("service"); //$NON-NLS-1$
List<Element> elements = element.elements("arrayMapping"); //$NON-NLS-1$
for (Element item : elements) {
Attribute attribute = item.attribute("qname"); //$NON-NLS-1$
item.remove(attribute);
attribute.setValue(attribute.getValue().replaceFirst(">", "")); //$NON-NLS-1$ //$NON-NLS-2$
item.add(attribute);
}
Element root = doc.getRootElement();
List<Node> content = root.content();
for (int i = 0; i < content.size(); i++) {
Node n = content.get(i);
if (n instanceof Element) {
if (n.getName().equals("transport")) { //$NON-NLS-1$
content.add(i - 1, element);
break;
}
}
}
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(serverConfigFile), "UTF-8")); //$NON-NLS-1$
OutputFormat format = OutputFormat.createPrettyPrint();
XMLWriter output = new XMLWriter(writer, format);
output.write(doc);
output.flush();
output.close();
} catch (Exception e) {
ExceptionHandler.process(e);
}
}
private ExportFileResource getServerConfigFile(Boolean needConfigFile) {
ExportFileResource webInfo = new ExportFileResource(null, "WEB-INF"); //$NON-NLS-1$
if (!needConfigFile) {
return webInfo;
}
String serverConfigFile = getTmpFolder() + PATH_SEPARATOR + "server-config.wsdd"; //$NON-NLS-1$
List<URL> urlList = new ArrayList<URL>();
try {
urlList.add(new File(serverConfigFile).toURL());
} catch (MalformedURLException e) {
ExceptionHandler.process(e);
}
webInfo.addResources(urlList);
return webInfo;
}
/**
* DOC x Comment method "genMetaInfoForder".
*
* @param list
* @return
*/
private ExportFileResource genMetaInfoFolder(Boolean needMetaInfo) {
ExportFileResource metaInfoResource = new ExportFileResource(null, "META-INF"); //$NON-NLS-1$
if (!needMetaInfo) {
return metaInfoResource;
}
// generate the MANIFEST.MF file in the temp folder
String manifestPath = getTmpFolder() + PATH_SEPARATOR + "MANIFEST.MF"; //$NON-NLS-1$
Manifest manifest = new Manifest();
Map<String, Attributes> m = manifest.getEntries();
Attributes a = new Attributes();
a.put(Attributes.Name.IMPLEMENTATION_VERSION, "1.0"); //$NON-NLS-1$
a.put(Attributes.Name.IMPLEMENTATION_VENDOR, "Talend Open Studio"); //$NON-NLS-1$
m.put("talendWebService", a); //$NON-NLS-1$
FileOutputStream fos = null;
try {
fos = new FileOutputStream(manifestPath);
manifest.write(fos);
} catch (FileNotFoundException e1) {
ExceptionHandler.process(e1);
} catch (IOException e1) {
ExceptionHandler.process(e1);
} finally {
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
ExceptionHandler.process(e);
}
}
}
List<URL> urlList = new ArrayList<URL>();
try {
urlList.add(new File(manifestPath).toURL());
} catch (MalformedURLException e) {
ExceptionHandler.process(e);
}
metaInfoResource.addResources(urlList);
return metaInfoResource;
}
/**
* DOC x Comment method "main".
*
* @param args
*/
static class TalendJava2WSDL extends Java2WSDL {
Throwable t = null;
public static void generateWSDL(String[] args) throws Throwable {
TalendJava2WSDL java2WSDL = new TalendJava2WSDL();
java2WSDL.run(args);
if (java2WSDL.t != null) {
throw new Throwable(java2WSDL.t);
}
}
/**
* run checks the command-line arguments and runs the tool.
*
* @param args String[] command-line arguments.
* @return
*/
protected int run(String[] args) {
// Parse the arguments
CLArgsParser argsParser = new CLArgsParser(args, options);
// Print parser errors, if any
if (null != argsParser.getErrorString()) {
System.err.println(Messages.getMessage("j2werror00", argsParser.getErrorString())); //$NON-NLS-1$
printUsage();
return (1);
}
// Get a list of parsed options
List clOptions = argsParser.getArguments();
int size = clOptions.size();
try {
// Parse the options and configure the emitter as appropriate.
for (int i = 0; i < size; i++) {
if (!parseOption((CLOption) clOptions.get(i))) {
return (1);
}
}
// validate argument combinations
if (!validateOptions()) {
return (1);
}
// Set the namespace map
if (!namespaceMap.isEmpty()) {
emitter.setNamespaceMap(namespaceMap);
}
TypeMappingRegistryImpl tmr = new TypeMappingRegistryImpl();
tmr.doRegisterFromVersion(typeMappingVersion);
emitter.setTypeMappingRegistry(tmr);
// Find the class using the name
emitter.setCls(className);
// Generate a full wsdl, or interface & implementation wsdls
if (wsdlImplFilename == null) {
emitter.emit(wsdlFilename, mode);
} else {
emitter.emit(wsdlFilename, wsdlImplFilename);
}
if (isDeploy) {
generateServerSide(emitter, (wsdlImplFilename != null) ? wsdlImplFilename : wsdlFilename);
}
// everything is good
return (0);
} catch (Throwable t) {
this.t = t;
return (1);
}
} // run
/*
* (non-Javadoc)
*
* @see org.apache.axis.wsdl.Java2WSDL#generateServerSide(org.apache.axis.wsdl.fromJava.Emitter,
* java.lang.String)
*/
@Override
protected void generateServerSide(Emitter j2w, String wsdlFileName) throws Exception {
org.apache.axis.wsdl.toJava.Emitter w2j = new org.apache.axis.wsdl.toJava.Emitter();
File wsdlFile = new File(wsdlFileName);
w2j.setServiceDesc(j2w.getServiceDesc());
w2j.setQName2ClassMap(j2w.getQName2ClassMap());
w2j.setOutputDir(wsdlFile.getParent());
w2j.setServerSide(true);
w2j.setHelperWanted(true);
// setup namespace-to-package mapping
String ns = j2w.getIntfNamespace();
String pkg = j2w.getCls().getPackage().getName();
w2j.getNamespaceMap().put(ns, pkg);
Map nsmap = j2w.getNamespaceMap();
if (nsmap != null) {
for (Iterator i = nsmap.keySet().iterator(); i.hasNext();) {
pkg = (String) i.next();
ns = (String) nsmap.get(pkg);
w2j.getNamespaceMap().put(ns, pkg);
}
}
// set 'deploy' mode
w2j.setDeploy(true);
if (j2w.getImplCls() != null) {
w2j.setImplementationClassName(j2w.getImplCls().getName());
} else {
if (!j2w.getCls().isInterface()) {
w2j.setImplementationClassName(j2w.getCls().getName());
} else {
throw new Exception(
org.talend.repository.i18n.Messages.getString("JobJavaScriptsWSManager.impClassNotSpecified")); //$NON-NLS-1$
}
}
// w2j.run(wsdlFileName);
// Note by xtan: in order to support the "jdk1.6.0_05"
w2j.run(wsdlFile.toURI().toString());
}
}
@Override
public void setTopFolder(List<ExportFileResource> resourcesToExport) {
return;
}
@Override
public String getOutputSuffix() {
return outputSuffix;
}
}