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="DebuggerServiceRegistrations">
428
        <api name="DebuggerCoreAPI"/>
429
        <summary>Allow multiple debugger service registrations and position order</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.
437
             For the need of being able to define multiple different
438
             registrations for a single instance, @DebuggerServiceRegistrations
439
             and ActionsProvider.Registrations annotations are introduced.
440
             </p>
441
        </description>
442
        <class package="org.netbeans.spi.debugger" name="DebuggerServiceRegistration" />
443
        <class package="org.netbeans.spi.debugger" name="DebuggerServiceRegistrations" />
444
        <class package="org.netbeans.spi.debugger" name="ActionsProvider" />
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 / +256 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 116-121 Link Here
116
            //        write();
126
            //        write();
117
            cnt++;
127
            cnt++;
118
        }
128
        }
129
        for (Element e : env.getElementsAnnotatedWith(ActionsProvider.Registrations.class)) {
130
            ActionsProvider.Registrations regs = e.getAnnotation(ActionsProvider.Registrations.class);
131
            for (ActionsProvider.Registration reg : regs.value()) {
132
                final String path = reg.path();
133
                final String[] actions = reg.actions();
134
                final String[] mimeTypes = reg.activateForMIMETypes();
135
                handleProviderRegistrationInner(e, ActionsProvider.class, path, actions, mimeTypes);
136
            }
137
            cnt++;
138
        }
119
        for (Element e : env.getElementsAnnotatedWith(LazyActionsManagerListener.Registration.class)) {
139
        for (Element e : env.getElementsAnnotatedWith(LazyActionsManagerListener.Registration.class)) {
120
            LazyActionsManagerListener.Registration reg = e.getAnnotation(LazyActionsManagerListener.Registration.class);
140
            LazyActionsManagerListener.Registration reg = e.getAnnotation(LazyActionsManagerListener.Registration.class);
121
141
Lines 139-196 Link Here
139
        }
159
        }
140
        for (Element e : env.getElementsAnnotatedWith(DebuggerServiceRegistration.class)) {
160
        for (Element e : env.getElementsAnnotatedWith(DebuggerServiceRegistration.class)) {
141
            DebuggerServiceRegistration reg = e.getAnnotation(DebuggerServiceRegistration.class);
161
            DebuggerServiceRegistration reg = e.getAnnotation(DebuggerServiceRegistration.class);
142
162
            // 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.
163
            AnnotationMirror am = null;
144
            // e.getAnnotationMirrors() - use this not to generate MirroredTypeException
164
            for (AnnotationMirror am_ : e.getAnnotationMirrors()) {
145
            String classNames = null;
165
                if (am_.getAnnotationType().toString().equals(DebuggerServiceRegistration.class.getName())) {
146
            for (AnnotationMirror am : e.getAnnotationMirrors()) {
166
                    am = am_;
147
                if (am.getAnnotationType().toString().equals(DebuggerServiceRegistration.class.getName())) {
167
                    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
                }
168
                }
157
            }
169
            }
158
            //System.err.println("classNames before translation = "+classNames);
170
159
            classNames = translateClassNames(classNames);
171
            handleServiceRegistration(e, reg, am);
160
            if (!implementsInterfaces(e, classNames)) {
172
            cnt++;
161
                throw new IllegalArgumentException("Annotated element "+e+" does not implement all interfaces " + classNames);
173
        }
174
        for (Element e : env.getElementsAnnotatedWith(DebuggerServiceRegistrations.class)) {
175
            DebuggerServiceRegistrations regs = e.getAnnotation(DebuggerServiceRegistrations.class);
176
            // TODO: Get rid of AnnotationMirror after http://bugs.sun.com/view_bug.do?bug_id=6519115 is fixed.
177
            AnnotationMirror amregs = null;
178
            for (AnnotationMirror am_ : e.getAnnotationMirrors()) {
179
                if (am_.getAnnotationType().toString().equals(DebuggerServiceRegistrations.class.getName())) {
180
                    amregs = am_;
181
                    break;
182
                }
162
            }
183
            }
163
            //System.err.println("classNames after  translation = "+classNames);
184
164
            /*
185
            DebuggerServiceRegistration[] regsv = regs.value();
165
            Class[] classes;
186
            if (regsv == null || regsv.length == 0) {
166
            String classNames;
187
                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
            }
188
            }
176
            */
189
            AnnotationMirror[] ams = new AnnotationMirror[regsv.length];
177
            String path = reg.path();
190
            Map<? extends ExecutableElement, ? extends AnnotationValue> annElementValues = amregs.getElementValues();
178
            if (path != null && path.length() > 0) {
191
            for (AnnotationValue av : annElementValues.values()) {
179
                path = "Debugger/"+path;
192
                Object value = av.getValue();
180
            } else {
193
                if (value instanceof Collection) {
181
                path = "Debugger";
194
                    ams = (AnnotationMirror[]) ((Collection) value).toArray(ams);
195
                }
182
            }
196
            }
183
            layer(e).instanceFile(path, null, null).
197
            for (int i = 0; i < regsv.length; i++) {
184
                    stringvalue(ContextAwareServiceHandler.SERVICE_NAME, instantiableClassOrMethod(e)).
198
                handleServiceRegistration(e, regsv[i], ams[i]);
185
                    //stringvalue(ContextAwareServiceHandler.SERVICE_CLASSES, classNames). - taken from instanceOf so that we do not have to provide it twice
199
            }
186
                    stringvalue("instanceOf", classNames).
187
                    methodvalue("instanceCreate", "org.netbeans.spi.debugger.ContextAwareSupport", "createService").
188
                    write();
189
            cnt++;
200
            cnt++;
190
        }
201
        }
