1 12 13 package org.eclipse.pde.internal.build.tasks; 14 15 import java.io.*; 16 import java.util.*; 17 import java.util.zip.ZipEntry ; 18 import java.util.zip.ZipFile ; 19 import javax.xml.parsers.*; 20 import org.xml.sax.*; 21 import org.xml.sax.helpers.DefaultHandler ; 22 23 27 public class JNLPGenerator extends DefaultHandler { 28 29 private SAXParser parser; 30 private File featureRoot; 31 32 private String codebase; 33 private String j2se; 34 35 45 private final static SAXParserFactory parserFactory = SAXParserFactory.newInstance(); 46 private PrintWriter out; 47 private String destination; 48 private String provider; 49 private String label; 50 private String version; 51 private String id; 52 private String description; 53 private boolean resourceWritten = false; 54 private String currentOS = null; 55 private String currentArch = null; 56 private Locale locale = null; 57 private PropertyResourceBundle nlsBundle = null; 58 private boolean generateOfflineAllowed; 59 private Config[] configs; 60 61 64 public static void main(String [] args) { 65 JNLPGenerator generator = new JNLPGenerator(args[0], args[1], args[2], args[3]); 66 generator.process(); 67 } 68 69 72 public JNLPGenerator(String feature, String destination, String codebase, String j2se) { 73 this(feature, destination, codebase, j2se, Locale.getDefault(), true, null); 74 } 75 76 79 public JNLPGenerator(String feature, String destination, String codebase, String j2se, Locale locale, boolean generateOfflineAllowed, String configs) { 80 super(); 81 this.featureRoot = new File (feature); 82 this.destination = destination; 83 this.codebase = codebase; 84 this.j2se = j2se; 85 this.locale = locale; 86 this.generateOfflineAllowed = generateOfflineAllowed; 87 try { 88 parserFactory.setNamespaceAware(true); 89 parser = parserFactory.newSAXParser(); 90 } catch (ParserConfigurationException e) { 91 System.out.println(e); 92 } catch (SAXException e) { 93 System.out.println(e); 94 } 95 setConfigInfo(configs); 96 } 97 98 101 public void process() { 102 InputStream in = null; 103 final String FEATURE_XML = "feature.xml"; 105 try { 106 ZipFile featureArchive = null; 107 InputStream nlsStream = null; 108 if (featureRoot.isFile()) { 109 featureArchive = new ZipFile (featureRoot); 110 nlsStream = getNLSStream(featureArchive); 111 ZipEntry featureXML = featureArchive.getEntry(FEATURE_XML); 112 in = featureArchive.getInputStream(featureXML); 113 } else { 114 nlsStream = getNLSStream(this.featureRoot); 115 in = new BufferedInputStream(new FileInputStream(new File (featureRoot, FEATURE_XML))); 116 } 117 try { 118 if (nlsStream != null) { 119 nlsBundle = new PropertyResourceBundle(nlsStream); 120 nlsStream.close(); 121 } 122 } catch (IOException e) { 123 } 125 try { 126 parser.parse(new InputSource(in), this); 127 writeResourceEpilogue(); 128 writeEpilogue(); 129 } catch (SAXException e) { 130 } finally { 132 in.close(); 133 if (out != null) 134 out.close(); 135 if (featureArchive != null) 136 featureArchive.close(); 137 } 138 } catch (IOException e) { 139 } 141 } 142 143 149 private InputStream getNLSStream(File root) { 150 String appendix = ".properties"; String [] potentials = createNLSPotentials(); 152 153 Map validEntries = new HashMap(); 154 File [] files = root.listFiles(); 155 for (int i = 0; i < files.length; i++) { 156 String filename = files[i].getName(); 157 if (filename.endsWith(appendix)) { 158 validEntries.put(filename, files[i]); 159 } 160 } 161 InputStream stream = null; 162 if (validEntries.size() > 0) { 163 for (int i = 0; i < potentials.length; i++) { 164 File file = (File ) validEntries.get(potentials[i]); 165 if (file != null) { 166 try { 167 stream = new BufferedInputStream(new FileInputStream(file)); 168 break; 169 } catch (IOException e) { 170 } 172 } 173 } 174 if (stream == null) { 175 File file = (File ) validEntries.values().iterator().next(); 176 try { 177 stream = new BufferedInputStream(new FileInputStream(file)); 178 } catch (IOException e) { 179 } 181 } 182 } 183 return stream; 184 } 185 186 192 private InputStream getNLSStream(ZipFile featureArchive) { 193 String appendix = ".properties"; String [] potentials = createNLSPotentials(); 195 196 Map validEntries = new HashMap(); 197 for (Enumeration enumeration = featureArchive.entries(); enumeration.hasMoreElements();) { 198 ZipEntry entry = (ZipEntry ) enumeration.nextElement(); 199 String entryName = entry.getName(); 200 if (entryName.endsWith(appendix)) { 201 validEntries.put(entryName, entry); 202 } 203 } 204 InputStream stream = null; 205 if (validEntries.size() > 0) { 206 for (int i = 0; i < potentials.length; i++) { 207 ZipEntry entry = (ZipEntry ) validEntries.get(potentials[i]); 208 if (entry != null) { 209 try { 210 stream = featureArchive.getInputStream(entry); 211 break; 212 } catch (IOException e) { 213 } 215 } 216 } 217 if (stream == null) { 218 ZipEntry entry = (ZipEntry ) validEntries.values().iterator().next(); 219 try { 220 stream = featureArchive.getInputStream(entry); 221 } catch (IOException e) { 222 } 224 } 225 } 226 return stream; 227 } 228 229 private String [] createNLSPotentials() { 230 String suffix = "feature"; String appendix = ".properties"; 233 String language = locale.getLanguage(); 234 String country = locale.getCountry(); 235 String variant = locale.getVariant(); 236 237 String potential1 = '_' + language + '_' + country + '_' + variant; 238 String potential2 = '_' + language + '_' + country; 239 String potential3 = '_' + language; 240 String potential4 = ""; 242 String [] potentials = new String [] {potential1, potential2, potential3, potential4}; 243 for (int i = 0; i < potentials.length; i++) { 244 potentials[i] = suffix + potentials[i] + appendix; 245 } 246 return potentials; 247 } 248 249 public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { 250 try { 251 if ("feature".equals(localName)) { processFeature(attributes); 253 } else if ("includes".equals(localName)) { processIncludes(attributes); 255 } else if ("description".equals(localName)) { processDescription(attributes); 257 } else if ("plugin".equals(localName)) { processPlugin(attributes); 259 } 260 } catch (IOException e) { 261 throw new SAXException(e); 262 } 263 } 264 265 private void processPlugin(Attributes attributes) throws IOException { 266 writePrologue(); 267 String pluginId = attributes.getValue("id"); String pluginVersion = attributes.getValue("version"); String os = attributes.getValue("os"); String ws = attributes.getValue("ws"); String arch = attributes.getValue("arch"); if (isValidEnvironment(os, ws, arch)) { 273 writeResourcePrologue(os, ws, arch); 274 out.println("\t\t<jar HREF=\"plugins/" + pluginId + "_" + pluginVersion + ".jar\"/>"); } 276 } 277 278 private void writeResourceEpilogue() { 279 if (!resourceWritten) 280 return; 281 out.println("\t</resources>"); resourceWritten = false; 283 currentOS = null; 284 } 285 286 private void writeResourcePrologue(String os, String ws, String arch) { 287 if (os == null) 288 os = ws; 289 os = convertOS(os); 290 arch = convertArch(arch); 291 if (resourceWritten && osMatch(os) && archMatch(arch)) 292 return; 293 if (resourceWritten) 294 writeResourceEpilogue(); 295 out.println("\t<resources" + (os == null ? "" : " os=\"" + os + "\"") + (arch == null ? "" : " arch=\"" + arch + "\"") + ">"); resourceWritten = true; 297 currentOS = os; 298 currentArch = arch; 299 } 300 301 private String convertOS(String os) { 302 if (os == null) 303 return null; 304 if ("win32".equalsIgnoreCase(os)) return "Windows"; if ("macosx".equalsIgnoreCase(os)) return "Mac"; if ("linux".equalsIgnoreCase(os)) return "Linux"; if ("solaris".equalsIgnoreCase(os)) return "Solaris"; if ("hpux".equalsIgnoreCase(os)) return "HP-UX"; if ("aix".equalsIgnoreCase(os)) return "AIX"; return os; 317 } 318 319 private boolean osMatch(String os) { 320 if (os == currentOS) 321 return true; 322 if (os == null) 323 return false; 324 return os.equals(currentOS); 325 } 326 327 private String convertArch(String arch) { 328 if (arch == null) 329 return null; 330 331 if ("x86".equals(arch)) return "x86"; 334 if ("PA_RISC".equals(arch)) return "PA_RISC"; 337 if ("ppc".equals(arch)) return "ppc"; 340 if ("sparc".equals(arch)) return "sparc"; 343 if ("x86_64".equals(arch)) return "x86_64"; 346 if ("ia64".equals(arch)) return "ia64"; 349 if ("ia64_32".equals(arch)) return "ia64_32"; 352 return arch; 353 } 354 355 private boolean archMatch(String arch) { 356 if (arch == currentOS) 357 return true; 358 if (arch == null) 359 return false; 360 return arch.equals(currentArch); 361 } 362 363 private void processDescription(Attributes attributes) { 364 } 365 366 private void processIncludes(Attributes attributes) throws IOException { 367 writePrologue(); 368 String inclusionId = attributes.getValue("id"); String inclusionVersion = attributes.getValue("version"); String name = attributes.getValue("name"); String os = attributes.getValue("os"); String ws = attributes.getValue("ws"); String arch = attributes.getValue("arch"); if (isValidEnvironment(os, ws, arch)) { 375 writeResourcePrologue(os, ws, arch); 376 out.print("\t\t<extension "); if (name != null) 378 out.print("name=\"" + name + "\" "); if (inclusionId != null) { 380 out.print("href=\"features/" + inclusionId); if (inclusionVersion != null) 382 out.print('_' + inclusionVersion); 383 out.print(".jnlp\" "); } 385 out.println("/>"); } 387 } 388 389 private void processFeature(Attributes attributes) { 390 id = attributes.getValue("id"); version = attributes.getValue("version"); label = processNLS(attributes.getValue("label")); provider = processNLS(attributes.getValue("provider-name")); } 395 396 405 private String processNLS(String string) { 406 if (string == null) 407 return null; 408 string = string.trim(); 409 if (!string.startsWith("%")) { return string; 411 } 412 if (string.startsWith("%%")) { return string.substring(1); 414 } 415 int index = string.indexOf(" "); String key = index == -1 ? string : string.substring(0, index); 417 String dflt = index == -1 ? string : string.substring(index + 1); 418 if (nlsBundle == null) { 419 return dflt; 420 } 421 try { 422 return nlsBundle.getString(key.substring(1)); 423 } catch (MissingResourceException e) { 424 return dflt; 425 } 426 } 427 428 private void writePrologue() throws IOException { 429 if (out != null) 430 return; 431 if (destination == null) { 432 featureRoot.getParentFile(); 433 destination = featureRoot.getParent() + '/'; 434 } 435 if (destination.endsWith("/") || destination.endsWith("\\")) destination = new File (featureRoot.getParentFile(), id + "_" + version + ".jnlp").getAbsolutePath(); out = new PrintWriter(new BufferedOutputStream(new FileOutputStream(destination))); 438 writePrologue(); 439 out.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"); out.print("<jnlp spec=\"1.0+\" "); if (codebase != null) 442 out.print("codebase=\"" + codebase); out.println("\">"); out.println("\t<information>"); if (label != null) 446 out.println("\t\t<title>" + label + "</title>"); if (provider != null) 448 out.println("\t\t<vendor>" + provider + "</vendor>"); if (description != null) 450 out.println("\t\t<description>" + description + "</description>"); if (generateOfflineAllowed) 452 out.println("\t\t<offline-allowed/>"); out.println("\t</information>"); out.println("\t<security>"); out.println("\t\t<all-permissions/>"); out.println("\t</security>"); out.println("\t<component-desc/>"); out.println("\t<resources>"); out.println("\t\t<j2se version=\"" + j2se + "\" />"); out.println("\t</resources>"); } 462 463 private void writeEpilogue() { 464 out.println("</jnlp>"); } 466 467 private boolean isMatching(String candidateValues, String siteValues) { 468 if (candidateValues == null) 469 return true; 470 if (siteValues == null) 471 return false; 472 if ("*".equals(candidateValues))return true; if ("".equals(candidateValues))return true; StringTokenizer siteTokens = new StringTokenizer(siteValues, ","); while (siteTokens.hasMoreTokens()) { 477 StringTokenizer candidateTokens = new StringTokenizer(candidateValues, ","); String siteValue = siteTokens.nextToken(); 479 while (candidateTokens.hasMoreTokens()) { 480 if (siteValue.equalsIgnoreCase(candidateTokens.nextToken())) 481 return true; 482 } 483 } 484 return false; 485 } 486 487 private boolean isValidEnvironment(String os, String ws, String arch) { 488 if (configs.length==0) 489 return true; 490 for (int i = 0; i < configs.length; i++) { 491 if (isMatching(os, configs[i].getOs()) && isMatching(ws, configs[i].getWs()) && isMatching(arch, configs[i].getArch())) 492 return true; 493 } 494 return false; 495 } 496 497 private void setConfigInfo(String spec) { 498 if (spec != null && spec.startsWith("$")) { configs = new Config[0]; 500 return; 501 } 502 if (spec == null) { 503 configs = new Config[] {Config.genericConfig()}; 504 return; 505 } 506 StringTokenizer tokens = new StringTokenizer(spec, "&"); int configNbr = tokens.countTokens(); 508 ArrayList configInfos = new ArrayList(configNbr); 509 while (tokens.hasMoreElements()) { 510 String aConfig = tokens.nextToken(); 511 StringTokenizer configTokens = new StringTokenizer(aConfig, ","); if (configTokens.countTokens() == 3) { 513 Config toAdd = new Config(configTokens.nextToken().trim(), configTokens.nextToken().trim(), configTokens.nextToken().trim()); 514 if (toAdd.equals(Config.genericConfig())) 515 toAdd = Config.genericConfig(); 516 configInfos.add(toAdd); 517 } 518 } 519 if (configInfos.size() == 0) 520 configInfos.add(Config.genericConfig()); 521 configs = (Config[]) configInfos.toArray(new Config[configInfos.size()]); 522 } 523 } 524 | Popular Tags |