# HG changeset patch # Parent d43dacbdcf031db0cffad672bfe7ea13b0573ab7 # User Jesse Glick #206954: annotation to register navigator panels. diff --git a/apisupport.refactoring/src/org/netbeans/modules/apisupport/hints/NavigatorHinter.java b/apisupport.refactoring/src/org/netbeans/modules/apisupport/hints/NavigatorHinter.java new file mode 100644 --- /dev/null +++ b/apisupport.refactoring/src/org/netbeans/modules/apisupport/hints/NavigatorHinter.java @@ -0,0 +1,96 @@ +/* + * 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.apisupport.hints; + +import com.sun.source.tree.ModifiersTree; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.concurrent.Callable; +import javax.lang.model.element.Element; +import org.netbeans.api.java.source.GeneratorUtilities; +import org.netbeans.api.java.source.WorkingCopy; +import static org.netbeans.modules.apisupport.hints.Bundle.*; +import org.openide.DialogDisplayer; +import org.openide.NotifyDescriptor; +import org.openide.filesystems.FileObject; +import org.openide.util.NbBundle.Messages; +import org.openide.util.lookup.ServiceProvider; + +@ServiceProvider(service=Hinter.class) +public class NavigatorHinter implements Hinter { + + private static final String PANELS_FOLDER = "Navigator/Panels/"; + private static final String REGISTRATION_BINARY = "org.netbeans.spi.navigator.NavigatorPanel$Registration"; + + @Messages("NavigatorHinter.missing_dep=You must be using org.netbeans.spi.navigator 1.22+ before using this fix.") + @Override public void process(final Context ctx) throws Exception { + final FileObject file = ctx.file(); + if (!file.getPath().startsWith(PANELS_FOLDER)) { + return; + } + final Object instanceCreate = ctx.instanceAttribute(file); + if (instanceCreate != null) { + ctx.addStandardAnnotationHint(new Callable() { + public @Override Void call() throws Exception { + if (!ctx.canAccess(REGISTRATION_BINARY)) { + DialogDisplayer.getDefault().notify(new NotifyDescriptor.Message(NavigatorHinter_missing_dep(), NotifyDescriptor.WARNING_MESSAGE)); + return null; + } + ctx.findAndModifyDeclaration(instanceCreate, new Context.ModifyDeclarationTask() { + @Override public void run(WorkingCopy wc, Element declaration, ModifiersTree modifiers) throws Exception { + Map params = new LinkedHashMap(); + params.put("mimeType", file.getParent().getPath().substring(PANELS_FOLDER.length())); + params.put("position", file.getAttribute("position")); + String canon = REGISTRATION_BINARY.replace('$', '.'); + ModifiersTree nue = ctx.addAnnotation(wc, modifiers, canon, canon + "s", params); + ctx.delete(file); + wc.rewrite(modifiers, GeneratorUtilities.get(wc).importFQNs(nue)); + } + }); + return null; + } + }); + } + } + +} diff --git a/image/src/org/netbeans/modules/image/Layer.xml b/image/src/org/netbeans/modules/image/Layer.xml --- a/image/src/org/netbeans/modules/image/Layer.xml +++ b/image/src/org/netbeans/modules/image/Layer.xml @@ -161,30 +161,4 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/image/src/org/netbeans/modules/image/navigation/ImageNavigatorPanel.java b/image/src/org/netbeans/modules/image/navigation/ImageNavigatorPanel.java --- a/image/src/org/netbeans/modules/image/navigation/ImageNavigatorPanel.java +++ b/image/src/org/netbeans/modules/image/navigation/ImageNavigatorPanel.java @@ -48,6 +48,8 @@ import javax.swing.SwingUtilities; import org.netbeans.modules.image.ImageDataObject; import org.netbeans.spi.navigator.NavigatorPanel; +import org.netbeans.spi.navigator.NavigatorPanel.Registration; +import org.netbeans.spi.navigator.NavigatorPanel.Registrations; import org.openide.filesystems.FileChangeAdapter; import org.openide.filesystems.FileChangeListener; import org.openide.filesystems.FileEvent; @@ -60,6 +62,12 @@ * * @author jpeska */ +@Registrations({ + @Registration(mimeType="image/png"), + @Registration(mimeType="image/jpeg"), + @Registration(mimeType="image/bmp"), + @Registration(mimeType="image/gif") +}) public class ImageNavigatorPanel implements NavigatorPanel { /** diff --git a/maven.grammar/src/org/netbeans/modules/maven/grammar/layer.xml b/maven.grammar/src/org/netbeans/modules/maven/grammar/layer.xml --- a/maven.grammar/src/org/netbeans/modules/maven/grammar/layer.xml +++ b/maven.grammar/src/org/netbeans/modules/maven/grammar/layer.xml @@ -131,12 +131,6 @@ - - - - - - diff --git a/maven.grammar/src/org/netbeans/modules/maven/navigator/POMInheritanceNavigator.java b/maven.grammar/src/org/netbeans/modules/maven/navigator/POMInheritanceNavigator.java --- a/maven.grammar/src/org/netbeans/modules/maven/navigator/POMInheritanceNavigator.java +++ b/maven.grammar/src/org/netbeans/modules/maven/navigator/POMInheritanceNavigator.java @@ -44,6 +44,7 @@ import java.util.Collection; import javax.swing.JComponent; +import org.netbeans.modules.maven.api.Constants; import org.netbeans.spi.navigator.NavigatorPanel; import org.openide.loaders.DataObject; import org.openide.util.Lookup; @@ -54,6 +55,7 @@ * * @author mkleint */ +@NavigatorPanel.Registration(mimeType=Constants.POM_MIME_TYPE, position=200) public class POMInheritanceNavigator implements NavigatorPanel { private POMInheritancePanel component; diff --git a/maven.grammar/src/org/netbeans/modules/maven/navigator/POMModelNavigator.java b/maven.grammar/src/org/netbeans/modules/maven/navigator/POMModelNavigator.java --- a/maven.grammar/src/org/netbeans/modules/maven/navigator/POMModelNavigator.java +++ b/maven.grammar/src/org/netbeans/modules/maven/navigator/POMModelNavigator.java @@ -44,6 +44,7 @@ import java.util.Collection; import javax.swing.JComponent; +import org.netbeans.modules.maven.api.Constants; import org.netbeans.spi.navigator.NavigatorPanel; import org.openide.loaders.DataObject; import org.openide.util.Lookup; @@ -55,6 +56,7 @@ * * @author mkleint */ +@NavigatorPanel.Registration(mimeType=Constants.POM_MIME_TYPE, position=100) public class POMModelNavigator implements NavigatorPanel { private POMModelPanel component; diff --git a/spi.navigator/apichanges.xml b/spi.navigator/apichanges.xml --- a/spi.navigator/apichanges.xml +++ b/spi.navigator/apichanges.xml @@ -108,7 +108,25 @@ - + + + Added @NavigatorPanel.Registration + + + + +