191
        return cnt == annotations.size();
202
        return cnt == annotations.size();
192
    }
203
    }
193
204
205
    private List<? extends TypeMirror> getTypeMirrors(DebuggerServiceRegistration reg, AnnotationMirror am) {
206
207
        /* TODO uncomment this after http://bugs.sun.com/view_bug.do?bug_id=6519115 is fixed.
208
        List<? extends TypeMirror> typeMirrors = null;
209
        try {
210
            reg.types();
211
            throw new IllegalStateException("No type mirros obtained from element "+e);
212
        } catch (MirroredTypeException mte) {
213
            typeMirrors = Collections.singletonList(mte.getTypeMirror());
214
            System.err.println("Have one "+typeMirrors.get(0)+" type mirror for element "+e);
215
        } catch (MirroredTypesException mte) {
216
            typeMirrors = mte.getTypeMirrors();
217
            System.err.println("Have "+typeMirrors.size()+" type mirrors for element "+e);
218
            System.err.println("    mirrors = "+typeMirrors);
219
        }
220
         */
221
222
        // TODO: Delete the rest of this method after http://bugs.sun.com/view_bug.do?bug_id=6519115 is fixed.
223
        List<TypeMirror> typeMirrors = null;
224
        Map<? extends ExecutableElement, ? extends AnnotationValue> elementValues =
225
                am.getElementValues();
226
        //System.err.println("am:\n elementValues = "+elementValues);
227
        String classNames = null;
228
        for (ExecutableElement ee : elementValues.keySet()) {
229
            if (ee.getSimpleName().contentEquals("types")) { // NOI18N
230
                classNames = elementValues.get(ee).getValue().toString();
231
            }
232
        }
233
        if (classNames == null) {
234
            throw new IllegalArgumentException("Annotation "+am+" does not provide types");
235
        }
236
        //System.err.println("classNames before translation = "+classNames);
237
        typeMirrors = new ArrayList<TypeMirror>();
238
        int i1 = 0;
239
        int i2;
240
        while ((i2 = classNames.indexOf(',', i1)) > 0 || i1 < classNames.length()) {
241
            if (i2 < 0) i2 = classNames.length();
242
            String className = classNames.substring(i1, i2).trim();
243
            if (className.endsWith(".class")) {
244
                className = className.substring(0, className.length() - ".class".length());
245
            }
246
            TypeElement type = processingEnv.getElementUtils().getTypeElement(className);
247
            typeMirrors.add(type.asType());
248
            i1 = i2 + 1;
249
        }
250
        //System.err.println("=> type mirrors = "+typeMirrors);
251
252
        return typeMirrors;
253
    }
