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 247404
Collapse All | Expand All

(-)a/api.io/arch.xml (+1172 lines)
Line 0 Link Here
1
<?xml version="1.0" encoding="UTF-8"?>
2
<!DOCTYPE api-answers PUBLIC "-//NetBeans//DTD Arch Answers//EN" "../nbbuild/antsrc/org/netbeans/nbbuild/Arch.dtd" [
3
  <!ENTITY api-questions SYSTEM "../nbbuild/antsrc/org/netbeans/nbbuild/Arch-api-questions.xml">
4
]>
5
6
<api-answers
7
  question-version="1.29"
8
  author="jhavlin@netbeans.org"
9
>
10
<!-- This file was based on arch.xml file in module openide.io. -->
11
12
  &api-questions;
13
14
15
    <!--
16
            <question id="arch-overall" when="init">
17
                Describe the overall architecture.
18
                <hint>
19
                What will be API for
20
                <a href="http://wiki.netbeans.org/API_Design#Separate_API_for_clients_from_support_API">
21
                    clients and what support API</a>?
22
                What parts will be pluggable?
23
                How will plug-ins be registered? Please use <code>&lt;api type="export"/&gt;</code>
24
                to describe your general APIs and specify their
25
                <a href="http://wiki.netbeans.org/API_Stability#Private">
26
                stability categories</a>.
27
                If possible please provide simple diagrams.
28
                </hint>
29
            </question>
30
    -->
31
    <answer id="arch-overall">
32
        <api
33
            name="NbInputOutputAPI"
34
            group="java"
35
            type="export"
36
            category="official"
37
            url="@org-netbeans-api-io@/org/netbeans/api/io/package-summary.html"
38
        >
39
            <p>
40
                The module contains APIs for creating output panes (e.g. output tabs in Output Window in the IDE)
41
                and for writing data into them. It also supports some advanced techniques, e.g. color text,
42
                hyperlinks, code folding, scrolling to stored positions.
43
            </p>
44
        </api>
45
        <api
46
            name="NbInputOutputSPI"
47
            group="java"
48
            type="export"
49
            category="official"
50
            url="@org-netbeans-api-io@/org/netbeans/spi/io/package-summary.html"
51
        >
52
            <p>
53
                SPI for providing custom implementations of output window is also included in this module, in package
54
                <code>org.netbeans.spi.io</code>
55
            </p>
56
        </api>
57
    </answer>
58
59
60
61
    <!--
62
            <question id="arch-quality" when="init">
63
                How will the <a href="http://www.netbeans.org/community/guidelines/q-evangelism.html">quality</a>
64
                of your code be tested and
65
                how are future regressions going to be prevented?
66
                <hint>
67
                What kind of testing do
68
                you want to use? How much functionality, in which areas,
69
                should be covered by the tests? How you find out that your
70
                project was successful?
71
                </hint>
72
            </question>
73
    -->
74
    <answer id="arch-quality">
75
        <p>
76
            Unit test will be prepared for invocable code in API classes. But most of the
77
            code is just definition of API and SPI.
78
        </p>
79
    </answer>
80
81
82
83
    <!--
84
            <question id="arch-time" when="init">
85
                What are the time estimates of the work?
86
                <hint>
87
                Please express your estimates of how long the design, implementation,
88
                stabilization are likely to last. How many people will be needed to
89
                implement this and what is the expected milestone by which the work should be
90
                ready?
91
                </hint>
92
            </question>
93
    -->
94
    <answer id="arch-time">
95
        <p>
96
            The design, implementation, preparing unit tests and reviews will
97
            probably take several weeks.
98
        </p>
99
    </answer>
100
101
102
103
<!--
104
        <question id="arch-usecases" when="init">
105
            <hint>
106
                Content of this answer will be displayed as part of page at
107
                http://www.netbeans.org/download/dev/javadoc/usecases.html
108
                You can use tags &lt;usecase name="name&gt; regular html description &lt;/usecase&gt;
109
                and if you want to use an URL you can prefix if with @TOP@ to begin
110
                at the root of your javadoc
111
            </hint>
112
113
                Describe the main <a href="http://wiki.netbeans.org/API_Design#The_Importance_of_Being_Use_Case_Oriented">
114
                use cases</a> of the new API. Who will use it under
115
                what circumstances? What kind of code would typically need to be written
116
                to use the module?
117
            </question>
118
    -->
119
    <answer id="arch-usecases">
120
121
        <usecase id="print" name="Print a simple output to a new output tab">
122
            <p>
123
                The basic use-case is printing a simple text, e.g. text output of an application,
124
                into a dedicated pane in the UI, e.g. a tab in Output Window in the IDE.
125
            </p>
126
            <pre>
127
    InputOutput io = InputOutput.get("UseCase1", true);
128
    io.getOut().println("This is a simple output");
129
    io.getOut().close();
130
            </pre>
131
        </usecase>
132
133
        <usecase id="printOnClickHyperlink" name="Print a line with hyperlink for invocation of arbitrary code">
134
            <p>
135
                Hyperlinks can be also used to invoke some code when clicked.
136
            </p>
137
            <pre>
138
    InputOutput io = InputOutput.get("UseCase3", true);
139
    io.getOut().print("A line containing a ");
140
    io.getOut().print("hyperlink", Hyperlink.from(new Runnable() {
141
        public void run() {
142
            System.gc();
143
        }
144
    }));
145
    io.getOut().println(" for invocation of custom code.");
146
    io.getOut().close();
147
            </pre>
148
        </usecase>
149
150
        <usecase id="printColor" name="Print color text">
151
            <p>
152
                Print a color text. Users can select a predefined color for
153
                common cases (debug, warning, failure, success), or custom
154
                color specified as RGB value.
155
            </p>
156
            <pre>
157
    InputOutput io = InputOutput.get("UseCase4", true);
158
    io.getOut().println("Let's print some info", OutputColor.debug());
159
    io.getOut().println("or warning with appropriate color", OutputColor.warning());
160
    io.getOut().println("Maybe also text with custom reddish color", OutputColor.rgb(255, 16, 16));
161
    io.getOut().close();
162
            </pre>
163
        </usecase>
164
165
        <usecase id="printAndReset" name="Reset an InputOutput to clear all previosly printed text">
166
            <p>
167
                It is possible to reuse already created output pane and clear
168
                all the previously printed text if it is not needed any more.
169
            </p>
170
            <pre>
171
    InputOutput io = InputOutput.get("UseCase5", true);
172
    io.getOut().println("Let's print some text");
173
    io.getErr().println("and reset the pane immediately.");
174
    io.reset();
175
    io.getOut().println("The pane is now empty and we can reuse it simply");
176
    io.getOut().close();
177
            </pre>
178
        </usecase>
179
180
    </answer>
181
182
183
184
    <!--
185
            <question id="arch-what" when="init">
186
                What is this project good for?
187
                <hint>
188
                Please provide here a few lines describing the project,
189
                what problem it should solve, provide links to documentation,
190
                specifications, etc.
191
                </hint>
192
            </question>
193
    -->
194
    <answer id="arch-what">
195
        <p>
196
            The Input/Output API and SPI is a small module
197
            which contains <code>InputOutput</code> and related interfaces used in
198
            driving the Output Window.
199
        </p>
200
        <p>
201
            The normal implementation is <code>org.netbeans.core.output2</code>.
202
        </p>
203
    </answer>
204
205
206
207
    <!--
208
            <question id="arch-where" when="impl">
209
                Where one can find sources for your module?
210
                <hint>
211
                    Please provide link to the Hg web client at
212
                    http://hg.netbeans.org/
213
                    or just use tag defaultanswer generate='here'
214
                </hint>
215
            </question>
216
    -->
217
    <answer id="arch-where">
218
        <defaultanswer generate='here' />
219
    </answer>
220
221
222
223
    <!--
224
            <question id="compat-deprecation" when="init">
225
                How the introduction of your project influences functionality
226
                provided by previous version of the product?
227
                <hint>
228
                If you are planning to deprecate/remove/change any existing APIs,
229
                list them here accompanied with the reason explaining why you
230
                are doing so.
231
                </hint>
232
            </question>
233
    -->
234
    <answer id="compat-deprecation">
235
        <p>
236
            Backward compatibility of other modules is not broken.
237
        </p>
238
        <p>
239
            This module should replace original I/O API module
240
            <code>org.openide.io</code>, which has the same goals, but which is
241
            not UI independent, and which is difficult to extend.
242
        </p>
243
    </answer>
244
245
246
247
    <!--
248
            <question id="compat-i18n" when="impl">
249
                Is your module correctly internationalized?
250
                <hint>
251
                Correct internationalization means that it obeys instructions
252
                at <a href="http://www.netbeans.org/download/dev/javadoc/org-openide-modules/org/openide/modules/doc-files/i18n-branding.html">
253
                NetBeans I18N pages</a>.
254
                </hint>
255
            </question>
256
    -->
257
    <answer id="compat-i18n">
258
        <p>
259
            Yes. There is not much to internationalize.
260
        </p>
261
    </answer>
262
263
264
265
    <!--
266
            <question id="compat-standards" when="init">
267
                Does the module implement or define any standards? Is the
268
                implementation exact or does it deviate somehow?
269
            </question>
270
    -->
271
    <answer id="compat-standards">
272
        <p>
273
            The module defines an API.
274
        </p>
275
    </answer>
276
277
278
279
    <!--
280
        <question id="compat-version" when="impl">
281
            Can your module coexist with earlier and future
282
            versions of itself? Can you correctly read all old settings? Will future
283
            versions be able to read your current settings? Can you read
284
            or politely ignore settings stored by a future version?
285
286
                <hint>
287
                Very helpful for reading settings is to store version number
288
                there, so future versions can decide whether how to read/convert
289
                the settings and older versions can ignore the new ones.
290
                </hint>
291
            </question>
292
    -->
293
    <answer id="compat-version">
294
        <p>
295
            N/A. No settings are read or written by this module.
296
        </p>
297
    </answer>
298
299
300
301
    <!--
302
            <question id="dep-jre" when="final">
303
                Which version of JRE do you need (1.2, 1.3, 1.4, etc.)?
304
                <hint>
305
                It is expected that if your module runs on 1.x that it will run
306
                on 1.x+1 if no, state that please. Also describe here cases where
307
                you run different code on different versions of JRE and why.
308
                </hint>
309
            </question>
310
    -->
311
    <answer id="dep-jre">
312
        1.7
313
    </answer>
314
315
316
317
    <!--
318
            <question id="dep-jrejdk" when="final">
319
                Do you require the JDK or is the JRE enough?
320
            </question>
321
    -->
322
    <answer id="dep-jrejdk">
323
        JRE
324
    </answer>
325
326
327
328
    <!--
329
            <question id="dep-nb" when="init">
330
                What other NetBeans projects and modules does this one depend on?
331
                <hint>
332
                Depending on other NetBeans projects influnces the ability of
333
                users of your work to customize their own branded version of
334
                NetBeans by enabling and disabling some modules. Too
335
                much dependencies restrict this kind of customization. If that
336
                is your case, then you may want to split your functionality into
337
                pieces of autoload, eager and regular modules which can be
338
                enabled independently. Usually the answer to this question
339
                is generated from your <code>project.xml</code> file, but
340
                if it is not guessed correctly, you can suppress it by
341
                specifying &lt;defaultanswer generate="none"/&gt; and
342
                write here your own. Please describe such projects as imported APIs using
343
                the <code>&lt;api name="identification" type="import or export" category="stable" url="where is the description" /&gt;</code>.
344
                By doing this information gets listed in the summary page of your
345
                javadoc.
346
                </hint>
347
            </question>
348
    -->
349
    <answer id="dep-nb">
350
        <defaultanswer generate='here' />
351
    </answer>
352
353
354
355
<!--
356
        <question id="dep-non-nb" when="init">
357
            What other projects outside NetBeans does this one depend on?
358
359
                <hint>
360
                Depending on 3rd party libraries is always problematic,
361
                especially if they are not open source, as that complicates
362
                the licensing scheme of NetBeans. Please enumerate your
363
                external dependencies here, so it is correctly understood since
364
                the begining what are the legal implications of your project.
365
                Also please note that
366
                some non-NetBeans projects are packaged as NetBeans modules
367
                (see <a href="http://libs.netbeans.org/">libraries</a>) and
368
                it is preferred to use this approach when more modules may
369
                depend and share such third-party libraries.
370
                </hint>
371
            </question>
372
    -->
373
    <answer id="dep-non-nb">
374
        None.
375
    </answer>
376
377
378
379
    <!--
380
            <question id="dep-platform" when="init">
381
                On which platforms does your module run? Does it run in the same
382
                way on each?
383
                <hint>
384
                If you plan any dependency on OS or any usage of native code,
385
                please describe why you are doing so and describe how you envision
386
                to enforce the portability of your code.
387
                Please note that there is a support for <a href="http://www.netbeans.org/download/dev/javadoc/org-openide-modules/org/openide/modules/doc-files/api.html#how-os-specific">OS conditionally
388
                enabled modules</a> which together with autoload/eager modules
389
                can allow you to enable to provide the best OS aware support
390
                on certain OSes while providing compatibility bridge on the not
391
                supported ones.
392
                Also please list the supported
393
                OSes/HW platforms and mentioned the lovest version of JDK required
394
                for your project to run on. Also state whether JRE is enough or
395
                you really need JDK.
396
                </hint>
397
            </question>
398
    -->
399
    <answer id="dep-platform">
400
        Any.
401
    </answer>
402
403
404
405
    <!--
406
            <question id="deploy-dependencies" when="final">
407
                What do other modules need to do to declare a dependency on this one,
408
                in addition to or instead of the normal module dependency declaration
409
                (e.g. tokens to require)?
410
                <hint>
411
                    Provide a sample of the actual lines you would add to a module manifest
412
                    to declare a dependency, for example OpenIDE-Module-Requires: some.token.
413
                    If other modules should not depend on this module, or should just use a
414
                    simple regular module dependency, you can just answer "nothing". If you
415
                    intentionally expose a semistable API to clients using implementation
416
                    dependencies, you should mention that here (but there is no need to give
417
                    an example of usage).
418
                </hint>
419
            </question>
420
    -->
421
    <answer id="deploy-dependencies">
422
        <p>
423
            Normal module dependency is enough.
424
        </p>
425
        <p>
426
            Availability of some implementation of the SPI is guaranteed by
427
            "OpenIDE-Module-Needs: org.netbeans.spi.io.InputOutputProvider" in
428
            the manifest of this module.
429
        </p>
430
    </answer>
431
432
433
434
    <!--
435
        <question id="deploy-jar" when="impl">
436
            Do you deploy just module JAR file(s) or other files as well?
437
            <hint>
438
            Usually a module consist of one JAR file (perhaps with Class-Path
439
            extensions) and also a configuration file that enables it. If you
440
            have any other files, use
441
            &lt;api group="java.io.File" name="yourname" type="export" category="friend"&gt;...&lt;/api&gt;
442
            to define the location, name and stability of your files (of course
443
            changing "yourname" and "friend" to suit your needs).
444
445
                If it uses more than one JAR, describe where they are located, how
446
                they refer to each other.
447
                If it consist of module JAR(s) and other files, please describe
448
                what is their purpose, why other files are necessary. Please
449
                make sure that installation/uninstallation leaves the system
450
                in state as it was before installation.
451
                </hint>
452
            </question>
453
    -->
454
    <answer id="deploy-jar">
455
        <p>
456
            Just the module JAR.
457
        </p>
458
    </answer>
459
460
461
462
    <!--
463
            <question id="deploy-nbm" when="impl">
464
                Can you deploy an NBM via the Update Center?
465
                <hint>
466
                If not why?
467
                </hint>
468
            </question>
469
    -->
470
    <answer id="deploy-nbm">
471
        <p>
472
            Yes.
473
        </p>
474
    </answer>
475
476
477
478
    <!--
479
        <question id="deploy-packages" when="init">
480
            Are packages of your module made inaccessible by not declaring them
481
            public?
482
483
                <hint>
484
                By default NetBeans build harness treats all packages are private.
485
                If you export some of them - either as public or friend packages,
486
                you should have a reason. If the reason is described elsewhere
487
                in this document, you can ignore this question.
488
                </hint>
489
            </question>
490
    -->
491
    <answer id="deploy-packages">
492
        <p>
493
            No; only API classes are public.
494
        </p>
495
    </answer>
496
497
498
499
    <!--
500
            <question id="deploy-shared" when="final">
501
                Do you need to be installed in the shared location only, or in the user directory only,
502
                or can your module be installed anywhere?
503
                <hint>
504
                Installation location shall not matter, if it does explain why.
505
                Consider also whether <code>InstalledFileLocator</code> can help.
506
                </hint>
507
            </question>
508
    -->
509
    <answer id="deploy-shared">
510
        <p>
511
            Anywhere.
512
        </p>
513
    </answer>
514
515
516
517
    <!--
518
        <question id="exec-ant-tasks" when="impl">
519
            Do you define or register any ant tasks that other can use?
520
521
                <hint>
522
                If you provide an ant task that users can use, you need to be very
523
                careful about its syntax and behaviour, as it most likely forms an
524
                      API for end users and as there is a lot of end users, their reaction
525
                when such API gets broken can be pretty strong.
526
                </hint>
527
            </question>
528
    -->
529
    <answer id="exec-ant-tasks">
530
        <p>
531
            No.
532
        </p>
533
    </answer>
534
535
536
537
    <!--
538
            <question id="exec-classloader" when="impl">
539
                Does your code create its own class loader(s)?
540
                <hint>
541
                A bit unusual. Please explain why and what for.
542
                </hint>
543
            </question>
544
    -->
545
    <answer id="exec-classloader">
546
        <p>
547
            No.
548
        </p>
549
    </answer>
550
551
552
553
    <!--
554
        <question id="exec-component" when="impl">
555
            Is execution of your code influenced by any (string) property
556
            of any of your components?
557
558
                <hint>
559
                Often <code>JComponent.getClientProperty</code>, <code>Action.getValue</code>
560
                or <code>PropertyDescriptor.getValue</code>, etc. are used to influence
561
                a behavior of some code. This of course forms an interface that should
562
                be documented. Also if one depends on some interface that an object
563
                implements (<code>component instanceof Runnable</code>) that forms an
564
                API as well.
565
                </hint>
566
            </question>
567
    -->
568
    <answer id="exec-component">
569
        <p>
570
            No.
571
        </p>
572
    </answer>
573
574
575
576
    <!--
577
            <question id="exec-introspection" when="impl">
578
                Does your module use any kind of runtime type information (<code>instanceof</code>,
579
                work with <code>java.lang.Class</code>, etc.)?
580
                <hint>
581
                Check for cases when you have an object of type A and you also
582
                expect it to (possibly) be of type B and do some special action. That
583
                should be documented. The same applies on operations in meta-level
584
                (Class.isInstance(...), Class.isAssignableFrom(...), etc.).
585
                </hint>
586
            </question>
587
    -->
588
    <answer id="exec-introspection">
589
        <p>
590
            No.
591
        </p>
592
    </answer>
593
594
595
596
    <!--
597
            <question id="exec-privateaccess" when="final">
598
                Are you aware of any other parts of the system calling some of
599
                your methods by reflection?
600
                <hint>
601
                If so, describe the "contract" as an API. Likely private or friend one, but
602
                still API and consider rewrite of it.
603
                </hint>
604
            </question>
605
    -->
606
    <answer id="exec-privateaccess">
607
        <p>
608
            No.
609
        </p>
610
    </answer>
611
612
613
614
    <!--
615
            <question id="exec-process" when="impl">
616
                Do you execute an external process from your module? How do you ensure
617
                that the result is the same on different platforms? Do you parse output?
618
                Do you depend on result code?
619
                <hint>
620
                If you feed an input, parse the output please declare that as an API.
621
                </hint>
622
            </question>
623
    -->
624
    <answer id="exec-process">
625
        <p>
626
            No.
627
        </p>
628
    </answer>
629
630
631
632
    <!--
633
            <question id="exec-property" when="impl">
634
                Is execution of your code influenced by any environment or
635
                Java system (<code>System.getProperty</code>) property?
636
                On a similar note, is there something interesting that you
637
                pass to <code>java.util.logging.Logger</code>? Or do you observe
638
                what others log?
639
                <hint>
640
                If there is a property that can change the behavior of your
641
                code, somebody will likely use it. You should describe what it does
642
                and the <a href="http://wiki.netbeans.org/API_Stability">stability category</a>
643
                of this API. You may use
644
                <pre>
645
                    &lt;api type="export" group="property" name="id" category="private" url="http://..."&gt;
646
                        description of the property, where it is used, what it influence, etc.
647
                    &lt;/api&gt;
648
                </pre>
649
                </hint>
650
            </question>
651
    -->
652
    <answer id="exec-property">
653
        <p>
654
            No.
655
        </p>
656
    </answer>
657
658
659
660
    <!--
661
            <question id="exec-reflection" when="impl">
662
                Does your code use Java Reflection to execute other code?
663
                <hint>
664
                This usually indicates a missing or insufficient API in the other
665
                part of the system. If the other side is not aware of your dependency
666
                this contract can be easily broken.
667
                </hint>
668
            </question>
669
    -->