+ Upgrade manual layer registrations. +

+
+ +

+ Added @NavigatorPanel.Registration for ease of use. +

+
+ + +
Added SPI interface NavigatorDisplayer diff --git a/spi.navigator/arch.xml b/spi.navigator/arch.xml --- a/spi.navigator/arch.xml +++ b/spi.navigator/arch.xml @@ -78,8 +78,6 @@

API allows its clients to plug in their Swing based views easily, which then will be automatically shown in specialized Navigator UI.

-

- Client's views are registered through declarative xml layers approach.

@@ -146,13 +144,8 @@ In order to plug in a view into Navigator UI for certain document (data) type, - module writers need to complete following steps: - -
    -
  • Write NavigatorPanel - implementation
  • -
  • Register implementation class in xml layer
  • -
+ module writers need to write a NavigatorPanel + implementation marked with @Registration.

Writing NavigatorPanel implementation

Implementing NavigatorPanel @@ -163,10 +156,7 @@

  • Instantiation: Your implementation of NavigatorPanel - is instantied automatically by the system if you register it in a layer - (described in next step). See detailed - Instantiation rules - to understand which kind of instantiation possibilities are on the plate.

  • + is instantied automatically by the system if you register it using @Registration.
  • getComponent method: Simply create and return your UI representation of your data in Swing's JComponent envelope. Just be sure @@ -209,7 +199,7 @@ should show some please wait message.

-

