aboutsummaryrefslogtreecommitdiffstats
path: root/winery/org.eclipse.winery.generators.ia/src
diff options
context:
space:
mode:
authorhuangjian <huang.jian12@zte.com.cn>2016-08-31 16:47:33 +0800
committerhuangjian <huang.jian12@zte.com.cn>2016-08-31 16:47:33 +0800
commitfa49e78cc199526a9e33b59c5194f8e3bf0f0952 (patch)
tree3478e867a8f304266dbceca6e992cceca410ede4 /winery/org.eclipse.winery.generators.ia/src
parent159d40f0011559c8f82338b29dca1bffd700f2c8 (diff)
Add winery source code
Change-Id: I1c5088121d79b71098c3cba1996c6f784737532e Issue-id: TOSCA-49 Signed-off-by: huangjian <huang.jian12@zte.com.cn>
Diffstat (limited to 'winery/org.eclipse.winery.generators.ia/src')
-rw-r--r--winery/org.eclipse.winery.generators.ia/src/main/java/org/eclipse/winery/generators/ia/Generator.java393
-rw-r--r--winery/org.eclipse.winery.generators.ia/src/main/resources/template/java/AbstractIAService.java.template86
-rw-r--r--winery/org.eclipse.winery.generators.ia/src/main/resources/template/java/TemplateService.java.template17
-rw-r--r--winery/org.eclipse.winery.generators.ia/src/main/resources/template/project/README.txt61
-rw-r--r--winery/org.eclipse.winery.generators.ia/src/main/resources/template/project/pom.xml251
-rw-r--r--winery/org.eclipse.winery.generators.ia/src/main/resources/template/project/src/main/webapp/WEB-INF/beans.xml16
-rw-r--r--winery/org.eclipse.winery.generators.ia/src/main/resources/template/project/src/main/webapp/WEB-INF/web.xml33
-rw-r--r--winery/org.eclipse.winery.generators.ia/src/test/java/META-INF/MANIFEST.MF3
-rw-r--r--winery/org.eclipse.winery.generators.ia/src/test/java/org/eclipse/winery/generators/ia/Test.java148
9 files changed, 1008 insertions, 0 deletions
diff --git a/winery/org.eclipse.winery.generators.ia/src/main/java/org/eclipse/winery/generators/ia/Generator.java b/winery/org.eclipse.winery.generators.ia/src/main/java/org/eclipse/winery/generators/ia/Generator.java
new file mode 100644
index 0000000..571d42c
--- /dev/null
+++ b/winery/org.eclipse.winery.generators.ia/src/main/java/org/eclipse/winery/generators/ia/Generator.java
@@ -0,0 +1,393 @@
+/*******************************************************************************
+ * Copyright (c) 2013,2015 University of Stuttgart.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * and the Apache License 2.0 which both accompany this distribution,
+ * and are available at http://www.eclipse.org/legal/epl-v10.html
+ * and http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Contributors:
+ * Tobias Binz - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.winery.generators.ia;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.nio.charset.Charset;
+import java.nio.file.Files;
+import java.nio.file.OpenOption;
+import java.nio.file.Path;
+import java.nio.file.StandardCopyOption;
+import java.nio.file.StandardOpenOption;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+
+import org.apache.commons.compress.archivers.ArchiveEntry;
+import org.apache.commons.compress.archivers.ArchiveOutputStream;
+import org.apache.commons.compress.archivers.ArchiveStreamFactory;
+import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
+import org.apache.commons.compress.utils.IOUtils;
+import org.apache.commons.io.FileUtils;
+import org.eclipse.winery.model.tosca.TBoolean;
+import org.eclipse.winery.model.tosca.TInterface;
+import org.eclipse.winery.model.tosca.TOperation;
+import org.eclipse.winery.model.tosca.TParameter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class Generator {
+
+ private static final Logger logger = LoggerFactory.getLogger(Generator.class);
+
+ // Placeholder applicable for all files
+ public static final String PLACEHOLDER_JAVA_PACKAGE = "IA_PACKAGE";
+ public static final String PLACEHOLDER_NAMESPACE = "IA_NAMESPACE";
+ public static final String PLACEHOLDER_CLASS_NAME = "IA_CLASS_NAME";
+ public static final String PLACEHOLDER_IA_ARTIFACT_TEMPLATE_UPLOAD_URL = "IA_ARTIFACT_TEMPLATE_UPLOAD_URL";
+
+ // Placeholders in Java Service Files
+ public static final String PLACEHOLDER_GENERATED_WEBSERVICE_METHODS = "GENERATED_WEBSERVICE_METHODS";
+
+ // Template folder relative to resources folder in this project
+ public static final String TEMPLATE_PROJECT_FOLDER = "template/project";
+ public static final String TEMPLATE_JAVA_FOLDER = "template/java";
+
+ private static final String TEMPLATE_JAVA_ABSTRACT_IA_SERVICE = "AbstractIAService.java.template";
+ private static final String TEMPLATE_JAVA_TEMPLATE_SERVICE = "TemplateService.java.template";
+
+ private final TInterface tinterface;
+ private final File workingDir;
+ private final File outDir;
+ private final String name;
+ private final String javaPackage;
+ private final String namespace;
+ private final URL iaArtifactTemplateUploadUrl;
+
+
+ /**
+ * Creates a new IA Generator instance for the given {@link TInterface}.
+ *
+ * @param tinterface TOSCA interface to generate the IA for
+ * @param packageAndNamespace Package to be used for the generated Java
+ * code, e.g. 'org.opentosca.ia'. To generate the respective
+ * Namespace for the Web Service the components of the package
+ * are reverted, prepended with 'http://' and appended with '/'.
+ * This is provided by the user in a textfield in the Winery UI.
+ * @param iaArtifactTemplateUploadUrl The URL to which the generated IA
+ * should be posted.
+ * @param name unique and valid name to be used for the generated maven
+ * project name, java project name, class name, port type name.
+ * @param workingDir working directory to generate the files. This directory
+ * also will contain the ZIP file with the Eclipse project after
+ * generating it.
+ */
+ public Generator(TInterface tinterface, String packageAndNamespace, URL iaArtifactTemplateUploadUrl, String name, File workingDir) {
+ super();
+ this.tinterface = tinterface;
+ this.javaPackage = packageAndNamespace;
+ this.iaArtifactTemplateUploadUrl = iaArtifactTemplateUploadUrl;
+ this.name = name;
+ this.workingDir = new File(workingDir.getAbsolutePath() + File.separator + this.name);
+ this.outDir = new File(workingDir.getAbsolutePath());
+
+ if (this.workingDir.exists()) {
+ Generator.logger.error("Workdir " + this.workingDir + " already exits. This might lead to corrupted results if it is not empty!");
+ }
+
+ // Generate Namespace
+ String[] splitPkg = this.javaPackage.split("\\.");
+ String tmpNamespace = "http://";
+ for (int i = splitPkg.length - 1; i >= 0; i--) {
+ tmpNamespace += splitPkg[i];
+ // Add '.' if it is not the last iterations
+ if (i != 0) {
+ tmpNamespace += ".";
+ }
+ }
+ this.namespace = tmpNamespace += "/";
+ }
+
+ /**
+ * Generates the IA project.
+ *
+ * @return The ZIP file containing the maven/eclipse project to be
+ * downloaded by the user.
+ */
+ public File generateProject() {
+
+ try {
+ Path workingDirPath = this.workingDir.toPath();
+ Files.createDirectories(workingDirPath);
+
+ // directory to store the template files to generate the java files from
+ Path javaTemplateDir = workingDirPath.resolve("../java");
+ Files.createDirectories(javaTemplateDir);
+
+ // Copy template project and template java files
+ String s = this.getClass().getResource("").getPath();
+ if (s.contains("jar!")) {
+ Generator.logger.trace("we work on a jar file");
+ Generator.logger.trace("Location of the current class: {}", s);
+
+ // we have a jar file
+ // format: file:/location...jar!...path-in-the-jar
+ // we only want to have location :)
+ int excl = s.lastIndexOf("!");
+ s = s.substring(0, excl);
+ s = s.substring("file:".length());
+
+ try (JarFile jf = new JarFile(s);) {
+ Enumeration<JarEntry> entries = jf.entries();
+ while (entries.hasMoreElements()) {
+ JarEntry je = entries.nextElement();
+ String name = je.getName();
+ if (name.startsWith(Generator.TEMPLATE_PROJECT_FOLDER + "/") && (name.length() > (Generator.TEMPLATE_PROJECT_FOLDER.length() + 1))) {
+ // strip "template/" from the beginning to have paths without "template" starting relatively from the working dir
+ name = name.substring(Generator.TEMPLATE_PROJECT_FOLDER.length() + 1);
+ if (je.isDirectory()) {
+ // directory found
+ Path dir = workingDirPath.resolve(name);
+ Files.createDirectory(dir);
+ } else {
+ Path file = workingDirPath.resolve(name);
+ try (InputStream is = jf.getInputStream(je);) {
+ Files.copy(is, file, StandardCopyOption.REPLACE_EXISTING);
+ }
+ }
+ } else if (name.startsWith(Generator.TEMPLATE_JAVA_FOLDER + "/") && (name.length() > (Generator.TEMPLATE_JAVA_FOLDER.length() + 1))) {
+ if (!je.isDirectory()) {
+ // we copy the file directly into javaTemplateDir
+ File f = new File(name);
+ Path file = javaTemplateDir.resolve(f.getName());
+ try (InputStream is = jf.getInputStream(je);) {
+ Files.copy(is, file, StandardCopyOption.REPLACE_EXISTING);
+ }
+ }
+ }
+ }
+ }
+ } else {
+ // we're running in debug mode, we can work on the plain file system
+ File templateProjectDir = new File(this.getClass().getResource("/" + Generator.TEMPLATE_PROJECT_FOLDER).getFile());
+ FileUtils.copyDirectory(templateProjectDir, this.workingDir);
+
+ File javaTemplatesDir = new File(this.getClass().getResource("/" + Generator.TEMPLATE_JAVA_FOLDER).getFile());
+ FileUtils.copyDirectory(javaTemplatesDir, javaTemplateDir.toFile());
+ }
+
+ // Create Java Code Folder
+ String[] splitPkg = this.javaPackage.split("\\.");
+ String javaFolderString = this.workingDir.getAbsolutePath() + File.separator + "src" + File.separator + "main" + File.separator + "java";
+ for (int i = 0; i < splitPkg.length; i++) {
+ javaFolderString += File.separator + splitPkg[i];
+ }
+
+ // Copy TEMPLATE_JAVA_ABSTRACT_IA_SERVICE
+ Path templateAbstractIAService = javaTemplateDir.resolve(Generator.TEMPLATE_JAVA_ABSTRACT_IA_SERVICE);
+ File javaAbstractIAService = new File(javaFolderString + File.separator + "AbstractIAService.java");
+ Files.createDirectories(javaAbstractIAService.toPath().getParent());
+ Files.copy(templateAbstractIAService, javaAbstractIAService.toPath(), StandardCopyOption.REPLACE_EXISTING);
+
+ // Copy and rename TEMPLATE_JAVA_TEMPLATE_SERVICE
+ Path templateJavaService = javaTemplateDir.resolve(Generator.TEMPLATE_JAVA_TEMPLATE_SERVICE);
+ File javaService = new File(javaFolderString + File.separator + this.name + ".java");
+ Files.createDirectories(javaService.toPath().getParent());
+ Files.copy(templateJavaService, javaService.toPath(), StandardCopyOption.REPLACE_EXISTING);
+
+ this.generateJavaFile(javaService);
+ this.updateFilesRecursively(this.workingDir);
+ return this.packageProject();
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ return null;
+ }
+ }
+
+ private void generateJavaFile(File javaService) throws IOException {
+
+ // Generate methods
+ StringBuilder sb = new StringBuilder();
+
+ for (TOperation op : this.tinterface.getOperation()) {
+ // Annotations
+ sb.append("\t@WebMethod\n");
+ sb.append("\t@SOAPBinding\n");
+ sb.append("\t@Oneway\n");
+
+ // Signatur
+ String operationReturn = "void";
+ sb.append("\tpublic " + operationReturn + " " + op.getName() + "(\n");
+
+ // Parameter
+ boolean first = true;
+ if (op.getInputParameters() != null) {
+ for (TParameter parameter : op.getInputParameters().getInputParameter()) {
+ String parameterName = parameter.getName();
+
+ if (first) {
+ first = false;
+ sb.append("\t\t");
+ } else {
+ sb.append(",\n\t\t");
+ }
+
+ // Generate @WebParam
+ sb.append("@WebParam(name=\"" + parameterName + "\", targetNamespace=\"" + this.namespace + "\") ");
+
+ // Handle required and optional parameters using @XmlElement
+ if (parameter.getRequired().equals(TBoolean.YES)) {
+ sb.append("@XmlElement(required=true)");
+ } else {
+ sb.append("@XmlElement(required=false)");
+ }
+
+ sb.append(" String " + parameterName);
+ }
+ }
+ sb.append("\n\t) {\n");
+
+ // If there are output parameters we generate the respective HashMap
+ boolean outputParamsExist = (op.getOutputParameters() != null) && (!op.getOutputParameters().getOutputParameter().isEmpty());
+ if (outputParamsExist) {
+ sb.append("\t\t// This HashMap holds the return parameters of this operation.\n");
+ sb.append("\t\tfinal HashMap<String,String> returnParameters = new HashMap<String, String>();\n\n");
+ }
+
+ sb.append("\t\t// TODO: Implement your operation here.\n");
+
+ // Generate code to set output parameters
+ if (outputParamsExist) {
+ for (TParameter outputParam : op.getOutputParameters().getOutputParameter()) {
+ sb.append("\n\n\t\t// Output Parameter '" + outputParam.getName() + "' ");
+ if (outputParam.getRequired().equals(TBoolean.YES)) {
+ sb.append("(required)");
+ } else {
+ sb.append("(optional)");
+ }
+ sb.append("\n\t\t// TODO: Set " + outputParam.getName() + " parameter here.");
+ sb.append("\n\t\t// Do NOT delete the next line of code. Set \"\" as value if you want to return nothing or an empty result!");
+ sb.append("\n\t\treturnParameters.put(\"" + outputParam.getName() + "\", \"TODO\");");
+ }
+ sb.append("\n\n\t\tsendResponse(returnParameters);\n");
+ }
+
+ sb.append("\t}\n\n");
+ }
+
+ // Read file and replace placeholders
+ Charset cs = Charset.defaultCharset();
+ List<String> lines = new ArrayList<>();
+ for (String line : Files.readAllLines(javaService.toPath(), cs)) {
+ // Replace web service method
+ line = line.replaceAll(Generator.PLACEHOLDER_GENERATED_WEBSERVICE_METHODS, sb.toString());
+ lines.add(line);
+ }
+
+ // Write file
+ OpenOption[] options = new OpenOption[] {StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING};
+ Files.write(javaService.toPath(), lines, cs, options);
+ }
+
+ /**
+ * Iterates recursively through all the files in the project working
+ * directory and tries to replace the global placeholders.
+ *
+ * @param folderOrFile to start with
+ */
+ private void updateFilesRecursively(File folderOrFile) {
+ if (folderOrFile.isFile()) {
+
+ if (folderOrFile.getAbsolutePath().endsWith(".jar")) {
+ return;
+ }
+
+ Generator.logger.trace("Updating file " + folderOrFile);
+
+ try {
+ // Read file and replace placeholders
+ Charset cs = Charset.defaultCharset();
+ List<String> lines = new ArrayList<>();
+ for (String line : Files.readAllLines(folderOrFile.toPath(), cs)) {
+ line = line.replaceAll(Generator.PLACEHOLDER_CLASS_NAME, this.name);
+ line = line.replaceAll(Generator.PLACEHOLDER_JAVA_PACKAGE, this.javaPackage);
+ line = line.replaceAll(Generator.PLACEHOLDER_NAMESPACE, this.namespace);
+ line = line.replaceAll(Generator.PLACEHOLDER_IA_ARTIFACT_TEMPLATE_UPLOAD_URL, this.iaArtifactTemplateUploadUrl.toString());
+ lines.add(line);
+ }
+
+ // Write file
+ OpenOption[] options = new OpenOption[] {StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING};
+ Files.write(folderOrFile.toPath(), lines, cs, options);
+
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+
+ } else {
+ Generator.logger.trace("Updating folder " + folderOrFile);
+ for (File childFile : folderOrFile.listFiles()) {
+ this.updateFilesRecursively(childFile);
+ }
+ }
+ }
+
+ /**
+ * Packages the generated project into a ZIP file which is stored in outDir
+ * and has the name of the Project.
+ *
+ * @return ZIP file
+ */
+ private File packageProject() {
+ try {
+ File packagedProject = new File(this.outDir.getAbsoluteFile() + File.separator + this.name + ".zip");
+ FileOutputStream fileOutputStream = new FileOutputStream(packagedProject);
+ final ArchiveOutputStream zos = new ArchiveStreamFactory().createArchiveOutputStream("zip", fileOutputStream);
+
+ this.addFilesRecursively(this.workingDir.getAbsoluteFile(), this.workingDir.getAbsoluteFile().getAbsolutePath() + File.separator, zos);
+
+ zos.finish();
+ zos.close();
+
+ return packagedProject;
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ /**
+ * Recursive Helper function for packageProject()
+ *
+ * @param folderOrFile to add into the archive
+ * @param baseDir
+ * @param zos ArchiveOutputStream to add the files to
+ */
+ private void addFilesRecursively(File folderOrFile, String baseDir, ArchiveOutputStream zos) {
+ if (folderOrFile.isFile()) {
+ String nameOfFileInZip = folderOrFile.getAbsolutePath().replace(baseDir, "");
+ Generator.logger.trace("Adding " + folderOrFile + " as " + nameOfFileInZip);
+ ArchiveEntry archiveEntry = new ZipArchiveEntry(nameOfFileInZip);
+ try (InputStream is = new FileInputStream(folderOrFile)) {
+ zos.putArchiveEntry(archiveEntry);
+ IOUtils.copy(is, zos);
+ zos.closeArchiveEntry();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ } else {
+ Generator.logger.trace("Adding folder " + folderOrFile);
+ for (File childFile : folderOrFile.listFiles()) {
+ this.addFilesRecursively(childFile, baseDir, zos);
+ }
+ }
+ }
+}
diff --git a/winery/org.eclipse.winery.generators.ia/src/main/resources/template/java/AbstractIAService.java.template b/winery/org.eclipse.winery.generators.ia/src/main/resources/template/java/AbstractIAService.java.template
new file mode 100644
index 0000000..4d4d2a4
--- /dev/null
+++ b/winery/org.eclipse.winery.generators.ia/src/main/resources/template/java/AbstractIAService.java.template
@@ -0,0 +1,86 @@
+package IA_PACKAGE;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map.Entry;
+
+import javax.annotation.Resource;
+import javax.xml.ws.WebServiceContext;
+
+import org.apache.cxf.headers.Header;
+import org.apache.cxf.helpers.CastUtils;
+import org.apache.cxf.jaxws.context.WrappedMessageContext;
+import org.apache.cxf.message.Message;
+import org.w3c.dom.Node;
+
+import org.eclipse.winery.highlevelrestapi.HighLevelRestApi;
+
+public abstract class AbstractIAService {
+
+ @Resource
+ private WebServiceContext context;
+
+ protected void sendResponse (HashMap<String,String> returnParameters) {
+
+ // Extract message
+ WrappedMessageContext wrappedContext = (WrappedMessageContext) context.getMessageContext();
+ Message message = wrappedContext.getWrappedMessage();
+
+ // Extract headers from message
+ List<Header> headers = CastUtils.cast((List<?>) message.get(Header.HEADER_LIST));
+
+ // Find ReplyTo and MessageID SOAP Header
+ String replyTo = null;
+ String messageID = null;
+ for (Header iter : headers) {
+
+ Object headerObject = iter.getObject();
+
+ // Unmarshall to org.w3c.dom.Node
+ if (headerObject instanceof Node) {
+ Node node = (Node) headerObject;
+ String localPart = iter.getName().getLocalPart();
+ String content = node.getTextContent();
+
+ // Extract ReplyTo Header value
+ if ("ReplyTo".equals(localPart)) {
+ replyTo = content;
+ }
+
+ // Extract MessageID Header value
+ if ("MessageID".equals(localPart)) {
+ messageID = content;
+ }
+ }
+ }
+
+ // Create asynchronous SOAP Response Message
+ StringBuilder builder = new StringBuilder();
+
+ builder.append("<soapenv:Envelope xmlns:soapenv='http://schemas.xmlsoap.org/soap/envelope/' xmlns:sch='http://siserver.org/schema'>");
+ builder.append(" <soapenv:Header/>");
+ builder.append(" <soapenv:Body>");
+ builder.append(" <sch:invokeResponse>");
+ builder.append(" <sch:MessageID>" + messageID + "</sch:MessageID>");
+
+ // Insert return parameters into asynchronous SOAP Response Message
+ for (Entry<String, String> paramIter : returnParameters.entrySet()) {
+
+ String key = paramIter.getKey();
+ String value = paramIter.getValue();
+
+ builder.append(" <" + key + ">" + value + "</" + key +">");
+ }
+
+ builder.append(" </sch:invokeResponse>");
+ builder.append(" </soapenv:Body>");
+ builder.append("</soapenv:Envelope>");
+
+ // Send SOAP Response Message back to requester
+ if(replyTo == null) {
+ System.err.println("No 'ReplyTo' header found!\nTherefore, reply message is printed here:\n" + builder.toString());
+ } else {
+ HighLevelRestApi.Post(replyTo, builder.toString(), "");
+ }
+ }
+}
diff --git a/winery/org.eclipse.winery.generators.ia/src/main/resources/template/java/TemplateService.java.template b/winery/org.eclipse.winery.generators.ia/src/main/resources/template/java/TemplateService.java.template
new file mode 100644
index 0000000..692905e
--- /dev/null
+++ b/winery/org.eclipse.winery.generators.ia/src/main/resources/template/java/TemplateService.java.template
@@ -0,0 +1,17 @@
+package IA_PACKAGE;
+
+import java.util.HashMap;
+
+import javax.jws.Oneway;
+import javax.jws.WebMethod;
+import javax.jws.WebParam;
+import javax.jws.WebService;
+import javax.jws.soap.SOAPBinding;
+import javax.xml.bind.annotation.XmlElement;
+
+@WebService
+public class IA_CLASS_NAME extends AbstractIAService {
+
+GENERATED_WEBSERVICE_METHODS
+
+} \ No newline at end of file
diff --git a/winery/org.eclipse.winery.generators.ia/src/main/resources/template/project/README.txt b/winery/org.eclipse.winery.generators.ia/src/main/resources/template/project/README.txt
new file mode 100644
index 0000000..bce220d
--- /dev/null
+++ b/winery/org.eclipse.winery.generators.ia/src/main/resources/template/project/README.txt
@@ -0,0 +1,61 @@
+###########################################################################
+GENERATED IMPLEMENTATION ARTIFACT SKELETON FOR IA_CLASS_NAME
+
+Interface Name: IA_CLASS_NAME
+Namespace: IA_NAMESPACE
+Java Package: IA_PACKAGE
+URL: IA_ARTIFACT_TEMPLATE_UPLOAD_URL../
+###########################################################################
+
+##### Preconditions
+To develop and build this Implementation Artifact you need Maven and Eclipse.
++ How to install maven is described at the end of this file
++ If you use an Eclipse workspace for the first time with a maven project you've to run this command before starting eclipse:
+ mvn -Declipse.workspace="<your_workspace_location>" eclipse:configure-workspace
+ - When using Windows: Make sure you replace '\' (backslashes) with '/' ('slashes')
+ - It doesn't hurt to run it multiple times
+ - This command must not be executed in a particular folder
+
+##### Preparations
++ Unzip the archive generated by Winery into a location of your choice.
++ Note: All following maven commands are executed on a shell in the root folder of the Implementation Artifact.
+
+##### Create eclipse project
+- Run: mvn eclipse:eclipse
+- Open Eclipse
+- 'File' -> 'Import' -> 'Existing Project into Workspace' -> click 'Next'
+- Click 'Browse' and select folder where you unzipped the generated Implementation Artifact
+- Select the project from the list and click 'Finish'
+
+##### Test your Implementation Artifact
+- Run: mvn clean package tomcat7:run-war
+ (more information: http://tomcat.apache.org/maven-plugin-trunk/tomcat7-maven-plugin/plugin-info.html)
+- Open this page to see the list of available services: http://localhost:9090/services/
+- This page also links the WSDL
+- With the WSDL your're able to test your IA using SOAPui or other tools.
+
+##### Upload your Implementation Artifact
+You have to options to do this:
+
+### 1) Automatically (to the Winery instance this IA project was generated with)
+- Run: mvn deploy
+- The WAR is directly uploaded into the correct ArtifactTemplate. Previous versions are overwritten.
+
+### 2) Manually
+- Run: mvn clean package
+- Locate the WAR file in the /target folder
+- Open Winery in your browser, locate the NodeType and then click through to the Implementation of the respective Interface, its Implementation Artifacts and lastly to the ArtifactTemplate representing this IA.
+- Upload the WAR file by clicking on the "Attach file..." button
+
+
+##### Install Maven
+- Download latest release of Maven: http://maven.apache.org/download.cgi (Binary zip)
+- Unzip into directory of your choice
+- Set environment variables (in system environment variables, not the ones for the user account):
+ + Check that the variables JAVA_HOME and JRE_HOME are set. If not create them and enter the path to your JDK, e.g., C:\Program Files (x86)\Java\jdk1.6.0_21
+ + Create the following environment variables
+ M2_HOME = C:\Path\where\your\maven\was\unzipped\to (no backslash at the end)
+ M2 = %M2_HOME%\bin
+ MAVEN_OPTS = -Xms256m -Xmx512m
+ + Append ;%M2% to the 'Path' environment variable. Make sure to separate the new entry with a semicolon (;) from the last one.
+- After that you have to open a new command line windows (if you already opened one) to let the changes take effect. \ No newline at end of file
diff --git a/winery/org.eclipse.winery.generators.ia/src/main/resources/template/project/pom.xml b/winery/org.eclipse.winery.generators.ia/src/main/resources/template/project/pom.xml
new file mode 100644
index 0000000..1a0b715
--- /dev/null
+++ b/winery/org.eclipse.winery.generators.ia/src/main/resources/template/project/pom.xml
@@ -0,0 +1,251 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>IA_PACKAGE</groupId>
+ <artifactId>IA_CLASS_NAME</artifactId>
+ <packaging>war</packaging>
+ <version>1.0-SNAPSHOT</version>
+ <name>Implementation Artifact IA_CLASS_NAME</name>
+
+ <repositories>
+ <repository>
+ <id>2471.de</id>
+ <url>http://2471.de/maven2</url>
+ </repository>
+ </repositories>
+
+ <properties>
+ <run.HttpPort>9090</run.HttpPort>
+ <winery.upload.url>IA_ARTIFACT_TEMPLATE_UPLOAD_URL</winery.upload.url>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ <cxf.version>2.7.6</cxf.version>
+ <highlevelrestapi.version>0.1.6</highlevelrestapi.version>
+ </properties>
+
+ <dependencies>
+ <!-- LIBRARIES ADDED FOR IMPLEMENTATION ARTIFACT IMPLEMENTATION -->
+
+
+ <!-- END - LIBRARIES ADDED FOR IMPLEMENTATION ARTIFACT IMPLEMENTATION -->
+
+ <dependency>
+ <groupId>org.eclipse.winery</groupId>
+ <artifactId>org.eclipse.winery.highlevelrestapi</artifactId>
+ <version>${highlevelrestapi.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.5</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-web</artifactId>
+ <version>3.0.7.RELEASE</version>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-context</artifactId>
+ <version>3.0.7.RELEASE</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.cxf</groupId>
+ <artifactId>cxf-rt-frontend-jaxws</artifactId>
+ <version>${cxf.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.cxf</groupId>
+ <artifactId>cxf-rt-frontend-simple</artifactId>
+ <version>${cxf.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.cxf</groupId>
+ <artifactId>cxf-rt-transports-http</artifactId>
+ <version>${cxf.version}</version>
+ </dependency>
+ </dependencies>
+ <build>
+ <finalName>IA_CLASS_NAME</finalName>
+ <plugins>
+ <plugin>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>3.0</version>
+ <configuration>
+ <source>1.6</source>
+ <target>1.6</target>
+ </configuration>
+ </plugin>
+
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-eclipse-plugin</artifactId>
+ <version>2.9</version>
+ <configuration>
+ <downloadSources>false</downloadSources>
+ <downloadJavadocs>true</downloadJavadocs>
+ </configuration>
+ </plugin>
+
+ <plugin>
+ <groupId>org.apache.cxf</groupId>
+ <artifactId>cxf-java2ws-plugin</artifactId>
+ <version>${cxf.version}</version>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.cxf</groupId>
+ <artifactId>cxf-rt-frontend-jaxws</artifactId>
+ <version>${cxf.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.cxf</groupId>
+ <artifactId>cxf-rt-frontend-simple</artifactId>
+ <version>${cxf.version}</version>
+ </dependency>
+ </dependencies>
+ <executions>
+ <execution>
+ <id>process-classes</id>
+ <phase>process-classes</phase>
+ <configuration>
+ <className>IA_PACKAGE.IA_CLASS_NAME</className>
+ <outputFile>${basedir}/src/main/webapp/wsdl/IA_CLASS_NAME.wsdl</outputFile>
+ <genWsdl>true</genWsdl>
+ <verbose>true</verbose>
+ </configuration>
+ <goals>
+ <goal>java2ws</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-war-plugin</artifactId>
+ <version>2.3</version>
+ <configuration>
+ <webXml>src/main/webapp/WEB-INF/web.xml</webXml>
+ </configuration>
+ </plugin>
+
+ <!-- Inspired by: http://giallone.blogspot.de/2013/02/post-file-to-web-page-as-part-of-maven.html -->
+ <plugin>
+ <groupId>org.codehaus.gmaven</groupId>
+ <artifactId>gmaven-plugin</artifactId>
+ <version>1.4</version>
+ <dependencies>
+ <dependency>
+ <groupId>org.codehaus.gmaven.runtime</groupId>
+ <artifactId>gmaven-runtime-1.7</artifactId>
+ <version>1.2</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.httpcomponents</groupId>
+ <artifactId>httpmime</artifactId>
+ <version>4.2.1</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.httpcomponents</groupId>
+ <artifactId>httpcore</artifactId>
+ <version>4.2.1</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.httpcomponents</groupId>
+ <artifactId>httpclient</artifactId>
+ <version>4.2.1</version>
+ </dependency>
+ </dependencies>
+ <executions>
+ <execution>
+ <id>upload2winery</id>
+ <!-- In this mvn phase... -->
+ <phase>deploy</phase>
+ <!-- ...run the execute goal of this plugin -->
+ <goals>
+ <goal>execute</goal>
+ </goals>
+ <configuration>
+ <providerSelection>1.7</providerSelection>
+ <source>
+ import org.apache.http.impl.client.DefaultHttpClient
+ import org.apache.http.client.methods.HttpPost
+ import org.apache.http.entity.mime.MultipartEntity
+ import org.apache.http.entity.mime.content.FileBody
+
+ // Get WAR file
+ def name = "target/${project.build.finalName}.war"
+ println "Archive file: $name"
+ def f = new File(name)
+
+ // POST file
+ DefaultHttpClient httpclient = new DefaultHttpClient()
+ println "Upload URL: ${winery.upload.url}"
+ def post = new HttpPost("${winery.upload.url}")
+ def entity = new MultipartEntity()
+ def fileBody = new FileBody(f)
+ entity.addPart("files[]", fileBody)
+ post.setEntity(entity)
+
+ // Process response
+ def response = httpclient.execute(post)
+ def status = response.getStatusLine()
+ if( !(status ==~ /.*Created.*/) )
+ fail("IA upload to Winery FAILED, please upload manually. (HTTP status code: $status)" )
+ else
+ println "IA upload finished sucessfully (HTTP status code $status)"
+ </source>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+
+ </plugins>
+
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.tomcat.maven</groupId>
+ <artifactId>tomcat7-maven-plugin</artifactId>
+ <version>2.1</version>
+ <configuration>
+ <!-- http port -->
+ <port>${run.HttpPort}</port>
+ <!-- application path always starts with / -->
+ <path>/</path>
+ <!-- if you want to use test dependencies rather than only runtime -->
+ <useTestClasspath>false</useTestClasspath>
+ </configuration>
+ </plugin>
+
+ <!-- Disable default install phase, because we don't install into maven
+ repo but into Winery (during deploy phase). -->
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-install-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>default-install</id>
+ <phase>none</phase>
+ </execution>
+ </executions>
+ </plugin>
+
+ <!-- Disable default deploy phase, because we don't deploy into remote
+ maven repo but into remote Winery. -->
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-deploy-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>default-deploy</id>
+ <phase>none</phase>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+
+ </build>
+</project> \ No newline at end of file
diff --git a/winery/org.eclipse.winery.generators.ia/src/main/resources/template/project/src/main/webapp/WEB-INF/beans.xml b/winery/org.eclipse.winery.generators.ia/src/main/resources/template/project/src/main/webapp/WEB-INF/beans.xml
new file mode 100644
index 0000000..2a926f2
--- /dev/null
+++ b/winery/org.eclipse.winery.generators.ia/src/main/resources/template/project/src/main/webapp/WEB-INF/beans.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxws="http://cxf.apache.org/jaxws"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd">
+ <import resource="classpath:META-INF/cxf/cxf.xml" />
+ <import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" />
+ <import resource="classpath:META-INF/cxf/cxf-servlet.xml" />
+ <jaxws:endpoint xmlns:tns="IA_NAMESPACE"
+ id="IA_CLASS_NAME" implementor="IA_PACKAGE.IA_CLASS_NAME"
+ wsdlLocation="wsdl/IA_CLASS_NAME.wsdl" endpointName="tns:IA_CLASS_NAMEPort"
+ serviceName="tns:IA_CLASS_NAMEService" address="/IA_CLASS_NAMEPort">
+ <jaxws:features>
+ <bean class="org.apache.cxf.feature.LoggingFeature" />
+ </jaxws:features>
+ </jaxws:endpoint>
+</beans>
diff --git a/winery/org.eclipse.winery.generators.ia/src/main/resources/template/project/src/main/webapp/WEB-INF/web.xml b/winery/org.eclipse.winery.generators.ia/src/main/resources/template/project/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 0000000..f7bd1bf
--- /dev/null
+++ b/winery/org.eclipse.winery.generators.ia/src/main/resources/template/project/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0">
+ <display-name>IA_CLASS_NAME</display-name>
+ <welcome-file-list>
+ <welcome-file>index.html</welcome-file>
+ <welcome-file>index.htm</welcome-file>
+ <welcome-file>index.jsp</welcome-file>
+ <welcome-file>default.html</welcome-file>
+ <welcome-file>default.htm</welcome-file>
+ <welcome-file>default.jsp</welcome-file>
+ </welcome-file-list>
+ <servlet>
+ <description>Apache CXF Endpoint</description>
+ <display-name>cxf</display-name>
+ <servlet-name>cxf</servlet-name>
+ <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
+ <load-on-startup>1</load-on-startup>
+ </servlet>
+ <servlet-mapping>
+ <servlet-name>cxf</servlet-name>
+ <url-pattern>/services/*</url-pattern>
+ </servlet-mapping>
+ <session-config>
+ <session-timeout>60</session-timeout>
+ </session-config>
+ <context-param>
+ <param-name>contextConfigLocation</param-name>
+ <param-value>WEB-INF/beans.xml</param-value>
+ </context-param>
+ <listener>
+ <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
+ </listener>
+</web-app>
diff --git a/winery/org.eclipse.winery.generators.ia/src/test/java/META-INF/MANIFEST.MF b/winery/org.eclipse.winery.generators.ia/src/test/java/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..254272e
--- /dev/null
+++ b/winery/org.eclipse.winery.generators.ia/src/test/java/META-INF/MANIFEST.MF
@@ -0,0 +1,3 @@
+Manifest-Version: 1.0
+Class-Path:
+
diff --git a/winery/org.eclipse.winery.generators.ia/src/test/java/org/eclipse/winery/generators/ia/Test.java b/winery/org.eclipse.winery.generators.ia/src/test/java/org/eclipse/winery/generators/ia/Test.java
new file mode 100644
index 0000000..73d4127
--- /dev/null
+++ b/winery/org.eclipse.winery.generators.ia/src/test/java/org/eclipse/winery/generators/ia/Test.java
@@ -0,0 +1,148 @@
+/*******************************************************************************
+ * Copyright (c) 2013 University of Stuttgart.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * and the Apache License 2.0 which both accompany this distribution,
+ * and are available at http://www.eclipse.org/legal/epl-v10.html
+ * and http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Contributors:
+ * Tobias Binz - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.winery.generators.ia;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.nio.file.Files;
+import java.nio.file.Path;
+
+import org.eclipse.winery.model.tosca.ObjectFactory;
+import org.eclipse.winery.model.tosca.TInterface;
+import org.eclipse.winery.model.tosca.TNodeType;
+import org.eclipse.winery.model.tosca.TOperation;
+import org.eclipse.winery.model.tosca.TOperation.InputParameters;
+import org.eclipse.winery.model.tosca.TOperation.OutputParameters;
+import org.eclipse.winery.model.tosca.TParameter;
+import org.junit.BeforeClass;
+
+public class Test {
+
+ private static Path WORKING_DIR;
+
+
+ @BeforeClass
+ public static void initializeWorkingDir() throws IOException {
+ Test.WORKING_DIR = Files.createTempDirectory("IAGenerator");
+ }
+
+ @org.junit.Test
+ public void testInOut() throws MalformedURLException {
+ ObjectFactory f = new ObjectFactory();
+
+ TInterface tinterface = f.createTInterface();
+ tinterface.setName("http://www.example.org/interfaces/lifecycle");
+
+ TOperation op1 = f.createTOperation();
+ op1.setName("Op1InOut");
+ tinterface.getOperation().add(op1);
+ InputParameters op1InputParameters = f.createTOperationInputParameters();
+
+ TParameter op1ip1 = f.createTParameter();
+ op1ip1.setName("op1ip1");
+ op1ip1.setType("xs:string");
+ op1InputParameters.getInputParameter().add(op1ip1);
+ TParameter op1ip2 = f.createTParameter();
+ op1ip2.setName("op1ip2");
+ op1ip2.setType("xs:string");
+ op1InputParameters.getInputParameter().add(op1ip2);
+ op1.setInputParameters(op1InputParameters);
+
+ OutputParameters op1OutputParameters = f.createTOperationOutputParameters();
+ TParameter op1op1 = f.createTParameter();
+ op1op1.setName("op1op1");
+ op1op1.setType("xs:string");
+ op1OutputParameters.getOutputParameter().add(op1op1);
+ TParameter op1op2 = f.createTParameter();
+ op1op2.setName("op1op2");
+ op1op1.setType("xs:string");
+ op1OutputParameters.getOutputParameter().add(op1op2);
+ op1.setOutputParameters(op1OutputParameters);
+
+ TNodeType nodeType = f.createTNodeType();
+ nodeType.setName("test");
+ nodeType.setTargetNamespace("http://asd.com");
+
+ Generator gen = new Generator(tinterface, "org.opentosca.ia", new URL("http://asd.com"), "testname", Test.WORKING_DIR.toFile());
+ File generateProject = gen.generateProject();
+ System.out.println(generateProject);
+ }
+
+ @org.junit.Test
+ public void testMultipleOperationsInOrOut() throws MalformedURLException {
+ ObjectFactory f = new ObjectFactory();
+
+ TInterface tinterface = f.createTInterface();
+ tinterface.setName("TestInOrOut");
+
+ TOperation opIn = f.createTOperation();
+ opIn.setName("OpIn");
+ tinterface.getOperation().add(opIn);
+
+ InputParameters op1InputParameters = f.createTOperationInputParameters();
+ TParameter op1ip1 = f.createTParameter();
+ op1ip1.setName("op1ip1");
+ op1ip1.setType("xs:string");
+ op1InputParameters.getInputParameter().add(op1ip1);
+ TParameter op1ip2 = f.createTParameter();
+ op1ip2.setName("op1ip2");
+ op1ip2.setType("xs:string");
+ op1InputParameters.getInputParameter().add(op1ip2);
+ opIn.setInputParameters(op1InputParameters);
+
+ TOperation opOut = f.createTOperation();
+ opOut.setName("OpOut");
+ tinterface.getOperation().add(opOut);
+
+ OutputParameters op1OutputParameters = f.createTOperationOutputParameters();
+ TParameter op1op1 = f.createTParameter();
+ op1op1.setName("op1op1");
+ op1op1.setType("xs:string");
+ op1OutputParameters.getOutputParameter().add(op1op1);
+ TParameter op1op2 = f.createTParameter();
+ op1op2.setName("op1op2");
+ op1op1.setType("xs:string");
+ op1OutputParameters.getOutputParameter().add(op1op2);
+ opOut.setOutputParameters(op1OutputParameters);
+
+ TNodeType nodeType = f.createTNodeType();
+ nodeType.setName("test");
+ nodeType.setTargetNamespace("http://asd.com");
+
+ Generator gen = new Generator(tinterface, "org.opentosca.ia", new URL("http://asd.com"), "testname", Test.WORKING_DIR.toFile());
+ File generateProject = gen.generateProject();
+ System.out.println(generateProject);
+ }
+
+ @org.junit.Test
+ public void testNoParams() throws MalformedURLException {
+ ObjectFactory f = new ObjectFactory();
+
+ TInterface tinterface = f.createTInterface();
+ tinterface.setName("TestNoParams");
+
+ TOperation opIn = f.createTOperation();
+ opIn.setName("OpNoParams");
+ tinterface.getOperation().add(opIn);
+
+ TNodeType nodeType = f.createTNodeType();
+ nodeType.setName("test");
+ nodeType.setTargetNamespace("http://asd.com");
+
+ Generator gen = new Generator(tinterface, "org.opentosca.ia", new URL("http://asd.com"), "testname", Test.WORKING_DIR.toFile());
+ File generateProject = gen.generateProject();
+ System.out.println(generateProject);
+ }
+
+}