All Downloads are FREE. Search and download functionalities are using the official Maven repository.

edu.sc.seis.launch4j.CreateLaunch4jXMLTask Maven / Gradle / Ivy

package edu.sc.seis.launch4j;

import java.io.File;
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.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.gradle.api.DefaultTask;
import org.gradle.api.tasks.OutputFile;
import org.gradle.api.tasks.TaskAction;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

public class CreateLaunch4jXMLTask extends DefaultTask
{
    @OutputFile
    public File getXmlOutFile()
    {
        return ((Launch4jPluginExtension) getProject().getExtensions().getByName(Launch4jPlugin.LAUNCH4J_CONFIGURATION_NAME)).getXmlOutFileForProject(getProject());
    }

    @TaskAction
    public void writeXmlConfig() throws ParserConfigurationException, TransformerException
    {
        Launch4jPluginExtension cfg = (Launch4jPluginExtension) getProject().getExtensions().getByName("launch4j");

        File file = getXmlOutFile();
        file.getParentFile().mkdirs();

        DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
        DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
        Document doc = docBuilder.newDocument();

        Element root = doc.createElement("launch4jConfig");
        doc.appendChild(root);

        Element child;

        textElement(doc, root, "dontWrapJar",    cfg.getDontWrapJar());
        textElement(doc, root, "headerType",     cfg.getHeaderType());
        textElement(doc, root, "jar",            new File(cfg.getJar()).getAbsolutePath());
        textElement(doc, root, "outfile",        new File(cfg.getOutfile()).getAbsolutePath());
        textElement(doc, root, "errTitle",       cfg.getErrTitle());
        textElement(doc, root, "cmdLine",        cfg.getCmdLine());
        textElement(doc, root, "chdir",          cfg.getChdir());
        textElement(doc, root, "priority",       cfg.getPriority());
        textElement(doc, root, "downloadUrl",    cfg.getDownloadUrl());
        textElement(doc, root, "supportUrl",     cfg.getSupportUrl());
        textElement(doc, root, "customProcName", cfg.getCustomProcName());
        textElement(doc, root, "stayAlive",      cfg.getStayAlive());
        textElement(doc, root, "manifest",       cfg.getManifest());
        textElement(doc, root, "icon",           cfg.getIcon());

        /*
        child = doc.createElement("classPath");
        {
            root.appendChild(child);
            textElement(doc, child, "icon", cfg.getIcon());
        }
        */

        child = doc.createElement("versionInfo");
        {
            String originalFilename = ensureLength(46, new File(cfg.getOutfile()).getName());
            if (!originalFilename.endsWith(".exe")) originalFilename += ".exe";

            textElement(doc, child, "fileVersion",       ensureLength(20,  parseDotVersion(cfg.getVersion())));    //Max 20
            textElement(doc, child, "txtFileVersion",    ensureLength(50,  cfg.getVersion()));                     //Max 50
            textElement(doc, child, "fileDescription",   ensureLength(150, getProject().getName()));               //Max 150
            textElement(doc, child, "copyright",         ensureLength(20,  cfg.getCopyright()));                   //Max 150
            textElement(doc, child, "productVersion",    ensureLength(20,  parseDotVersion(cfg.getVersion())));    //Max 20
            textElement(doc, child, "txtProductVersion", ensureLength(50,  cfg.getVersion()));                     //Max 50
            textElement(doc, child, "productName",       ensureLength(150, getProject().getName()));               //Max 150
            textElement(doc, child, "internalName",      ensureLength(150, getProject().getName()));               //Max 50, Must NOT end in .exe
            textElement(doc, child, "originalFilename",  originalFilename);                                         //Max 50, Must end in .exe
        }

        child = doc.createElement("jre");
        {
            root.appendChild(child);
            textElement(doc, child, "path",               cfg.getBundledJrePath());
            textElement(doc, child, "minVersion",         cfg.getJreMinVersion());
            textElement(doc, child, "maxVersion",         cfg.getJreMaxVersion());
            textElement(doc, child, "opt",                cfg.getOpt());
            textElement(doc, child, "initialHeapSize",    cfg.getInitialHeapSize());
            textElement(doc, child, "initialHeapPercent", cfg.getInitialHeapPercent());
            textElement(doc, child, "maxHeapSize",        cfg.getMaxHeapSize());
            textElement(doc, child, "maxHeapPercent",     cfg.getMaxHeapPercent());
        }

        if (cfg.getMessagesStartupError() != null ||
            cfg.getMessagesBundledJreError() != null ||
            cfg.getMessagesJreVersionError() != null ||
            cfg.getMessagesLauncherError() != null)
        {
            child = doc.createElement("messages");
            {
                root.appendChild(child);
                textElement(doc, child, "startupErr",    cfg.getMessagesStartupError());
                textElement(doc, child, "bundledJreErr", cfg.getMessagesBundledJreError());
                textElement(doc, child, "jreVersionErr", cfg.getMessagesJreVersionError());
                textElement(doc, child, "launcherErr",   cfg.getMessagesLauncherError());
            }
        }

        if (cfg.getMutexName() != null || cfg.getWindowTitle() != null)
        {
            child = doc.createElement("singleInstance");
            {
                root.appendChild(child);
                textElement(doc, child, "mutexName", cfg.getMutexName());
                textElement(doc, child, "windowTitle", cfg.getWindowTitle());
            }
        }

        // now for writing it...

        // write the content into xml file
        TransformerFactory transformerFactory = TransformerFactory.newInstance();
        Transformer transformer = transformerFactory.newTransformer();
        transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no");
        transformer.setOutputProperty(OutputKeys.METHOD, "xml");
        transformer.setOutputProperty(OutputKeys.INDENT, "yes");
        transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
        transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");

        DOMSource source = new DOMSource(doc);
        StreamResult result = new StreamResult(file);
        //StreamResult result = new StreamResult(System.out);

        transformer.transform(source, result);
    }
    private String ensureLength(int maxLen, String value)
    {
        if (value.length() > maxLen) return value.substring(0, maxLen - 1);
        return value;
    }

    private void textElement(Document doc, Element parent, String name, Integer val)
    {
        if (val == null) return;
        textElement(doc, parent, name, val.toString());
    }
    private void textElement(Document doc, Element parent, String name, boolean val)
    {
        textElement(doc, parent, name, val ? "true" : "false");
    }
    private void textElement(Document doc, Element parent, String name, String val)
    {
        if (val == null || name == null || val.isEmpty())
            return;

        Element node = doc.createElement(name);

        node.appendChild(doc.createTextNode(val));

        if (parent != null)
            parent.appendChild(node);
    }

    private final Pattern VERSION1 = Pattern.compile("\\d+(\\.\\d+){3}");
    private final Pattern VERSION2 = Pattern.compile("\\d+(\\.\\d+){0,2}");

    /**
     * launch4j fileVersion and productVersion are required to be x.y.z.w format, no text like beta or
     * SNAPSHOT. I think this is a windows thing. So we check the version, and if it is only dots and
     * numbers, we use it. If not we use 0.0.0.1
     * @param version
     */
    private String parseDotVersion(String version)
    {
        if (VERSION1.matcher(version).matches())
        {
            return version;
        }
        else if (VERSION2.matcher(version).matches())
        {
            String s = version + ".0";
            while (VERSION2.matcher(s).matches())
            {
                s += ".0";
            }
            return s;
        }
        else
        {
            return "0.0.0.1";
        }
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy