diff --git a/api.intent/arch.xml b/api.intent/arch.xml new file mode 100644 --- /dev/null +++ b/api.intent/arch.xml @@ -0,0 +1,1142 @@ + + +]> + + + + &api-questions; + + + +

+ This module was originally created to provide a way to handle + clicks on hyperlinks in the output window. Some more sophisticated + objects for describing intended operations can be added into this + module in the future. +

+

+ The URI-based actions are useful if the front-end and back-end of + the application is separated, e.g. in network environment. The + actions can be specified on back-end, but handled on front-end, + without any unnecessary communication. +

+ + +

+ API for invoking some intended operation, specified by + a URI. For example, for displaying a web page in browser, or for + opening a source file in editor. +

+
+ +

+ SPI for handlers that are able to invoke proper operation for + some URI. +

+
+
+ + + + + +

+ The code is checked by unit tests. +

+
+ + + + + +

+ Done. +

+
+ + + + + + +
+    Intent.execute(Intent.forUri(new URI("scheme://path/")));
+            
+
+ + +
+    @OpenUriHandler.Registration(displayName = "Show my item in MyEditor", position = 800, uriPattern = "myscheme://.*")
+    public class TestOpenUriHandler implements OpenUriHandler {
+
+        public Object open(URI uri) {
+            if (someCondition) {
+                // perform the operation
+                return new Object();
+            } else {
+                return null;
+            }
+        }
+    }
+            
+
+
+ + + + + +

+ This module provides a contract between API clients that can express + some intention to invoke an operation (specified e.g. by a URI) and + SPI providers that can handle the URI. +

+

+ This is useful in client-server environments, where the intention + can be constructed on server-side, but handled on client-side. The + objects that describe the intention should be easy to construct, + transfer and interpret. +

+
+ + + + + + + + + + + + +

+ No deprecation needed. +

+
+ + + + + +

+ Yes. +

+
+ + + + + +

+ No standards. +

+
+ + + + + +

+ No settings are read or written. +

+
+ + + + + +

+ 1.6 +

+
+ + + + + +

+ JRE +

+
+ + + + + + + + + + + + +

+ No non-NB dependencies. +

+
+ + + + + +

+ Any platform. +

+
+ + + + + +

+ Standard module dependency is sufficient. +

+
+ + + + + +

+ Just module JAR. +

+
+ + + + + +

+ Yes. +

+
+ + + + + +

+ Only API and SPI packages are public. +

+
+ + + + + +

+ Installation location does not matter. +

+
+ + + + + +

+ No. +

+
+ + + + + +

+ No. +

+
+ + + + + +

+ No. +

+
+ + + + + +

+ No. +

+
+ + + + + +

+ No. +

+
+ + + + + +

+ No. +

+
+ + + + + +

+ No. +

+
+ + + + + +

+ No. +

+
+ + + + + +

+ The API is threadsafe. SPI implementations should ensure proper + synchronization. +

+
+ + + + + +

+ No clipboard access. +

+
+ + + + + +

+ No Drag & Drop support. +

+
+ + + + + +

+ No files are read or written by this module. +

+
+ + + + + +

+ No. +

+
+ + + + + +

+ The annotation processor is registered using ServiceProvider. +

+
+ + + + + +

+ No. +

+
+ + + + + +

+ No. +

+
+ + + + + +

+ No. +

+
+ + + + + +

+ No. +

+
+ + + + + +

+ Very little memory consumed. +

+
+ + + + + +

+ No. +

+
+ + + + + +

+ No. +

+
+ + + + + +

+ Code in the module is very simple. Performance is incluenced mosly + by SPI implementations, which should run quite quickly. +

+
+ + + + + +

+ No performance criteria are enforced. The plugged-in code is invoked + by a dedicated executor. +

+
+ + + + + +

+ No. +

+
+ + + + + +

+ No. +

+
+ + + + + +

+ No. +

+
+ + + + + +

+ No. +

+
+ + + + + +

+ No. +

+
+ + + + + +

+ No. +

+
+ + + + + +

+ No. +

+
+ + + + + +

+ No. +

+
+ + + + + +

+ No. +

