/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License.
*/
/** Makes a localized <code>.nbm</code> (<b>N</b>et<b>B</b>eans <b>M</b>odule) file. * This version is temporary, intended to be used only until * the functionality added to this version since rev 1.29 * of MakeNBM.java can be added into MakeNBM.java * * @author Jerry Huth (email: jerry@solidstep.com)
*/ publicclass MakeLNBM extends MatchingTask {
/** The same syntax may be used for either <samp><license></samp> or * <samp><description></samp> subelements. * <p>By setting the property <code>makenbm.nocdata</code> to <code>true</code>, * you can avoid using XML <code>CDATA</code> (for compatibility with older versions * of Auto Update which could not handle it).
*/ publicclass Blurb { /** You may embed a <samp><file></samp> element inside the blurb. * If there is text on either side of it, that will be separated * with a line of dashes automatically. * But use nested <samp><text></samp> for this purpose.
*/ publicclass FileInsert { /** File location. */ publicvoid setLocation (File file) throws BuildException {
log("Including contents of " + file, Project.MSG_VERBOSE); long lmod = file.lastModified (); if (lmod > mostRecentInput) mostRecentInput = lmod;
addSeparator (); try { try (InputStream is = new FileInputStream (file)) {
Reader r = new InputStreamReader (is, "UTF-8"); //NOI18N char[] buf = newchar[4096]; int len; while ((len = r.read (buf)) != -1)
text.append (buf, 0, len);
}
} catch (IOException ioe) { thrownew BuildException ("Exception reading blurb from " + file, ioe, getLocation ());
}
}
} private StringBuffer text = new StringBuffer (); private String name = null; /** There may be freeform text inside the element. Prefer to use nested elements. */ publicvoid addText (String t) {
addSeparator (); // Strips indentation. Needed because of common style: // <description> // Some text here. // And another line. // </description>
t = getProject().replaceProperties(t.trim()); int min = Integer.MAX_VALUE;
StringTokenizer tok = new StringTokenizer (t, "\n"); //NOI18N boolean first = true; while (tok.hasMoreTokens ()) {
String line = tok.nextToken (); if (first) {
first = false;
} else { int i; for (i = 0;
i < line.length () &&
Character.isWhitespace (line.charAt (i));
i++)
; if (i < min) min = i;
}
} if (min == 0) {
text.append (t);
} else {
tok = new StringTokenizer (t, "\n"); //NOI18N
first = true; while (tok.hasMoreTokens ()) {
String line = tok.nextToken (); if (first) {
first = false;
} else {
text.append ('\n'); //NOI18N
line = line.substring (min);
}
text.append (line);
}
}
} /** Contents of a file to include. */ public FileInsert createFile () { returnnew FileInsert ();
} /** Text to include literally. */ publicclass Text { publicvoid addText(String t) {
Blurb.this.addText(t);
}
} // At least on Ant 1.3, mixed content does not work: all the text is added // first, then all the file inserts. Need to use subelements to be sure. /** Include nested literal text. */ public Text createText() { returnnew Text();
} privatevoid addSeparator () { if (text.length () > 0) { // some sort of separator if (text.charAt (text.length () - 1) != '\n') //NOI18N
text.append ('\n'); //NOI18N
text.append ("-----------------------------------------------------\n"); //NOI18N
}
} public String getText () {
String nocdata = getProject().getProperty("makenbm.nocdata"); //NOI18N if (nocdata != null && Project.toBoolean(nocdata)) { return xmlEscape(text.toString());
} else { return" + text.toString () + "]]>"; //NOI18N
}
} /** You can either set a name for the blurb, or using the <code>file</code> attribute does this. * The name is mandatory for licenses, as this identifies the license in * an update description.
*/ publicvoid setName (String name) { this.name = name;
} public String getName () { return name;
} /** Include a file (and set the license name according to its basename). */ publicvoid setFile (File file) { // This actually adds the text and so on: new FileInsert ().setLocation (file); // Default for the name too, as a convenience. if (name == null) name = file.getName ();
}
}
// Similar to org.openide.xml.XMLUtil methods. privatestatic String xmlEscape(String s) { int max = s.length();
StringBuffer s2 = new StringBuffer((int)(max * 1.1 + 1)); for (int i = 0; i < max; i++) { char c = s.charAt(i); switch (c) { case'<': //NOI18N
s2.append("<"); //NOI18N break; case'>': //NOI18N
s2.append(">"); //NOI18N break; case'&': //NOI18N
s2.append("&"); //NOI18N break; case'"': //NOI18N
s2.append("""); //NOI18N break; default:
s2.append(c); break;
}
} return s2.toString();
}
/** <samp><signature></samp> subelement for signing the NBM. */ public/*static*/ class Signature { public File keystore; public String storepass, alias; /** Path to the keystore (private key). */ publicvoid setKeystore (File f) {
keystore = f;
} /** Password for the keystore. * If a question mark (<samp>?</samp>), the NBM will not be signed * and a warning will be printed.
*/ publicvoid setStorepass (String s) {
storepass = s;
} /** Alias for the private key. */ publicvoid setAlias (String s) {
alias = s;
}
}
/** Include netbeans directory - default is true */ publicvoid setIsStandardInclude(boolean isStandardInclude) { this.isStandardInclude = isStandardInclude;
}
/** Name of resulting NBM file. */ publicvoid setFile (File file) { this.file = file;
} /** Top directory. * Expected to contain a subdirectory <samp>netbeans/</samp> with the * desired contents of the NBM. * Will create <samp>Info/info.xml</samp> with metadata.
*/ publicvoid setTopdir (File topdir) { this.topdir = topdir;
} /** Module manifest needed for versioning. * @deprecated Use {@link #setModule} instead.
*/
@Deprecated publicvoid setManifest (File manifest) { this.manifest = manifest; long lmod = manifest.lastModified (); if (lmod > mostRecentInput) mostRecentInput = lmod;
log(getLocation() + "The 'manifest' attr on is deprecated, please use 'module' instead", Project.MSG_WARN);
} /** Module JAR needed for generating the info file. * Information may be gotten either from its manifest, * or if it declares OpenIDE-Module-Localizing-Bundle in its * manifest, from that bundle. * The base locale variant, if any, is also checked if necessary * for the named bundle. * Currently no other locale variants of the module are examined; * the information is available but there is no published specification * of what the resulting variant NBMs (or variant information within * the NBM) should look like.
*/ publicvoid setModule(File module) { this.module = module; // mostRecentInput updated below...
} /** URL to a home page describing the module. */ publicvoid setHomepage (String homepage) { this.homepage = homepage;
} /** Does module need IDE restart to be installed? */ publicvoid setNeedsrestart (String needsrestart) { this.needsrestart = needsrestart;
} /** URL where this NBM file is expected to be downloadable from. */ publicvoid setDistribution (String distribution) throws BuildException { if (distribution.startsWith("http://")) { //NOI18N this.distribution = distribution;
} elseif (!(distribution.equals(""))) { // workaround for typical bug in build script this.distribution = "http://" + distribution; //NOI18N
} else { thrownew BuildException("Distribution URL is empty, check build.xml file", getLocation());
} // check the URL try {
URI uri = java.net.URI.create(this.distribution);
} catch (IllegalArgumentException ile) { thrownew BuildException("Distribution URL \"" + this.distribution + "\" is not a valid URI", ile, getLocation());
}
} public Blurb createLicense () { return (license = new Blurb ());
} public Blurb createNotification () { return (notification = new Blurb ());
} public Blurb createDescription () {
log(getLocation() + "The subelement in is deprecated except for emergency patches, please ensure your module has an OpenIDE-Module-Long-Description instead", Project.MSG_WARN); return (description = new Blurb ());
} public Signature createSignature () { return (signature = new Signature ());
}
public ExternalPackage createExternalPackage(){
ExternalPackage externalPackage = new ExternalPackage (); if (externalPackages == null)
externalPackages = new Vector<>();
externalPackages.add( externalPackage ); return externalPackage;
}
publicvoid execute () throws BuildException { if (file == null) { thrownew BuildException("must set file for makenbm", getLocation());
} if (manifest == null && module == null && reqManOrMod()) { thrownew BuildException("must set module for makenbm", getLocation());
} if (manifest != null && module != null) { thrownew BuildException("cannot set both manifest and module for makenbm", getLocation());
} // Will create a file Info/info.xml to be stored alongside netbeans/ contents.
File infodir = new File (topdir, "Info"); //NOI18N
infodir.mkdirs ();
File infofile = new File (infodir, "info.xml"); //NOI18N if (infofile.exists ()) {
infofile.delete();
}
Attributes attr = null; if (module != null) { // The normal case; read attributes from its manifest and maybe bundle. long mMod = module.lastModified(); if (mostRecentInput < mMod) mostRecentInput = mMod; try { try (JarFile modulejar = new JarFile(module)) {
attr = modulejar.getManifest().getMainAttributes();
String bundlename = attr.getValue("OpenIDE-Module-Localizing-Bundle"); //NOI18N if (bundlename != null) {
Properties p = new Properties();
ZipEntry bundleentry = modulejar.getEntry(bundlename); if (bundleentry != null) { try (InputStream is = modulejar.getInputStream(bundleentry)) {
p.load(is);
}
} else { // Not found in main JAR, check locale variant JAR.
File variant = new File(new File(module.getParentFile(), "locale"), module.getName()); //NOI18N if (!variant.isFile()) thrownew BuildException(bundlename + " not found in " + module, getLocation()); long vmMod = variant.lastModified(); if (mostRecentInput < vmMod) mostRecentInput = vmMod; try (ZipFile variantjar = new ZipFile(variant)) {
bundleentry = variantjar.getEntry(bundlename); if (bundleentry == null) thrownew BuildException(bundlename + " not found in " + module + " nor in " + variant, getLocation());
InputStream is = variantjar.getInputStream(bundleentry); try {
p.load(is);
} finally {
is.close();
}
}
} // Now pick up attributes from the bundle. for(String key: p.stringPropertyNames()) { if(key.startsWith("OpenIDE-Module-")) {
attr.putValue(key, p.getProperty(key));
}
}
} // else all loc attrs in main manifest, OK
}
} catch (IOException ioe) { thrownew BuildException("exception while reading " + module, ioe, getLocation());
}
} // else we will read attr later if info file is out of date boolean skipInfo = false; if (infofile.exists ()) { // Check for up-to-date w.r.t. manifest and maybe license file. long iMod = infofile.lastModified (); if (mostRecentInput < iMod)
skipInfo = true;
} if (! skipInfo) {
log ("Creating NBM info file " + infofile); if (manifest != null) { // Read module manifest for main attributes. try { try (InputStream manifestStream = new FileInputStream (manifest)) {
attr = new Manifest (manifestStream).getMainAttributes ();
}
} catch (IOException e) { thrownew BuildException("exception when reading manifest " + manifest, e, getLocation());
}
} // else we read attr before try { try (OutputStream infoStream = new FileOutputStream (infofile)) {
PrintWriter ps = new PrintWriter(new OutputStreamWriter(infoStream, "UTF-8")); // Begin writing XML.
ps.println ("1.0\" encoding=\"UTF-8\"?>"); //NOI18N
ps.println("-//NetBeans//DTD Autoupdate Module Info 2.4//EN\" \"http://www.netbeans.org/dtds/autoupdate-info-2_4.dtd\">"); //NOI18N if( attr != null) {
String codenamebase = attr.getValue ("OpenIDE-Module"); //NOI18N if (codenamebase == null) thrownew BuildException("invalid manifest, does not contain OpenIDE-Module", getLocation()); // Strip major release number if any.
codenamebase = getCodenameBase( codenamebase) ;
ps.println ("" + xmlEscape(codenamebase) + "\""); //NOI18N
} else {
ps.print( "); //NOI18N if( modInfo != null && !modInfo.trim().equals( "")) {
String codenamebase = getCodenameBase( modInfo) ;
ps.println( "codenamebase=\"" + xmlEscape(codenamebase) + "\""); //NOI18N
} else {
ps.println( "") ; //NOI18N
}
} if (homepage != null)
ps.println (" homepage=\"" + xmlEscape(homepage) + "\""); //NOI18N if (distribution != null) {
ps.println (" distribution=\"" + xmlEscape(distribution) + "\""); //NOI18N
} else { thrownew BuildException("NBM distribution URL is not set", getLocation());
} // Here we only write a name for the license. if (license != null) {
String name = license.getName (); if (name == null) thrownew BuildException("Every license must have a name or file attribute", getLocation());
ps.println (" license=\"" + xmlEscape(name) + "\""); //NOI18N
}
ps.println (" downloadsize=\"0\""); //NOI18N if (needsrestart != null)
ps.println (" needsrestart=\"" + xmlEscape(needsrestart) + "\""); //NOI18N
ps.println (">"); //NOI18N if (description != null) {
ps.print (" "); //NOI18N
ps.print (description.getText ());
ps.println (""); //NOI18N
}
// Write manifest attributes. if( attr != null) {
ps.print (" ); //NOI18N boolean firstline = true;
List<String> attrNames = new ArrayList<>(attr.size());
Iterator<Object> it = attr.keySet().iterator(); while (it.hasNext()) {
attrNames.add(((Attributes.Name)it.next()).toString());
}
Collections.sort(attrNames); for (String name: attrNames) { // Ignore irrelevant attributes (cf. www/www/dtds/autoupdate-catalog-2_0.dtd // and www/www/dtds/autoupdate-info-1_0.dtd): if (! name.startsWith("OpenIDE-Module")) continue; //NOI18N if (name.equals("OpenIDE-Module-Localizing-Bundle")) continue; //NOI18N if (name.equals("OpenIDE-Module-Install")) continue; //NOI18N if (name.equals("OpenIDE-Module-Layer")) continue; //NOI18N if (name.equals("OpenIDE-Module-Description")) continue; //NOI18N if (name.equals("OpenIDE-Module-Package-Dependency-Message")) continue; //NOI18N if (name.equals("OpenIDE-Module-Public-Packages")) continue; //NOI18N if (firstline)
firstline = false; else
ps.print (" "); //NOI18N
ps.println(name + "=\"" + xmlEscape(attr.getValue(name)) + "\""); //NOI18N
}
ps.println (" />"); //NOI18N
} elseif( modInfo != null && !modInfo.trim().equals( "")) { //NOI18N
String specver, majorver ;
public Attributes getAttributes() throws IOException { if (manifest != null) { try (InputStream is = new FileInputStream(manifest)) { returnnew Manifest(is).getMainAttributes();
}
} elseif (module != null) { try (JarFile jar = new JarFile(module)) { return jar.getManifest().getMainAttributes();
}
} else { thrownew IOException(getLocation() + "must give either 'manifest' or 'module' on ");
}
}
protected String getCodenameBase( String openide_module) {
String ret = openide_module ; int idx = ret.indexOf ('/'); //NOI18N if (idx != -1) {
ret = ret.substring (0, idx);
} return( ret) ;
}
protected String getSpecVer( String mod_info) {
String ret = null ; int first_idx, second_idx ;
// If there are 2 slashes. //
first_idx = mod_info.indexOf( '/') ; //NOI18N if( first_idx != -1) {
second_idx = mod_info.indexOf( '/', first_idx+1) ; //NOI18N if( second_idx != -1) {
// Return the string after the second slash. //
ret = mod_info.substring( second_idx+1, mod_info.length()) ;
}
}
// Return null rather than an empty string. // if( ret != null && ret.trim().equals( "")) { //NOI18N
ret = null ;
} return( ret) ;
}
protected String getMajorVer( String mod_info) {
String ret = null ; int first_idx, second_idx ;
// If there are 2 slashes. //
first_idx = mod_info.indexOf( '/') ; //NOI18N if( first_idx != -1) {
second_idx = mod_info.indexOf( '/', first_idx+1) ; //NOI18N if( second_idx != -1) {
// Return the string between the slashes. //
ret = mod_info.substring( first_idx+1, second_idx) ;
}
// Else return the string after the first slash. // else {
ret = mod_info.substring( first_idx+1, mod_info.length()) ;
}
}
// Return null rather than an empty string. // if( ret != null && ret.trim().equals( "")) { //NOI18N
ret = null ;
} return( ret) ;
}
/** For l10n NBM's, this is the localizing bundle file * that we'll look in to get module name, description, etc.
*/ publicvoid setLocBundle( File f) {
locBundle = f ;
}
/** See reqManOrMod() */ publicvoid setManOrModReq( boolean b) {
manOrModReq = b ;
manOrModReqSet = true ;
}
/** If the manifest and module aren't required, use this * to set the module codename, major version and spec version.
*/ publicvoid setModInfo( String s) {
modInfo = s ;
}
/** Set the language code for localized NBM's. */ publicvoid setLangCode( String s) {
langCode = s ;
}
/** Set the branding code for branded NBM's. */ publicvoid setBrandingCode( String s) {
brandingCode = s ;
}
/** Returns true if either a manifest or a module must be specified. * This is true unless either the global property * makenbm.manOrModReq is false, or the manOrModReq attribute of * this task is false. The attribute, if set, has priority over the * global property.
*/ publicboolean reqManOrMod() { boolean req = true ;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.