001: /*******************************************************************************
002: * Copyright (c) 2005, 2006 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.pde.internal.build;
011:
012: import java.io.*;
013: import java.util.*;
014: import javax.xml.parsers.*;
015: import org.eclipse.core.runtime.*;
016: import org.eclipse.osgi.util.NLS;
017: import org.xml.sax.*;
018: import org.xml.sax.helpers.DefaultHandler;
019:
020: /**
021: *
022: * @since 3.1
023: */
024: public class ProductFile extends DefaultHandler implements
025: IPDEBuildConstants {
026: private final static SAXParserFactory parserFactory = SAXParserFactory
027: .newInstance();
028:
029: private static final String PROGRAM_ARGS = "programArgs"; //$NON-NLS-1$
030: private static final String PROGRAM_ARGS_LINUX = "programArgsLin"; //$NON-NLS-1$
031: private static final String PROGRAM_ARGS_MAC = "programArgsMac"; //$NON-NLS-1$
032: private static final String PROGRAM_ARGS_SOLARIS = "programArgsSol"; //$NON-NLS-1$
033: private static final String PROGRAM_ARGS_WIN = "programArgsWin"; //$NON-NLS-1$
034: private static final String VM_ARGS = "vmArgs"; //$NON-NLS-1$
035: private static final String VM_ARGS_LINUX = "vmArgsLin"; //$NON-NLS-1$
036: private static final String VM_ARGS_MAC = "vmArgsMac"; //$NON-NLS-1$
037: private static final String VM_ARGS_SOLARIS = "vmArgsSol"; //$NON-NLS-1$
038: private static final String VM_ARGS_WIN = "vmArgsWin"; //$NON-NLS-1$
039:
040: private static final String SOLARIS_LARGE = "solarisLarge"; //$NON-NLS-1$
041: private static final String SOLARIS_MEDIUM = "solarisMedium"; //$NON-NLS-1$
042: private static final String SOLARIS_SMALL = "solarisSmall"; //$NON-NLS-1$
043: private static final String SOLARIS_TINY = "solarisTiny"; //$NON-NLS-1$
044: private static final String WIN32_16_LOW = "winSmallLow"; //$NON-NLS-1$
045: private static final String WIN32_16_HIGH = "winSmallHigh"; //$NON-NLS-1$
046: private static final String WIN32_24_LOW = "win24Low"; //$NON-NLS-1$
047: private static final String WIN32_32_LOW = "winMediumLow"; //$NON-NLS-1$
048: private static final String WIN32_32_HIGH = "winMediumHigh"; //$NON-NLS-1$
049: private static final String WIN32_48_LOW = "winLargeLow"; //$NON-NLS-1$
050: private static final String WIN32_48_HIGH = "winLargeHigh"; //$NON-NLS-1$
051:
052: private static final String PRODUCT = "product"; //$NON-NLS-1$
053: private static final String CONFIG_INI = "configIni"; //$NON-NLS-1$
054: private static final String LAUNCHER = "launcher"; //$NON-NLS-1$
055: private static final String LAUNCHER_ARGS = "launcherArgs"; //$NON-NLS-1$
056: private static final String PLUGINS = "plugins"; //$NON-NLS-1$
057: private static final String FEATURES = "features"; //$NON-NLS-1$
058: private static final String SPLASH = "splash"; //$NON-NLS-1$
059: private static final String P_USE_ICO = "useIco"; //$NON-NLS-1$
060:
061: //These constants form a small state machine to parse the .product file
062: private static final int STATE_START = 0;
063: private static final int STATE_PRODUCT = 1;
064: private static final int STATE_LAUNCHER = 2;
065: private static final int STATE_LAUNCHER_ARGS = 3;
066: private static final int STATE_PLUGINS = 4;
067: private static final int STATE_FEATURES = 5;
068: private static final int STATE_PROGRAM_ARGS = 6;
069: private static final int STATE_PROGRAM_ARGS_LINUX = 7;
070: private static final int STATE_PROGRAM_ARGS_MAC = 8;
071: private static final int STATE_PROGRAM_ARGS_SOLARIS = 9;
072: private static final int STATE_PROGRAM_ARGS_WIN = 10;
073: private static final int STATE_VM_ARGS = 11;
074: private static final int STATE_VM_ARGS_LINUX = 12;
075: private static final int STATE_VM_ARGS_MAC = 13;
076: private static final int STATE_VM_ARGS_SOLARIS = 14;
077: private static final int STATE_VM_ARGS_WIN = 15;
078:
079: private int state = STATE_START;
080:
081: private SAXParser parser;
082: private String currentOS = null;
083: private boolean useIco = false;
084: private ArrayList result = new ArrayList(6);
085: private String launcherName = null;
086: private String icons[] = null;
087: private String configPath = null;
088: private String id = null;
089: private boolean useFeatures = false;
090: private List plugins = null;
091: private List fragments = null;
092: private List features = null;
093: private String splashLocation = null;
094: private String productName = null;
095: private String application = null;
096:
097: private Properties launcherArgs = new Properties();
098:
099: private static String normalize(String text) {
100: if (text == null || text.trim().length() == 0)
101: return ""; //$NON-NLS-1$
102:
103: text = text.replaceAll("\\r|\\n|\\f|\\t", " "); //$NON-NLS-1$ //$NON-NLS-2$
104: return text.replaceAll("\\s+", " "); //$NON-NLS-1$ //$NON-NLS-2$
105: }
106:
107: /**
108: * Constructs a feature parser.
109: */
110: public ProductFile(String location, String os) throws CoreException {
111: super ();
112: this .currentOS = os;
113: try {
114: parserFactory.setNamespaceAware(true);
115: parser = parserFactory.newSAXParser();
116: InputStream in = new BufferedInputStream(
117: new FileInputStream(location));
118: parser.parse(new InputSource(in), this );
119: } catch (ParserConfigurationException e) {
120: throw new CoreException(new Status(IStatus.ERROR,
121: PI_PDEBUILD, EXCEPTION_PRODUCT_FORMAT, NLS.bind(
122: Messages.exception_productParse, location),
123: e));
124: } catch (SAXException e) {
125: throw new CoreException(new Status(IStatus.ERROR,
126: PI_PDEBUILD, EXCEPTION_PRODUCT_FORMAT, NLS.bind(
127: Messages.exception_productParse, location),
128: e));
129: } catch (FileNotFoundException e) {
130: throw new CoreException(new Status(IStatus.ERROR,
131: PI_PDEBUILD, EXCEPTION_PRODUCT_FILE, NLS
132: .bind(Messages.exception_missingElement,
133: location), null));
134: } catch (IOException e) {
135: throw new CoreException(new Status(IStatus.ERROR,
136: PI_PDEBUILD, EXCEPTION_PRODUCT_FORMAT, NLS.bind(
137: Messages.exception_productParse, location),
138: e));
139: }
140: }
141:
142: public String getLauncherName() {
143: return launcherName;
144: }
145:
146: public List getPlugins() {
147: return getPlugins(true);
148: }
149:
150: public List getPlugins(boolean includeFragments) {
151: List p = plugins != null ? plugins : Collections.EMPTY_LIST;
152: if (!includeFragments)
153: return p;
154:
155: List f = fragments != null ? fragments : Collections.EMPTY_LIST;
156: int size = p.size() + f.size();
157: if (size == 0)
158: return Collections.EMPTY_LIST;
159:
160: List both = new ArrayList(size);
161: both.addAll(p);
162: both.addAll(f);
163: return both;
164: }
165:
166: public List getFragments() {
167: if (fragments == null)
168: return Collections.EMPTY_LIST;
169: return fragments;
170: }
171:
172: public List getFeatures() {
173: if (features == null)
174: return Collections.EMPTY_LIST;
175: return features;
176: }
177:
178: public boolean containsPlugin(String plugin) {
179: return (plugins != null && plugins.contains(plugin))
180: || (fragments != null && fragments.contains(plugin));
181: }
182:
183: /**
184: * Parses the specified url and constructs a feature
185: */
186: public String[] getIcons() {
187: if (icons != null)
188: return icons;
189: String[] temp = new String[result.size()];
190: int i = 0;
191: for (Iterator iter = result.iterator(); iter.hasNext();) {
192: String element = (String) iter.next();
193: if (element != null)
194: temp[i++] = element;
195: }
196: icons = new String[i];
197: System.arraycopy(temp, 0, icons, 0, i);
198: return icons;
199: }
200:
201: public String getConfigIniPath() {
202: return configPath;
203: }
204:
205: public String getId() {
206: return id;
207: }
208:
209: public String getSplashLocation() {
210: return splashLocation;
211: }
212:
213: public String getProductName() {
214: return productName;
215: }
216:
217: public String getApplication() {
218: return application;
219: }
220:
221: public boolean useFeatures() {
222: return useFeatures;
223: }
224:
225: public String getVMArguments(String os) {
226: String key = null;
227: if (os.equals(Platform.OS_WIN32)) {
228: key = VM_ARGS_WIN;
229: } else if (os.equals(Platform.OS_LINUX)) {
230: key = VM_ARGS_LINUX;
231: } else if (os.equals(Platform.OS_MACOSX)) {
232: key = VM_ARGS_MAC;
233: } else if (os.equals(Platform.OS_SOLARIS)) {
234: key = VM_ARGS_SOLARIS;
235: }
236:
237: String prefix = launcherArgs.getProperty(VM_ARGS);
238: String platform = null, args = null;
239: if (key != null)
240: platform = launcherArgs.getProperty(key);
241: if (prefix != null)
242: args = platform != null ? prefix + " " + platform : prefix; //$NON-NLS-1$
243: else
244: args = platform != null ? platform : ""; //$NON-NLS-1$
245: return normalize(args);
246: }
247:
248: public String getProgramArguments(String os) {
249: String key = null;
250: if (os.equals(Platform.OS_WIN32)) {
251: key = PROGRAM_ARGS_WIN;
252: } else if (os.equals(Platform.OS_LINUX)) {
253: key = PROGRAM_ARGS_LINUX;
254: } else if (os.equals(Platform.OS_MACOSX)) {
255: key = PROGRAM_ARGS_MAC;
256: } else if (os.equals(Platform.OS_SOLARIS)) {
257: key = PROGRAM_ARGS_SOLARIS;
258: }
259:
260: String prefix = launcherArgs.getProperty(PROGRAM_ARGS);
261: String platform = null, args = null;
262: if (key != null)
263: platform = launcherArgs.getProperty(key);
264: if (prefix != null)
265: args = platform != null ? prefix + " " + platform : prefix; //$NON-NLS-1$
266: else
267: args = platform != null ? platform : ""; //$NON-NLS-1$
268: return normalize(args);
269: }
270:
271: public void startElement(String uri, String localName,
272: String qName, Attributes attributes) {
273: switch (state) {
274: case STATE_START:
275: if (PRODUCT.equals(localName)) {
276: processProduct(attributes);
277: state = STATE_PRODUCT;
278: }
279: break;
280:
281: case STATE_PRODUCT:
282: if (CONFIG_INI.equals(localName)) {
283: processConfigIni(attributes);
284: } else if (LAUNCHER.equals(localName)) {
285: processLauncher(attributes);
286: state = STATE_LAUNCHER;
287: } else if (PLUGINS.equals(localName)) {
288: state = STATE_PLUGINS;
289: } else if (FEATURES.equals(localName)) {
290: state = STATE_FEATURES;
291: } else if (LAUNCHER_ARGS.equals(localName)) {
292: state = STATE_LAUNCHER_ARGS;
293: } else if (SPLASH.equals(localName)) {
294: splashLocation = attributes.getValue("location"); //$NON-NLS-1$
295: }
296: break;
297:
298: case STATE_LAUNCHER:
299: if (Platform.OS_SOLARIS.equals(localName)) {
300: processSolaris(attributes);
301: } else if ("win".equals(localName)) { //$NON-NLS-1$
302: processWin(attributes);
303: } else if (Platform.OS_LINUX.equals(localName)) {
304: processLinux(attributes);
305: } else if (Platform.OS_MACOSX.equals(localName)) {
306: processMac(attributes);
307: }
308: if ("ico".equals(localName)) { //$NON-NLS-1$
309: processIco(attributes);
310: } else if ("bmp".equals(localName)) { //$NON-NLS-1$
311: processBmp(attributes);
312: }
313: break;
314:
315: case STATE_LAUNCHER_ARGS:
316: if (PROGRAM_ARGS.equals(localName)) {
317: state = STATE_PROGRAM_ARGS;
318: } else if (PROGRAM_ARGS_LINUX.equals(localName)) {
319: state = STATE_PROGRAM_ARGS_LINUX;
320: } else if (PROGRAM_ARGS_MAC.equals(localName)) {
321: state = STATE_PROGRAM_ARGS_MAC;
322: } else if (PROGRAM_ARGS_SOLARIS.equals(localName)) {
323: state = STATE_PROGRAM_ARGS_SOLARIS;
324: } else if (PROGRAM_ARGS_WIN.equals(localName)) {
325: state = STATE_PROGRAM_ARGS_WIN;
326: } else if (VM_ARGS.equals(localName)) {
327: state = STATE_VM_ARGS;
328: } else if (VM_ARGS_LINUX.equals(localName)) {
329: state = STATE_VM_ARGS_LINUX;
330: } else if (VM_ARGS_MAC.equals(localName)) {
331: state = STATE_VM_ARGS_MAC;
332: } else if (VM_ARGS_SOLARIS.equals(localName)) {
333: state = STATE_VM_ARGS_SOLARIS;
334: } else if (VM_ARGS_WIN.equals(localName)) {
335: state = STATE_VM_ARGS_WIN;
336: }
337: break;
338:
339: case STATE_PLUGINS:
340: if ("plugin".equals(localName)) { //$NON-NLS-1$
341: processPlugin(attributes);
342: }
343: break;
344:
345: case STATE_FEATURES:
346: if ("feature".equals(localName)) { //$NON-NLS-1$
347: processFeature(attributes);
348: }
349: break;
350: }
351: }
352:
353: public void endElement(String uri, String localName, String qName) {
354: switch (state) {
355: case STATE_PLUGINS:
356: if (PLUGINS.equals(localName))
357: state = STATE_PRODUCT;
358: break;
359: case STATE_FEATURES:
360: if (FEATURES.equals(localName))
361: state = STATE_PRODUCT;
362: break;
363: case STATE_LAUNCHER_ARGS:
364: if (LAUNCHER_ARGS.equals(localName))
365: state = STATE_PRODUCT;
366: break;
367: case STATE_LAUNCHER:
368: if (LAUNCHER.equals(localName))
369: state = STATE_PRODUCT;
370: break;
371:
372: case STATE_PROGRAM_ARGS:
373: case STATE_PROGRAM_ARGS_LINUX:
374: case STATE_PROGRAM_ARGS_MAC:
375: case STATE_PROGRAM_ARGS_SOLARIS:
376: case STATE_PROGRAM_ARGS_WIN:
377: case STATE_VM_ARGS:
378: case STATE_VM_ARGS_LINUX:
379: case STATE_VM_ARGS_MAC:
380: case STATE_VM_ARGS_SOLARIS:
381: case STATE_VM_ARGS_WIN:
382: state = STATE_LAUNCHER_ARGS;
383: break;
384: }
385: }
386:
387: public void characters(char[] ch, int start, int length) {
388: switch (state) {
389: case STATE_PROGRAM_ARGS:
390: addLaunchArgumentToMap(PROGRAM_ARGS, String.valueOf(ch,
391: start, length));
392: break;
393: case STATE_PROGRAM_ARGS_LINUX:
394: addLaunchArgumentToMap(PROGRAM_ARGS_LINUX, String.valueOf(
395: ch, start, length));
396: break;
397: case STATE_PROGRAM_ARGS_MAC:
398: addLaunchArgumentToMap(PROGRAM_ARGS_MAC, String.valueOf(ch,
399: start, length));
400: break;
401: case STATE_PROGRAM_ARGS_SOLARIS:
402: addLaunchArgumentToMap(PROGRAM_ARGS_SOLARIS, String
403: .valueOf(ch, start, length));
404: break;
405: case STATE_PROGRAM_ARGS_WIN:
406: addLaunchArgumentToMap(PROGRAM_ARGS_WIN, String.valueOf(ch,
407: start, length));
408: break;
409: case STATE_VM_ARGS:
410: addLaunchArgumentToMap(VM_ARGS, String.valueOf(ch, start,
411: length));
412: break;
413: case STATE_VM_ARGS_LINUX:
414: addLaunchArgumentToMap(VM_ARGS_LINUX, String.valueOf(ch,
415: start, length));
416: break;
417: case STATE_VM_ARGS_MAC:
418: addLaunchArgumentToMap(VM_ARGS_MAC, String.valueOf(ch,
419: start, length));
420: break;
421: case STATE_VM_ARGS_SOLARIS:
422: addLaunchArgumentToMap(VM_ARGS_SOLARIS, String.valueOf(ch,
423: start, length));
424: break;
425: case STATE_VM_ARGS_WIN:
426: addLaunchArgumentToMap(VM_ARGS_WIN, String.valueOf(ch,
427: start, length));
428: break;
429: }
430: }
431:
432: private void addLaunchArgumentToMap(String key, String value) {
433: if (launcherArgs == null)
434: launcherArgs = new Properties();
435:
436: String oldValue = launcherArgs.getProperty(key);
437: if (oldValue != null)
438: launcherArgs.setProperty(key, oldValue + value);
439: else
440: launcherArgs.setProperty(key, value);
441: }
442:
443: private void processPlugin(Attributes attributes) {
444: String fragment = attributes.getValue("fragment"); //$NON-NLS-1$
445: if (fragment != null && new Boolean(fragment).booleanValue()) {
446: if (fragments == null)
447: fragments = new ArrayList();
448: fragments.add(attributes.getValue("id")); //$NON-NLS-1$
449: } else {
450: if (plugins == null)
451: plugins = new ArrayList();
452: plugins.add(attributes.getValue("id")); //$NON-NLS-1$
453: }
454: }
455:
456: private void processFeature(Attributes attributes) {
457: if (features == null)
458: features = new ArrayList();
459: features.add(attributes.getValue("id")); //$NON-NLS-1$
460: }
461:
462: private void processProduct(Attributes attributes) {
463: id = attributes.getValue("id"); //$NON-NLS-1$
464: productName = attributes.getValue("name"); //$NON-NLS-1$
465: application = attributes.getValue("application"); //$NON-NLS-1$
466: String use = attributes.getValue("useFeatures"); //$NON-NLS-1$
467: if (use != null)
468: useFeatures = IBuildPropertiesConstants.TRUE
469: .equalsIgnoreCase(use);
470: }
471:
472: private void processConfigIni(Attributes attributes) {
473: if (attributes.getValue("use").equals("custom")) { //$NON-NLS-1$//$NON-NLS-2$
474: configPath = attributes.getValue("path"); //$NON-NLS-1$
475: }
476: }
477:
478: private void processLauncher(Attributes attributes) {
479: launcherName = attributes.getValue("name"); //$NON-NLS-1$
480: }
481:
482: private boolean osMatch(String os) {
483: if (os == currentOS)
484: return true;
485: if (os == null)
486: return false;
487: return os.equals(currentOS);
488: }
489:
490: private void processSolaris(Attributes attributes) {
491: if (!osMatch(Platform.OS_SOLARIS))
492: return;
493: result.add(attributes.getValue(SOLARIS_LARGE));
494: result.add(attributes.getValue(SOLARIS_MEDIUM));
495: result.add(attributes.getValue(SOLARIS_SMALL));
496: result.add(attributes.getValue(SOLARIS_TINY));
497: }
498:
499: private void processWin(Attributes attributes) {
500: if (!osMatch(Platform.OS_WIN32))
501: return;
502: useIco = IBuildPropertiesConstants.TRUE
503: .equalsIgnoreCase(attributes.getValue(P_USE_ICO));
504: }
505:
506: private void processIco(Attributes attributes) {
507: if (!osMatch(Platform.OS_WIN32) || !useIco)
508: return;
509: result.add(attributes.getValue("path")); //$NON-NLS-1$
510: }
511:
512: private void processBmp(Attributes attributes) {
513: if (!osMatch(Platform.OS_WIN32) || useIco)
514: return;
515: result.add(attributes.getValue(WIN32_16_HIGH));
516: result.add(attributes.getValue(WIN32_16_LOW));
517: result.add(attributes.getValue(WIN32_24_LOW));
518: result.add(attributes.getValue(WIN32_32_HIGH));
519: result.add(attributes.getValue(WIN32_32_LOW));
520: result.add(attributes.getValue(WIN32_48_HIGH));
521: result.add(attributes.getValue(WIN32_48_LOW));
522: }
523:
524: private void processLinux(Attributes attributes) {
525: if (!osMatch(Platform.OS_LINUX))
526: return;
527: result.add(attributes.getValue("icon")); //$NON-NLS-1$
528: }
529:
530: private void processMac(Attributes attributes) {
531: if (!osMatch(Platform.OS_MACOSX))
532: return;
533: result.add(attributes.getValue("icon")); //$NON-NLS-1$
534: }
535: }
|