254
255
    private void handleServiceRegistration(Element e, DebuggerServiceRegistration reg, AnnotationMirror am) throws LayerGenerationException {
256
        // Class[] classes = reg.types(); - Cant NOT do that, classes are not created at compile time.
257
        // e.getAnnotationMirrors() - use this not to generate MirroredTypeException
258
        List<? extends TypeMirror> typeMirrors = getTypeMirrors(reg, am);
259
260
        List<? extends TypeMirror> notImplTypeMirrors = implementsInterfaces(e, typeMirrors);
261
        if (!notImplTypeMirrors.isEmpty()) {
262
            throw new IllegalArgumentException("Annotated element "+e+" does not implement all interfaces " + notImplTypeMirrors);
263
        }
264
265
        String path = reg.path();
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
        if (path != null && path.length() > 0) {
286
            path = "Debugger/"+path;
287
        } else {
288
            path = "Debugger";
289
        }
290
        //System.err.println("path = "+path);
291
        String basename = className.replace('.', '-');
292
        LayerBuilder.File f = lb.file(path + "/" + basename + ".instance");
293
        //LayerBuilder.File f = lb.instanceFile(path, null, Evaluator.class);
294
        f.stringvalue(ContextAwareServiceHandler.SERVICE_NAME, className).
295
          //stringvalue("serviceClass", Evaluator.class.getName()).
296
          stringvalue("instanceOf", classNamesBuilder.toString()).
297
          methodvalue("instanceCreate", "org.netbeans.spi.debugger.ContextAwareSupport", "createService").
298
          position(reg.position()).
299
          write();
300
    }
301
194
    private void handleProviderRegistrationInner(Element e, Class providerClass, String path) throws IllegalArgumentException, LayerGenerationException {
302
    private void handleProviderRegistrationInner(Element e, Class providerClass, String path) throws IllegalArgumentException, LayerGenerationException {
195
        handleProviderRegistrationInner(e, providerClass, path, null, null);
303
        handleProviderRegistrationInner(e, providerClass, path, null, null);
196
    }
304
    }
Lines 207-215 Link Here
207
        } else {
315
        } else {
208
            path = "Debugger";
316
            path = "Debugger";
209
        }
317
        }
210
        File f = layer(e).instanceFile(path, null, providerClass).
318
        LayerBuilder lb = layer(e);
211
                stringvalue(ContextAwareServiceHandler.SERVICE_NAME, className).
319
        String basename = className.replace('.', '-');
212
                stringvalue("serviceClass", providerClass.getName());
320
        LayerBuilder.File f = lb.file(path + "/" + basename + ".instance");
321
        f.stringvalue(ContextAwareServiceHandler.SERVICE_NAME, className).
322
          stringvalue("serviceClass", providerClass.getName());
213
        if (actions != null && actions.length > 0) {
323
        if (actions != null && actions.length > 0) {
214
            f.stringvalue(ContextAwareServiceHandler.SERVICE_ACTIONS, Arrays.toString(actions));
324
            f.stringvalue(ContextAwareServiceHandler.SERVICE_ACTIONS, Arrays.toString(actions));
215
        }
325
        }
Lines 267-272 Link Here
267
            case CLASS:
377
            case CLASS:
268
            case INTERFACE: {
378
            case INTERFACE: {
269
                TypeElement te = (TypeElement) e;
379
                TypeElement te = (TypeElement) e;
380
                removeImplementingInterfaces(te.asType(), interfaces);
381
                /*
270
                List<? extends TypeMirror> interfs = te.getInterfaces();
382
                List<? extends TypeMirror> interfs = te.getInterfaces();
271
                for (TypeMirror tm : interfs) {
383
                for (TypeMirror tm : interfs) {
272
                    e = ((DeclaredType) tm).asElement();
384
                    e = ((DeclaredType) tm).asElement();
Lines 276-281 Link Here
276
                        implementsInterfaces(e, interfaces);
388
                        implementsInterfaces(e, interfaces);
277
                    }
389
                    }
278
                }
390
                }
391
                 */
279
                break;
392
                break;
280
            }
393
            }
281
            case METHOD: {
394
            case METHOD: {
Lines 299-321 Link Here
299
        return interfaces.isEmpty();
412
        return interfaces.isEmpty();
300
    }
413
    }
301
414
415
    private void removeImplementingInterfaces(TypeMirror tm, Set<String> interfaces) {
416
        for (Iterator<String> i = interfaces.iterator(); i.hasNext(); ) {
417
            String type = i.next();
418
            TypeMirror typeMirror =
419
                processingEnv.getTypeUtils().getDeclaredType(
420
                    processingEnv.getElementUtils().getTypeElement(type.replace('$', '.')));
421
422
            if (processingEnv.getTypeUtils().isAssignable(tm, typeMirror)) {
423
                i.remove();
424
            }
425
        }
426
    }
427
428
    private List<? extends TypeMirror> implementsInterfaces(Element e, List<? extends TypeMirror> typeMirrors) {
429
        List<TypeMirror> notImplementedMirrors = Collections.emptyList();
430
        switch (e.getKind()) {
431
            case CLASS:
432
            case INTERFACE: {
433
                TypeElement te = (TypeElement) e;
434
                TypeMirror tm = te.asType();
435
                for (TypeMirror typeMirror : typeMirrors) {
436
                    if (!processingEnv.getTypeUtils().isAssignable(tm, typeMirror)) {
437
                        if (notImplementedMirrors == Collections.EMPTY_LIST) {
438
                            notImplementedMirrors = new ArrayList<TypeMirror>();
439
                        }
440
                        notImplementedMirrors.add(typeMirror);
441
                    }
442
                }
443
                /*
444
                TypeMirror typeMirror = type != null ?
445
                    processingEnv.getTypeUtils().getDeclaredType(
446
                        processingEnv.getElementUtils().getTypeElement(type.getName().replace('$', '.'))) :
447
                    null;
448
449
                        processingEnv.getTypeUtils().isAssignable(te.asType(), null);
450
                 */
451
                //removeImplementingInterfaces(te.asType(), interfaces);
452
                /*
453
                List<? extends TypeMirror> interfs = te.getInterfaces();
454
                for (TypeMirror tm : interfs) {
455
                    e = ((DeclaredType) tm).asElement();
456
                    String clazz = processingEnv.getElementUtils().getBinaryName((TypeElement) e).toString();
457
                    boolean contains = interfaces.remove(clazz);
458
                    if (!contains) {
459
                        implementsInterfaces(e, interfaces);
460
                    }
461
                }
462
                 */
463
                break;
464
            }
465
            case METHOD: {
466
                TypeMirror retType = ((ExecutableElement) e).getReturnType();
467
                if (retType.getKind().equals(TypeKind.NONE)) {
468
                    return typeMirrors;
469
                } else {
470
                    TypeElement te = (TypeElement) ((DeclaredType) retType).asElement();
471
                    TypeMirror tm = te.asType();
472
                    for (TypeMirror typeMirror : typeMirrors) {
473
                        if (!processingEnv.getTypeUtils().isAssignable(tm, typeMirror)) {
474
                            if (notImplementedMirrors == Collections.EMPTY_LIST) {
475
                                notImplementedMirrors = new ArrayList<TypeMirror>();
476
                            }
477
                            notImplementedMirrors.add(typeMirror);
478
                        }
479
                    }
480
481
                    /*
482
                    List<? extends TypeMirror> interfs = te.getInterfaces();
483
                    for (TypeMirror tm : interfs) {
484
                        e = ((DeclaredType) tm).asElement();
485
                        String clazz = processingEnv.getElementUtils().getBinaryName((TypeElement) e).toString();
486
                        interfaces.remove(clazz);
487
                    }
488
                     */
489
                }
490
                break;
491
            }
492
            default:
493
                throw new IllegalArgumentException("Annotated element is not loadable as an instance: " + e);
494
        }
495
        return notImplementedMirrors;
496
    }
