Java tutorial
package org.eclipselabs.tycho.installer.plugin.win; import java.io.BufferedReader; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.Reader; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; import org.antlr.stringtemplate.StringTemplate; import org.antlr.stringtemplate.StringTemplateGroup; import org.antlr.stringtemplate.language.DefaultTemplateLexer; import org.apache.maven.plugin.logging.Log; import org.codehaus.plexus.util.FileUtils; import org.codehaus.plexus.util.cli.CommandLineException; import org.codehaus.plexus.util.cli.Commandline; import org.eclipselabs.tycho.installer.plugin.AbstractInstallerCreator; import org.eclipselabs.tycho.installer.plugin.InstallerConfig; import org.eclipselabs.tycho.installer.plugin.Product; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Charsets; import com.google.common.io.Closeables; import com.google.common.io.Files; import com.lowagie.text.Document; import com.lowagie.text.Paragraph; import com.lowagie.text.rtf.RtfWriter2; public class MsiInstallerCreator extends AbstractInstallerCreator { private final static List<String> COMMON_ARGS = Arrays.asList("-ext", "WixUIExtension", "-ext", "WixUtilExtension"); private StringTemplateGroup templateGroup; private StringTemplateGroup noLicenseTemplateGroup; public MsiInstallerCreator(Log log) { super(log); initTemplates(); } private void initTemplates() { templateGroup = initTemplate("product-wxs.stg"); noLicenseTemplateGroup = initTemplate("product-nolicense-wxs.stg"); } private StringTemplateGroup initTemplate(String template) { final InputStream inputStream = getClass().getResourceAsStream(template); if (inputStream == null) { throw new IllegalStateException("Error: " + template + " not found"); } try { final Reader reader = new BufferedReader(new InputStreamReader(inputStream, Charsets.UTF_8)); try { return new StringTemplateGroup(reader, DefaultTemplateLexer.class); } finally { Closeables.closeQuietly(reader); } } finally { Closeables.closeQuietly(inputStream); } } @Override public void verifyToolSetup() throws IllegalStateException { try { Commandline heatCmd = buildCmd("heat", Collections.<String>emptyList()); executeCmd(heatCmd, false); Commandline candleCmd = buildCmd("candle", Collections.<String>emptyList()); executeCmd(candleCmd, false); Commandline lightCmd = buildCmd("light", Collections.<String>emptyList()); executeCmd(lightCmd, false); } catch (CommandLineException e) { throw new IllegalStateException(e); } } @Override public void createInstaller(InstallerConfig config) throws Exception { File tempProductDir = Files.createTempDir(); FileUtils.copyDirectoryStructure(config.productDir, tempProductDir); File msiProductDir = new File(config.productDir.getParentFile(), "msi"); msiProductDir.mkdirs(); File productFilesWxsFile = new File(msiProductDir, config.installerName + "-files.wxs"); harvestDir(tempProductDir, false, "ProductFiles", "APPLICATIONROOTDIRECTORY", productFilesWxsFile); File productWxsFile = new File(msiProductDir, config.installerName + ".wxs"); boolean includeLicenseAgreement = !config.product.licenseText.equals(""); generateProductWxsFile(config.product, productWxsFile, includeLicenseAgreement); File licenseFile = null; if (includeLicenseAgreement) { licenseFile = createLicenseFile(msiProductDir, config.product.licenseText); } List<File> compiledWxsFiles = compileWxsFiles(productFilesWxsFile, productWxsFile); createMsiInstaller(config, tempProductDir, compiledWxsFiles, licenseFile); } private void harvestDir(File dir, boolean includeRootDir, String componentGroup, String directoryRef, File outFile) throws CommandLineException { List<String> args = new ArrayList<String>(); Collections.addAll(args, "dir", dir.getAbsolutePath()); Collections.addAll(args, "-template", "fragment", "-gg", "-sfrag", "-scom", "-sreg"); if (!includeRootDir) args.add("-srd"); Collections.addAll(args, "-cg", componentGroup); Collections.addAll(args, "-dr", directoryRef); Collections.addAll(args, "-out", outFile.getAbsolutePath()); Commandline cmd = buildCmd("heat", args); executeCmd(cmd); } @VisibleForTesting void generateProductWxsFile(Product product, File productWxsFile, boolean includeLicenseAgreement) throws IOException { StringTemplate template = (includeLicenseAgreement ? templateGroup : noLicenseTemplateGroup) .getInstanceOf("productWxsFile"); template.setAttribute("product", product); FileOutputStream fileOutputStream = null; OutputStreamWriter outputStreamWriter = null; try { fileOutputStream = new FileOutputStream(productWxsFile); outputStreamWriter = new OutputStreamWriter(fileOutputStream, "UTF-8"); outputStreamWriter.append(template.toString()); } finally { Closeables.closeQuietly(outputStreamWriter); Closeables.closeQuietly(fileOutputStream); } } private List<File> compileWxsFiles(File... wxsFiles) throws CommandLineException { List<File> compiledFiles = new ArrayList<File>(); for (File wxsFile : wxsFiles) { String wxsName = wxsFile.getName(); String extension = FileUtils.getExtension(wxsName); String compiledName = wxsName.substring(0, wxsName.length() - extension.length()) + "wixobj"; File outFile = new File(wxsFile.getParentFile(), compiledName); compiledFiles.add(outFile); List<String> args = new ArrayList<String>(); Collections.addAll(args, "-sw1077", "-out", outFile.getAbsolutePath()); args.add(wxsFile.getAbsolutePath()); args.addAll(COMMON_ARGS); Commandline cmd = buildCmd("candle", args); executeCmd(cmd); } return compiledFiles; } private void createMsiInstaller(InstallerConfig config, File productDir, List<File> compiledWxsFiles, File licenseFile) throws Exception { List<String> args = new ArrayList<String>(); if (licenseFile != null) { args.add("-dWixUILicenseRtf=" + licenseFile.getAbsolutePath()); } Collections.addAll(args, "-out", new File(config.installerDir, config.installerName + ".msi").getAbsolutePath()); for (File compiledWxsFile : compiledWxsFiles) { args.add(compiledWxsFile.getAbsolutePath()); } args.addAll(COMMON_ARGS); Collections.addAll(args, "-sw1076", "-b", productDir.getAbsolutePath()); Commandline cmd = buildCmd("light", args); executeCmd(cmd); } private File createLicenseFile(File dir, String licenseText) throws Exception { File licenseFile = new File(dir, "license.rtf"); Document document = new Document(); FileOutputStream fileOutputStream = new FileOutputStream(licenseFile); try { RtfWriter2.getInstance(document, fileOutputStream); document.open(); document.add(new Paragraph(licenseText)); document.close(); } finally { Closeables.closeQuietly(fileOutputStream); } return licenseFile; } }