2
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
4
* Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
6
* The contents of this file are subject to the terms of either the GNU
7
* General Public License Version 2 only ("GPL") or the Common
8
* Development and Distribution License("CDDL") (collectively, the
9
* "License"). You may not use this file except in compliance with the
10
* License. You can obtain a copy of the License at
11
* http://www.netbeans.org/cddl-gplv2.html
12
* or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
13
* specific language governing permissions and limitations under the
14
* License. When distributing the software, include this License Header
15
* Notice in each file and include the License file at
16
* nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
17
* particular file as subject to the "Classpath" exception as provided
18
* by Sun in the GPL Version 2 section of the License file that
19
* accompanied this code. If applicable, add the following below the
20
* License Header, with the fields enclosed by brackets [] replaced by
21
* your own identifying information:
22
* "Portions Copyrighted [year] [name of copyright owner]"
26
* The Original Software is NetBeans. The Initial Developer of the Original
27
* Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
28
* Microsystems, Inc. All Rights Reserved.
30
* If you wish your version of this file to be governed by only the CDDL
31
* or only the GPL Version 2, indicate your decision by adding
32
* "[Contributor] elects to include this software in this distribution
33
* under the [CDDL or GPL Version 2] license." If you do not indicate a
34
* single choice of license, a recipient has the option to distribute
35
* your version of this file under either the CDDL, the GPL Version 2 or
36
* to extend the choice of license to its licensees as provided above.
37
* However, if you add GPL Version 2 code and therefore, elected the GPL
38
* Version 2 license, then the option applies only if the new code is
39
* made subject to such option by the copyright holder.
42
package org.netbeans.nbbuild;
45
import java.io.FileInputStream;
46
import java.io.FileOutputStream;
47
import java.io.IOException;
48
import java.io.InputStream;
49
import java.io.InputStreamReader;
50
import java.io.OutputStream;
51
import java.io.OutputStreamWriter;
52
import java.io.PrintWriter;
53
import java.io.Reader;
55
import java.util.ArrayList;
56
import java.util.Collections;
57
import java.util.Enumeration;
58
import java.util.Iterator;
59
import java.util.List;
61
import java.util.Properties;
62
import java.util.StringTokenizer;
63
import java.util.Vector;
64
import java.util.jar.Attributes;
65
import java.util.jar.JarFile;
66
import java.util.jar.Manifest;
67
import java.util.zip.ZipEntry;
68
import java.util.zip.ZipFile;
69
import org.apache.tools.ant.BuildException;
70
import org.apache.tools.ant.Project;
71
import org.apache.tools.ant.taskdefs.Jar;
72
import org.apache.tools.ant.taskdefs.MatchingTask;
73
import org.apache.tools.ant.taskdefs.SignJar;
74
import org.apache.tools.ant.types.FileSet;
76
/** Makes a localized <code>.nbm</code> (<b>N</b>et<b>B</b>eans <b>M</b>odule) file.
77
* This version is temporary, intended to be used only until
78
* the functionality added to this version since rev 1.29
79
* of MakeNBM.java can be added into MakeNBM.java
81
* @author Jerry Huth (email: jerry@solidstep.com)
83
public class MakeLNBM extends MatchingTask {
85
/** The same syntax may be used for either <samp><license></samp> or
86
* <samp><description></samp> subelements.
87
* <p>By setting the property <code>makenbm.nocdata</code> to <code>true</code>,
88
* you can avoid using XML <code>CDATA</code> (for compatibility with older versions
89
* of Auto Update which could not handle it).
92
/** You may embed a <samp><file></samp> element inside the blurb.
93
* If there is text on either side of it, that will be separated
94
* with a line of dashes automatically.
95
* But use nested <samp><text></samp> for this purpose.
97
public class FileInsert {
99
public void setLocation (File file) throws BuildException {
100
log("Including contents of " + file, Project.MSG_VERBOSE);
101
long lmod = file.lastModified ();
102
if (lmod > mostRecentInput) mostRecentInput = lmod;
105
InputStream is = new FileInputStream (file);
107
Reader r = new InputStreamReader (is, "UTF-8"); //NOI18N
108
char[] buf = new char[4096];
110
while ((len = r.read (buf)) != -1)
111
text.append (buf, 0, len);
115
} catch (IOException ioe) {
116
throw new BuildException ("Exception reading blurb from " + file, ioe, getLocation ());
120
private StringBuffer text = new StringBuffer ();
121
private String name = null;
122
/** There may be freeform text inside the element. Prefer to use nested elements. */
123
public void addText (String t) {
125
// Strips indentation. Needed because of common style:
130
t = getProject().replaceProperties(t.trim());
131
int min = Integer.MAX_VALUE;
132
StringTokenizer tok = new StringTokenizer (t, "\n"); //NOI18N
133
boolean first = true;
134
while (tok.hasMoreTokens ()) {
135
String line = tok.nextToken ();
141
i < line.length () &&
142
Character.isWhitespace (line.charAt (i));
145
if (i < min) min = i;
151
tok = new StringTokenizer (t, "\n"); //NOI18N
153
while (tok.hasMoreTokens ()) {
154
String line = tok.nextToken ();
158
text.append ('\n'); //NOI18N
159
line = line.substring (min);
165
/** Contents of a file to include. */
166
public FileInsert createFile () {
167
return new FileInsert ();
169
/** Text to include literally. */
171
public void addText(String t) {
172
Blurb.this.addText(t);
175
// At least on Ant 1.3, mixed content does not work: all the text is added
176
// first, then all the file inserts. Need to use subelements to be sure.
177
/** Include nested literal text. */
178
public Text createText() {
181
private void addSeparator () {
182
if (text.length () > 0) {
183
// some sort of separator
184
if (text.charAt (text.length () - 1) != '\n') //NOI18N
185
text.append ('\n'); //NOI18N
186
text.append ("-----------------------------------------------------\n"); //NOI18N
189
public String getText () {
190
String nocdata = getProject().getProperty("makenbm.nocdata"); //NOI18N
191
if (nocdata != null && Project.toBoolean(nocdata)) {
192
return xmlEscape(text.toString());
194
return "<![CDATA[" + text.toString () + "]]>"; //NOI18N
197
/** You can either set a name for the blurb, or using the <code>file</code> attribute does this.
198
* The name is mandatory for licenses, as this identifies the license in
199
* an update description.
201
public void setName (String name) {
204
public String getName () {
207
/** Include a file (and set the license name according to its basename). */
208
public void setFile (File file) {
209
// This actually adds the text and so on:
210
new FileInsert ().setLocation (file);
211
// Default for the name too, as a convenience.
212
if (name == null) name = file.getName ();
216
public class ExternalPackage {
218
String targetName = null;
219
String startUrl = null;
220
String description = null;
222
public void setName(String n) {
226
public void setTargetName(String t) {
230
public void setStartURL(String u) {
234
public void setDescription(String d) {
235
this.description = d;
240
// Similar to org.openide.xml.XMLUtil methods.
241
private static String xmlEscape(String s) {
242
int max = s.length();
243
StringBuffer s2 = new StringBuffer((int)(max * 1.1 + 1));
244
for (int i = 0; i < max; i++) {
245
char c = s.charAt(i);
248
s2.append("<"); //NOI18N
251
s2.append(">"); //NOI18N
254
s2.append("&"); //NOI18N
257
s2.append("""); //NOI18N
264
return s2.toString();
267
/** <samp><signature></samp> subelement for signing the NBM. */
268
public /*static*/ class Signature {
269
public File keystore;
270
public String storepass, alias;
271
/** Path to the keystore (private key). */
272
public void setKeystore (File f) {
275
/** Password for the keystore.
276
* If a question mark (<samp>?</samp>), the NBM will not be signed
277
* and a warning will be printed.
279
public void setStorepass (String s) {
282
/** Alias for the private key. */
283
public void setAlias (String s) {
288
private File file = null;
289
private File topdir = null;
290
private File manifest = null;
291
/** see #13850 for explanation */
292
private File module = null;
293
private String homepage = null;
294
private String distribution = null;
295
private String needsrestart = null;
296
private Blurb license = null;
297
private Blurb description = null;
298
private Blurb notification = null;
299
private Signature signature = null;
300
private long mostRecentInput = 0L;
301
private boolean isStandardInclude = true;
302
private Vector<ExternalPackage> externalPackages = null;
303
private boolean manOrModReq = true ;
304
private boolean manOrModReqSet = false ;
305
private String langCode = null ;
306
private String brandingCode = null ;
307
private String modInfo = null ;
308
private File locBundle = null ; // Localizing Bundle
310
/** Include netbeans directory - default is true */
311
public void setIsStandardInclude(boolean isStandardInclude) {
312
this.isStandardInclude = isStandardInclude;
315
/** Name of resulting NBM file. */
316
public void setFile (File file) {
320
* Expected to contain a subdirectory <samp>netbeans/</samp> with the
321
* desired contents of the NBM.
322
* Will create <samp>Info/info.xml</samp> with metadata.
324
public void setTopdir (File topdir) {
325
this.topdir = topdir;
327
/** Module manifest needed for versioning.
328
* @deprecated Use {@link #setModule} instead.
331
public void setManifest (File manifest) {
332
this.manifest = manifest;
333
long lmod = manifest.lastModified ();
334
if (lmod > mostRecentInput) mostRecentInput = lmod;
335
log(getLocation() + "The 'manifest' attr on <makenbm> is deprecated, please use 'module' instead", Project.MSG_WARN);
337
/** Module JAR needed for generating the info file.
338
* Information may be gotten either from its manifest,
339
* or if it declares OpenIDE-Module-Localizing-Bundle in its
340
* manifest, from that bundle.
341
* The base locale variant, if any, is also checked if necessary
342
* for the named bundle.
343
* Currently no other locale variants of the module are examined;
344
* the information is available but there is no published specification
345
* of what the resulting variant NBMs (or variant information within
346
* the NBM) should look like.
348
public void setModule(File module) {
349
this.module = module;
350
// mostRecentInput updated below...
352
/** URL to a home page describing the module. */
353
public void setHomepage (String homepage) {
354
this.homepage = homepage;
356
/** Does module need IDE restart to be installed? */
357
public void setNeedsrestart (String needsrestart) {
358
this.needsrestart = needsrestart;
360
/** URL where this NBM file is expected to be downloadable from. */
361
public void setDistribution (String distribution) throws BuildException {
362
if (distribution.startsWith("http://")) { //NOI18N
363
this.distribution = distribution;
364
} else if (!(distribution.equals(""))) {
365
// workaround for typical bug in build script
366
this.distribution = "http://" + distribution; //NOI18N
368
throw new BuildException("Distribution URL is empty, check build.xml file", getLocation());
372
URI uri = java.net.URI.create(this.distribution);
373
} catch (IllegalArgumentException ile) {
374
throw new BuildException("Distribution URL \"" + this.distribution + "\" is not a valid URI", ile, getLocation());
377
public Blurb createLicense () {
378
return (license = new Blurb ());
380
public Blurb createNotification () {
381
return (notification = new Blurb ());
383
public Blurb createDescription () {
384
log(getLocation() + "The <description> subelement in <makenbm> is deprecated except for emergency patches, please ensure your module has an OpenIDE-Module-Long-Description instead", Project.MSG_WARN);
385
return (description = new Blurb ());
387
public Signature createSignature () {
388
return (signature = new Signature ());
391
public ExternalPackage createExternalPackage(){
392
ExternalPackage externalPackage = new ExternalPackage ();
393
if (externalPackages == null)
394
externalPackages = new Vector<ExternalPackage>();
395
externalPackages.add( externalPackage );
396
return externalPackage;
399
public void execute () throws BuildException {
401
throw new BuildException("must set file for makenbm", getLocation());
403
if (manifest == null && module == null && reqManOrMod()) {
404
throw new BuildException("must set module for makenbm", getLocation());
406
if (manifest != null && module != null) {
407
throw new BuildException("cannot set both manifest and module for makenbm", getLocation());
409
// Will create a file Info/info.xml to be stored alongside netbeans/ contents.
410
File infodir = new File (topdir, "Info"); //NOI18N
412
File infofile = new File (infodir, "info.xml"); //NOI18N
413
if (infofile.exists ()) {
416
Attributes attr = null;
417
if (module != null) {
418
// The normal case; read attributes from its manifest and maybe bundle.
419
long mMod = module.lastModified();
420
if (mostRecentInput < mMod) mostRecentInput = mMod;
422
JarFile modulejar = new JarFile(module);
424
attr = modulejar.getManifest().getMainAttributes();
425
String bundlename = attr.getValue("OpenIDE-Module-Localizing-Bundle"); //NOI18N
426
if (bundlename != null) {
427
Properties p = new Properties();
428
ZipEntry bundleentry = modulejar.getEntry(bundlename);
429
if (bundleentry != null) {
430
InputStream is = modulejar.getInputStream(bundleentry);
437
// Not found in main JAR, check locale variant JAR.
438
File variant = new File(new File(module.getParentFile(), "locale"), module.getName()); //NOI18N
439
if (!variant.isFile()) throw new BuildException(bundlename + " not found in " + module, getLocation());
440
long vmMod = variant.lastModified();
441
if (mostRecentInput < vmMod) mostRecentInput = vmMod;
442
ZipFile variantjar = new ZipFile(variant);
444
bundleentry = variantjar.getEntry(bundlename);
445
if (bundleentry == null) throw new BuildException(bundlename + " not found in " + module + " nor in " + variant, getLocation());
446
InputStream is = variantjar.getInputStream(bundleentry);
456
// Now pick up attributes from the bundle.
457
Iterator it = p.entrySet().iterator();
458
while (it.hasNext()) {
459
Map.Entry entry = (Map.Entry)it.next();
460
String name = (String)entry.getKey();
461
if (! name.startsWith("OpenIDE-Module-")) continue; //NOI18N
462
attr.putValue(name, (String)entry.getValue());
464
} // else all loc attrs in main manifest, OK
468
} catch (IOException ioe) {
469
throw new BuildException("exception while reading " + module, ioe, getLocation());
471
} // else we will read attr later if info file is out of date
472
boolean skipInfo = false;
473
if (infofile.exists ()) {
474
// Check for up-to-date w.r.t. manifest and maybe license file.
475
long iMod = infofile.lastModified ();
476
if (mostRecentInput < iMod)
480
log ("Creating NBM info file " + infofile);
481
if (manifest != null) {
482
// Read module manifest for main attributes.
484
InputStream manifestStream = new FileInputStream (manifest);
486
attr = new Manifest (manifestStream).getMainAttributes ();
488
manifestStream.close ();
490
} catch (IOException e) {
491
throw new BuildException("exception when reading manifest " + manifest, e, getLocation());
493
} // else we read attr before
495
OutputStream infoStream = new FileOutputStream (infofile);
497
PrintWriter ps = new PrintWriter(new OutputStreamWriter(infoStream, "UTF-8"));
498
// Begin writing XML.
499
ps.println ("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"); //NOI18N
500
ps.println("<!DOCTYPE module PUBLIC \"-//NetBeans//DTD Autoupdate Module Info 2.4//EN\" \"http://www.netbeans.org/dtds/autoupdate-info-2_4.dtd\">"); //NOI18N
502
String codenamebase = attr.getValue ("OpenIDE-Module"); //NOI18N
503
if (codenamebase == null)
504
throw new BuildException("invalid manifest, does not contain OpenIDE-Module", getLocation());
505
// Strip major release number if any.
506
codenamebase = getCodenameBase( codenamebase) ;
507
ps.println ("<module codenamebase=\"" + xmlEscape(codenamebase) + "\""); //NOI18N
510
ps.print( "<module "); //NOI18N
511
if( modInfo != null && !modInfo.trim().equals( "")) {
512
String codenamebase = getCodenameBase( modInfo) ;
513
ps.println( "codenamebase=\"" + xmlEscape(codenamebase) + "\""); //NOI18N
516
ps.println( "") ; //NOI18N
519
if (homepage != null)
520
ps.println (" homepage=\"" + xmlEscape(homepage) + "\""); //NOI18N
521
if (distribution != null) {
522
ps.println (" distribution=\"" + xmlEscape(distribution) + "\""); //NOI18N
524
throw new BuildException("NBM distribution URL is not set", getLocation());
526
// Here we only write a name for the license.
527
if (license != null) {
528
String name = license.getName ();
530
throw new BuildException("Every license must have a name or file attribute", getLocation());
531
ps.println (" license=\"" + xmlEscape(name) + "\""); //NOI18N
533
ps.println (" downloadsize=\"0\""); //NOI18N
534
if (needsrestart != null)
535
ps.println (" needsrestart=\"" + xmlEscape(needsrestart) + "\""); //NOI18N
536
ps.println (">"); //NOI18N
537
if (description != null) {
538
ps.print (" <description>"); //NOI18N
539
ps.print (description.getText ());
540
ps.println ("</description>"); //NOI18N
543
// Write manifest attributes.
545
ps.print (" <manifest "); //NOI18N
546
boolean firstline = true;
547
List<String> attrNames = new ArrayList<String>(attr.size());
548
Iterator<Object> it = attr.keySet().iterator();
549
while (it.hasNext()) {
550
attrNames.add(((Attributes.Name)it.next()).toString());
552
Collections.sort(attrNames);
553
for (String name: attrNames) {
554
// Ignore irrelevant attributes (cf. www/www/dtds/autoupdate-catalog-2_0.dtd
555
// and www/www/dtds/autoupdate-info-1_0.dtd):
556
if (! name.startsWith("OpenIDE-Module")) continue; //NOI18N
557
if (name.equals("OpenIDE-Module-Localizing-Bundle")) continue; //NOI18N
558
if (name.equals("OpenIDE-Module-Install")) continue; //NOI18N
559
if (name.equals("OpenIDE-Module-Layer")) continue; //NOI18N
560
if (name.equals("OpenIDE-Module-Description")) continue; //NOI18N
561
if (name.equals("OpenIDE-Module-Package-Dependency-Message")) continue; //NOI18N
562
if (name.equals("OpenIDE-Module-Public-Packages")) continue; //NOI18N
566
ps.print (" "); //NOI18N
567
ps.println(name + "=\"" + xmlEscape(attr.getValue(name)) + "\""); //NOI18N
569
ps.println (" />"); //NOI18N
571
else if( modInfo != null && !modInfo.trim().equals( "")) { //NOI18N
572
String specver, majorver ;
574
// Write the l10n tag and lang/branding codes. //
575
ps.println(" <l10n "); //NOI18N
576
if( langCode != null && !langCode.trim().equals( "")) { //NOI18N
577
ps.println( " langcode=\"" + xmlEscape(langCode) + "\"") ; //NOI18N
579
if( brandingCode != null && !brandingCode.trim().equals( "")) { //NOI18N
580
ps.println( " brandingcode=\"" + xmlEscape(brandingCode) + "\"") ; //NOI18N
583
// Write the major version if possible. //
584
majorver = getMajorVer( modInfo) ;
585
if( majorver != null && !majorver.trim().equals( "")) { //NOI18N
586
ps.println( " module_major_version=\"" + xmlEscape(majorver) + "\"") ; //NOI18N
589
// Write the spec version if possible. //
590
specver = getSpecVer( modInfo) ;
591
if( specver != null && !specver.trim().equals( "")) { //NOI18N
592
ps.println( " module_spec_version=\"" + xmlEscape(specver) + "\"") ; //NOI18N
595
// Read localizing bundle and write relevant attr's. //
596
if( locBundle != null) {
597
writeLocBundleAttrs( ps) ;
600
ps.println( " />") ; //NOI18N
603
// Maybe write out license text.
604
if (license != null) {
605
ps.print (" <license name=\"" + xmlEscape(license.getName ()) + "\">"); //NOI18N
606
ps.print (license.getText ());
607
ps.println ("</license>"); //NOI18N
609
if (notification != null) {
610
ps.print(" <module_notification>"); //NOI18N
611
ps.print(notification.getText());
612
ps.println("</module_notification>"); //NOI18N
614
if (externalPackages != null) {
615
Enumeration<ExternalPackage> exp = externalPackages.elements();
616
while (exp.hasMoreElements()) {
617
ExternalPackage externalPackage = exp.nextElement();
618
if (externalPackage.name == null ||
619
externalPackage.targetName == null ||
620
externalPackage.startUrl == null)
621
throw new BuildException("Must define name, targetname, starturl for external package");
622
ps.print(" <external_package "); //NOI18N
623
ps.print("name=\""+xmlEscape(externalPackage.name)+"\" "); //NOI18N
624
ps.print("target_name=\""+xmlEscape(externalPackage.targetName)+"\" "); //NOI18N
625
ps.print("start_url=\""+xmlEscape(externalPackage.startUrl)+"\""); //NOI18N
626
if (externalPackage.description != null)
627
ps.print(" description=\""+xmlEscape(externalPackage.description)+"\""); //NOI18N
628
ps.println("/>"); //NOI18N
631
ps.println ("</module>"); //NOI18N
636
} catch (IOException e) {
637
throw new BuildException("exception when creating Info/info.xml", e, getLocation());
641
// JAR it all up together.
642
long jarModified = file.lastModified (); // may be 0
643
//log ("Ensuring existence of NBM file " + file);
644
Jar jar = (Jar) getProject().createTask("jar"); //NOI18N
645
jar.setDestFile(file);
646
//jar.setBasedir (topdir.getAbsolutePath ());
647
jar.setCompress(true);
648
//jar.createInclude ().setName ("netbeans/"); //NOI18N
649
//jar.createInclude ().setName ("Info/info.xml"); //NOI18N
650
jar.addFileset (getFileSet());
651
jar.setLocation(getLocation());
655
if (signature != null && file.lastModified () != jarModified) {
656
if (signature.keystore == null)
657
throw new BuildException ("must define keystore attribute on <signature/>");
658
if (signature.storepass == null)
659
throw new BuildException ("must define storepass attribute on <signature/>");
660
if (signature.alias == null)
661
throw new BuildException ("must define alias attribute on <signature/>");
662
if (signature.storepass.equals ("?") || !signature.keystore.exists()) {
663
log ("Not signing NBM file " + file + "; no stored-key password provided or keystore ("
664
+ signature.keystore.toString() + ") doesn't exist", Project.MSG_WARN);
666
log ("Signing NBM file " + file);
667
SignJar signjar = (SignJar) getProject().createTask("signjar"); //NOI18N
668
//I have to use Reflection API, because there was changed API in ANT1.5
671
Class[] paramsT = {String.class};
672
Object[] paramsV1 = {signature.keystore.getAbsolutePath()};
673
Object[] paramsV2 = {file.getAbsolutePath()};
674
signjar.getClass().getDeclaredMethod( "setKeystore", paramsT ).invoke( signjar, paramsV1 ); //NOI18N
675
signjar.getClass().getDeclaredMethod( "setJar", paramsT ).invoke( signjar, paramsV2 ); //NOI18N
676
} catch (NoSuchMethodException ex1) {
679
Class[] paramsT = {File.class};
680
Object[] paramsV1 = {signature.keystore};
681
Object[] paramsV2 = {file};
682
signjar.getClass().getDeclaredMethod( "setKeystore", paramsT ).invoke( signjar, paramsV1 ); //NOI18N
683
signjar.getClass().getDeclaredMethod( "setJar", paramsT ).invoke( signjar, paramsV2 ); //NOI18N
684
} catch (NoSuchMethodException ex2) {
687
Class[] paramsT1 = {File.class};
688
Class[] paramsT2 = {String.class};
689
Object[] paramsV1 = {signature.keystore.getAbsolutePath()};
690
Object[] paramsV2 = {file};
691
signjar.getClass().getDeclaredMethod( "setKeystore", paramsT2 ).invoke( signjar, paramsV1 ); //NOI18N
692
signjar.getClass().getDeclaredMethod( "setJar", paramsT1 ).invoke( signjar, paramsV2 ); //NOI18N
693
} catch (NoSuchMethodException ex3) {
694
throw new BuildException("Unknown Ant version, only Ant 1.6.5+ is currently supported.");
698
} catch (IllegalAccessException ex4) {
699
throw new BuildException(ex4);
700
} catch (java.lang.reflect.InvocationTargetException ex5) {
701
throw new BuildException(ex5);
703
signjar.setStorepass (signature.storepass);
704
signjar.setAlias (signature.alias);
705
signjar.setLocation(getLocation());
712
// Reflection access from MakeListOfNBM:
714
public FileSet getFileSet() {
715
FileSet fs = fileset; //makes in apperance to excludes and includes files defined in XML
718
if (isStandardInclude) {
719
fs.createInclude ().setName ("netbeans/"); //NOI18N
720
fs.createExclude ().setName ("netbeans/update_tracking/*.xml"); //NOI18N
723
fs.createInclude ().setName ("Info/info.xml"); //NOI18N
727
public Attributes getAttributes() throws IOException {
728
if (manifest != null) {
729
InputStream is = new FileInputStream(manifest);
731
return new Manifest(is).getMainAttributes();
735
} else if (module != null) {
736
JarFile jar = new JarFile(module);
738
return jar.getManifest().getMainAttributes();
743
throw new IOException(getLocation() + "must give either 'manifest' or 'module' on <makenbm>");
747
protected String getCodenameBase( String openide_module) {
748
String ret = openide_module ;
749
int idx = ret.indexOf ('/'); //NOI18N
751
ret = ret.substring (0, idx);
756
protected String getSpecVer( String mod_info) {
758
int first_idx, second_idx ;
760
// If there are 2 slashes. //
761
first_idx = mod_info.indexOf( '/') ; //NOI18N
762
if( first_idx != -1) {
763
second_idx = mod_info.indexOf( '/', first_idx+1) ; //NOI18N
764
if( second_idx != -1) {
766
// Return the string after the second slash. //
767
ret = mod_info.substring( second_idx+1, mod_info.length()) ;
771
// Return null rather than an empty string. //
772
if( ret != null && ret.trim().equals( "")) { //NOI18N
778
protected String getMajorVer( String mod_info) {
780
int first_idx, second_idx ;
782
// If there are 2 slashes. //
783
first_idx = mod_info.indexOf( '/') ; //NOI18N
784
if( first_idx != -1) {
785
second_idx = mod_info.indexOf( '/', first_idx+1) ; //NOI18N
786
if( second_idx != -1) {
788
// Return the string between the slashes. //
789
ret = mod_info.substring( first_idx+1, second_idx) ;
792
// Else return the string after the first slash. //
794
ret = mod_info.substring( first_idx+1, mod_info.length()) ;
798
// Return null rather than an empty string. //
799
if( ret != null && ret.trim().equals( "")) { //NOI18N
805
/** For l10n NBM's, this is the localizing bundle file
806
* that we'll look in to get module name, description, etc.
808
public void setLocBundle( File f) {
812
/** See reqManOrMod() */
813
public void setManOrModReq( boolean b) {
815
manOrModReqSet = true ;
818
/** If the manifest and module aren't required, use this
819
* to set the module codename, major version and spec version.
821
public void setModInfo( String s) {
825
/** Set the language code for localized NBM's. */
826
public void setLangCode( String s) {
830
/** Set the branding code for branded NBM's. */
831
public void setBrandingCode( String s) {
835
/** Returns true if either a manifest or a module must be specified.
836
* This is true unless either the global property
837
* makenbm.manOrModReq is false, or the manOrModReq attribute of
838
* this task is false. The attribute, if set, has priority over the
841
public boolean reqManOrMod() {
845
if( manOrModReqSet) {
849
s = getProject().getProperty("makenbm.manOrModReq"); //NOI18N
850
if( s != null && !s.equals( "")) { //NOI18N
851
req = getProject().toBoolean(s);
858
protected void writeLocBundleAttrs( PrintWriter ps) {
859
FileInputStream fis ;
860
Properties p = new Properties() ;
862
boolean hadone = false ;
865
fis = new FileInputStream( locBundle) ;
869
catch( Exception e) {
870
System.out.println( "ERROR: " + e.getMessage()) ;
871
e.printStackTrace() ;
872
throw new BuildException() ;
875
s = p.getProperty( "OpenIDE-Module-Name") ; //NOI18N
876
if( writeProp( "OpenIDE-Module-Name", s, ps)) { //NOI18N
880
s = p.getProperty( "OpenIDE-Module-Long-Description") ; //NOI18N
881
if( writeProp( "OpenIDE-Module-Long-Description", s, ps)) { //NOI18N
886
log( "WARNING: Localizing bundle had neither property: " + locBundle) ;
890
protected boolean writeProp( String name,
893
boolean ret = false ;
895
ps.println( name + "=\"" + xmlEscape(val) +"\"") ; //NOI18N