497
302
    private String instantiableClassOrMethod(Element e) throws IllegalArgumentException, LayerGenerationException {
498
    private String instantiableClassOrMethod(Element e) throws IllegalArgumentException, LayerGenerationException {
303
        switch (e.getKind()) {
499
        switch (e.getKind()) {
304
            case CLASS: {
500
            case CLASS: {
305
                String clazz = processingEnv.getElementUtils().getBinaryName((TypeElement) e).toString();
501
                String clazz = processingEnv.getElementUtils().getBinaryName((TypeElement) e).toString();
502
                //System.err.println("instantiableClassOrMethod(): class = "+clazz);
306
                if (e.getModifiers().contains(Modifier.ABSTRACT)) {
503
                if (e.getModifiers().contains(Modifier.ABSTRACT)) {
307
                    throw new LayerGenerationException(clazz + " must not be abstract", e);
504
                    throw new LayerGenerationException(clazz + " must not be abstract", e);
308
                }
505
                }
309
                {
506
                {
310
                    boolean hasDefaultCtor = false;
507
                    boolean hasDefaultCtor = false;
508
                    boolean hasContextCtor = false;
311
                    for (ExecutableElement constructor : ElementFilter.constructorsIn(e.getEnclosedElements())) {
509
                    for (ExecutableElement constructor : ElementFilter.constructorsIn(e.getEnclosedElements())) {
312
                        if (constructor.getParameters().isEmpty()) {
510
                        List<? extends VariableElement> parameters = constructor.getParameters();
511
                        //System.err.println("  parameters = "+parameters+", size = "+parameters.size());
512
                        if (parameters.isEmpty()) {
313
                            hasDefaultCtor = true;
513
                            hasDefaultCtor = true;
314
                            break;
514
                            break;
315
                        }
515
                        }
516
                        if (parameters.size() == 1) {
517
                            String type = parameters.get(0).asType().toString();
518
                            //System.err.println("Param type = "+type);
519
                            if (ContextProvider.class.getName().equals(type)) {
520
                                hasContextCtor = true;
521
                                break;
522
                            }
523
                        }
316
                    }
524
                    }
317
                    if (!hasDefaultCtor) {
525
                    if (!(hasDefaultCtor || hasContextCtor)) {
318
                        throw new LayerGenerationException(clazz + " must have a no-argument constructor", e);
526
                        throw new LayerGenerationException(clazz + " must have a no-argument constructor or constuctor taking "+ContextProvider.class.getName()+" as a parameter.", e);
319
                    }
527
                    }
320
                }
528
                }
321
                /*propType = processingEnv.getElementUtils().getTypeElement("java.util.Properties").asType();
529
                /*propType = processingEnv.getElementUtils().getTypeElement("java.util.Properties").asType();
(-)a/api.debugger/src/org/netbeans/spi/debugger/ActionsProvider.java (+10 lines)
Lines 174-179 Link Here
174
174
175
    }
175
    }
176
176
177
    /**
178
     * Allows registration of multiple {@link Registration} annotations.
179
     * @since 1.28
180
     */
181
    @Retention(RetentionPolicy.SOURCE)
182
    @Target({ElementType.TYPE})
183
    public @interface Registrations {
184
        Registration[] value();
185
    }
186
177
    static class ContextAware extends ActionsProvider implements ContextAwareService<ActionsProvider> {
187
    static class ContextAware extends ActionsProvider implements ContextAwareService<ActionsProvider> {
178
188
179
        private static final String ERROR = "error in getting MIMEType";    // NOI18N
189
        private static final String ERROR = "error in getting MIMEType";    // NOI18N
(-)a/api.debugger/src/org/netbeans/spi/debugger/DebuggerServiceRegistration.java (+6 lines)
Lines 72-75 Link Here
72
     * The list of interfaces that this class implements and wish to register for.
72
     * The list of interfaces that this class implements and wish to register for.
73
     */
73
     */
74
    Class[] types();
74
    Class[] types();
75
76
    /**
77
     * Position of this service within its path.
78
     * @since 1.28
79
     */
80
    int position() default Integer.MAX_VALUE;
75
}
81
}
(-)04d674b90c8a (+60 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.ElementType;
46
import java.lang.annotation.Retention;
47
import java.lang.annotation.RetentionPolicy;
48
import java.lang.annotation.Target;
49
50
/**
51
 * Allows registration of multiple {@link DebuggerServiceRegistration} annotations.
52
 * @since 1.28
53
 *
54
 * @author Martin Entlicher
55
 */
56
@Retention(RetentionPolicy.SOURCE)
57
@Target({ElementType.TYPE})
58
public @interface DebuggerServiceRegistrations {
59
    DebuggerServiceRegistration[] value();
60
}
(-)a/spi.debugger.ui/manifest.mf (-1 / +1 lines)
Lines 2-7 Link Here
2
OpenIDE-Module: org.netbeans.spi.debugger.ui/1
2
OpenIDE-Module: org.netbeans.spi.debugger.ui/1
3
OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/debugger/ui/Bundle.properties
3
OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/debugger/ui/Bundle.properties
4
OpenIDE-Module-Layer: org/netbeans/modules/debugger/resources/mf-layer.xml
4
OpenIDE-Module-Layer: org/netbeans/modules/debugger/resources/mf-layer.xml
5
OpenIDE-Module-Specification-Version: 2.24
5
OpenIDE-Module-Specification-Version: 2.25
6
OpenIDE-Module-Provides: org.netbeans.spi.debugger.ui
6
OpenIDE-Module-Provides: org.netbeans.spi.debugger.ui
7
OpenIDE-Module-Install: org/netbeans/modules/debugger/ui/DebuggerModule.class
7
OpenIDE-Module-Install: org/netbeans/modules/debugger/ui/DebuggerModule.class
(-)a/spi.debugger.ui/src/org/netbeans/modules/debugger/ui/registry/DebuggerProcessor.java (-19 / +47 lines)
Lines 46-51 Link Here
46
46
47
import java.util.Arrays;
47
import java.util.Arrays;
48
import java.util.HashSet;
48
import java.util.HashSet;
49
import java.util.List;
49
import java.util.Set;
50
import java.util.Set;
50
import javax.annotation.processing.Processor;
51
import javax.annotation.processing.Processor;
51
import javax.annotation.processing.RoundEnvironment;
52
import javax.annotation.processing.RoundEnvironment;
Lines 55-69 Link Here
55
import javax.lang.model.element.ExecutableElement;
56
import javax.lang.model.element.ExecutableElement;
56
import javax.lang.model.element.Modifier;
57
import javax.lang.model.element.Modifier;
57
import javax.lang.model.element.TypeElement;
58
import javax.lang.model.element.TypeElement;
59
import javax.lang.model.element.VariableElement;
58
import javax.lang.model.type.DeclaredType;
60
import javax.lang.model.type.DeclaredType;
59
import javax.lang.model.type.TypeKind;
61
import javax.lang.model.type.TypeKind;
60
import javax.lang.model.type.TypeMirror;
62
import javax.lang.model.type.TypeMirror;
61
import javax.lang.model.util.ElementFilter;
63
import javax.lang.model.util.ElementFilter;
64
import org.netbeans.spi.debugger.ContextProvider;
62
65
63
import org.netbeans.spi.debugger.ui.AttachType;
66
import org.netbeans.spi.debugger.ui.AttachType;
64
import org.netbeans.spi.debugger.ui.BreakpointType;
67
import org.netbeans.spi.debugger.ui.BreakpointType;
65
import org.netbeans.spi.debugger.ui.ColumnModelRegistration;
68
import org.netbeans.spi.debugger.ui.ColumnModelRegistration;
69
import org.netbeans.spi.debugger.ui.ColumnModelRegistrations;
66
import org.netbeans.spi.viewmodel.ColumnModel;
70
import org.netbeans.spi.viewmodel.ColumnModel;
71
import org.openide.filesystems.annotations.LayerBuilder;
67
72
68
import org.openide.filesystems.annotations.LayerGeneratingProcessor;
73
import org.openide.filesystems.annotations.LayerGeneratingProcessor;
69
import org.openide.filesystems.annotations.LayerGenerationException;
74
import org.openide.filesystems.annotations.LayerGenerationException;
Lines 123-128 Link Here
123
            handleProviderRegistration(e, ColumnModel.class, path, position);
128
            handleProviderRegistration(e, ColumnModel.class, path, position);
124
            cnt++;
129
            cnt++;
125
        }
130
        }
131
        for (Element e : env.getElementsAnnotatedWith(ColumnModelRegistrations.class)) {
132
            ColumnModelRegistrations regs = e.getAnnotation(ColumnModelRegistrations.class);
133
            for (ColumnModelRegistration reg : regs.value()) {
134
                final String path = reg.path();
135
                final int position = reg.position();
136
                handleProviderRegistration(e, ColumnModel.class, path, position);
137
            }
138
            cnt++;
139
        }
126
        return cnt == annotations.size();
140
        return cnt == annotations.size();
127
    }
141
    }
128
142
Lines 136-149 Link Here
136
        } else {
150
        } else {
137
            path = "Debugger";
151
            path = "Debugger";
138
        }
152
        }
139
        layer(e).instanceFile(path, null, providerClass).
153
        LayerBuilder lb = layer(e);
140
                stringvalue(SERVICE_NAME, className).
154
        String basename = className.replace('.', '-');
141
                stringvalue("serviceClass", providerClass.getName()).
155
        LayerBuilder.File f = lb.file(path + "/" + basename + ".instance");
142
                stringvalue("instanceOf", providerClass.getName()).
156
        f.stringvalue(SERVICE_NAME, className).
143
                //methodvalue("instanceCreate", providerClass.getName()+"$ContextAware", "createService").
157
          stringvalue("serviceClass", providerClass.getName()).
144
                methodvalue("instanceCreate", "org.netbeans.modules.debugger.ui.registry."+providerClass.getSimpleName()+"ContextAware", "createService").
158
          stringvalue("instanceOf", providerClass.getName()).
145
                position(position).
159
          //methodvalue("instanceCreate", providerClass.getName()+"$ContextAware", "createService").
146
                write();
160
          methodvalue("instanceCreate", "org.netbeans.modules.debugger.ui.registry."+providerClass.getSimpleName()+"ContextAware", "createService").
161
          position(position).
162
          write();
147
    }
