Package org.pomizer.application

Source Code of org.pomizer.application.Deployer

package org.pomizer.application;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.filefilter.TrueFileFilter;
import org.apache.commons.io.filefilter.WildcardFileFilter;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Node;
import org.pomizer.exception.ApplicationException;
import org.pomizer.model.DeployerCommandInfo;
import org.pomizer.model.DeployerProject;
import org.pomizer.model.DeployerResourceInfo;
import org.pomizer.model.DeployerSettings;
import org.pomizer.model.DeployerSourcesInfo;
import org.pomizer.model.IndexInfo;
import org.pomizer.util.DeployerProjectUtils;
import org.pomizer.util.IndexUtils;
import org.pomizer.util.JavaUtils;
import org.pomizer.util.StringUtils;
import org.pomizer.util.SvnUtils;
import org.pomizer.util.XmlUtils;
import org.pomizer.wrapper.DeployerChangeSet;

public class Deployer {
   
    private static String JAVA_FILE_EXTENSION = ".java";

    private static String CLASS_FILE_EXTENSION = ".class";
   
    private static String BACKUP_FILE_EXTENSION = ".bck";

    private static String BACKUP_FOLDER = "backup";
   
    public static void main(String[] args) {

        if (args.length < 1) {
            System.out.println("Application usage: <program> <path to configuration file>\n");
            System.exit(1);
        }

        String configurationFileName = args[0];
       
        JavaUtils.checkFileExists(configurationFileName);

        deployFiles(configurationFileName);
    }

