This Bugzilla instance is a read-only archive of historic NetBeans bug reports. To report a bug in NetBeans please follow the project's instructions for reporting issues.

View | Details | Raw Unified | Return to bug 190080
Collapse All | Expand All

(-)a/api.debugger/apichanges.xml (+21 lines)
Lines 424-429 Link Here
424
        <issue number="179759"/>
424
        <issue number="179759"/>
425
    </change>
425
    </change>
426
426
427
    <change id="ServiceRegistrationPositionAndPaths">
428
        <api name="DebuggerCoreAPI"/>
429
        <summary>Debugger service registration position and paths</summary>
430
        <version major="1" minor="28"/>
431
        <date day="8" month="9" year="2010"/>
432
        <author login="mentlicher"/>
433
        <compatibility binary="compatible" source="compatible" addition="yes"/>
434
        <description>
435
             <p>
436
             Allow to specify the order of the debugger service registry and
437
             multiple paths under which the service is registered.
438
             For the need of being able to define multiple different
439
             registrations for a single instance, @DebuggerServiceRegistrations
440
             annotation is introduced.
441
             </p>
442
        </description>
443
        <class package="org.netbeans.spi.debugger" name="DebuggerServiceRegistration" />
444
        <class package="org.netbeans.spi.debugger" name="DebuggerServiceRegistrations" />
445
        <issue number="190080"/>
446
    </change>
447
427
</changes>
448
</changes>
428
449
429
  <!-- Now the surrounding HTML text and document structure: -->
450
  <!-- Now the surrounding HTML text and document structure: -->
(-)a/api.debugger/manifest.mf (-1 / +1 lines)
Lines 1-5 Link Here
1
Manifest-Version: 1.0
1
Manifest-Version: 1.0
2
OpenIDE-Module: org.netbeans.api.debugger/1
2
OpenIDE-Module: org.netbeans.api.debugger/1
3
OpenIDE-Module-Localizing-Bundle: org/netbeans/api/debugger/Bundle.properties
3
OpenIDE-Module-Localizing-Bundle: org/netbeans/api/debugger/Bundle.properties
4
OpenIDE-Module-Specification-Version: 1.27
4
OpenIDE-Module-Specification-Version: 1.28
5
OpenIDE-Module-Layer: org/netbeans/api/debugger/layer.xml
5
OpenIDE-Module-Layer: org/netbeans/api/debugger/layer.xml
(-)a/api.debugger/src/org/netbeans/debugger/registry/DebuggerProcessor.java (-48 / +258 lines)
Lines 44-51 Link Here
44
44
45
package org.netbeans.debugger.registry;
45
package org.netbeans.debugger.registry;
46
46
47
import java.util.ArrayList;
47
import java.util.Arrays;
48
import java.util.Arrays;
49
import java.util.Collection;
50
import java.util.Collections;
48
import java.util.HashSet;
51
import java.util.HashSet;
52
import java.util.Iterator;
49
import java.util.List;
53
import java.util.List;
50
import java.util.Map;
54
import java.util.Map;
51
import java.util.Set;
55
import java.util.Set;
Lines 59-74 Link Here
59
import javax.lang.model.element.ExecutableElement;
63
import javax.lang.model.element.ExecutableElement;
60
import javax.lang.model.element.Modifier;
64
import javax.lang.model.element.Modifier;
61
import javax.lang.model.element.TypeElement;
65
import javax.lang.model.element.TypeElement;
66
import javax.lang.model.element.VariableElement;
62
import javax.lang.model.type.DeclaredType;
67
import javax.lang.model.type.DeclaredType;
68
import javax.lang.model.type.MirroredTypeException;
69
import javax.lang.model.type.MirroredTypesException;
63
import javax.lang.model.type.TypeKind;
70
import javax.lang.model.type.TypeKind;
64
import javax.lang.model.type.TypeMirror;
71
import javax.lang.model.type.TypeMirror;
65
import javax.lang.model.util.ElementFilter;
72
import javax.lang.model.util.ElementFilter;
66
73
67
import org.netbeans.api.debugger.LazyActionsManagerListener;
74
import org.netbeans.api.debugger.LazyActionsManagerListener;
68
import org.netbeans.spi.debugger.ActionsProvider;
75
import org.netbeans.spi.debugger.ActionsProvider;
76
import org.netbeans.spi.debugger.ContextProvider;
69
import org.netbeans.spi.debugger.DebuggerEngineProvider;
77
import org.netbeans.spi.debugger.DebuggerEngineProvider;
70
import org.netbeans.spi.debugger.DebuggerServiceRegistration;
78
import org.netbeans.spi.debugger.DebuggerServiceRegistration;
79
import org.netbeans.spi.debugger.DebuggerServiceRegistrations;
71
import org.netbeans.spi.debugger.SessionProvider;
80
import org.netbeans.spi.debugger.SessionProvider;
81
import org.openide.filesystems.annotations.LayerBuilder;
72
import org.openide.filesystems.annotations.LayerBuilder.File;
82
import org.openide.filesystems.annotations.LayerBuilder.File;
73
import org.openide.filesystems.annotations.LayerGeneratingProcessor;
83
import org.openide.filesystems.annotations.LayerGeneratingProcessor;
74
import org.openide.filesystems.annotations.LayerGenerationException;
84
import org.openide.filesystems.annotations.LayerGenerationException;
Lines 105-114 Link Here
105
        for (Element e : env.getElementsAnnotatedWith(ActionsProvider.Registration.class)) {
115
        for (Element e : env.getElementsAnnotatedWith(ActionsProvider.Registration.class)) {
106
            ActionsProvider.Registration reg = e.getAnnotation(ActionsProvider.Registration.class);
116
            ActionsProvider.Registration reg = e.getAnnotation(ActionsProvider.Registration.class);
107
117
108
            final String path = reg.path();
118
            final String[] paths = reg.path();
119
            if (paths == null || paths.length == 0) {
120
                throw new IllegalArgumentException("No path defined for element "+e);
121
            }
109
            final String[] actions = reg.actions();
122
            final String[] actions = reg.actions();
110
            final String[] mimeTypes = reg.activateForMIMETypes();
123
            final String[] mimeTypes = reg.activateForMIMETypes();
111
            handleProviderRegistrationInner(e, ActionsProvider.class, path, actions, mimeTypes);
124
            for (String path : paths) {
125
                handleProviderRegistrationInner(e, ActionsProvider.class, path, actions, mimeTypes);
126
            }
112
            //layer(e).instanceFile("Debugger/"+path, null, ActionsProvider.class).
127
            //layer(e).instanceFile("Debugger/"+path, null, ActionsProvider.class).
113
            //        stringvalue("serviceName", instantiableClassOrMethod(e)).
128
            //        stringvalue("serviceName", instantiableClassOrMethod(e)).
114
            //        stringvalue("serviceClass", ActionsProvider.class.getName()).
129
            //        stringvalue("serviceClass", ActionsProvider.class.getName()).
Lines 139-194 Link Here
139
        }
154
        }