163
    }
148
164
149
    private void handleProviderRegistrationDisplayName(Element e, Class providerClass, String displayName, String path, int position) throws IllegalArgumentException, LayerGenerationException {
165
    private void handleProviderRegistrationDisplayName(Element e, Class providerClass, String displayName, String path, int position) throws IllegalArgumentException, LayerGenerationException {
Lines 156-169 Link Here
156
        } else {
172
        } else {
157
            path = "Debugger";
173
            path = "Debugger";
158
        }
174
        }
159
        layer(e).instanceFile(path, null, providerClass).
175
        LayerBuilder lb = layer(e);
160
                stringvalue(SERVICE_NAME, className).
176
        String basename = className.replace('.', '-');
161
                stringvalue("serviceClass", providerClass.getName()).
177
        LayerBuilder.File f = lb.file(path + "/" + basename + ".instance");
162
                stringvalue("instanceOf", providerClass.getName()).
178
        f.stringvalue(SERVICE_NAME, className).
163
                bundlevalue("displayName", displayName).
179
          stringvalue("serviceClass", providerClass.getName()).
164
                methodvalue("instanceCreate", providerClass.getName()+"$ContextAware", "createService").
180
          stringvalue("instanceOf", providerClass.getName()).
165
                position(position).
181
          bundlevalue("displayName", displayName).