670
    <answer id="exec-reflection">
671
        <p>
672
            No.
673
        </p>
674
    </answer>
675
676
677
678
    <!--
679
            <question id="exec-threading" when="init">
680
                What threading models, if any, does your module adhere to? How the
681
                project behaves with respect to threading?
682
                <hint>
683
                    Is your API threadsafe? Can it be accessed from any threads or
684
                    just from some dedicated ones? Any special relation to AWT and
685
                    its Event Dispatch thread? Also
686
                    if your module calls foreign APIs which have a specific threading model,
687
                    indicate how you comply with the requirements for multithreaded access
688
                    (synchronization, mutexes, etc.) applicable to those APIs.
689
                    If your module defines any APIs, or has complex internal structures
690
                    that might be used from multiple threads, declare how you protect
691
                    data against concurrent access, race conditions, deadlocks, etc.,
692
                    and whether such rules are enforced by runtime warnings, errors, assertions, etc.
693
                    Examples: a class might be non-thread-safe (like Java Collections); might
694
                    be fully thread-safe (internal locking); might require access through a mutex
695
                    (and may or may not automatically acquire that mutex on behalf of a client method);
696
                    might be able to run only in the event queue; etc.
697
                    Also describe when any events are fired: synchronously, asynchronously, etc.
698
                    Ideas: <a href="http://core.netbeans.org/proposals/threading/index.html#recommendations">Threading Recommendations</a> (in progress)
699
                </hint>
700
            </question>
701
    -->
702
    <answer id="exec-threading">
703
        <p>
704
            API classes are thread safe, they mostly represent immutable
705
            objects, or delegate to the SPI.
706
        </p>
707
        <p>
708
            Implementators of the SPI should ensure that their code is properly
709
            synchronized, as it can be called from any thread.
710
        </p>
711
    </answer>
712
713
714
715
<!--
716
        <question id="format-clipboard" when="impl">
717
            Which data flavors (if any) does your code read from or insert to