140
        for (Element e : env.getElementsAnnotatedWith(DebuggerServiceRegistration.class)) {
155
        for (Element e : env.getElementsAnnotatedWith(DebuggerServiceRegistration.class)) {
141
            DebuggerServiceRegistration reg = e.getAnnotation(DebuggerServiceRegistration.class);
156
            DebuggerServiceRegistration reg = e.getAnnotation(DebuggerServiceRegistration.class);
142
157
            // TODO: Get rid of AnnotationMirror after http://bugs.sun.com/view_bug.do?bug_id=6519115 is fixed.
143
            // Class[] classes = reg.types(); - Cant NOT do that, classes are not created at compile time.
158
            AnnotationMirror am = null;
144
            // e.getAnnotationMirrors() - use this not to generate MirroredTypeException
159
            for (AnnotationMirror am_ : e.getAnnotationMirrors()) {
145
            String classNames = null;
160
                if (am_.getAnnotationType().toString().equals(DebuggerServiceRegistration.class.getName())) {
146
            for (AnnotationMirror am : e.getAnnotationMirrors()) {
161
                    am = am_;
147
                if (am.getAnnotationType().toString().equals(DebuggerServiceRegistration.class.getName())) {
162
                    break;
148
                    Map<? extends ExecutableElement, ? extends AnnotationValue> elementValues =
149
                            am.getElementValues();
150
                    //System.err.println("am:\n elementValues = "+elementValues);
151
                    for (ExecutableElement ee : elementValues.keySet()) {
152
                        if (ee.getSimpleName().contentEquals("types")) { // NOI18N
153
                            classNames = elementValues.get(ee).getValue().toString();
154
                        }
155
                    }
156
                }
163
                }
157
            }
164
            }
158
            //System.err.println("classNames before translation = "+classNames);
165
159
            classNames = translateClassNames(classNames);
166
            handleServiceRegistration(e, reg, am);
160
            if (!implementsInterfaces(e, classNames)) {
167
            cnt++;
161
                throw new IllegalArgumentException("Annotated element "+e+" does not implement all interfaces " + classNames);
168
        }
169
        for (Element e : env.getElementsAnnotatedWith(DebuggerServiceRegistrations.class)) {
170
            DebuggerServiceRegistrations regs = e.getAnnotation(DebuggerServiceRegistrations.class);
171
            // TODO: Get rid of AnnotationMirror after http://bugs.sun.com/view_bug.do?bug_id=6519115 is fixed.
172
            AnnotationMirror amregs = null;
173
            for (AnnotationMirror am_ : e.getAnnotationMirrors()) {
174
                if (am_.getAnnotationType().toString().equals(DebuggerServiceRegistrations.class.getName())) {
175
                    amregs = am_;
176
                    break;
177
                }
162
            }
178
            }
163
            //System.err.println("classNames after  translation = "+classNames);
179
164
            /*
180
            DebuggerServiceRegistration[] regsv = regs.value();
165
            Class[] classes;
181
            if (regsv == null || regsv.length == 0) {
166
            String classNames;
182
                throw new IllegalArgumentException("No service registration for element "+e);
167
            try {
168
                classes = reg.types();
169
                //className = clazz.getName();
170
                classNames = null;
171
            } catch (MirroredTypeException mtex) {
172
                TypeMirror tm = mtex.getTypeMirror();
173
                classes = null;
174
                classNames = tm.toString();
175
            }
183
            }
176
            */
184
            AnnotationMirror[] ams = new AnnotationMirror[regsv.length];
177
            String path = reg.path();
185
            Map<? extends ExecutableElement, ? extends AnnotationValue> annElementValues = amregs.getElementValues();
186
            for (AnnotationValue av : annElementValues.values()) {
187
                Object value = av.getValue();
188
                System.err.println("Annotation value = "+value);
189
                System.err.println("class = "+value.getClass());
190
                if (value instanceof Collection) {
191
                    ams = (AnnotationMirror[]) ((Collection) value).toArray(ams);
192
                }
193
            }
194
            for (int i = 0; i < regsv.length; i++) {
195
                handleServiceRegistration(e, regsv[i], ams[i]);
196
            }
197
            cnt++;
198
        }
199
        return cnt == annotations.size();
200
    }
