You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@netbeans.apache.org by po...@apache.org on 2017/09/03 17:33:13 UTC
[20/51] [partial] incubator-netbeans-jackpot30 git commit:
INFRA-15006 Import for http://bits.netbeans.org/download/apache-donation
http://git-wip-us.apache.org/repos/asf/incubator-netbeans-jackpot30/blob/9ed0a377/remoting/ide/usages/src/org/netbeans/modules/jackpot30/ide/usages/RemoteUsages.java
----------------------------------------------------------------------
diff --git a/remoting/ide/usages/src/org/netbeans/modules/jackpot30/ide/usages/RemoteUsages.java b/remoting/ide/usages/src/org/netbeans/modules/jackpot30/ide/usages/RemoteUsages.java
new file mode 100644
index 0000000..06bbd03
--- /dev/null
+++ b/remoting/ide/usages/src/org/netbeans/modules/jackpot30/ide/usages/RemoteUsages.java
@@ -0,0 +1,491 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2011 Oracle and/or its affiliates. All rights reserved.
+ *
+ * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
+ * Other names may be trademarks of their respective owners.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common
+ * Development and Distribution License("CDDL") (collectively, the
+ * "License"). You may not use this file except in compliance with the
+ * License. You can obtain a copy of the License at
+ * http://www.netbeans.org/cddl-gplv2.html
+ * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
+ * specific language governing permissions and limitations under the
+ * License. When distributing the software, include this License Header
+ * Notice in each file and include the License file at
+ * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the GPL Version 2 section of the License file that
+ * accompanied this code. If applicable, add the following below the
+ * License Header, with the fields enclosed by brackets [] replaced by
+ * your own identifying information:
+ * "Portions Copyrighted [year] [name of copyright owner]"
+ *
+ * If you wish your version of this file to be governed by only the CDDL
+ * or only the GPL Version 2, indicate your decision by adding
+ * "[Contributor] elects to include this software in this distribution
+ * under the [CDDL or GPL Version 2] license." If you do not indicate a
+ * single choice of license, a recipient has the option to distribute
+ * your version of this file under either the CDDL, the GPL Version 2 or
+ * to extend the choice of license to its licensees as provided above.
+ * However, if you add GPL Version 2 code and therefore, elected the GPL
+ * Version 2 license, then the option applies only if the new code is
+ * made subject to such option by the copyright holder.
+ *
+ * Contributor(s):
+ *
+ * Portions Copyrighted 2011 Sun Microsystems, Inc.
+ */
+package org.netbeans.modules.jackpot30.ide.usages;
+
+import com.sun.source.util.TreePath;
+import java.awt.BorderLayout;
+import java.awt.CardLayout;
+import java.awt.Dialog;
+import java.awt.Insets;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.EnumSet;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicBoolean;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.ElementKind;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.type.DeclaredType;
+import javax.lang.model.type.TypeKind;
+import javax.lang.model.type.TypeMirror;
+import javax.lang.model.util.ElementFilter;
+import javax.swing.JButton;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.SwingUtilities;
+import javax.swing.border.EmptyBorder;
+import javax.swing.text.JTextComponent;
+import org.codeviation.pojson.Pojson;
+import org.netbeans.api.editor.EditorRegistry;
+import org.netbeans.api.java.source.CompilationController;
+import org.netbeans.api.java.source.CompilationInfo;
+import org.netbeans.api.java.source.ElementHandle;
+import org.netbeans.api.java.source.JavaSource;
+import org.netbeans.api.java.source.SourceUtils;
+import org.netbeans.api.java.source.Task;
+import org.netbeans.api.java.source.ui.ElementHeaders;
+import org.netbeans.api.java.source.ui.ScanDialog;
+import org.netbeans.modules.editor.NbEditorUtilities;
+import org.netbeans.modules.jackpot30.common.api.JavaUtils;
+import org.netbeans.modules.jackpot30.remoting.api.RemoteIndex;
+import org.netbeans.modules.jackpot30.remoting.api.Utilities;
+import org.netbeans.modules.jackpot30.remoting.api.Utilities.RemoteSourceDescription;
+import org.netbeans.modules.jackpot30.remoting.api.WebUtilities;
+import org.openide.DialogDescriptor;
+import org.openide.DialogDisplayer;
+import org.openide.NotifyDescriptor;
+import org.openide.NotifyDescriptor.Message;
+import org.openide.awt.ActionID;
+import org.openide.awt.ActionReference;
+import org.openide.awt.ActionReferences;
+import org.openide.awt.ActionRegistration;
+import org.openide.filesystems.FileObject;
+import org.openide.filesystems.FileUtil;
+import org.openide.filesystems.URLMapper;
+import org.openide.nodes.Node;
+import org.openide.util.Cancellable;
+import org.openide.util.Exceptions;
+import org.openide.util.NbBundle.Messages;
+import org.openide.util.RequestProcessor;
+
+@ActionID(category = "Refactoring",
+id = "org.netbeans.modules.jackpot30.ide.usages.RemoteUsages")
+@ActionRegistration(displayName = "#CTL_RemoteUsages")
+@ActionReferences({
+ @ActionReference(path = "Menu/Edit", position = 2250)
+})
+@Messages("CTL_RemoteUsages=Find Remote Usages...")
+public final class RemoteUsages implements ActionListener {
+
+ private final RequestProcessor WORKER = new RequestProcessor(RemoteUsages.class.getName(), 1, false, false);
+
+ public void actionPerformed(ActionEvent e) {
+ JTextComponent comp = EditorRegistry.lastFocusedComponent(); //XXX
+
+ if (comp == null) return;
+
+ final FileObject file = NbEditorUtilities.getFileObject(comp.getDocument());
+ final int pos = comp.getCaretPosition();
+ final ElementDescription element = findElement(file, pos);
+
+ if (element == null) {
+ Message message = new NotifyDescriptor.Message("Cannot find usages of this element", NotifyDescriptor.Message.ERROR_MESSAGE);
+ DialogDisplayer.getDefault().notifyLater(message);
+ return ;
+ }
+
+ final Set<SearchOptions> options = EnumSet.noneOf(SearchOptions.class);
+ final JButton okButton = new JButton("OK");
+ JButton cancelButton = new JButton("Cancel");
+ final ElementHandle[] searchFor = new ElementHandle[1];
+ JPanel dialogContent = constructDialog(element, options, new SelectionListener() {
+ @Override
+ public void elementSelected(ElementHandle<?> selected) {
+ searchFor[0] = selected;
+ }
+ }, okButton);
+
+ DialogDescriptor dd = new DialogDescriptor(dialogContent, "Remote Find Usages", true, new Object[] {okButton, cancelButton}, okButton, DialogDescriptor.DEFAULT_ALIGN, null, new ActionListener() {
+ @Override public void actionPerformed(ActionEvent e) { }
+ });
+ final Dialog d = DialogDisplayer.getDefault().createDialog(dd);
+
+ final AtomicBoolean cancel = new AtomicBoolean();
+
+ okButton.addActionListener(new ActionListener() {
+ @Override public void actionPerformed(ActionEvent e) {
+ okButton.setEnabled(false);
+ WORKER.post(new FindUsagesWorker(searchFor[0], options, d, cancel));
+ }
+ });
+
+ cancelButton.addActionListener(new ActionListener() {
+ @Override public void actionPerformed(ActionEvent e) {
+ cancel.set(true);
+ d.setVisible(false);
+ }
+ });
+
+ d.setVisible(true);
+ }
+
+ private static ElementDescription findElement(final FileObject file, final int pos) {
+ final ElementDescription[] handle = new ElementDescription[1];
+
+ if ("text/x-java".equals(FileUtil.getMIMEType(file, "text/x-java"))) {
+ final JavaSource js = JavaSource.forFileObject(file);
+
+ ScanDialog.runWhenScanFinished(new Runnable() {
+ @Override public void run() {
+ try {
+ js.runUserActionTask(new Task<CompilationController>() {
+ @Override public void run(CompilationController parameter) throws Exception {
+ parameter.toPhase(JavaSource.Phase.RESOLVED);
+
+ TreePath tp = parameter.getTreeUtilities().pathFor(pos);
+ Element el = parameter.getTrees().getElement(tp);
+
+ if (el != null && JavaUtils.SUPPORTED_KINDS.contains(el.getKind())) {
+ handle[0] = new ElementDescription(parameter, el);
+ }
+ }
+ }, true);
+ } catch (IOException ex) {
+ Exceptions.printStackTrace(ex);
+ }
+ }
+
+ }, "Find Remote Usages");
+
+ return handle[0];
+ } else {
+ RemoteSourceDescription rsd = org.netbeans.modules.jackpot30.remoting.api.Utilities.remoteSource(file);
+
+ if (rsd != null) {
+ try {
+ URI sourceURI = new URI(rsd.idx.remote.toExternalForm() + "/ui/target?path=" + WebUtilities.escapeForQuery(rsd.idx.remoteSegment) + "&relative=" + WebUtilities.escapeForQuery(rsd.relative) + "&position=" + pos);
+ Map<Object, Object> targetData = Pojson.load(HashMap.class, sourceURI.toURL().openStream());
+
+ String signature = (String) targetData.get("signature");
+
+ if (signature != null) {
+ List<String> baseMethodsSpec = (List<String>) targetData.get("superMethods");
+ baseMethodsSpec = baseMethodsSpec != null ? baseMethodsSpec : Collections.<String>emptyList();
+ List<ElementHandle<?>> baseMethods = new ArrayList<ElementHandle<?>>(baseMethodsSpec.size());
+ for (String spec : baseMethodsSpec) {
+ baseMethods.add(signature2Handle(spec));
+ }
+ return new ElementDescription(signature2Handle(signature),
+ baseMethods);
+ }
+ } catch (URISyntaxException ex) {
+ Exceptions.printStackTrace(ex);
+ } catch (IOException ex) {
+ Exceptions.printStackTrace(ex);
+ }
+ }
+
+ return null;
+ }
+ }
+
+ private static ElementHandle<?> signature2Handle(String signature) {
+ if (signature == null) return null;
+ String[] parts = signature.split(":");
+ ElementHandle<?> h = Utilities.createElementHandle(ElementKind.valueOf(parts[0]),
+ parts[1],
+ parts.length > 2 ? parts[2] : null,
+ parts.length > 3 ? parts[3] : null);
+ return h;
+ }
+
+ private JPanel constructDialog(ElementDescription toSearch, Set<SearchOptions> options, SelectionListener sl, JButton ok) {
+ JPanel searchKind;
+
+ switch (toSearch.element.getKind()) {
+ case METHOD: searchKind = new MethodOptions(toSearch, options, sl); break;
+ case CLASS:
+ case INTERFACE:
+ case ANNOTATION_TYPE: searchKind = new ClassOptions(options); break;
+ default:
+ options.add(RemoteUsages.SearchOptions.USAGES);
+ searchKind = new JPanel();
+ break;
+ }
+
+ final JPanel progress = new JPanel();
+
+ progress.setLayout(new CardLayout());
+ progress.add(new JPanel(), "hide");
+ progress.add(new JLabel("Querying remote server(s), please wait"), "show");
+
+ ok.addActionListener(new ActionListener() {
+ @Override public void actionPerformed(ActionEvent e) {
+ ((CardLayout) progress.getLayout()).show(progress, "show");
+ }
+ });
+
+ JPanel result = new JPanel();
+
+ result.setLayout(new BorderLayout());
+ result.setBorder(new EmptyBorder(new Insets(12, 12, 12, 12)));
+
+ result.add(new JLabel("Usages of: " + toSearch.displayName), BorderLayout.NORTH);
+ result.add(searchKind, BorderLayout.CENTER);
+ result.add(progress, BorderLayout.SOUTH);
+
+ sl.elementSelected(toSearch.element);
+
+ return result;
+ }
+
+ public static final class ElementDescription {
+ public final ElementHandle<?> element;
+ public final String displayName;
+ public final List<ElementHandle<?>> superMethods;
+
+ public ElementDescription(CompilationInfo info, Element el) {
+ element = ElementHandle.create(el);
+ displayName = displayNameForElement(ElementHandle.create(el));
+
+ if (el.getKind() == ElementKind.METHOD) {
+ superMethods = superMethods(info, new HashSet<TypeElement>(), (ExecutableElement) el, (TypeElement) el.getEnclosingElement());
+ } else {
+ superMethods = null;
+ }
+ }
+
+ private List<ElementHandle<?>> superMethods(CompilationInfo info, Set<TypeElement> seenTypes, ExecutableElement baseMethod, TypeElement currentType) {
+ if (!seenTypes.add(currentType))
+ return Collections.emptyList();
+
+ List<ElementHandle<?>> result = new ArrayList<ElementHandle<?>>();
+
+ for (TypeElement sup : superTypes(info, currentType)) {
+ for (ExecutableElement ee : ElementFilter.methodsIn(sup.getEnclosedElements())) {
+ if (info.getElements().overrides(baseMethod, ee, (TypeElement) baseMethod.getEnclosingElement())) {
+ result.add(ElementHandle.create(ee));
+ }
+ }
+
+ result.addAll(superMethods(info, seenTypes, baseMethod, currentType));
+ }
+
+ return result;
+ }
+
+ private List<TypeElement> superTypes(CompilationInfo info, TypeElement type) {
+ List<TypeElement> superTypes = new ArrayList<TypeElement>();
+
+ for (TypeMirror sup : info.getTypes().directSupertypes(type.asType())) {
+ if (sup.getKind() == TypeKind.DECLARED) {
+ superTypes.add((TypeElement) ((DeclaredType) sup).asElement());
+ }
+ }
+
+ return superTypes;
+ }
+
+ public ElementDescription(ElementHandle<?> element, List<ElementHandle<?>> superMethods) {
+ this.element = element;
+ displayName = displayNameForElement(element);
+ this.superMethods = superMethods;
+ }
+
+ private String displayNameForElement(ElementHandle<?> el) throws UnsupportedOperationException {
+ String[] signatures = SourceUtils.getJVMSignature(el);
+ String classSimpleName = signatures[0];
+ int lastDotDollar = Math.max(classSimpleName.lastIndexOf('.'), classSimpleName.lastIndexOf('$'));
+ if (lastDotDollar > (-1)) classSimpleName = classSimpleName.substring(lastDotDollar + 1);
+ switch (el.getKind()) {
+ case METHOD:
+ return signatures[1] + Utilities.decodeMethodParameterTypes(signatures[2]);
+ case CONSTRUCTOR:
+ return classSimpleName + Utilities.decodeMethodParameterTypes(signatures[2]);
+ case CLASS:
+ case INTERFACE:
+ case ENUM:
+ case ANNOTATION_TYPE:
+ return classSimpleName;
+ case FIELD:
+ case ENUM_CONSTANT:
+ return signatures[1];
+ default:
+ throw new UnsupportedOperationException();
+ }
+ }
+
+ }
+
+ private static class FindUsagesWorker implements Runnable, Cancellable {
+
+ private final ElementHandle<?> toSearch;
+ private final Set<SearchOptions> options;
+ private final Dialog d;
+ private final AtomicBoolean cancel;
+
+ public FindUsagesWorker(ElementHandle<?> toSearch, Set<SearchOptions> options, Dialog d, AtomicBoolean cancel) {
+ this.toSearch = toSearch;
+ this.options = options;
+ this.d = d;
+ this.cancel = cancel;
+ }
+
+ @Override public void run() {
+ try {
+ final String serialized = JavaUtils.serialize(toSearch);
+
+ Set<FileObject> resultSet = new HashSet<FileObject>();
+ List<FileObject> result = new ArrayList<FileObject>();
+ Map<RemoteIndex, List<String>> unmappable = new HashMap<RemoteIndex, List<String>>();
+
+ for (RemoteIndex idx : RemoteIndex.loadIndices()) {
+ URL localFolderURL = idx.getLocalFolder();
+ FileObject localFolder = localFolderURL != null ? URLMapper.findFileObject(localFolderURL) : null;
+
+ if (options.contains(SearchOptions.USAGES)) {
+ URI resolved = new URI(idx.remote.toExternalForm() + "/usages/search?path=" + WebUtilities.escapeForQuery(idx.remoteSegment) + "&signatures=" + WebUtilities.escapeForQuery(serialized));
+ Collection<? extends String> response = WebUtilities.requestStringArrayResponse(resolved, cancel);
+
+ if (cancel.get()) return;
+ if (response == null) continue;
+
+ for (String path : response) {
+ if (path.trim().isEmpty()) continue;
+ FileObject file = localFolder != null ? localFolder.getFileObject(path) : null;
+
+ if (file != null) {
+ if (resultSet.add(file)) {
+ result.add(file);
+ }
+ } else {
+ List<String> um = unmappable.get(idx);
+
+ if (um == null) {
+ unmappable.put(idx, um = new ArrayList<String>());
+ }
+
+ um.add(path);
+ }
+ }
+ }
+
+ if (options.contains(SearchOptions.SUB)) {
+ URI resolved;
+ if (toSearch.getKind() == ElementKind.METHOD) {
+ resolved = new URI(idx.remote.toExternalForm() + "/implements/search?path=" + WebUtilities.escapeForQuery(idx.remoteSegment) + "&method=" + WebUtilities.escapeForQuery(serialized));
+ } else {
+ resolved = new URI(idx.remote.toExternalForm() + "/implements/search?path=" + WebUtilities.escapeForQuery(idx.remoteSegment) + "&type=" + WebUtilities.escapeForQuery(toSearch.getBinaryName()));
+ }
+
+ String response = WebUtilities.requestStringResponse(resolved, cancel);
+
+ if (cancel.get()) return;
+ if (response == null) continue;
+
+ //XXX:
+ Map<String, List<Map<String, String>>> formattedResponse = Pojson.load(LinkedHashMap.class, response);
+
+ for (Entry<String, List<Map<String, String>>> e : formattedResponse.entrySet()) {
+ for (Map<String, String> p : e.getValue()) {
+ String path = p.get("file");
+ FileObject file = localFolder != null ? localFolder.getFileObject(path) : null;
+
+ if (file != null) {
+ if (resultSet.add(file)) {
+ result.add(file);
+ }
+ } else {
+ List<String> um = unmappable.get(idx);
+
+ if (um == null) {
+ unmappable.put(idx, um = new ArrayList<String>());
+ }
+
+ um.add(path);
+ }
+ }
+ }
+ }
+ }
+
+ final Node view = Nodes.constructSemiLogicalView(result, unmappable, toSearch, options);
+
+ if (!cancel.get()) {
+ SwingUtilities.invokeLater(new Runnable() {
+ @Override public void run() {
+ RemoteUsagesWindowTopComponent.openFor(view);
+ }
+ });
+ }
+ } catch (URISyntaxException ex) {
+ Exceptions.printStackTrace(ex);
+ } finally {
+ cancel.set(true);
+ SwingUtilities.invokeLater(new Runnable() {
+ @Override public void run() {
+ d.setVisible(false);
+ }
+ });
+ }
+ }
+
+ @Override public boolean cancel() {
+ cancel.set(true);
+ return true;
+ }
+ }
+
+ public enum SearchOptions {
+ USAGES,
+ SUB;
+ }
+
+ public interface SelectionListener {
+ public void elementSelected(ElementHandle<?> selected);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-netbeans-jackpot30/blob/9ed0a377/remoting/ide/usages/src/org/netbeans/modules/jackpot30/ide/usages/RemoteUsagesWindowTopComponent.form
----------------------------------------------------------------------
diff --git a/remoting/ide/usages/src/org/netbeans/modules/jackpot30/ide/usages/RemoteUsagesWindowTopComponent.form b/remoting/ide/usages/src/org/netbeans/modules/jackpot30/ide/usages/RemoteUsagesWindowTopComponent.form
new file mode 100644
index 0000000..d0fffb9
--- /dev/null
+++ b/remoting/ide/usages/src/org/netbeans/modules/jackpot30/ide/usages/RemoteUsagesWindowTopComponent.form
@@ -0,0 +1,17 @@
+<?xml version="1.1" encoding="UTF-8" ?>
+
+<Form version="1.3" maxVersion="1.8" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
+ <AuxValues>
+ <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
+ <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
+ <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
+ <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
+ <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
+ <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
+ <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
+ <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
+ <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
+ </AuxValues>
+
+ <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/>
+</Form>
http://git-wip-us.apache.org/repos/asf/incubator-netbeans-jackpot30/blob/9ed0a377/remoting/ide/usages/src/org/netbeans/modules/jackpot30/ide/usages/RemoteUsagesWindowTopComponent.java
----------------------------------------------------------------------
diff --git a/remoting/ide/usages/src/org/netbeans/modules/jackpot30/ide/usages/RemoteUsagesWindowTopComponent.java b/remoting/ide/usages/src/org/netbeans/modules/jackpot30/ide/usages/RemoteUsagesWindowTopComponent.java
new file mode 100644
index 0000000..4ee2131
--- /dev/null
+++ b/remoting/ide/usages/src/org/netbeans/modules/jackpot30/ide/usages/RemoteUsagesWindowTopComponent.java
@@ -0,0 +1,147 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2011 Oracle and/or its affiliates. All rights reserved.
+ *
+ * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
+ * Other names may be trademarks of their respective owners.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common
+ * Development and Distribution License("CDDL") (collectively, the
+ * "License"). You may not use this file except in compliance with the
+ * License. You can obtain a copy of the License at
+ * http://www.netbeans.org/cddl-gplv2.html
+ * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
+ * specific language governing permissions and limitations under the
+ * License. When distributing the software, include this License Header
+ * Notice in each file and include the License file at
+ * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the GPL Version 2 section of the License file that
+ * accompanied this code. If applicable, add the following below the
+ * License Header, with the fields enclosed by brackets [] replaced by
+ * your own identifying information:
+ * "Portions Copyrighted [year] [name of copyright owner]"
+ *
+ * If you wish your version of this file to be governed by only the CDDL
+ * or only the GPL Version 2, indicate your decision by adding
+ * "[Contributor] elects to include this software in this distribution
+ * under the [CDDL or GPL Version 2] license." If you do not indicate a
+ * single choice of license, a recipient has the option to distribute
+ * your version of this file under either the CDDL, the GPL Version 2 or
+ * to extend the choice of license to its licensees as provided above.
+ * However, if you add GPL Version 2 code and therefore, elected the GPL
+ * Version 2 license, then the option applies only if the new code is
+ * made subject to such option by the copyright holder.
+ *
+ * Contributor(s):
+ *
+ * Portions Copyrighted 2011 Sun Microsystems, Inc.
+ */
+package org.netbeans.modules.jackpot30.ide.usages;
+
+import java.awt.BorderLayout;
+import org.openide.util.NbBundle;
+import org.openide.windows.Mode;
+import org.openide.windows.TopComponent;
+import org.netbeans.api.settings.ConvertAsProperties;
+import org.openide.awt.ActionID;
+import org.openide.awt.ActionReference;
+import org.openide.explorer.ExplorerManager;
+import org.openide.explorer.view.BeanTreeView;
+import org.openide.nodes.Node;
+import org.openide.windows.WindowManager;
+
+/**
+ * Top component which displays something.
+ */
+@ConvertAsProperties(dtd = "-//org.netbeans.modules.jackpot30.ide.usages//RemoteUsagesWindow//EN",
+autostore = false)
+@TopComponent.Description(preferredID = "RemoteUsagesWindowTopComponent",
+//iconBase="SET/PATH/TO/ICON/HERE",
+persistenceType = TopComponent.PERSISTENCE_ALWAYS)
+@TopComponent.Registration(mode = "output", openAtStartup = false)
+@ActionID(category = "Window", id = "org.netbeans.modules.jackpot30.ide.usages.RemoteUsagesWindowTopComponent")
+@ActionReference(path = "Menu/Window" /*, position = 333 */)
+@TopComponent.OpenActionRegistration(displayName = "#CTL_RemoteUsagesWindowAction",
+preferredID = "RemoteUsagesWindowTopComponent")
+public final class RemoteUsagesWindowTopComponent extends TopComponent implements ExplorerManager.Provider {
+
+ public RemoteUsagesWindowTopComponent() {
+ initComponents();
+ setName(NbBundle.getMessage(RemoteUsagesWindowTopComponent.class, "CTL_RemoteUsagesWindowTopComponent"));
+ setToolTipText(NbBundle.getMessage(RemoteUsagesWindowTopComponent.class, "HINT_RemoteUsagesWindowTopComponent"));
+
+ BeanTreeView btv = new BeanTreeView();
+
+ add(btv, BorderLayout.CENTER);
+
+ btv.setRootVisible(false);
+ }
+
+ /** This method is called from within the constructor to
+ * initialize the form.
+ * WARNING: Do NOT modify this code. The content of this method is
+ * always regenerated by the Form Editor.
+ */
+ // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
+ private void initComponents() {
+
+ setLayout(new java.awt.BorderLayout());
+ }// </editor-fold>//GEN-END:initComponents
+
+ // Variables declaration - do not modify//GEN-BEGIN:variables
+ // End of variables declaration//GEN-END:variables
+ @Override
+ public void componentOpened() {
+ // TODO add custom code on component opening
+ }
+
+ @Override
+ public void componentClosed() {
+ // TODO add custom code on component closing
+ }
+
+ void writeProperties(java.util.Properties p) {
+ // better to version settings since initial version as advocated at
+ // http://wiki.apidesign.org/wiki/PropertyFiles
+ p.setProperty("version", "1.0");
+ // TODO store your settings
+ }
+
+ void readProperties(java.util.Properties p) {
+ String version = p.getProperty("version");
+ // TODO read your settings according to their version
+ }
+
+ @Override
+ public int getPersistenceType() {
+ return PERSISTENCE_NEVER;
+ }
+
+ private final ExplorerManager manager = new ExplorerManager();
+
+ @Override
+ public ExplorerManager getExplorerManager() {
+ return manager;
+ }
+
+ @Override
+ public void open() {
+ Mode outputMode = WindowManager.getDefault().findMode("output");
+
+ if (outputMode != null)
+ outputMode.dockInto(this);
+ super.open();
+ requestActive();
+ requestFocusInWindow(false);
+ }
+
+ public static void openFor(Node n) {
+ RemoteUsagesWindowTopComponent c = new RemoteUsagesWindowTopComponent();
+
+ c.manager.setRootContext(n);
+ c.open();
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-netbeans-jackpot30/blob/9ed0a377/remoting/ide/usages/src/org/netbeans/modules/jackpot30/ide/usages/hints/RemotelyUnused.java
----------------------------------------------------------------------
diff --git a/remoting/ide/usages/src/org/netbeans/modules/jackpot30/ide/usages/hints/RemotelyUnused.java b/remoting/ide/usages/src/org/netbeans/modules/jackpot30/ide/usages/hints/RemotelyUnused.java
new file mode 100644
index 0000000..72302d5
--- /dev/null
+++ b/remoting/ide/usages/src/org/netbeans/modules/jackpot30/ide/usages/hints/RemotelyUnused.java
@@ -0,0 +1,152 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2012 Oracle and/or its affiliates. All rights reserved.
+ *
+ * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
+ * Other names may be trademarks of their respective owners.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common
+ * Development and Distribution License("CDDL") (collectively, the
+ * "License"). You may not use this file except in compliance with the
+ * License. You can obtain a copy of the License at
+ * http://www.netbeans.org/cddl-gplv2.html
+ * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
+ * specific language governing permissions and limitations under the
+ * License. When distributing the software, include this License Header
+ * Notice in each file and include the License file at
+ * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the GPL Version 2 section of the License file that
+ * accompanied this code. If applicable, add the following below the
+ * License Header, with the fields enclosed by brackets [] replaced by
+ * your own identifying information:
+ * "Portions Copyrighted [year] [name of copyright owner]"
+ *
+ * If you wish your version of this file to be governed by only the CDDL
+ * or only the GPL Version 2, indicate your decision by adding
+ * "[Contributor] elects to include this software in this distribution
+ * under the [CDDL or GPL Version 2] license." If you do not indicate a
+ * single choice of license, a recipient has the option to distribute
+ * your version of this file under either the CDDL, the GPL Version 2 or
+ * to extend the choice of license to its licensees as provided above.
+ * However, if you add GPL Version 2 code and therefore, elected the GPL
+ * Version 2 license, then the option applies only if the new code is
+ * made subject to such option by the copyright holder.
+ *
+ * Contributor(s):
+ *
+ * Portions Copyrighted 2012 Sun Microsystems, Inc.
+ */
+
+package org.netbeans.modules.jackpot30.ide.usages.hints;
+
+import com.sun.source.tree.Tree.Kind;
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.BitSet;
+import java.util.concurrent.atomic.AtomicBoolean;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.ElementKind;
+import javax.lang.model.element.ExecutableElement;
+import org.apache.lucene.document.Document;
+import org.apache.lucene.document.Field;
+import org.apache.lucene.document.Field.Index;
+import org.apache.lucene.document.Field.Store;
+import org.apache.lucene.index.IndexReader;
+import org.apache.lucene.index.IndexWriter;
+import org.apache.lucene.index.Term;
+import org.apache.lucene.search.Collector;
+import org.apache.lucene.search.IndexSearcher;
+import org.apache.lucene.search.Query;
+import org.apache.lucene.search.Searcher;
+import org.apache.lucene.search.TermQuery;
+import org.netbeans.api.java.source.ElementHandle;
+import org.netbeans.modules.jackpot30.common.api.JavaUtils;
+import org.netbeans.modules.jackpot30.common.api.LuceneHelpers.BitSetCollector;
+import org.netbeans.modules.jackpot30.remoting.api.LocalCache;
+import org.netbeans.modules.jackpot30.remoting.api.LocalCache.Task;
+import org.netbeans.modules.jackpot30.remoting.api.RemoteIndex;
+import org.netbeans.modules.jackpot30.remoting.api.WebUtilities;
+import org.netbeans.spi.editor.hints.ErrorDescription;
+import org.netbeans.spi.java.hints.ErrorDescriptionFactory;
+import org.netbeans.spi.java.hints.Hint;
+import org.netbeans.spi.java.hints.HintContext;
+import org.netbeans.spi.java.hints.TriggerTreeKind;
+import org.openide.util.NbBundle.Messages;
+
+/**
+ *
+ * @author lahvac
+ */
+@Hint(displayName="#DN_RemotelyUnused", description="#DESC_RemotelyUnused", category="general", enabled=false)
+@Messages({"DN_RemotelyUnused=Unused in Remote Projects",
+ "DESC_RemotelyUnused=Not used in any known remote project",
+ "ERR_NoUsages=No usages found in any know projects"})
+public class RemotelyUnused {
+
+ private static final String VAL_UNUSED = "unused";
+ private static final String VAL_USED = "used";
+ private static final String VAL_UNKNOWN = "unknown";
+
+ @TriggerTreeKind({Kind.VARIABLE, Kind.METHOD})
+ public static ErrorDescription hint(HintContext ctx) throws URISyntaxException, IOException {
+ Element toSearch = ctx.getInfo().getTrees().getElement(ctx.getPath());
+
+ if (toSearch == null) return null;
+ if (!toSearch.getKind().isField() && toSearch.getKind() != ElementKind.METHOD && toSearch.getKind() != ElementKind.CONSTRUCTOR) return null;
+ if (toSearch.getKind() == ElementKind.METHOD && ctx.getInfo().getElementUtilities().overridesMethod((ExecutableElement) toSearch)) return null;
+
+ final String serialized = JavaUtils.serialize(ElementHandle.create(toSearch));
+
+ for (RemoteIndex idx : RemoteIndex.loadIndices()) {
+ String result = LocalCache.runOverLocalCache(idx, new Task<IndexReader, String>() {
+ @Override
+ public String run(IndexReader reader, AtomicBoolean cancel) throws IOException {
+ Query query = new TermQuery(new Term("usagesSignature", serialized));
+ Searcher s = new IndexSearcher(reader);
+ BitSet matchingDocuments = new BitSet(reader.maxDoc());
+ Collector c = new BitSetCollector(matchingDocuments);
+
+ s.search(query, c);
+
+ for (int docNum = matchingDocuments.nextSetBit(0); docNum >= 0; docNum = matchingDocuments.nextSetBit(docNum + 1)) {
+ if (cancel.get()) return VAL_UNKNOWN;
+
+ final Document doc = reader.document(docNum);
+
+ return doc.get("usagesUsages");
+ }
+
+ return VAL_UNKNOWN;
+ }
+ }, null, new AtomicBoolean()/*XXX*/);
+
+ if (result == null) {
+ URI resolved = new URI(idx.remote.toExternalForm() + "/usages/search?path=" + WebUtilities.escapeForQuery(idx.remoteSegment) + "&signatures=" + WebUtilities.escapeForQuery(serialized));
+ String response = WebUtilities.requestStringResponse(resolved, new AtomicBoolean());
+
+ if (response != null) {
+ result = response.trim().isEmpty() ? VAL_UNUSED : VAL_USED;
+ } else {
+ result = VAL_UNKNOWN;
+ }
+ final String resultFin = result;
+ LocalCache.saveToLocalCache(idx, new Task<IndexWriter, Void>() {
+ @Override public Void run(IndexWriter p, AtomicBoolean cancel) throws IOException {
+ Document doc = new Document();
+ doc.add(new Field("usagesSignature", serialized, Store.NO, Index.NOT_ANALYZED));
+ doc.add(new Field("usagesUsages", resultFin, Store.YES, Index.NO));
+ p.addDocument(doc);
+ return null;
+ }
+ });
+ }
+ if (!VAL_UNUSED.equals(result)) return null;
+ }
+
+ return ErrorDescriptionFactory.forName(ctx, ctx.getPath(), Bundle.ERR_NoUsages());
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-netbeans-jackpot30/blob/9ed0a377/remoting/ide/usages/test/unit/src/org/netbeans/modules/jackpot30/ide/usages/NodesTest.java
----------------------------------------------------------------------
diff --git a/remoting/ide/usages/test/unit/src/org/netbeans/modules/jackpot30/ide/usages/NodesTest.java b/remoting/ide/usages/test/unit/src/org/netbeans/modules/jackpot30/ide/usages/NodesTest.java
new file mode 100644
index 0000000..696378e
--- /dev/null
+++ b/remoting/ide/usages/test/unit/src/org/netbeans/modules/jackpot30/ide/usages/NodesTest.java
@@ -0,0 +1,158 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2011 Oracle and/or its affiliates. All rights reserved.
+ *
+ * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
+ * Other names may be trademarks of their respective owners.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common
+ * Development and Distribution License("CDDL") (collectively, the
+ * "License"). You may not use this file except in compliance with the
+ * License. You can obtain a copy of the License at
+ * http://www.netbeans.org/cddl-gplv2.html
+ * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
+ * specific language governing permissions and limitations under the
+ * License. When distributing the software, include this License Header
+ * Notice in each file and include the License file at
+ * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the GPL Version 2 section of the License file that
+ * accompanied this code. If applicable, add the following below the
+ * License Header, with the fields enclosed by brackets [] replaced by
+ * your own identifying information:
+ * "Portions Copyrighted [year] [name of copyright owner]"
+ *
+ * If you wish your version of this file to be governed by only the CDDL
+ * or only the GPL Version 2, indicate your decision by adding
+ * "[Contributor] elects to include this software in this distribution
+ * under the [CDDL or GPL Version 2] license." If you do not indicate a
+ * single choice of license, a recipient has the option to distribute
+ * your version of this file under either the CDDL, the GPL Version 2 or
+ * to extend the choice of license to its licensees as provided above.
+ * However, if you add GPL Version 2 code and therefore, elected the GPL
+ * Version 2 license, then the option applies only if the new code is
+ * made subject to such option by the copyright holder.
+ *
+ * Contributor(s):
+ *
+ * Portions Copyrighted 2011 Sun Microsystems, Inc.
+ */
+package org.netbeans.modules.jackpot30.ide.usages;
+
+import java.util.ArrayList;
+import java.util.EnumSet;
+import java.util.List;
+import javax.lang.model.element.TypeElement;
+import org.netbeans.api.java.source.CompilationInfo;
+import org.netbeans.api.java.source.ElementHandle;
+import org.netbeans.api.java.source.JavaSource;
+import org.netbeans.api.java.source.JavaSource.Phase;
+import org.netbeans.api.java.source.SourceUtilsTestUtil;
+import org.netbeans.api.java.source.TestUtilities;
+import org.netbeans.junit.NbTestCase;
+import org.netbeans.modules.parsing.impl.indexing.CacheFolder;
+import org.openide.filesystems.FileObject;
+import org.openide.filesystems.FileUtil;
+import org.openide.nodes.Node;
+
+/**
+ *
+ * @author lahvac
+ */
+public class NodesTest extends NbTestCase {
+
+ public NodesTest(String testName) {
+ super(testName);
+ }
+
+ public void testA() throws Exception {
+ FileObject data = FileUtil.createData(src, "test/Test.java");
+ TestUtilities.copyStringToFile(data, "package test;\n" +
+ "public class Test {\n" +
+ " public Test () {}\n" +
+ " private void test() { new Test(); }\n" +
+ "}\n");
+ CompilationInfo info = SourceUtilsTestUtil.getCompilationInfo(JavaSource.forFileObject(data), Phase.RESOLVED);
+ ElementHandle<?> eh = ElementHandle.create(info.getTopLevelElements().get(0).getEnclosedElements().get(0));
+ List<Node> constructed = new ArrayList<Node>();
+
+ Nodes.computeOccurrences(data, eh, EnumSet.of(RemoteUsages.SearchOptions.USAGES), constructed);
+
+ Node n = constructed.get(0);
+
+ assertEquals(" private void test() { new <b>Test</b>(); }<br>", n.getHtmlDisplayName());
+ }
+
+ public void testMethodImplementations() throws Exception {
+ FileObject data = FileUtil.createData(src, "test/Test.java");
+ TestUtilities.copyStringToFile(data, "package test;\n" +
+ "public class Test implements Runnable {\n" +
+ " public void run() {\n" +
+ " Runnable r = null;\n" +
+ " r.run();\n" +
+ " }\n" +
+ "}\n");
+ CompilationInfo info = SourceUtilsTestUtil.getCompilationInfo(JavaSource.forFileObject(data), Phase.RESOLVED);
+ TypeElement runnable = info.getElements().getTypeElement("java.lang.Runnable");
+
+ assertNotNull(runnable);
+
+ ElementHandle<?> eh = ElementHandle.create(runnable.getEnclosedElements().get(0));
+ List<Node> constructed = new ArrayList<Node>();
+
+ Nodes.computeOccurrences(data, eh, EnumSet.of(RemoteUsages.SearchOptions.SUB), constructed);
+
+ assertEquals(1, constructed.size());
+
+ Node n = constructed.get(0);
+
+ assertEquals(" public void <b>run</b>() {<br>", n.getHtmlDisplayName());
+ }
+
+ public void testSubtypes() throws Exception {
+ FileObject data = FileUtil.createData(src, "test/Test.java");
+ TestUtilities.copyStringToFile(data, "package test;\n" +
+ "public class Test implements Runnable {\n" +
+ " public void run() {\n" +
+ " Runnable r = null;\n" +
+ " r.run();\n" +
+ " }\n" +
+ "}\n");
+ CompilationInfo info = SourceUtilsTestUtil.getCompilationInfo(JavaSource.forFileObject(data), Phase.RESOLVED);
+ TypeElement runnable = info.getElements().getTypeElement("java.lang.Runnable");
+
+ assertNotNull(runnable);
+
+ ElementHandle<?> eh = ElementHandle.create(runnable);
+ List<Node> constructed = new ArrayList<Node>();
+
+ Nodes.computeOccurrences(data, eh, EnumSet.of(RemoteUsages.SearchOptions.SUB), constructed);
+
+ assertEquals(1, constructed.size());
+
+ Node n = constructed.get(0);
+
+ assertEquals("public class <b>Test</b> implements Runnable {<br>", n.getHtmlDisplayName());
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ SourceUtilsTestUtil.prepareTest(new String[0], new Object[0]);
+ prepareTest();
+ super.setUp();
+ }
+
+ private FileObject src;
+
+ private void prepareTest() throws Exception {
+ FileObject workdir = SourceUtilsTestUtil.makeScratchDir(this);
+
+ src = FileUtil.createFolder(workdir, "src");
+
+ FileObject cache = FileUtil.createFolder(workdir, "cache");
+
+ CacheFolder.setCacheFolder(cache);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-netbeans-jackpot30/blob/9ed0a377/remoting/post-build.sh
----------------------------------------------------------------------
diff --git a/remoting/post-build.sh b/remoting/post-build.sh
new file mode 100755
index 0000000..1d1dc51
--- /dev/null
+++ b/remoting/post-build.sh
@@ -0,0 +1,56 @@
+#!/bin/bash
+
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+#
+# Copyright 2009-2017 Oracle and/or its affiliates. All rights reserved.
+#
+# Oracle and Java are registered trademarks of Oracle and/or its affiliates.
+# Other names may be trademarks of their respective owners.
+#
+# The contents of this file are subject to the terms of either the GNU
+# General Public License Version 2 only ("GPL") or the Common
+# Development and Distribution License("CDDL") (collectively, the
+# "License"). You may not use this file except in compliance with the
+# License. You can obtain a copy of the License at
+# http://www.netbeans.org/cddl-gplv2.html
+# or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
+# specific language governing permissions and limitations under the
+# License. When distributing the software, include this License Header
+# Notice in each file and include the License file at
+# nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
+# particular file as subject to the "Classpath" exception as provided
+# by Oracle in the GPL Version 2 section of the License file that
+# accompanied this code. If applicable, add the following below the
+# License Header, with the fields enclosed by brackets [] replaced by
+# your own identifying information:
+# "Portions Copyrighted [year] [name of copyright owner]"
+#
+# Contributor(s):
+#
+# The Original Software is NetBeans. The Initial Developer of the Original
+# Software is Sun Microsystems, Inc. Portions Copyright 2009-2010 Sun
+# Microsystems, Inc. All Rights Reserved.
+#
+# If you wish your version of this file to be governed by only the CDDL
+# or only the GPL Version 2, indicate your decision by adding
+# "[Contributor] elects to include this software in this distribution
+# under the [CDDL or GPL Version 2] license." If you do not indicate a
+# single choice of license, a recipient has the option to distribute
+# your version of this file under either the CDDL, the GPL Version 2 or
+# to extend the choice of license to its licensees as provided above.
+# However, if you add GPL Version 2 code and therefore, elected the GPL
+# Version 2 license, then the option applies only if the new code is
+# made subject to such option by the copyright holder.
+
+cp -r ../duplicates/server/indexer/build/cluster/* build/indexing-backend/indexer/indexer
+cp -r ../duplicates/ide/build/cluster/* build/indexing-backend/indexer/indexer
+cp -r ../remoting/ide/build/cluster/* build/indexing-backend/indexer/indexer
+cp -r ../language/ide/build/cluster/* build/indexing-backend/indexer/indexer
+cp -r ../duplicates/server/web/*/dist/*.jar build/indexing-backend/web/lib
+cp -r ../language/server/web/*/dist/*.jar build/indexing-backend/web/lib
+cp -r ../language/server/web/*/dist/lib/*.jar build/indexing-backend/web/lib
+
+(cd build; zip -r indexing-backend-feature-packed.zip indexing-backend) || exit 1
+(cd build; zip -r indexing-backend-feature-packed-shortened.zip `find indexing-backend -type f | grep -v indexing-backend/indexer/enterprise/ | grep -v indexing-backend/indexer/apisupport/ | grep -v indexing-backend/indexer/cnd/ | grep -v indexing-backend/indexer/dlight/ | grep -v indexing-backend/indexer/harness/ | grep -v indexing-backend/indexer/ide/ | grep -v indexing-backend/indexer/java | grep -v indexing-backend/indexer/nb/ | grep -v indexing-backend/indexer/platform/ | grep -v indexing-backend/indexer/profiler/ | grep -v indexing-backend/indexer/websvccommon/`) || exit 1
+
+(cd server/tests; ./run-integration-tests) || exit 1
http://git-wip-us.apache.org/repos/asf/incubator-netbeans-jackpot30/blob/9ed0a377/remoting/server/hudson/pom.xml
----------------------------------------------------------------------
diff --git a/remoting/server/hudson/pom.xml b/remoting/server/hudson/pom.xml
new file mode 100644
index 0000000..27062be
--- /dev/null
+++ b/remoting/server/hudson/pom.xml
@@ -0,0 +1,77 @@
+<!--
+DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+
+Copyright 2009-2017 Oracle and/or its affiliates. All rights reserved.
+
+Oracle and Java are registered trademarks of Oracle and/or its affiliates.
+Other names may be trademarks of their respective owners.
+
+The contents of this file are subject to the terms of either the GNU
+General Public License Version 2 only ("GPL") or the Common
+Development and Distribution License("CDDL") (collectively, the
+"License"). You may not use this file except in compliance with the
+License. You can obtain a copy of the License at
+http://www.netbeans.org/cddl-gplv2.html
+or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
+specific language governing permissions and limitations under the
+License. When distributing the software, include this License Header
+Notice in each file and include the License file at
+nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
+particular file as subject to the "Classpath" exception as provided
+by Oracle in the GPL Version 2 section of the License file that
+accompanied this code. If applicable, add the following below the
+License Header, with the fields enclosed by brackets [] replaced by
+your own identifying information:
+"Portions Copyrighted [year] [name of copyright owner]"
+
+Contributor(s):
+
+The Original Software is NetBeans. The Initial Developer of the Original
+Software is Sun Microsystems, Inc. Portions Copyright 2009-2010 Sun
+Microsystems, Inc. All Rights Reserved.
+
+If you wish your version of this file to be governed by only the CDDL
+or only the GPL Version 2, indicate your decision by adding
+"[Contributor] elects to include this software in this distribution
+under the [CDDL or GPL Version 2] license." If you do not indicate a
+single choice of license, a recipient has the option to distribute
+your version of this file under either the CDDL, the GPL Version 2 or
+to extend the choice of license to its licensees as provided above.
+However, if you add GPL Version 2 code and therefore, elected the GPL
+Version 2 license, then the option applies only if the new code is
+made subject to such option by the copyright holder.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <name>Jackpot 3.0 Hudson Plugin</name>
+ <parent>
+ <groupId>org.jenkins-ci.plugins</groupId>
+ <artifactId>plugin</artifactId>
+ <version>1.424</version><!-- which version of Jenkins is this plugin built against? -->
+ </parent>
+
+ <groupId>org.netbeans.modules.jackpot30.hudson</groupId>
+ <artifactId>org.netbeans.modules.jackpot30.hudson</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ <packaging>hpi</packaging>
+
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ </properties>
+
+ <!-- get every artifact through repo.jenkins-ci.org, which proxies all the artifacts that we need -->
+ <repositories>
+ <repository>
+ <id>repo.jenkins-ci.org</id>
+ <url>http://repo.jenkins-ci.org/public/</url>
+ </repository>
+ </repositories>
+
+ <pluginRepositories>
+ <pluginRepository>
+ <id>repo.jenkins-ci.org</id>
+ <url>http://repo.jenkins-ci.org/public/</url>
+ </pluginRepository>
+ </pluginRepositories>
+
+</project>
http://git-wip-us.apache.org/repos/asf/incubator-netbeans-jackpot30/blob/9ed0a377/remoting/server/hudson/src/main/java/org/netbeans/modules/jackpot30/hudson/ClearIndexProperty.java
----------------------------------------------------------------------
diff --git a/remoting/server/hudson/src/main/java/org/netbeans/modules/jackpot30/hudson/ClearIndexProperty.java b/remoting/server/hudson/src/main/java/org/netbeans/modules/jackpot30/hudson/ClearIndexProperty.java
new file mode 100644
index 0000000..cc30684
--- /dev/null
+++ b/remoting/server/hudson/src/main/java/org/netbeans/modules/jackpot30/hudson/ClearIndexProperty.java
@@ -0,0 +1,131 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common
+ * Development and Distribution License("CDDL") (collectively, the
+ * "License"). You may not use this file except in compliance with the
+ * License. You can obtain a copy of the License at
+ * http://www.netbeans.org/cddl-gplv2.html
+ * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
+ * specific language governing permissions and limitations under the
+ * License. When distributing the software, include this License Header
+ * Notice in each file and include the License file at
+ * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the GPL Version 2 section of the License file that
+ * accompanied this code. If applicable, add the following below the
+ * License Header, with the fields enclosed by brackets [] replaced by
+ * your own identifying information:
+ * "Portions Copyrighted [year] [name of copyright owner]"
+ *
+ * If you wish your version of this file to be governed by only the CDDL
+ * or only the GPL Version 2, indicate your decision by adding
+ * "[Contributor] elects to include this software in this distribution
+ * under the [CDDL or GPL Version 2] license." If you do not indicate a
+ * single choice of license, a recipient has the option to distribute
+ * your version of this file under either the CDDL, the GPL Version 2 or
+ * to extend the choice of license to its licensees as provided above.
+ * However, if you add GPL Version 2 code and therefore, elected the GPL
+ * Version 2 license, then the option applies only if the new code is
+ * made subject to such option by the copyright holder.
+ *
+ * Contributor(s):
+ *
+ * Portions Copyrighted 2010 Sun Microsystems, Inc.
+ */
+
+package org.netbeans.modules.jackpot30.hudson;
+
+import hudson.Extension;
+import hudson.model.Action;
+import hudson.model.Hudson;
+import hudson.model.Job;
+import hudson.model.JobProperty;
+import hudson.model.JobPropertyDescriptor;
+import hudson.model.Project;
+import java.io.File;
+import java.io.IOException;
+import java.util.Collection;
+import java.util.Collections;
+import javax.servlet.ServletException;
+import net.sf.json.JSONObject;
+import org.kohsuke.stapler.StaplerRequest;
+import org.kohsuke.stapler.StaplerResponse;
+import org.netbeans.modules.jackpot30.hudson.IndexingBuilder.DescriptorImpl;
+
+/**
+ *
+ * @author lahvac
+ */
+public class ClearIndexProperty extends JobProperty<Job<?, ?>> {
+
+ @Override
+ public Collection<? extends Action> getJobActions(Job<?, ?> job) {
+ return Collections.singleton(new ClearIndexAction(job));
+ }
+
+ public static final class ClearIndexAction implements Action {
+
+ private final Job<?, ?> job;
+
+ public ClearIndexAction(Job<?, ?> job) {
+ this.job = job;
+ }
+
+ public String getIconFileName() {
+ return "folder-delete.gif";
+ }
+
+ public String getDisplayName() {
+ return "Clear Job Index";
+ }
+
+ public String getUrlName() {
+ return "clearIndex";
+ }
+
+ public void doDynamic(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException, InterruptedException {
+ File cacheDir = ((DescriptorImpl) DescriptorImpl.find(DescriptorImpl.class.getName())).getCacheDir();
+ File jobCacheDir = new File(cacheDir, IndexingBuilder.codeNameForJob(job));
+
+ deleteRecursivelly(jobCacheDir);
+
+ rsp.forwardToPreviousPage(req);
+ }
+
+ private static void deleteRecursivelly(File f) {
+ File[] files = f.listFiles();
+
+ if (files != null) {
+ for (File c : files) {
+ deleteRecursivelly(c);
+ }
+ }
+
+ f.delete();
+ }
+ }
+
+ @Extension // this marker indicates Hudson that this is an implementation of an extension point.
+ public static final class ClearIndexPropertyDescription extends JobPropertyDescriptor {
+
+ @Override
+ public JobProperty<?> newInstance(StaplerRequest req, JSONObject formData) throws FormException {
+ return new ClearIndexProperty();
+ }
+
+ @Override
+ public String getDisplayName() {
+ return "Clear Indices Desc";
+ }
+
+ @Override
+ public boolean isApplicable(Class<? extends Job> jobType) {
+ return Project.class.isAssignableFrom(jobType);
+ }
+
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-netbeans-jackpot30/blob/9ed0a377/remoting/server/hudson/src/main/java/org/netbeans/modules/jackpot30/hudson/IndexGlobalAction.java
----------------------------------------------------------------------
diff --git a/remoting/server/hudson/src/main/java/org/netbeans/modules/jackpot30/hudson/IndexGlobalAction.java b/remoting/server/hudson/src/main/java/org/netbeans/modules/jackpot30/hudson/IndexGlobalAction.java
new file mode 100644
index 0000000..912fb37
--- /dev/null
+++ b/remoting/server/hudson/src/main/java/org/netbeans/modules/jackpot30/hudson/IndexGlobalAction.java
@@ -0,0 +1,105 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2011-2012 Oracle and/or its affiliates. All rights reserved.
+ *
+ * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
+ * Other names may be trademarks of their respective owners.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common
+ * Development and Distribution License("CDDL") (collectively, the
+ * "License"). You may not use this file except in compliance with the
+ * License. You can obtain a copy of the License at
+ * http://www.netbeans.org/cddl-gplv2.html
+ * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
+ * specific language governing permissions and limitations under the
+ * License. When distributing the software, include this License Header
+ * Notice in each file and include the License file at
+ * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the GPL Version 2 section of the License file that
+ * accompanied this code. If applicable, add the following below the
+ * License Header, with the fields enclosed by brackets [] replaced by
+ * your own identifying information:
+ * "Portions Copyrighted [year] [name of copyright owner]"
+ *
+ * If you wish your version of this file to be governed by only the CDDL
+ * or only the GPL Version 2, indicate your decision by adding
+ * "[Contributor] elects to include this software in this distribution
+ * under the [CDDL or GPL Version 2] license." If you do not indicate a
+ * single choice of license, a recipient has the option to distribute
+ * your version of this file under either the CDDL, the GPL Version 2 or
+ * to extend the choice of license to its licensees as provided above.
+ * However, if you add GPL Version 2 code and therefore, elected the GPL
+ * Version 2 license, then the option applies only if the new code is
+ * made subject to such option by the copyright holder.
+ *
+ * Contributor(s):
+ *
+ * Portions Copyrighted 2011-2012 Sun Microsystems, Inc.
+ */
+package org.netbeans.modules.jackpot30.hudson;
+
+import hudson.Extension;
+import hudson.model.RootAction;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URLConnection;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.servlet.ServletException;
+import org.kohsuke.stapler.StaplerRequest;
+import org.kohsuke.stapler.StaplerResponse;
+
+/**
+ *
+ * @author lahvac
+ */
+@Extension
+public class IndexGlobalAction implements RootAction {
+
+ public String getIconFileName() {
+ return null;
+ }
+
+ public String getDisplayName() {
+ return "Jackpot 3.0 Index";
+ }
+
+ public String getUrlName() {
+ return "index";
+ }
+
+ public void doDynamic(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException, InterruptedException {
+ InputStream in = null;
+ OutputStream out = null;
+ try {
+ URI delegateURI = new URI("http://localhost:9998/index" + req.getRestOfPath() + "?" + req.getQueryString());
+ URLConnection inConnection = delegateURI.toURL().openConnection();
+ in = inConnection.getInputStream();
+
+ rsp.setContentType(inConnection.getContentType());
+ rsp.setCharacterEncoding(inConnection.getContentEncoding());
+
+ out = rsp.getOutputStream();
+ int read;
+
+ while ((read = in.read()) != (-1)) {
+ out.write(read);
+ }
+ } catch (URISyntaxException ex) {
+ Logger.getLogger(IndexGlobalAction.class.getName()).log(Level.SEVERE, null, ex);
+ } finally {
+ if (in != null) {
+ in.close();
+ }
+ if (out != null) {
+ out.close();
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-netbeans-jackpot30/blob/9ed0a377/remoting/server/hudson/src/main/java/org/netbeans/modules/jackpot30/hudson/IndexingBuilder.java
----------------------------------------------------------------------
diff --git a/remoting/server/hudson/src/main/java/org/netbeans/modules/jackpot30/hudson/IndexingBuilder.java b/remoting/server/hudson/src/main/java/org/netbeans/modules/jackpot30/hudson/IndexingBuilder.java
new file mode 100644
index 0000000..8e933e8
--- /dev/null
+++ b/remoting/server/hudson/src/main/java/org/netbeans/modules/jackpot30/hudson/IndexingBuilder.java
@@ -0,0 +1,384 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common
+ * Development and Distribution License("CDDL") (collectively, the
+ * "License"). You may not use this file except in compliance with the
+ * License. You can obtain a copy of the License at
+ * http://www.netbeans.org/cddl-gplv2.html
+ * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
+ * specific language governing permissions and limitations under the
+ * License. When distributing the software, include this License Header
+ * Notice in each file and include the License file at
+ * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the GPL Version 2 section of the License file that
+ * accompanied this code. If applicable, add the following below the
+ * License Header, with the fields enclosed by brackets [] replaced by
+ * your own identifying information:
+ * "Portions Copyrighted [year] [name of copyright owner]"
+ *
+ * If you wish your version of this file to be governed by only the CDDL
+ * or only the GPL Version 2, indicate your decision by adding
+ * "[Contributor] elects to include this software in this distribution
+ * under the [CDDL or GPL Version 2] license." If you do not indicate a
+ * single choice of license, a recipient has the option to distribute
+ * your version of this file under either the CDDL, the GPL Version 2 or
+ * to extend the choice of license to its licensees as provided above.
+ * However, if you add GPL Version 2 code and therefore, elected the GPL
+ * Version 2 license, then the option applies only if the new code is
+ * made subject to such option by the copyright holder.
+ *
+ * Contributor(s):
+ *
+ * Portions Copyrighted 2010 Sun Microsystems, Inc.
+ */
+
+package org.netbeans.modules.jackpot30.hudson;
+
+import hudson.Extension;
+import hudson.FilePath;
+import hudson.FilePath.FileCallable;
+import hudson.Launcher;
+import hudson.Proc;
+import hudson.model.AbstractBuild;
+import hudson.model.AbstractProject;
+import hudson.model.BuildListener;
+import hudson.model.Descriptor;
+import hudson.model.Descriptor.FormException;
+import hudson.model.Hudson;
+import hudson.model.Job;
+import hudson.remoting.VirtualChannel;
+import hudson.tasks.Builder;
+import hudson.util.ArgumentListBuilder;
+import hudson.util.FormValidation;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.io.Serializable;
+import java.io.Writer;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.regex.PatternSyntaxException;
+import net.sf.json.JSONObject;
+import org.kohsuke.stapler.AncestorInPath;
+import org.kohsuke.stapler.DataBoundConstructor;
+import org.kohsuke.stapler.QueryParameter;
+import org.kohsuke.stapler.StaplerRequest;
+
+/**
+ *
+ * @author lahvac
+ */
+public class IndexingBuilder extends Builder {
+
+ private final String projectName;
+ private final String toolName;
+ private final String indexSubDirectory;
+ private final String ignorePatterns;
+
+ public IndexingBuilder(StaplerRequest req, JSONObject json) throws FormException {
+ projectName = json.getString("projectName");
+ toolName = json.optString("toolName", IndexingTool.DEFAULT_INDEXING_NAME);
+ indexSubDirectory = json.optString("indexSubDirectory", "");
+ ignorePatterns = json.optString("ignorePatterns", "");
+ }
+
+ @DataBoundConstructor
+ public IndexingBuilder(String projectName, String toolName, String indexSubDirectory, String ignorePatterns) {
+ this.projectName = projectName;
+ this.toolName = toolName;
+ this.indexSubDirectory = indexSubDirectory;
+ this.ignorePatterns = ignorePatterns != null ? ignorePatterns : "";
+ }
+
+ public String getProjectName() {
+ return projectName;
+ }
+
+ public String getToolName() {
+ return toolName;
+ }
+
+ public String getIndexSubDirectory() {
+ return indexSubDirectory;
+ }
+
+ public String getIgnorePatterns() {
+ return ignorePatterns;
+ }
+
+ @Override
+ public DescriptorImpl getDescriptor() {
+ return (DescriptorImpl) super.getDescriptor();
+ }
+
+ @Override
+ public boolean perform(AbstractBuild<?, ?> build, Launcher launcher, BuildListener listener) throws InterruptedException, IOException {
+ IndexingTool t = findSelectedTool();
+
+ if (t == null) {
+ listener.getLogger().println("Cannot find indexing tool: " + toolName);
+ return false;
+ }
+
+ t = t.forNode(build.getBuiltOn(), listener);
+
+ listener.getLogger().println("Looking for projects in: " + build.getWorkspace().getRemote());
+
+ FilePath base = indexSubDirectory == null || indexSubDirectory.isEmpty() ? build.getWorkspace() : build.getWorkspace().child(indexSubDirectory); //XXX: child also supports absolute paths! absolute paths should not be allowed here (for security)
+ RemoteResult res = base.act(new FindProjects(t.getHome(), getIgnorePatterns()));
+
+ listener.getLogger().println("Running: " + toolName + " on projects: " + res);
+
+ String codeName = codeNameForJob(build.getParent());
+ ArgumentListBuilder args = new ArgumentListBuilder();
+ FilePath targetZip = build.getBuiltOn().getRootPath().createTempFile(codeName, "zip");
+
+ //XXX: there should be a way to specify Java runtime!
+ args.add(new File(t.getHome(), "index.sh")); //XXX
+ args.add(codeName);
+ args.add(projectName); //XXX
+ args.add(targetZip);
+ args.add(res.root);
+ args.add(res.foundProjects.toArray(new String[0]));
+
+ Proc indexer = launcher.launch().pwd(base)
+ .cmds(args)
+ .envs("JPT30_INFO=BUILD_ID=" + build.getNumber())
+ .stdout(listener)
+ .start();
+
+ indexer.join();
+
+ InputStream ins = targetZip.read();
+
+ try {
+ UploadIndex.uploadIndex(codeName, ins);
+ } finally {
+ ins.close();
+ targetZip.delete();
+ }
+
+ return true;
+ }
+
+ public IndexingTool findSelectedTool() {
+ for (IndexingTool t : getDescriptor().getIndexingTools()) {
+ if (toolName.equals(t.getName())) return t;
+ }
+
+ return null;
+ }
+
+ private static void findProjects(File root, Collection<String> result, Iterable<Pattern> markers, Iterable<Pattern> ignores, Pattern perProjectIgnore, StringBuilder relPath) {
+ int len = relPath.length();
+ boolean first = relPath.length() == 0;
+
+ for (Pattern marker : markers) {
+ Matcher m = marker.matcher(relPath);
+
+ if (m.matches()) {
+ if (perProjectIgnore == null || !perProjectIgnore.matcher(relPath).matches()) {
+ result.add(m.group(1));
+ }
+ break;
+ }
+ }
+
+ File[] children = root.listFiles();
+
+ if (children != null) {
+ Arrays.sort(children, new Comparator<File>() {
+ public int compare(File o1, File o2) {
+ return o1.getName().compareTo(o2.getName());
+ }
+ });
+ OUTER: for (File c : children) {
+ for (Pattern ignore : ignores) {
+ if (ignore.matcher(c.getName()).matches()) continue OUTER;
+ }
+ if (!first)
+ relPath.append("/");
+ relPath.append(c.getName());
+ findProjects(c, result, markers, ignores, perProjectIgnore, relPath);
+ relPath.delete(len, relPath.length());
+ }
+ }
+ }
+
+ public static String codeNameForJob(Job<?, ?> job) {
+ return job.getName();
+ }
+
+ private static final class RemoteResult implements Serializable {
+ private final Collection<String> foundProjects;
+ private final String root;
+ public RemoteResult(Collection<String> foundProjects, String root) {
+ this.foundProjects = foundProjects;
+ this.root = root;
+ }
+ }
+
+ @Extension // this marker indicates Hudson that this is an implementation of an extension point.
+ public static class DescriptorImpl extends Descriptor<Builder> { //non-final for tests
+
+ private File cacheDir;
+ private String webVMOptions;
+
+ public DescriptorImpl() {
+ cacheDir = new File(Hudson.getInstance().getRootDir(), "index").getAbsoluteFile();
+ webVMOptions = "";
+ load();
+ }
+
+ public File getCacheDir() {
+ return cacheDir;
+ }
+
+ public String getWebVMOptions() {
+ return webVMOptions;
+ }
+
+ @Override
+ public Builder newInstance(StaplerRequest req, JSONObject formData) throws FormException {
+ return new IndexingBuilder(req, formData);
+ }
+
+ @Override
+ public boolean configure(StaplerRequest req, JSONObject json) throws FormException {
+ cacheDir = new File(json.getString("cacheDir"));
+
+ String newWebVMOptions = json.getString("webVMOptions");
+
+ if (newWebVMOptions == null) newWebVMOptions = "";
+
+ boolean restartWebFrontEnd = !webVMOptions.equals(newWebVMOptions);
+
+ webVMOptions = newWebVMOptions;
+
+ save();
+
+ boolean result = super.configure(req, json);
+
+ if (restartWebFrontEnd)
+ WebFrontEnd.restart();
+
+ return result;
+ }
+
+ @Override
+ public String getDisplayName() {
+ return "Run Indexers";
+ }
+
+ public List<? extends IndexingTool> getIndexingTools() {
+ return Arrays.asList(Hudson.getInstance().getDescriptorByType(IndexingTool.DescriptorImpl.class).getInstallations());
+ }
+
+ public boolean hasNonStandardIndexingTool() {
+ return getIndexingTools().size() > 1;
+ }
+
+ public FormValidation doCheckIndexSubDirectory(@AncestorInPath AbstractProject project, @QueryParameter String value) throws IOException, InterruptedException {
+ FilePath workspace = project.getSomeWorkspace();
+ if (workspace == null || !workspace.exists() || value == null || value.isEmpty() || workspace.child(value).isDirectory()) {
+ return FormValidation.ok();
+ } else {
+ return workspace.validateRelativeDirectory(value);
+ }
+ }
+
+ public FormValidation doCheckIgnorePatterns(@AncestorInPath AbstractProject project, @QueryParameter String ignorePatterns) throws IOException, InterruptedException {
+ FilePath workspace = project.getSomeWorkspace();
+ if (workspace == null || !workspace.exists() || ignorePatterns == null || ignorePatterns.isEmpty()) {
+ return FormValidation.ok();
+ } else {
+ try {
+ Pattern.compile(ignorePatterns);
+ return FormValidation.ok();
+ } catch (PatternSyntaxException ex) {
+ return FormValidation.error("Not a valid regular expression (" + ex.getDescription() + ")");
+ }
+ }
+ }
+
+ }
+
+ private static class FindProjects implements FileCallable<RemoteResult> {
+ private final String toolHome;
+ private final String perProjectIgnore;
+ public FindProjects(String toolHome, String perProjectIgnore) {
+ this.toolHome = toolHome;
+ this.perProjectIgnore = perProjectIgnore;
+ }
+ public RemoteResult invoke(File file, VirtualChannel vc) throws IOException, InterruptedException {
+ List<Pattern> projectMarkers = new ArrayList<Pattern>();
+ List<Pattern> ignorePatterns = new ArrayList<Pattern>();
+ FilePath indexerPath = new FilePath(new File(toolHome, "indexer"));
+ for (FilePath clusters : indexerPath.listDirectories()) {
+ FilePath patternsDirectory = clusters.child("patterns");
+ if (!patternsDirectory.isDirectory()) continue;
+ for (FilePath patterns : patternsDirectory.list()) {
+ if (patterns.getName().startsWith("project-marker-")) {
+ projectMarkers.addAll(readPatterns(patterns));
+ } else if (patterns.getName().startsWith("ignore-")) {
+ ignorePatterns.addAll(readPatterns(patterns));
+ }
+ }
+ }
+
+ Set<String> projects = new HashSet<String>();
+
+ findProjects(file, projects, projectMarkers, ignorePatterns, perProjectIgnore == null || perProjectIgnore.trim().isEmpty() ? null : Pattern.compile(perProjectIgnore), new StringBuilder());
+
+ return new RemoteResult(projects, file.getCanonicalPath()/*XXX: will resolve symlinks!!!*/);
+ }
+ }
+
+ private static List<Pattern> readPatterns(FilePath source) {
+ BufferedReader in = null;
+
+ List<Pattern> result = new ArrayList<Pattern>();
+ try {
+ in = new BufferedReader(new InputStreamReader(source.read(), "UTF-8"));
+ String line;
+
+ while ((line = in.readLine()) != null) {
+ line = line.trim();
+ if (!line.isEmpty()) {
+ result.add(Pattern.compile(line));
+ }
+ }
+ } catch (IOException ex) {
+ Logger.getLogger(IndexingBuilder.class.getName()).log(Level.SEVERE, null, ex);
+ } finally {
+ if (in != null) {
+ try {
+ in.close();
+ } catch (IOException ex) {
+ Logger.getLogger(IndexingBuilder.class.getName()).log(Level.SEVERE, null, ex);
+ }
+ }
+ }
+
+ return result;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-netbeans-jackpot30/blob/9ed0a377/remoting/server/hudson/src/main/java/org/netbeans/modules/jackpot30/hudson/IndexingTool.java
----------------------------------------------------------------------
diff --git a/remoting/server/hudson/src/main/java/org/netbeans/modules/jackpot30/hudson/IndexingTool.java b/remoting/server/hudson/src/main/java/org/netbeans/modules/jackpot30/hudson/IndexingTool.java
new file mode 100644
index 0000000..3fae28f
--- /dev/null
+++ b/remoting/server/hudson/src/main/java/org/netbeans/modules/jackpot30/hudson/IndexingTool.java
@@ -0,0 +1,100 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2011 Sun Microsystems, Inc. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common
+ * Development and Distribution License("CDDL") (collectively, the
+ * "License"). You may not use this file except in compliance with the
+ * License. You can obtain a copy of the License at
+ * http://www.netbeans.org/cddl-gplv2.html
+ * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
+ * specific language governing permissions and limitations under the
+ * License. When distributing the software, include this License Header
+ * Notice in each file and include the License file at
+ * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the GPL Version 2 section of the License file that
+ * accompanied this code. If applicable, add the following below the
+ * License Header, with the fields enclosed by brackets [] replaced by
+ * your own identifying information:
+ * "Portions Copyrighted [year] [name of copyright owner]"
+ *
+ * If you wish your version of this file to be governed by only the CDDL
+ * or only the GPL Version 2, indicate your decision by adding
+ * "[Contributor] elects to include this software in this distribution
+ * under the [CDDL or GPL Version 2] license." If you do not indicate a
+ * single choice of license, a recipient has the option to distribute
+ * your version of this file under either the CDDL, the GPL Version 2 or
+ * to extend the choice of license to its licensees as provided above.
+ * However, if you add GPL Version 2 code and therefore, elected the GPL
+ * Version 2 license, then the option applies only if the new code is
+ * made subject to such option by the copyright holder.
+ *
+ * Contributor(s):
+ *
+ * Portions Copyrighted 2011 Sun Microsystems, Inc.
+ */
+package org.netbeans.modules.jackpot30.hudson;
+
+import hudson.Extension;
+import hudson.model.Node;
+import hudson.model.TaskListener;
+import hudson.slaves.NodeSpecific;
+import hudson.tools.ToolDescriptor;
+import hudson.tools.ToolInstallation;
+import hudson.tools.ToolProperty;
+import java.io.IOException;
+import java.util.List;
+import org.kohsuke.stapler.DataBoundConstructor;
+
+/**
+ *
+ * @author lahvac
+ */
+public class IndexingTool extends ToolInstallation implements NodeSpecific<IndexingTool> {
+
+ public static final String DEFAULT_INDEXING_NAME = "Main NetBeans Indexing";
+
+ @DataBoundConstructor
+ public IndexingTool(String name, String home, List<? extends ToolProperty<?>> properties) {
+ super(name, home, properties);
+ }
+
+ public IndexingTool forNode(Node node, TaskListener tl) throws IOException, InterruptedException {
+ return new IndexingTool(getName(), translateFor(node, tl), getProperties().toList());
+ }
+
+ @Extension
+ public static final class DescriptorImpl extends ToolDescriptor<IndexingTool> {
+
+ @Override
+ public String getDisplayName() {
+ return "Indexing Tool";
+ }
+
+ private IndexingTool[] installations;
+
+ @Override
+ public IndexingTool[] getInstallations() {
+ if (installations == null) {
+ load();
+
+ if (installations == null) {
+ installations = new IndexingTool[0];
+ }
+ }
+
+ return installations.clone();
+ }
+
+ @Override
+ public void setInstallations(IndexingTool... installations) {
+ this.installations = installations.clone();
+ save();
+ }
+
+
+ }
+}