Introducing ability to store classpath and "external" jars in the index.
1.1 --- a/remoting/server/indexer/impl/src/org/netbeans/modules/jackpot30/backend/impl/OptionProcessorImpl.java Fri Sep 28 07:12:24 2012 +0200
1.2 +++ b/remoting/server/indexer/impl/src/org/netbeans/modules/jackpot30/backend/impl/OptionProcessorImpl.java Mon Oct 01 08:59:20 2012 -0700
1.3 @@ -48,6 +48,7 @@
1.4 import java.io.InputStream;
1.5 import java.util.Arrays;
1.6 import java.util.Collections;
1.7 +import java.util.HashMap;
1.8 import java.util.HashSet;
1.9 import java.util.Map;
1.10 import java.util.Map.Entry;
1.11 @@ -64,6 +65,8 @@
1.12 import org.apache.lucene.store.FSDirectory;
1.13 import org.netbeans.api.java.classpath.ClassPath;
1.14 import org.netbeans.api.java.classpath.GlobalPathRegistry;
1.15 +import org.netbeans.api.java.queries.SourceForBinaryQuery;
1.16 +import org.netbeans.api.java.queries.SourceForBinaryQuery.Result2;
1.17 import org.netbeans.api.java.source.SourceUtils;
1.18 import org.netbeans.api.project.Project;
1.19 import org.netbeans.api.project.ProjectManager;
1.20 @@ -100,6 +103,7 @@
1.21 private final Option CACHE_TARGET = Option.requiredArgument(Option.NO_SHORT_NAME, "cache-target");
1.22 private final Option INFO = Option.requiredArgument(Option.NO_SHORT_NAME, "info");
1.23 private final Set<Option> OPTIONS = new HashSet<Option>(Arrays.asList(CATEGORY_ID, CATEGORY_NAME, CATEGORY_PROJECTS, CATEGORY_ROOT_DIR, CACHE_TARGET, INFO));
1.24 + private final boolean STORE_CLASSPATH = Boolean.getBoolean("jackpot.store.classpath");
1.25
1.26 @Override
1.27 protected Set<Option> getOptions() {
1.28 @@ -147,6 +151,8 @@
1.29
1.30 FileObject cacheFolder = CacheFolder.getCacheFolder();
1.31 FileObject cacheTemp = cacheFolder.getFileObject("index");
1.32 + Map<String, String> classpath;
1.33 + Map<FileObject, String> extraJars = new HashMap<FileObject, String>();
1.34
1.35 try {
1.36 if (cacheTemp != null) cacheTemp.delete();
1.37 @@ -157,7 +163,7 @@
1.38 IndexAccessor.current = new IndexAccessor(w, baseDir);
1.39 Set<FileObject> roots = getRoots(optionValues.get(CATEGORY_PROJECTS), env);
1.40
1.41 - indexProjects(roots, env);
1.42 + classpath = indexProjects(roots, extraJars, env);
1.43 } catch (InterruptedException ex) {
1.44 LOG.log(Level.FINE, null, ex);
1.45 throw (CommandException) new CommandException(0).initCause(ex);
1.46 @@ -255,6 +261,26 @@
1.47 out.write("\n}\n".getBytes("UTF-8"));
1.48 out.write("\n}\n".getBytes("UTF-8"));
1.49
1.50 + if (STORE_CLASSPATH) {
1.51 + out.putNextEntry(new ZipEntry(categoryId + "/classpath"));
1.52 +
1.53 + for (Entry<String, String> e : classpath.entrySet()) {
1.54 + out.write((e.getKey() + "=" + e.getValue() + "\n").getBytes("UTF-8"));
1.55 + }
1.56 +
1.57 + for (Entry<FileObject, String> ej : extraJars.entrySet()) {
1.58 + out.putNextEntry(new ZipEntry(categoryId + "/" + ej.getValue()));
1.59 +
1.60 + InputStream jarIn = ej.getKey().getInputStream();
1.61 +
1.62 + try {
1.63 + FileUtil.copy(jarIn, out);
1.64 + } finally {
1.65 + jarIn.close();
1.66 + }
1.67 + }
1.68 + }
1.69 +
1.70 for (FileObject s : cacheFolder.getChildren()) {
1.71 if (!s.isFolder() || !s.getNameExt().startsWith("s") || s.getChildren().length == 0) continue;
1.72
1.73 @@ -346,9 +372,10 @@
1.74 return sourceRoots;
1.75 }
1.76
1.77 - private void indexProjects(Set<FileObject> sourceRoots, Env env) throws IOException, InterruptedException {
1.78 + private Map<String, String> indexProjects(Set<FileObject> sourceRoots, Map<FileObject, String> extraJars, Env env) throws IOException, InterruptedException {
1.79 if (sourceRoots.isEmpty()) {
1.80 env.getErrorStream().println("Error: There is nothing to index!");
1.81 + return Collections.emptyMap();
1.82 } else {
1.83 //XXX: to start up the project systems and RepositoryUpdater:
1.84 ((Runnable) OpenProjects.getDefault().openProjects()).run();
1.85 @@ -358,7 +385,63 @@
1.86 LOG.log(Level.FINE, "Registering as source path: {0}", source.toString());
1.87 GlobalPathRegistry.getDefault().register(ClassPath.SOURCE, new ClassPath[] {source});
1.88 SourceUtils.waitScanFinished();
1.89 + Map<String, String> classpath = new HashMap<String, String>();
1.90 +
1.91 + if (STORE_CLASSPATH) {
1.92 + long extraJarCounter = 0;
1.93 +
1.94 + for (FileObject sourceRoot : sourceRoots) {
1.95 + StringBuilder cp = new StringBuilder();
1.96 + ClassPath sourceCP = ClassPath.getClassPath(sourceRoot, ClassPath.SOURCE);
1.97 +
1.98 + if (sourceCP != null) {
1.99 + for (ClassPath.Entry e : sourceCP.entries()) {
1.100 + cp.append(CacheFolder.getDataFolder(e.getURL()).getNameExt());
1.101 + cp.append(":");
1.102 + }
1.103 + }
1.104 +
1.105 + ClassPath compileCP = ClassPath.getClassPath(sourceRoot, ClassPath.COMPILE);
1.106 +
1.107 + if (compileCP != null) {
1.108 + for (ClassPath.Entry e : compileCP.entries()) {
1.109 + Result2 sourceMapping = SourceForBinaryQuery.findSourceRoots2(e.getURL());
1.110 +
1.111 + if (sourceMapping.preferSources() && /*XXX:*/ sourceMapping.getRoots().length > 0) {
1.112 + for (FileObject sr : sourceMapping.getRoots()) {
1.113 + cp.append(CacheFolder.getDataFolder(sr.toURL()).getNameExt());
1.114 + cp.append(":");
1.115 + }
1.116 + } else {
1.117 + FileObject root = e.getRoot();
1.118 + FileObject jar = FileUtil.getArchiveFile(root);
1.119 +
1.120 + if (jar != null) root = jar;
1.121 +
1.122 + if (root != null && root.isData()) { //XXX: class folders
1.123 + String rootId = extraJars.get(root);
1.124 +
1.125 + if (rootId == null) {
1.126 + extraJars.put(root, rootId = "ej" + extraJarCounter++ + ".jar");
1.127 + }
1.128 +
1.129 + cp.append(rootId);
1.130 + cp.append(":");
1.131 + }
1.132 + }
1.133 + }
1.134 + }
1.135 +
1.136 + if (cp.length() > 0)
1.137 + cp.deleteCharAt(cp.length() - 1);
1.138 +
1.139 + classpath.put(CacheFolder.getDataFolder(sourceRoot.toURL()).getNameExt(), cp.toString());
1.140 + }
1.141 + }
1.142 +
1.143 GlobalPathRegistry.getDefault().unregister(ClassPath.SOURCE, new ClassPath[] {source});
1.144 +
1.145 + return classpath;
1.146 }
1.147 }
1.148