diff -u -N -r ../../HG_FRESH/main/api.debugger/apichanges.xml api.debugger/apichanges.xml --- ../../HG_FRESH/main/api.debugger/apichanges.xml 2008-08-20 02:00:43.000000000 +0200 +++ api.debugger/apichanges.xml 2009-01-25 17:37:11.000000000 +0100 @@ -278,6 +278,41 @@ + + + Lookup improvements and service annotation registration. + + + + + +

+ In order to be able to register debugger services on System FileSystem, + which brings more flexibility and better performance (see also + ), + we add non-recursive content of org.openide.util.Lookups.forPath() + into debugger lookup. + Since debugger needs retrieve context-aware services from the lookup, + ContextAwareService interface is introduced. +

+

+ Annotations are added for easy registration on module layers. + DebuggerServiceRegistration to register implementations + of interfaces, *Provider.Registration to register + implementations of appropriate providers. +

+
+ + + + + + + + + +
+ diff -u -N -r ../../HG_FRESH/main/api.debugger/manifest.mf api.debugger/manifest.mf --- ../../HG_FRESH/main/api.debugger/manifest.mf 2008-11-18 20:59:37.000000000 +0100 +++ api.debugger/manifest.mf 2009-01-25 16:50:25.000000000 +0100 @@ -1,5 +1,4 @@ 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.15 - +OpenIDE-Module-Specification-Version: 1.16 diff -u -N -r ../../HG_FRESH/main/api.debugger/src/org/netbeans/spi/debugger/ContextAwareService.java api.debugger/src/org/netbeans/spi/debugger/ContextAwareService.java --- ../../HG_FRESH/main/api.debugger/src/org/netbeans/spi/debugger/ContextAwareService.java 1970-01-01 01:00:00.000000000 +0100 +++ api.debugger/src/org/netbeans/spi/debugger/ContextAwareService.java 2009-01-25 17:12:20.000000000 +0100 @@ -0,0 +1,81 @@ +/* + * 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.spi.debugger; + +/** + * Instance of registry entry, that delegates to a debugger service, that can be + * context-aware. + * This instances should be registered in layers and created by ContextAwareSupport.createService factory + * method as follows: + * + *
+ *   <folder name="Debugger">
+ *       <file name="MyDebuggerService.instance">
+ *           <attr name="instanceCreate" methodvalue="org.netbeans.spi.debugger.ContextAwareSupport.createService"/>
+ *           <attr name="serviceName" stringvalue="org.netbeans.my_debugger.MyServiceImpl"/>
+ *           <attr name="serviceClass" stringvalue="org.netbeans.debugger.Service"/>
+ *       </file>
+ *   </folder>
+ * + *
+ * + * @author Martin Entlicher + * @since 1.16 + */ +public interface ContextAwareService { + + /** + * Create a debugger service in a context. + * + * @param context the context to create the service with + * @return the debugger service of type T. + */ + T forContext(ContextProvider context); + + /** + * The ID of the service, usually the implementation class name. + * Services can be made hidden by this ID. + * + * @return the session ID + */ + // Lookup.Item.getId() is used instead. + //String serviceID(); + +} diff -u -N -r ../../HG_FRESH/main/api.debugger/src/org/netbeans/spi/debugger/ContextAwareSupport.java api.debugger/src/org/netbeans/spi/debugger/ContextAwareSupport.java --- ../../HG_FRESH/main/api.debugger/src/org/netbeans/spi/debugger/ContextAwareSupport.java 1970-01-01 01:00:00.000000000 +0100 +++ api.debugger/src/org/netbeans/spi/debugger/ContextAwareSupport.java 2009-01-25 17:12:32.000000000 +0100 @@ -0,0 +1,208 @@ +/* + * 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.spi.debugger; + +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Map; +import java.util.logging.Level; +import java.util.logging.Logger; + +import org.netbeans.debugger.registry.ContextAwareServiceHandler; +import org.openide.util.Exceptions; +import org.openide.util.Lookup; + +/** + * Support class for context-aware debugger services. + * + * @author Martin Entlicher + * @since 1.16 + */ +public final class ContextAwareSupport { + + private ContextAwareSupport() {} + + /** + * A helper method that creates a context-aware debugger service. + * The service must be a public class with public constructor or a public + * static method. The constructor or method takes + * no arguments or takes {@link ContextProvider} as an argument. + *

+ * This method is typically called by the implementation of {@link ContextAwareService} + * to create an instance with the given context. + * + * @param service The full class name or static method that ends with '()' + * @param context The context with which is the service to be created + * @return The instance of the service with the given context. + * @since 1.16 + */ + public static Object createInstance(String service, ContextProvider context) { + try { + ClassLoader cl = org.openide.util.Lookup.getDefault().lookup(ClassLoader.class); + String method = null; + if (service.endsWith("()")) { + int lastdot = service.lastIndexOf('.'); + if (lastdot < 0) { + Exceptions.printStackTrace( + new IllegalStateException("Bad service - dot before method name is missing: " + + "'" + service + "'.")); + return null; + } + method = service.substring(lastdot + 1, service.length() - 2).trim(); + service = service.substring(0, lastdot); + } + Class cls = cl.loadClass (service); + + Object o = null; + if (method != null) { + Method m = null; + if (context != null) { + try { + m = cls.getDeclaredMethod(method, new Class[] { ContextProvider.class }); + } catch (NoSuchMethodException nsmex) {} + } + if (m == null) { + try { + m = cls.getDeclaredMethod(method, new Class[] { }); + } catch (NoSuchMethodException nsmex) {} + } + if (m != null) { + o = m.invoke(null, (m.getParameterTypes().length == 0) + ? new Object[] {} : new Object[] { context }); + } + } + if (o == null && context != null) { + Constructor[] cs = cls.getConstructors (); + int i, k = cs.length; + for (i = 0; i < k; i++) { + Constructor c = cs [i]; + if (c.getParameterTypes ().length != 1 || + !ContextProvider.class.isAssignableFrom(c.getParameterTypes()[0])) { + continue; + } + try { + o = c.newInstance (new Object[] {context}); + } catch (IllegalAccessException e) { + Exceptions.printStackTrace(Exceptions.attachMessage(e, "service: " + service)); + } catch (IllegalArgumentException e) { + Exceptions.printStackTrace(Exceptions.attachMessage(e, "service: " + service)); + } + } + } + if (o == null) + o = cls.newInstance (); + if (Logger.getLogger(ContextAwareSupport.class.getName()).isLoggable(Level.FINE)) { + Logger.getLogger(ContextAwareSupport.class.getName()).fine("instance "+o+" created."); + } + return o; + } catch (ClassNotFoundException e) { + Exceptions.printStackTrace( + Exceptions.attachMessage( + e, + "The service "+service+" not found.")); + } catch (InstantiationException e) { + Exceptions.printStackTrace( + Exceptions.attachMessage( + e, + "The service "+service+" can not be instantiated.")); + } catch (IllegalAccessException e) { + Exceptions.printStackTrace( + Exceptions.attachMessage( + e, + "The service "+service+" can not be accessed.")); + } catch (InvocationTargetException ex) { + Exceptions.printStackTrace( + Exceptions.attachMessage( + ex, + "The service "+service+" can not be created.")); + } catch (ExceptionInInitializerError ex) { + Exceptions.printStackTrace( + Exceptions.attachMessage( + ex, + "The service "+service+" can not be initialized.")); + } + return null; + } + + /** + * Creates instance of ContextAwareService based on layer.xml + * attribute values + * + * @param attrs attributes loaded from layer.xml + * @return new ContextAwareService instance + */ + static ContextAwareService createService(Map attrs) throws ClassNotFoundException { + String serviceName = (String) attrs.get(ContextAwareServiceHandler.SERVICE_NAME); + String[] serviceClassNames = splitClasses((String) attrs.get(ContextAwareServiceHandler.SERVICE_CLASSES)); + + //Map methodValues = new HashMap(attrs); - MUST NOT DO THAT! Creates a loop initializing the entries from XML + //methodValues.remove(SERVICE_NAME); + //methodValues.remove(SERVICE_CLASS); + + ClassLoader cl = Lookup.getDefault().lookup(ClassLoader.class); + Class[] classes = new Class[serviceClassNames.length + 1]; + classes[0] = ContextAwareService.class; + for (int i = 0; i < serviceClassNames.length; i++) { + classes[i+1] = Class.forName(serviceClassNames[i], true, cl); + } + return (ContextAwareService) + Proxy.newProxyInstance( + cl, + classes, + new ContextAwareServiceHandler(serviceName, classes, Collections.EMPTY_MAP)); + } + + private static String[] splitClasses(String classes) { + ArrayList list = new ArrayList(); + int i1 = 0; + int i2; + while ((i2 = classes.indexOf(',', i1)) > 0) { + list.add(classes.substring(i1, i2).trim()); + i1 = i2 + 1; + } + list.add(classes.substring(i1).trim()); + return list.toArray(new String[] {}); + } + +} diff -u -N -r ../../HG_FRESH/main/spi.debugger.ui/manifest.mf spi.debugger.ui/manifest.mf --- ../../HG_FRESH/main/spi.debugger.ui/manifest.mf 2008-11-18 21:00:41.000000000 +0100 +++ spi.debugger.ui/manifest.mf 2009-01-25 17:38:02.000000000 +0100 @@ -2,6 +2,6 @@ OpenIDE-Module: org.netbeans.spi.debugger.ui/1 OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/debugger/ui/Bundle.properties OpenIDE-Module-Layer: org/netbeans/modules/debugger/resources/mf-layer.xml -OpenIDE-Module-Specification-Version: 2.15 +OpenIDE-Module-Specification-Version: 2.16 OpenIDE-Module-Provides: org.netbeans.spi.debugger.ui OpenIDE-Module-Install: org/netbeans/modules/debugger/ui/DebuggerModule.class diff -u -N -r ../../HG_FRESH/main/spi.debugger.ui/nbproject/project.xml spi.debugger.ui/nbproject/project.xml --- ../../HG_FRESH/main/spi.debugger.ui/nbproject/project.xml 2008-09-29 16:42:38.000000000 +0200 +++ spi.debugger.ui/nbproject/project.xml 2009-01-25 17:38:19.000000000 +0100 @@ -52,7 +52,7 @@ 1 - 1.13 + 1.16