    private static void deployFiles(final String configurationFileName) {
       
        try {
            JavaUtils.printToConsole("Loading configuration file...");
           
            Document configurationXmlDocument = XmlUtils.loadXmlDocumentWithValidation(configurationFileName,
                    "deployer.rng");
           
            DeployerSettings globalSettings = new DeployerSettings();
            List<DeployerProject> projects = new ArrayList<DeployerProject>();
            IndexInfo indeces = null;
            List<String> postProcessCallUrls = new ArrayList<String>();
            List<DeployerCommandInfo> postProcessCallCommands = new ArrayList<DeployerCommandInfo>();
           
            Map<String, Map<String, String>> jarsToDeploy =
                    new HashMap<String, Map<String, String>>();
            Map<String, List<String>> filesToDeploy = new HashMap<String, List<String>>();
            DeployerChangeSet changeset = new DeployerChangeSet(configurationFileName);
            changeset.load();
           
            DeployerProjectUtils.loadSettingsSection("/deployer/settings", configurationXmlDocument, globalSettings);
            DeployerProjectUtils.loadProjectsSection(projects, configurationXmlDocument, globalSettings);
            DeployerProjectUtils.loadCopySection(configurationXmlDocument, filesToDeploy);
            DeployerProjectUtils.loadPostProcessCallUrls(configurationXmlDocument, postProcessCallUrls);
            DeployerProjectUtils.loadPostProcessCommands(configurationXmlDocument, postProcessCallCommands);
           
            indeces = loadIndex(configurationXmlDocument, projects);
           
            JavaUtils.printToConsole("Processing changes...");
            processProjectChanges(projects, indeces, jarsToDeploy, filesToDeploy);
           
            final String backupFolder = FilenameUtils.concat(FilenameUtils.getFullPath(configurationFileName),
                    BACKUP_FOLDER);
            final File backupFolderFile = new File(backupFolder);
            FileUtils.forceMkdir(backupFolderFile);
           
            deployJars(jarsToDeploy, changeset, backupFolderFile);
            deployFiles(filesToDeploy, changeset, backupFolderFile);
            processUrls(postProcessCallUrls);
            processCommands(postProcessCallCommands, jarsToDeploy, filesToDeploy);
           
            JavaUtils.printToConsole("Finished");
        }
        catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static void processCommands(List<DeployerCommandInfo> postProcessCallCommands,
            Map<String, Map<String, String>> jarsToDeploy, Map<String, List<String>> filesToDeploy) throws IOException {
        JavaUtils.printToConsole("Executing commands...");
        for (DeployerCommandInfo commandInfo : postProcessCallCommands) {
           
            boolean foundUpdatePath = false;
            final String cannonicalUpdatePath = new File(commandInfo.onUpdatedPath).getCanonicalPath();
            for (String jar : jarsToDeploy.keySet()) {
                if (FilenameUtils.directoryContains(cannonicalUpdatePath, new File(jar).getCanonicalPath())) {
                    foundUpdatePath = true;
                    break;
                }
            }
           
            if (!foundUpdatePath) {
                for (String fileName : filesToDeploy.keySet()) {
                    for (int i = 0; i < filesToDeploy.get(fileName).size(); i++) {
                        String deploymentPath = filesToDeploy.get(fileName).get(i);
                        if (FilenameUtils.directoryContains(cannonicalUpdatePath,
                                new File(deploymentPath).getCanonicalPath())) {
                            foundUpdatePath = true;
                            break;
                        }
                    }
                }
                if (foundUpdatePath) {
                    break;
                }
            }
           
            if (foundUpdatePath) {
                JavaUtils.printToConsole("  command: " + commandInfo.commandLine);
                JavaUtils.executeCommand(commandInfo.commandLine);
            }
        }
    }

    private static void processUrls(List<String> postProcessCallUrls) throws IOException {
        JavaUtils.printToConsole("Calling URLs...");
        for (String url : postProcessCallUrls) {
            JavaUtils.printToConsole("  " + url + " ...");
            JavaUtils.downloadUrl(url);
        }
    }

    private static void deployFiles(final Map<String, List<String>> filesToDeploy, final DeployerChangeSet changeset,
            final File backupFolderFile) throws IOException {
       
        JavaUtils.printToConsole("Deploying files...");
        for (String changedFileName : filesToDeploy.keySet()) {
           
            final File changedFile = new File(changedFileName);
           
            if (changedFile.exists()) {
                for (String pathToDeploy : filesToDeploy.get(changedFileName)) {
                    JavaUtils.printToConsole(String.format("  file \"%s\" to \"%s\"...",
                            changedFileName, pathToDeploy));
                    final File pathToDeployFile = new File(pathToDeploy);
                    if (pathToDeployFile.exists()) {
                        getBackupFile(changeset, backupFolderFile, pathToDeploy);
                    }
                    else {
                        int position = changeset.indexOf(pathToDeploy);
                        if (-1 == position) {
                            changeset.add(pathToDeploy, "");
                            changeset.save();
                        }
                    }
                    FileUtils.copyFile(changedFile, pathToDeployFile);
                }
            }
            else {
                JavaUtils.printToConsole(String.format("  file \"%s\" doesn\'t exist...",
                        changedFileName));
            }
        }
    }

    private static void deployJars(final Map<String, Map<String, String>> jarsToDeploy,
            final DeployerChangeSet changeset, final File backupFolderFile) throws IOException {
       
        JavaUtils.printToConsole("Deploying jars...");
        for (String jar : jarsToDeploy.keySet()) {
            File backupFile = getBackupFile(changeset, backupFolderFile, jar);
           
            Map<String, List<String>> filesToAdd = new HashMap<String, List<String>>();
            for (String classPath : jarsToDeploy.get(jar).keySet()) {
                List<String> classNameWildcards = new ArrayList<String>();
                classNameWildcards.add(FilenameUtils.getBaseName(classPath) + CLASS_FILE_EXTENSION);
                classNameWildcards.add(FilenameUtils.getBaseName(classPath) + "$*" + CLASS_FILE_EXTENSION);
                String targetDirectory = JavaUtils.ensurePathHasSeparatorAtTheEnd(
                        jarsToDeploy.get(jar).get(classPath));
                String fullClassFileDirectory = FilenameUtils.concat(targetDirectory,
                        FilenameUtils.getFullPath(classPath));
                Collection<File> foundFiles = FileUtils.listFiles(new File(fullClassFileDirectory),
                        new WildcardFileFilter(classNameWildcards), null);
                if (!filesToAdd.containsKey(targetDirectory)) {
                    filesToAdd.put(targetDirectory, new ArrayList<String>());
                }
                for (File file : foundFiles) {
                    filesToAdd.get(targetDirectory).add(file.getAbsolutePath().substring(
                            targetDirectory.length()));
                }
            }
           
            JavaUtils.printToConsole(String.format("Deploying classes to \"%s\"...", jar));
            for (String basePath : filesToAdd.keySet()) {
                JavaUtils.printToConsole("  from path \"" + basePath + "\"");
                for (String addedFile : filesToAdd.get(basePath)) {
                    JavaUtils.printToConsole("    adding file \"" + addedFile + "\"...");
                }
            }
           
            final File tempJarFile = File.createTempFile("jar_temp_file_", null);
            tempJarFile.delete();
            FileUtils.copyFile(backupFile, tempJarFile);
            JavaUtils.addFilesToExistingZip(tempJarFile, filesToAdd);
            FileUtils.copyFile(tempJarFile, new File(jar));
            tempJarFile.delete();
        }
    }

    private static File getBackupFile(final DeployerChangeSet changeset, final File backupFolderFile,
            final String fileName) throws IOException {
        int position = changeset.indexOf(fileName);
        File backupFile;
        if (-1 == position) {
            backupFile = File.createTempFile(FilenameUtils.getName(fileName).replace('.', '_'+ '_',
                    BACKUP_FILE_EXTENSION, backupFolderFile);
            backupFile.delete();
            FileUtils.copyFile(new File(fileName), backupFile);
            changeset.add(fileName, backupFile.getAbsolutePath());
            changeset.save();
        }
        else {
            backupFile = new File(changeset.getBackupPath(position));
        }
        return backupFile;
    }

    private static void processProjectChanges(final List<DeployerProject> projects, final IndexInfo indeces,
            final Map<String, Map<String, String>> jarsToDeploy, final Map<String, List<String>> filesToDeploy)
            throws IOException, DocumentException, ApplicationException {
       
        for (int i = 0; i < projects.size(); i++) {
           
            DeployerProject project = projects.get(i);
            List<String> changedFiles = new ArrayList<String>();
            loadChangesetForProject(project.path, changedFiles);
           
            for (int j = 0; j < changedFiles.size(); j++) {
                processSourcesChanges(indeces, jarsToDeploy, project, changedFiles.get(j));
                processResourcesChanges(filesToDeploy, project, changedFiles.get(j));
            }
        }
    }

    private static void processSourcesChanges(IndexInfo indeces,
            Map<String, Map<String, String>> jarsToDeploy, DeployerProject project,
            final String changedFileName) throws IOException {
       
        final File changedFile = new File(changedFileName);
        for (int i = 0; i < project.sources.size(); i++) {
            final DeployerSourcesInfo sourcesInfo = project.sources.get(i);
            String sourcesFullPath = FilenameUtils.concat(project.path, sourcesInfo.path);
            final File sourceFullDirectory = new File(sourcesFullPath);
       
            if (FileUtils.directoryContains(sourceFullDirectory, changedFile) &&
                    changedFileName.endsWith(JAVA_FILE_EXTENSION)) {
               
                sourcesFullPath = JavaUtils.ensurePathHasSeparatorAtTheEnd(sourcesFullPath);
               
                String targetPath = FilenameUtils.concat(project.path, sourcesInfo.binariesFolder);
                targetPath = JavaUtils.ensurePathHasSeparatorAtTheEnd(targetPath);
               
                String classPath = changedFileName.substring(sourcesFullPath.length(),
                        changedFileName.length() - JAVA_FILE_EXTENSION.length());
               
                List<String> deploymentJarsList = new ArrayList<String>(project.sources.get(i).deploymentPaths);
                if (project.settings.useIndex && (null != indeces)) {
                    String className = classPath.replace(File.separatorChar, '.');
                    IndexUtils.getJarsForClass(indeces, className, deploymentJarsList);
                }
               
                for (int j = 0; j < deploymentJarsList.size(); j++) {
                   
                    final String jarPath = deploymentJarsList.get(j);
                    if (!jarsToDeploy.containsKey(jarPath)) {
                        jarsToDeploy.put(jarPath, new HashMap<String, String>());
                    }
                    jarsToDeploy.get(jarPath).put(classPath, targetPath);
                    //TODO: Add here warning that adding two classPaths to the same JAR
                }
            }
        }
    }
   
    private static void processResourcesChanges(final Map<String, List<String>> filesToDeploy, final DeployerProject project,
            final String changedFile) throws IOException {
       
        for (int i = 0; i < project.resources.size(); i++) {
            final DeployerResourceInfo resourceInfo = project.resources.get(i);
            String resourceFullPath = FilenameUtils.concat(project.path, resourceInfo.path);
            if (JavaUtils.isFile(resourceFullPath)) {
                if (JavaUtils.isTheSamePath(resourceFullPath, changedFile)) {
                    for (int j = 0; j < resourceInfo.deploymentPaths.size(); j++) {
                       
                        if (!filesToDeploy.containsKey(changedFile)) {
                            filesToDeploy.put(changedFile, new ArrayList<String>());
                        }
                        filesToDeploy.get(changedFile).add(resourceInfo.deploymentPaths.get(j));
                    }
                }
            }
            else {
                resourceFullPath = JavaUtils.ensurePathHasSeparatorAtTheEnd(resourceFullPath);
                if (FilenameUtils.directoryContains(resourceFullPath, changedFile)) {
                    for (int j = 0; j < resourceInfo.deploymentPaths.size(); j++) {
                       
                        final String relativeResourcePath = changedFile.substring(resourceFullPath.length());
                        final String resourceDeploymentPath = FilenameUtils.concat(resourceInfo.deploymentPaths.get(j),
                                relativeResourcePath);
                       
                        if (!filesToDeploy.containsKey(changedFile)) {
                            filesToDeploy.put(changedFile, new ArrayList<String>());
                        }
                        filesToDeploy.get(changedFile).add(resourceDeploymentPath);
                    }
                }
            }
        }
    }

    @SuppressWarnings("rawtypes")
    private static void loadChangesetForProject(final String projectPath,
            final List<String> changedFiles) throws IOException, DocumentException, ApplicationException {
       
        Document projectChangeset = SvnUtils.getChangeset(projectPath);
        List changedFilesNodes = projectChangeset.selectNodes("/status/target/entry/@path");
        if (null != changedFilesNodes) {
            for (int i = 0; i < changedFilesNodes.size(); i++) {
                Node changedFilesNode = (Node)changedFilesNodes.get(i);
                final String changedFileName = FilenameUtils.concat(projectPath, changedFilesNode.getText());
                final File changedFile = new File(changedFileName);
               
                if (changedFile.exists()) {
                    if (changedFile.isDirectory()) {
                       
                       final Collection<File> files = FileUtils.listFiles(changedFile, TrueFileFilter.INSTANCE,
                               TrueFileFilter.INSTANCE);
                       for (File file : files) {
                           if (file.isFile()) {
                               changedFiles.add(file.getAbsolutePath());
                           }
                       }
                       
                    }
                    else {
                        changedFiles.add(changedFileName);
                    }
                }
            }
        }
    }

    private static IndexInfo loadIndex(final Document configurationXmlDocument, List<DeployerProject> projects) {
        IndexInfo indeces = null;
        boolean loadIndex = false;
        for (int i = 0; !loadIndex && (i < projects.size()); i++) {
            loadIndex = projects.get(i).settings.useIndex;
        }
       
        if (loadIndex) {
            final String indexFileName = XmlUtils.getChildNodeTrimmedText(
                    configurationXmlDocument.getRootElement(), "index");
            if (!StringUtils.isNullOrEmpty(indexFileName)) {
                indeces = IndexUtils.loadIndeces(indexFileName);
            }
        }
        return indeces;
    }

}
TOP

Related Classes of org.pomizer.application.Deployer

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.