201
202
    private List<? extends TypeMirror> getTypeMirrors(DebuggerServiceRegistration reg, AnnotationMirror am) {
203
204
        /* TODO uncomment this after http://bugs.sun.com/view_bug.do?bug_id=6519115 is fixed.
205
        List<? extends TypeMirror> typeMirrors = null;
206
        try {
207
            reg.types();
208
            throw new IllegalStateException("No type mirros obtained from element "+e);
209
        } catch (MirroredTypeException mte) {
210
            typeMirrors = Collections.singletonList(mte.getTypeMirror());
211
            System.err.println("Have one "+typeMirrors.get(0)+" type mirror for element "+e);
212
        } catch (MirroredTypesException mte) {
213
            typeMirrors = mte.getTypeMirrors();
214
            System.err.println("Have "+typeMirrors.size()+" type mirrors for element "+e);
215
            System.err.println("    mirrors = "+typeMirrors);
216
        }
217
         */
218
219
        // TODO: Delete the rest of this method after http://bugs.sun.com/view_bug.do?bug_id=6519115 is fixed.
220
        List<TypeMirror> typeMirrors = null;
221
        Map<? extends ExecutableElement, ? extends AnnotationValue> elementValues =
222
                am.getElementValues();
223
        //System.err.println("am:\n elementValues = "+elementValues);
224
        String classNames = null;
225
        for (ExecutableElement ee : elementValues.keySet()) {
226
            if (ee.getSimpleName().contentEquals("types")) { // NOI18N
227
                classNames = elementValues.get(ee).getValue().toString();
228
            }
229
        }
230
        if (classNames == null) {
231
            throw new IllegalArgumentException("Annotation "+am+" does not provide types");
232
        }
233
        //System.err.println("classNames before translation = "+classNames);
234
        typeMirrors = new ArrayList<TypeMirror>();
235
        int i1 = 0;
236
        int i2;
237
        while ((i2 = classNames.indexOf(',', i1)) > 0 || i1 < classNames.length()) {
238
            if (i2 < 0) i2 = classNames.length();
239
            String className = classNames.substring(i1, i2).trim();
240
            if (className.endsWith(".class")) {
241
                className = className.substring(0, className.length() - ".class".length());
242
            }
243
            TypeElement type = processingEnv.getElementUtils().getTypeElement(className);
244
            typeMirrors.add(type.asType());
245
            i1 = i2 + 1;
246
        }
247
        //System.err.println("=> type mirrors = "+typeMirrors);
248
249
        return typeMirrors;
250
    }
