blob: e56d06493f6e4b4c174eb67b44137d6fcb970c75 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2015 BSI Business Systems Integration AG.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* BSI Business Systems Integration AG - initial API and implementation
******************************************************************************/
package org.eclipse.scout.sdk.core.s.project;
import java.io.File;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Result;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Validate;
import org.eclipse.scout.sdk.core.s.util.MavenCliRunner;
import org.eclipse.scout.sdk.core.util.CoreUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
/**
* <h3>{@link ScoutProjectNewHelper}</h3>
*
* @author Matthias Villiger
* @since 5.2.0
*/
public final class ScoutProjectNewHelper {
public static final String SCOUT_ARCHETYPES_HELLOWORLD_VERSION = "5.2.0.M4";
public static final String SCOUT_ARCHETYPES_HELLOWORLD_ARTIFACT_ID = "scout-helloworld-app";
public static final String SCOUT_ARCHETYPES_GROUP_ID = "org.eclipse.scout.archetypes";
public static final Pattern DISPLAY_NAME_PATTERN = Pattern.compile("[^\"\\/<>=:]+");
public static final Pattern SYMBOLIC_NAME_PATTERN = Pattern.compile("^[a-z]{1}[a-z0-9_]{0,32}(\\.[a-z]{1}[a-z0-9_]{0,32}){0,16}$");
public static final String DEFAULT_JAVA_VERSION = "5.2.0.M4";
private ScoutProjectNewHelper() {
}
public static void createProject(File targetDirectory, String groupId, String artifactId, String displayName) throws IOException, GeneralSecurityException {
createProject(targetDirectory, groupId, artifactId, displayName, null);
}
public static void createProject(File targetDirectory, String groupId, String artifactId, String displayName, String javaVersion) throws IOException, GeneralSecurityException {
createProject(targetDirectory, groupId, artifactId, displayName, javaVersion, null, null, null);
}
public static void createProject(File targetDirectory, String groupId, String artifactId, String displayName, String javaVersion, String archetypeGroupId, String archeTypeArtifactId, String archetypeVersion)
throws IOException, GeneralSecurityException {
createProject(targetDirectory, groupId, artifactId, displayName, javaVersion, archetypeGroupId, archeTypeArtifactId, archetypeVersion, null, null);
}
public static void createProject(File targetDirectory, String groupId, String artifactId, String displayName, String javaVersion,
String archetypeGroupId, String archeTypeArtifactId, String archetypeVersion, String mavenGlobalSettings, String mavenSettings)
throws IOException, GeneralSecurityException {
// validate input
Validate.notNull(targetDirectory);
String groupIdMsg = getMavenNameErrorMessage(groupId, "groupId");
if (groupIdMsg != null) {
throw new IllegalArgumentException(groupIdMsg);
}
String artifactIdMsg = getMavenNameErrorMessage(artifactId, "artifactId");
if (artifactIdMsg != null) {
throw new IllegalArgumentException(artifactIdMsg);
}
String displayNameMsg = getDisplayNameErrorMEssage(displayName);
if (displayNameMsg != null) {
throw new IllegalArgumentException(displayNameMsg);
}
if (StringUtils.isEmpty(javaVersion)) {
javaVersion = DEFAULT_JAVA_VERSION;
}
if (StringUtils.isBlank(archetypeGroupId) || StringUtils.isBlank(archeTypeArtifactId) || StringUtils.isBlank(archetypeVersion)) {
// use default
archetypeGroupId = SCOUT_ARCHETYPES_GROUP_ID;
archeTypeArtifactId = SCOUT_ARCHETYPES_HELLOWORLD_ARTIFACT_ID;
archetypeVersion = SCOUT_ARCHETYPES_HELLOWORLD_VERSION;
}
String pck = null;
if (groupId.equals(artifactId)) {
pck = artifactId;
}
else {
pck = new StringBuilder(groupId).append('.').append(artifactId).toString();
}
// create command
String[] authKeysForWar = CoreUtils.generateKeyPair();
String[] authKeysForDev = CoreUtils.generateKeyPair();
String[] args = new String[]{"archetype:generate", "-B", "-X",
"-DarchetypeGroupId=" + archetypeGroupId, "-DarchetypeArtifactId=" + archeTypeArtifactId, "-DarchetypeVersion=" + archetypeVersion,
"-DgroupId=" + groupId, "-DartifactId=" + artifactId, "-Dversion=1.0.0-SNAPSHOT", "-Dpackage=" + pck,
"-DdisplayName=" + displayName, "-DscoutAuthPublicKey=" + authKeysForWar[1], "-DscoutAuthPrivateKey=" + authKeysForWar[0], "-DscoutAuthPublicKeyDev=" + authKeysForDev[1], "-DscoutAuthPrivateKeyDev=" + authKeysForDev[0],
"-DjavaVersion=" + javaVersion, "-DuserName=" + CoreUtils.getUsername(),
"-Dmaven.ext.class.path=''"};
// execute archetype generation
new MavenCliRunner().execute(targetDirectory, args, mavenGlobalSettings, mavenSettings);
postProcessRootPom(new File(targetDirectory, artifactId));
}
/**
* Workaround so that only the parent module is referenced in the root (remove non-parent modules)
*/
protected static void postProcessRootPom(File targetDirectory) throws IOException {
try {
File pom = new File(targetDirectory, "pom.xml");
if (!pom.isFile()) {
return;
}
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
Document doc = docBuilder.parse(pom);
Element modules = getFirstChildElement(doc.getDocumentElement(), "modules");
NodeList childNodes = modules.getChildNodes();
List<Node> nodesToRemove = new ArrayList<>();
for (int i = 0; i < childNodes.getLength(); i++) {
Node n = childNodes.item(i);
if (n.getNodeType() == Node.TEXT_NODE) {
nodesToRemove.add(n);
}
else if (n.getNodeType() == Node.ELEMENT_NODE && "module".equals(((Element) n).getTagName()) && !n.getTextContent().trim().endsWith(".parent")) {
nodesToRemove.add(n);
}
}
for (Node n : nodesToRemove) {
modules.removeChild(n);
}
writeDocument(doc, new StreamResult(pom));
}
catch (ParserConfigurationException | SAXException | TransformerException e) {
throw new IOException(e);
}
}
protected static void writeDocument(Document document, Result result) throws TransformerException {
TransformerFactory tf = TransformerFactory.newInstance();
Transformer transformer = tf.newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "no");
transformer.transform(new DOMSource(document), result);
}
protected static Element getFirstChildElement(Element parent, String tagName) {
NodeList children = parent.getElementsByTagName(tagName);
for (int i = 0; i < children.getLength(); ++i) {
Node n = children.item(i);
if (n.getNodeType() == Node.ELEMENT_NODE) {
return ((Element) n);
}
}
return null;
}
public static String getDisplayNameErrorMEssage(String displayNameCandidate) {
if (StringUtils.isEmpty(displayNameCandidate)) {
return "Display Name is not set.";
}
if (!DISPLAY_NAME_PATTERN.matcher(displayNameCandidate).matches()) {
return "The Display Name must not contain these characters: \\\"/<>:=";
}
return null;
}
public static String getMavenNameErrorMessage(String symbolicNameCandidate, String attribName) {
if (StringUtils.isEmpty(symbolicNameCandidate)) {
return attribName + " is not set.";
}
if (!SYMBOLIC_NAME_PATTERN.matcher(symbolicNameCandidate).matches()) {
return "The " + attribName + " value is not valid.";
}
// reserved java keywords
String jkw = getContainingJavaKeyWord(symbolicNameCandidate);
if (jkw != null) {
return "The " + attribName + " must not contain the Java keyword '" + jkw + "'.";
}
return null;
}
private static String getContainingJavaKeyWord(String s) {
for (String keyWord : CoreUtils.getJavaKeyWords()) {
if (s.startsWith(keyWord + ".") || s.endsWith("." + keyWord) || s.contains("." + keyWord + ".")) {
return keyWord;
}
}
return null;
}
}