Trying to make the remote Go to Type/Symbol query less intrusive.
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/remoting/ide/jumpto/src/org/netbeans/modules/jackpot30/jumpto/AbstractDescriptor.java Thu Jul 14 23:03:50 2011 +0200
1.3 @@ -0,0 +1,118 @@
1.4 +/*
1.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
1.6 + *
1.7 + * Copyright 2011 Oracle and/or its affiliates. All rights reserved.
1.8 + *
1.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
1.10 + * Other names may be trademarks of their respective owners.
1.11 + *
1.12 + * The contents of this file are subject to the terms of either the GNU
1.13 + * General Public License Version 2 only ("GPL") or the Common
1.14 + * Development and Distribution License("CDDL") (collectively, the
1.15 + * "License"). You may not use this file except in compliance with the
1.16 + * License. You can obtain a copy of the License at
1.17 + * http://www.netbeans.org/cddl-gplv2.html
1.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
1.19 + * specific language governing permissions and limitations under the
1.20 + * License. When distributing the software, include this License Header
1.21 + * Notice in each file and include the License file at
1.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
1.23 + * particular file as subject to the "Classpath" exception as provided
1.24 + * by Oracle in the GPL Version 2 section of the License file that
1.25 + * accompanied this code. If applicable, add the following below the
1.26 + * License Header, with the fields enclosed by brackets [] replaced by
1.27 + * your own identifying information:
1.28 + * "Portions Copyrighted [year] [name of copyright owner]"
1.29 + *
1.30 + * If you wish your version of this file to be governed by only the CDDL
1.31 + * or only the GPL Version 2, indicate your decision by adding
1.32 + * "[Contributor] elects to include this software in this distribution
1.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
1.34 + * single choice of license, a recipient has the option to distribute
1.35 + * your version of this file under either the CDDL, the GPL Version 2 or
1.36 + * to extend the choice of license to its licensees as provided above.
1.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
1.38 + * Version 2 license, then the option applies only if the new code is
1.39 + * made subject to such option by the copyright holder.
1.40 + *
1.41 + * Contributor(s):
1.42 + *
1.43 + * Portions Copyrighted 2011 Sun Microsystems, Inc.
1.44 + */
1.45 +package org.netbeans.modules.jackpot30.jumpto;
1.46 +
1.47 +import java.util.concurrent.atomic.AtomicReference;
1.48 +import javax.swing.Icon;
1.49 +import org.netbeans.api.project.FileOwnerQuery;
1.50 +import org.netbeans.api.project.Project;
1.51 +import org.netbeans.api.project.ProjectUtils;
1.52 +import org.openide.filesystems.FileObject;
1.53 +
1.54 +/**
1.55 + *
1.56 + * @author lahvac
1.57 + */
1.58 +public abstract class AbstractDescriptor {
1.59 +
1.60 + private final AtomicReference<String> displayName = new AtomicReference<String>();
1.61 + private final AtomicReference<FileObject> file = new AtomicReference<FileObject>();
1.62 +
1.63 + protected AbstractDescriptor() {
1.64 + }
1.65 +
1.66 + public String getProjectName() {
1.67 + String displayName = this.displayName.get();
1.68 +
1.69 + if (displayName != null) {
1.70 + return displayName;
1.71 + }
1.72 +
1.73 + FileObject file = getFileObject();
1.74 +
1.75 + if (file == null) {
1.76 + return null;
1.77 + }
1.78 +
1.79 + Project prj = FileOwnerQuery.getOwner(file);
1.80 +
1.81 + if (prj == null) {
1.82 + return null;
1.83 + }
1.84 +
1.85 + this.displayName.set(displayName = ProjectUtils.getInformation(prj).getDisplayName());
1.86 +
1.87 + return displayName;
1.88 + }
1.89 +
1.90 + public Icon getProjectIcon() {
1.91 + FileObject file = getFileObject();
1.92 +
1.93 + if (file == null) {
1.94 + return null;
1.95 + }
1.96 +
1.97 + Project prj = FileOwnerQuery.getOwner(file);
1.98 +
1.99 + if (prj == null) {
1.100 + return null;
1.101 + }
1.102 +
1.103 + return ProjectUtils.getInformation(prj).getIcon();
1.104 + }
1.105 +
1.106 + public FileObject getFileObject() {
1.107 + FileObject f = this.file.get();
1.108 +
1.109 + if (f == null) {
1.110 + f = resolveFile();
1.111 +
1.112 + if (f != null) {
1.113 + this.file.set(f);
1.114 + }
1.115 + }
1.116 +
1.117 + return f;
1.118 + }
1.119 +
1.120 + protected abstract FileObject resolveFile();
1.121 +}
2.1 --- a/remoting/ide/jumpto/src/org/netbeans/modules/jackpot30/jumpto/RemoteGoToSymbol.java Thu Jul 14 15:29:41 2011 +0200
2.2 +++ b/remoting/ide/jumpto/src/org/netbeans/modules/jackpot30/jumpto/RemoteGoToSymbol.java Thu Jul 14 23:03:50 2011 +0200
2.3 @@ -44,7 +44,7 @@
2.4 import java.io.File;
2.5 import java.net.URI;
2.6 import java.net.URISyntaxException;
2.7 -import java.util.Arrays;
2.8 +import java.util.ArrayList;
2.9 import java.util.Collection;
2.10 import java.util.EnumSet;
2.11 import java.util.HashSet;
2.12 @@ -53,7 +53,6 @@
2.13 import java.util.Map;
2.14 import java.util.Map.Entry;
2.15 import java.util.Set;
2.16 -import java.util.concurrent.atomic.AtomicReference;
2.17 import javax.lang.model.element.ElementKind;
2.18 import javax.lang.model.element.Modifier;
2.19 import javax.swing.Icon;
2.20 @@ -62,17 +61,14 @@
2.21 import org.netbeans.api.java.source.ElementHandle;
2.22 import org.netbeans.api.java.source.ui.ElementIcons;
2.23 import org.netbeans.api.java.source.ui.ElementOpen;
2.24 -import org.netbeans.api.project.FileOwnerQuery;
2.25 -import org.netbeans.api.project.Project;
2.26 -import org.netbeans.api.project.ProjectUtils;
2.27 +import org.netbeans.modules.jackpot30.jumpto.RemoteGoToSymbol.RemoteSymbolDescriptor;
2.28 +import org.netbeans.modules.jackpot30.jumpto.RemoteQuery.SimpleNameable;
2.29 import org.netbeans.modules.jackpot30.remoting.api.RemoteIndex;
2.30 import org.netbeans.modules.jackpot30.remoting.api.WebUtilities;
2.31 import org.netbeans.modules.java.source.ElementHandleAccessor;
2.32 -import org.netbeans.modules.java.source.usages.ClassFileUtil;
2.33 import org.netbeans.spi.jumpto.symbol.SymbolDescriptor;
2.34 import org.netbeans.spi.jumpto.symbol.SymbolProvider;
2.35 -import org.netbeans.spi.jumpto.type.TypeDescriptor;
2.36 -import org.netbeans.spi.jumpto.type.TypeProvider;
2.37 +import org.netbeans.spi.jumpto.type.SearchType;
2.38 import org.openide.filesystems.FileObject;
2.39 import org.openide.filesystems.FileUtil;
2.40 import org.openide.util.Exceptions;
2.41 @@ -83,7 +79,7 @@
2.42 * @author lahvac
2.43 */
2.44 @ServiceProvider(service=SymbolProvider.class)
2.45 -public class RemoteGoToSymbol implements SymbolProvider {
2.46 +public class RemoteGoToSymbol extends RemoteQuery<RemoteSymbolDescriptor> implements SymbolProvider {
2.47
2.48 @Override
2.49 public String name() {
2.50 @@ -96,10 +92,22 @@
2.51 }
2.52
2.53 @Override
2.54 - public void computeSymbolNames(Context context, Result result) {
2.55 + public void computeSymbolNames(Context context, final Result result) {
2.56 + performQuery(context.getText(), context.getSearchType(), new ResultWrapper<RemoteSymbolDescriptor>() {
2.57 + @Override public void setMessage(String message) {
2.58 + result.setMessage(message);
2.59 + }
2.60 + @Override public void addResult(RemoteSymbolDescriptor r) {
2.61 + result.addResult(r);
2.62 + }
2.63 + });
2.64 + }
2.65 +
2.66 + @Override
2.67 + protected void compute(String text, SearchType searchType) {
2.68 for (RemoteIndex ri : RemoteIndex.loadIndices()) {
2.69 try {
2.70 - URI resolved = new URI(ri.remote.toExternalForm() + "/symbol/search?path=" + WebUtilities.escapeForQuery(ri.remoteSegment) + "&prefix=" + WebUtilities.escapeForQuery(context.getText()) + "&querykind=" + WebUtilities.escapeForQuery(context.getSearchType().name()));
2.71 + URI resolved = new URI(ri.remote.toExternalForm() + "/symbol/search?path=" + WebUtilities.escapeForQuery(ri.remoteSegment) + "&prefix=" + WebUtilities.escapeForQuery(text) + "&querykind=" + WebUtilities.escapeForQuery(searchType.name()));
2.72 String response = WebUtilities.requestStringResponse(resolved);
2.73
2.74 if (response == null) continue;
2.75 @@ -107,34 +115,37 @@
2.76 @SuppressWarnings("unchecked") //XXX: should not trust something got from the network!
2.77 Map<String, Iterable<Map<String, Object>>> types = Pojson.load(LinkedHashMap.class, response);
2.78
2.79 + List<RemoteSymbolDescriptor> result = new ArrayList<RemoteSymbolDescriptor>();
2.80 +
2.81 for (Entry<String, Iterable<Map<String, Object>>> e : types.entrySet()) {
2.82 for (Map<String, Object> properties : e.getValue()) {
2.83 - result.addResult(new RemoteSymbolDescriptor(ri, properties));
2.84 + result.add(new RemoteSymbolDescriptor(ri, properties));
2.85 }
2.86 }
2.87 +
2.88 + addResults(result);
2.89 } catch (URISyntaxException ex) {
2.90 Exceptions.printStackTrace(ex);
2.91 }
2.92 }
2.93 }
2.94
2.95 - @Override
2.96 - public void cancel() {
2.97 - }
2.98 + static final class RemoteSymbolDescriptor extends SymbolDescriptor implements SimpleNameable {
2.99
2.100 - @Override
2.101 - public void cleanup() {
2.102 - }
2.103 + private final Map<String, Object> properties;
2.104 + private final AbstractDescriptor delegate;
2.105
2.106 - static final class RemoteSymbolDescriptor extends SymbolDescriptor {
2.107 + public RemoteSymbolDescriptor(final RemoteIndex origin, final Map<String, Object> properties) {
2.108 + this.properties = properties;
2.109 + this.delegate = new AbstractDescriptor() {
2.110 + @Override
2.111 + protected FileObject resolveFile() {
2.112 + String relativePath = (String) properties.get("file");
2.113 + FileObject originFolder = FileUtil.toFileObject(FileUtil.normalizeFile(new File(origin.folder)));
2.114
2.115 - private final RemoteIndex origin;
2.116 - private final Map<String, Object> properties;
2.117 - private final AtomicReference<FileObject> file = new AtomicReference<FileObject>();
2.118 -
2.119 - public RemoteSymbolDescriptor(RemoteIndex origin, Map<String, Object> properties) {
2.120 - this.origin = origin;
2.121 - this.properties = properties;
2.122 + return originFolder != null ? originFolder.getFileObject(relativePath) : null;
2.123 + }
2.124 + };
2.125 }
2.126
2.127 @Override
2.128 @@ -168,43 +179,17 @@
2.129
2.130 @Override
2.131 public String getProjectName() {
2.132 - FileObject file = getFileObject();
2.133 -
2.134 - if (file == null) return null;
2.135 -
2.136 - Project prj = FileOwnerQuery.getOwner(file);
2.137 -
2.138 - if (prj == null) return null;
2.139 -
2.140 - return ProjectUtils.getInformation(prj).getDisplayName();
2.141 + return delegate.getProjectName();
2.142 }
2.143
2.144 @Override
2.145 public Icon getProjectIcon() {
2.146 - FileObject file = getFileObject();
2.147 -
2.148 - if (file == null) return null;
2.149 -
2.150 - Project prj = FileOwnerQuery.getOwner(file);
2.151 -
2.152 - if (prj == null) return null;
2.153 -
2.154 - return ProjectUtils.getInformation(prj).getIcon();
2.155 + return delegate.getProjectIcon();
2.156 }
2.157
2.158 @Override
2.159 public FileObject getFileObject() {
2.160 - FileObject f = this.file.get();
2.161 -
2.162 - if (f == null) {
2.163 - String relativePath = (String) properties.get("file");
2.164 - FileObject originFolder = FileUtil.toFileObject(FileUtil.normalizeFile(new File(origin.folder)));
2.165 -
2.166 - if (originFolder != null) f = originFolder.getFileObject(relativePath);
2.167 - if (f != null) this.file.set(f);
2.168 - }
2.169 -
2.170 - return f;
2.171 + return delegate.getFileObject();
2.172 }
2.173
2.174 @Override
2.175 @@ -242,6 +227,11 @@
2.176 return (String) properties.get("enclosingFQN");
2.177 }
2.178
2.179 + @Override
2.180 + public String getSimpleName() {
2.181 + return (String) properties.get("simpleName");
2.182 + }
2.183 +
2.184 }
2.185
2.186 private static char getChar (final String buffer, final int pos) {
3.1 --- a/remoting/ide/jumpto/src/org/netbeans/modules/jackpot30/jumpto/RemoteGoToType.java Thu Jul 14 15:29:41 2011 +0200
3.2 +++ b/remoting/ide/jumpto/src/org/netbeans/modules/jackpot30/jumpto/RemoteGoToType.java Thu Jul 14 23:03:50 2011 +0200
3.3 @@ -44,12 +44,12 @@
3.4 import java.io.File;
3.5 import java.net.URI;
3.6 import java.net.URISyntaxException;
3.7 +import java.util.ArrayList;
3.8 import java.util.EnumSet;
3.9 import java.util.LinkedHashMap;
3.10 import java.util.List;
3.11 import java.util.Map;
3.12 import java.util.Map.Entry;
3.13 -import java.util.concurrent.atomic.AtomicReference;
3.14 import javax.lang.model.element.ElementKind;
3.15 import javax.lang.model.element.Modifier;
3.16 import javax.swing.Icon;
3.17 @@ -58,12 +58,12 @@
3.18 import org.netbeans.api.java.source.ElementHandle;
3.19 import org.netbeans.api.java.source.ui.ElementIcons;
3.20 import org.netbeans.api.java.source.ui.ElementOpen;
3.21 -import org.netbeans.api.project.FileOwnerQuery;
3.22 -import org.netbeans.api.project.Project;
3.23 -import org.netbeans.api.project.ProjectUtils;
3.24 +import org.netbeans.modules.jackpot30.jumpto.RemoteGoToType.RemoteTypeDescriptor;
3.25 +import org.netbeans.modules.jackpot30.jumpto.RemoteQuery.SimpleNameable;
3.26 import org.netbeans.modules.jackpot30.remoting.api.RemoteIndex;
3.27 import org.netbeans.modules.jackpot30.remoting.api.WebUtilities;
3.28 import org.netbeans.modules.java.source.ElementHandleAccessor;
3.29 +import org.netbeans.spi.jumpto.type.SearchType;
3.30 import org.netbeans.spi.jumpto.type.TypeDescriptor;
3.31 import org.netbeans.spi.jumpto.type.TypeProvider;
3.32 import org.openide.filesystems.FileObject;
3.33 @@ -76,7 +76,7 @@
3.34 * @author lahvac
3.35 */
3.36 @ServiceProvider(service=TypeProvider.class)
3.37 -public class RemoteGoToType implements TypeProvider {
3.38 +public class RemoteGoToType extends RemoteQuery<RemoteTypeDescriptor> implements TypeProvider {
3.39
3.40 @Override
3.41 public String name() {
3.42 @@ -89,10 +89,23 @@
3.43 }
3.44
3.45 @Override
3.46 - public void computeTypeNames(Context context, Result result) {
3.47 + public void computeTypeNames(Context context, final Result result) {
3.48 + performQuery(context.getText(), context.getSearchType(), new ResultWrapper<RemoteTypeDescriptor>() {
3.49 + @Override public void setMessage(String message) {
3.50 + result.setMessage(message);
3.51 + }
3.52 + @Override public void addResult(RemoteTypeDescriptor r) {
3.53 + result.addResult(r);
3.54 + }
3.55 + });
3.56 + }
3.57 +
3.58 + @Override
3.59 + protected void compute(String text, SearchType searchType) {
3.60 for (RemoteIndex ri : RemoteIndex.loadIndices()) {
3.61 try {
3.62 - URI resolved = new URI(ri.remote.toExternalForm() + "/type/search?path=" + WebUtilities.escapeForQuery(ri.remoteSegment) + "&prefix=" + WebUtilities.escapeForQuery(context.getText()));
3.63 + //XXX: should send exact search type:
3.64 + URI resolved = new URI(ri.remote.toExternalForm() + "/type/search?path=" + WebUtilities.escapeForQuery(ri.remoteSegment) + "&prefix=" + WebUtilities.escapeForQuery(text));
3.65 String response = WebUtilities.requestStringResponse(resolved);
3.66
3.67 if (response == null) continue;
3.68 @@ -100,36 +113,43 @@
3.69 @SuppressWarnings("unchecked") //XXX: should not trust something got from the network!
3.70 Map<String, List<String>> types = Pojson.load(LinkedHashMap.class, response);
3.71
3.72 + List<RemoteTypeDescriptor> result = new ArrayList<RemoteTypeDescriptor>();
3.73 +
3.74 for (Entry<String, List<String>> e : types.entrySet()) {
3.75 for (String binaryName : e.getValue()) {
3.76 - result.addResult(new RemoteTypeDescriptor(ri, e.getKey(), binaryName));
3.77 + result.add(new RemoteTypeDescriptor(ri, e.getKey(), binaryName));
3.78 }
3.79 }
3.80 +
3.81 + addResults(result);
3.82 } catch (URISyntaxException ex) {
3.83 Exceptions.printStackTrace(ex);
3.84 }
3.85 }
3.86 }
3.87
3.88 - @Override
3.89 - public void cancel() {
3.90 - }
3.91 + static final class RemoteTypeDescriptor extends TypeDescriptor implements SimpleNameable {
3.92
3.93 - @Override
3.94 - public void cleanup() {
3.95 - }
3.96 + private final String binaryName;
3.97 + private final AbstractDescriptor delegate;
3.98
3.99 - private static final class RemoteTypeDescriptor extends TypeDescriptor {
3.100 + public RemoteTypeDescriptor(final RemoteIndex origin, final String relativePath, final String binaryName) {
3.101 + this.binaryName = binaryName;
3.102
3.103 - private final RemoteIndex origin;
3.104 - private final String relativePath;
3.105 - private final String binaryName;
3.106 - private final AtomicReference<FileObject> file = new AtomicReference<FileObject>();
3.107 + delegate = new AbstractDescriptor() {
3.108 + @Override
3.109 + protected FileObject resolveFile() {
3.110 + String fqn = binaryName;
3.111
3.112 - public RemoteTypeDescriptor(RemoteIndex origin, String relativePath, String binaryName) {
3.113 - this.origin = origin;
3.114 - this.relativePath = relativePath;
3.115 - this.binaryName = binaryName;
3.116 + if (fqn.contains("$")) {
3.117 + fqn = fqn.substring(0, fqn.indexOf("$"));
3.118 + }
3.119 +
3.120 + FileObject originFolder = FileUtil.toFileObject(FileUtil.normalizeFile(new File(origin.folder)));
3.121 +
3.122 + return originFolder != null ? originFolder.getFileObject(relativePath + "/" + fqn.replace('.', '/') + ".java") : null;
3.123 + }
3.124 + };
3.125 }
3.126
3.127 @Override
3.128 @@ -177,48 +197,17 @@
3.129
3.130 @Override
3.131 public String getProjectName() {
3.132 - FileObject file = getFileObject();
3.133 -
3.134 - if (file == null) return null;
3.135 -
3.136 - Project prj = FileOwnerQuery.getOwner(file);
3.137 -
3.138 - if (prj == null) return null;
3.139 -
3.140 - return ProjectUtils.getInformation(prj).getDisplayName();
3.141 + return delegate.getProjectName();
3.142 }
3.143
3.144 @Override
3.145 public Icon getProjectIcon() {
3.146 - FileObject file = getFileObject();
3.147 -
3.148 - if (file == null) return null;
3.149 -
3.150 - Project prj = FileOwnerQuery.getOwner(file);
3.151 -
3.152 - if (prj == null) return null;
3.153 -
3.154 - return ProjectUtils.getInformation(prj).getIcon();
3.155 + return delegate.getProjectIcon();
3.156 }
3.157
3.158 @Override
3.159 public FileObject getFileObject() {
3.160 - FileObject f = this.file.get();
3.161 -
3.162 - if (f == null) {
3.163 - String fqn = binaryName;
3.164 -
3.165 - if (fqn.contains("$")) {
3.166 - fqn = fqn.substring(0, fqn.indexOf("$"));
3.167 - }
3.168 -
3.169 - FileObject originFolder = FileUtil.toFileObject(FileUtil.normalizeFile(new File(origin.folder)));
3.170 -
3.171 - if (originFolder != null) f = originFolder.getFileObject(relativePath + "/" + fqn.replace('.', '/') + ".java");
3.172 - if (f != null) this.file.set(f);
3.173 - }
3.174 -
3.175 - return f;
3.176 + return delegate.getFileObject();
3.177 }
3.178
3.179 @Override
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
4.2 +++ b/remoting/ide/jumpto/src/org/netbeans/modules/jackpot30/jumpto/RemoteQuery.java Thu Jul 14 23:03:50 2011 +0200
4.3 @@ -0,0 +1,136 @@
4.4 +/*
4.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
4.6 + *
4.7 + * Copyright 2011 Oracle and/or its affiliates. All rights reserved.
4.8 + *
4.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
4.10 + * Other names may be trademarks of their respective owners.
4.11 + *
4.12 + * The contents of this file are subject to the terms of either the GNU
4.13 + * General Public License Version 2 only ("GPL") or the Common
4.14 + * Development and Distribution License("CDDL") (collectively, the
4.15 + * "License"). You may not use this file except in compliance with the
4.16 + * License. You can obtain a copy of the License at
4.17 + * http://www.netbeans.org/cddl-gplv2.html
4.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
4.19 + * specific language governing permissions and limitations under the
4.20 + * License. When distributing the software, include this License Header
4.21 + * Notice in each file and include the License file at
4.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
4.23 + * particular file as subject to the "Classpath" exception as provided
4.24 + * by Oracle in the GPL Version 2 section of the License file that
4.25 + * accompanied this code. If applicable, add the following below the
4.26 + * License Header, with the fields enclosed by brackets [] replaced by
4.27 + * your own identifying information:
4.28 + * "Portions Copyrighted [year] [name of copyright owner]"
4.29 + *
4.30 + * If you wish your version of this file to be governed by only the CDDL
4.31 + * or only the GPL Version 2, indicate your decision by adding
4.32 + * "[Contributor] elects to include this software in this distribution
4.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
4.34 + * single choice of license, a recipient has the option to distribute
4.35 + * your version of this file under either the CDDL, the GPL Version 2 or
4.36 + * to extend the choice of license to its licensees as provided above.
4.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
4.38 + * Version 2 license, then the option applies only if the new code is
4.39 + * made subject to such option by the copyright holder.
4.40 + *
4.41 + * Contributor(s):
4.42 + *
4.43 + * Portions Copyrighted 2011 Sun Microsystems, Inc.
4.44 + */
4.45 +package org.netbeans.modules.jackpot30.jumpto;
4.46 +
4.47 +import java.util.ArrayList;
4.48 +import java.util.Collection;
4.49 +import java.util.List;
4.50 +import java.util.logging.Level;
4.51 +import java.util.logging.Logger;
4.52 +import org.netbeans.modules.jackpot30.jumpto.RemoteQuery.SimpleNameable;
4.53 +import org.netbeans.modules.jackpot30.remoting.api.RemoteIndex;
4.54 +import org.netbeans.spi.jumpto.support.NameMatcher;
4.55 +import org.netbeans.spi.jumpto.support.NameMatcherFactory;
4.56 +import org.netbeans.spi.jumpto.type.SearchType;
4.57 +import org.openide.util.RequestProcessor;
4.58 +import org.openide.util.RequestProcessor.Task;
4.59 +
4.60 +/**
4.61 + *
4.62 + * @author lahvac
4.63 + */
4.64 +public abstract class RemoteQuery<R extends SimpleNameable> {
4.65 +
4.66 + private static final RequestProcessor WORKER = new RequestProcessor(RemoteGoToType.class.getName(), 1, true, false);
4.67 +
4.68 + private String mostGenericQueryText;
4.69 + private List<R> results;
4.70 + private Task currentWorker;
4.71 +
4.72 + protected final void performQuery(final String text, final SearchType searchType, ResultWrapper<R> result) {
4.73 + if (!RemoteIndex.loadIndices().iterator().hasNext()) return; //TODO: optimize!
4.74 +
4.75 + synchronized (this) {
4.76 + if (mostGenericQueryText == null || !text.startsWith(mostGenericQueryText)) {
4.77 + if (currentWorker != null) currentWorker.cancel();
4.78 +
4.79 + mostGenericQueryText = text;
4.80 +
4.81 + currentWorker = WORKER.create(new Runnable() {
4.82 + @Override public void run() {
4.83 + compute(text, searchType == SearchType.EXACT_NAME ? SearchType.PREFIX : searchType);
4.84 + }
4.85 + });
4.86 +
4.87 + currentWorker.schedule(0);
4.88 + results = new ArrayList<R>();
4.89 + }
4.90 + }
4.91 +
4.92 + try {
4.93 + currentWorker.waitFinished(100);
4.94 + } catch (InterruptedException ex) {
4.95 + Logger.getLogger(RemoteGoToType.class.getName()).log(Level.FINE, null, ex);
4.96 + }
4.97 +
4.98 + boolean finished = currentWorker.isFinished();
4.99 + NameMatcher matcher = NameMatcherFactory.createNameMatcher(text, searchType);
4.100 +
4.101 + synchronized (this) {
4.102 + for (R td : results) {
4.103 + if (matcher.accept(td.getSimpleName()))
4.104 + result.addResult(td);
4.105 + }
4.106 + }
4.107 +
4.108 + if (!finished) {
4.109 + result.setMessage("Remote query still running, some remote results may be missing");
4.110 + }
4.111 + }
4.112 +
4.113 + protected abstract void compute(String text, SearchType searchType);
4.114 +
4.115 + protected final synchronized void addResults(Collection<? extends R> r) {
4.116 + results.addAll(r);
4.117 + }
4.118 +
4.119 + public void cancel() {
4.120 + }
4.121 +
4.122 + public void cleanup() {
4.123 + mostGenericQueryText = null;
4.124 + results = null;
4.125 + currentWorker = null;
4.126 + }
4.127 +
4.128 + protected static interface ResultWrapper<R> {
4.129 +
4.130 + public void setMessage(String message);
4.131 + public void addResult(R r);
4.132 +
4.133 + }
4.134 +
4.135 + protected static interface SimpleNameable {
4.136 + public String getSimpleName();
4.137 + }
4.138 +
4.139 +}