251
252
    private void handleServiceRegistration(Element e, DebuggerServiceRegistration reg, AnnotationMirror am) throws LayerGenerationException {
253
        // Class[] classes = reg.types(); - Cant NOT do that, classes are not created at compile time.
254
        // e.getAnnotationMirrors() - use this not to generate MirroredTypeException
255
        List<? extends TypeMirror> typeMirrors = getTypeMirrors(reg, am);
256
257
        List<? extends TypeMirror> notImplTypeMirrors = implementsInterfaces(e, typeMirrors);
258
        if (!notImplTypeMirrors.isEmpty()) {
259
            throw new IllegalArgumentException("Annotated element "+e+" does not implement all interfaces " + notImplTypeMirrors);
260
        }
261
262
        String[] paths = reg.path();
263
        if (paths == null || paths.length == 0) {
264
            throw new IllegalArgumentException("No path defined for element "+e);
265
        }
266
        LayerBuilder lb = layer(e);
267
        String className = instantiableClassOrMethod(e);
268
        //System.err.println("icm = "+className);
269
270
        StringBuilder classNamesBuilder = new StringBuilder();
271
        for (TypeMirror tm : typeMirrors) {
272
            TypeElement te = (TypeElement) processingEnv.getTypeUtils().asElement(tm);
273
            String cn;
274
            if (te != null) {
275
                cn = processingEnv.getElementUtils().getBinaryName(te).toString();
276
            } else {
277
                cn = tm.toString();
278
            }
279
            if (classNamesBuilder.length() > 0) {
280
                classNamesBuilder.append(", ");
281
            }
282
            classNamesBuilder.append(cn);
283
        }
284
285
        for (String path : paths) {
178
            if (path != null && path.length() > 0) {
286
            if (path != null && path.length() > 0) {
179
                path = "Debugger/"+path;
287
                path = "Debugger/"+path;
180
            } else {
288
            } else {
181
                path = "Debugger";
289
                path = "Debugger";
182
            }
290
            }
183
            layer(e).instanceFile(path, null, null).
291
            //System.err.println("path = "+path);
184
                    stringvalue(ContextAwareServiceHandler.SERVICE_NAME, instantiableClassOrMethod(e)).
292
            String basename = className.replace('.', '-');
185
                    //stringvalue(ContextAwareServiceHandler.SERVICE_CLASSES, classNames). - taken from instanceOf so that we do not have to provide it twice
293
            LayerBuilder.File f = lb.file(path + "/" + basename + ".instance");
186
                    stringvalue("instanceOf", classNames).
294
            //LayerBuilder.File f = lb.instanceFile(path, null, Evaluator.class);
187
                    methodvalue("instanceCreate", "org.netbeans.spi.debugger.ContextAwareSupport", "createService").
295
            f.stringvalue(ContextAwareServiceHandler.SERVICE_NAME, className).
188
                    write();
296
              //stringvalue("serviceClass", Evaluator.class.getName()).
189
            cnt++;
297
              stringvalue("instanceOf", classNamesBuilder.toString()).
298
              methodvalue("instanceCreate", "org.netbeans.spi.debugger.ContextAwareSupport", "createService").
299
              position(reg.position()).
300
              write();
190
        }
301
        }
191
        return cnt == annotations.size();
192
    }
302
    }
193
303
194
    private void handleProviderRegistrationInner(Element e, Class providerClass, String path) throws IllegalArgumentException, LayerGenerationException {
304
    private void handleProviderRegistrationInner(Element e, Class providerClass, String path) throws IllegalArgumentException, LayerGenerationException {
Lines 207-215 Link Here
207
        } else {
317
        } else {
208
            path = "Debugger";
318
            path = "Debugger";
209
        }
319
        }
210
        File f = layer(e).instanceFile(path, null, providerClass).
320
        LayerBuilder lb = layer(e);
211
                stringvalue(ContextAwareServiceHandler.SERVICE_NAME, className).
321
        String basename = className.replace('.', '-');
212
                stringvalue("serviceClass", providerClass.getName());
322
        LayerBuilder.File f = lb.file(path + "/" + basename + ".instance");
323
        f.stringvalue(ContextAwareServiceHandler.SERVICE_NAME, className).
324
          stringvalue("serviceClass", providerClass.getName());
213
        if (actions != null && actions.length > 0) {
325
        if (actions != null && actions.length > 0) {
214
            f.stringvalue(ContextAwareServiceHandler.SERVICE_ACTIONS, Arrays.toString(actions));
326
            f.stringvalue(ContextAwareServiceHandler.SERVICE_ACTIONS, Arrays.toString(actions));
215
        }
327
        }
Lines 267-272 Link Here
267
            case CLASS:
379
            case CLASS:
268
            case INTERFACE: {
380
            case INTERFACE: {
269
                TypeElement te = (TypeElement) e;
381
                TypeElement te = (TypeElement) e;
382
                removeImplementingInterfaces(te.asType(), interfaces);
383
                /*
270
                List<? extends TypeMirror> interfs = te.getInterfaces();
384
                List<? extends TypeMirror> interfs = te.getInterfaces();
271
                for (TypeMirror tm : interfs) {
385
                for (TypeMirror tm : interfs) {
272
                    e = ((DeclaredType) tm).asElement();
386
                    e = ((DeclaredType) tm).asElement();
Lines 276-281 Link Here
276
                        implementsInterfaces(e, interfaces);
390
                        implementsInterfaces(e, interfaces);
277
                    }
391
                    }
278
                }
392
                }
393
                 */
279
                break;
394
                break;
280
            }
395
            }
281
            case METHOD: {
396
            case METHOD: {
Lines 299-321 Link Here
299
        return interfaces.isEmpty();
414
        return interfaces.isEmpty();
300
    }
415
    }
301
416
417
    private void removeImplementingInterfaces(TypeMirror tm, Set<String> interfaces) {
418
        for (Iterator<String> i = interfaces.iterator(); i.hasNext(); ) {
419
            String type = i.next();
420
            TypeMirror typeMirror =
421
                processingEnv.getTypeUtils().getDeclaredType(
422
                    processingEnv.getElementUtils().getTypeElement(type.replace('$', '.')));
423
424
            if (processingEnv.getTypeUtils().isAssignable(tm, typeMirror)) {
425
                i.remove();
426
            }
427
        }
428
    }
