/* * 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.
*/
/** Set the location of <samp>jhall.jar</samp> or <samp>jsearch.jar</samp> (JavaHelp tools library). */ public Path createClasspath() { // JavaHelp release notes say jhtools.jar is enough, but class NoClassDefFoundError // on javax.help.search.IndexBuilder when I tried it... if (classpath == null) {
classpath = new Path(getProject());
} return classpath.createPath();
}
/** Set the location of the output database. * E.g. <samp>JavaHelpSearch</samp>). * <strong>Warning:</strong> the directory will be deleted and recreated.
*/ publicvoid setDb (File db) { this.db = db;
}
/** Set the base directory from which to scan files. * This should be the directory containing the helpset for the database to work correctly.
*/ publicvoid setBasedir (File basedir) { this.basedir = basedir;
} publicvoid setLocale (String locale) { this.locale = locale;
}
/** * A set of additional files forming a branding variant. * @see #addBrandedFileSet
*/ publicstaticfinalclass BrandedFileSet extends FileSet {
String branding; publicvoid setBranding(String b) { this.branding = b;
}
}
/** * Add a set of branded files to be indexed. * For example, you may have in <samp>/the/base/dir</samp> * <ul> * <li><samp>foo.html</samp> * <li><samp>bar.html</samp> * <li><samp>baz.html</samp> * </ul> * Now create a new directory <samp>/the/new/dir</samp>: * <ul> * <li><samp>foo_brand.html</samp> * <li><samp>baz_brand.html</samp> * </ul> * If you include this with: * <pre> <jhindexer basedir="/the/base/dir"> <include name="**/*.html"/> <brandedfileset dir="/the/new/dir" branding="brand"> <include name="**/*.html"/> </brandedfileset> </jhindexer> * </pre> * then the search database will contain entries: * <table border="1"> * <tr><th>JH name</th><th>From file</th></tr> * <tr><td><samp>foo.html</samp></td><td><samp>/the/new/dir/foo_brand.html</samp></td></tr> * <tr><td><samp>bar.html</samp></td><td><samp>/the/base/dir/bar.html</samp></td></tr> * <tr><td><samp>baz.html</samp></td><td><samp>/the/new/dir/baz_brand.html</samp></td></tr> * </table> * and every file in the database (<samp>TMAP</samp> etc.) * will receive the special suffix <samp>_brand</samp>. * <p>You may give multiple branding filesets, so long as the branding * tokens supplied are nested: i.e. for every pair of tokens among the supplied * filesets, one is a prefix of the other (with <samp>_</samp> being the * separator between the prefix and suffix). The search database suffix is then * an underscore followed by the longest branding token. * <p>Such a database is suitable for branding NetBeans: consider a module * with documentation entries such as the following: * <ul> * <li><samp>modules/docs/foo.jar!/some/pkg/foo/foo.html</samp> * <li><samp>modules/docs/foo.jar!/some/pkg/foo/bar.html</samp> * <li><samp>modules/docs/foo.jar!/some/pkg/foo/baz.html</samp> * <li><samp>modules/docs/foo.jar!/some/pkg/foo/JavaHelpSearch/TMAP</samp> (etc.) * <li><samp>modules/docs/locale/foo_brand.jar!/some/pkg/foo/foo_brand.html</samp> * <li><samp>modules/docs/locale/foo_brand.jar!/some/pkg/foo/baz_brand.html</samp> * <li><samp>modules/docs/locale/foo_brand.jar!/some/pkg/foo/JavaHelpSearch/TMAP_brand</samp> (etc.) * </ul> * where the files in <samp>modules/docs/foo.jar!/some/pkg/foo/JavaHelpSearch/</samp> * were generated by a regular invocation of this task and the files in * <samp>modules/docs/locale/foo_brand.jar!/some/pkg/foo/JavaHelpSearch/</samp> * were generated by the variant above. Then a help set reference using a URL such as * <samp>nbdocs:/some/pkg/foo/helpset.xml</samp> will, when running with branding * <samp>brand</samp>, not only display the expected variants of <samp>foo.html</samp> * and <samp>baz.html</samp>, but be able to search for strings specifically in them * (including correct offsets). * @see <a href="http://www.netbeans.org/issues/show_bug.cgi?id=31044">Issue #31044</a>
*/ publicvoid addBrandedFileSet(BrandedFileSet s) {
brandings.add(s);
}
/** @deprecated Use {@link #createClasspath} instead. */
@Deprecated publicvoid setJhall(File f) {
log("The 'jhall' attribute to is deprecated. Use a nested instead.", Project.MSG_WARN);
createClasspath().setLocation(f);
}
public @Override void execute() throws BuildException { if (classpath == null) { thrownew BuildException ("Must specify the classpath attribute to find jhall.jar or jsearch.jar");
} if (db == null) { thrownew BuildException ("Must specify the db attribute");
} if (basedir == null) { thrownew BuildException ("Must specify the basedir attribute");
}
FileScanner scanner = getDirectoryScanner (basedir);
scanner.scan ();
String[] files = scanner.getIncludedFiles (); // First, an up-to-date check. ;-) if (basedir.exists () && db.exists ()) { long lastModified = Long.MIN_VALUE; // First scan output dir for any files.
FileScanner output = new DirectoryScanner ();
output.setBasedir (db);
output.scan ();
String[] outfiles = output.getIncludedFiles (); if (outfiles.length > 0) { for (int i = 0; i < outfiles.length; i++) { long mod = new File (db, outfiles[i]).lastModified (); if (mod > lastModified) {
lastModified = mod;
}
} // Now check to see if any source files are newer. boolean ok = true; for (int i = 0; i < files.length; i++) { long mod = new File (basedir, files[i]).lastModified (); if (mod > lastModified) {
ok = false; break;
}
} if (!brandings.isEmpty()) { // Check these too! for(FileSet fs: brandings) {
FileScanner scanner2 = fs.getDirectoryScanner(getProject());
String[] files2 = scanner2.getIncludedFiles(); for (int i = 0; i < files2.length; i++) { long mod = new File (basedir, files2[i]).lastModified (); if (mod > lastModified) {
ok = false; break;
}
}
}
} if (ok) { // No need to rebuild. return;
}
}
} Deletedelete = (Delete) getProject().createTask("delete"); delete.setDir (db); delete.init (); delete.setLocation(getLocation()); delete.execute ();
Mkdir mkdir = (Mkdir) getProject().createTask("mkdir");
mkdir.setDir (db);
mkdir.init ();
mkdir.setLocation(getLocation());
mkdir.execute ();
String maxbranding = null; if (!brandings.isEmpty()) { // Copy all files, overriding by branding, to a fresh dir somewhere. // Does not suffice to simply use IndexRemove to strip off the basedirs // of files in branded filesets, since their filenames will also include // the branding token, and this will mess up the search database: it needs // to store just the simple file name with no branding infix.
File tmp = new File(System.getProperty("java.io.tmpdir"), "jhindexer-branding-merge"); delete = (Delete) getProject().createTask("delete"); delete.setDir(tmp); delete.init(); delete.setLocation(getLocation()); delete.execute();
tmp.mkdir(); // Start with the base files.
Copy copy = (Copy) getProject().createTask("copy");
copy.setTodir(tmp);
copy.addFileset(fileset);
copy.init();
copy.setLocation(getLocation());
copy.execute(); // Now branded filesets. Must be done in order of branding, so that // more specific files override generic ones. class BrandingLengthComparator implements Comparator<BrandedFileSet> { publicint compare(BrandedFileSet a, BrandedFileSet b) { return a.branding.length() - b.branding.length();
}
}
Collections.sort(brandings, new BrandingLengthComparator()); for (BrandedFileSet s: brandings) { if (maxbranding != null && !s.branding.startsWith(maxbranding + "_")) { thrownew BuildException("Illegal branding: " + s.branding, getLocation());
}
maxbranding = s.branding; // only last one will be kept
String[] suffixes = { ".html", ".htm", ".xhtml", // XXX any others? unpleasant to hardcode but this is easiest, // since glob mappers do not permit *_x* -> ** syntax.
}; for (int i = 0; i < suffixes.length; i++) {
String suffix = suffixes[i];
copy = (Copy) getProject().createTask("copy");
copy.setTodir(tmp);
copy.setOverwrite(true);
copy.addFileset(s);
Mapper m = copy.createMapper();
Mapper.MapperType mt = new Mapper.MapperType();
mt.setValue("glob");
m.setType(mt);
m.setFrom("*_" + s.branding + suffix);
m.setTo("*" + suffix);
copy.init();
copy.setLocation(getLocation());
copy.execute(); if (locale != null) { // Possibly have e.g. x_f4j_ja.html.
suffix = "_" + locale + suffix;
copy = (Copy) getProject().createTask("copy");
copy.setTodir(tmp);
copy.setOverwrite(true);
copy.addFileset(s);
m = copy.createMapper();
mt = new Mapper.MapperType();
mt.setValue("glob");
m.setType(mt);
m.setFrom("*_" + s.branding + suffix);
m.setTo("*" + suffix);
copy.init();
copy.setLocation(getLocation());
copy.execute();
}
}
} // Now replace basedir & files with this temp dir.
basedir = tmp;
FileSet tmpf = new FileSet();
tmpf.setProject(getProject());
tmpf.setDir(tmp);
files = tmpf.getDirectoryScanner(getProject()).getIncludedFiles();
}
log ("Running JavaHelp search database indexer..."); try {
File config = File.createTempFile ("jhindexer-config", ".txt"); try { try (OutputStream os = new FileOutputStream (config)) {
PrintWriter pw = new PrintWriter (os);
pw.println ("IndexRemove " + basedir + File.separator);
String message = "Files to be indexed:"; for (int i = 0; i < files.length; i++) { // [PENDING] JavaHelp docs say to use / as file sep for File directives; // so what should the complete path be? Someone should test this on Windoze...
String path = basedir + File.separator + files[i];
pw.println ("File " + path);
message += "\n\t" + path;
}
log (message, Project.MSG_VERBOSE);
pw.flush ();
}
AntClassLoader loader = new AntClassLoader(getProject(), classpath);
loader.addLoaderPackageRoot("com.sun.java.help.search"); try { Class<?> clazz = loader.loadClass("com.sun.java.help.search.Indexer");
Method main = clazz.getMethod("main", String[].class);
List<String> args = Arrays.asList( "-c", config.getAbsolutePath(), "-db", db.getAbsolutePath()
); if (locale != null) {
args = new ArrayList<>(args); // #35244
args.add("-locale");
args.add(locale);
}
main.invoke(null, new Object[] {args.toArray(new String[args.size()])});
} catch (InvocationTargetException ite) { thrownew BuildException(ite.getTargetException(), getLocation());
} catch (Exception e) { // ClassNotFoundException, NoSuchMethodException, ... thrownew BuildException(e, getLocation());
}
} finally {
config.delete ();
}
} catch (IOException ioe) { thrownew BuildException("Could not make temporary config file", ioe, getLocation());
} if (maxbranding != null) { // Now rename search DB files to include branding suffix. // Note that DOCS.TAB -> DOCS_brand.TAB to work with nbdocs: protocol.
String[] dbfiles = db.list(); for (int i = 0; i < dbfiles.length; i++) {
String basename, ext; int idx = dbfiles[i].lastIndexOf('.'); if (idx != -1) {
basename = dbfiles[i].substring(0, idx);
ext = dbfiles[i].substring(idx);
} else {
basename = dbfiles[i];
ext = "";
}
File old = new File(db, dbfiles[i]);
File nue = new File(db, basename + "_" + maxbranding + ext);
log("Moving " + old + " to " + nue, Project.MSG_VERBOSE);
old.renameTo(nue);
}
}
}
}
Messung V0.5
¤ Dauer der Verarbeitung: 0.2 Sekunden
(vorverarbeitet)
¤
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.