blob: ece9dbd2f612b3556410e349ab10b5b556e5e878 [file] [log] [blame]
/*
* Copyright 2006 ProductiveMe Inc.
* Copyright 2013 JetBrains s.r.o.
*
* Licensed 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 com.pme.launcher;
import org.apache.sanselan.ImageFormat;
import org.apache.sanselan.Sanselan;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.input.SAXBuilder;
import java.awt.image.BufferedImage;
import java.io.*;
import java.nio.charset.Charset;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @author yole
*/
public class LauncherGeneratorMain {
public static void main(String[] args) {
if (args.length != 5) {
System.err.println("Usage: LauncherGeneratorMain <template EXE file> <app info file> <resource.h file> <properties> <output>");
System.exit(1);
}
File template = new File(args[0]);
if (!template.exists()) {
System.err.println("Launcher template EXE file " + args[0] + " not found");
System.exit(2);
}
String appInfoFileName = args[1];
InputStream appInfoStream;
try {
appInfoStream = new FileInputStream(appInfoFileName);
}
catch (FileNotFoundException e) {
appInfoStream = LauncherGeneratorMain.class.getClassLoader().getResourceAsStream(appInfoFileName);
}
if (appInfoStream == null) {
System.err.println("Application info file " + appInfoFileName + " not found");
System.exit(3);
}
Document appInfo;
try {
appInfo = new SAXBuilder().build(appInfoStream);
} catch (Exception e) {
System.err.println("Error loading application info file " + appInfoFileName + ": " + e.getMessage());
System.exit(4);
return;
}
Element appInfoRoot = appInfo.getRootElement();
String splashUrl = appInfoRoot.getChild("logo").getAttributeValue("url");
if (splashUrl.startsWith("/")) {
splashUrl = splashUrl.substring(1);
}
InputStream splashStream = LauncherGeneratorMain.class.getClassLoader().getResourceAsStream(splashUrl);
if (splashStream == null) {
System.err.println("Splash screen image file file " + splashUrl + " not found");
System.exit(5);
}
ByteArrayOutputStream splashBmpStream = new ByteArrayOutputStream();
try {
BufferedImage bufferedImage = Sanselan.getBufferedImage(splashStream);
Sanselan.writeImage(bufferedImage, splashBmpStream, ImageFormat.IMAGE_FORMAT_BMP, new HashMap());
}
catch (Exception e) {
System.err.println("Error converting splash screen to BMP: " + e.getMessage());
System.exit(6);
}
String icoUrl = appInfoRoot.getChild("icon").getAttributeValue("ico");
if (icoUrl == null) {
System.err.println(".ico file URL not specified in application info file " + appInfoFileName);
System.exit(11);
}
InputStream iconStream = LauncherGeneratorMain.class.getClassLoader().getResourceAsStream(icoUrl);
if (iconStream == null) {
System.err.println(".ico file " + icoUrl + " not found");
System.exit(12);
}
Map<String, Integer> resourceIDs;
try {
resourceIDs = loadResourceIDs(args[2]);
}
catch (Exception e) {
System.err.println("Error loading resource.h: " + e.getMessage());
System.exit(7);
return;
}
Properties properties = new Properties();
try {
FileInputStream fis = new FileInputStream(args[3]);
try {
properties.load(fis);
}
finally {
fis.close();
}
}
catch (IOException e) {
System.err.println("Error loading launcher properties: " + e.getMessage());
System.exit(8);
}
String companyName = appInfoRoot.getChild("company").getAttributeValue("name");
Element names = appInfoRoot.getChild("names");
String productShortName = names.getAttributeValue("product");
String productFullName = names.getAttributeValue("fullname");
Element versionElement = appInfoRoot.getChild("version");
int majorVersion = Integer.parseInt(versionElement.getAttributeValue("major"));
String minorVersionString = versionElement.getAttributeValue("minor");
Pattern p = Pattern.compile("(\\d+)(\\.(\\d+))?");
Matcher matcher = p.matcher(minorVersionString);
if (!matcher.matches()) {
System.err.println("Unexpected minor version format: " + minorVersionString);
}
int minorVersion = Integer.parseInt(matcher.group(1));
int bugfixVersion = matcher.group(3) != null ? Integer.parseInt(matcher.group(3)) : 0;
String buildNumber = appInfoRoot.getChild("build").getAttributeValue("number");
String versionString = "" + majorVersion + "." + minorVersion + "." + bugfixVersion + "." + buildNumber;
int year = new GregorianCalendar().get(Calendar.YEAR);
LauncherGenerator generator = new LauncherGenerator(template, new File(args[4]));
try {
generator.load();
for (Map.Entry<Object, Object> pair : properties.entrySet()) {
String key = (String) pair.getKey();
Integer id = resourceIDs.get(key);
if (id == null) {
System.err.println("Invalid stringtable ID found: " + key);
System.exit(9);
}
generator.setResourceString(id, (String) pair.getValue());
}
generator.injectBitmap(resourceIDs.get("IDB_SPLASH"), splashBmpStream.toByteArray());
generator.injectIcon(resourceIDs.get("IDI_WINLAUNCHER"), iconStream);
generator.setVersionInfoString("LegalCopyright", "Copyright (C) 2000-" + year + " " + companyName);
generator.setVersionInfoString("ProductName", productFullName);
generator.setVersionInfoString("FileVersion", versionString);
generator.setVersionInfoString("FileDescription", productFullName);
generator.setVersionInfoString("ProductVersion", versionString);
generator.setVersionInfoString("InternalName", productShortName.toLowerCase() + ".exe");
generator.setVersionInfoString("OriginalFilename", productShortName.toLowerCase() + ".exe");
generator.setVersionNumber(majorVersion, minorVersion, bugfixVersion);
generator.generate();
} catch (IOException e) {
e.printStackTrace();
System.exit(10);
}
}
private static Map<String, Integer> loadResourceIDs(String arg) throws IOException {
Map<String, Integer> result = new HashMap<String, Integer>();
BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(arg), Charset.forName("UTF-16")));
Pattern pattern = Pattern.compile("#define (\\w+)\\s+(\\d+)");
try {
while(true) {
String line = reader.readLine();
if (line == null) break;
Matcher m = pattern.matcher(line);
if (m.matches()) {
result.put(m.group(1), Integer.parseInt(m.group(2)));
}
}
}
finally {
reader.close();
}
return result;
}
}