diff -r 3fe06f4d27a4 api.debugger/apichanges.xml --- a/api.debugger/apichanges.xml Fri Feb 05 15:54:05 2010 +0100 +++ b/api.debugger/apichanges.xml Sat Feb 06 16:17:47 2010 +0100 @@ -364,6 +364,26 @@ + + + A declarative mechanism that creates action provider instance after a file with specific MIME type becomes active. + + + + + +

+ ActionsProvider.Registration annotation is enhanced with two additional + methods getActions() and enabledOnMIMETypes(). Until a file with the + listed MIME type is selected in the IDE, the appropriate actions provider + is left disabled for the given list of actions, without instantiating the + implementation class. +

+
+ + +
+ diff -r 3fe06f4d27a4 api.debugger/manifest.mf --- a/api.debugger/manifest.mf Fri Feb 05 15:54:05 2010 +0100 +++ b/api.debugger/manifest.mf Sat Feb 06 16:17:47 2010 +0100 @@ -1,5 +1,5 @@ Manifest-Version: 1.0 OpenIDE-Module: org.netbeans.api.debugger/1 OpenIDE-Module-Localizing-Bundle: org/netbeans/api/debugger/Bundle.properties -OpenIDE-Module-Specification-Version: 1.22 +OpenIDE-Module-Specification-Version: 1.23 OpenIDE-Module-Layer: org/netbeans/api/debugger/layer.xml diff -r 3fe06f4d27a4 api.debugger/src/org/netbeans/debugger/registry/ContextAwareServiceHandler.java --- a/api.debugger/src/org/netbeans/debugger/registry/ContextAwareServiceHandler.java Fri Feb 05 15:54:05 2010 +0100 +++ b/api.debugger/src/org/netbeans/debugger/registry/ContextAwareServiceHandler.java Sat Feb 06 16:17:47 2010 +0100 @@ -70,6 +70,8 @@ public static final String SERVICE_NAME = "serviceName"; // NOI18N public static final String SERVICE_CLASSES = "serviceClasses"; // NOI18N + public static final String SERVICE_ACTIONS = "debugger_actions"; // NOI18N + public static final String SERVICE_ENABLED_MIMETYPES = "debugger_enabledOnMIMETypes"; // NOI18N private String serviceName; private Class[] serviceClasses; diff -r 3fe06f4d27a4 api.debugger/src/org/netbeans/debugger/registry/DebuggerProcessor.java --- a/api.debugger/src/org/netbeans/debugger/registry/DebuggerProcessor.java Fri Feb 05 15:54:05 2010 +0100 +++ b/api.debugger/src/org/netbeans/debugger/registry/DebuggerProcessor.java Sat Feb 06 16:17:47 2010 +0100 @@ -66,6 +66,7 @@ import org.netbeans.spi.debugger.DebuggerEngineProvider; import org.netbeans.spi.debugger.DebuggerServiceRegistration; import org.netbeans.spi.debugger.SessionProvider; +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; @@ -102,7 +103,9 @@ ActionsProvider.Registration reg = e.getAnnotation(ActionsProvider.Registration.class); final String path = reg.path(); - handleProviderRegistrationInner(e, ActionsProvider.class, path); + final String[] actions = reg.getActions(); + final String[] mimeTypes = reg.enabledOnMIMETypes(); + handleProviderRegistrationInner(e, ActionsProvider.class, path, actions, mimeTypes); //layer(e).instanceFile("Debugger/"+path, null, ActionsProvider.class). // stringvalue("serviceName", instantiableClassOrMethod(e)). // stringvalue("serviceClass", ActionsProvider.class.getName()). @@ -186,6 +189,12 @@ } private void handleProviderRegistrationInner(Element e, Class providerClass, String path) throws IllegalArgumentException, LayerGenerationException { + handleProviderRegistrationInner(e, providerClass, path, null, null); + } + + private void handleProviderRegistrationInner(Element e, Class providerClass, String path, + String[] actions, String[] enabledOnMIMETypes + ) throws IllegalArgumentException, LayerGenerationException { String className = instantiableClassOrMethod(e); if (!isClassOf(e, providerClass)) { throw new IllegalArgumentException("Annotated element "+e+" is not an instance of " + providerClass); @@ -195,12 +204,18 @@ } else { path = "Debugger"; } - layer(e).instanceFile(path, null, providerClass). - stringvalue("serviceName", className). - stringvalue("serviceClass", providerClass.getName()). - stringvalue("instanceOf", providerClass.getName()). - methodvalue("instanceCreate", providerClass.getName()+"$ContextAware", "createService"). - write(); + File f = layer(e).instanceFile(path, null, providerClass). + stringvalue(ContextAwareServiceHandler.SERVICE_NAME, className). + stringvalue("serviceClass", providerClass.getName()); + if (actions != null && actions.length > 0) { + f.stringvalue(ContextAwareServiceHandler.SERVICE_ACTIONS, Arrays.toString(actions)); + } + if (enabledOnMIMETypes != null && enabledOnMIMETypes.length > 0) { + f.stringvalue(ContextAwareServiceHandler.SERVICE_ENABLED_MIMETYPES, Arrays.toString(enabledOnMIMETypes)); + } + f.stringvalue("instanceOf", providerClass.getName()); + f.methodvalue("instanceCreate", providerClass.getName()+"$ContextAware", "createService"); + f.write(); } private boolean isClassOf(Element e, Class providerClass) { diff -r 3fe06f4d27a4 api.debugger/src/org/netbeans/spi/debugger/ActionsProvider.java --- a/api.debugger/src/org/netbeans/spi/debugger/ActionsProvider.java Fri Feb 05 15:54:05 2010 +0100 +++ b/api.debugger/src/org/netbeans/spi/debugger/ActionsProvider.java Sat Feb 06 16:17:47 2010 +0100 @@ -41,14 +41,25 @@ package org.netbeans.spi.debugger; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; import java.util.Map; import java.util.Set; + import org.netbeans.debugger.registry.ContextAwareServiceHandler; -import org.netbeans.spi.debugger.ContextAwareSupport; +import org.openide.filesystems.FileObject; +import org.openide.util.Exceptions; +import org.openide.util.Lookup; import org.openide.util.RequestProcessor; /** @@ -134,33 +145,84 @@ */ String path() default ""; + /** + * Provide the list of actions that this provider supports. + * This list is used before an instance of the registered class is created, + * it's necessary when {@link #enabledOnMIMETypes()} is overriden + * to prevent from the class instantiation. + * @return The list of actions. + * @since 1.23 + */ + String[] getActions() default {}; + + /** + * Provide the list of MIME types that are compared to the MIME type of + * a file currently active in the IDE and when matched, this provider + * is activated (an instance of the registered class is created). + * This method is used to delay the instatiation of the implementation + * class for performance reasons. + * @return The list of MIME types + * @since 1.23 + */ + String[] enabledOnMIMETypes() default {}; + } static class ContextAware extends ActionsProvider implements ContextAwareService { + + private static final String ERROR = "error in getting MIMEType"; // NOI18N private String serviceName; private ContextProvider context; private ActionsProvider delegate; - private ContextAware(String serviceName) { + private Set actions; + private Set enabledOnMIMETypes; + private List listeners = new ArrayList(); + private PropertyChangeListener contextDispatcherListener; + + private ContextAware(String serviceName, Set actions, Set enabledOnMIMETypes) { this.serviceName = serviceName; + this.actions = actions; + this.enabledOnMIMETypes = enabledOnMIMETypes; } - private ContextAware(String serviceName, ContextProvider context) { + private ContextAware(String serviceName, Set actions, Set enabledOnMIMETypes, + ContextProvider context) { this.serviceName = serviceName; + this.actions = actions; + this.enabledOnMIMETypes = enabledOnMIMETypes; this.context = context; } private synchronized ActionsProvider getDelegate() { if (delegate == null) { delegate = (ActionsProvider) ContextAwareSupport.createInstance(serviceName, context); + for (ActionsProviderListener l : listeners) { + delegate.addActionsProviderListener(l); + } + listeners.clear(); + if (contextDispatcherListener != null) { + detachContextDispatcherListener(); + } } return delegate; } @Override public Set getActions() { - return getDelegate().getActions(); + ActionsProvider actionsDelegate; + if (actions != null) { + synchronized (this) { + actionsDelegate = this.delegate; + } + } else { + actionsDelegate = getDelegate(); + } + if (actionsDelegate == null) { + return actions; + } + return actionsDelegate.getActions(); } @Override @@ -175,24 +237,62 @@ @Override public boolean isEnabled(Object action) { + ActionsProvider actionsDelegate; + if (enabledOnMIMETypes != null) { + synchronized (this) { + actionsDelegate = this.delegate; + } + } else { + actionsDelegate = getDelegate(); + } + if (actionsDelegate == null) { + String currentMIMEType = getCurrentMIMEType(); + if (currentMIMEType != ERROR) { + if (!enabledOnMIMETypes.contains(currentMIMEType)) { + return false; + } + } + } return getDelegate().isEnabled(action); } @Override public void addActionsProviderListener(ActionsProviderListener l) { - getDelegate().addActionsProviderListener(l); + ActionsProvider actionsDelegate; + synchronized (this) { + actionsDelegate = delegate; + if (actionsDelegate == null) { + listeners.add(l); + if (contextDispatcherListener == null && enabledOnMIMETypes != null) { + contextDispatcherListener = attachContextDispatcherListener(); + } + return ; + } + } + actionsDelegate.addActionsProviderListener(l); } @Override public void removeActionsProviderListener(ActionsProviderListener l) { - getDelegate().removeActionsProviderListener(l); + ActionsProvider actionsDelegate; + synchronized (this) { + actionsDelegate = delegate; + if (actionsDelegate == null) { + listeners.remove(l); + if (listeners.size() == 0 && contextDispatcherListener != null) { + detachContextDispatcherListener(); + } + return ; + } + } + actionsDelegate.removeActionsProviderListener(l); } public ActionsProvider forContext(ContextProvider context) { if (context == this.context) { return this; } else { - return new ActionsProvider.ContextAware(serviceName, context); + return new ActionsProvider.ContextAware(serviceName, actions, enabledOnMIMETypes, context); } } @@ -205,7 +305,159 @@ */ static ContextAwareService createService(Map attrs) throws ClassNotFoundException { String serviceName = (String) attrs.get(ContextAwareServiceHandler.SERVICE_NAME); - return new ActionsProvider.ContextAware(serviceName); + String actionsStr = (String) attrs.get(ContextAwareServiceHandler.SERVICE_ACTIONS); + String enabledOnMIMETypesStr = (String) attrs.get(ContextAwareServiceHandler.SERVICE_ENABLED_MIMETYPES); + String[] actions = parseArray(actionsStr); + String[] enabledOnMIMETypes = parseArray(enabledOnMIMETypesStr); + return new ActionsProvider.ContextAware(serviceName, + createSet(actions), + createSet(enabledOnMIMETypes)); + } + + private static String[] parseArray(String strArray) { + if (strArray == null) { + return null; + } + if (strArray.startsWith("[")) strArray = strArray.substring(1); + if (strArray.endsWith("]")) strArray = strArray.substring(0, strArray.length() - 1); + strArray = strArray.trim(); + int index = 0; + List strings = new ArrayList(); + while (index < strArray.length()) { + int index2 = strArray.indexOf(',', index); + if (index2 < 0) index2 = strArray.length(); + if (index2 > index) { + String s = strArray.substring(index, index2).trim(); + if (s.length() > 0) { // Can be trimmed to 0 length + strings.add(s); + } + index = index2 + 1; + } else { + index++; + continue; + } + } + return strings.toArray(new String[0]); + } + + private static Set createSet(T[] array) { + if (array != null) { + return Collections.unmodifiableSet(new HashSet(Arrays.asList(array))); + } else { + return null; + } + } + + private static String getCurrentMIMEType() { + // Ask EditorContextDispatcher.getDefault().getMostRecentFile() + // It's not in a dependent module, therefore we have to find it dynamically: + try { + Class editorContextDispatcherClass = Lookup.getDefault().lookup(ClassLoader.class).loadClass("org.netbeans.spi.debugger.ui.EditorContextDispatcher"); + try { + try { + Object editorContextDispatcher = editorContextDispatcherClass.getMethod("getDefault").invoke(null); + FileObject file = (FileObject) editorContextDispatcherClass.getMethod("getMostRecentFile").invoke(editorContextDispatcher); + if (file != null) { + return file.getMIMEType(); + } else { + return null; + } + } catch (IllegalAccessException ex) { + Exceptions.printStackTrace(ex); + } catch (IllegalArgumentException ex) { + Exceptions.printStackTrace(ex); + } catch (InvocationTargetException ex) { + Exceptions.printStackTrace(ex); + } + } catch (NoSuchMethodException ex) { + Exceptions.printStackTrace(ex); + } catch (SecurityException ex) { + Exceptions.printStackTrace(ex); + } + } catch (ClassNotFoundException ex) { + } + return ERROR; + } + + private PropertyChangeListener attachContextDispatcherListener() { + // Call EditorContextDispatcher.getDefault().addPropertyChangeListener(String MIMEType, PropertyChangeListener l) + // It's not in a dependent module, therefore we have to find it dynamically: + PropertyChangeListener l = null; + try { + Class editorContextDispatcherClass = Lookup.getDefault().lookup(ClassLoader.class).loadClass("org.netbeans.spi.debugger.ui.EditorContextDispatcher"); + try { + try { + Object editorContextDispatcher = editorContextDispatcherClass.getMethod("getDefault").invoke(null); + java.lang.reflect.Method m = editorContextDispatcherClass.getMethod( + "addPropertyChangeListener", + String.class, + PropertyChangeListener.class); + l = new ContextDispatcherListener(); + for (String mimeType : enabledOnMIMETypes) { + m.invoke(editorContextDispatcher, mimeType, l); + } + } catch (IllegalAccessException ex) { + Exceptions.printStackTrace(ex); + } catch (IllegalArgumentException ex) { + Exceptions.printStackTrace(ex); + } catch (InvocationTargetException ex) { + Exceptions.printStackTrace(ex); + } + } catch (NoSuchMethodException ex) { + Exceptions.printStackTrace(ex); + } catch (SecurityException ex) { + Exceptions.printStackTrace(ex); + } + } catch (ClassNotFoundException ex) { + } + return l; + } + + private void detachContextDispatcherListener() { + // Call EditorContextDispatcher.getDefault().removePropertyChangeListener(PropertyChangeListener l) + // It's not in a dependent module, therefore we have to find it dynamically: + PropertyChangeListener l = null; + try { + Class editorContextDispatcherClass = Lookup.getDefault().lookup(ClassLoader.class).loadClass("org.netbeans.spi.debugger.ui.EditorContextDispatcher"); + try { + try { + Object editorContextDispatcher = editorContextDispatcherClass.getMethod("getDefault").invoke(null); + java.lang.reflect.Method m = editorContextDispatcherClass.getMethod( + "removePropertyChangeListener", + PropertyChangeListener.class); + m.invoke(editorContextDispatcher, contextDispatcherListener); + contextDispatcherListener = null; + } catch (IllegalAccessException ex) { + Exceptions.printStackTrace(ex); + } catch (IllegalArgumentException ex) { + Exceptions.printStackTrace(ex); + } catch (InvocationTargetException ex) { + Exceptions.printStackTrace(ex); + } + } catch (NoSuchMethodException ex) { + Exceptions.printStackTrace(ex); + } catch (SecurityException ex) { + Exceptions.printStackTrace(ex); + } + } catch (ClassNotFoundException ex) { + } + } + + private class ContextDispatcherListener implements PropertyChangeListener { + + @Override + public void propertyChange(PropertyChangeEvent evt) { + List ls; + synchronized (ContextAware.this) { + ls = new ArrayList(listeners); + } + for (ActionsProviderListener l : ls) { + for (Object action : actions) { + l.actionStateChange(action, isEnabled(action)); + } + } + } + } } diff -r 3fe06f4d27a4 spi.debugger.ui/src/org/netbeans/spi/debugger/ui/EditorContextDispatcher.java --- a/spi.debugger.ui/src/org/netbeans/spi/debugger/ui/EditorContextDispatcher.java Fri Feb 05 15:54:05 2010 +0100 +++ b/spi.debugger.ui/src/org/netbeans/spi/debugger/ui/EditorContextDispatcher.java Sat Feb 06 16:17:47 2010 +0100 @@ -277,6 +277,20 @@ */ public synchronized FileObject getMostRecentFile() { return mostRecentFileRef.get(); + } + + /** Used by unit test only */ + void setMostRecentFile(FileObject file) { + Object oldFile; + String MIMEType = null; + synchronized (this) { + oldFile = mostRecentFileRef.get(); + mostRecentFileRef = new WeakReference(file); + if (file != null) { + MIMEType = file.getMIMEType(); + } + } + refreshProcessor.post(new EventFirer(PROP_EDITOR, oldFile, file, MIMEType)); } /** diff -r 3fe06f4d27a4 spi.debugger.ui/test/unit/src/org/netbeans/api/debugger/ProvidersAnnotationTest.java --- a/spi.debugger.ui/test/unit/src/org/netbeans/api/debugger/ProvidersAnnotationTest.java Fri Feb 05 15:54:05 2010 +0100 +++ b/spi.debugger.ui/test/unit/src/org/netbeans/api/debugger/ProvidersAnnotationTest.java Sat Feb 06 16:17:47 2010 +0100 @@ -39,9 +39,14 @@ package org.netbeans.api.debugger; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.Date; +import java.util.Enumeration; import java.util.List; -import junit.framework.Test; import org.netbeans.api.debugger.providers.TestActionProvider; import org.netbeans.api.debugger.providers.TestAttachType; import org.netbeans.api.debugger.providers.TestBreakpointType; @@ -49,20 +54,28 @@ import org.netbeans.api.debugger.providers.TestExtendedNodeModelFilter; import org.netbeans.api.debugger.providers.TestLazyActionsManagerListenerAnnotated; import org.netbeans.api.debugger.providers.TestLazyDebuggerManagerListenerAnnotated; +import org.netbeans.api.debugger.providers.TestMIMETypeSensitiveActionProvider; import org.netbeans.api.debugger.providers.TestThreeModels; -import org.netbeans.junit.NbModuleSuite; import org.netbeans.modules.debugger.ui.models.ColumnModels; import org.netbeans.spi.debugger.ActionsProvider; +import org.netbeans.spi.debugger.ActionsProviderListener; import org.netbeans.spi.debugger.DebuggerEngineProvider; import org.netbeans.spi.debugger.SessionProvider; import org.netbeans.spi.debugger.ui.AttachType; import org.netbeans.spi.debugger.ui.BreakpointType; +import org.netbeans.spi.debugger.ui.EditorContextDispatcherManager; import org.netbeans.spi.viewmodel.ColumnModel; import org.netbeans.spi.viewmodel.ExtendedNodeModelFilter; import org.netbeans.spi.viewmodel.NodeModel; import org.netbeans.spi.viewmodel.NodeModelFilter; import org.netbeans.spi.viewmodel.TableModel; import org.netbeans.spi.viewmodel.TreeModel; +import org.openide.filesystems.FileChangeListener; +import org.openide.filesystems.FileLock; +import org.openide.filesystems.FileObject; +import org.openide.filesystems.FileStateInvalidException; +import org.openide.filesystems.FileSystem; +import org.openide.filesystems.LocalFileSystem; /** * @@ -200,4 +213,210 @@ //assertEquals(ColumnModels.createLocalsToStringColumn().getDisplayName(), list.get(3).getDisplayName()); - was made hidden! } } + + public void testMIMETypeSensitiveActionProviders() throws Exception { + Lookup.MetaInf l = new Lookup.MetaInf("unittest_MIME"); + + List list = l.lookup(null, ActionsProvider.class); + assertEquals("No test action provider instance should be created yet!", 0, TestMIMETypeSensitiveActionProvider.INSTANCES.size()); + assertInstanceOf("Wrong looked up object", list.get(0), ActionsProvider.class); + ActionsProvider ap = list.get(0); + Object action = ap.getActions().iterator().next(); + assertEquals(TestMIMETypeSensitiveActionProvider.ACTION_OBJECT, action); + assertEquals("No test action provider instance should be created yet!", 0, TestMIMETypeSensitiveActionProvider.INSTANCES.size()); + ap.isEnabled(action); + assertEquals("No test action provider instance should be created yet!", 0, TestMIMETypeSensitiveActionProvider.INSTANCES.size()); + final Boolean[] actionStateChanged = new Boolean[] { null }; + ap.addActionsProviderListener(new ActionsProviderListener() { + @Override + public void actionStateChange(Object action, boolean enabled) { + actionStateChanged[0] = enabled; + } + }); + assertEquals("No test action provider instance should be created yet!", 0, TestMIMETypeSensitiveActionProvider.INSTANCES.size()); + + /* + LocalFileSystem fs = new LocalFileSystem(); + fs.setRootDirectory(new File("/tmp")); + Repository.getDefault().addFileSystem(fs); + */ + FileObject f = createCFile(); + EditorContextDispatcherManager.setMostRecentFile(f); + Thread.sleep(500); + assertEquals("No test action provider instance should be created yet!", 0, TestMIMETypeSensitiveActionProvider.INSTANCES.size()); + + f = createJavaFile(); + EditorContextDispatcherManager.setMostRecentFile(f); + Thread.sleep(500); + assertEquals("One test action provider instance should be created!", 1, TestMIMETypeSensitiveActionProvider.INSTANCES.size()); + + } + + private static FileObject createCFile() throws IOException { + /* Creates FileObject with unknown content type without full IDE + File file = File.createTempFile("Foo", ".c"); + FileWriter fw = new FileWriter(file); + fw.append("#include \n\nmain() {\n printf(\"Hi there!\");\n}\n"); + fw.flush(); + fw.close(); + fs.refresh(true); + return FileUtil.toFileObject(file); + */ + return new FileObjectWithMIMEType("text/x-c"); + } + + private static FileObject createJavaFile() throws IOException { + /* Creates FileObject with unknown content type without full IDE + File file = File.createTempFile("Foo", ".java"); + FileWriter fw = new FileWriter(file); + fw.append("\nmain(String[] args) {\n System.out.println(\"Hi there!\");\n}\n"); + fw.flush(); + fw.close(); + fs.refresh(true); + return FileUtil.toFileObject(file); + */ + return new FileObjectWithMIMEType("text/x-java"); + } + + /** Test FileObject implementation that provides a given MIME type */ + private static class FileObjectWithMIMEType extends FileObject { + + private String MIMEType; + + public FileObjectWithMIMEType(String MIMEType) { + this.MIMEType = MIMEType; + } + + @Override + public String getMIMEType() { + return MIMEType; + } + + @Override + public String getName() { + return "Test Name"; + } + + @Override + public String getExt() { + return "Test ext."; + } + + @Override + public void rename(FileLock lock, String name, String ext) throws IOException { + throw new UnsupportedOperationException("Not supported."); + } + + @Override + public FileSystem getFileSystem() throws FileStateInvalidException { + return new LocalFileSystem(); + } + + @Override + public FileObject getParent() { + return null; + } + + @Override + public boolean isFolder() { + return false; + } + + @Override + public Date lastModified() { + return new Date(); + } + + @Override + public boolean isRoot() { + return false; + } + + @Override + public boolean isData() { + return true; + } + + @Override + public boolean isValid() { + return true; + } + + @Override + public void delete(FileLock lock) throws IOException { + throw new UnsupportedOperationException("Not supported."); + } + + @Override + public Object getAttribute(String attrName) { + return null; + } + + @Override + public void setAttribute(String attrName, Object value) throws IOException { + } + + @Override + public Enumeration getAttributes() { + return null; + } + + @Override + public void addFileChangeListener(FileChangeListener fcl) { + } + + @Override + public void removeFileChangeListener(FileChangeListener fcl) { + } + + @Override + public long getSize() { + return 1000; + } + + @Override + public InputStream getInputStream() throws FileNotFoundException { + throw new UnsupportedOperationException("Not supported."); + } + + @Override + public OutputStream getOutputStream(FileLock lock) throws IOException { + throw new UnsupportedOperationException("Not supported."); + } + + @Override + public FileLock lock() throws IOException { + throw new UnsupportedOperationException("Not supported."); + } + + @Override + public void setImportant(boolean b) { + } + + @Override + public FileObject[] getChildren() { + return new FileObject[] {}; + } + + @Override + public FileObject getFileObject(String name, String ext) { + return null; + } + + @Override + public FileObject createFolder(String name) throws IOException { + throw new UnsupportedOperationException("Not supported."); + } + + @Override + public FileObject createData(String name, String ext) throws IOException { + throw new UnsupportedOperationException("Not supported."); + } + + @Override + public boolean isReadOnly() { + return true; + } + + } } diff -r 3fe06f4d27a4 spi.debugger.ui/test/unit/src/org/netbeans/api/debugger/providers/TestMIMETypeSensitiveActionProvider.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/spi.debugger.ui/test/unit/src/org/netbeans/api/debugger/providers/TestMIMETypeSensitiveActionProvider.java Sat Feb 06 16:17:47 2010 +0100 @@ -0,0 +1,86 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2009 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 2009 Sun Microsystems, Inc. + */ + +package org.netbeans.api.debugger.providers; + +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; +import org.netbeans.spi.debugger.ActionsProvider; +import org.netbeans.spi.debugger.ActionsProviderListener; + +/** + * + * @author Martin Entlicher + */ +@ActionsProvider.Registration(path="unittest_MIME", getActions={"MIMETypeSensitiveAction"}, enabledOnMIMETypes={ "text/x-java" }) +public class TestMIMETypeSensitiveActionProvider extends ActionsProvider { + + public static Object ACTION_OBJECT = "MIMETypeSensitiveAction"; + + public static Set INSTANCES = new HashSet(); + + public TestMIMETypeSensitiveActionProvider() { + INSTANCES.add(this); + } + + @Override + public Set getActions() { + return Collections.singleton(ACTION_OBJECT); + } + + @Override + public void doAction(Object action) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public boolean isEnabled(Object action) { + return true; + } + + @Override + public void addActionsProviderListener(ActionsProviderListener l) { + } + + @Override + public void removeActionsProviderListener(ActionsProviderListener l) { + } + +} diff -r 3fe06f4d27a4 spi.debugger.ui/test/unit/src/org/netbeans/spi/debugger/ui/EditorContextDispatcherManager.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/spi.debugger.ui/test/unit/src/org/netbeans/spi/debugger/ui/EditorContextDispatcherManager.java Sat Feb 06 16:17:47 2010 +0100 @@ -0,0 +1,53 @@ +/* + * 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.spi.debugger.ui; + +import org.openide.filesystems.FileObject; + +/** + * Manages the state of EditorContextDispatcher. + * @author martin + */ +public class EditorContextDispatcherManager { + + public static void setMostRecentFile(FileObject file) { + EditorContextDispatcher.getDefault().setMostRecentFile(file); + } +}