Lines 26-37
Link Here
|
26 |
import java.io.StringWriter; |
26 |
import java.io.StringWriter; |
27 |
import java.io.Writer; |
27 |
import java.io.Writer; |
28 |
import java.util.ArrayList; |
28 |
import java.util.ArrayList; |
|
|
29 |
import java.util.Collections; |
29 |
import java.util.Enumeration; |
30 |
import java.util.Enumeration; |
30 |
import java.util.HashMap; |
31 |
import java.util.HashMap; |
|
|
32 |
import java.util.HashSet; |
31 |
import java.util.Iterator; |
33 |
import java.util.Iterator; |
32 |
import java.util.List; |
34 |
import java.util.List; |
33 |
import java.util.Map; |
35 |
import java.util.Map; |
34 |
import java.util.Properties; |
36 |
import java.util.Properties; |
|
|
37 |
import java.util.Set; |
35 |
import java.util.StringTokenizer; |
38 |
import java.util.StringTokenizer; |
36 |
import java.util.jar.JarEntry; |
39 |
import java.util.jar.JarEntry; |
37 |
import java.util.jar.JarFile; |
40 |
import java.util.jar.JarFile; |
Lines 46-52
Link Here
|
46 |
import org.apache.tools.ant.Task; |
49 |
import org.apache.tools.ant.Task; |
47 |
import org.apache.tools.ant.taskdefs.Copy; |
50 |
import org.apache.tools.ant.taskdefs.Copy; |
48 |
import org.apache.tools.ant.taskdefs.SignJar; |
51 |
import org.apache.tools.ant.taskdefs.SignJar; |
|
|
52 |
import org.apache.tools.ant.taskdefs.Zip; |
49 |
import org.apache.tools.ant.types.FileSet; |
53 |
import org.apache.tools.ant.types.FileSet; |
|
|
54 |
import org.apache.tools.ant.types.ZipFileSet; |
50 |
import org.xml.sax.SAXException; |
55 |
import org.xml.sax.SAXException; |
51 |
|
56 |
|
52 |
/** Generates JNLP files for signed versions of the module JAR files. |
57 |
/** Generates JNLP files for signed versions of the module JAR files. |
Lines 116-121
Link Here
|
116 |
permissions = s; |
121 |
permissions = s; |
117 |
} |
122 |
} |
118 |
|
123 |
|
|
|
124 |
private FileSet indirectJars; |
125 |
/** |
126 |
* Other JARs which should be copied into the destination directory and referred to as resources, |
127 |
* even though they are not listed as Class-Path extensions of the module and would not normally |
128 |
* be in its effective classpath. The basedir of the fileset should be a cluster root; for each |
129 |
* such JAR, a file META-INF/exists/$relpath will be inserted in the JAR, where $relpath is the |
130 |
* relative path within the cluster. This permits the JAR to be located at runtime in a flat classpath, |
131 |
* using ClassLoader.getResource. |
132 |
*/ |
133 |
public void addIndirectJars(FileSet fs) { |
134 |
indirectJars = fs; |
135 |
} |
136 |
|
119 |
public void execute() throws BuildException { |
137 |
public void execute() throws BuildException { |
120 |
if (target == null) throw new BuildException("Output dir must be provided"); |
138 |
if (target == null) throw new BuildException("Output dir must be provided"); |
121 |
if (files == null) throw new BuildException("modules must be provided"); |
139 |
if (files == null) throw new BuildException("modules must be provided"); |
Lines 128-133
Link Here
|
128 |
} |
146 |
} |
129 |
|
147 |
|
130 |
private void generateFiles() throws IOException, BuildException { |
148 |
private void generateFiles() throws IOException, BuildException { |
|
|
149 |
Set<String> indirectJarPaths = Collections.emptySet(); |
150 |
if (indirectJars != null) { |
151 |
DirectoryScanner scan = indirectJars.getDirectoryScanner(getProject()); |
152 |
indirectJarPaths = new HashSet<String>(); |
153 |
for (String f : scan.getIncludedFiles()) { |
154 |
indirectJarPaths.add(f.replace(File.pathSeparatorChar, '/')); |
155 |
} |
156 |
} |
157 |
|
131 |
DirectoryScanner scan = files.getDirectoryScanner(getProject()); |
158 |
DirectoryScanner scan = files.getDirectoryScanner(getProject()); |
132 |
for (String f : scan.getIncludedFiles()) { |
159 |
for (String f : scan.getIncludedFiles()) { |
133 |
File jar = new File (files.getDir(getProject()), f); |
160 |
File jar = new File (files.getDir(getProject()), f); |
Lines 170-179
Link Here
|
170 |
shrt = prop.getProperty("OpenIDE-Module-Long-Description", oneline); |
197 |
shrt = prop.getProperty("OpenIDE-Module-Long-Description", oneline); |
171 |
} |
198 |
} |
172 |
|
199 |
|
173 |
Map<String,List<File>> localizedFiles = verifyExtensions(jar, theJar.getManifest(), dashcnb, codenamebase, verify); |
200 |
Map<String,List<File>> localizedFiles = verifyExtensions(jar, theJar.getManifest(), dashcnb, codenamebase, verify, indirectJarPaths); |
174 |
|
201 |
|
|
|
202 |
new File(target, dashcnb).mkdir(); |
175 |
|
203 |
|
176 |
File signed = new File(target, jar.getName()); |
204 |
File signed = new File(new File(target, dashcnb), jar.getName()); |
177 |
File jnlp = new File(target, dashcnb + ".jnlp"); |
205 |
File jnlp = new File(target, dashcnb + ".jnlp"); |
178 |
|
206 |
|
179 |
StringWriter writeJNLP = new StringWriter(); |
207 |
StringWriter writeJNLP = new StringWriter(); |
Lines 187-195
Link Here
|
187 |
writeJNLP.write(" </information>\n"); |
215 |
writeJNLP.write(" </information>\n"); |
188 |
writeJNLP.write(permissions +"\n"); |
216 |
writeJNLP.write(permissions +"\n"); |
189 |
writeJNLP.write(" <resources>\n"); |
217 |
writeJNLP.write(" <resources>\n"); |
190 |
writeJNLP.write(" <jar href='"); writeJNLP.write(jar.getName()); writeJNLP.write("'/>\n"); |
218 |
writeJNLP.write(" <jar href='" + dashcnb + '/' + jar.getName() + "'/>\n"); |
191 |
|
219 |
|
192 |
processExtensions(jar, theJar.getManifest(), writeJNLP, dashcnb, codebase); |
220 |
processExtensions(jar, theJar.getManifest(), writeJNLP, dashcnb, codebase); |
|
|
221 |
processIndirectJars(writeJNLP, dashcnb, codebase); |
193 |
|
222 |
|
194 |
writeJNLP.write(" </resources>\n"); |
223 |
writeJNLP.write(" </resources>\n"); |
195 |
|
224 |
|
Lines 202-214
Link Here
|
202 |
writeJNLP.write(" <resources locale='" + locale + "'>\n"); |
231 |
writeJNLP.write(" <resources locale='" + locale + "'>\n"); |
203 |
|
232 |
|
204 |
for (File n : files) { |
233 |
for (File n : files) { |
205 |
File t = new File(target, n.getName()); |
234 |
File t = new File(new File(target, dashcnb), n.getName()); |
206 |
|
235 |
|
207 |
getSignTask().setJar(n); |
236 |
getSignTask().setJar(n); |
208 |
getSignTask().setSignedjar(t); |
237 |
getSignTask().setSignedjar(t); |
209 |
getSignTask().execute(); |
238 |
getSignTask().execute(); |
210 |
|
239 |
|
211 |
writeJNLP.write(" <jar href='"); writeJNLP.write(n.getName()); writeJNLP.write("'/>\n"); |
240 |
writeJNLP.write(" <jar href='" + dashcnb + '/' + n.getName() + "'/>\n"); |
212 |
} |
241 |
} |
213 |
|
242 |
|
214 |
writeJNLP.write(" </resources>\n"); |
243 |
writeJNLP.write(" </resources>\n"); |
Lines 234-240
Link Here
|
234 |
|
263 |
|
235 |
} |
264 |
} |
236 |
|
265 |
|
237 |
private Map<String,List<File>> verifyExtensions(File f, Manifest mf, String dashcnb, String codebasename, boolean verify) throws IOException, BuildException { |
266 |
private Map<String,List<File>> verifyExtensions(File f, Manifest mf, String dashcnb, String codebasename, boolean verify, Set<String> indirectJarPaths) throws IOException, BuildException { |
238 |
Map<String,List<File>> localizedFiles = new HashMap<String,List<File>>(); |
267 |
Map<String,List<File>> localizedFiles = new HashMap<String,List<File>>(); |
239 |
|
268 |
|
240 |
|
269 |
|
Lines 302-307
Link Here
|
302 |
} |
331 |
} |
303 |
|
332 |
|
304 |
fileToOwningModule.remove("ant/nblib/" + dashcnb + ".jar"); |
333 |
fileToOwningModule.remove("ant/nblib/" + dashcnb + ".jar"); |
|
|
334 |
|
335 |
fileToOwningModule.keySet().removeAll(indirectJarPaths); |
305 |
|
336 |
|
306 |
if (verifyExcludes != null) { |
337 |
if (verifyExcludes != null) { |
307 |
StringTokenizer tok = new StringTokenizer(verifyExcludes, ", "); |
338 |
StringTokenizer tok = new StringTokenizer(verifyExcludes, ", "); |
Lines 352-361
Link Here
|
352 |
private void processExtensions(File f, Manifest mf, Writer fileWriter, String dashcnb, String codebase) throws IOException, BuildException { |
383 |
private void processExtensions(File f, Manifest mf, Writer fileWriter, String dashcnb, String codebase) throws IOException, BuildException { |
353 |
|
384 |
|
354 |
File nblibJar = new File(new File(new File(f.getParentFile().getParentFile(), "ant"), "nblib"), dashcnb + ".jar"); |
385 |
File nblibJar = new File(new File(new File(f.getParentFile().getParentFile(), "ant"), "nblib"), dashcnb + ".jar"); |
355 |
//System.err.println(nblibJar + ".isFile=" + nblibJar.isFile()); |
|
|
356 |
if (nblibJar.isFile()) { |
386 |
if (nblibJar.isFile()) { |
357 |
File ext = new File(target, "ant-nblib-" + nblibJar.getName()); |
387 |
File ext = new File(new File(target, dashcnb), "ant-nblib-" + nblibJar.getName()); |
358 |
fileWriter.write(" <jar href='" + ext.getName() + "'/>\n"); |
388 |
fileWriter.write(" <jar href='" + dashcnb + '/' + ext.getName() + "'/>\n"); |
359 |
getSignTask().setJar(nblibJar); |
389 |
getSignTask().setJar(nblibJar); |
360 |
getSignTask().setSignedjar(ext); |
390 |
getSignTask().setSignedjar(ext); |
361 |
getSignTask().execute(); |
391 |
getSignTask().execute(); |
Lines 379-414
Link Here
|
379 |
n = n.substring(0, n.length() - 4); |
409 |
n = n.substring(0, n.length() - 4); |
380 |
} |
410 |
} |
381 |
|
411 |
|
382 |
if (isSigned (e)) { |
412 |
if (isSigned(e) != null) { |
383 |
Copy copy = (Copy)getProject().createTask("copy"); |
413 |
Copy copy = (Copy)getProject().createTask("copy"); |
384 |
copy.setFile(e); |
414 |
copy.setFile(e); |
385 |
File t = new File(target, e.getName()); |
415 |
File t = new File(new File(target, dashcnb), s.replace('/', '-')); |
386 |
copy.setTofile(t); |
416 |
copy.setTofile(t); |
387 |
copy.execute(); |
417 |
copy.execute(); |
388 |
|
418 |
|
389 |
String extJnlpName = dashcnb + "-ext-" + n + ".jnlp"; |
419 |
String extJnlpName = t.getName().replaceFirst("\\.jar$", "") + ".jnlp"; |
390 |
File jnlp = new File(target, extJnlpName); |
420 |
File jnlp = new File(new File(target, dashcnb), extJnlpName); |
391 |
|
421 |
|
392 |
FileWriter writeJNLP = new FileWriter(jnlp); |
422 |
FileWriter writeJNLP = new FileWriter(jnlp); |
393 |
writeJNLP.write("<?xml version='1.0' encoding='UTF-8'?>\n"); |
423 |
writeJNLP.write("<?xml version='1.0' encoding='UTF-8'?>\n"); |
394 |
writeJNLP.write("<jnlp spec='1.0+' codebase='" + codebase + "' >\n"); |
424 |
writeJNLP.write("<jnlp spec='1.0+' codebase='" + codebase + "' >\n"); |
395 |
writeJNLP.write(" <information>\n"); |
425 |
writeJNLP.write(" <information>\n"); |
396 |
writeJNLP.write(" <title>" + n + "</title>\n"); |
426 |
writeJNLP.write(" <title>" + n + "</title>\n"); |
397 |
writeJNLP.write(" <vendor>NetBeans</vendor>\n"); |
427 |
writeJNLP.write(" <vendor>NetBeans</vendor>\n"); |
398 |
writeJNLP.write(" </information>\n"); |
428 |
writeJNLP.write(" </information>\n"); |
399 |
writeJNLP.write(permissions +"\n"); |
429 |
writeJNLP.write(permissions +"\n"); |
400 |
writeJNLP.write(" <resources>\n"); |
430 |
writeJNLP.write(" <resources>\n"); |
401 |
writeJNLP.write(" <jar href='"); writeJNLP.write(e.getName()); writeJNLP.write("'/>\n"); |
431 |
writeJNLP.write(" <jar href='" + dashcnb + '/' + t.getName() + "'/>\n"); |
402 |
writeJNLP.write(" </resources>\n"); |
432 |
writeJNLP.write(" </resources>\n"); |
403 |
writeJNLP.write(" <component-desc/>\n"); |
433 |
writeJNLP.write(" <component-desc/>\n"); |
404 |
writeJNLP.write("</jnlp>\n"); |
434 |
writeJNLP.write("</jnlp>\n"); |
405 |
writeJNLP.close(); |
435 |
writeJNLP.close(); |
406 |
|
436 |
|
407 |
fileWriter.write(" <extension name='" + e.getName() + "' href='" + extJnlpName + "'/>\n"); |
437 |
fileWriter.write(" <extension name='" + e.getName().replaceFirst("\\.jar$", "") + "' href='" + dashcnb + '/' + extJnlpName + "'/>\n"); |
408 |
} else { |
438 |
} else { |
409 |
File ext = new File(target, e.getName()); |
439 |
File ext = new File(new File(target, dashcnb), s.replace('/', '-')); |
410 |
|
440 |
|
411 |
fileWriter.write(" <jar href='" + e.getName() + "'/>\n"); |
441 |
fileWriter.write(" <jar href='" + dashcnb + '/' + ext.getName() + "'/>\n"); |
412 |
|
442 |
|
413 |
getSignTask().setJar(e); |
443 |
getSignTask().setJar(e); |
414 |
getSignTask().setSignedjar(ext); |
444 |
getSignTask().setSignedjar(ext); |
Lines 416-421
Link Here
|
416 |
} |
446 |
} |
417 |
} |
447 |
} |
418 |
} |
448 |
} |
|
|
449 |
|
450 |
private void processIndirectJars(Writer fileWriter, String dashcnb, String codebase) throws IOException, BuildException { |
451 |
DirectoryScanner scan = indirectJars.getDirectoryScanner(getProject()); |
452 |
for (String f : scan.getIncludedFiles()) { |
453 |
File jar = new File(scan.getBasedir(), f); |
454 |
String rel = f.replace(File.separatorChar, '/'); |
455 |
String sig = isSigned(jar); |
456 |
// javaws will reject .zip files even with signatures. |
457 |
String rel2 = rel.endsWith(".jar") ? rel : rel.replaceFirst("(\\.zip)?$", ".jar"); |
458 |
File ext = new File(new File(target, dashcnb), rel2.replace('/', '-').replaceFirst("^modules-", "")); |
459 |
Zip jartask = (Zip) getProject().createTask("jar"); |
460 |
jartask.setDestFile(ext); |
461 |
ZipFileSet zfs = new ZipFileSet(); |
462 |
zfs.setSrc(jar); |
463 |
if (sig != null) { |
464 |
// Need to cancel original signature since we are adding one entry to the JAR. |
465 |
zfs.setExcludes("META-INF/" + sig + ".*"); |
466 |
} |
467 |
jartask.addZipfileset(zfs); |
468 |
zfs = new ZipFileSet(); |
469 |
File blank = File.createTempFile("empty", ""); |
470 |
blank.deleteOnExit(); |
471 |
zfs.setFile(blank); |
472 |
zfs.setFullpath("META-INF/exists/" + rel); |
473 |
jartask.addZipfileset(zfs); |
474 |
jartask.execute(); |
475 |
blank.delete(); |
476 |
fileWriter.write(" <jar href='" + dashcnb + '/' + ext.getName() + "'/>\n"); |
477 |
getSignTask().setJar(ext); |
478 |
getSignTask().setSignedjar(null); |
479 |
getSignTask().execute(); |
480 |
} |
481 |
} |
419 |
|
482 |
|
420 |
private static String relative(File file, File root) { |
483 |
private static String relative(File file, File root) { |
421 |
String sfile = file.toString().replace(File.separatorChar, '/'); |
484 |
String sfile = file.toString().replace(File.separatorChar, '/'); |
Lines 426-443
Link Here
|
426 |
return sfile; |
489 |
return sfile; |
427 |
} |
490 |
} |
428 |
|
491 |
|
429 |
private static boolean isSigned(File f) throws IOException { |
492 |
/** return alias if signed, or null if not */ |
|
|
493 |
private static String isSigned(File f) throws IOException { |
430 |
JarFile jar = new JarFile(f); |
494 |
JarFile jar = new JarFile(f); |
431 |
Enumeration<JarEntry> en = jar.entries(); |
495 |
try { |
432 |
while (en.hasMoreElements()) { |
496 |
Enumeration<JarEntry> en = jar.entries(); |
433 |
JarEntry e = en.nextElement(); |
497 |
while (en.hasMoreElements()) { |
434 |
if (e.getName().endsWith(".SF")) { |
498 |
Matcher m = SF.matcher(en.nextElement().getName()); |
435 |
jar.close(); |
499 |
if (m.matches()) { |
436 |
return true; |
500 |
return m.group(1); |
|
|
501 |
} |
437 |
} |
502 |
} |
|
|
503 |
return null; |
504 |
} finally { |
505 |
jar.close(); |
438 |
} |
506 |
} |
439 |
jar.close(); |
|
|
440 |
return false; |
441 |
} |
507 |
} |
|
|
508 |
private static final Pattern SF = Pattern.compile("META-INF/(.+)\\.SF"); |
442 |
|
509 |
|
443 |
} |
510 |
} |