Registering NavigatorPanel impl in a layer

+

Registering NavigatorPanel impl

Declarative registration of your NavigatorPanel impl connects this implementation with specific content type, which is type of the document, expressed in mime-type syntax, for example 'text/x-java' @@ -217,26 +207,7 @@ your NavigatorPanel impl in UI, when currently activated Node is backed by primary FileObject whose FileObject.getMimeType() - equals to content type specified in your layer.

-

- Writing layer registration itself is easy, you can again copy from template layer - - Basic Navigator Registration Layer.

- - Additional important info: - -
    -
  • System looks up for navigator providers only in - Navigator/Panels folder, nowhere else.

  • - -
  • Content type is specified as cascade of subdirectories under - Navigator/Panels directory. Mime-type syntax is recommended and - handy for specifying content type.

    - It is not compulsory though, so if you need to make up a name - for your content type, just go for it. (more below)

  • - -
- + equals to content type specified in your registering annotation (see more options below).

@@ -1372,8 +1343,7 @@

Yes Navigator module reads registered view providers from specific folder - /navigator/panels. - + Navigator/Panels.

diff --git a/spi.navigator/manifest.mf b/spi.navigator/manifest.mf --- a/spi.navigator/manifest.mf +++ b/spi.navigator/manifest.mf @@ -2,4 +2,4 @@ OpenIDE-Module: org.netbeans.spi.navigator/1 OpenIDE-Module-Layer: org/netbeans/modules/navigator/resources/layer.xml OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/navigator/resources/Bundle.properties -OpenIDE-Module-Specification-Version: 1.21 +OpenIDE-Module-Specification-Version: 1.22 diff --git a/spi.navigator/src/org/netbeans/modules/navigator/NavigatorPanelRegistrationProcessor.java b/spi.navigator/src/org/netbeans/modules/navigator/NavigatorPanelRegistrationProcessor.java new file mode 100644 --- /dev/null +++ b/spi.navigator/src/org/netbeans/modules/navigator/NavigatorPanelRegistrationProcessor.java @@ -0,0 +1,94 @@ +/* + * 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.navigator; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; +import javax.annotation.processing.Processor; +import javax.annotation.processing.RoundEnvironment; +import javax.annotation.processing.SupportedSourceVersion; +import javax.lang.model.SourceVersion; +import javax.lang.model.element.Element; +import javax.lang.model.element.TypeElement; +import org.netbeans.spi.navigator.NavigatorPanel; +import org.openide.filesystems.annotations.LayerGeneratingProcessor; +import org.openide.filesystems.annotations.LayerGenerationException; +import org.openide.util.lookup.ServiceProvider; + +@ServiceProvider(service=Processor.class) +@SupportedSourceVersion(SourceVersion.RELEASE_6) +public class NavigatorPanelRegistrationProcessor extends LayerGeneratingProcessor { + + @Override public Set getSupportedAnnotationTypes() { + return new HashSet(Arrays.asList(NavigatorPanel.Registration.class.getCanonicalName(), NavigatorPanel.Registrations.class.getCanonicalName())); + } + + @Override protected boolean handleProcess(Set annotations, RoundEnvironment roundEnv) throws LayerGenerationException { + if (roundEnv.processingOver()) { + return false; + } + for (Element e : roundEnv.getElementsAnnotatedWith(NavigatorPanel.Registration.class)) { + NavigatorPanel.Registration r = e.getAnnotation(NavigatorPanel.Registration.class); + if (r == null) { + continue; + } + register(e, r); + } + for (Element e : roundEnv.getElementsAnnotatedWith(NavigatorPanel.Registrations.class)) { + NavigatorPanel.Registrations rr = e.getAnnotation(NavigatorPanel.Registrations.class); + if (rr == null) { + continue; + } + for (NavigatorPanel.Registration r : rr.value()) { + register(e, r); + } + } + return true; + } + + private void register(Element e, NavigatorPanel.Registration r) throws LayerGenerationException { + layer(e).instanceFile(ProviderRegistry.PANELS_FOLDER + r.mimeType(), null, NavigatorPanel.class, r, null).position(r.position()).write(); + } + +} diff --git a/spi.navigator/src/org/netbeans/modules/navigator/ProviderRegistry.java b/spi.navigator/src/org/netbeans/modules/navigator/ProviderRegistry.java --- a/spi.navigator/src/org/netbeans/modules/navigator/ProviderRegistry.java +++ b/spi.navigator/src/org/netbeans/modules/navigator/ProviderRegistry.java @@ -60,7 +60,7 @@ class ProviderRegistry { /** folder in layer file system where navigator panels are searched for */ - private static final String PANELS_FOLDER = "/Navigator/Panels/"; //NOI18N + static final String PANELS_FOLDER = "Navigator/Panels/"; //NOI18N /** template for finding all NavigatorPanel instances in lookup */ private static final Lookup.Template NAV_PANEL_TEMPLATE = new Lookup.Template(NavigatorPanel.class); diff --git a/spi.navigator/src/org/netbeans/spi/navigator/NavigatorPanel.java b/spi.navigator/src/org/netbeans/spi/navigator/NavigatorPanel.java --- a/spi.navigator/src/org/netbeans/spi/navigator/NavigatorPanel.java +++ b/spi.navigator/src/org/netbeans/spi/navigator/NavigatorPanel.java @@ -44,14 +44,17 @@ package org.netbeans.spi.navigator; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; import javax.swing.JComponent; import org.openide.util.Lookup; /** Navigation related view description. * - * Implementors of this interface, also registered in layer, - * will be plugged into Navigator UI. - * + * Implementors of this interface will be plugged into Navigator UI. + * @see Registration * @author Dafe Simonek */ public interface NavigatorPanel { @@ -120,6 +123,36 @@ * @return Lookup instance or null */ public Lookup getLookup (); + + /** + * Registers a navigator panel. + * @since 1.22 + */ + @Target({ElementType.TYPE, ElementType.METHOD}) + @Retention(RetentionPolicy.SOURCE) + @interface Registration { + + /** + * MIME type to register under. + * For example: {@code text/javascript} + */ + String mimeType(); + + /** + * Optional position for this panel among others of the same type. + */ + int position() default Integer.MAX_VALUE; + + } - + /** + * Used in case multiple registrations are needed in one place. + * @since 1.22 + */ + @Target({ElementType.TYPE, ElementType.METHOD}) + @Retention(RetentionPolicy.SOURCE) + @interface Registrations { + Registration[] value(); + } + } diff --git a/spi.navigator/src/org/netbeans/spi/navigator/NavigatorPanelWithUndo.java b/spi.navigator/src/org/netbeans/spi/navigator/NavigatorPanelWithUndo.java --- a/spi.navigator/src/org/netbeans/spi/navigator/NavigatorPanelWithUndo.java +++ b/spi.navigator/src/org/netbeans/spi/navigator/NavigatorPanelWithUndo.java @@ -52,8 +52,8 @@ * Clients will implement this interface when they need undo and redo support * enabled for their Navigator view/panel. * - * Implementors of this interface, also registered in layer, - * will be plugged into Navigator UI. + * Implementors of this interface will be plugged into Navigator UI. + * @see NavigatorPanel.Registration * * @since 1.5 * diff --git a/spi.navigator/src/org/netbeans/spi/navigator/doc-files/BasicNavPanelImpl_java b/spi.navigator/src/org/netbeans/spi/navigator/doc-files/BasicNavPanelImpl_java --- a/spi.navigator/src/org/netbeans/spi/navigator/doc-files/BasicNavPanelImpl_java +++ b/spi.navigator/src/org/netbeans/spi/navigator/doc-files/BasicNavPanelImpl_java @@ -53,6 +53,7 @@ /** * Basic dummy implementation of NavigatorPanel interface. */ +@NavigatorPanel.Registration(mimeType="text/plain") public class BasicNavPanelImpl implements NavigatorPanel { /** holds UI of this panel */ diff --git a/spi.navigator/src/org/netbeans/spi/navigator/doc-files/basicNavLayer.xml b/spi.navigator/src/org/netbeans/spi/navigator/doc-files/basicNavLayer.xml deleted file mode 100644 --- a/spi.navigator/src/org/netbeans/spi/navigator/doc-files/basicNavLayer.xml +++ /dev/null @@ -1,62 +0,0 @@ - - - - - - - - - - - - - - - - - -