718
            the clipboard (by access to clipboard on means calling methods on <code>java.awt.datatransfer.Transferable</code>?
719
720
                <hint>
721
                Often Node's deal with clipboard by usage of <code>Node.clipboardCopy, Node.clipboardCut and Node.pasteTypes</code>.
722
                Check your code for overriding these methods.
723
                </hint>
724
            </question>
725
    -->
726
    <answer id="format-clipboard">
727
        <p>
728
            Plain Unicode text only.
729
        </p>
730
    </answer>
731
732
733
734
    <!--
735
            <question id="format-dnd" when="impl">
736
                Which protocols (if any) does your code understand during Drag &amp; Drop?
737
                <hint>
738
                Often Node's deal with clipboard by usage of <code>Node.drag, Node.getDropType</code>.
739
                Check your code for overriding these methods. Btw. if they are not overridden, they
740
                by default delegate to <code>Node.clipboardCopy, Node.clipboardCut and Node.pasteTypes</code>.
741
                </hint>
742
            </question>
743
    -->
744
    <answer id="format-dnd">
745
        <p>
746
            N/A
747
        </p>
748
    </answer>
749
750
751
752
    <!--
753
        <question id="format-types" when="impl">
754
            Which protocols and file formats (if any) does your module read or write on disk,
755
            or transmit or receive over the network? Do you generate an ant build script?
756
            Can it be edited and modified?
757
758
            <hint>
759
                <p>
760
                Files can be read and written by other programs, modules and users. If they influence
761
                your behaviour, make sure you either document the format or claim that it is a private
762
                api (using the &lt;api&gt; tag).
763
                </p>
764
                <p>
765
                If you generate an ant build file, this is very likely going to be seen by end users and
766
                they will be attempted to edit it. You should be ready for that and provide here a link
767
                to documentation that you have for such purposes and also describe how you are going to
768
                understand such files during next release, when you (very likely) slightly change the
769
                format.
770
                </p>
771
            </hint>
772
        </question>
773
    -->
774
    <answer id="format-types">
775
        <p>
776
            None.
777
        </p>
778
    </answer>
779
780
781
782
    <!--
783
        <question id="lookup-lookup" when="init">
784
            Does your module use <code>org.openide.util.Lookup</code>
785
            or any similar technology to find any components to communicate with? Which ones?
786
787
                <hint>
788
                NetBeans is build around a generic registry of services called
789
                lookup. It is preferable to use it for registration and discovery
790
                if possible. See
791
                <a href="http://www.netbeans.org/download/dev/javadoc/org-openide-util/org/openide/util/lookup/doc-files/index.html">
792
                The Solution to Comunication Between Components
793
                </a>. If you do not plan to use lookup and insist usage
794
                of other solution, then please describe why it is not working for
795
                you.
796
                <br/>
797
                When filling the final version of your arch document, please
798
                describe the interfaces you are searching for, where
799
                are defined, whether you are searching for just one or more of them,
800
                if the order is important, etc. Also classify the stability of such
801
                API contract. Use &lt;api group=&amp;lookup&amp; /&gt; tag, so
802
                your information gets listed in the summary page of your javadoc.
803
                </hint>
804
            </question>
805
    -->
806
    <answer id="lookup-lookup">
807
        <p>
808
            <code>IOProvider.getDefault()</code> asks lookup for the first instance
809
            of <code>InputOutputProvider</code>. This is normally provided by
810
            <code>org.netbeans.core.output2</code>.
811
        </p>
812
    </answer>
813
814
815
816
    <!--
817
            <question id="lookup-register" when="final">
818
                Do you register anything into lookup for other code to find?
819
                <hint>
820
                Do you register using layer file or using a declarative annotation such as <code>@ServiceProvider</code>?
821
                Who is supposed to find your component?
822
                </hint>
823
            </question>
824
    -->
825
    <answer id="lookup-register">
826
        <p>
827
            No.
828
        </p>
829
    </answer>
830
831
832
833
    <!--
834
            <question id="lookup-remove" when="final">
835
                Do you remove entries of other modules from lookup?
836
                <hint>
837
                Why? Of course, that is possible, but it can be dangerous. Is the module
838
                your are masking resource from aware of what you are doing?
839
                </hint>
840
            </question>
841
    -->
842
    <answer id="lookup-remove">
843
        <p>
844
            No.
845
        </p>
846
    </answer>
847
848
849
850
    <!--
851
            <question id="perf-exit" when="final">
852
                Does your module run any code on exit?
853
            </question>
854
    -->
855
    <answer id="perf-exit">
856
        <p>
857
            No.
858
        </p>
859
    </answer>
860
861
862
863
    <!--
864
            <question id="perf-huge_dialogs" when="final">
865
                Does your module contain any dialogs or wizards with a large number of
866
                GUI controls such as combo boxes, lists, trees, or text areas?
867
            </question>
868
    -->
869
    <answer id="perf-huge_dialogs">
870
        <p>
871
            No.
872
        </p>
873
    </answer>
874
875
876
877
    <!--
878
            <question id="perf-limit" when="init">
879
                Are there any hard-coded or practical limits in the number or size of
880
                elements your code can handle?
881
                <hint>
882
                    Most of algorithms have increasing memory and speed complexity
883
                    with respect to size of data they operate on. What is the critical
884
                    part of your project that can be seen as a bottleneck with
885
                    respect to speed or required memory? What are the practical
886
                    sizes of data you tested your project with? What is your estimate
887
                    of potential size of data that would cause visible performance
888
                    problems? Is there some kind of check to detect such situation
889
                    and prevent "hard" crashes - for example the CloneableEditorSupport
890
                    checks for size of a file to be opened in editor
891
                    and if it is larger than 1Mb it shows a dialog giving the
892
                    user the right to decide - e.g. to cancel or commit suicide.
893
                </hint>
894
            </question>
895
    -->
896
    <answer id="perf-limit">
897
        <p>
898
            No.
899
        </p>
900
    </answer>
901
902
903
904
    <!--
905
            <question id="perf-mem" when="final">
906
                How much memory does your component consume? Estimate
907
                with a relation to the number of windows, etc.
908
            </question>
909
    -->
910
    <answer id="perf-mem">
911
        <p>
912
            N/A
913
        </p>
914
    </answer>
915
916
917
918
    <!--
919
            <question id="perf-menus" when="final">
920
                Does your module use dynamically updated context menus, or
921
                context-sensitive actions with complicated and slow enablement logic?
922
                <hint>
923
                    If you do a lot of tricks when adding actions to regular or context menus, you can significantly
924
                    slow down display of the menu, even when the user is not using your action. Pay attention to
925
                    actions you add to the main menu bar, and to context menus of foreign nodes or components. If
926
                    the action is conditionally enabled, or changes its display dynamically, you need to check the
927
                    impact on performance. In some cases it may be more appropriate to make a simple action that is
928
                    always enabled but does more detailed checks in a dialog if it is actually run.
929
                </hint>
930
            </question>
931
    -->
932
    <answer id="perf-menus">
933
        <p>
934
            No.
935
        </p>
936
    </answer>
937
938
939
940
    <!--
941
        <question id="perf-progress" when="final">
942
            Does your module execute any long-running tasks?
943
944
                <hint>Long running tasks should never block
945
                AWT thread as it badly hurts the UI
946
                <a href="http://performance.netbeans.org/responsiveness/issues.html">
947
                responsiveness</a>.
948
                Tasks like connecting over
949
                network, computing huge amount of data, compilation
950
                be done asynchronously (for example
951
                using <code>RequestProcessor</code>), definitively it should
952
                not block AWT thread.
953
                </hint>
954
            </question>
955
    -->
956
    <answer id="perf-progress">
957
        <p>
958
            No.
959
        </p>
960
    </answer>
961
962
963
964
    <!--
965
            <question id="perf-scale" when="init">
966
                Which external criteria influence the performance of your
967
                program (size of file in editor, number of files in menu,
968
                in source directory, etc.) and how well your code scales?
969
                <hint>
970
                Please include some estimates, there are other more detailed
971
                questions to answer in later phases of implementation.`
972
                </hint>
973
            </question>
974
    -->
975
    <answer id="perf-scale">
976
        <p>
977
            Scalability in GUI speed and memory consumption is probably limited
978
            only by the Output Window implementation.
979
        </p>
980
    </answer>
981
982
983
984
    <!--
985
            <question id="perf-spi" when="init">
986
                How the performance of the plugged in code will be enforced?
987
                <hint>
988
                If you allow foreign code to be plugged into your own module, how
989
                do you enforce that it will behave correctly and quickly and will not
990
                negatively influence the performance of your own module?
991
                </hint>
992
            </question>
993
    -->
994
    <answer id="perf-spi">
995
        <p>
996
            No special behavior.
997
        </p>
998
    </answer>
999
1000
1001
1002
    <!--
1003
            <question id="perf-startup" when="final">
1004
                Does your module run any code on startup?
1005
            </question>
1006
    -->
1007
    <answer id="perf-startup">
1008
        <p>
1009
            No.
1010
        </p>
1011
    </answer>
1012
1013
1014
1015
    <!--
1016
            <question id="perf-wakeup" when="final">
1017
                Does any piece of your code wake up periodically and do something
1018
                even when the system is otherwise idle (no user interaction)?
1019
            </question>
1020
    -->
1021
    <answer id="perf-wakeup">
1022
        <p>
1023
            No.
1024
        </p>
1025
    </answer>
1026
1027
1028
1029
    <!--
1030
        <question id="resources-file" when="final">
1031
            Does your module use <code>java.io.File</code> directly?
1032
1033
                <hint>
1034
                NetBeans provide a logical wrapper over plain files called
1035
                <code>org.openide.filesystems.FileObject</code> that
1036
                provides uniform access to such resources and is the preferred
1037
                way that should be used. But of course there can be situations when
1038
                this is not suitable.
1039
                </hint>
1040
            </question>
1041
    -->
1042
    <answer id="resources-file">
1043
        <p>
1044
            No, but the implementation may.
1045
        </p>
1046
    </answer>
1047
1048
1049
1050
    <!--
1051
        <question id="resources-layer" when="final">
1052
            Does your module provide own layer? Does it create any files or
1053
            folders in it? What it is trying to communicate by that and with which
1054
            components?
1055
1056
                <hint>
1057
                NetBeans allows automatic and declarative installation of resources
1058
                by module layers. Module register files into appropriate places
1059
                and other components use that information to perform their task
1060
                (build menu, toolbar, window layout, list of templates, set of
1061
                options, etc.).
1062
                </hint>
1063
            </question>
1064
    -->
1065
    <answer id="resources-layer">
1066
        <p>
1067
            No.
1068
        </p>
1069
    </answer>
1070
1071
1072
1073
    <!--
1074
        <question id="resources-mask" when="final">
1075
            Does your module mask/hide/override any resources provided by other modules in
1076
            their layers?
1077
1078
                <hint>
1079
                If you mask a file provided by another module, you probably depend
1080
                on that and do not want the other module to (for example) change
1081
                the file's name. That module shall thus make that file available as an API
1082
                of some stability category.
1083
                </hint>
1084
            </question>
1085
    -->
1086
    <answer id="resources-mask">
1087
        <p>
1088
            No.
1089
        </p>
1090
    </answer>
1091
1092
1093
1094
    <!--
1095
            <question id="resources-preferences" when="final">
1096
                Does your module uses preferences via Preferences API? Does your module use NbPreferences or
1097
                or regular JDK Preferences ? Does it read, write or both ?
1098
                Does it share preferences with other modules ? If so, then why ?
1099
                <hint>
1100
                    You may use
1101
                        &lt;api type="export" group="preferences"
1102
                        name="preference node name" category="private"&gt;
1103
                        description of individual keys, where it is used, what it
1104
                        influences, whether the module reads/write it, etc.
1105
                        &lt;/api&gt;
1106
                    Due to XML ID restrictions, rather than /org/netbeans/modules/foo give the "name" as org.netbeans.modules.foo.
1107
                    Note that if you use NbPreferences this name will then be the same as the code name base of the module.
1108
                </hint>
1109
            </question>
1110
    -->
1111
    <answer id="resources-preferences">
1112
        <p>
1113
            No.
1114
        </p>
1115
    </answer>
1116
1117
1118
1119
    <!--
1120
        <question id="resources-read" when="final">
1121
            Does your module read any resources from layers? For what purpose?
1122
1123
                <hint>
1124
                As this is some kind of intermodule dependency, it is a kind of API.
1125
                Please describe it and classify according to
1126
                <a href="http://wiki.netbeans.org/API_Design#What_is_an_API.3F">
1127
                common stability categories</a>.
1128
                </hint>
1129
            </question>
1130
    -->
1131
    <answer id="resources-read">
1132
        <p>
1133
            No.
1134
        </p>
1135
    </answer>
1136
1137
1138
1139
    <!--
1140
            <question id="security-grant" when="final">
1141
                Does your code grant additional rights to some other code?
1142
                <hint>Avoid using a class loader that adds extra
1143
                permissions to loaded code unless really necessary.
1144
                Also note that your API implementation
1145
                can also expose unneeded permissions to enemy code by
1146
                calling AccessController.doPrivileged().</hint>
1147
            </question>
1148
    -->
1149
    <answer id="security-grant">
1150
        <p>
1151
            No.
1152
        </p>
1153
    </answer>
1154
1155
1156
1157
    <!--
1158
            <question id="security-policy" when="final">
1159
                Does your functionality require modifications to the standard policy file?
1160
                <hint>Your code might pass control to third-party code not
1161
                coming from trusted domains. This could be code downloaded over the
1162
                network or code coming from libraries that are not bundled
1163
                with NetBeans. Which permissions need to be granted to which domains?</hint>
1164
            </question>
1165
    -->
1166
    <answer id="security-policy">
1167
        <p>
1168
            No.
1169
        </p>
1170
    </answer>
1171
1172
</api-answers>
(-)a/api.io/build.xml (+5 lines)
Line 0 Link Here
1
<?xml version="1.0" encoding="UTF-8"?>
2
<project basedir="." default="netbeans" name="api.io">
3
    <description>Builds, tests, and runs the project org.netbeans.api.io</description>
4
    <import file="../nbbuild/templates/projectized.xml"/>
5
</project>
(-)a/api.io/manifest.mf (+6 lines)
Line 0 Link Here
1
Manifest-Version: 1.0
2
AutoUpdate-Show-In-Client: true
3
OpenIDE-Module: org.netbeans.api.io
4
OpenIDE-Module-Localizing-Bundle: org/netbeans/api/io/Bundle.properties
5
OpenIDE-Module-Specification-Version: 1.0
6
OpenIDE-Module-Needs: org.netbeans.spi.io.InputOutputProvider
(-)a/api.io/nbproject/project.properties (+4 lines)
Line 0 Link Here
1
is.autoload=true
2
javac.source=1.6
3
javac.compilerargs=-Xlint -Xlint:-serial
4
javadoc.arch=${basedir}/arch.xml
(-)a/api.io/nbproject/project.xml (+54 lines)
Line 0 Link Here
1
<?xml version="1.0" encoding="UTF-8"?>
2
<project xmlns="http://www.netbeans.org/ns/project/1">
3
    <type>org.netbeans.modules.apisupport.project</type>
4
    <configuration>
5
        <data xmlns="http://www.netbeans.org/ns/nb-module-project/3">
6
            <code-name-base>org.netbeans.api.io</code-name-base>
7
            <module-dependencies>
8
                <dependency>
9
                    <code-name-base>org.netbeans.api.annotations.common</code-name-base>
10
                    <build-prerequisite/>
11
                    <compile-dependency/>
12
                    <run-dependency>
13
                        <release-version>1</release-version>
14
                        <specification-version>1.25</specification-version>
15
                    </run-dependency>
16
                </dependency>
17
                <dependency>
18
                    <code-name-base>org.openide.util</code-name-base>
19
                    <build-prerequisite/>
20
                    <compile-dependency/>
21
                    <run-dependency>
22
                        <specification-version>9.3</specification-version>
23
                    </run-dependency>
24
                </dependency>
25
                <dependency>
26
                    <code-name-base>org.openide.util.lookup</code-name-base>
27
                    <build-prerequisite/>
28
                    <compile-dependency/>
29
                    <run-dependency>
30
                        <specification-version>8.26</specification-version>
31
                    </run-dependency>
32
                </dependency>
33
            </module-dependencies>
34
            <test-dependencies>
35
                <test-type>
36
                    <name>unit</name>
37
                    <test-dependency>
38
                        <code-name-base>org.netbeans.libs.junit4</code-name-base>
39
                        <compile-dependency/>
40
                    </test-dependency>
41
                    <test-dependency>
42
                        <code-name-base>org.netbeans.modules.nbjunit</code-name-base>
43
                        <compile-dependency/>
44
                    </test-dependency>
45
                </test-type>
46
            </test-dependencies>
47
            <public-packages>
48
                <package>org.netbeans.api.io</package>
49
                <package>org.netbeans.spi.io</package>
50
                <package>org.netbeans.spi.io.support</package>
51
            </public-packages>
52
        </data>
53
    </configuration>
54
</project>
(-)a/api.io/src/org/netbeans/api/io/Bundle.properties (+6 lines)
Line 0 Link Here
1
OpenIDE-Module-Display-Category=Infrastructure
2
OpenIDE-Module-Long-Description=\
3
    API classes for creating output panes (e.g. tabs in output window) and for writing data into them.\n\
4
    SPI for custom implementations of output window.
5
OpenIDE-Module-Name=I/O API and SPI
6
OpenIDE-Module-Short-Description=APIs and SPIs related to displaying output.
(-)a/api.io/src/org/netbeans/api/io/Fold.java (+131 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2014 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 2014 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.api.io;
43
44
import java.io.PrintWriter;
45
import org.netbeans.spi.io.InputOutputProvider;
46
47
/**
48
 * A fold (nested or standalone) in the output window.
49
 *
50
 * <p>
51
 * Methods of this class can be called in any thread.
52
 * </p>
53
 *
54
 * @author jhavlin
55
 */
56
public abstract class Fold {
57
58
    static final Fold UNSUPPORTED = new Fold() {
59
60
        @Override
61
        public void setExpanded(boolean expanded) {
62
        }
63
64
        @Override
65
        void endFold() {
66
        }
67
    };
68
69
    private Fold() {
70
    }
71
72
    static <IO, OW extends PrintWriter, P, F> Fold create(
73
            InputOutputProvider<IO, OW, P, F> provider, IO io, OW writer,
74
            F fold) {
75
        if (fold == null) {
76
            return UNSUPPORTED;
77
        } else {
78
            return new Impl<IO, OW, P, F>(provider, io, writer, fold);
79
        }
80
    }
81
82
    /**
83
     * Set fold expansion state.
84
     *
85
     * @param expanded True to expand the fold, false to collapse it.
86
     */
87
    public abstract void setExpanded(boolean expanded);
88
89
    abstract void endFold();
90
91
    /**
92
     * Expand the fold.
93
     */
94
    public final void expand() {
95
        setExpanded(true);
96
    }
97
98
    /**
99
     * Collapse the fold.
100
     */
101
    public final void collapse() {
102
        setExpanded(false);
103
    }
104
105
    private static class Impl<IO, OW extends PrintWriter, P, F> extends Fold {
106
107
        private final InputOutputProvider<IO, OW, P, F> provider;
108
        private final IO io;
109
        private final OW writer;
110
        private final F fold;
111
112
        public Impl(InputOutputProvider<IO, OW, P, F> provider, IO io,
113
                OW writer, F fold) {
114
115
            this.provider = provider;
116
            this.io = io;
117
            this.writer = writer;
118
            this.fold = fold;
119
        }
120
121
        @Override
122
        public void setExpanded(boolean expanded) {
123
            provider.setFoldExpanded(io, writer, fold, expanded);
124
        }
125
126
        @Override
127
        void endFold() {
128
            provider.endFold(io, writer, fold);
129
        }
130
    }
131
}
(-)a/api.io/src/org/netbeans/api/io/Hyperlink.java (+124 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2014 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 2014 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.api.io;
43
44
import org.netbeans.api.annotations.common.NonNull;
45
import org.netbeans.modules.io.HyperlinkAccessor;
46
import org.openide.util.Parameters;
47
48
/**
49
 * Hyperlink in output window. It can be specified by a {@link Runnable} to
50
 * invoke when the hyperlink is clicked.
51
 *
52
 * @author jhavlin
53
 */
54
public abstract class Hyperlink {
55
56
    private final boolean important;
57
58
    private Hyperlink(boolean important) {
59
        this.important = important;
60
    }
61
62
    static {
63
        HyperlinkAccessor.setDefault(new HyperlinkAccessorImpl());
64
    }
65
66
    /**
67
     * @return True if the hyperlink has been marked as important, false if it
68
     * is a standard link.
69
     */
70
    boolean isImportant() {
71
        return important;
72
    }
73
74
    /**
75
     * Create a new hyperlink for specified {@link Runnable}, which will be
76
     * invoked when the line is clicked.
77
     *
78
     * @param runnable The runnable to run on click.
79
     * @return The new hyperlink.
80
     */
81
    @NonNull
82
    public static Hyperlink from(@NonNull Runnable runnable) {
83
        return from(runnable, false);
84
    }
85
86
    /**
87
     * Create a new hyperlink for specified {@link Runnable}, which will be
88
     * invoked when the line is clicked.
89
     *
90
     * <div class="nonnormative">
91
     * <p>
92
     * Important hyperlinks can be printed in different color, or can have some
93
     * special behavior, e.g. automatic scrolling can be switched off to keep
94
     * the important hyperlink visible.
95
     * </p>
96
     * </div>
97
     *
98
     * @param runnable The runnable to run on click.
99
     * @param important True if the hyperlink should be handled as an important
100
     * one, false if it is a standard one.
101
     * @return The new hyperlink.
102
     */
103
    @NonNull
104
    public static Hyperlink from(@NonNull Runnable runnable,
105
            boolean important) {
106
        Parameters.notNull("runnable", runnable);
107
        return new OnClickHyperlink(runnable, important);
108
    }
109
110
    @SuppressWarnings("PackageVisibleInnerClass")
111
    static class OnClickHyperlink extends Hyperlink {
112
113
        private final Runnable runnable;
114
115
        public OnClickHyperlink(Runnable runnable, boolean important) {
116
            super(important);
117
            this.runnable = runnable;
118
        }
119
120
        public Runnable getRunnable() {
121
            return runnable;
122
        }
123
    }
124
}
(-)a/api.io/src/org/netbeans/api/io/HyperlinkAccessorImpl.java (+77 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2014 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 2014 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.api.io;
43
44
import org.netbeans.modules.io.HyperlinkAccessor;
45
import org.netbeans.modules.io.HyperlinkType;
46
47
/**
48
 * Implementation of accessor that enables retrieving information about
49
 * hyperlinks in SPI.
50
 *
51
 * @author jhavlin
52
 */
53
class HyperlinkAccessorImpl extends HyperlinkAccessor {
54
55
    @Override
56
    public HyperlinkType getType(Hyperlink hyperlink) {
57
        if (hyperlink instanceof Hyperlink.OnClickHyperlink) {
58
            return HyperlinkType.FROM_RUNNABLE;
59
        } else {
60
            throw new IllegalArgumentException("Unknown hyperlink.");   //NOI18N
61
        }
62
    }
63
64
    @Override
65
    public boolean isImportant(Hyperlink hyperlink) {
66
        return hyperlink.isImportant();
67
    }
68
69
    @Override
70
    public Runnable getRunnable(Hyperlink hyperlink) {
71
        if (hyperlink instanceof Hyperlink.OnClickHyperlink) {
72
            return ((Hyperlink.OnClickHyperlink) hyperlink).getRunnable();
73
        } else {
74
            throw new IllegalArgumentException("Not an ON_CLICK link.");//NOI18N
75
        }
76
    }
77
}
(-)a/api.io/src/org/netbeans/api/io/IOProvider.java (+365 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2014 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 2014 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.api.io;
43
44
import java.io.InputStreamReader;
45
import java.io.PrintWriter;
46
import java.io.Reader;
47
import java.lang.reflect.InvocationTargetException;
48
import java.lang.reflect.Method;
49
import java.util.Collection;
50
import java.util.Set;
51
import org.netbeans.api.annotations.common.NonNull;
52
import org.netbeans.spi.io.InputOutputProvider;
53
import org.openide.util.Lookup;
54
import org.openide.util.Parameters;
55
56
/**
57
 * A factory for IO tabs shown in the output window. To create a new tab to
58
 * write to, call e.g.
59
 * <code>IOProvider.getDefault().getIO("MyTab", false)</code> (pass true if
60
 * there may be an existing tab with the same name and you want to write to a
61
 * new tab).
62
 *
63
 * <p>
64
 * Methods of this class can be called in any thread.
65
 * </p>
66
 *
67
 * @author Jesse Glick, Jaroslav Havlin
68
 */
69
public abstract class IOProvider {
70
71
    private IOProvider() {
72
    }
73
74
    /**
75
     * Get the default I/O provider.
76
     * <p>
77
     * Normally this is taken from {@link Lookup#getDefault} but if there is no
78
     * instance in lookup, a fallback instance is created which just uses the
79
     * standard system I/O streams. This is useful for unit tests and perhaps
80
     * for standalone usage of various libraries.
81
     * </p>
82
     *
83
     * @return The default instance (never null).
84
     */
85
    @NonNull
86
    public static IOProvider getDefault() {
87
        InputOutputProvider<?, ?, ?, ?> def
88
                = Lookup.getDefault().lookup(InputOutputProvider.class);
89
        if (def != null) {
90
            return wrapProvider(def);
91
        } else {
92
            def = getBridgingDefault();
93
            if (def != null) {
94
                return wrapProvider(def);
95
            } else {
96
                return wrapProvider(new Trivial());
97
            }
98
        }
99
    }
100
101
    private static <IO, OW extends PrintWriter, P, F> IOProvider wrapProvider(
102
            InputOutputProvider<IO, OW, P, F> provider) {
103
104
        return new Impl<IO, OW, P, F>(provider);
105
    }
106
107
    /**
108
     * Get default provider implementing openide.io SPI and bridge it to api.io
109
     * SPI.
110
     */
111
    private static InputOutputProvider<?,?,?,?> getBridgingDefault() {
112
        return getBridging("getDefault", //NOI18N
113
                new Class<?>[0], new Object[0]);
114
    }
115
116
    /**
117
     * Get provider implementing openide.io SPI and bridge it to api.io SPI.
118
     *
119
     * @param name Name of the provider.
120
     */
121
    private static InputOutputProvider<?,?,?,?> getBridging(String name) {
122
        return getBridging("get", //NOI18N
123
                new Class<?>[]{String.class},
124
                new Object[]{name});
125
    }
126
127
    /**
128
     * Invoke method on getter of providers implementing openide.io SPI bridged
129
     * to api.io SPI.
130
     *
131
     * @param methodName Method to invoke on the getter.
132
     * @param paramTypes Parameters types of the method.
133
     * @param params Arguments to pass to the method.
134
     *
135
     * @return IOProvider bridged to InputOutputProvider returned from specified
136
     * getter's method, or null if not available or some problem occured.
137
     */
138
    private static InputOutputProvider<?,?,?,?> getBridging(String methodName,
139
            Class<?>[] paramTypes, Object[] params) {
140
141
        String className = "org.openide.io.BridgingGetter";             //NOI18N
142
        ClassLoader cl = Lookup.getDefault().lookup(ClassLoader.class);
143
        if (cl != null) {
144
            try {
145
                Class<? extends Object> c = Class.forName(className, true, cl);
146
                Object instance = c.newInstance();
147
                Method m = c.getDeclaredMethod(methodName, paramTypes);
148
                Object result = m.invoke(instance, params);
149
                if (result instanceof InputOutputProvider) {
150
                    return (InputOutputProvider) result;
151
                }
152
            } catch (ClassNotFoundException ex) {
153
            } catch (NoSuchMethodException ex) {
154
            } catch (SecurityException ex) {
155
            } catch (InstantiationException ex) {
156
            } catch (IllegalAccessException ex) {
157
            } catch (IllegalArgumentException ex) {
158
            } catch (InvocationTargetException ex) {
159
            }
160
        }
161
        return null;
162
    }
163
164
    /**
165
     * Gets IOProvider of selected name or delegates to getDefault() if none was
166
     * found.
167
     *
168
     * @param id ID of provider.
169
     * @return The instance corresponding to provided name or default instance
170
     * if not found.
171
     */
172
    @NonNull
173
    public static IOProvider get(@NonNull String id) {
174
        Parameters.notNull("id", id);
175
176
        @SuppressWarnings("rawtypes")
177
        Collection<? extends InputOutputProvider> providers
178
                = Lookup.getDefault().lookupAll(InputOutputProvider.class);
179
180
        for (InputOutputProvider<?, ?, ?, ?> p : providers) {
181
            if (p.getId().equals(id)) {
182
                return wrapProvider(p);
183
            }
184
        }
185
        InputOutputProvider<?,?,?,?> bridgingImpl = getBridging(id);
186
        if (bridgingImpl != null) {
187
            return wrapProvider(bridgingImpl);
188
        } else {
189
            return getDefault();
190
        }
191
    }
192
193
    /**
194
     * Gets identifier of this provider.
195
     *
196
     * @return Name of this provider.
197
     */
198
    @NonNull
199
    public abstract String getId();
200
201
    /**
202
     * Get a named instance of InputOutput, which represents an output tab in
203
     * the output window. Streams for reading/writing can be accessed via
204
     * getters on the returned instance.
205
     *
206
     * @param name A localised display name for the tab.
207
     * @param newIO If <tt>true</tt>, a new <code>InputOutput</code> is
208
     * returned, else an existing <code>InputOutput</code> of the same name may
209
     * be returned.
210
     * @return An <code>InputOutput</code> instance for accessing the new tab.
211
     * @see InputOutput
212
     */
213
    @NonNull
214
    public abstract InputOutput getIO(@NonNull String name, boolean newIO);
215
216
    /**
217
     * Get a named instance of InputOutput, which represents an output tab in
218
     * the output window. Streams for reading/writing can be accessed via
219
     * getters on the returned instance.
220
     *
221
     * @param name A localised display name for the tab.
222
     * @param newIO If <tt>true</tt>, a new <code>InputOutput</code> is
223
     * returned, else an existing <code>InputOutput</code> of the same name may
224
     * be returned.
225
     * @param lookup Lookup which may contain additional information for various
226
     * implementations of output window.
227
     * @return An <code>InputOutput</code> instance for accessing the new tab.
228
     * @see InputOutput
229
     */
230
    @NonNull
231
    public abstract InputOutput getIO(@NonNull String name, boolean newIO,
232
            @NonNull Lookup lookup);
233
234
    /**
235
     * Implementation of IOProvider that uses {@link InputOutputProvider} SPI
236
     * internally.
237
     *
238
     * @param <IO>
239
     * @param <OW>
240
     * @param <POS>
241
     */
242
    private static class Impl<IO, OW extends PrintWriter, P, F>
243
            extends IOProvider {
244
245
        private final InputOutputProvider<IO, OW, P, F> impl;
246
247
        public Impl(InputOutputProvider<IO, OW, P, F> impl) {
248
            this.impl = impl;
249
        }
250
251
        @Override
252
        public String getId() {
253
            return impl.getId();
254
        }
255
256
        @Override
257
        public InputOutput getIO(String name, boolean newIO) {
258
            return getIO(name, newIO, Lookup.EMPTY);
259
        }
260
261
        @Override
262
        public InputOutput getIO(String name, boolean newIO, Lookup lookup) {
263
            Parameters.notNull("name", name);
264
            Parameters.notNull("lookup", lookup);
265
            return InputOutput.create(impl, impl.getIO(name, newIO, lookup));
266
        }
267
    }
268
269
    /**
270
     * Trivial implementation of {@link IOProvider} that uses system input,
271
     * output and error streams.
272
     */
273
    private static class Trivial
274
            implements InputOutputProvider<Object, PrintWriter, Void, Void> {
275
276
        @Override
277
        public String getId() {
278
            return "Trivial";
279
        }
280
281
        @Override
282
        public Object getIO(String name, boolean newIO, Lookup lookup) {
283
            return this;
284
        }
285
286
        @Override
287
        public Reader getIn(Object io) {
288
            return new InputStreamReader(System.in);
289
        }
290
291
        @Override
292
        public PrintWriter getOut(Object io) {
293
            return new PrintWriter(System.out);
294
        }
295
296
        @Override
297
        public PrintWriter getErr(Object io) {
298
            return new PrintWriter(System.err);
299
        }
300
301
        @Override
302
        public void print(Object io, PrintWriter writer, String text,
303
                Hyperlink link, OutputColor color, boolean printLineEnd) {
304
            writer.print(text);
305
            if (printLineEnd) {
306
                writer.println();
307
            }
308
        }
309
310
        @Override
311
        public Lookup getIOLookup(Object io) {
312
            return Lookup.EMPTY;
313
        }
314
315
        @Override
316
        public void resetIO(Object io) {
317
        }
318
319
        @Override
320
        public void showIO(Object io,
321
                Set<ShowOperation> operations) {
322
        }
323
324
        @Override
325
        public void closeIO(Object io) {
326
        }
327
328
        @Override
329
        public boolean isIOClosed(Object io) {
330
            return false;
331
        }
332
333
        @Override
334
        public Void getCurrentPosition(Object io, PrintWriter writer) {
335
            return null;
336
        }
337
338
        @Override
339
        public void scrollTo(Object io, PrintWriter writer, Void position) {
340
        }
341
342
        @Override
343
        public Void startFold(Object io, PrintWriter writer, boolean expanded) {
344
            return null;
345
        }
346
347
        @Override
348
        public void endFold(Object io, PrintWriter writer, Void fold) {
349
        }
350
351
        @Override
352
        public void setFoldExpanded(Object io, PrintWriter writer, Void fold,
353
                boolean expanded) {
354
        }
355
356
        @Override
357
        public String getIODescription(Object io) {
358
            return null;
359
        }
360
361
        @Override
362
        public void setIODescription(Object io, String description) {
363
        }
364
    }
365
}
(-)a/api.io/src/org/netbeans/api/io/InputOutput.java (+314 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2014 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 2014 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.api.io;
43
44
import java.io.PrintWriter;
45
import java.io.Reader;
46
import java.util.Collections;
47
import java.util.EnumSet;
48
import java.util.Map;
49
import java.util.Set;
50
import java.util.WeakHashMap;
51
import org.netbeans.api.annotations.common.CheckForNull;
52
import org.netbeans.api.annotations.common.NonNull;
53
import org.netbeans.api.annotations.common.NullAllowed;
54
import org.netbeans.spi.io.InputOutputProvider;
55
import org.openide.util.Lookup;
56
57
/**
58
 * An I/O connection to one tab on the Output Window. To acquire an instance to
59
 * write to, call, e.g.,
60
 * <code>IOProvider.getDefault().getInputOutput("someName", false)</code>. To
61
 * get actual streams to write to, call <code>getOut()</code> or <code>
62
 * getErr()</code> on the returned instance.
63
 * <p>
64
 * Generally it is preferable not to hold a reference to an instance of
65
 * {@link org.netbeans.api.io.InputOutput}, but rather to fetch it by name from
66
 * {@link org.netbeans.api.io.IOProvider} as needed.
67
 * </p>
68
 *
69
 * <p>
70
 * Methods of this class can be called in any thread.
71
 * </p>
72
 *
73
 * @see OutputWriter
74
 * @author Ian Formanek, Jaroslav Tulach, Petr Hamernik, Ales Novak, Jan
75
 * Jancura, Jaroslav Havlin
76
 */
77
public abstract class InputOutput implements Lookup.Provider {
78
79
    private static final Set<ShowOperation> DEFAULT_SHOW_OPERATIONS
80
            = EnumSet.of(ShowOperation.OPEN, ShowOperation.MAKE_VISIBLE);
81
82
    private InputOutput() {
83
    }
84
85
    /**
86
     * Get a named instance of InputOutput from the default {@link IOProvider},
87
     * which represents an output tab in the output window. Streams for
88
     * reading/writing can be accessed via getters on the returned instance.
89
     *
90
     * <p>
91
     * This is a shorthand for {@code IOProvider.getDefault().getIO(...)}.
92
     * </p>
93
     *
94
     * @param name A localised display name for the tab.
95
     * @param newIO If <tt>true</tt>, a new <code>InputOutput</code> is
96
     * returned, else an existing <code>InputOutput</code> of the same name may
97
     * be returned.
98
     * @return An <code>InputOutput</code> instance for accessing the new tab.
99
     * @see IOProvider
100
     */
101
    @NonNull
102
    public static InputOutput get(@NonNull String name, boolean newIO) {
103
        return IOProvider.getDefault().getIO(name, newIO);
104
    }
105
106
     /**
107
     * Get a named instance of InputOutput from the default {@link IOProvider},
108
     * which represents an output tab in the output window. Streams for
109
     * reading/writing can be accessed via getters on the returned instance.
110
     *
111
     * <p>
112
     * This is a shorthand for {@code IOProvider.getDefault().getIO(...)}.
113
     * </p>
114
     *
115
     * @param name A localised display name for the tab.
116
     * @param newIO If <tt>true</tt>, a new <code>InputOutput</code> is
117
     * returned, else an existing <code>InputOutput</code> of the same name may
118
     * be returned.
119
     * @param lookup Lookup which may contain additional information for various
120
     * implementations of output window.
121
     * @return An <code>InputOutput</code> instance for accessing the new tab.
122
     * @see IOProvider
123
     */
124
    @NonNull
125
    public static InputOutput get(@NonNull String name, boolean newIO,
126
            @NonNull Lookup lookup) {
127
        return IOProvider.getDefault().getIO(name, newIO, lookup);
128
    }
129
130
    /**
131
     * Get a reader to read from the tab.
132
     *
133
     * @return The reader.
134
     */
135
    @NonNull
136
    public abstract Reader getIn();
137
138
    /**
139
     * Acquire an output writer to write to the tab.
140
     *
141
     * @return The writer.
142
     */
143
    @NonNull
144
    public abstract OutputWriter getOut();
145
146
    /**
147
     * Get an output writer to write to the tab in error mode. This might show
148
     * up in a different color than the regular output, e.g., or appear in a
149
     * separate pane.
150
     *
151
     * @return The writer.
152
     */
153
    @NonNull
154
    public abstract OutputWriter getErr();
155
156
    /**
157
     * Clear the output pane.
158
     */
159
    public abstract void reset();
160
161
    /**
162
     * Get lookup which may contain extensions provided by implementation of
163
     * output window.
164
     *
165
     * @return The lookup.
166
     */
167
    @NonNull
168
    @Override
169
    public abstract Lookup getLookup();
170
171
    /**
172
     * Closes this tab. The effect of calling any method on an instance of
173
     * InputOutput after calling <code>close()</code> on it is
174
     * undefined.
175
     */
176
    public abstract void close();
177
178
    /**
179
     * Test whether this tab has been closed, either by a call to
180
     * {@link #close()} or by the user closing the tab in the UI.
181
     *
182
     * @return Value <code>true</code> if it is closed.
183
     */
184
    public abstract boolean isClosed();
185
186
    /**
187
     * Get description of this I/O instance.
188
     *
189
     * @return The description, or null if not set.
190
     */
191
    @CheckForNull
192
    public abstract String getDescription();
193
194
    /**
195
     * Set description of this I/O instance. It can be used e.g. as tooltip for
196
     * output tab in the GUI.
197
     *
198
     * @param description The description, can be null.
199
     */
200
    public abstract void setDescription(@NullAllowed String description);
201
202
    static <IO, OW extends PrintWriter, P, F> InputOutput create(
203
            InputOutputProvider<IO, OW, P, F> provider, IO io) {
204
205
        return new Impl<IO, OW, P, F>(provider, io);
206
    }
207
208
    /**
209
     * Show this I/O if possible (e.g. in tabbed pane).
210
     * <p>
211
     * Calling this method is the same as calling:
212
     * </p>
213
     * <pre>
214
     * show(EnumSet.of(ShowOperation.OPEN, ShowOperation.MAKE_VISIBLE));
215
     * </pre>
216
     *
217
     * @see #show(java.util.Set)
218
     */
219
    public final void show() {
220
        show(DEFAULT_SHOW_OPERATIONS);
221
    }
222
223
    /**
224
     * Show this I/O if possible (e.g. in tabbed pane).
225
     *
226
     * @param operations Set of operations that should be invoked to show the
227
     * output. If the set is empty or null, pane for this I/O will be only
228
     * selected, but its component will not be opened or made visible. So it
229
     * will stay closed or hidden if it is not opened or not visible.
230
     *
231
     * @see ShowOperation
232
     */
233
    public abstract void show(@NullAllowed Set<ShowOperation> operations);
234
235
    private static class Impl<IO, OW extends PrintWriter, P, F>
236
            extends InputOutput {
237
238
        private final Map<OW, OutputWriter> cache
239
                = Collections.synchronizedMap(
240
                        new WeakHashMap<OW, OutputWriter>());
241
242
        private final InputOutputProvider<IO, OW, P, F> provider;
243
        private final IO ioObject;
244
245
        public Impl(InputOutputProvider<IO, OW, P, F> provider, IO ioObject) {
246
247
            this.provider = provider;
248
            this.ioObject = ioObject;
249
        }
250
251
        @Override
252
        public Reader getIn() {
253
            return provider.getIn(ioObject);
254
        }
255
256
        @Override
257
        public OutputWriter getOut() {
258
            return createOrGetCachedWrapper(provider.getOut(ioObject));
259
        }
260
261
        @Override
262
        public OutputWriter getErr() {
263
            return createOrGetCachedWrapper(provider.getErr(ioObject));
264
        }
265
266
        @Override
267
        @NonNull
268
        public Lookup getLookup() {
269
            return provider.getIOLookup(ioObject);
270
        }
271
272
        @Override
273
        public void reset() {
274
            provider.resetIO(ioObject);
275
        }
276
277
        private OutputWriter createOrGetCachedWrapper(OW pw) {
278
            OutputWriter ow = cache.get(pw);
279
            if (ow == null) {
280
                ow = OutputWriter.create(provider, ioObject, pw);
281
                cache.put(pw, ow);
282
            }
283
            return ow;
284
        }
285
286
        @Override
287
        public void close() {
288
            provider.closeIO(ioObject);
289
        }
290
291
        @Override
292
        public boolean isClosed() {
293
            return provider.isIOClosed(ioObject);
294
        }
295
296
        @Override
297
        public String getDescription() {
298
            return provider.getIODescription(ioObject);
299
        }
300
301
        @Override
302
        public void setDescription(String description) {
303
            provider.setIODescription(ioObject, description);
304
        }
305
306
        @Override
307
        public void show(Set<ShowOperation> operations) {
308
            provider.showIO(ioObject,
309
                    operations != null
310
                            ? operations
311
                            : Collections.<ShowOperation>emptySet());
312
        }
313
    }
314
}
(-)a/api.io/src/org/netbeans/api/io/OutputColor.java (+198 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2014 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 2014 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.api.io;
43
44
import org.netbeans.spi.io.support.OutputColorType;
45
import org.netbeans.api.annotations.common.NonNull;
46
import org.netbeans.modules.io.OutputColorAccessor;
47
48
/**
49
 * A color specified for part of text in output pane. It can be a predefined
50
 * color for some type of text (success, debug, warning, failure), or arbitrary
51
 * RGB color.
52
 * <p>
53
 * Although using wide range of custom RGB colors may be tempting, predefined
54
 * colors are recommended, as they can be configured to respect GUI theme in
55
 * use.
56
 * </p>
57
 *
58
 * @author jhavlin
59
 */
60
public abstract class OutputColor {
61
62
63
    private final OutputColorType type;
64
    private static final OutputColor CLR_WARNING = new TypeColor(OutputColorType.WARNING);
65
    private static final OutputColor CLR_FAILURE = new TypeColor(OutputColorType.FAILURE);
66
    private static final OutputColor CLR_DEBUG = new TypeColor(OutputColorType.DEBUG);
67
    private static final OutputColor CLR_SUCCESS = new TypeColor(OutputColorType.SUCCESS);
68
69
    static {
70
        OutputColorAccessor.setDefault(new OutputColorAccessorImpl());
71
    }
72
73
    private OutputColor(OutputColorType type) {
74
        this.type = type;
75
    }
76
77
    OutputColorType getType() {
78
        return type;
79
    }
80
81
    /**
82
     * Warning text color.
83
     *
84
     * @return Predefined color for text of type "warning".
85
     */
86
    @NonNull
87
    public static OutputColor warning() {
88
        return CLR_WARNING;
89
    }
90
91
    /**
92
     * Failure text color.
93
     *
94
     * @return Predefined color for text of type "failure".
95
     */
96
    @NonNull
97
    public static OutputColor failure() {
98
        return CLR_FAILURE;
99
    }
100
101
    /**
102
     * Debug text color.
103
     *
104
     * @return Predefined color for text of type "debug".
105
     */
106
    @NonNull
107
    public static OutputColor debug() {
108
        return CLR_DEBUG;
109
    }
110
111
    /**
112
     * Success text color.
113
     *
114
     * @return Predefined color for text of type "success".
115
     */
116
    @NonNull
117
    public static OutputColor success() {
118
        return CLR_SUCCESS;
119
    }
120
121
    /**
122
     * Arbitrary constant RGB color.
123
     *
124
     * <p>
125
     * Please note that it is recommended to use colors for predefined text
126
     * types, which can respect color theme used by the GUI.
127
     * </p>
128
     *
129
     * @param r The red component, in the range (0 - 255).
130
     * @param g The green component, in the range (0 - 255).
131
     * @param b The blue component, in the range (0 - 255).
132
     *
133
     * @return Color specified for a constant RGB value.
134
     * @throws IllegalArgumentException If some of color components is out of
135
     * range.
136
     */
137
    @NonNull
138
    public static OutputColor rgb(int r, int g, int b) {
139
        checkColorComponentRange("r", r);
140
        checkColorComponentRange("g", g);
141
        checkColorComponentRange("b", b);
142
        int value = ((r & 0xFF) << 16)
143
                | ((g & 0xFF) << 8)
144
                | ((b & 0xFF));
145
        return rgb(value);
146
    }
147
148
    /**
149
     * Arbitrary constant RGB color. Creates an opaque sRGB color with the
150
     * specified combined RGB value consisting of the red component in bits
151
     * 16-23, the green component in bits 8-15, and the blue component in bits
152
     * 0-7.
153
     *
154
     * <p>
155
     * Please note that it is recommended to use colors for predefined text
156
     * types, which can respect color theme used by the GUI.
157
     * </p>
158
     *
159
     * @param rgbValue The combined RGB components.
160
     *
161
     * @return Color specified for a constant RGB value.
162
     */
163
    @NonNull
164
    public static OutputColor rgb(int rgbValue) {
165
        return new RgbColor(rgbValue);
166
    }
167
168
    private static void checkColorComponentRange(String name,
169
            int colorComponent) {
170
171
        if (colorComponent < 0 || colorComponent > 255) {
172
            throw new IllegalArgumentException("Color component " + name//NOI18N
173
                    + " is out of range (0 - 255): " + colorComponent); //NOI18N
174
        }
175
    }
176
177
    private static class TypeColor extends OutputColor {
178
179
        public TypeColor(OutputColorType type) {
180
            super(type);
181
        }
182
    }
183
184
    @SuppressWarnings("PackageVisibleInnerClass")
185
    static class RgbColor extends OutputColor {
186
187
        private final int value;
188
189
        public RgbColor(int value) {
190
            super(OutputColorType.RGB);
191
            this.value = value;
192
        }
193
194
        public int getRGB() {
195
            return value;
196
        }
197
    }
198
}
(-)a/api.io/src/org/netbeans/api/io/OutputColorAccessorImpl.java (+68 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2014 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 2014 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.api.io;
43
44
import org.netbeans.modules.io.OutputColorAccessor;
45
import org.netbeans.spi.io.support.OutputColorType;
46
47
/**
48
 * Implementation of accessor that enables retrieving information about output
49
 * colors in SPI.
50
 *
51
 * @author jhavlin
52
 */
53
class OutputColorAccessorImpl extends OutputColorAccessor{
54
55
    @Override
56
    public OutputColorType getType(OutputColor color) {
57
        return color.getType();
58
    }
59
60
    @Override
61
    public int getRgb(OutputColor color) {
62
        if (color instanceof OutputColor.RgbColor) {
63
            return ((OutputColor.RgbColor) color).getRGB();
64
        } else {
65
            throw new IllegalArgumentException("Not an RGB color.");    //NOI18N
66
        }
67
    }
68
}
(-)a/api.io/src/org/netbeans/api/io/OutputWriter.java (+366 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2014 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 2014 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.api.io;
43
44
import java.io.IOException;
45
import java.io.PrintWriter;
46
import java.io.Writer;
47
import java.util.Collections;
48
import java.util.EnumSet;
49
import java.util.Locale;
50
import java.util.Set;
51
import org.netbeans.api.annotations.common.NullAllowed;
52
import org.netbeans.spi.io.InputOutputProvider;
53
54
/**
55
 * Extended {@link PrintWriter} for writing into output window or similar output
56
 * GUI component. It can support features like color printing, hyperlinks, or
57
 * folding.
58
 *
59
 * <p>
60
 * Methods of this class can be called in any thread.
61
 * </p>
62
 *
63
 * @author jhavlin
64
 */
65
public abstract class OutputWriter extends PrintWriter {
66
67
    private OutputWriter() {
68
        super(new DummyWriter());
69
    }
70
71
    /**
72
     * Get current position in the output stream.
73
     *
74
     * @return The position.
75
     */
76
    public abstract Position getCurrentPosition();
77
78
    /**
79
     * Start a new fold. If a fold already exists, a nested fold will be
80
     * created.
81
     *
82
     * @param expanded True if the fold should be expanded by default, false if
83
     * it should be collapsed.
84
     *
85
     * @return The fold handle.
86
     */
87
    public abstract Fold startFold(boolean expanded);
88
89
    /**
90
     * Finish a fold. If it contains some unfinished nested folds, they will be
91
     * finished as well.
92
     *
93
     * @param fold The fold to finish.
94
     */
95
    public abstract void endFold(Fold fold);
96
97
    public abstract void print(String s, Hyperlink link, OutputColor color);
98
99
    public abstract void print(String s, Hyperlink link);
100
101
    public abstract void print(String s, OutputColor color);
102
103
    public abstract void println(String s, Hyperlink link, OutputColor color);
104
105
    public abstract void println(String s, Hyperlink link);
106
107
    public abstract void println(String s, OutputColor color);
108
109
    static <IO, OW extends PrintWriter, P, F> OutputWriter create(
110
            InputOutputProvider<IO, OW, P, F> provider, IO io, OW writer) {
111
112
        return new Impl<IO, OW, P, F>(provider, io, writer);
113
    }
114
115
    private static class Impl<IO, OW extends PrintWriter, P, F>
116
            extends OutputWriter {
117
118
        private final InputOutputProvider<IO, OW, P, F> provider;
119
        private final IO io;
120
        private final OW writer;
121
122
        public Impl(InputOutputProvider<IO, OW, P, F> provider,
123
                IO io, OW writer) {
124
125
            this.provider = provider;
126
            this.io = io;
127
            this.writer = writer;
128
        }
129
130
        @Override
131
        public Position getCurrentPosition() {
132
            return Position.create(provider, io, writer,
133
                    provider.getCurrentPosition(io, writer));
134
        }
135
136
        @Override
137
        public void print(String s, Hyperlink link, OutputColor color) {
138
            provider.print(io, writer, s, link, color, false);
139
        }
140
141
        @Override
142
        public void print(String s, Hyperlink link) {
143
            provider.print(io, writer, s, link, null, false);
144
        }
145
146
        @Override
147
        public void print(String s, OutputColor color) {
148
            provider.print(io, writer, s, null, color, false);
149
        }
150
151
        @Override
152
        public void println(String s, Hyperlink link, OutputColor color) {
153
            provider.print(io, writer, s, link, color, true);
154
        }
155
156
        @Override
157
        public void println(String s, Hyperlink link) {
158
            provider.print(io, writer, s, link, null, true);
159
        }
160
161
        @Override
162
        public void println(String s, OutputColor color) {
163
            provider.print(io, writer, s, null, color, true);
164
        }
165
166
        @Override
167
        public void flush() {
168
            writer.flush();
169
        }
170
171
        @Override
172
        public void close() {
173
            writer.close();
174
        }
175
176
        @Override
177
        public boolean checkError() {
178
            return writer.checkError();
179
        }
180
181
        @Override
182
        public void write(int c) {
183
            writer.write(c);
184
        }
185
186
        @Override
187
        public void write(char[] buf, int off, int len) {
188
            writer.write(buf, off, len);
189
        }
190
191
        @Override
192
        public void write(char[] buf) {
193
            writer.write(buf);
194
        }
195
196
        @Override
197
        public void write(String s, int off, int len) {
198
            writer.write(s, off, len);
199
        }
200
201
        @Override
202
        public void write(String s) {
203
            writer.write(s);
204
        }
205
206
        @Override
207
        public void print(boolean b) {
208
            writer.print(b);
209
        }
210
211
        @Override
212
        public void print(char c) {
213
            writer.print(c);
214
        }
215
216
        @Override
217
        public void print(int i) {
218
            writer.print(i);
219
        }
220
221
        @Override
222
        public void print(long l) {
223
            writer.print(l);
224
        }
225
226
        @Override
227
        public void print(float f) {
228
            writer.print(f);
229
        }
230
231
        @Override
232
        public void print(double d) {
233
            writer.print(d);
234
        }
235
236
        @Override
237
        @SuppressWarnings("ImplicitArrayToString")
238
        public void print(char[] s) {
239
            writer.print(s);
240
        }
241
242
        @Override
243
        public void print(String s) {
244
            writer.print(s);
245
        }
246
247
        @Override
248
        public void print(Object obj) {
249
            writer.print(obj);
250
        }
251
252
        @Override
253
        public void println() {
254
            writer.println();
255
        }
256
257
        @Override
258
        public void println(boolean x) {
259
            writer.println(x);
260
        }
261
262
        @Override
263
        public void println(char x) {
264
            writer.println(x);
265
        }
266
267
        @Override
268
        public void println(int x) {
269
            writer.println(x);
270
        }
271
272
        @Override
273
        public void println(long x) {
274
            writer.println(x);
275
        }
276
277
        @Override
278
        public void println(float x) {
279
            writer.println(x);
280
        }
281
282
        @Override
283
        public void println(double x) {
284
            writer.println(x);
285
        }
286
287
        @Override
288
        @SuppressWarnings("ImplicitArrayToString")
289
        public void println(char[] x) {
290
            writer.println(x);
291
        }
292
293
        @Override
294
        public void println(String x) {
295
            writer.println(x);
296
        }
297
298
        @Override
299
        public void println(Object x) {
300
            writer.println(x);
301
        }
302
303
        @Override
304
        public PrintWriter printf(String format, Object... args) {
305
            return writer.printf(format, args);
306
        }
307
308
        @Override
309
        public PrintWriter printf(Locale l, String format, Object... args) {
310
            return writer.printf(l, format, args);
311
        }
312
313
        @Override
314
        public PrintWriter format(String format, Object... args) {
315
            return writer.format(format, args);
316
        }
317
318
        @Override
319
        public PrintWriter format(Locale l, String format, Object... args) {
320
            return writer.format(l, format, args);
321
        }
322
323
        @Override
324
        public PrintWriter append(CharSequence csq) {
325
            return writer.append(csq);
326
        }
327
328
        @Override
329
        public PrintWriter append(CharSequence csq, int start, int end) {
330
            return writer.append(csq, start, end);
331
        }
332
333
        @Override
334
        public PrintWriter append(char c) {
335
            return writer.append(c);
336
        }
337
338
        @Override
339
        public Fold startFold(boolean expanded) {
340
            F fold = provider.startFold(io, writer, expanded);
341
            return Fold.create(provider, io, writer, fold);
342
        }
343
344
        @Override
345
        public void endFold(Fold fold) {
346
            if (fold != Fold.UNSUPPORTED) {
347
                fold.endFold();
348
            }
349
        }
350
    }
351
352
    private static class DummyWriter extends Writer {
353
354
        @Override
355
        public void write(char[] cbuf, int off, int len) throws IOException {
356
        }
357
358
        @Override
359
        public void flush() throws IOException {
360
        }
361
362
        @Override
363
        public void close() throws IOException {
364
        }
365
    }
366
}
(-)a/api.io/src/org/netbeans/api/io/Position.java (+106 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2014 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 2014 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.api.io;
43
44
import java.io.PrintWriter;
45
import org.netbeans.spi.io.InputOutputProvider;
46
47
/**
48
 *
49
 * Stored position in the output window.
50
 *
51
 * <p>
52
 * Methods of this class can be called in any thread.
53
 * </p>
54
 *
55
 * @author jhavlin
56
 */
57
public abstract class Position {
58
59
    static final Position UNSUPPORTED = new Position() {
60
61
        @Override
62
        public void scrollTo() {
63
        }
64
    };
65
66
    private Position() {
67
    }
68
69
    /**
70
     * Scroll to this position.
71
     */
72
    public abstract void scrollTo();
73
74
    static <IO, OW extends PrintWriter, P, F> Position create(
75
            InputOutputProvider<IO, OW, P, F> provider, IO io,
76
            OW writer, P position) {
77
78
        if (position == null) {
79
            return UNSUPPORTED;
80
        } else {
81
            return new Impl<IO, OW, P, F>(provider, io, writer, position);
82
        }
83
    }
84
85
    private static class Impl<IO, OW extends PrintWriter, P, F>
86
            extends Position {
87
88
        private final InputOutputProvider<IO, OW, P, F> provider;
89
        private final IO io;
90
        private final OW ow;
91
        private final P position;
92
93
        public Impl(InputOutputProvider<IO, OW, P, F> provider, IO io, OW ow,
94
                P position) {
95
            this.provider = provider;
96
            this.io = io;
97
            this.ow = ow;
98
            this.position = position;
99
        }
100
101
        @Override
102
        public void scrollTo() {
103
            provider.scrollTo(io, ow, position);
104
        }
105
    }
106
}
(-)a/api.io/src/org/netbeans/api/io/ShowOperation.java (+65 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2014 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 2014 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.api.io;
43
44
/**
45
 * Operations that should take part when showing a component. The actual
46
 * behavior depends on implementation (some features may be unsupported).
47
 *
48
 * @author jhavlin
49
 */
50
public enum ShowOperation {
51
    /**
52
     * Open the GUI component (Output Window) if it is closed.
53
     */
54
    OPEN,
55
    /**
56
     * Make the GUI component (Output Window) visible. E.g. show it if it is
57
     * minimized.
58
     */
59
    MAKE_VISIBLE,
60
    /**
61
     * Activate the GUI component (Output Window). E.g. highlight and possibly
62
     * focus it.
63
     */
64
    ACTIVATE
65
}
(-)a/api.io/src/org/netbeans/modules/io/HyperlinkAccessor.java (+85 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2014 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 2014 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.io;
43
44
import org.netbeans.api.io.Hyperlink;
45
46
/**
47
 *
48
 * @author jhavlin
49
 */
50
public abstract class HyperlinkAccessor {
51
52
    /**
53
     * The default implementation is set in static initializer of
54
     * {@link Hyperlink}.
55
     */
56
    private static HyperlinkAccessor DEFAULT;
57
58
    public static void setDefault(HyperlinkAccessor def) {
59
        HyperlinkAccessor.DEFAULT = def;
60
    }
61
62
    public static HyperlinkAccessor getDefault() {
63
        if (DEFAULT != null) {
64
            return DEFAULT;
65
        }
66
67
        // invokes static initializer of Item.class
68
        // that will assign value to the DEFAULT field above
69
        Class<Hyperlink> c = Hyperlink.class;
70
        try {
71
            Class.forName(c.getName(), true, c.getClassLoader());
72
        } catch (ClassNotFoundException ex) {
73
            assert false : ex;
74
        }
75
        assert DEFAULT != null :
76
                "The DEFAULT field must be initialized";                //NOI18N
77
        return DEFAULT;
78
    }
79
80
    public abstract HyperlinkType getType(Hyperlink hyperlink);
81
82
    public abstract boolean isImportant(Hyperlink hyperlink);
83
84
    public abstract Runnable getRunnable(Hyperlink hyperlink);
85
}
(-)a/api.io/src/org/netbeans/modules/io/HyperlinkType.java (+62 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2014 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 2014 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.io;
43
44
import org.netbeans.spi.io.support.Hyperlinks;
45
46
/**
47
 * Type of the hyperlink.
48
 * <p>
49
 * Note: New items may be added in the future.
50
 * </p>
51
 * <p>
52
 * Note: When more hyperlink types are added, this enum can be moved to package
53
 * org.netbeans.spi.io.support, and getType(), getRunnable() (for correct type)
54
 * methods can be added to {@link Hyperlinks} class. So that implementation can
55
 * work with specific hyperlink types differently. See bug 247404.
56
 * </p>
57
 *
58
 * @author jhavlin
59
 */
60
public enum HyperlinkType {
61
    FROM_RUNNABLE
62
}
(-)a/api.io/src/org/netbeans/modules/io/OutputColorAccessor.java (+84 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2014 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 2014 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.io;
43
44
import org.netbeans.api.io.OutputColor;
45
import org.netbeans.spi.io.support.OutputColorType;
46
47
/**
48
 *
49
 * @author jhavlin
50
 */
51
public abstract class OutputColorAccessor {
52
53
    /**
54
     * The default implementation is set in static initializer of
55
     * {@link OutputColor}.
56
     */
57
    private static OutputColorAccessor DEFAULT;
58
59
    public static void setDefault(OutputColorAccessor def) {
60
        OutputColorAccessor.DEFAULT = def;
61
    }
62
63
    public static OutputColorAccessor getDefault() {
64
        if (DEFAULT != null) {
65
            return DEFAULT;
66
        }
67
68
        // invokes static initializer of Item.class
69
        // that will assign value to the DEFAULT field above
70
        Class<OutputColor> c = OutputColor.class;
71
        try {
72
            Class.forName(c.getName(), true, c.getClassLoader());
73
        } catch (ClassNotFoundException ex) {
74
            assert false : ex;
75
        }
76
        assert DEFAULT != null :
77
                "The DEFAULT field must be initialized";                //NOI18N
78
        return DEFAULT;
79
    }
80
81
    public abstract OutputColorType getType(OutputColor color);
82
83
    public abstract int getRgb(OutputColor color);
84
}
(-)a/api.io/src/org/netbeans/spi/io/InputOutputProvider.java (+329 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2014 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 2014 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.spi.io;
43
44
import java.io.PrintWriter;
45
import java.io.Reader;
46
import java.util.Set;
47
import org.netbeans.api.annotations.common.CheckForNull;
48
import org.netbeans.api.annotations.common.NonNull;
49
import org.netbeans.api.annotations.common.NullAllowed;
50
import org.netbeans.api.io.Hyperlink;
51
import org.netbeans.api.io.InputOutput;
52
import org.netbeans.api.io.OutputColor;
53
import org.netbeans.api.io.ShowOperation;
54
import org.openide.util.Lookup;
55
import org.openide.util.lookup.ServiceProvider;
56
57
/**
58
 *
59
 * SPI for custom output window implementations.
60
 * <p>
61
 * Use {@link ServiceProvider} annotation for registration.
62
 * </p>
63
 *
64
 * <p>
65
 * Note: Methods of this interface can be called in any thread by the
66
 * infrastructure, so implementations should ensure proper synchronization.
67
 * </p>
68
 *
69
 * @author jhavlin
70
 *
71
 * @param <IO> Type of objects that will represent I/O instances (e.g. tabs in
72
 * output window).
73
 * @param <WRITER> Type of writers for standard and error streams.
74
 * @param <POS> Type of object that describes position of a character in the
75
 * output window. If the implementation does not support this type of
76
 * information, use {@link Void} here.
77
 * @param <FOLD> Type of object that describes a fold in output window. If the
78
 * implementation does not support this type of information, use {@link Void}
79
 * here.
80
 */
81
public interface InputOutputProvider<IO, WRITER extends PrintWriter, POS, FOLD> {
82
83
    /**
84
     * Get identifier of this provider.
85
     *
86
     * @return Name of this provider, never null.
87
     */
88
    @NonNull
89
    String getId();
90
91
    /**
92
     * Get or create an object that encapsulates state of a single I/O instance
93
     * (e.g. tab in output window).
94
     *
95
     * @param name Display name of the output pane.
96
     * @param newIO True to always create new I/O, false to return already
97
     * existing instance if available.
98
     * @param lookup Lookup with additional information.
99
     *
100
     * @return A single I/O instance, a newly created or already existing.
101
     * @see InputOutput
102
     */
103
    @NonNull
104
    IO getIO(@NonNull String name, boolean newIO, @NonNull Lookup lookup);
105
106
    /**
107
     * Get input of the passed I/O.
108
     *
109
     * @param io I/O instance.
110
     *
111
     * @return {@link Reader} Reader for the input entered in the output pane.
112
     */
113
    @NonNull
114
    Reader getIn(@NonNull IO io);
115
116
    /**
117
     * Get output stream of the passed I/O.
118
     *
119
     * @param io I/O instance.
120
     *
121
     * @return {@link PrintWriter} for the output stream.
122
     */
123
    @NonNull
124
    WRITER getOut(@NonNull IO io);
125
126
    /**
127
     * Get error stream of the passed I/O.
128
     *
129
     * @param io The I/O instance.
130
     *
131
     * @return {@link PrintWriter} for the error stream.
132
     */
133
    @NonNull
134
    WRITER getErr(@NonNull IO io);
135
136
    /**
137
     * Print enhanced text. It can represent a clickable hyperlink, and can be
138
     * assigned some color.
139
     *
140
     * <p>
141
     * If the implementation doesn't support this feature, this method should
142
     * call something like
143
     * {@code writer.print(text); if (printLineEnd) {writer.println();}}.
144
     * </p>
145
     *
146
     * @param io The I/O instance.
147
     * @param writer The Stream to write into.
148
     * @param text Text to print.
149
     * @param link Link which should be represented by the text, can be null for
150
     * standard text.
151
     * @param color Color of the text, can be null for the default color of the
152
     * stream.
153
     * @param printLineEnd True if new-line should be appended after printing
154
     * {code text}.
155
     */
156
    void print(@NonNull IO io, @NonNull WRITER writer, @NullAllowed String text,
157
            @NullAllowed Hyperlink link, @NullAllowed OutputColor color,
158
            boolean printLineEnd);
159
160
    /**
161
     * Get lookup of an I/O instance, which can contain various extensions and
162
     * additional info.
163
     *
164
     * @param io The I/O instance.
165
     *
166
     * @return The lookup, which can be empty, but never null.
167
     */
168
    @NonNull
169
    Lookup getIOLookup(@NonNull IO io);
170
171
    /**
172
     * Reset the I/O. Clear previously written data and prepare it for new data.
173
     * <p>
174
     * If the implementation doesn't support this feature, this method should do
175
     * nothing.
176
     * </p>
177
     *
178
     * @param io The I/O instance.
179
     */
180
    void resetIO(@NonNull IO io);
181
182
    /**
183
     * Show output pane for the passed I/O instance.
184
     * <p>
185
     * If the implementation doesn't support this feature, this method should do
186
     * nothing.
187
     * </p>
188
     *
189
     * @param io The I/O instance.
190
     * @param operations Operations that should be performed to show the output.
191
     * If the set is empty, the output pane (e.g. tab) can be selected, but no
192
     * GUI component should be shown or made visible if it is currently closed
193
     * or hidden.
194
     *
195
     * @see ShowOperation
196
     */
197
    void showIO(@NonNull IO io,
198
            Set<ShowOperation> operations);
199
200
    /**
201
     * Close the I/O, its output pane and release resources.
202
     *
203
     * @param io The I/O instance.
204
     *
205
     * @see #isIOClosed(java.lang.Object)
206
     */
207
    void closeIO(@NonNull IO io);
208
209
    /**
210
     * Check whether the I/O is closed.
211
     *
212
     * @param io The I/O instance.
213
     *
214
     * @return True if the I/O was closed, false otherwise.
215
     *
216
     * @see #closeIO(java.lang.Object)
217
     */
218
    boolean isIOClosed(@NonNull IO io);
219
220
    /**
221
     * Get current position.
222
     *
223
     * @param io The I/O instance.
224
     * @param writer Output or error writer. If the streams are merged, the
225
     * value can be ignored.
226
     *
227
     * @return The current position in the output pane. If this feature is not
228
     * supported, return null.
229
     */
230
    @CheckForNull
231
    POS getCurrentPosition(@NonNull IO io, @NonNull WRITER writer);
232
233
    /**
234
     * Scroll to a position.
235
     * <p>
236
     * If this feature is not supported
237
     * ({@link #getCurrentPosition(Object, PrintWriter)} returns null), this
238
     * method should do nothing, it will be never called.
239
     * </p>
240
     *
241
     * @param io The I/O instance.
242
     * @param writer Output or error writer. If the streams are merged, the
243
     * value can be ignored.
244
     * @param position The position to scroll to.
245
     *
246
     * @see #getCurrentPosition(java.lang.Object, java.io.PrintWriter)
247
     */
248
    void scrollTo(@NonNull IO io, @NonNull WRITER writer,
249
            @NonNull POS position);
250
251
    /**
252
     * Start fold at the current position. If a fold is already open, start a
253
     * new nested fold (but if a fold with the same start position already
254
     * exists, no nested fold will be created, and the same start position will
255
     * be returned).
256
     *
257
     * @param io The I/O instance.
258
     * @param writer Output or error writer. If the streams are merged, the
259
     * value can be ignored.
260
     * @param expanded True if the new fold should be expanded by default, false
261
     * if it should be collapsed.
262
     *
263
     * @return Object the fold. If the implementation doesn't support this
264
     * feature, return null.
265
     */
266
    @CheckForNull
267
    FOLD startFold(@NonNull IO io, @NonNull WRITER writer, boolean expanded);
268
269
    /**
270
     * Finish a fold specified by its start position. If some nested folds
271
     * exist, they will be finished as well if needed.
272
     *
273
     * <p>
274
     * If this feature is not supported
275
     * ({@link #startFold(Object, PrintWriter, boolean)} returns null), this
276
     * method should do nothing, it will be never called.
277
     * </p>
278
     *
279
     * @param io The I/O instance.
280
     * @param writer Output or error writer. If the streams are merged, the
281
     * value can be ignored.
282
     * @param fold The fold to finish.
283
     */
284
    void endFold(@NonNull IO io, @NonNull WRITER writer,
285
            @NonNull FOLD fold);
286
287
    /**
288
     * Expand or collapse a fold.
289
     *
290
     * <p>
291
     * If this feature is not supported
292
     * ({@link #startFold(Object, PrintWriter, boolean)} returns null), this
293
     * method should do nothing, it will be never called.
294
     * </p>
295
     *
296
     * @param io The I/O instance.
297
     * @param writer Output or error writer. If the streams are merged, the
298
     * value can be ignored.
299
     * @param fold The fold to finish.
300
     * @param expanded True to expand the fold, false to collapse the fold.
301
     */
302
    void setFoldExpanded(@NonNull IO io, @NonNull WRITER writer,
303
            FOLD fold, boolean expanded);
304
305
306
    /**
307
     * Get description of an I/O instance. It can be used e.g. as tooltip text
308
     * for the output tab.
309
     *
310
     * @param io The I/O instance.
311
     *
312
     * @return The description, or null if not set.
313
     */
314
    @CheckForNull String getIODescription(@NonNull IO io);
315
316
    /**
317
     * Set description of an I/O instance.
318
     *
319
     * <p>
320
     * If this feature is not supported, this method should do nothing.
321
     * </p>
322
     *
323
     * @param io The I/O instance.
324
     * @param description The description, can be null.
325
     *
326
     * @see #getIODescription(java.lang.Object)
327
     */
328
    void setIODescription(@NonNull IO io, @NullAllowed String description);
329
}
(-)a/api.io/src/org/netbeans/spi/io/support/Hyperlinks.java (+121 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2014 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 2014 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.spi.io.support;
43
44
import org.netbeans.modules.io.HyperlinkType;
45
import org.netbeans.api.annotations.common.NonNull;
46
import org.netbeans.api.io.Hyperlink;
47
import org.netbeans.modules.io.HyperlinkAccessor;
48
49
/**
50
 * Helper class for accessing information from {@link Hyperlink} objects.
51
 *
52
 * @author jhavlin
53
 */
54
public final class Hyperlinks {
55
56
    private Hyperlinks() {
57
    }
58
59
    /**
60
     * Get hyperlink type.
61
     *
62
     * @param hyperlink The hyperlink to get type of.
63
     * @return The type of the hyperlink.
64
     */
65
    @NonNull
66
    static HyperlinkType getType(@NonNull Hyperlink hyperlink) {
67
        return HyperlinkAccessor.getDefault().getType(hyperlink);
68
    }
69
70
    /**
71
     * Check whether a hyperlink is important.
72
     *
73
     * <div class="nonnormative">
74
     * <p>
75
     * Important hyperlinks can be printed in different color, or can have some
76
     * special behavior, e.g. automatic scrolling can be switched off to keep
77
     * the important hyperlink visible.
78
     * </p>
79
     * </div>
80
     *
81
     * @param hyperlink The hyperlink to check.
82
     *
83
     * @return True if the hyperlink has been marked as important, false if it
84
     * is a standard link.
85
     */
86
    public static boolean isImportant(@NonNull Hyperlink hyperlink) {
87
        return HyperlinkAccessor.getDefault().isImportant(hyperlink);
88
    }
89
90
    /**
91
     * Get runnable associated with a hyperlink of type
92
     * {@link HyperlinkType#FROM_RUNNABLE}.
93
     *
94
     * @param hyperlink The hyperlink to get runnable from.
95
     *
96
     * @return A runnable.
97
     * @throws IllegalArgumentException if type of the hyperlink is not
98
     * {@link HyperlinkType#FROM_RUNNABLE}.
99
     * @see #getType(org.netbeans.api.io.Hyperlink)
100
     * @see HyperlinkType
101
     */
102
    @NonNull
103
    static Runnable getRunnable(@NonNull Hyperlink hyperlink) {
104
        return HyperlinkAccessor.getDefault().getRunnable(hyperlink);
105
    }
106
107
    /**
108
     * Invoke appropriate action for the hyperlink.
109
     *
110
     * @param hyperlink Hyperlink to invoke.
111
     */
112
    public static void invoke(Hyperlink hyperlink) {
113
        switch (getType(hyperlink)) {
114
            case FROM_RUNNABLE:
115
                getRunnable(hyperlink).run();
116
                break;
117
            default:
118
                break;
119
        }
120
    }
121
}
(-)a/api.io/src/org/netbeans/spi/io/support/OutputColorType.java (+54 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2014 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 2014 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.spi.io.support;
43
44
/**
45
 * Type of the color - static (rgb) or dynamic.
46
 * <p>
47
 * Note: New items may be added in the future.
48
 * </p>
49
 *
50
 * @author jhavlin
51
 */
52
public enum OutputColorType {
53
    WARNING, FAILURE, DEBUG, SUCCESS, RGB
54
}
(-)a/api.io/src/org/netbeans/spi/io/support/OutputColors.java (+83 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2014 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 2014 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.spi.io.support;
43
44
import org.netbeans.api.annotations.common.NonNull;
45
import org.netbeans.api.io.OutputColor;
46
import org.netbeans.modules.io.OutputColorAccessor;
47
48
/**
49
 * Helper class for accessing information from {@link OutputColor} objects.
50
 *
51
 * @author jhavlin
52
 */
53
public final class OutputColors {
54
55
    private OutputColors() {
56
    }
57
58
    /**
59
     * Get type of a color.
60
     *
61
     * @param color The color to get type of.
62
     * @return Type of color.
63
     */
64
    @NonNull
65
    public static OutputColorType getType(@NonNull OutputColor color) {
66
        return OutputColorAccessor.getDefault().getType(color);
67
    }
68
69
    /**
70
     * Get RGB value for an {@link OutputColor} specified for a constant RGB
71
     * color (type {@link OutputColorType#RGB}).
72
     *
73
     * @param color The color to get RGB value for.
74
     *
75
     * @return RGB value of the color.
76
     * @throws IllegalArgumentException if the color is not of type
77
     * {@link OutputColorType#RGB}.
78
     */
79
    public static int getRGB(OutputColor color) {
80
        return OutputColorAccessor.getDefault().getRgb(color);
81
    }
82
83
}
(-)a/api.io/test/unit/src/org/netbeans/api/io/IOProviderTest.java (+286 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2014 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 2014 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.api.io;
43
44
import java.io.PrintWriter;
45
import java.io.Reader;
46
import java.io.StringReader;
47
import java.io.StringWriter;
48
import java.util.ArrayList;
49
import java.util.Set;
50
import org.junit.Test;
51
import static org.junit.Assert.*;
52
import org.netbeans.junit.MockServices;
53
import org.netbeans.spi.io.InputOutputProvider;
54
import org.openide.util.Lookup;
55
import org.openide.util.lookup.Lookups;
56
57
/**
58
 *
59
 * @author jhavlin
60
 */
61
public class IOProviderTest {
62
63
    public IOProviderTest() {
64
    }
65
66
    @Test
67
    public void useCase1() {
68
        InputOutput io = IOProvider.getDefault().getIO("UseCase1", true);
69
        io.getOut().println("This is a simple output");
70
        io.getOut().close();
71
    }
72
73
    @Test
74
    public void useCase2() {
75
        InputOutput io = IOProvider.getDefault().getIO("UseCase2", false);
76
        io.getOut().print("A line containing a ");
77
        io.getOut().print("hyperlink", Hyperlink.from(new Runnable() {
78
79
            @Override
80
            public void run() {
81
                // some action
82
            }
83
        }));
84
        io.getOut().println(" for a URI.");
85
        io.getOut().close();
86
    }
87
88
    @Test
89
    public void useCase3() {
90
        InputOutput io = IOProvider.getDefault().getIO("UseCase3", true);
91
        io.getOut().print("A line containing a ");
92
        io.getOut().print("hyperlink", Hyperlink.from(new Runnable() {
93
            @Override
94
            public void run() {
95
                System.gc();
96
            }
97
        }));
98
        io.getOut().println(" for invokation of custom code.");
99
        io.getOut().close();
100
    }
101
102
    @Test
103
    public void useCase4() {
104
        InputOutput io = IOProvider.getDefault().getIO("UseCase4", true);
105
        io.getOut().println("Let's print some info", OutputColor.debug());
106
        io.getOut().println("or warning with appropriate color",
107
                OutputColor.warning());
108
        io.getOut().println("Maybe also text with custom reddish color",
109
                OutputColor.rgb(255, 16, 16));
110
        io.getOut().close();
111
    }
112
113
    @Test
114
    public void useCase5() {
115
        InputOutput io = IOProvider.getDefault().getIO("UseCase5", true);
116
        io.getOut().println("Let's print some text");
117
        io.getErr().println("and reset the pane immediately.");
118
        io.reset();
119
        io.getOut().println("The pane is now empty and we can reuse it simply");
120
        io.getOut().close();
121
    }
122
123
    @Test
124
    public void testTrivialImplementationAlwaysAvailable() {
125
        assertEquals("Trivial", IOProvider.getDefault().getId());
126
        assertEquals("Trivial", IOProvider.get("Trivial").getId());
127
        assertEquals("Trivial", IOProvider.get("Another").getId());
128
    }
129
130
    @Test
131
    public void testGetFromLookup() {
132
        MockServices.setServices(MockInputOutputProvider.class);
133
        try {
134
            assertEquals("mock", IOProvider.getDefault().getId());
135
            assertEquals("mock", IOProvider.get("mock").getId());
136
            assertEquals("mock", IOProvider.get("wrong").getId());
137
        } finally {
138
            MockServices.setServices();
139
        }
140
    }
141
142
    @Test
143
    public void testAllMethodsAreDelegatedToSPI() {
144
        MockServices.setServices(MockInputOutputProvider.class);
145
        try {
146
            IOProvider.getDefault().getIO("test1", true);
147
            Lookup lkp = IOProvider.getDefault()
148
                    .getIO("test1", false, Lookup.EMPTY).getLookup();
149
            CalledMethodList list = lkp.lookup(CalledMethodList.class);
150
            assertEquals("getIO", list.get(0));
151
            assertEquals("getIO", list.get(1));
152
            assertEquals("getIOLookup", list.get(2));
153
            assertEquals(3, list.size());
154
        } finally {
155
            MockServices.setServices();
156
        }
157
    }
158
159
    @SuppressWarnings("PackageVisibleInnerClass")
160
    static class CalledMethodList extends ArrayList<String> {
161
    }
162
163
    @SuppressWarnings("PublicInnerClass")
164
    public static class MockInputOutputProvider implements
165
            InputOutputProvider<Object, PrintWriter, Object, Object> {
166
167
        private final CalledMethodList calledMethods = new CalledMethodList();
168
        private final StringWriter stringWriter = new StringWriter();
169
        private final Lookup lookup = Lookups.fixed(calledMethods, stringWriter);
170
171
        @Override
172
        public String getId() {
173
            return "mock";
174
        }
175
176
        @Override
177
        public Object getIO(String name, boolean newIO, Lookup lookup) {
178
            calledMethods.add("getIO");
179
            return new Object();
180
        }
181
182
        @Override
183
        public Reader getIn(Object io) {
184
            calledMethods.add("getIn");
185
            return new StringReader("");
186
        }
187
188
        @Override
189
        public PrintWriter getOut(Object io) {
190
            calledMethods.add("getOut");
191
            return new PrintWriter(stringWriter);
192
        }
193
194
        @Override
195
        public PrintWriter getErr(Object io) {
196
            calledMethods.add("getErr");
197
            return new PrintWriter(stringWriter);
198
        }
199
200
        @Override
201
        public void print(Object io, PrintWriter writer, String text,
202
                Hyperlink link, OutputColor color, boolean printLineEnd) {
203
            if (link != null || color != null) {
204
                stringWriter.append("<ext");
205
                stringWriter.append(color != null ? " color" : "");
206
                stringWriter.append(link != null ? " link" : "");
207
                stringWriter.append(">");
208
            }
209
            stringWriter.append(text);
210
            if (link != null || color != null) {
211
                stringWriter.append("</ext>");
212
            }
213
            calledMethods.add("print");
214
            if (printLineEnd) {
215
                stringWriter.append(System.getProperty("line.separator"));
216
            }
217
        }
218
219
        @Override
220
        public Lookup getIOLookup(Object io) {
221
            calledMethods.add("getIOLookup");
222
            return lookup;
223
        }
224
225
        @Override
226
        public void resetIO(Object io) {
227
            calledMethods.add("resetIO");
228
        }
229
230
        @Override
231
        public void showIO(Object io,
232
                Set<ShowOperation> operations) {
233
            calledMethods.add("showIO");
234
        }
235
236
        @Override
237
        public void closeIO(Object io) {
238
            calledMethods.add("closeIO");
239
        }
240
241
        @Override
242
        public boolean isIOClosed(Object io) {
243
            calledMethods.add("isIOClosed");
244
            return false;
245
        }
246
247
        @Override
248
        public Object getCurrentPosition(Object io, PrintWriter writer) {
249
            calledMethods.add("getCurrentPosition");
250
            return new Object();
251
        }
252
253
        @Override
254
        public void scrollTo(Object io, PrintWriter writer, Object position) {
255
            calledMethods.add("scrollTo");
256
        }
257
258
        @Override
259
        public Object startFold(Object io, PrintWriter writer, boolean expanded) {
260
            calledMethods.add("startFold");
261
            return new Object();
262
        }
263
264
        @Override
265
        public void endFold(Object io, PrintWriter writer, Object foldNumber) {
266
            calledMethods.add("endFold");
267
        }
268
269
        @Override
270
        public void setFoldExpanded(Object io, PrintWriter writer,
271
                Object foldNumber, boolean expanded) {
272
            calledMethods.add("setFoldExpanded");
273
        }
274
275
        @Override
276
        public String getIODescription(Object io) {
277
            calledMethods.add("getIODescription");
278
            return null;
279
        }
280
281
        @Override
282
        public void setIODescription(Object io, String description) {
283
            calledMethods.add("setIODescription");
284
        }
285
    }
286
}
(-)a/api.io/test/unit/src/org/netbeans/api/io/InputOutputTest.java (+91 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2014 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 2014 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.api.io;
43
44
import org.junit.Test;
45
import static org.junit.Assert.*;
46
import org.netbeans.junit.MockServices;
47
import org.openide.util.Lookup;
48
49
/**
50
 *
51
 * @author jhavlin
52
 */
53
public class InputOutputTest {
54
55
    public InputOutputTest() {
56
    }
57
58
    @Test
59
    @SuppressWarnings("ValueOfIncrementOrDecrementUsed")
60
    public void testAllMethodsAreDelegatedToSPI() {
61
        MockServices.setServices(IOProviderTest.MockInputOutputProvider.class);
62
        try {
63
            InputOutput io = IOProvider.getDefault().getIO("test1", true);
64
            io.getIn();
65
            io.getOut();
66
            io.getErr();
67
            io.reset();
68
            io.isClosed();
69
            io.close();
70
            io.getDescription();
71
            io.setDescription(null);
72
            Lookup lkp = io.getLookup();
73
            IOProviderTest.CalledMethodList list
74
                    = lkp.lookup(IOProviderTest.CalledMethodList.class);
75
76
            int order = 0;
77
            assertEquals("getIO", list.get(order++));
78
            assertEquals("getIn", list.get(order++));
79
            assertEquals("getOut", list.get(order++));
80
            assertEquals("getErr", list.get(order++));
81
            assertEquals("resetIO", list.get(order++));
82
            assertEquals("isIOClosed", list.get(order++));
83
            assertEquals("closeIO", list.get(order++));
84
            assertEquals("getIODescription", list.get(order++));
85
            assertEquals("setIODescription", list.get(order++));
86
            assertEquals("getIOLookup", list.get(order++));
87
        } finally {
88
            MockServices.setServices();
89
        }
90
    }
91
}
(-)a/api.io/test/unit/src/org/netbeans/api/io/OutputColorTest.java (+91 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2014 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 2014 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.api.io;
43
44
import org.netbeans.spi.io.support.OutputColorType;
45
import org.junit.Test;
46
import static org.junit.Assert.*;
47
import org.netbeans.spi.io.support.OutputColors;
48
49
/**
50
 *
51
 * @author jhavlin
52
 */
53
public class OutputColorTest {
54
55
    @Test
56
    public void testRgbColor() {
57
        OutputColor c = OutputColor.rgb(127, 255, 1);
58
        assertEquals(OutputColorType.RGB, OutputColors.getType(c));
59
        int value = OutputColors.getRGB(c);
60
        int r = value >> 16;
61
        int g = value >> 8 & 0xFF;
62
        int b = value & 0xFF;
63
        assertEquals(127, r);
64
        assertEquals(255, g);
65
        assertEquals(1, b);
66
    }
67
68
    @Test
69
    public void testWarningColor() {
70
        OutputColor c = OutputColor.warning();
71
        assertEquals(OutputColorType.WARNING, c.getType());
72
    }
73
74
    @Test
75
    public void testFailureColor() {
76
        OutputColor c = OutputColor.failure();
77
        assertEquals(OutputColorType.FAILURE, c.getType());
78
    }
79
80
    @Test
81
    public void testDebugColor() {
82
        OutputColor c = OutputColor.debug();
83
        assertEquals(OutputColorType.DEBUG, c.getType());
84
    }
85
86
    @Test
87
    public void testSuccessColor() {
88
        OutputColor c = OutputColor.success();
89
        assertEquals(OutputColorType.SUCCESS, c.getType());
90
    }
91
}
(-)a/api.io/test/unit/src/org/netbeans/api/io/OutputWriterTest.java (+134 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2014 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 2014 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.api.io;
43
44
import java.io.StringWriter;
45
import org.junit.Test;
46
import static org.junit.Assert.*;
47
import org.netbeans.junit.MockServices;
48
import org.openide.util.Lookup;
49
50
/**
51
 *
52
 * @author jhavlin
53
 */
54
public class OutputWriterTest {
55
56
    public OutputWriterTest() {
57
    }
58
59
    @Test
60
    @SuppressWarnings("ValueOfIncrementOrDecrementUsed")
61
    public void testAllMethodsAreDelegatedToSPI() {
62
        MockServices.setServices(IOProviderTest.MockInputOutputProvider.class);
63
        try {
64
65
            InputOutput io = IOProvider.getDefault().getIO("test1", true);
66
            OutputWriter ow = io.getOut();
67
            Lookup lkp = io.getLookup();
68
69
            IOProviderTest.CalledMethodList list
70
                    = lkp.lookup(IOProviderTest.CalledMethodList.class);
71
72
            io.show();
73
            Position p = ow.getCurrentPosition();
74
            p.scrollTo();
75
            Fold f = ow.startFold(true);
76
            f.expand();
77
            f.collapse();
78
            ow.endFold(f);
79
80
            int order = 0;
81
            assertEquals("getIO", list.get(order++));
82
            assertEquals("getOut", list.get(order++));
83
            assertEquals("getIOLookup", list.get(order++));
84
            assertEquals("showIO", list.get(order++));
85
            assertEquals("getCurrentPosition", list.get(order++));
86
            assertEquals("scrollTo", list.get(order++));
87
            assertEquals("startFold", list.get(order++));
88
            assertEquals("setFoldExpanded", list.get(order++));
89
            assertEquals("setFoldExpanded", list.get(order++));
90
            assertEquals("endFold", list.get(order++));
91
92
            ow.print("Line");
93
            ow.print(" 1");
94
            ow.println();
95
96
            Runnable runnable = new Runnable() {
97
98
                @Override
99
                public void run() {
100
                }
101
            };
102
103
            ow.print("Hyperlink ", Hyperlink.from(runnable));
104
            ow.print(" ");
105
            ow.print("Color", OutputColor.debug());
106
            ow.print(" ");
107
            ow.print("Color link", Hyperlink.from(runnable),
108
                    OutputColor.debug());
109
            ow.println();
110
111
            ow.println("Line with link", Hyperlink.from(runnable));
112
            ow.println("Color line", OutputColor.debug());
113
            ow.println("Color line with link",
114
                    Hyperlink.from(runnable), OutputColor.debug());
115
116
            StringWriter sw = lkp.lookup(StringWriter.class);
117
            sw.toString();
118
119
            String[] lines = sw.toString().split(
120
                    System.getProperty("line.separator"));
121
122
            assertEquals("Line 1", lines[0]);
123
            assertEquals("<ext link>Hyperlink </ext> <ext color>Color</ext> "
124
                    + "<ext color link>Color link</ext>", lines[1]);
125
            assertEquals("<ext link>Line with link</ext>", lines[2]);
126
            assertEquals("<ext color>Color line</ext>", lines[3]);
127
            assertEquals("<ext color link>Color line with link</ext>", lines[4]);
128
129
        } finally {
130
            MockServices.setServices();
131
        }
132
    }
133
134
}
(-)a/api.io/test/unit/src/org/netbeans/spi/io/support/HyperlinksTest.java (+82 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2014 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 2014 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.spi.io.support;
43
44
import static org.junit.Assert.*;
45
import org.junit.Test;
46
import org.netbeans.api.io.Hyperlink;
47
import org.netbeans.modules.io.HyperlinkType;
48
49
/**
50
 *
51
 * @author jhavlin
52
 */
53
public class HyperlinksTest {
54
55
    @Test
56
    public void testOnClickLink() {
57
58
        final boolean[] invoked = new boolean[1];
59
        Hyperlink h = Hyperlink.from(new Runnable() {
60
61
            @Override
62
            public void run() {
63
                invoked[0] = true;
64
            }
65
        });
66
        assertTrue(Hyperlinks.getType(h) == HyperlinkType.FROM_RUNNABLE);
67
        assertFalse(Hyperlinks.isImportant(h));
68
        assertNotNull(Hyperlinks.getRunnable(h));
69
        Hyperlinks.getRunnable(h).run();
70
        assertTrue("The passed code should be invoked", invoked[0]);
71
    }
72
73
    @Test
74
    public void testOnClickLinkImportant() {
75
        Hyperlink h = Hyperlink.from(new Runnable() {
76
            @Override
77
            public void run() {
78
            }
79
        }, true);
80
        assertTrue(Hyperlinks.isImportant(h));
81
    }
82
}
(-)a/core.output2/manifest.mf (-1 / +1 lines)
Lines 2-8 Link Here
2
OpenIDE-Module: org.netbeans.core.output2/1
2
OpenIDE-Module: org.netbeans.core.output2/1
3
OpenIDE-Module-Layer: org/netbeans/core/output2/layer.xml
3
OpenIDE-Module-Layer: org/netbeans/core/output2/layer.xml
4
OpenIDE-Module-Localizing-Bundle: org/netbeans/core/output2/Bundle.properties
4
OpenIDE-Module-Localizing-Bundle: org/netbeans/core/output2/Bundle.properties
5
OpenIDE-Module-Provides: org.openide.windows.IOProvider
5
OpenIDE-Module-Provides: org.openide.windows.IOProvider org.netbeans.spi.io.InputOutputProvider
6
AutoUpdate-Essential-Module: true
6
AutoUpdate-Essential-Module: true
7
OpenIDE-Module-Specification-Version: 1.39
7
OpenIDE-Module-Specification-Version: 1.39
8
8
(-)a/core.output2/nbproject/project.xml (-1 / +9 lines)
Lines 50-55 Link Here
50
            <code-name-base>org.netbeans.core.output2</code-name-base>
50
            <code-name-base>org.netbeans.core.output2</code-name-base>
51
            <module-dependencies>
51
            <module-dependencies>
52
                <dependency>
52
                <dependency>
53
                    <code-name-base>org.netbeans.api.io</code-name-base>
54
                    <build-prerequisite/>
55
                    <compile-dependency/>
56
                    <run-dependency>
57
                        <specification-version>1.0</specification-version>
58
                    </run-dependency>
59
                </dependency>
60
                <dependency>
53
                    <code-name-base>org.netbeans.modules.options.api</code-name-base>
61
                    <code-name-base>org.netbeans.modules.options.api</code-name-base>
54
                    <build-prerequisite/>
62
                    <build-prerequisite/>
55
                    <compile-dependency/>
63
                    <compile-dependency/>
Lines 111-117 Link Here
111
                    <build-prerequisite/>
119
                    <build-prerequisite/>
112
                    <compile-dependency/>
120
                    <compile-dependency/>
113
                    <run-dependency>
121
                    <run-dependency>
114
                        <specification-version>1.40</specification-version>
122
                        <specification-version>1.47</specification-version>
115
                    </run-dependency>
123
                    </run-dependency>
116
                </dependency>
124
                </dependency>
117
                <dependency>
125
                <dependency>
(-)a/core.output2/src/org/netbeans/core/output2/NbIO.java (-2 / +65 lines)
Lines 86-91 Link Here
86
    private Lookup lookup;
86
    private Lookup lookup;
87
    private IOTabImpl ioTab;
87
    private IOTabImpl ioTab;
88
    private IOColorsImpl ioColors;
88
    private IOColorsImpl ioColors;
89
    private IOFoldingImpl ioFolding;
89
    private IOFoldingImpl.NbIoFoldHandleDefinition currentFold = null;
90
    private IOFoldingImpl.NbIoFoldHandleDefinition currentFold = null;
90
91
91
    /** Creates a new instance of NbIO 
92
    /** Creates a new instance of NbIO 
Lines 321-333 Link Here
321
        return getIn();
322
        return getIn();
322
    }
323
    }
323
324
325
    public synchronized IOFoldingImpl getIoFolding() {
326
        if (ioFolding == null) {
327
            ioFolding = new IOFoldingImpl();
328
        }
329
        return ioFolding;
330
    }
331
332
    @Override
324
    public synchronized Lookup getLookup() {
333
    public synchronized Lookup getLookup() {
325
        if (lookup == null) {
334
        if (lookup == null) {
326
            ioTab = new IOTabImpl();
335
            ioTab = new IOTabImpl();
327
            ioColors = new IOColorsImpl();
336
            ioColors = new IOColorsImpl();
337
            ioFolding = getIoFolding();
328
            lookup = Lookups.fixed(ioTab, ioColors, new IOPositionImpl(),
338
            lookup = Lookups.fixed(ioTab, ioColors, new IOPositionImpl(),
329
                    new IOColorLinesImpl(), new IOColorPrintImpl(),
339
                    new IOColorLinesImpl(), new IOColorPrintImpl(),
330
                    new IOSelectImpl(), new IOFoldingImpl(), options);
340
                    new IOSelectImpl(), ioFolding, options);
331
        }
341
        }
332
        return lookup;
342
        return lookup;
333
    }
343
    }
Lines 481-486 Link Here
481
        return ioTab != null ? ioTab.getToolTipText() : null;
491
        return ioTab != null ? ioTab.getToolTipText() : null;
482
    }
492
    }
483
493
494
    void setTooltipText(String toolTip) {
495
        post(NbIO.this, IOEvent.CMD_SET_TOOLTIP, toolTip);
496
    }
497
484
    Color getColor(IOColors.OutputType type) {
498
    Color getColor(IOColors.OutputType type) {
485
        return ioColors != null ? ioColors.getColor(type) : AbstractLines.getDefColors()[type.ordinal()];
499
        return ioColors != null ? ioColors.getColor(type) : AbstractLines.getDefColors()[type.ordinal()];
486
    }
500
    }
Lines 508-514 Link Here
508
        @Override
522
        @Override
509
        protected void setToolTipText(String text) {
523
        protected void setToolTipText(String text) {
510
            toolTip = text;
524
            toolTip = text;
511
            post(NbIO.this, IOEvent.CMD_SET_TOOLTIP, toolTip);
525
            NbIO.this.setTooltipText(toolTip);
512
        }
526
        }
513
    }
527
    }
514
528
Lines 687-692 Link Here
687
                return ((AbstractLines) out().getLines());
701
                return ((AbstractLines) out().getLines());
688
            }
702
            }
689
        }
703
        }
704
705
        /**
706
         * Access to fold creation via org.netbeans.api.io API.
707
         *
708
         * @return The new fold handle definition.
709
         */
710
        private NbIoFoldHandleDefinition createFold(
711
                NbIoFoldHandleDefinition parent, int foldStartIndex,
712
                boolean expanded) {
713
714
            return new NbIoFoldHandleDefinition(parent, foldStartIndex,
715
                    expanded);
716
717
        }
690
    }
718
    }
691
719
692
    private int getLastLineNumber() {
720
    private int getLastLineNumber() {
Lines 707-710 Link Here
707
    OutputOptions getOptions() {
735
    OutputOptions getOptions() {
708
        return this.options;
736
        return this.options;
709
    }
737
    }
738
739
    @SuppressWarnings("AccessingNonPublicFieldOfAnotherObject")
740
    int startFold(boolean expanded) {
741
742
        synchronized (outOrException()) {
743
            int foldStartIndex = getLastLineNumber();
744
            if (currentFold != null && currentFold.start == foldStartIndex) {
745
                return foldStartIndex;
746
            } else {
747
                currentFold = getIoFolding().createFold(currentFold,
748
                        foldStartIndex, expanded);
749
                return foldStartIndex;
750
            }
751
        }
752
    }
753
754
    @SuppressWarnings("AccessingNonPublicFieldOfAnotherObject")
755
    void endFold(int foldStartIndex) {
756
        synchronized (outOrException()) {
757
            IOFoldingImpl.NbIoFoldHandleDefinition fold = currentFold;
758
            while (fold != null && fold.start != foldStartIndex) {
759
                fold = fold.parent;
760
            }
761
762
            if (fold != null) {
763
                IOFoldingImpl.NbIoFoldHandleDefinition nested = currentFold;
764
                while (nested != fold) {
765
                    nested.finish();
766
                    nested = nested.parent;
767
                }
768
                fold.finish();
769
                currentFold = fold.parent;
770
            }
771
        }
772
    }
710
}
773
}
(-)a/core.output2/src/org/netbeans/core/output2/NbIOProvider.java (-2 / +264 lines)
Lines 44-65 Link Here
44
44
45
package org.netbeans.core.output2;
45
package org.netbeans.core.output2;
46
46
47
import java.awt.Color;
47
import java.io.IOException;
48
import java.io.IOException;
49
import java.io.Reader;
50
import java.util.EnumSet;
51
import java.util.Set;
48
import java.util.WeakHashMap;
52
import java.util.WeakHashMap;
49
import javax.swing.Action;
53
import javax.swing.Action;
54
import org.netbeans.api.io.Hyperlink;
55
import org.netbeans.api.io.OutputColor;
56
import org.netbeans.api.io.ShowOperation;
57
import org.netbeans.spi.io.InputOutputProvider;
58
import org.netbeans.spi.io.support.Hyperlinks;
59
import org.netbeans.spi.io.support.OutputColorType;
60
import org.netbeans.spi.io.support.OutputColors;
50
import org.openide.util.Exceptions;
61
import org.openide.util.Exceptions;
62
import org.openide.util.Lookup;
51
import org.openide.util.NbBundle;
63
import org.openide.util.NbBundle;
64
import org.openide.util.lookup.ServiceProvider;
65
import org.openide.util.lookup.ServiceProviders;
66
import org.openide.windows.IOColors;
52
import org.openide.windows.IOContainer;
67
import org.openide.windows.IOContainer;
53
import org.openide.windows.IOProvider;
68
import org.openide.windows.IOProvider;
69
import org.openide.windows.IOSelect;
54
import org.openide.windows.InputOutput;
70
import org.openide.windows.InputOutput;
71
import org.openide.windows.OutputEvent;
72
import org.openide.windows.OutputListener;
55
import org.openide.windows.OutputWriter;
73
import org.openide.windows.OutputWriter;
56
74
57
/**
75
/**
58
 * Supplies Output Window implementation through Lookup.
76
 * Supplies Output Window implementation through Lookup.
59
 * @author Jesse Glick, Tim Boudreau
77
 * @author Jesse Glick, Tim Boudreau
60
 */
78
 */
61
@org.openide.util.lookup.ServiceProvider(service=org.openide.windows.IOProvider.class, position=100)
79
@ServiceProviders({
62
public final class NbIOProvider extends IOProvider {
80
    @ServiceProvider(service=IOProvider.class, position=100),
81
    @ServiceProvider(service=InputOutputProvider.class, position=100)
82
})
83
public final class NbIOProvider extends IOProvider implements
84
        InputOutputProvider<InputOutput, OutputWriter, Integer, Integer> {
85
63
    private static final WeakHashMap<IOContainer, PairMap> containerPairMaps =
86
    private static final WeakHashMap<IOContainer, PairMap> containerPairMaps =
64
            new WeakHashMap<IOContainer, PairMap>();
87
            new WeakHashMap<IOContainer, PairMap>();
65
88
Lines 93-98 Link Here
93
    }
116
    }
94
    
117
    
95
    
118
    
119
    @Override
96
    public InputOutput getIO(String name, boolean newIO) {
120
    public InputOutput getIO(String name, boolean newIO) {
97
        return getIO (name, newIO, new Action[0], null);
121
        return getIO (name, newIO, new Action[0], null);
98
    }
122
    }
Lines 156-160 Link Here
156
            }
180
            }
157
        }
181
        }
158
    }
182
    }
183
184
    @Override
185
    public String getId() {
186
        return getName();
187
    }
188
189
    @Override
190
    public InputOutput getIO(String name, boolean newIO, Lookup lookup) {
191
        Action[] actions = lookup.lookup(Action[].class);
192
        IOContainer container = lookup.lookup(IOContainer.class);
193
        return getIO(name, newIO,
194
                actions == null ? new Action[0] : actions,
195
                container);
196
    }
197
198
    @Override
199
    public Reader getIn(InputOutput io) {
200
        return io.getIn();
201
    }
202
203
    @Override
204
    public OutputWriter getOut(InputOutput io) {
205
        return io.getOut();
206
    }
207
208
    @Override
209
    public OutputWriter getErr(InputOutput io) {
210
        return io.getErr();
211
    }
212
213
    @Override
214
    public void print(InputOutput io, OutputWriter writer, String text,
215
            Hyperlink link, OutputColor outputColor, boolean printLineEnd) {
216
        Color awtColor = outputColorToAwtColor(io, outputColor);
217
        OutputListener listener = hyperlinkToOutputListener(link);
218
        boolean listenerImportant = link != null && Hyperlinks.isImportant(link);
219
        if (io instanceof NbIO) {
220
            OutWriter out = ((NbIO) io).out();
221
            if (out != null) {
222
                out.print(text, listener, listenerImportant, awtColor, null,
223
                        OutputKind.OUT, printLineEnd);
224
            }
225
        } else {
226
            throw new IllegalArgumentException();
227
        }
228
    }
229
230
    @Override
231
    public Lookup getIOLookup(InputOutput io) {
232
        if (io instanceof NbIO) {
233
            return ((NbIO) io).getLookup();
234
        } else {
235
            throw new IllegalArgumentException();
236
        }
237
    }
238
239
    @Override
240
    public void resetIO(InputOutput io) {
241
        if (io instanceof NbIO) {
242
            ((NbIO) io).reset();
243
        } else {
244
            throw new IllegalArgumentException();
245
        }
246
    }
247
248
    @Override
249
    public void showIO(InputOutput io, Set<ShowOperation> operations) {
250
          if (operations.contains(ShowOperation.OPEN)
251
                && operations.contains(ShowOperation.MAKE_VISIBLE)
252
                && operations.size() == 2) {
253
            io.select();
254
        } else {
255
            IOSelect.select(io, showOperationsToIoSelect(operations));
256
        }
257
    }
258
259
    @Override
260
    public void closeIO(InputOutput io) {
261
        io.closeInputOutput();
262
    }
263
264
    @Override
265
    public boolean isIOClosed(InputOutput io) {
266
        return io.isClosed();
267
    }
268
269
    @Override
270
    public Integer getCurrentPosition(InputOutput io,
271
            OutputWriter writer) {
272
        if (io instanceof NbIO) {
273
            OutWriter out = ((NbIO) io).out();
274
            int size = 0;
275
            if (out != null) {
276
                size = out.getLines().getCharCount();
277
            }
278
            return size;
279
        } else {
280
            throw new IllegalArgumentException();
281
        }
282
    }
283
284
    @Override
285
    public void scrollTo(InputOutput io, OutputWriter writer,
286
            Integer position) {
287
        if (io instanceof NbIO) {
288
            NbIO.post(new IOEvent((NbIO) io, IOEvent.CMD_SCROLL, position));
289
        }
290
    }
291
292
    @Override
293
    public Integer startFold(InputOutput io, OutputWriter writer,
294
            boolean expanded) {
295
        if (io instanceof NbIO) {
296
            return ((NbIO) io).startFold(expanded);
297
        } else {
298
            throw new IllegalArgumentException();
299
        }
300
    }
301
302
    @Override
303
    public void endFold(InputOutput io, OutputWriter writer, Integer fold) {
304
        if (io instanceof NbIO) {
305
            ((NbIO) io).endFold(fold);
306
        } else {
307
            throw new IllegalArgumentException();
308
        }
309
    }
310
311
    @Override
312
    public void setFoldExpanded(InputOutput io, OutputWriter writer,
313
            Integer fold, boolean expanded) {
314
        if (io instanceof NbIO) {
315
            NbIO nbIO = ((NbIO) io);
316
            if (expanded) {
317
                nbIO.out().getLines().showFoldAndParentFolds(fold);
318
            } else {
319
                nbIO.out().getLines().hideFold(fold);
320
            }
321
        } else {
322
            throw new IllegalArgumentException();
323
        }
324
    }
325
326
    @Override
327
    public String getIODescription(InputOutput io) {
328
        if (io instanceof NbIO) {
329
            return ((NbIO) io).getToolTipText();
330
        } else {
331
            throw new IllegalArgumentException();
332
        }
333
    }
334
335
    @Override
336
    public void setIODescription(InputOutput io, String description) {
337
        if (io instanceof NbIO) {
338
            ((NbIO) io).setTooltipText(description);
339
        } else {
340
            throw new IllegalArgumentException();
341
        }
342
    }
343
344
    /**
345
     * Translate set of {@link ShowOperation}s to set of
346
     * {@link IOSelect.AdditionalOperation}s.
347
     */
348
    private Set<IOSelect.AdditionalOperation> showOperationsToIoSelect(
349
            Set<ShowOperation> operations) {
350
        Set<IOSelect.AdditionalOperation> res
351
                = EnumSet.noneOf(IOSelect.AdditionalOperation.class);
352
        for (ShowOperation so : operations) {
353
            switch (so) {
354
                case OPEN:
355
                    res.add(IOSelect.AdditionalOperation.OPEN);
356
                    break;
357
                case MAKE_VISIBLE:
358
                    res.add(IOSelect.AdditionalOperation.REQUEST_VISIBLE);
359
                    break;
360
                case ACTIVATE:
361
                    res.add(IOSelect.AdditionalOperation.REQUEST_ACTIVE);
362
                    break;
363
            }
364
        }
365
        return res;
366
    }
367
368
    /**
369
     * Convert a hyperlink to an output listener.
370
     *
371
     * @param link The hyperlink.
372
     * @return The wrapping output listener.
373
     */
374
    private static OutputListener hyperlinkToOutputListener(
375
            final Hyperlink link) {
376
377
        if (link == null) {
378
            return null;
379
        }
380
        return new OutputListener() {
381
382
            @Override
383
            public void outputLineSelected(OutputEvent ev) {
384
            }
385
386
            @Override
387
            public void outputLineAction(OutputEvent ev) {
388
                Hyperlinks.invoke(link);
389
            }
390
391
            @Override
392
            public void outputLineCleared(OutputEvent ev) {
393
            }
394
        };
395
    }
396
397
    private static Color outputColorToAwtColor(InputOutput io,
398
            OutputColor color) {
399
400
        if (color == null) {
401
            return null;
402
        }
403
        OutputColorType type = OutputColors.getType(color);
404
        if (type == OutputColorType.RGB) {
405
            return new Color(OutputColors.getRGB(color));
406
        } else {
407
            switch (type) {
408
                case DEBUG:
409
                    return IOColors.getColor(io, IOColors.OutputType.LOG_DEBUG);
410
                case FAILURE:
411
                    return IOColors.getColor(io, IOColors.OutputType.LOG_FAILURE);
412
                case WARNING:
413
                    return IOColors.getColor(io, IOColors.OutputType.LOG_WARNING);
414
                case SUCCESS:
415
                    return IOColors.getColor(io, IOColors.OutputType.LOG_SUCCESS);
416
                default:
417
                    return null;
418
            }
419
        }
420
    }
159
}
421
}
160
422
(-)a/nbbuild/build.properties (+1 lines)
Lines 100-105 Link Here
100
config.javadoc.stable=\
100
config.javadoc.stable=\
101
    api.annotations.common,\
101
    api.annotations.common,\
102
    api.html4j,\
102
    api.html4j,\
103
    api.io,\
103
    api.maven,\
104
    api.maven,\
104
    autoupdate.services,\
105
    autoupdate.services,\
105
    autoupdate.ui,\
106
    autoupdate.ui,\
(-)a/nbbuild/cluster.properties (+1 lines)
Lines 195-200 Link Here
195
nb.cluster.platform=\
195
nb.cluster.platform=\
196
        api.annotations.common,\
196
        api.annotations.common,\
197
        api.html4j,\
197
        api.html4j,\
198
        api.io,\
198
        api.progress,\
199
        api.progress,\
199
        api.progress.compat8,\
200
        api.progress.compat8,\
200
        api.progress.nb,\
201
        api.progress.nb,\
(-)a/nbbuild/javadoctools/links.xml (+1 lines)
Lines 240-242 Link Here
240
<link href="${javadoc.docs.org-netbeans-modules-parsing-nb}" offline="true" packagelistloc="${netbeans.javadoc.dir}/org-netbeans-modules-parsing-nb"/>
240
<link href="${javadoc.docs.org-netbeans-modules-parsing-nb}" offline="true" packagelistloc="${netbeans.javadoc.dir}/org-netbeans-modules-parsing-nb"/>
241
<link href="${javadoc.docs.org-netbeans-modules-project-libraries-ui}" offline="true" packagelistloc="${netbeans.javadoc.dir}/org-netbeans-modules-project-libraries-ui"/>
241
<link href="${javadoc.docs.org-netbeans-modules-project-libraries-ui}" offline="true" packagelistloc="${netbeans.javadoc.dir}/org-netbeans-modules-project-libraries-ui"/>
242
<link href="${javadoc.docs.org-openide-filesystems-nb}" offline="true" packagelistloc="${netbeans.javadoc.dir}/org-openide-filesystems-nb"/>
242
<link href="${javadoc.docs.org-openide-filesystems-nb}" offline="true" packagelistloc="${netbeans.javadoc.dir}/org-openide-filesystems-nb"/>
243
<link href="${javadoc.docs.org-netbeans-api-io}" offline="true" packagelistloc="${netbeans.javadoc.dir}\org-netbeans-api-io"/>
(-)a/nbbuild/javadoctools/properties.xml (+1 lines)
Lines 239-241 Link Here
239
<property name="javadoc.docs.org-netbeans-modules-parsing-nb" value="${javadoc.web.root}/org-netbeans-modules-parsing-nb"/>
239
<property name="javadoc.docs.org-netbeans-modules-parsing-nb" value="${javadoc.web.root}/org-netbeans-modules-parsing-nb"/>
240
<property name="javadoc.docs.org-netbeans-modules-project-libraries-ui" value="${javadoc.web.root}/org-netbeans-modules-project-libraries-ui"/>
240
<property name="javadoc.docs.org-netbeans-modules-project-libraries-ui" value="${javadoc.web.root}/org-netbeans-modules-project-libraries-ui"/>
241
<property name="javadoc.docs.org-openide-filesystems-nb" value="${javadoc.web.root}/org-openide-filesystems-nb"/>
241
<property name="javadoc.docs.org-openide-filesystems-nb" value="${javadoc.web.root}/org-openide-filesystems-nb"/>
242
<property name="javadoc.docs.org-netbeans-api-io" value="${javadoc.web.root}/org-netbeans-api-io"/>
(-)a/nbbuild/javadoctools/replaces.xml (+1 lines)
Lines 239-241 Link Here
239
<replacefilter token="@org-netbeans-modules-parsing-nb@" value="${javadoc.docs.org-netbeans-modules-parsing-nb}"/>
239
<replacefilter token="@org-netbeans-modules-parsing-nb@" value="${javadoc.docs.org-netbeans-modules-parsing-nb}"/>
240
<replacefilter token="@org-netbeans-modules-project-libraries-ui@" value="${javadoc.docs.org-netbeans-modules-project-libraries-ui}"/>
240
<replacefilter token="@org-netbeans-modules-project-libraries-ui@" value="${javadoc.docs.org-netbeans-modules-project-libraries-ui}"/>
241
<replacefilter token="@org-openide-filesystems-nb@" value="${javadoc.docs.org-openide-filesystems-nb}"/>
241
<replacefilter token="@org-openide-filesystems-nb@" value="${javadoc.docs.org-openide-filesystems-nb}"/>
242
<replacefilter token="@org-netbeans-api-io@" value="${javadoc.docs.org-netbeans-api-io}"/>
(-)a/openide.io/apichanges.xml (+18 lines)
Lines 107-112 Link Here
107
    <!-- ACTUAL CHANGES BEGIN HERE: -->
107
    <!-- ACTUAL CHANGES BEGIN HERE: -->
108
108
109
<changes>
109
<changes>
110
    <change id="BridgingIOProvider">
111
      <api name="io"/>
112
      <summary>Create a provider abstract class that implements new I/O SPI</summary>
113
      <version major="1" minor="47"/>
114
      <date day="22" month="10" year="2014"/>
115
      <author login="jhavlin"/>
116
      <compatibility addition="yes" binary="compatible" semantic="compatible" />
117
      <description>
118
          <p>
119
              As new API and SPI for output windows has been introduced, it is
120
              useful to have a convenient way for implementators of the original
121
              API to support the new API as well. The BridgingIOProvider class
122
              implements both SPIs, and its JavaDoc explains how to use it.
123
          </p>
124
      </description>
125
      <class package="org.openide.windows" name="BridgingIOProvider"/>
126
      <issue number="247404" />
127
    </change>
110
    <change id="enhancedFoldHandleApi">
128
    <change id="enhancedFoldHandleApi">
111
      <api name="io"/>
129
      <api name="io"/>
112
      <summary>Created new user-friendly methods for working with FoldHandle instances.</summary>
130
      <summary>Created new user-friendly methods for working with FoldHandle instances.</summary>
(-)a/openide.io/nbproject/org-openide-io.sig (-1 / +1 lines)
Lines 1-5 Link Here
1
#Signature file v4.1
1
#Signature file v4.1
2
#Version 1.45
2
#Version 1.44.1
3
3
4
CLSS public abstract interface java.io.Closeable
4
CLSS public abstract interface java.io.Closeable
5
intf java.lang.AutoCloseable
5
intf java.lang.AutoCloseable
(-)a/openide.io/nbproject/project.xml (-2 / +2 lines)
Lines 59-69 Link Here
59
                    </run-dependency>
59
                    </run-dependency>
60
                </dependency>
60
                </dependency>
61
                <dependency>
61
                <dependency>
62
                    <code-name-base>org.openide.util.ui</code-name-base>
62
                    <code-name-base>org.netbeans.api.io</code-name-base>
63
                    <build-prerequisite/>
63
                    <build-prerequisite/>
64
                    <compile-dependency/>
64
                    <compile-dependency/>
65
                    <run-dependency>
65
                    <run-dependency>
66
                        <specification-version>9.3</specification-version>
66
                        <specification-version>1.0</specification-version>
67
                    </run-dependency>
67
                    </run-dependency>
68
                </dependency>
68
                </dependency>
69
                <dependency>
69
                <dependency>
(-)a/openide.io/src/org/openide/io/BridgingGetter.java (+89 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2014 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 2014 Sun Microsystems, Inc.
41
 */
42
package org.openide.io;
43
44
import java.util.Collection;
45
import org.netbeans.spi.io.InputOutputProvider;
46
import org.openide.util.Lookup;
47
import org.openide.windows.IOProvider;
48
49
/**
50
 * Class for private contract between new api.io and this module. The new API
51
 * can retrieve this class using reflection and ask it for implementations of
52
 * output window, converted (bridged) to new SPI interface.
53
 *
54
 * @author jhavlin
55
 */
56
public class BridgingGetter {
57
58
    /**
59
     * Find the first IOProvider in default lookup and wrap it to
60
 BridgingInputOutputProvider.
61
     *
62
     * @return The default implementation of IOProvider from default lookup (not
63
     * the trivial one), or null if not available.
64
     */
65
    public InputOutputProvider<?, ?, ?, ?> getDefault() {
66
        IOProvider io = Lookup.getDefault().lookup(IOProvider.class);
67
        return io == null ? null : new BridgingInputOutputProvider(io);
68
    }
69
70
    /**
71
     * Find IOProvider of given name and wrap it to BridgingInputOutputProvider.
72
     *
73
     * @return IOProvider with specified name, or null if not available.
74
     */
75
    public InputOutputProvider<?, ?, ?, ?> get(String name) {
76
        if (name == null) {
77
            throw new NullPointerException(
78
                    "Provider name cannot be null");                    //NOI18N
79
        }
80
        Collection<? extends IOProvider> providers
81
                = Lookup.getDefault().lookupAll(IOProvider.class);
82
        for (IOProvider p : providers) {
83
            if (name.equals(p.getName())) {
84
                return new BridgingInputOutputProvider(p);
85
            }
86
        }
87
        return null;
88
    }
89
}
(-)a/openide.io/src/org/openide/io/BridgingIOProvider.java (+394 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2014 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 2014 Sun Microsystems, Inc.
41
 */
42
package org.openide.io;
43
44
import java.awt.Color;
45
import java.io.IOException;
46
import java.io.PrintWriter;
47
import java.io.Reader;
48
import java.io.StringWriter;
49
import java.util.EnumSet;
50
import java.util.Set;
51
import java.util.logging.Level;
52
import java.util.logging.Logger;
53
import javax.swing.Action;
54
import org.netbeans.api.io.Hyperlink;
55
import org.netbeans.api.io.OutputColor;
56
import org.netbeans.api.io.ShowOperation;
57
import org.netbeans.spi.io.InputOutputProvider;
58
import org.openide.util.Lookup;
59
import org.openide.util.NbBundle;
60
import org.openide.util.lookup.Lookups;
61
import org.openide.util.lookup.ProxyLookup;
62
import org.openide.windows.IOColorLines;
63
import org.openide.windows.IOColorPrint;
64
import org.openide.windows.IOContainer;
65
import org.openide.windows.IOFolding;
66
import org.openide.windows.IOPosition;
67
import org.openide.windows.IOProvider;
68
import org.openide.windows.InputOutput;
69
import org.openide.windows.OutputListener;
70
import org.openide.windows.OutputWriter;
71
72
/**
73
 *
74
 * @author jhavlin
75
 */
76
public class BridgingIOProvider<IO, S extends PrintWriter, P, F>
77
        extends IOProvider {
78
79
    private static final Logger LOG
80
            = Logger.getLogger(BridgingIOProvider.class.getName());
81
    private static final Set<ShowOperation> DEFAULT_SHOW_OPERATIONS
82
            = EnumSet.of(ShowOperation.OPEN, ShowOperation.MAKE_VISIBLE);
83
84
    private final InputOutputProvider<IO, S, P, F> providerDelegate;
85
    private Lookup lookup = null;
86
87
    public static <A, B extends PrintWriter, C, D> IOProvider create(
88
            InputOutputProvider<A, B, C, D> delegate) {
89
        return new BridgingIOProvider<A, B, C, D>(delegate);
90
    }
91
92
    private BridgingIOProvider(
93
            InputOutputProvider<IO, S, P, F> delegate) {
94
        this.providerDelegate = delegate;
95
    }
96
97
    @Override
98
    public InputOutput getIO(String name, boolean newIO) {
99
        return new BridgingInputOutput(
100
                providerDelegate.getIO(name, newIO, Lookup.EMPTY));
101
    }
102
103
    @Override
104
    public InputOutput getIO(String name, Action[] actions) {
105
        return new BridgingInputOutput(
106
                providerDelegate.getIO(name, true,
107
                        Lookups.fixed((Object[]) actions)));
108
    }
109
110
    @Override
111
    public InputOutput getIO(String name, Action[] actions,
112
            IOContainer ioContainer) {
113
        return getIO(name, true, actions, ioContainer);
114
    }
115
116
    @Override
117
    public InputOutput getIO(String name, boolean newIO, Action[] actions,
118
            IOContainer ioContainer) {
119
        return new BridgingInputOutput(
120
                providerDelegate.getIO(name, newIO,
121
                        Lookups.fixed((Object[]) actions, ioContainer)));
122
    }
123
124
    @NbBundle.Messages({"LBL_STDOUT=Standard output"})
125
    @Override
126
    public OutputWriter getStdOut() {
127
        IO io = providerDelegate.getIO(Bundle.LBL_STDOUT(), false, Lookup.EMPTY);
128
        S out = providerDelegate.getOut(io);
129
        return new BridgingOutputWriter(io, out);
130
    }
131
132
    private Hyperlink listenerToHyperlink(
133
            final OutputListener l,
134
            final boolean important) {
135
        return l == null
136
                ? null
137
                : Hyperlink.from(new Runnable() {
138
139
                    @Override
140
                    public void run() {
141
                        try {
142
                            // Event is null, it can cause problems.
143
                            l.outputLineAction(null);
144
                        } catch (Exception e) {
145
                            LOG.log(Level.INFO, "Cannot process output" //NOI18N
146
                                    + " listener action", e);           //NOI18N
147
                        }
148
                    }
149
                }, important);
150
    }
151
152
    /**
153
     * Bridge from old SPI to new API for I/O instance.
154
     */
155
    private class BridgingInputOutput implements InputOutput, Lookup.Provider {
156
157
        private final IO ioDelegate;
158
159
        public BridgingInputOutput(IO delegate) {
160
            this.ioDelegate = delegate;
161
        }
162
163
        @Override
164
        public OutputWriter getOut() {
165
            return new BridgingOutputWriter(ioDelegate,
166
                    providerDelegate.getOut(ioDelegate));
167
        }
168
169
        @Override
170
        public Reader getIn() {
171
            return providerDelegate.getIn(ioDelegate);
172
        }
173
174
        @Override
175
        public OutputWriter getErr() {
176
            return new BridgingOutputWriter(ioDelegate,
177
                    providerDelegate.getOut(ioDelegate)
178
        );
179
        }
180
181
        @Override
182
        public void closeInputOutput() {
183
            providerDelegate.closeIO(ioDelegate);
184
        }
185
186
        @Override
187
        public boolean isClosed() {
188
            return providerDelegate.isIOClosed(ioDelegate);
189
        }
190
191
        @Override
192
        public void setOutputVisible(boolean value) {
193
        }
194
195
        @Override
196
        public void setErrVisible(boolean value) {
197
        }
198
199
        @Override
200
        public void setInputVisible(boolean value) {
201
        }
202
203
        @Override
204
        public void select() {
205
            providerDelegate.showIO(ioDelegate, DEFAULT_SHOW_OPERATIONS);
206
        }
207
208
        @Override
209
        public boolean isErrSeparated() {
210
            return false;
211
        }
212
213
        @Override
214
        public void setErrSeparated(boolean value) {
215
        }
216
217
        @Override
218
        public boolean isFocusTaken() {
219
            return false;
220
        }
221
222
        @Override
223
        public void setFocusTaken(boolean value) {
224
        }
225
226
        @Override
227
        @SuppressWarnings("deprecation")
228
        public Reader flushReader() {
229
            return getIn();
230
        }
231
232
        @Override
233
        public synchronized Lookup getLookup() {
234
            if (lookup == null) {
235
                Lookup origLookup = providerDelegate.getIOLookup(ioDelegate);
236
                Lookup extLookup = Lookups.fixed(
237
                        new BridgingIOColorLines(ioDelegate),
238
                        new BridgingIOColorPrint(ioDelegate),
239
                        new BridgingIOPosition(ioDelegate),
240
                        new BridgingIOFolding(ioDelegate)
241
                );
242
                if (origLookup == Lookup.EMPTY) {
243
                    lookup = extLookup;
244
                } else {
245
                    lookup = new ProxyLookup(origLookup, extLookup);
246
                }
247
            }
248
            return lookup;
249
        }
250
    }
251
252
    /**
253
     * Bridge from old SPI to new API for a stream instance.
254
     */
255
    private class BridgingOutputWriter extends OutputWriter {
256
257
        PrintWriter printWriterToReplace = null;
258
        private final S writerDelegate;
259
        private final IO ioDelegate;
260
261
        public BridgingOutputWriter(IO ioDelegate, S delegate) {
262
            super(new StringWriter());
263
            this.writerDelegate = delegate;
264
            this.ioDelegate = ioDelegate;
265
        }
266
267
        @Override
268
        public void println(String s, final OutputListener l)
269
                throws IOException {
270
271
            println(s, l, false);
272
        }
273
274
        @Override
275
        public void println(String s, final OutputListener l, boolean important)
276
                throws IOException {
277
278
            Hyperlink h = listenerToHyperlink(l, important);
279
            providerDelegate.print(ioDelegate, writerDelegate, s,
280
                    h, null, true);
281
        }
282
283
        @Override
284
        public void reset() throws IOException {
285
            providerDelegate.resetIO(ioDelegate);
286
        }
287
    }
288
289
    private class BridgingIOColorLines extends IOColorLines {
290
291
        private final IO ioDelegate;
292
293
        public BridgingIOColorLines(IO ioDelegate) {
294
            this.ioDelegate = ioDelegate;
295
        }
296
297
        @Override
298
        protected void println(CharSequence text, OutputListener listener,
299
                boolean important, Color color) throws IOException {
300
            Hyperlink h = listenerToHyperlink(listener, important);
301
            providerDelegate.print(ioDelegate,
302
                    providerDelegate.getOut(ioDelegate), text.toString(),
303
                    h, null, true);
304
        }
305
    }
306
307
    private class BridgingIOColorPrint extends IOColorPrint {
308
309
        private final IO ioDelegate;
310
311
        public BridgingIOColorPrint(IO ioDelegate) {
312
            this.ioDelegate = ioDelegate;
313
        }
314
315
        @Override
316
        protected void print(CharSequence text, OutputListener listener,
317
                boolean important, Color color) throws IOException {
318
319
            Hyperlink h = listenerToHyperlink(listener, important);
320
            providerDelegate.print(ioDelegate,
321
                    providerDelegate.getOut(ioDelegate), text.toString(),
322
                    h, OutputColor.rgb(color.getRGB()), false);
323
        }
324
    }
325
326
    private class BridgingIOPosition extends IOPosition {
327
328
        private final IO ioDelegate;
329
330
        public BridgingIOPosition(IO ioDelegate) {
331
            this.ioDelegate = ioDelegate;
332
        }
333
334
        @Override
335
        protected Position currentPosition() {
336
337
            final S writer = providerDelegate.getOut(ioDelegate);
338
            final P pos = providerDelegate.getCurrentPosition(ioDelegate,
339
                    writer);
340
341
            return new Position() {
342
343
                @Override
344
                public void scrollTo() {
345
                    providerDelegate.scrollTo(ioDelegate, writer, pos);
346
                }
347
            };
348
        }
349
    }
350
351
    private class BridgingIOFolding extends IOFolding {
352
353
        private final IO ioDelegate;
354
355
        public BridgingIOFolding(IO ioDelegate) {
356
            this.ioDelegate = ioDelegate;
357
        }
358
359
        @Override
360
        protected FoldHandleDefinition startFold(boolean expanded) {
361
            S writer = providerDelegate.getOut(ioDelegate);
362
            F fold = providerDelegate.startFold(ioDelegate, writer, expanded);
363
            return new BridgingFoldHandleDefinition(writer, fold);
364
        }
365
366
        private class BridgingFoldHandleDefinition extends FoldHandleDefinition {
367
368
            private final S writer;
369
            private final F fold;
370
371
            public BridgingFoldHandleDefinition(S writer, F fold) {
372
                this.writer = writer;
373
                this.fold = fold;
374
            }
375
376
            @Override
377
            public void finish() {
378
                providerDelegate.endFold(ioDelegate, writer, fold);
379
            }
380
381
            @Override
382
            public FoldHandleDefinition startFold(boolean expanded) {
383
                F f = providerDelegate.startFold(ioDelegate, writer, expanded);
384
                return new BridgingFoldHandleDefinition(writer, f);
385
            }
386
387
            @Override
388
            public void setExpanded(boolean expanded) {
389
                providerDelegate.setFoldExpanded(ioDelegate, writer, fold,
390
                        expanded);
391
            }
392
        }
393
    }
394
}
(-)a/openide.io/src/org/openide/io/BridgingInputOutputProvider.java (+364 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2014 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 2014 Sun Microsystems, Inc.
41
 */
42
package org.openide.io;
43
44
import java.awt.Color;
45
import java.io.IOException;
46
import java.io.Reader;
47
import java.util.ArrayDeque;
48
import java.util.Deque;
49
import java.util.EnumSet;
50
import java.util.Set;
51
import java.util.logging.Level;
52
import java.util.logging.Logger;
53
import javax.swing.Action;
54
import org.netbeans.api.io.Hyperlink;
55
import org.netbeans.api.io.OutputColor;
56
import org.netbeans.api.io.ShowOperation;
57
import org.netbeans.spi.io.support.Hyperlinks;
58
import org.netbeans.spi.io.InputOutputProvider;
59
import org.netbeans.spi.io.support.OutputColorType;
60
import org.netbeans.spi.io.support.OutputColors;
61
import org.openide.util.Lookup;
62
import org.openide.windows.FoldHandle;
63
import org.openide.windows.IOColorLines;
64
import org.openide.windows.IOColorPrint;
65
import org.openide.windows.IOColors;
66
import org.openide.windows.IOColors.OutputType;
67
import org.openide.windows.IOContainer;
68
import org.openide.windows.IOFolding;
69
import org.openide.windows.IOPosition;
70
import org.openide.windows.IOPosition.Position;
71
import org.openide.windows.IOProvider;
72
import org.openide.windows.IOSelect;
73
import org.openide.windows.IOTab;
74
import org.openide.windows.InputOutput;
75
import org.openide.windows.OutputEvent;
76
import org.openide.windows.OutputListener;
77
import org.openide.windows.OutputWriter;
78
79
/**
80
 * Wrapper class for converting implementations of IOProvider SPI to new SPI
81
 * interface {@link InputOutputProvider}.
82
 *
83
 * @author jhavlin
84
 */
85
public final class BridgingInputOutputProvider
86
        implements InputOutputProvider<InputOutput, OutputWriter, Position, FoldHandle> {
87
88
    private final IOProvider delegate;
89
90
    public BridgingInputOutputProvider(IOProvider delegate) {
91
        this.delegate = delegate;
92
    }
93
94
    private static final Logger LOG
95
            = Logger.getLogger(BridgingInputOutputProvider.class.getName());
96
97
    private final Deque<FoldHandle> foldStack = new ArrayDeque<FoldHandle>();
98
99
    @Override
100
    public String getId() {
101
        return delegate.getName();
102
    }
103
104
    @Override
105
    public InputOutput getIO(String name, boolean newIO, Lookup lookup) {
106
        Action[] actions = lookup.lookup(Action[].class);
107
        IOContainer container = lookup.lookup(IOContainer.class);
108
        if (container == null && actions == null) {
109
            return delegate.getIO(name, newIO);
110
        } else if (newIO) {
111
            if (container != null && actions != null) {
112
                return delegate.getIO(name, actions, container);
113
            } else if (actions != null) {
114
                return delegate.getIO(name, actions);
115
            } else {
116
                return delegate.getIO(name, new Action[0], container);
117
            }
118
        } else {
119
            return delegate.getIO(name, newIO, actions == null ? new Action[0] : actions,
120
                    container);
121
        }
122
    }
123
124
    @Override
125
    public Reader getIn(InputOutput io) {
126
        return io.getIn();
127
    }
128
129
    @Override
130
    public OutputWriter getOut(InputOutput io) {
131
        return io.getOut();
132
    }
133
134
    @Override
135
    public OutputWriter getErr(InputOutput io) {
136
        return io.getErr();
137
    }
138
139
    @Override
140
    public void print(InputOutput io, OutputWriter writer, String text,
141
            Hyperlink link, OutputColor outputColor, boolean printLineEnd) {
142
143
        Color awtColor = outputColorToAwtColor(io, outputColor);
144
        OutputListener listener = hyperlinkToOutputListener(link);
145
        boolean listenerImportant = link != null && Hyperlinks.isImportant(link);
146
        try {
147
            if (printLineEnd && outputColor == null) {
148
                writer.println(text, listener, listenerImportant);
149
            } else if (printLineEnd && IOColorLines.isSupported(io)) {
150
                IOColorLines.println(io, text, listener, listenerImportant,
151
                        awtColor);
152
            } else if (IOColorPrint.isSupported(io)) {
153
                IOColorPrint.print(io, text, listener, listenerImportant,
154
                        awtColor);
155
                if (printLineEnd) {
156
                    writer.println();
157
                }
158
            } else if (printLineEnd) {
159
                writer.println(text);
160
            } else {
161
                writer.print(text);
162
            }
163
        } catch (IOException ex) {
164
            LOG.log(Level.FINE, "Cannot print color or hyperlink", ex); //NOI18N
165
        }
166
    }
167
168
    @Override
169
    public Lookup getIOLookup(InputOutput io) {
170
        if (io instanceof Lookup.Provider) {
171
            return ((Lookup.Provider) io).getLookup();
172
        } else {
173
            return Lookup.EMPTY;
174
        }
175
    }
176
177
    @Override
178
    public void resetIO(InputOutput io) {
179
        try {
180
            io.getOut().reset();
181
        } catch (IOException ex) {
182
            LOG.log(Level.FINE, "Cannot reset InputOutput.", ex);       //NOI18N
183
        }
184
    }
185
186
    @Override
187
    public void showIO(InputOutput io,
188
            Set<ShowOperation> operations) {
189
        if (operations.contains(ShowOperation.OPEN)
190
                && operations.contains(ShowOperation.MAKE_VISIBLE)
191
                && operations.size() == 2) {
192
            io.select();
193
        } else {
194
            IOSelect.select(io, showOperationsToIoSelect(operations));
195
        }
196
    }
197
198
    /**
199
     * Translate set of {@link ShowOperation}s to set of
200
     * {@link IOSelect.AdditionalOperation}s.
201
     */
202
    private Set<IOSelect.AdditionalOperation> showOperationsToIoSelect(
203
            Set<ShowOperation> operations) {
204
        Set<IOSelect.AdditionalOperation> res
205
                = EnumSet.noneOf(IOSelect.AdditionalOperation.class);
206
        for (ShowOperation so : operations) {
207
            switch (so) {
208
                case OPEN:
209
                    res.add(IOSelect.AdditionalOperation.OPEN);
210
                    break;
211
                case MAKE_VISIBLE:
212
                    res.add(IOSelect.AdditionalOperation.REQUEST_VISIBLE);
213
                    break;
214
                case ACTIVATE:
215
                    res.add(IOSelect.AdditionalOperation.REQUEST_ACTIVE);
216
                    break;
217
            }
218
        }
219
        return res;
220
    }
221
222
    @Override
223
    public void closeIO(InputOutput io) {
224
        io.closeInputOutput();
225
    }
226
227
    @Override
228
    public boolean isIOClosed(InputOutput io) {
229
        return io.isClosed();
230
    }
231
232
    @Override
233
    public Position getCurrentPosition(InputOutput io, OutputWriter writer) {
234
        if (IOPosition.isSupported(io)) {
235
            return IOPosition.currentPosition(io);
236
        } else {
237
            return null;
238
        }
239
    }
240
241
    @Override
242
    public void scrollTo(InputOutput io, OutputWriter writer, Position position) {
243
        position.scrollTo();
244
    }
245
246
    @Override
247
    public FoldHandle startFold(InputOutput io, OutputWriter writer,
248
            boolean expanded) {
249
250
        if (IOFolding.isSupported(io)) {
251
            synchronized (foldStack) {
252
                if (foldStack.isEmpty()) {
253
                    foldStack.addLast(IOFolding.startFold(io, expanded));
254
                } else {
255
                    foldStack.addLast(foldStack.getLast().startFold(expanded));
256
                }
257
                return foldStack.getLast();
258
            }
259
        } else {
260
            return null;
261
        }
262
    }
263
264
    @Override
265
    public void endFold(InputOutput io, OutputWriter writer, FoldHandle fold) {
266
        synchronized (foldStack) {
267
            while (!foldStack.isEmpty()) {
268
                if (foldStack.removeLast() == fold) {
269
                    break;
270
                }
271
            }
272
            fold.silentFinish();
273
        }
274
    }
275
276
    @Override
277
    public void setFoldExpanded(InputOutput io, OutputWriter writer,
278
            FoldHandle fold, boolean expanded) {
279
        fold.setExpanded(expanded);
280
    }
281
282
    @Override
283
    public String getIODescription(InputOutput io) {
284
        if (IOTab.isSupported(io)) {
285
            return IOTab.getToolTipText(io);
286
        } else {
287
            return null;
288
        }
289
    }
290
291
    @Override
292
    public void setIODescription(InputOutput io, String description) {
293
        if (IOTab.isSupported(io)) {
294
            IOTab.setToolTipText(io, description);
295
        }
296
    }
297
298
    /**
299
     * Convert a hyperlink to an output listener.
300
     *
301
     * @param link The hyperlink.
302
     * @return The wrapping output listener.
303
     */
304
    private static OutputListener hyperlinkToOutputListener(
305
            final Hyperlink link) {
306
307
        if (link == null) {
308
            return null;
309
        }
310
        return new OutputListenerAdapter() {
311
            @Override
312
            public void outputLineAction(OutputEvent ev) {
313
                Hyperlinks.invoke(link);
314
            }
315
        };
316
    }
317
318
    /**
319
     * Convert AWT-independent {@link OutputColor} to {@link java.awt.Color}.
320
     *
321
     * @return Appropriate color, or null if default color should be used.
322
     */
323
    private static Color outputColorToAwtColor(InputOutput io,
324
            OutputColor color) {
325
326
        if (color == null) {
327
            return null;
328
        }
329
        OutputColorType type = OutputColors.getType(color);
330
        if (type == OutputColorType.RGB) {
331
            return new Color(OutputColors.getRGB(color));
332
        } else if (IOColors.isSupported(io)) {
333
            switch (type) {
334
                case DEBUG:
335
                    return IOColors.getColor(io, OutputType.LOG_DEBUG);
336
                case FAILURE:
337
                    return IOColors.getColor(io, OutputType.LOG_FAILURE);
338
                case WARNING:
339
                    return IOColors.getColor(io, OutputType.LOG_WARNING);
340
                case SUCCESS:
341
                    return IOColors.getColor(io, OutputType.LOG_SUCCESS);
342
                default:
343
                    return null;
344
            }
345
        } else {
346
            return null;
347
        }
348
    }
349
350
    private static class OutputListenerAdapter implements OutputListener {
351
352
        @Override
353
        public void outputLineSelected(OutputEvent ev) {
354
        }
355
356
        @Override
357
        public void outputLineAction(OutputEvent ev) {
358
        }
359
360
        @Override
361
        public void outputLineCleared(OutputEvent ev) {
362
        }
363
    }
364
}
(-)a/openide.io/src/org/openide/io/Bundle.properties (-1 / +1 lines)
Lines 40-46 Link Here
40
# Version 2 license, then the option applies only if the new code is
40
# Version 2 license, then the option applies only if the new code is
41
# made subject to such option by the copyright holder.
41
# made subject to such option by the copyright holder.
42
42
43
OpenIDE-Module-Name=I/O APIs
43
OpenIDE-Module-Name=I/O APIs - Swing
44
OpenIDE-Module-Display-Category=Infrastructure
44
OpenIDE-Module-Display-Category=Infrastructure
45
OpenIDE-Module-Short-Description=Open APIs relating to displaying output.
45
OpenIDE-Module-Short-Description=Open APIs relating to displaying output.
46
OpenIDE-Module-Long-Description=\
46
OpenIDE-Module-Long-Description=\
(-)a/openide.io/src/org/openide/windows/IOProvider.java (-1 / +17 lines)
Lines 54-59 Link Here
54
import javax.swing.Action;
54
import javax.swing.Action;
55
import org.netbeans.api.annotations.common.NonNull;
55
import org.netbeans.api.annotations.common.NonNull;
56
import org.netbeans.api.annotations.common.NullAllowed;
56
import org.netbeans.api.annotations.common.NullAllowed;
57
import org.netbeans.spi.io.InputOutputProvider;
58
import org.openide.io.BridgingIOProvider;
57
import org.openide.util.Lookup;
59
import org.openide.util.Lookup;
58
60
59
/** A factory for IO tabs shown in the output window.  To create a new tab to
61
/** A factory for IO tabs shown in the output window.  To create a new tab to
Lines 78-84 Link Here
78
    public static IOProvider getDefault() {
80
    public static IOProvider getDefault() {
79
        IOProvider iop = Lookup.getDefault().lookup(IOProvider.class);
81
        IOProvider iop = Lookup.getDefault().lookup(IOProvider.class);
80
        if (iop == null) {
82
        if (iop == null) {
81
            iop = new Trivial();
83
            InputOutputProvider<?, ?, ?, ?> newSpiDef
84
                    = Lookup.getDefault().lookup(InputOutputProvider.class);
85
            if (newSpiDef != null) {
86
                iop = BridgingIOProvider.create(newSpiDef);
87
            } else {
88
                iop = new Trivial();
89
            }
82
        }
90
        }
83
        return iop;
91
        return iop;
84
    }
92
    }
Lines 89-94 Link Here
89
     * @return the instance corresponding to provided name or default instance if not found
97
     * @return the instance corresponding to provided name or default instance if not found
90
     * @since 1.15
98
     * @since 1.15
91
     */
99
     */
100
    @SuppressWarnings("rawtypes")
92
    public static IOProvider get(String name) {
101
    public static IOProvider get(String name) {
93
        Collection<? extends IOProvider> res = Lookup.getDefault().lookupAll(IOProvider.class);
102
        Collection<? extends IOProvider> res = Lookup.getDefault().lookupAll(IOProvider.class);
94
        for (IOProvider iop : res) {
103
        for (IOProvider iop : res) {
Lines 96-101 Link Here
96
                return iop;
105
                return iop;
97
            }
106
            }
98
        }
107
        }
108
        Collection<? extends InputOutputProvider> newSpiImpls
109
                = Lookup.getDefault().lookupAll(InputOutputProvider.class);
110
        for (InputOutputProvider<?,?,?,?> impl: newSpiImpls) {
111
            if (impl.getId().equals(name)) {
112
                return BridgingIOProvider.create(impl);
113
            }
114
        }
99
        return getDefault();
115
        return getDefault();
100
    }
116
    }
101
117

Return to bug 247404