429
430
    private List<? extends TypeMirror> implementsInterfaces(Element e, List<? extends TypeMirror> typeMirrors) {
431
        List<TypeMirror> notImplementedMirrors = Collections.emptyList();
432
        switch (e.getKind()) {
433
            case CLASS:
434
            case INTERFACE: {
435
                TypeElement te = (TypeElement) e;
436
                TypeMirror tm = te.asType();
437
                for (TypeMirror typeMirror : typeMirrors) {
438
                    if (!processingEnv.getTypeUtils().isAssignable(tm, typeMirror)) {
439
                        if (notImplementedMirrors == Collections.EMPTY_LIST) {
440
                            notImplementedMirrors = new ArrayList<TypeMirror>();
441
                        }
442
                        notImplementedMirrors.add(typeMirror);
443
                    }
444
                }
445
                /*
446
                TypeMirror typeMirror = type != null ?
447
                    processingEnv.getTypeUtils().getDeclaredType(
448
                        processingEnv.getElementUtils().getTypeElement(type.getName().replace('$', '.'))) :
449
                    null;
450
451
                        processingEnv.getTypeUtils().isAssignable(te.asType(), null);
452
                 */
453
                //removeImplementingInterfaces(te.asType(), interfaces);
454
                /*
455
                List<? extends TypeMirror> interfs = te.getInterfaces();
456
                for (TypeMirror tm : interfs) {
457
                    e = ((DeclaredType) tm).asElement();
458
                    String clazz = processingEnv.getElementUtils().getBinaryName((TypeElement) e).toString();
459
                    boolean contains = interfaces.remove(clazz);
460
                    if (!contains) {
461
                        implementsInterfaces(e, interfaces);
462
                    }
463
                }
464
                 */
465
                break;
466
            }
467
            case METHOD: {
468
                TypeMirror retType = ((ExecutableElement) e).getReturnType();
469
                if (retType.getKind().equals(TypeKind.NONE)) {
470
                    return typeMirrors;
471
                } else {
472
                    TypeElement te = (TypeElement) ((DeclaredType) retType).asElement();
473
                    TypeMirror tm = te.asType();
474
                    for (TypeMirror typeMirror : typeMirrors) {
475
                        if (!processingEnv.getTypeUtils().isAssignable(tm, typeMirror)) {
476
                            if (notImplementedMirrors == Collections.EMPTY_LIST) {
477
                                notImplementedMirrors = new ArrayList<TypeMirror>();
478
                            }
479
                            notImplementedMirrors.add(typeMirror);
480
                        }
481
                    }
482
483
                    /*
484
                    List<? extends TypeMirror> interfs = te.getInterfaces();
485
                    for (TypeMirror tm : interfs) {
486
                        e = ((DeclaredType) tm).asElement();
487
                        String clazz = processingEnv.getElementUtils().getBinaryName((TypeElement) e).toString();
488
                        interfaces.remove(clazz);
489
                    }
490
                     */
491
                }
492
                break;
493
            }
494
            default:
495
                throw new IllegalArgumentException("Annotated element is not loadable as an instance: " + e);
496
        }
497
        return notImplementedMirrors;
498
    }
