de.egore911.versioning.deployer.Main.java Source code

Java tutorial

Introduction

Here is the source code for de.egore911.versioning.deployer.Main.java

Source

/*
 * Copyright 2013  Christoph Brill <egore911@gmail.com>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of
 * the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package de.egore911.versioning.deployer;

import java.io.File;
import java.io.IOException;
import java.net.ConnectException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.NumberFormat;
import java.util.Collection;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException;

import org.apache.commons.cli.BasicParser;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.filefilter.TrueFileFilter;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import de.egore911.versioning.deployer.performer.PerformCheckout;
import de.egore911.versioning.deployer.performer.PerformCopy;
import de.egore911.versioning.deployer.performer.PerformExtraction;
import de.egore911.versioning.deployer.performer.PerformReplacement;
import de.egore911.versioning.deployer.util.XmlHolder;

/**
 * @author Christoph Brill &lt;egore911@gmail.com&gt;
 */
public class Main {

    private static final Logger LOG = LoggerFactory.getLogger(Main.class);
    private static final NumberFormat PERCENT_FORMAT = NumberFormat.getNumberInstance();
    static {
        PERCENT_FORMAT.setMaximumFractionDigits(0);
    }

    public static void main(String[] args) throws IOException {

        Options options = new Options();
        options.addOption("help", false, "print this message");
        options.addOption("r", "replace-only", false,
                "only perform replacements (skip downloading, extracting, etc.)");

        CommandLine line;
        try {
            CommandLineParser parser = new BasicParser();
            line = parser.parse(options, args);
        } catch (ParseException e) {
            System.out.println("Wrong command line parameters:" + e.getMessage());
            showHelp(options);
            System.exit(1);
            return;
        }

        if (line.getArgs().length == 0) {
            LOG.error("Please pass at least one URL as one and only argument");
            System.exit(1);
            return;
        }

        for (String arg : line.getArgs()) {
            perform(arg, line);
        }
    }

    private static void perform(String arg, CommandLine line) throws IOException {
        URL url;
        try {
            url = new URL(arg);
        } catch (MalformedURLException e) {
            LOG.error("Invalid URI: {}", e.getMessage(), e);
            System.exit(1);
            return;
        }

        HttpURLConnection connection;
        try {
            connection = (HttpURLConnection) url.openConnection();
            int response = connection.getResponseCode();
            if (response != HttpURLConnection.HTTP_OK) {
                LOG.error("Could not download {}", url);
                connection.disconnect();
                System.exit(1);
                return;
            }
        } catch (ConnectException e) {
            LOG.error("Error during download from URI {}: {}", url, e.getMessage());
            System.exit(1);
            return;
        }

        XmlHolder xmlHolder = XmlHolder.getInstance();
        DocumentBuilder documentBuilder = xmlHolder.documentBuilder;
        XPath xPath = xmlHolder.xPath;

        try {

            XPathExpression serverNameXpath = xPath.compile("/server/name/text()");
            XPathExpression serverTargetdirXpath = xPath.compile("/server/targetdir/text()");
            XPathExpression serverDeploymentsDeploymentXpath = xPath.compile("/server/deployments/deployment");

            Document doc = documentBuilder.parse(connection.getInputStream());
            connection.disconnect();

            String serverName = (String) serverNameXpath.evaluate(doc, XPathConstants.STRING);
            LOG.info("Deploying {}", serverName);

            boolean shouldPerformCopy = !line.hasOption('r');
            PerformCopy performCopy = new PerformCopy(xPath);
            boolean shouldPerformExtraction = !line.hasOption('r');
            PerformExtraction performExtraction = new PerformExtraction(xPath);
            boolean shouldPerformCheckout = !line.hasOption('r');
            PerformCheckout performCheckout = new PerformCheckout(xPath);
            boolean shouldPerformReplacement = true;
            PerformReplacement performReplacement = new PerformReplacement(xPath);

            String targetdir = (String) serverTargetdirXpath.evaluate(doc, XPathConstants.STRING);
            FileUtils.forceMkdir(new File(targetdir));

            NodeList serverDeploymentsDeploymentNodes = (NodeList) serverDeploymentsDeploymentXpath.evaluate(doc,
                    XPathConstants.NODESET);
            int max = serverDeploymentsDeploymentNodes.getLength();
            for (int i = 0; i < serverDeploymentsDeploymentNodes.getLength(); i++) {
                Node serverDeploymentsDeploymentNode = serverDeploymentsDeploymentNodes.item(i);

                // Copy
                if (shouldPerformCopy) {
                    performCopy.perform(serverDeploymentsDeploymentNode);
                }

                // Extraction
                if (shouldPerformExtraction) {
                    performExtraction.perform(serverDeploymentsDeploymentNode);
                }

                // Checkout
                if (shouldPerformCheckout) {
                    performCheckout.perform(serverDeploymentsDeploymentNode);
                }

                // Replacement
                if (shouldPerformReplacement) {
                    performReplacement.perform(serverDeploymentsDeploymentNode);
                }

                logPercent(i + 1, max);
            }

            // validate that "${versioning:" is not present
            Collection<File> files = FileUtils.listFiles(new File(targetdir), TrueFileFilter.TRUE,
                    TrueFileFilter.INSTANCE);
            for (File file : files) {
                String content;
                try {
                    content = FileUtils.readFileToString(file);
                } catch (IOException e) {
                    continue;
                }
                if (content.contains("${versioning:")) {
                    LOG.error("{} contains placeholders even after applying the replacements",
                            file.getAbsolutePath());
                }
            }

            LOG.info("Done deploying {}", serverName);

        } catch (SAXException | IOException | XPathExpressionException e) {
            LOG.error("Error performing deployment: {}", e.getMessage(), e);
        }
    }

    private static void showHelp(Options options) {
        HelpFormatter formatter = new HelpFormatter();
        formatter.printHelp("versioning-deployer", options);
    }

    private static void logPercent(int i, int max) {
        int digits = Integer.toString(max).length();
        String percent = PERCENT_FORMAT.format(100f / max * i);
        LOG.info("{}/{} deployments, {}%", StringUtils.leftPad(Integer.toString(i), digits), max,
                StringUtils.leftPad(percent, 3));
    }
}