166
                write();
182
          methodvalue("instanceCreate", providerClass.getName()+"$ContextAware", "createService").
183
          position(position).
184
          write();
167
    }
185
    }
168
186
169
    private boolean isClassOf(Element e, Class providerClass) {
187
    private boolean isClassOf(Element e, Class providerClass) {
Lines 211-224 Link Here
211
                }
229
                }
212
                {
230
                {
213
                    boolean hasDefaultCtor = false;
231
                    boolean hasDefaultCtor = false;
232
                    boolean hasContextCtor = false;
214
                    for (ExecutableElement constructor : ElementFilter.constructorsIn(e.getEnclosedElements())) {
233
                    for (ExecutableElement constructor : ElementFilter.constructorsIn(e.getEnclosedElements())) {
215
                        if (constructor.getParameters().isEmpty()) {
234
                        List<? extends VariableElement> parameters = constructor.getParameters();
235
                        if (parameters.isEmpty()) {
216
                            hasDefaultCtor = true;
236
                            hasDefaultCtor = true;
217
                            break;
237
                            break;
218
                        }
238
                        }
239
                        if (parameters.size() == 1) {
240
                            String type = parameters.get(0).asType().toString();
241
                            //System.err.println("Param type = "+type);
242
                            if (ContextProvider.class.getName().equals(type)) {
243
                                hasContextCtor = true;
244
                                break;
245
                            }
246
                        }
219
                    }
247
                    }
220
                    if (!hasDefaultCtor) {
248
                    if (!(hasDefaultCtor || hasContextCtor)) {
221
                        throw new LayerGenerationException(clazz + " must have a no-argument constructor", e);
249
                        throw new LayerGenerationException(clazz + " must have a no-argument constructor or constuctor taking "+ContextProvider.class.getName()+" as a parameter.", e);
222
                    }
250
                    }
223
                }
251
                }
224
                /*propType = processingEnv.getElementUtils().getTypeElement("java.util.Properties").asType();
252
                /*propType = processingEnv.getElementUtils().getTypeElement("java.util.Properties").asType();
(-)04d674b90c8a (+60 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.ui;
44
45
import java.lang.annotation.ElementType;
46
import java.lang.annotation.Retention;
47
import java.lang.annotation.RetentionPolicy;
48
import java.lang.annotation.Target;
49
50
/**
51
 * Allows registration of multiple {@link ColumnModelRegistration} annotations.
52
 * 
53
 * @author Martin Entlicher
54
 * @since 2.25
55
 */
56
@Retention(RetentionPolicy.SOURCE)
57
@Target({ElementType.TYPE, ElementType.METHOD})
58
public @interface ColumnModelRegistrations {
59
    ColumnModelRegistration[] value();
60
}
(-)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
        
(-)04d674b90c8a (+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", types={NodeModel.class, TableModel.class}),
62
    @DebuggerServiceRegistration(path="unittest/annotated3", 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