001: /*
002: Launch4j (http://launch4j.sourceforge.net/)
003: Cross-platform Java application wrapper for creating Windows native executables.
004:
005: Copyright (c) 2004, 2007 Grzegorz Kowal
006:
007: All rights reserved.
008:
009: Redistribution and use in source and binary forms, with or without modification,
010: are permitted provided that the following conditions are met:
011:
012: * Redistributions of source code must retain the above copyright notice,
013: this list of conditions and the following disclaimer.
014: * Redistributions in binary form must reproduce the above copyright notice,
015: this list of conditions and the following disclaimer in the documentation
016: and/or other materials provided with the distribution.
017: * Neither the name of the Launch4j nor the names of its contributors
018: may be used to endorse or promote products derived from this software without
019: specific prior written permission.
020:
021: THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
022: "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
023: LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
024: A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
025: CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
026: EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
027: PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
028: PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
029: LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
030: NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
031: SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
032: */
033:
034: /*
035: * Created on Apr 22, 2005
036: */
037: package net.sf.launch4j.config;
038:
039: import java.io.BufferedWriter;
040: import java.io.File;
041: import java.io.FileInputStream;
042: import java.io.FileReader;
043: import java.io.FileWriter;
044: import java.io.IOException;
045: import java.util.ArrayList;
046: import java.util.List;
047: import java.util.Properties;
048:
049: import net.sf.launch4j.Util;
050:
051: import com.thoughtworks.xstream.XStream;
052: import com.thoughtworks.xstream.io.xml.DomDriver;
053:
054: /**
055: * @author Copyright (C) 2005 Grzegorz Kowal
056: */
057: public class ConfigPersister {
058:
059: private static final ConfigPersister _instance = new ConfigPersister();
060:
061: private final XStream _xstream;
062: private Config _config;
063: private File _configPath;
064:
065: private ConfigPersister() {
066: _xstream = new XStream(new DomDriver());
067: _xstream.alias("launch4jConfig", Config.class);
068: _xstream.alias("classPath", ClassPath.class);
069: _xstream.alias("jre", Jre.class);
070: _xstream.alias("splash", Splash.class);
071: _xstream.alias("versionInfo", VersionInfo.class);
072:
073: _xstream.addImplicitCollection(Config.class, "headerObjects",
074: "obj", String.class);
075: _xstream.addImplicitCollection(Config.class, "libs", "lib",
076: String.class);
077: _xstream.addImplicitCollection(Config.class, "variables",
078: "var", String.class);
079: _xstream.addImplicitCollection(ClassPath.class, "paths", "cp",
080: String.class);
081: _xstream.addImplicitCollection(Jre.class, "options", "opt",
082: String.class);
083: }
084:
085: public static ConfigPersister getInstance() {
086: return _instance;
087: }
088:
089: public Config getConfig() {
090: return _config;
091: }
092:
093: public File getConfigPath() {
094: return _configPath;
095: }
096:
097: public File getOutputPath() throws IOException {
098: if (_config.getOutfile().isAbsolute()) {
099: return _config.getOutfile().getParentFile();
100: }
101: File parent = _config.getOutfile().getParentFile();
102: return (parent != null) ? new File(_configPath, parent
103: .getPath()) : _configPath;
104: }
105:
106: public File getOutputFile() throws IOException {
107: return _config.getOutfile().isAbsolute() ? _config.getOutfile()
108: : new File(getOutputPath(), _config.getOutfile()
109: .getName());
110: }
111:
112: public void createBlank() {
113: _config = new Config();
114: _config.setJre(new Jre());
115: _configPath = null;
116: }
117:
118: public void setAntConfig(Config c, File basedir) {
119: _config = c;
120: _configPath = basedir;
121: }
122:
123: public void load(File f) throws ConfigPersisterException {
124: try {
125: FileReader r = new FileReader(f);
126: char[] buf = new char[(int) f.length()];
127: r.read(buf);
128: r.close();
129: // Convert 2.x config to 3.x
130: String s = String
131: .valueOf(buf)
132: .replaceAll("<headerType>0<", "<headerType>gui<")
133: .replaceAll("<headerType>1<",
134: "<headerType>console<")
135: .replaceAll("jarArgs>", "cmdLine>")
136: .replaceAll("<jarArgs[ ]*/>", "<cmdLine/>")
137: .replaceAll("args>", "opt>")
138: .replaceAll("<args[ ]*/>", "<opt/>")
139: .replaceAll(
140: "<dontUsePrivateJres>false</dontUsePrivateJres>",
141: "<jdkPreference>"
142: + Jre.JDK_PREFERENCE_PREFER_JRE
143: + "</jdkPreference>")
144: .replaceAll(
145: "<dontUsePrivateJres>true</dontUsePrivateJres>",
146: "<jdkPreference>"
147: + Jre.JDK_PREFERENCE_JRE_ONLY
148: + "</jdkPreference>").replaceAll(
149: "<initialHeapSize>0</initialHeapSize>", "")
150: .replaceAll("<maxHeapSize>0</maxHeapSize>", "");
151: _config = (Config) _xstream.fromXML(s);
152: setConfigPath(f);
153: } catch (Exception e) {
154: throw new ConfigPersisterException(e);
155: }
156: }
157:
158: /**
159: * Imports launch4j 1.x.x config file.
160: */
161: public void loadVersion1(File f) throws ConfigPersisterException {
162: try {
163: Props props = new Props(f);
164: _config = new Config();
165: String header = props.getProperty(Config.HEADER);
166: _config
167: .setHeaderType(header == null
168: || header.toLowerCase().equals(
169: "guihead.bin") ? Config.GUI_HEADER
170: : Config.CONSOLE_HEADER);
171: _config.setJar(props.getFile(Config.JAR));
172: _config.setOutfile(props.getFile(Config.OUTFILE));
173: _config.setJre(new Jre());
174: _config.getJre().setPath(props.getProperty(Jre.PATH));
175: _config.getJre().setMinVersion(
176: props.getProperty(Jre.MIN_VERSION));
177: _config.getJre().setMaxVersion(
178: props.getProperty(Jre.MAX_VERSION));
179: String args = props.getProperty(Jre.ARGS);
180: if (args != null) {
181: List jreOptions = new ArrayList();
182: jreOptions.add(args);
183: _config.getJre().setOptions(jreOptions);
184: }
185: _config.setCmdLine(props.getProperty(Config.JAR_ARGS));
186: _config.setChdir("true".equals(props
187: .getProperty(Config.CHDIR)) ? "." : null);
188: _config.setCustomProcName("true".equals(props
189: .getProperty("setProcName"))); // 1.x
190: _config.setStayAlive("true".equals(props
191: .getProperty(Config.STAY_ALIVE)));
192: _config.setErrTitle(props.getProperty(Config.ERR_TITLE));
193: _config.setIcon(props.getFile(Config.ICON));
194: File splashFile = props.getFile(Splash.SPLASH_FILE);
195: if (splashFile != null) {
196: _config.setSplash(new Splash());
197: _config.getSplash().setFile(splashFile);
198: String waitfor = props.getProperty("waitfor"); // 1.x
199: _config.getSplash().setWaitForWindow(
200: waitfor != null && !waitfor.equals(""));
201: String splashTimeout = props
202: .getProperty(Splash.TIMEOUT);
203: if (splashTimeout != null) {
204: _config.getSplash().setTimeout(
205: Integer.parseInt(splashTimeout));
206: }
207: _config.getSplash().setTimeoutErr(
208: "true".equals(props
209: .getProperty(Splash.TIMEOUT_ERR)));
210: } else {
211: _config.setSplash(null);
212: }
213: setConfigPath(f);
214: } catch (IOException e) {
215: throw new ConfigPersisterException(e);
216: }
217: }
218:
219: public void save(File f) throws ConfigPersisterException {
220: try {
221: BufferedWriter w = new BufferedWriter(new FileWriter(f));
222: _xstream.toXML(_config, w);
223: w.close();
224: setConfigPath(f);
225: } catch (Exception e) {
226: throw new ConfigPersisterException(e);
227: }
228: }
229:
230: private void setConfigPath(File configFile) {
231: _configPath = configFile.getAbsoluteFile().getParentFile();
232: }
233:
234: private class Props {
235: final Properties _properties = new Properties();
236:
237: public Props(File f) throws IOException {
238: FileInputStream is = null;
239: try {
240: is = new FileInputStream(f);
241: _properties.load(is);
242: } finally {
243: Util.close(is);
244: }
245: }
246:
247: /**
248: * Get property and remove trailing # comments.
249: */
250: public String getProperty(String key) {
251: String p = _properties.getProperty(key);
252: if (p == null) {
253: return null;
254: }
255: int x = p.indexOf('#');
256: if (x == -1) {
257: return p;
258: }
259: do {
260: x--;
261: } while (x > 0
262: && (p.charAt(x) == ' ' || p.charAt(x) == '\t'));
263: return (x == 0) ? "" : p.substring(0, x + 1);
264: }
265:
266: public File getFile(String key) {
267: String value = getProperty(key);
268: return value != null ? new File(value) : null;
269: }
270: }
271: }
|