org.apache.syncope.installer.utilities.MavenUtils.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.syncope.installer.utilities.MavenUtils.java

Source

/*
 * 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.syncope.installer.utilities;

import com.izforge.izpack.panels.process.AbstractUIProcessHandler;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Properties;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.TransformerException;

import org.apache.commons.io.FileUtils;
import org.apache.maven.shared.invoker.DefaultInvocationRequest;
import org.apache.maven.shared.invoker.DefaultInvoker;
import org.apache.maven.shared.invoker.InvocationRequest;
import org.apache.maven.shared.invoker.InvocationResult;
import org.apache.maven.shared.invoker.Invoker;
import org.apache.maven.shared.invoker.MavenInvocationException;
import org.apache.maven.shared.invoker.PrintStreamHandler;
import org.apache.maven.shared.invoker.PrintStreamLogger;
import org.jasypt.commons.CommonUtils;
import org.jasypt.digest.StandardStringDigester;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.xml.sax.SAXException;

public class MavenUtils {

    private static final String MAVEN_HOME_PROPERTY = "maven.home";

    private final AbstractUIProcessHandler handler;

    public MavenUtils(final String mavenHomeDirectory, final AbstractUIProcessHandler handler) {
        if (System.getProperty(MAVEN_HOME_PROPERTY) == null || System.getProperty(MAVEN_HOME_PROPERTY).isEmpty()) {
            System.setProperty(MAVEN_HOME_PROPERTY, mavenHomeDirectory);
        }
        this.handler = handler;
    }

    public void archetypeGenerate(final String archetypeVersion, final String groupId, final String artifactId,
            final String secretKey, final String anonymousKey, final String jwsKey, final String adminPassword,
            final String installPath, final File customSettingsFile) {

        final InvocationRequest request = new DefaultInvocationRequest();
        request.setGoals(Collections.singletonList(archetypeVersion.contains("SNAPSHOT")
                ? "org.apache.maven.plugins:maven-archetype-plugin:2.4:generate"
                : "archetype:generate"));
        request.setBatchMode(true);
        final Properties properties = archetypeProperties(archetypeVersion, groupId, artifactId, secretKey,
                anonymousKey, jwsKey, adminPassword);
        request.setProperties(properties);
        if (customSettingsFile != null && FileUtils.sizeOf(customSettingsFile) > 0) {
            request.setUserSettingsFile(customSettingsFile);
        }
        logToHandler(request.getGoals(), properties);
        logToFile(request.getGoals(), properties);
        invoke(request, installPath);
    }

    private Properties archetypeProperties(final String archetypeVersion, final String groupId,
            final String artifactId, final String secretKey, final String anonymousKey, final String jwsKey,
            final String adminPassword) {

        final Properties properties = new Properties();
        properties.setProperty("archetypeGroupId", "org.apache.syncope");
        properties.setProperty("archetypeArtifactId", "syncope-archetype");
        properties.setProperty("archetypeRepository",
                archetypeVersion.contains("SNAPSHOT")
                        ? "http://repository.apache.org/content/repositories/snapshots"
                        : "http://repo1.maven.org/maven2");
        properties.setProperty("archetypeVersion", archetypeVersion);
        properties.setProperty("groupId", groupId);
        properties.setProperty("artifactId", artifactId);
        properties.setProperty("secretKey", secretKey);
        properties.setProperty("anonymousKey", anonymousKey);
        properties.setProperty("jwsKey", jwsKey);

        if (adminPassword != null) {
            StandardStringDigester digester = getDigester("S-SHA-256");
            String encodedPassword = digester.digest(adminPassword);
            properties.setProperty("adminPassword", encodedPassword);
        }
        properties.setProperty("version", "1.0-SNAPSHOT");
        return properties;
    }

    public void mvnCleanPackageWithProperties(final String path, final Properties properties,
            final File customSettingsFile) {

        final InvocationRequest request = new DefaultInvocationRequest();
        request.setProperties(properties);
        if (customSettingsFile != null && FileUtils.sizeOf(customSettingsFile) > 0) {
            request.setUserSettingsFile(customSettingsFile);
        }
        final List<String> mavenGoals = new ArrayList<>();
        mavenGoals.add("clean");
        mavenGoals.add("package");
        request.setGoals(mavenGoals);
        logToHandler(request.getGoals(), properties);
        logToFile(request.getGoals(), properties);
        invoke(request, path);
    }

    private void logToHandler(final List<String> goals, final Properties properties) {
        handler.logOutput("Executing maven command:", true);
        final StringBuilder mavenCommand = new StringBuilder("mvn ");
        for (final String goal : goals) {
            mavenCommand.append(goal).append(" ");
        }
        handler.logOutput(mavenCommand.toString(), true);
        for (final String propertyName : properties.stringPropertyNames()) {
            handler.logOutput("-D " + propertyName + "=" + properties.getProperty(propertyName), true);
        }
    }

    private void logToFile(final List<String> goals, final Properties properties) {
        InstallLog.getInstance().info("Executing maven command:");
        final StringBuilder mavenCommand = new StringBuilder("mvn ");
        for (final String goal : goals) {
            mavenCommand.append(goal).append(" ");
        }
        InstallLog.getInstance().info(mavenCommand.toString());
        for (final String propertyName : properties.stringPropertyNames()) {
            InstallLog.getInstance().info("-D " + propertyName + "=" + properties.getProperty(propertyName));
        }
    }

    private InvocationResult invoke(final InvocationRequest request, final String path) {
        InvocationResult result = null;
        final Invoker invoker = new DefaultInvoker();
        try {
            invoker.setLogger(
                    new PrintStreamLogger(new PrintStream(InstallLog.getInstance().getFileAbsolutePath()), 1000));
            invoker.setOutputHandler(
                    new PrintStreamHandler(new PrintStream(InstallLog.getInstance().getFileAbsolutePath()), true));
            invoker.setWorkingDirectory(new File(path));
            result = invoker.execute(request);
        } catch (MavenInvocationException | FileNotFoundException ex) {
            final String messageError = "Maven exception: " + ex.getMessage();
            handler.emitError(messageError, messageError);
            InstallLog.getInstance().info(messageError);
        }
        return result;
    }

    public static File createSettingsWithProxy(final String path, final String proxyHost, final String proxyPort,
            final String proxyUser, final String proxyPassword)
            throws IOException, ParserConfigurationException, TransformerException, SAXException {
        final File settingsXML = new File(System.getProperty(MAVEN_HOME_PROPERTY)
                + (System.getProperty(MAVEN_HOME_PROPERTY).endsWith("/") ? "conf/settings.xml"
                        : "/conf/settings.xml"));
        final File tempSettingsXML = new File(
                path + (path.endsWith("/") ? "settings_temp.xml" : "/settings_temp.xml"));
        if (settingsXML.canRead() && !tempSettingsXML.exists()) {
            tempSettingsXML.createNewFile();

            final DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            dbf.setFeature(javax.xml.XMLConstants.FEATURE_SECURE_PROCESSING, true);
            final DocumentBuilder builder = dbf.newDocumentBuilder();
            // parse settings.xml
            final Document settings = builder.parse(settingsXML);

            final Element proxies = (Element) settings.getDocumentElement().getElementsByTagName("proxies").item(0);

            final Element proxy = settings.createElement("proxy");

            final Element id = settings.createElement("id");
            final Element active = settings.createElement("active");
            final Element protocol = settings.createElement("protocol");
            final Element host = settings.createElement("host");
            final Element port = settings.createElement("port");
            final Element nonProxyHosts = settings.createElement("nonProxyHosts");
            id.appendChild(settings.createTextNode("optional"));
            active.appendChild(settings.createTextNode("true"));
            protocol.appendChild(settings.createTextNode("http"));
            host.appendChild(settings.createTextNode(proxyHost));
            port.appendChild(settings.createTextNode(proxyPort));
            proxy.appendChild(id);
            proxy.appendChild(active);
            proxy.appendChild(protocol);
            // create username and password tags only if required
            if (proxyUser != null && !proxyUser.isEmpty() && proxyPassword != null) {
                final Element username = settings.createElement("username");
                final Element password = settings.createElement("password");
                username.appendChild(settings.createTextNode(proxyUser));
                password.appendChild(settings.createTextNode(proxyPassword));
                proxy.appendChild(username);
                proxy.appendChild(password);
            }
            proxy.appendChild(host);
            proxy.appendChild(port);
            proxy.appendChild(nonProxyHosts);

            proxies.appendChild(proxy);

            FileSystemUtils.writeXML(settings, Files.newOutputStream(tempSettingsXML.toPath()));

        }
        return tempSettingsXML;
    }

    private static StandardStringDigester getDigester(final String cipherAlgorithm) {
        StandardStringDigester digester = new StandardStringDigester();

        if (cipherAlgorithm.startsWith("S-")) {
            // Salted ...
            digester.setAlgorithm(cipherAlgorithm.replaceFirst("S\\-", ""));
            digester.setIterations(1);
            digester.setSaltSizeBytes(8);
            digester.setInvertPositionOfPlainSaltInEncryptionResults(true);
            digester.setInvertPositionOfSaltInMessageBeforeDigesting(true);
            digester.setUseLenientSaltSizeCheck(true);
        } else {
            // Not salted ...
            digester.setAlgorithm(cipherAlgorithm);
            digester.setIterations(1);
            digester.setSaltSizeBytes(0);
        }

        digester.setStringOutputType(CommonUtils.STRING_OUTPUT_TYPE_HEXADECIMAL);
        return digester;
    }
}