+
+ +
diff --git a/api.intent/build.xml b/api.intent/build.xml new file mode 100644 --- /dev/null +++ b/api.intent/build.xml @@ -0,0 +1,5 @@ + + + Builds, tests, and runs the project org.netbeans.api.intent + + diff --git a/api.intent/manifest.mf b/api.intent/manifest.mf new file mode 100644 --- /dev/null +++ b/api.intent/manifest.mf @@ -0,0 +1,6 @@ +Manifest-Version: 1.0 +AutoUpdate-Show-In-Client: true +OpenIDE-Module: org.netbeans.api.intent +OpenIDE-Module-Localizing-Bundle: org/netbeans/api/intent/Bundle.properties +OpenIDE-Module-Specification-Version: 1.0 + diff --git a/api.intent/nbproject/project.properties b/api.intent/nbproject/project.properties new file mode 100644 --- /dev/null +++ b/api.intent/nbproject/project.properties @@ -0,0 +1,4 @@ +is.autoload=true +javac.source=1.6 +javac.compilerargs=-Xlint -Xlint:-serial +javadoc.arch=${basedir}/arch.xml diff --git a/api.intent/nbproject/project.xml b/api.intent/nbproject/project.xml new file mode 100644 --- /dev/null +++ b/api.intent/nbproject/project.xml @@ -0,0 +1,61 @@ + + + org.netbeans.modules.apisupport.project + + + org.netbeans.api.intent + + + org.netbeans.api.annotations.common + + + + 1 + 1.25 + + + + org.openide.filesystems + + + + 9.1 + + + + org.openide.util.base + + + + 9.1 + + + + org.openide.util.lookup + + + + 8.26 + + + + + + unit + + org.netbeans.libs.junit4 + + + + org.netbeans.modules.nbjunit + + + + + + org.netbeans.api.intent + org.netbeans.spi.intent.uri + + + + diff --git a/api.intent/src/org/netbeans/api/intent/Bundle.properties b/api.intent/src/org/netbeans/api/intent/Bundle.properties new file mode 100644 --- /dev/null +++ b/api.intent/src/org/netbeans/api/intent/Bundle.properties @@ -0,0 +1,7 @@ +OpenIDE-Module-Display-Category=Infrastructure +OpenIDE-Module-Long-Description=\ + API for invoking intended operations (described by suitable type of object, e.g. \ + URI) by some of registered handlers.\n\ + SPI for handlers of possible intended operations. +OpenIDE-Module-Name=Intent API +OpenIDE-Module-Short-Description=Performing intended operations by suitable handlers diff --git a/api.intent/src/org/netbeans/api/intent/Intent.java b/api.intent/src/org/netbeans/api/intent/Intent.java new file mode 100644 --- /dev/null +++ b/api.intent/src/org/netbeans/api/intent/Intent.java @@ -0,0 +1,118 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2014 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 2014 Sun Microsystems, Inc. + */ +package org.netbeans.api.intent; + +import java.net.URI; +import java.util.concurrent.Callable; +import java.util.concurrent.Future; +import org.netbeans.api.annotations.common.NonNull; +import org.netbeans.spi.intent.uri.OpenUriHandler; +import org.openide.util.Parameters; +import org.openide.util.RequestProcessor; + +/** + * Class that describes an intended operation. + * + * @author jhavlin + * + * @param Result type of the intended operation. + */ +public abstract class Intent { + + abstract R invoke(); + + Intent() { + } + + private static final RequestProcessor RP = new RequestProcessor( + Intent.class); + + /** + * Execute an intent by an internal executor. + * + * @param intent The intent to execute. + */ + public static void execute(final Intent intent) { + RP.execute(new Runnable() { + + @Override + public void run() { + intent.invoke(); + } + }); + } + + /** + * Submit an intent to an internal executor. + * + * @param Result type of the intended operation. + * @param intent The intent to submit. + * + * @return {@link Future} object of the submitted task. + */ + public static Future submit(final Intent intent) { + return RP.submit(new Callable() { + + @Override + public T call() throws Exception { + return intent.invoke(); + } + }); + } + + /** + * Create an intended operation described by a URI. + *

+ * Result type of the operation will be a boolean value: true if the URI was + * handled, false if no provider was able to handle it. + *

+ * + * @param uri URI describing the operation. + * @return The new URI-based intended operation. + * + * @see OpenUriHandler + */ + public static Intent forUri(@NonNull URI uri) { + Parameters.notNull("uri", uri); //NOI18N + return new UriIntent(uri); + } +} diff --git a/api.intent/src/org/netbeans/api/intent/UriIntent.java b/api.intent/src/org/netbeans/api/intent/UriIntent.java new file mode 100644 --- /dev/null +++ b/api.intent/src/org/netbeans/api/intent/UriIntent.java @@ -0,0 +1,148 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2014 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 2014 Sun Microsystems, Inc. + */ +package org.netbeans.api.intent; + +import java.net.URI; +import java.util.Set; +import java.util.TreeSet; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.regex.Pattern; +import org.netbeans.spi.intent.uri.OpenUriHandler; +import org.openide.filesystems.FileObject; +import org.openide.filesystems.FileUtil; + +/** + * Intent described by a URI object. + * + *

+ * This is a package-private implementation returned by + * {@link Intent#forUri(java.net.URI)}. + *

+ * + * @author jhavlin + */ +class UriIntent extends Intent { + + private final URI uri; + private static final Logger LOG + = Logger.getLogger(UriIntent.class.getName()); + + UriIntent(URI uri) { + this.uri = uri; + } + + @Override + Object invoke() { + FileObject f = FileUtil.getConfigFile("Services/Intent/URI"); + if (f == null) { + return null; + } + Set candidates = new TreeSet(); + for (FileObject fo :f.getChildren()) { + if ("instance".equals(fo.getExt())) { + Object pattern = fo.getAttribute("uriPattern"); + Object displayName = fo.getAttribute("displayName"); + Object position = fo.getAttribute("position"); + if (pattern instanceof String && displayName instanceof String + && position instanceof Integer) { + if (Pattern.compile((String) pattern) + .matcher(uri.toString()).matches()) { + OpenUriHandler handler = FileUtil.getConfigObject( + fo.getPath(), + OpenUriHandler.class); + if (handler != null) { + candidates.add( + new IntentInfo( + (String) displayName, + handler, + (Integer) position)); + } + } + } else { + LOG.log(Level.FINE, "Invalid URI handler {0}", fo.getPath()); + } + } + } + for (IntentInfo ii : candidates) { + try { + Object result = ii.getHandler().open(uri); + if (result != null) { + return result; + } + } catch (Exception e) { + LOG.log(Level.INFO, "Exception while trying to open" //NOI18N + + " a URI", e); //NOI18N + } + } + return null; + } + + private class IntentInfo implements Comparable { + final String displayName; + final OpenUriHandler handler; + final int position; + + public IntentInfo(String displayName, OpenUriHandler handler, int position) { + this.displayName = displayName; + this.handler = handler; + this.position = position; + } + + public String getDisplayName() { + return displayName; + } + + public OpenUriHandler getHandler() { + return handler; + } + + public int getPosition() { + return position; + } + + @Override + public int compareTo(IntentInfo o) { + return this.position - o.getPosition(); + } + } +} diff --git a/api.intent/src/org/netbeans/modules/intent/OpenUriHandlerProcessor.java b/api.intent/src/org/netbeans/modules/intent/OpenUriHandlerProcessor.java new file mode 100644 --- /dev/null +++ b/api.intent/src/org/netbeans/modules/intent/OpenUriHandlerProcessor.java @@ -0,0 +1,110 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2014 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 2014 Sun Microsystems, Inc. + */ +package org.netbeans.modules.intent; + +import java.util.Set; +import javax.annotation.processing.Processor; +import javax.annotation.processing.RoundEnvironment; +import javax.annotation.processing.SupportedAnnotationTypes; +import javax.annotation.processing.SupportedSourceVersion; +import javax.lang.model.SourceVersion; +import javax.lang.model.element.Element; +import javax.lang.model.element.ElementKind; +import javax.lang.model.element.TypeElement; +import org.netbeans.spi.intent.uri.OpenUriHandler; +import org.openide.filesystems.annotations.LayerBuilder; +import org.openide.filesystems.annotations.LayerBuilder.File; +import org.openide.filesystems.annotations.LayerGeneratingProcessor; +import org.openide.filesystems.annotations.LayerGenerationException; +import org.openide.util.lookup.ServiceProvider; + +/** + * + * @author jhavlin + */ +@ServiceProvider(service = Processor.class) +@SupportedSourceVersion(SourceVersion.RELEASE_7) +@SupportedAnnotationTypes("org.netbeans.spi.intent.uri.OpenUriHandler.Registration") +public class OpenUriHandlerProcessor extends LayerGeneratingProcessor { + + @Override + protected boolean handleProcess( + Set annotations, + RoundEnvironment roundEnv) throws LayerGenerationException { + + for (Element e : roundEnv.getElementsAnnotatedWith( + OpenUriHandler.Registration.class)) { + + OpenUriHandler.Registration r = e.getAnnotation( + OpenUriHandler.Registration.class); + registerHandler(e, r); + } + return true; + } + + private static final String SUFFIX = ".instance"; + + private void registerHandler(Element e, OpenUriHandler.Registration r) + throws LayerGenerationException { + + final LayerBuilder b = layer(e); + File f = b.file("Services/Intent/URI/" //NOI18N + + getName(e).replace('.', '-') + SUFFIX); + f.position(r.position()); + f.stringvalue("instanceOf", //NOI18N + OpenUriHandler.class.getCanonicalName()); + f.bundlevalue("displayName", r.displayName()); //NOI18N + f.stringvalue("uriPattern", r.uriPattern()); //NOI18N + f.write(); + } + + private String getName(Element e) { + if (e.getKind().isClass() || e.getKind().isInterface()) { + return processingEnv.getElementUtils().getBinaryName( + (TypeElement) e).toString(); + } else if (e.getKind() == ElementKind.PACKAGE) { + return e.getSimpleName().toString(); + } else { + return getName(e.getEnclosingElement()) + '.' + e.getSimpleName(); + } + } +} diff --git a/api.intent/src/org/netbeans/spi/intent/uri/OpenUriHandler.java b/api.intent/src/org/netbeans/spi/intent/uri/OpenUriHandler.java new file mode 100644 --- /dev/null +++ b/api.intent/src/org/netbeans/spi/intent/uri/OpenUriHandler.java @@ -0,0 +1,108 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2014 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 2014 Sun Microsystems, Inc. + */ +package org.netbeans.spi.intent.uri; + +import java.net.URI; +import java.util.regex.Pattern; +import org.netbeans.api.annotations.common.CheckForNull; +import org.netbeans.api.annotations.common.NonNull; +import org.netbeans.api.intent.Intent; + +/** + * SPI for handlers that can process URI hyperlinks that were clicked in the + * application (or somehow invoked). To register your handler, use + * {@link Registration} annotation. + * + *

+ * This is a handler for intents created by + * {@link Intent#forUri(java.net.URI)}. + *

+ * + * @see Intent#forUri(java.net.URI) + * @author jhavlin + */ +public interface OpenUriHandler { + + /** + * Handle the passed URI, if it is supported by this handler. + * + * @param uri The URI to open. + * + * @return Some non-null value if the URI has been handled succesfully, null + * if this handler doesn't support it and thus it should be passed to next + * available handler. + * + * @see Intent#forUri(java.net.URI) + */ + @CheckForNull + Object open(@NonNull URI uri); + + /** + * Annotation for registering your {@link OpenUriHandler} into the + * application. + */ + @SuppressWarnings("PublicInnerClass") + public @interface Registration { + + /** + * Position of the handler. The lesser value, the bigger priority. + * + * @return The position. + */ + int position(); + + /** + * Pattern of supported URIs. See {@link Pattern}. Examples: To handle + * all URIs, use ".*", to handle http adresses, use "http://.*". + * + * @return The URI pattern. + */ + String uriPattern(); + + /** + * Display name of this handler. Bundle keys can be used here. + * + * @return The display name. + */ + String displayName(); + } +} diff --git a/api.intent/test/unit/src/org/netbeans/api/intent/UriIntentTest.java b/api.intent/test/unit/src/org/netbeans/api/intent/UriIntentTest.java new file mode 100644 --- /dev/null +++ b/api.intent/test/unit/src/org/netbeans/api/intent/UriIntentTest.java @@ -0,0 +1,157 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2014 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 2014 Sun Microsystems, Inc. + */ +package org.netbeans.api.intent; + +import java.net.URI; +import java.net.URISyntaxException; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; +import org.junit.Test; +import static org.junit.Assert.*; +import org.netbeans.spi.intent.uri.OpenUriHandler; + +/** + * + * @author jhavlin + */ +public class UriIntentTest { + + @Test + public void testOpenUri() throws URISyntaxException, InterruptedException, + ExecutionException { + + assertFalse(TestOpenUriHandler.HANDLED); + Future res2 = Intent.submit(Intent.forUri( + new URI("test://a/b/c/"))); + assertNotNull(res2.get()); + assertTrue(TestOpenUriHandler.HANDLED); + + Future res3 = Intent.submit(Intent.forUri( + new URI("other://x/y/z/"))); + assertNull(res3.get()); + } + + @Test + public void testSelectAppropriateHandler() + throws URISyntaxException, InterruptedException, + ExecutionException { + + Future f0 = Intent.submit(Intent.forUri( + new URI("unsupported://resource"))); + assertNull(f0.get()); + + Future f1 = Intent.submit(Intent.forUri( + new URI("netbeans://resource"))); + assertEquals(NetBeansOpenURIHandler.NAME, f1.get()); + + Future f2 = Intent.submit(Intent.forUri( + new URI("netbeans://resource?someParam=x"))); + assertEquals(NetBeansOpenURIHandler.NAME, f2.get()); + + Future f3 = Intent.submit(Intent.forUri( + new URI("netbeans://resource?x=y&requiredParam=123"))); + assertEquals(ParametrizedNetBeansOpenURIHandler.NAME, f3.get()); + } + + /** + * Handler that claims to support all URI patterns, but that actually + * accepts only scheme "test". + */ + @SuppressWarnings("PublicInnerClass") + @OpenUriHandler.Registration( + displayName = "Test", + position = 999, + uriPattern = ".*") + public static class TestOpenUriHandler implements OpenUriHandler { + + @SuppressWarnings("PackageVisibleField") + static boolean HANDLED = false; + + @Override + public Object open(URI uri) { + if ("test".equals(uri.getScheme())) { + HANDLED = true; + return new Object(); + } else { + return null; + } + } + } + + /** + * Handler for URIs with scheme "netbeans". + */ + @SuppressWarnings("PublicInnerClass") + @OpenUriHandler.Registration( + displayName = NetBeansOpenURIHandler.NAME, + position = 998, + uriPattern = "netbeans://.*") + public static class NetBeansOpenURIHandler implements OpenUriHandler { + + public static final String NAME = "NetBeans Test"; + + @Override + public Object open(URI uri) { + return NAME; + } + + } + + /** + * Handler for URIs with scheme "netbeans" and parameter "requiredParam". + */ + @SuppressWarnings("PublicInnerClass") + @OpenUriHandler.Registration( + displayName = ParametrizedNetBeansOpenURIHandler.NAME, + position = 997, + uriPattern = "netbeans://.*[?&]requiredParam=.+") + public static class ParametrizedNetBeansOpenURIHandler + implements OpenUriHandler { + + public static final String NAME = "Parametrized NetBeans Test"; + + @Override + public Object open(URI uri) { + return NAME; + } + } +} diff --git a/nbbuild/build.properties b/nbbuild/build.properties --- a/nbbuild/build.properties +++ b/nbbuild/build.properties @@ -100,6 +100,7 @@ config.javadoc.stable=\ api.annotations.common,\ api.html4j,\ + api.intent,\ api.maven,\ autoupdate.services,\ autoupdate.ui,\ diff --git a/nbbuild/cluster.properties b/nbbuild/cluster.properties --- a/nbbuild/cluster.properties +++ b/nbbuild/cluster.properties @@ -195,6 +195,7 @@ nb.cluster.platform=\ api.annotations.common,\ api.html4j,\ + api.intent,\ api.progress,\ api.progress.compat8,\ api.progress.nb,\ diff --git a/nbbuild/javadoctools/links.xml b/nbbuild/javadoctools/links.xml --- a/nbbuild/javadoctools/links.xml +++ b/nbbuild/javadoctools/links.xml @@ -240,3 +240,4 @@ + diff --git a/nbbuild/javadoctools/properties.xml b/nbbuild/javadoctools/properties.xml --- a/nbbuild/javadoctools/properties.xml +++ b/nbbuild/javadoctools/properties.xml @@ -239,3 +239,4 @@ + diff --git a/nbbuild/javadoctools/replaces.xml b/nbbuild/javadoctools/replaces.xml --- a/nbbuild/javadoctools/replaces.xml +++ b/nbbuild/javadoctools/replaces.xml @@ -239,3 +239,4 @@ +