499
302
    private String instantiableClassOrMethod(Element e) throws IllegalArgumentException, LayerGenerationException {
500
    private String instantiableClassOrMethod(Element e) throws IllegalArgumentException, LayerGenerationException {
303
        switch (e.getKind()) {
501
        switch (e.getKind()) {
304
            case CLASS: {
502
            case CLASS: {
305
                String clazz = processingEnv.getElementUtils().getBinaryName((TypeElement) e).toString();
503
                String clazz = processingEnv.getElementUtils().getBinaryName((TypeElement) e).toString();
504
                //System.err.println("instantiableClassOrMethod(): class = "+clazz);
306
                if (e.getModifiers().contains(Modifier.ABSTRACT)) {
505
                if (e.getModifiers().contains(Modifier.ABSTRACT)) {
307
                    throw new LayerGenerationException(clazz + " must not be abstract", e);
506
                    throw new LayerGenerationException(clazz + " must not be abstract", e);
308
                }
507
                }
309
                {
508
                {
310
                    boolean hasDefaultCtor = false;
509
                    boolean hasDefaultCtor = false;
510
                    boolean hasContextCtor = false;
311
                    for (ExecutableElement constructor : ElementFilter.constructorsIn(e.getEnclosedElements())) {
511
                    for (ExecutableElement constructor : ElementFilter.constructorsIn(e.getEnclosedElements())) {
312
                        if (constructor.getParameters().isEmpty()) {
512
                        List<? extends VariableElement> parameters = constructor.getParameters();
513
                        //System.err.println("  parameters = "+parameters+", size = "+parameters.size());
514
                        if (parameters.isEmpty()) {
313
                            hasDefaultCtor = true;
515
                            hasDefaultCtor = true;
314
                            break;
516
                            break;
315
                        }
517
                        }
518
                        if (parameters.size() == 1) {
519
                            String type = parameters.get(0).asType().toString();
520
                            //System.err.println("Param type = "+type);
521
                            if (ContextProvider.class.getName().equals(type)) {
522
                                hasContextCtor = true;
523
                                break;
524
                            }
525
                        }
316
                    }
526
                    }
317
                    if (!hasDefaultCtor) {
527
                    if (!(hasDefaultCtor || hasContextCtor)) {
318
                        throw new LayerGenerationException(clazz + " must have a no-argument constructor", e);
528
                        throw new LayerGenerationException(clazz + " must have a no-argument constructor or constuctor taking "+ContextProvider.class.getName()+" as a parameter.", e);
319
                    }
529
                    }
320
                }
530
                }
321
                /*propType = processingEnv.getElementUtils().getTypeElement("java.util.Properties").asType();
531
                /*propType = processingEnv.getElementUtils().getTypeElement("java.util.Properties").asType();
(-)a/api.debugger/src/org/netbeans/spi/debugger/ActionsProvider.java (-1 / +1 lines)
Lines 148-154 Link Here
148
         * An optional path to register this implementation in.
148
         * An optional path to register this implementation in.
149
         * Usually the session ID.
149
         * Usually the session ID.
150
         */
150
         */
151
        String path() default "";
151
        String[] path() default {""};
152
152
153
        /**
153
        /**
154
         * Provide the list of actions that this provider supports.
154
         * Provide the list of actions that this provider supports.
(-)a/api.debugger/src/org/netbeans/spi/debugger/DebuggerServiceRegistration.java (-1 / +8 lines)
Lines 65-75 Link Here
65
    /**
65
    /**
66
     * An optional path to register this implementation in.
66
     * An optional path to register this implementation in.
67
     * Usually the session ID, view name, etc.
67
     * Usually the session ID, view name, etc.
68
     * Since v. 1.28 it is possible to provide multiple paths as an array.
68
     */
69
     */
69
    String path() default "";
70
    String[] path() default {""};
70
71
71
    /**
72
    /**
72
     * The list of interfaces that this class implements and wish to register for.
73
     * The list of interfaces that this class implements and wish to register for.
73
     */
74
     */
74
    Class[] types();
75
    Class[] types();
76
77
    /**
78
     * Position of this service within its path.
79
     * @since 1.28
80
     */
81
    int position() default Integer.MAX_VALUE;
75
}
82
}
(-)1f48f3eff75f (+66 lines)
Added Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2010 Oracle and/or its affiliates. All rights reserved.
5
 *
6
 * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
7
 * Other names may be trademarks of their respective owners.
8
 *
9
 * The contents of this file are subject to the terms of either the GNU
10
 * General Public License Version 2 only ("GPL") or the Common
11
 * Development and Distribution License("CDDL") (collectively, the
12
 * "License"). You may not use this file except in compliance with the
13
 * License. You can obtain a copy of the License at
14
 * http://www.netbeans.org/cddl-gplv2.html
15
 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
16
 * specific language governing permissions and limitations under the
17
 * License.  When distributing the software, include this License Header
18
 * Notice in each file and include the License file at
19
 * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
20
 * particular file as subject to the "Classpath" exception as provided
21
 * by Oracle in the GPL Version 2 section of the License file that
22
 * accompanied this code. If applicable, add the following below the
23
 * License Header, with the fields enclosed by brackets [] replaced by
24
 * your own identifying information:
25
 * "Portions Copyrighted [year] [name of copyright owner]"
26
 *
27
 * If you wish your version of this file to be governed by only the CDDL
28
 * or only the GPL Version 2, indicate your decision by adding
29
 * "[Contributor] elects to include this software in this distribution
30
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
31
 * single choice of license, a recipient has the option to distribute
32
 * your version of this file under either the CDDL, the GPL Version 2 or
33
 * to extend the choice of license to its licensees as provided above.
34
 * However, if you add GPL Version 2 code and therefore, elected the GPL
35
 * Version 2 license, then the option applies only if the new code is
36
 * made subject to such option by the copyright holder.
37
 *
38
 * Contributor(s):
39
 *
40
 * Portions Copyrighted 2009 Sun Microsystems, Inc.
41
 */
42
43
package org.netbeans.spi.debugger;
44
45
import java.lang.annotation.Annotation;
46
import java.lang.annotation.ElementType;
47
import java.lang.annotation.Retention;
48
import java.lang.annotation.RetentionPolicy;
49
import java.lang.annotation.Target;
50
51
/**
52
 * Declarative registration of debugger service provider implementing a set
53
 * of interfaces.
54
 * By marking an implementation class with this annotation,
55
 * you automatically register that implementation for use by debugger.
56
 * The class must be public and have a public constructor which takes
57
 * no arguments or takes {@link ContextProvider} as an argument.
58
 * @since 1.28
59
 *
60
 * @author Martin Entlicher
61
 */
62
@Retention(RetentionPolicy.SOURCE)
63
@Target({ElementType.TYPE})
64
public @interface DebuggerServiceRegistrations {
65
    DebuggerServiceRegistration[] value();
66
}
(-)a/spi.debugger.ui/src/org/netbeans/spi/debugger/ui/ColumnModelRegistration.java (-1 / +2 lines)
Lines 65-72 Link Here
65
    /**
65
    /**
66
     * An optional path to register this implementation in.
66
     * An optional path to register this implementation in.
67
     * Usually the session ID, view name, etc.
67
     * Usually the session ID, view name, etc.
68
     * Since v. 2.25 it is possible to provide multiple paths as an array.
68
     */
69
     */
69
    String path();
70
    String[] path();
70
71
71
    /**
72
    /**
72
     * An optional position in which to register this service relative to others.
73
     * An optional position in which to register this service relative to others.
(-)a/spi.debugger.ui/test/unit/src/org/netbeans/api/debugger/ProvidersAnnotationTest.java (+42 lines)
Lines 58-63 Link Here
58
import org.netbeans.api.debugger.providers.TestLazyActionsManagerListenerAnnotated;
58
import org.netbeans.api.debugger.providers.TestLazyActionsManagerListenerAnnotated;
59
import org.netbeans.api.debugger.providers.TestLazyDebuggerManagerListenerAnnotated;
59
import org.netbeans.api.debugger.providers.TestLazyDebuggerManagerListenerAnnotated;
60
import org.netbeans.api.debugger.providers.TestMIMETypeSensitiveActionProvider;
60
import org.netbeans.api.debugger.providers.TestMIMETypeSensitiveActionProvider;
61
import org.netbeans.api.debugger.providers.TestMultiModelRegistrations;
61
import org.netbeans.api.debugger.providers.TestThreeModels;
62
import org.netbeans.api.debugger.providers.TestThreeModels;
62
import org.netbeans.modules.debugger.ui.models.ColumnModels;
63
import org.netbeans.modules.debugger.ui.models.ColumnModels;
63
import org.netbeans.spi.debugger.ActionsProvider;
64
import org.netbeans.spi.debugger.ActionsProvider;
Lines 206-211 Link Here
206
        }
207
        }
207
    }
208
    }
208
209
210
    public void testMultiModelRegistrations() throws Exception {
211
        Lookup.MetaInf l = new Lookup.MetaInf("unittest");
212
        Object instance;
213
        {
214
        List<? extends TreeModel> list = l.lookup("annotated1", TreeModel.class);
215
        assertEquals("Wrong looked up object", 1, list.size());
216
        instance = ((TestMultiModelRegistrations) list.get(0)).INSTANCES.iterator().next();
217
        assertEquals("One provider instance should be created!", 1, TestMultiModelRegistrations.INSTANCES.size());
218
        List<? extends NodeModel> list2 = l.lookup("annotated1", NodeModel.class);
219
        assertEquals("Wrong looked up object", 0, list2.size());
220
        List<? extends TableModel> list3 = l.lookup("annotated1", TableModel.class);
221
        assertEquals("Wrong looked up object", 0, list3.size());
222
        }
223
224
        {
225
        List<? extends TreeModel> list = l.lookup("annotated2", TreeModel.class);
226
        assertEquals("Wrong looked up object", 0, list.size());
227
        List<? extends NodeModel> list2 = l.lookup("annotated2", NodeModel.class);
228
        assertEquals("Wrong looked up object", 1, list2.size());
229
        List<? extends TableModel> list3 = l.lookup("annotated2", TableModel.class);
230
        assertEquals("Wrong looked up object", 1, list3.size());
231
        list2.get(0);
232
        assertEquals("One provider instance should be created!", 1, TestMultiModelRegistrations.INSTANCES.size());
233
        list3.get(0);
234
        assertEquals("One provider instance should be created!", 1, TestMultiModelRegistrations.INSTANCES.size());
235
        }
236
237
        {
238
        List<? extends TreeModel> list = l.lookup("annotated3", TreeModel.class);
239
        assertEquals("Wrong looked up object", 0, list.size());
240
        List<? extends NodeModel> list2 = l.lookup("annotated3", NodeModel.class);
241
        assertEquals("Wrong looked up object", 1, list2.size());
242
        List<? extends TableModel> list3 = l.lookup("annotated3", TableModel.class);
243
        assertEquals("Wrong looked up object", 1, list3.size());
244
        list2.get(0);
245
        assertEquals("One provider instance should be created!", 1, TestMultiModelRegistrations.INSTANCES.size());
246
        assertEquals("Wrong instance", instance, list3.get(0));
247
        assertEquals("One provider instance should be created!", 1, TestMultiModelRegistrations.INSTANCES.size());
248
        }
249
    }
250
209
    public void testColumnProviders() throws Exception {
251
    public void testColumnProviders() throws Exception {
210
        Lookup.MetaInf l = new Lookup.MetaInf("unittest/annotated");
252
        Lookup.MetaInf l = new Lookup.MetaInf("unittest/annotated");
211
        
253
        
(-)1f48f3eff75f (+120 lines)
Added Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2010 Oracle and/or its affiliates. All rights reserved.
5
 *
6
 * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
7
 * Other names may be trademarks of their respective owners.
8
 *
9
 * The contents of this file are subject to the terms of either the GNU
10
 * General Public License Version 2 only ("GPL") or the Common
11
 * Development and Distribution License("CDDL") (collectively, the
12
 * "License"). You may not use this file except in compliance with the
13
 * License. You can obtain a copy of the License at
14
 * http://www.netbeans.org/cddl-gplv2.html
15
 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
16
 * specific language governing permissions and limitations under the
17
 * License.  When distributing the software, include this License Header
18
 * Notice in each file and include the License file at
19
 * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
20
 * particular file as subject to the "Classpath" exception as provided
21
 * by Oracle in the GPL Version 2 section of the License file that
22
 * accompanied this code. If applicable, add the following below the
23
 * License Header, with the fields enclosed by brackets [] replaced by
24
 * your own identifying information:
25
 * "Portions Copyrighted [year] [name of copyright owner]"
26
 *
27
 * If you wish your version of this file to be governed by only the CDDL
28
 * or only the GPL Version 2, indicate your decision by adding
29
 * "[Contributor] elects to include this software in this distribution
30
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
31
 * single choice of license, a recipient has the option to distribute
32
 * your version of this file under either the CDDL, the GPL Version 2 or
33
 * to extend the choice of license to its licensees as provided above.
34
 * However, if you add GPL Version 2 code and therefore, elected the GPL
35
 * Version 2 license, then the option applies only if the new code is
36
 * made subject to such option by the copyright holder.
37
 *
38
 * Contributor(s):
39
 *
40
 * Portions Copyrighted 2009 Sun Microsystems, Inc.
41
 */
42
43
package org.netbeans.api.debugger.providers;
44
45
import java.util.HashSet;
46
import java.util.Set;
47
import org.netbeans.spi.debugger.DebuggerServiceRegistration;
48
import org.netbeans.spi.debugger.DebuggerServiceRegistrations;
49
import org.netbeans.spi.viewmodel.ModelListener;
50
import org.netbeans.spi.viewmodel.NodeModel;
51
import org.netbeans.spi.viewmodel.TableModel;
52
import org.netbeans.spi.viewmodel.TreeModel;
53
import org.netbeans.spi.viewmodel.UnknownTypeException;
54
55
/**
56
 *
57
 * @author Martin Entlicher
58
 */
59
@DebuggerServiceRegistrations({
60
    @DebuggerServiceRegistration(path="unittest/annotated1", types=TreeModel.class),
61
    @DebuggerServiceRegistration(path={"unittest/annotated2", "unittest/annotated3"},
62
                                 types={NodeModel.class, TableModel.class})
63
})
64
public class TestMultiModelRegistrations implements TreeModel, NodeModel, TableModel {
65
    
66
    public static Set<TestMultiModelRegistrations> INSTANCES = new HashSet<TestMultiModelRegistrations>();
67
68
    public TestMultiModelRegistrations() {
69
        INSTANCES.add(this);
70
    }
71
72
    public Object getRoot() {
73
        throw new UnsupportedOperationException("Not supported yet.");
74
    }
75
76
    public Object[] getChildren(Object parent, int from, int to) throws UnknownTypeException {
77
        throw new UnsupportedOperationException("Not supported yet.");
78
    }
79
80
    public boolean isLeaf(Object node) throws UnknownTypeException {
81
        throw new UnsupportedOperationException("Not supported yet.");
82
    }
83
84
    public int getChildrenCount(Object node) throws UnknownTypeException {
85
        throw new UnsupportedOperationException("Not supported yet.");
86
    }
87
88
    public void addModelListener(ModelListener l) {
89
        throw new UnsupportedOperationException("Not supported yet.");
90
    }
91
92
    public void removeModelListener(ModelListener l) {
93
        throw new UnsupportedOperationException("Not supported yet.");
94
    }
95
96
    public String getDisplayName(Object node) throws UnknownTypeException {
97
        throw new UnsupportedOperationException("Not supported yet.");
98
    }
99
100
    public String getIconBase(Object node) throws UnknownTypeException {
101
        throw new UnsupportedOperationException("Not supported yet.");
102
    }
103
104
    public String getShortDescription(Object node) throws UnknownTypeException {
105
        throw new UnsupportedOperationException("Not supported yet.");
106
    }
107
108
    public Object getValueAt(Object node, String columnID) throws UnknownTypeException {
109
        throw new UnsupportedOperationException("Not supported yet.");
110
    }
111
112
    public boolean isReadOnly(Object node, String columnID) throws UnknownTypeException {
113
        throw new UnsupportedOperationException("Not supported yet.");
114
    }
115
116
    public void setValueAt(Object node, String columnID, Object value) throws UnknownTypeException {
117
        throw new UnsupportedOperationException("Not supported yet.");
118
    }
119
120
}

Return to bug 190080