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

(-)a/cnd.api.remote/nbproject/project.xml (+8 lines)
Lines 38-43 Link Here
38
                    </run-dependency>
38
                    </run-dependency>
39
                </dependency>
39
                </dependency>
40
                <dependency>
40
                <dependency>
41
                    <code-name-base>org.netbeans.modules.cnd.execution</code-name-base>
42
                    <build-prerequisite/>
43
                    <compile-dependency/>
44
                    <run-dependency>
45
                        <specification-version>1.0</specification-version>
46
                    </run-dependency>
47
                </dependency>
48
                <dependency>
41
                    <code-name-base>org.netbeans.modules.projectapi</code-name-base>
49
                    <code-name-base>org.netbeans.modules.projectapi</code-name-base>
42
                    <build-prerequisite/>
50
                    <build-prerequisite/>
43
                    <compile-dependency/>
51
                    <compile-dependency/>
(-)a/cnd.debugger.common2/nbproject/project.xml (+8 lines)
Lines 154-159 Link Here
154
                    </run-dependency>
154
                    </run-dependency>
155
                </dependency>
155
                </dependency>
156
                <dependency>
156
                <dependency>
157
                    <code-name-base>org.netbeans.modules.cnd.execution</code-name-base>
158
                    <build-prerequisite/>
159
                    <compile-dependency/>
160
                    <run-dependency>
161
                        <specification-version>1.0</specification-version>
162
                    </run-dependency>
163
                </dependency>
164
                <dependency>
157
                    <code-name-base>org.netbeans.modules.options.api</code-name-base>
165
                    <code-name-base>org.netbeans.modules.options.api</code-name-base>
158
                    <build-prerequisite/>
166
                    <build-prerequisite/>
159
                    <compile-dependency/>
167
                    <compile-dependency/>
(-)a/cnd.execution/arch.xml (+1200 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="akrasny@netbeans.org"
9
>
10
11
  &api-questions;
12
13
14
<!--
15
        <question id="arch-overall" when="init">
16
            Describe the overall architecture. 
17
            <hint>
18
            What will be API for 
19
            <a href="http://wiki.netbeans.org/API_Design#Separate_API_for_clients_from_support_API">
20
                clients and what support API</a>? 
21
            What parts will be pluggable?
22
            How will plug-ins be registered? Please use <code>&lt;api type="export"/&gt;</code>
23
            to describe your general APIs and specify their
24
            <a href="http://wiki.netbeans.org/API_Stability#Private">
25
            stability categories</a>.
26
            If possible please provide simple diagrams.
27
            </hint>
28
        </question>
29
-->
30
    <answer id="arch-overall">
31
        <p>
32
            Native Execution API is intended to provide a flexible and extendable 
33
            aid for running external processes on a local or remote hosts.
34
        </p>
35
        <p>
36
            The module itself doesn't provide any specific implementation. It 
37
            also doesn't make any strict obligations on what is considered to be a 
38
            Process or a Host. But it has some assumptions regarging those 
39
            entities though...
40
        </p>
41
        <p>
42
            But first, two words about what this module is about and what it is not. 
43
            This module is NOT about hosts management nor it is about connections
44
            management system (in sense of UI elements, persistance, etc.). This 
45
            module is almost entirely about establishing a connection to some 
46
            destination target (usually a host), running a process there and
47
            getting back it's I/O. Also some basic utilities are provided that 
48
            could make these tasks easier to achieve.
49
        </p>
50
        <p>
51
            From the SPI implementor point of view this module is a set of 
52
            extension points to introduce own notion of Process/Connection 
53
            and add own implementation without a need to deal (a lot) with 
54
            threading and other annoying issues...
55
        </p>
56
        <p>
57
            This API/SPI was written while keeping in mind a previous experiense 
58
            with NativeExecution module. An attempt to re-design some questinoable 
59
            approaches used in the previous implementation has been made.
60
        </p>
61
        Requirements for the module:
62
        <ul>
63
            <li>Extensibility - provide a way for adding new authorization 
64
                schemes, new transport layers
65
            </li>
66
            <li>Predictibility - no hidden acctions (like unexpected 
67
                connections initialization)
68
            </li>
69
            <li>Separatation between host (whatever it could be), user, 
70
                authorization way and transport
71
            </li>
72
            <li>Clear error-flow</li>
73
            <li>Clear threading model</li>
74
            <li>Clear control over streams encodings</li>
75
            <li>Easy to use utilities</li>
76
        </ul>
77
        <p>
78
            The entity a user of this API starts with is a Connection. 
79
            Any connection is identified by an URI. ConnectionManager is asked 
80
            to give a connection for some URI and this Connection becames a 
81
            provider of a NativeProcessBuilder which in turn can be used to 
82
            start a NativeProcess in the context of that Connection.
83
        </p>
84
        <p>
85
            A scheme of an URI passed to the ConnectionManager is used to lookup 
86
            an SPI implementor that can initiate, establish and provide a connection.
87
            All SPI implementors that deal with particular 'kind' of connections 
88
            are registered in "ConnectionService/&lt;scheme&gt;" lookup path.
89
        </p>
90
    </answer>
91
92
93
94
<!--
95
        <question id="arch-quality" when="init">
96
            How will the <a href="http://www.netbeans.org/community/guidelines/q-evangelism.html">quality</a>
97
            of your code be tested and 
98
            how are future regressions going to be prevented?
99
            <hint>
100
            What kind of testing do
101
            you want to use? How much functionality, in which areas,
102
            should be covered by the tests? How you find out that your
103
            project was successful?
104
            </hint>
105
        </question>
106
-->
107
    <answer id="arch-quality">
108
        <p>
109
            There are already many users on an old API. The intention (and 
110
            success metric) is to move all client of the old API to this one.
111
            <br/>
112
            Unit tests will be provided. Also there should be no regression in 
113
            old API client's functionality.
114
        </p>
115
    </answer>
116
117
118
119
<!--
120
        <question id="arch-time" when="init">
121
            What are the time estimates of the work?
122
            <hint>
123
            Please express your estimates of how long the design, implementation,
124
            stabilization are likely to last. How many people will be needed to
125
            implement this and what is the expected milestone by which the work should be 
126
            ready?
127
            </hint>
128
        </question>
129
-->
130
    <answer id="arch-time">
131
        <p>
132
            This module should became a public replacement for dlight.nativeexecution module.
133
            <br/>
134
            As API is changed all friend-modules should be modified to use this new one.
135
            In most cases this should not be difficult, but taking into accont the
136
            number of 'old' API clients (100+ friend modules) this task could take a while. 
137
            Estimation is two months.
138
        </p>
139
    </answer>
140
141
142
143
<!--
144
        <question id="arch-usecases" when="init">
145
            <hint>
146
                Content of this answer will be displayed as part of page at
147
                http://www.netbeans.org/download/dev/javadoc/usecases.html 
148
                You can use tags &lt;usecase name="name&gt; regular html description &lt;/usecase&gt;
149
                and if you want to use an URL you can prefix if with @TOP@ to begin
150
                at the root of your javadoc
151
            </hint>
152
        
153
            Describe the main <a href="http://wiki.netbeans.org/API_Design#The_Importance_of_Being_Use_Case_Oriented">
154
            use cases</a> of the new API. Who will use it under
155
            what circumstances? What kind of code would typically need to be written
156
            to use the module?
157
        </question>
158
-->
159
    <answer id="arch-usecases">
160
        <p>
161
            This module could be used for running external processes on a local and
162
            remote hosts. It is extendable and SPI implementors could provide different 
163
            implementation of connections and processes... But at least two 
164
            implementations are to be provided together with this module (in a 
165
            separate implementation module). 
166
            <br/>
167
            They are for starting local processes ("localhost" scheme) and remote
168
            processes using Jsch services ("ssh" scheme).
169
            <br/>
170
            Common usage is:
171
            <usecase id="simple-remote-process" name="Simple Remote Process">
172
                <pre>
173
                try {
174
                    URI uri = new URI("ssh://tester:tester@testmachine.com");
175
                    Connection connection = ConnectionManager.connect(uri);
176
177
                    NativeProcessBuilder npb = connection.newProcessBuilder();
178
                    npb.setWorkingDirectory("/tmp/test").setCommand("my-command");
179
                    npb.getEnvironmentMap().prependPath("PATH", "/path/to/my-command");
180
181
                    ProcessUtils.ExitStatus result = ProcessUtils.execute(npb);
182
                    if (result.isOK()) {
183
                        System.out.println(result.output);
184
                    }
185
                } catch (NativeExecutionException ex) {
186
                    Exceptions.printStackTrace(ex);
187
                } catch (URISyntaxException ex) {
188
                    Exceptions.printStackTrace(ex);
189
                }
190
                </pre>
191
            </usecase>
192
        </p>
193
    </answer>
194
195
196
197
<!--
198
        <question id="arch-what" when="init">
199
            What is this project good for?
200
            <hint>
201
            Please provide here a few lines describing the project, 
202
            what problem it should solve, provide links to documentation, 
203
            specifications, etc.
204
            </hint>
205
        </question>
206
-->
207
    <answer id="arch-what">
208
        <p>
209
            This module provides an API/SPI be used for running external 
210
            processes on a local or remote hosts.
211
        </p>
212
    </answer>
213
214
215
216
<!--
217
        <question id="arch-where" when="impl">
218
            Where one can find sources for your module?
219
            <hint>
220
                Please provide link to the Hg web client at
221
                http://hg.netbeans.org/
222
                or just use tag defaultanswer generate='here'
223
            </hint>
224
        </question>
225
-->
226
    <answer id="arch-where">
227
        <defaultanswer generate='here' />
228
    </answer>
229
230
231
232
<!--
233
        <question id="compat-deprecation" when="init">
234
            How the introduction of your project influences functionality
235
            provided by previous version of the product?
236
            <hint>
237
            If you are planning to deprecate/remove/change any existing APIs,
238
            list them here accompanied with the reason explaining why you
239
            are doing so.
240
            </hint>
241
        </question>
242
-->
243
    <answer id="compat-deprecation">
244
        <p>
245
            Process-related API from dlight.nativeexecution is planned to be 
246
            first deprecated and then, when transition is done, demoved from 
247
            the product.
248
        </p>
249
    </answer>
250
251
252
253
<!--
254
        <question id="compat-i18n" when="impl">
255
            Is your module correctly internationalized?
256
            <hint>
257
            Correct internationalization means that it obeys instructions 
258
            at <a href="http://www.netbeans.org/download/dev/javadoc/org-openide-modules/org/openide/modules/doc-files/i18n-branding.html">
259
            NetBeans I18N pages</a>.
260
            </hint>
261
        </question>
262
-->
263
    <answer id="compat-i18n">
264
        <p>
265
            Yes. Currently it has no UI except a ProgressBar which indicates a
266
            connection to a remote host progress.
267
        </p>
268
    </answer>
269
270
271
272
<!--
273
        <question id="compat-standards" when="init">
274
            Does the module implement or define any standards? Is the 
275
            implementation exact or does it deviate somehow?
276
        </question>
277
-->
278
    <answer id="compat-standards">
279
        <p>
280
            N/A
281
        </p>
282
    </answer>
283
284
285
286
<!--
287
        <question id="compat-version" when="impl">
288
            Can your module coexist with earlier and future
289
            versions of itself? Can you correctly read all old settings? Will future
290
            versions be able to read your current settings? Can you read
291
            or politely ignore settings stored by a future version?
292
            
293
            <hint>
294
            Very helpful for reading settings is to store version number
295
            there, so future versions can decide whether how to read/convert
296
            the settings and older versions can ignore the new ones.
297
            </hint>
298
        </question>
299
-->
300
    <answer id="compat-version">
301
        <p>
302
            There is no any persistance in this module (at least for now).
303
            <br/>
304
            Module is extendable with SPI provided.
305
        </p>
306
    </answer>
307
308
309
310
<!--
311
        <question id="dep-jre" when="final">
312
            Which version of JRE do you need (1.2, 1.3, 1.4, etc.)?
313
            <hint>
314
            It is expected that if your module runs on 1.x that it will run 
315
            on 1.x+1 if no, state that please. Also describe here cases where
316
            you run different code on different versions of JRE and why.
317
            </hint>
318
        </question>
319
-->
320
    <answer id="dep-jre">
321
        <p>
322
            jre 1.6+
323
        </p>
324
    </answer>
325
326
327
328
<!--
329
        <question id="dep-jrejdk" when="final">
330
            Do you require the JDK or is the JRE enough?
331
        </question>
332
-->
333
    <answer id="dep-jrejdk">
334
        <p>
335
            JRE is enough.
336
        </p>
337
    </answer>
338
339
340
341
<!--
342
        <question id="dep-nb" when="init">
343
            What other NetBeans projects and modules does this one depend on?
344
            <hint>
345
            Depending on other NetBeans projects influnces the ability of
346
            users of your work to customize their own branded version of
347
            NetBeans by enabling and disabling some modules. Too
348
            much dependencies restrict this kind of customization. If that
349
            is your case, then you may want to split your functionality into
350
            pieces of autoload, eager and regular modules which can be
351
            enabled independently. Usually the answer to this question
352
            is generated from your <code>project.xml</code> file, but
353
            if it is not guessed correctly, you can suppress it by
354
            specifying &lt;defaultanswer generate="none"/&gt; and
355
            write here your own. Please describe such projects as imported APIs using
356
            the <code>&lt;api name="identification" type="import or export" category="stable" url="where is the description" /&gt;</code>.
357
            By doing this information gets listed in the summary page of your
358
            javadoc.
359
            </hint>
360
        </question>
361
-->
362
    <answer id="dep-nb">
363
        <defaultanswer generate='here' />
364
    </answer>
365
366
367
368
<!--
369
        <question id="dep-non-nb" when="init">
370
            What other projects outside NetBeans does this one depend on?
371
            
372
            <hint>
373
            Depending on 3rd party libraries is always problematic,
374
            especially if they are not open source, as that complicates
375
            the licensing scheme of NetBeans. Please enumerate your
376
            external dependencies here, so it is correctly understood since
377
            the begining what are the legal implications of your project.
378
            Also please note that
379
            some non-NetBeans projects are packaged as NetBeans modules
380
            (see <a href="http://libs.netbeans.org/">libraries</a>) and
381
            it is preferred to use this approach when more modules may
382
            depend and share such third-party libraries.
383
            </hint>
384
        </question>
385
-->
386
    <answer id="dep-non-nb">
387
        <p>
388
            none. The default implementation of remote processes support uses jsch.
389
            But this is a different (implementation) module.
390
        </p>
391
    </answer>
392
393
394
395
<!--
396
        <question id="dep-platform" when="init">
397
            On which platforms does your module run? Does it run in the same
398
            way on each?
399
            <hint>
400
            If you plan any dependency on OS or any usage of native code,
401
            please describe why you are doing so and describe how you envision
402
            to enforce the portability of your code.
403
            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
404
            enabled modules</a> which together with autoload/eager modules
405
            can allow you to enable to provide the best OS aware support
406
            on certain OSes while providing compatibility bridge on the not
407
            supported ones.
408
            Also please list the supported
409
            OSes/HW platforms and mentioned the lovest version of JDK required
410
            for your project to run on. Also state whether JRE is enough or
411
            you really need JDK.
412
            </hint>
413
        </question>
414
-->
415
    <answer id="dep-platform">
416
        <p>
417
            This module is almos a pure API/SPI so it is platform-independent.
418
            <br/>
419
            Implementation module with support of Windows, Linux, Solaris and MacOS 
420
            will be provided.
421
        </p>
422
    </answer>
423
424
425
426
<!--
427
        <question id="deploy-dependencies" when="final">
428
            What do other modules need to do to declare a dependency on this one,
429
            in addition to or instead of the normal module dependency declaration
430
            (e.g. tokens to require)?
431
            <hint>
432
                Provide a sample of the actual lines you would add to a module manifest
433
                to declare a dependency, for example OpenIDE-Module-Requires: some.token.
434
                If other modules should not depend on this module, or should just use a
435
                simple regular module dependency, you can just answer "nothing". If you
436
                intentionally expose a semistable API to clients using implementation
437
                dependencies, you should mention that here (but there is no need to give
438
                an example of usage).
439
            </hint>
440
        </question>
441
-->
442
    <answer id="deploy-dependencies">
443
        <p>
444
            This module needs implementation of the "localhost" scheme support.<br/>
445
            OpenIDE-Module-Needs: ConnectionService.localhost
446
        </p>
447
    </answer>
448
449
450
451
<!--
452
        <question id="deploy-jar" when="impl">
453
            Do you deploy just module JAR file(s) or other files as well?
454
            <hint>
455
            Usually a module consist of one JAR file (perhaps with Class-Path
456
            extensions) and also a configuration file that enables it. If you
457
            have any other files, use
458
            &lt;api group="java.io.File" name="yourname" type="export" category="friend"&gt;...&lt;/api&gt;
459
            to define the location, name and stability of your files (of course
460
            changing "yourname" and "friend" to suit your needs).
461
            
462
            If it uses more than one JAR, describe where they are located, how
463
            they refer to each other. 
464
            If it consist of module JAR(s) and other files, please describe
465
            what is their purpose, why other files are necessary. Please 
466
            make sure that installation/uninstallation leaves the system 
467
            in state as it was before installation.
468
            </hint>
469
        </question>
470
-->
471
    <answer id="deploy-jar">
472
        <p>
473
            just JAR.
474
        </p>
475
    </answer>
476
477
478
479
<!--
480
        <question id="deploy-nbm" when="impl">
481
            Can you deploy an NBM via the Update Center?
482
            <hint>
483
            If not why?
484
            </hint>
485
        </question>
486
-->
487
    <answer id="deploy-nbm">
488
        <p>
489
            Yes.
490
        </p>
491
    </answer>
492
493
494
495
<!--
496
        <question id="deploy-packages" when="init">
497
            Are packages of your module made inaccessible by not declaring them
498
            public?
499
            
500
            <hint>
501
            By default NetBeans build harness treats all packages are private.
502
            If you export some of them - either as public or friend packages,
503
            you should have a reason. If the reason is described elsewhere
504
            in this document, you can ignore this question.
505
            </hint>
506
        </question>
507
-->
508
    <answer id="deploy-packages">
509
        <p>
510
            There are several public API/SPI packages provided by this module.
511
        </p>
512
    </answer>
513
514
515
516
<!--
517
        <question id="deploy-shared" when="final">
518
            Do you need to be installed in the shared location only, or in the user directory only,
519
            or can your module be installed anywhere?
520
            <hint>
521
            Installation location shall not matter, if it does explain why.
522
            Consider also whether <code>InstalledFileLocator</code> can help.
523
            </hint>
524
        </question>
525
-->
526
    <answer id="deploy-shared">
527
        <p>
528
            Installation location doesn't not matter, but as this module will 
529
            become a part of the ide cluster, most likely it will be in a shared 
530
            location.
531
        </p>
532
    </answer>
533
534
535
536
<!--
537
        <question id="exec-ant-tasks" when="impl">
538
            Do you define or register any ant tasks that other can use?
539
            
540
            <hint>
541
            If you provide an ant task that users can use, you need to be very
542
            careful about its syntax and behaviour, as it most likely forms an
543
	          API for end users and as there is a lot of end users, their reaction
544
            when such API gets broken can be pretty strong.
545
            </hint>
546
        </question>
547
-->
548
    <answer id="exec-ant-tasks">
549
        <p>
550
            No.
551
        </p>
552
    </answer>
553
554
555
556
<!--
557
        <question id="exec-classloader" when="impl">
558
            Does your code create its own class loader(s)?
559
            <hint>
560
            A bit unusual. Please explain why and what for.
561
            </hint>
562
        </question>
563
-->
564
    <answer id="exec-classloader">
565
        <p>
566
            No.
567
        </p>
568
    </answer>
569
570
571
572
<!--
573
        <question id="exec-component" when="impl">
574
            Is execution of your code influenced by any (string) property
575
            of any of your components?
576
            
577
            <hint>
578
            Often <code>JComponent.getClientProperty</code>, <code>Action.getValue</code>
579
            or <code>PropertyDescriptor.getValue</code>, etc. are used to influence
580
            a behavior of some code. This of course forms an interface that should
581
            be documented. Also if one depends on some interface that an object
582
            implements (<code>component instanceof Runnable</code>) that forms an
583
            API as well.
584
            </hint>
585
        </question>
586
-->
587
    <answer id="exec-component">
588
        <p>
589
            See ConnectionInfoProvider javadoc.
590
        </p>
591
    </answer>
592
593
594
595
<!--
596
        <question id="exec-introspection" when="impl">
597
            Does your module use any kind of runtime type information (<code>instanceof</code>,
598
            work with <code>java.lang.Class</code>, etc.)?
599
            <hint>
600
            Check for cases when you have an object of type A and you also
601
            expect it to (possibly) be of type B and do some special action. That
602
            should be documented. The same applies on operations in meta-level
603
            (Class.isInstance(...), Class.isAssignableFrom(...), etc.).
604
            </hint>
605
        </question>
606
-->
607
    <answer id="exec-introspection">
608
        <p>
609
            There are connection-specific properties that could be of any kind.
610
            SPI implementor defines pairs of property name -- class and later 
611
            API clients are expected to get/set defined properties of defined 
612
            classes. Runtime type checking is performed in put/get methods. See 
613
            javadoc for NativeProcessBuilder, AuthDataProvider.
614
        </p>
615
    </answer>
616
617
618
619
<!--
620
        <question id="exec-privateaccess" when="final">
621
            Are you aware of any other parts of the system calling some of 
622
            your methods by reflection?
623
            <hint>
624
            If so, describe the "contract" as an API. Likely private or friend one, but
625
            still API and consider rewrite of it.
626
            </hint>
627
        </question>
628
-->
629
    <answer id="exec-privateaccess">
630
        <p>
631
            No.
632
        </p>
633
    </answer>
634
635
636
637
<!--
638
        <question id="exec-process" when="impl">
639
            Do you execute an external process from your module? How do you ensure
640
            that the result is the same on different platforms? Do you parse output?
641
            Do you depend on result code?
642
            <hint>
643
            If you feed an input, parse the output please declare that as an API.
644
            </hint>
645
        </question>
646
-->
647
    <answer id="exec-process">
648
        <p>
649
            Yes. This module is about starting external processes. It is up to 
650
            client to work with a result of execution.
651
        </p>
652
    </answer>
653
654
655
656
<!--
657
        <question id="exec-property" when="impl">
658
            Is execution of your code influenced by any environment or
659
            Java system (<code>System.getProperty</code>) property?
660
            On a similar note, is there something interesting that you
661
            pass to <code>java.util.logging.Logger</code>? Or do you observe
662
            what others log?
663
            <hint>
664
            If there is a property that can change the behavior of your 
665
            code, somebody will likely use it. You should describe what it does 
666
            and the <a href="http://wiki.netbeans.org/API_Stability">stability category</a>
667
            of this API. You may use
668
            <pre>
669
                &lt;api type="export" group="property" name="id" category="private" url="http://..."&gt;
670
                    description of the property, where it is used, what it influence, etc.
671
                &lt;/api&gt;            
672
            </pre>
673
            </hint>
674
        </question>
675
-->
676
    <answer id="exec-property">
677
        <p>
678
            "ide.execution.logger.level" is used to define a logger level.
679
        </p>
680
    </answer>
681
682
683
684
<!--
685
        <question id="exec-reflection" when="impl">
686
            Does your code use Java Reflection to execute other code?
687
            <hint>
688
            This usually indicates a missing or insufficient API in the other
689
            part of the system. If the other side is not aware of your dependency
690
            this contract can be easily broken.
691
            </hint>
692
        </question>
693
-->
694
    <answer id="exec-reflection">
695
        <p>
696
            No.
697
        </p>
698
    </answer>
699
700
701
702
<!--
703
        <question id="exec-threading" when="init">
704
            What threading models, if any, does your module adhere to? How the
705
            project behaves with respect to threading?
706
            <hint>
707
                Is your API threadsafe? Can it be accessed from any threads or
708
                just from some dedicated ones? Any special relation to AWT and
709
                its Event Dispatch thread? Also
710
                if your module calls foreign APIs which have a specific threading model,
711
                indicate how you comply with the requirements for multithreaded access
712
                (synchronization, mutexes, etc.) applicable to those APIs.
713
                If your module defines any APIs, or has complex internal structures
714
                that might be used from multiple threads, declare how you protect
715
                data against concurrent access, race conditions, deadlocks, etc.,
716
                and whether such rules are enforced by runtime warnings, errors, assertions, etc.
717
                Examples: a class might be non-thread-safe (like Java Collections); might
718
                be fully thread-safe (internal locking); might require access through a mutex
719
                (and may or may not automatically acquire that mutex on behalf of a client method);
720
                might be able to run only in the event queue; etc.
721
                Also describe when any events are fired: synchronously, asynchronously, etc.
722
                Ideas: <a href="http://core.netbeans.org/proposals/threading/index.html#recommendations">Threading Recommendations</a> (in progress)
723
            </hint>
724
        </question>
725
-->
726
    <answer id="exec-threading">
727
        <p>
728
            Some classes (most) are thread-safe, others are not. If class is not
729
            thread-safe, it is described in a javadoc.
730
        </p>
731
    </answer>
732
733
<!--
734
        <question id="format-clipboard" when="impl">
735
            Which data flavors (if any) does your code read from or insert to
736
            the clipboard (by access to clipboard on means calling methods on <code>java.awt.datatransfer.Transferable</code>?
737
            
738
            <hint>
739
            Often Node's deal with clipboard by usage of <code>Node.clipboardCopy, Node.clipboardCut and Node.pasteTypes</code>.
740
            Check your code for overriding these methods.
741
            </hint>
742
        </question>
743
-->
744
    <answer id="format-clipboard">
745
        <p>
746
            N/A
747
        </p>
748
    </answer>
749
750
751
752
<!--
753
        <question id="format-dnd" when="impl">
754
            Which protocols (if any) does your code understand during Drag &amp; Drop?
755
            <hint>
756
            Often Node's deal with clipboard by usage of <code>Node.drag, Node.getDropType</code>. 
757
            Check your code for overriding these methods. Btw. if they are not overridden, they
758
            by default delegate to <code>Node.clipboardCopy, Node.clipboardCut and Node.pasteTypes</code>.
759
            </hint>
760
        </question>
761
-->
762
    <answer id="format-dnd">
763
        <p>
764
            N/A
765
        </p>
766
    </answer>
767
768
769
770
<!--
771
        <question id="format-types" when="impl">
772
            Which protocols and file formats (if any) does your module read or write on disk,
773
            or transmit or receive over the network? Do you generate an ant build script?
774
            Can it be edited and modified? 
775
            
776
            <hint>
777
            <p>
778
            Files can be read and written by other programs, modules and users. If they influence
779
            your behaviour, make sure you either document the format or claim that it is a private
780
            api (using the &lt;api&gt; tag). 
781
            </p>
782
            
783
            <p>
784
            If you generate an ant build file, this is very likely going to be seen by end users and
785
            they will be attempted to edit it. You should be ready for that and provide here a link
786
            to documentation that you have for such purposes and also describe how you are going to
787
            understand such files during next release, when you (very likely) slightly change the 
788
            format.
789
            </p>
790
            </hint>
791
        </question>
792
-->
793
    <answer id="format-types">
794
        <p>
795
            N/A
796
        </p>
797
    </answer>
798
799
800
801
<!--
802
        <question id="lookup-lookup" when="init">
803
            Does your module use <code>org.openide.util.Lookup</code>
804
            or any similar technology to find any components to communicate with? Which ones?
805
            
806
            <hint>
807
            NetBeans is build around a generic registry of services called
808
            lookup. It is preferable to use it for registration and discovery
809
            if possible. See
810
            <a href="http://www.netbeans.org/download/dev/javadoc/org-openide-util/org/openide/util/lookup/doc-files/index.html">
811
            The Solution to Comunication Between Components
812
            </a>. If you do not plan to use lookup and insist usage
813
            of other solution, then please describe why it is not working for
814
            you.
815
            <br/>
816
            When filling the final version of your arch document, please
817
            describe the interfaces you are searching for, where 
818
            are defined, whether you are searching for just one or more of them,
819
            if the order is important, etc. Also classify the stability of such
820
            API contract. Use &lt;api group=&amp;lookup&amp; /&gt; tag, so
821
            your information gets listed in the summary page of your javadoc.
822
            </hint>
823
        </question>
824
-->
825
    <answer id="lookup-lookup">
826
        <p>
827
            Yes, Lookup is in use. Connection has an associated Lookup that is 
828
            explored to get implementations of some specific services 
829
            (like ConnectionInfoProvider, SignalSupportProvider).
830
            Also AuthDataProvider, URIIdentifier and Connector implementations 
831
            are registered in the global lookup within a "ConnectionService/&lt;scheme&gt;"
832
            path.
833
        </p>
834
    </answer>
835
836
837
838
<!--
839
        <question id="lookup-register" when="final">
840
            Do you register anything into lookup for other code to find?
841
            <hint>
842
            Do you register using layer file or using a declarative annotation such as <code>@ServiceProvider</code>?
843
            Who is supposed to find your component?
844
            </hint>
845
        </question>
846
-->
847
    <answer id="lookup-register">
848
        <p>
849
            No.
850
        </p>
851
    </answer>
852
853
854
855
<!--
856
        <question id="lookup-remove" when="final">
857
            Do you remove entries of other modules from lookup?
858
            <hint>
859
            Why? Of course, that is possible, but it can be dangerous. Is the module
860
            your are masking resource from aware of what you are doing?
861
            </hint>
862
        </question>
863
-->
864
    <answer id="lookup-remove">
865
        <p>
866
            No.
867
        </p>
868
    </answer>
869
870
871
872
<!--
873
        <question id="perf-exit" when="final">
874
            Does your module run any code on exit?
875
        </question>
876
-->
877
    <answer id="perf-exit">
878
        <p>
879
            No.
880
        </p>
881
    </answer>
882
883
884
885
<!--
886
        <question id="perf-huge_dialogs" when="final">
887
            Does your module contain any dialogs or wizards with a large number of
888
            GUI controls such as combo boxes, lists, trees, or text areas?
889
        </question>
890
-->
891
    <answer id="perf-huge_dialogs">
892
        <p>
893
            No.
894
        </p>
895
    </answer>
896
897
898
899
<!--
900
        <question id="perf-limit" when="init">
901
            Are there any hard-coded or practical limits in the number or size of
902
            elements your code can handle?
903
            <hint>
904
                Most of algorithms have increasing memory and speed complexity
905
                with respect to size of data they operate on. What is the critical
906
                part of your project that can be seen as a bottleneck with
907
                respect to speed or required memory? What are the practical
908
                sizes of data you tested your project with? What is your estimate
909
                of potential size of data that would cause visible performance
910
                problems? Is there some kind of check to detect such situation
911
                and prevent "hard" crashes - for example the CloneableEditorSupport
912
                checks for size of a file to be opened in editor
913
                and if it is larger than 1Mb it shows a dialog giving the
914
                user the right to decide - e.g. to cancel or commit suicide.
915
            </hint>
916
        </question>
917
-->
918
    <answer id="perf-limit">
919
        <p>
920
            No.
921
        </p>
922
    </answer>
923
924
925
926
<!--
927
        <question id="perf-mem" when="final">
928
            How much memory does your component consume? Estimate
929
            with a relation to the number of windows, etc.
930
        </question>
931
-->
932
    <answer id="perf-mem">
933
        <p>
934
            N/A
935
        </p>
936
    </answer>
937
938
939
940
<!--
941
        <question id="perf-menus" when="final">
942
            Does your module use dynamically updated context menus, or
943
            context-sensitive actions with complicated and slow enablement logic?
944
            <hint>
945
                If you do a lot of tricks when adding actions to regular or context menus, you can significantly
946
                slow down display of the menu, even when the user is not using your action. Pay attention to
947
                actions you add to the main menu bar, and to context menus of foreign nodes or components. If
948
                the action is conditionally enabled, or changes its display dynamically, you need to check the
949
                impact on performance. In some cases it may be more appropriate to make a simple action that is
950
                always enabled but does more detailed checks in a dialog if it is actually run.
951
            </hint>
952
        </question>
953
-->
954
    <answer id="perf-menus">
955
        <p>
956
            No.
957
        </p>
958
    </answer>
959
960
961
962
<!--
963
        <question id="perf-progress" when="final">
964
            Does your module execute any long-running tasks?
965
            
966
            <hint>Long running tasks should never block 
967
            AWT thread as it badly hurts the UI
968
            <a href="http://performance.netbeans.org/responsiveness/issues.html">
969
            responsiveness</a>.
970
            Tasks like connecting over
971
            network, computing huge amount of data, compilation
972
            be done asynchronously (for example
973
            using <code>RequestProcessor</code>), definitively it should 
974
            not block AWT thread.
975
            </hint>
976
        </question>
977
-->
978
    <answer id="perf-progress">
979
        <p>
980
            Yes. They are run outside the ETD.
981
        </p>
982
    </answer>
983
984
985
986
<!--
987
        <question id="perf-scale" when="init">
988
            Which external criteria influence the performance of your
989
            program (size of file in editor, number of files in menu, 
990
            in source directory, etc.) and how well your code scales?
991
            <hint>
992
            Please include some estimates, there are other more detailed 
993
            questions to answer in later phases of implementation. 
994
            </hint>
995
        </question>
996
-->
997
    <answer id="perf-scale">
998
        <p>
999
            N/A
1000
        </p>
1001
    </answer>
1002
1003
1004
1005
<!--
1006
        <question id="perf-spi" when="init">
1007
            How the performance of the plugged in code will be enforced?
1008
            <hint>
1009
            If you allow foreign code to be plugged into your own module, how
1010
            do you enforce that it will behave correctly and quickly and will not
1011
            negatively influence the performance of your own module?
1012
            </hint>
1013
        </question>
1014
-->
1015
    <answer id="perf-spi">
1016
        <p>
1017
            There is a code that can be plugged in and that can influence the
1018
            performance (like listeners implementations, as they are notified 
1019
            synchroniously). But this is done outside the EDT... <br/>
1020
        </p>
1021
    </answer>
1022
1023
1024
1025
<!--
1026
        <question id="perf-startup" when="final">
1027
            Does your module run any code on startup?
1028
        </question>
1029
-->
1030
    <answer id="perf-startup">
1031
        <p>
1032
            No.
1033
        </p>
1034
    </answer>
1035
1036
1037
1038
<!--
1039
        <question id="perf-wakeup" when="final">
1040
            Does any piece of your code wake up periodically and do something
1041
            even when the system is otherwise idle (no user interaction)?
1042
        </question>
1043
-->
1044
    <answer id="perf-wakeup">
1045
        <p>
1046
            Yes. There is a thread that is started once a second to test if all 
1047
            known connections are still alive.
1048
            <br/>
1049
            This thread exists only if there are listeners that are waiting for
1050
            "connection lost" event and only if there is at least one active
1051
            connection.
1052
        </p>
1053
    </answer>
1054
1055
1056
1057
<!--
1058
        <question id="resources-file" when="final">
1059
            Does your module use <code>java.io.File</code> directly?
1060
            
1061
            <hint>
1062
            NetBeans provide a logical wrapper over plain files called 
1063
            <code>org.openide.filesystems.FileObject</code> that
1064
            provides uniform access to such resources and is the preferred
1065
            way that should be used. But of course there can be situations when
1066
            this is not suitable.
1067
            </hint>
1068
        </question>
1069
-->
1070
    <answer id="resources-file">
1071
        <p>
1072
            No.
1073
        </p>
1074
    </answer>
1075
1076
1077
1078
<!--
1079
        <question id="resources-layer" when="final">
1080
            Does your module provide own layer? Does it create any files or
1081
            folders in it? What it is trying to communicate by that and with which 
1082
            components?
1083
            
1084
            <hint>
1085
            NetBeans allows automatic and declarative installation of resources 
1086
            by module layers. Module register files into appropriate places
1087
            and other components use that information to perform their task
1088
            (build menu, toolbar, window layout, list of templates, set of
1089
            options, etc.). 
1090
            </hint>
1091
        </question>
1092
-->
1093
    <answer id="resources-layer">
1094
        <p>
1095
            No.
1096
        </p>
1097
    </answer>
1098
1099
1100
1101
<!--
1102
        <question id="resources-mask" when="final">
1103
            Does your module mask/hide/override any resources provided by other modules in
1104
            their layers?
1105
            
1106
            <hint>
1107
            If you mask a file provided by another module, you probably depend
1108
            on that and do not want the other module to (for example) change
1109
            the file's name. That module shall thus make that file available as an API
1110
            of some stability category.
1111
            </hint>
1112
        </question>
1113
-->
1114
    <answer id="resources-mask">
1115
        <p>
1116
            No.
1117
        </p>
1118
    </answer>
1119
1120
1121
1122
<!--
1123
        <question id="resources-preferences" when="final">
1124
            Does your module uses preferences via Preferences API? Does your module use NbPreferences or
1125
            or regular JDK Preferences ? Does it read, write or both ? 
1126
            Does it share preferences with other modules ? If so, then why ?
1127
            <hint>
1128
                You may use
1129
                    &lt;api type="export" group="preferences"
1130
                    name="preference node name" category="private"&gt;
1131
                    description of individual keys, where it is used, what it
1132
                    influences, whether the module reads/write it, etc.
1133
                    &lt;/api&gt;
1134
                Due to XML ID restrictions, rather than /org/netbeans/modules/foo give the "name" as org.netbeans.modules.foo.
1135
                Note that if you use NbPreferences this name will then be the same as the code name base of the module.
1136
            </hint>
1137
        </question>
1138
-->
1139
    <answer id="resources-preferences">
1140
        <p>
1141
            No.
1142
        </p>
1143
    </answer>
1144
1145
1146
1147
<!--
1148
        <question id="resources-read" when="final">
1149
            Does your module read any resources from layers? For what purpose?
1150
            
1151
            <hint>
1152
            As this is some kind of intermodule dependency, it is a kind of API.
1153
            Please describe it and classify according to 
1154
            <a href="http://wiki.netbeans.org/API_Design#What_is_an_API.3F">
1155
            common stability categories</a>.
1156
            </hint>
1157
        </question>
1158
-->
1159
    <answer id="resources-read">
1160
        <p>
1161
            No.
1162
        </p>
1163
    </answer>
1164
1165
1166
1167
<!--
1168
        <question id="security-grant" when="final">
1169
            Does your code grant additional rights to some other code?
1170
            <hint>Avoid using a class loader that adds extra
1171
            permissions to loaded code unless really necessary.
1172
            Also note that your API implementation
1173
            can also expose unneeded permissions to enemy code by
1174
            calling AccessController.doPrivileged().</hint>
1175
        </question>
1176
-->
1177
    <answer id="security-grant">
1178
        <p>
1179
            No.
1180
        </p>
1181
    </answer>
1182
1183
1184
1185
<!--
1186
        <question id="security-policy" when="final">
1187
            Does your functionality require modifications to the standard policy file?
1188
            <hint>Your code might pass control to third-party code not
1189
            coming from trusted domains. This could be code downloaded over the
1190
            network or code coming from libraries that are not bundled
1191
            with NetBeans. Which permissions need to be granted to which domains?</hint>
1192
        </question>
1193
-->
1194
    <answer id="security-policy">
1195
        <p>
1196
            No.
1197
        </p>
1198
    </answer>
1199
1200
</api-answers>
(-)a/cnd.execution/build.xml (+5 lines)
Line 0 Link Here
1
<?xml version="1.0" encoding="UTF-8"?>
2
<project basedir="." default="netbeans" name="cnd.execution">
3
    <description>Builds, tests, and runs the project org.netbeans.modules.nativeexecution</description>
4
    <import file="../nbbuild/templates/projectized.xml"/>
5
</project>
(-)a/cnd.execution/manifest.mf (+8 lines)
Line 0 Link Here
1
Manifest-Version: 1.0
2
AutoUpdate-Show-In-Client: false
3
OpenIDE-Module: org.netbeans.modules.cnd.execution
4
OpenIDE-Module-Implementation-Version: 1
5
OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/cnd/execution/resources/Bundle.properties
6
OpenIDE-Module-Needs: ConnectionService.localhost
7
OpenIDE-Module-Provides: org.netbeans.modules.dlight.spi.terminal.ConnectionProvider
8
(-)a/cnd.execution/nbproject/project.properties (+5 lines)
Line 0 Link Here
1
javac.source=1.6
2
javac.compilerargs=-Xlint -Xlint:-serial
3
javadoc.arch=${basedir}/arch.xml
4
spec.version.base=1.0
5
(-)a/cnd.execution/nbproject/project.xml (+108 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.modules.cnd.execution</code-name-base>
7
            <module-dependencies>
8
                <dependency>
9
                    <code-name-base>org.netbeans.api.progress</code-name-base>
10
                    <build-prerequisite/>
11
                    <compile-dependency/>
12
                    <run-dependency>
13
                        <release-version>1</release-version>
14
                        <specification-version>1.28</specification-version>
15
                    </run-dependency>
16
                </dependency>
17
                <dependency>
18
                    <code-name-base>org.netbeans.modules.dlight.terminal</code-name-base>
19
                    <build-prerequisite/>
20
                    <compile-dependency/>
21
                    <run-dependency>
22
                        <specification-version>1.14</specification-version>
23
                    </run-dependency>
24
                </dependency>
25
                <dependency>
26
                    <code-name-base>org.netbeans.modules.extexecution</code-name-base>
27
                    <build-prerequisite/>
28
                    <compile-dependency/>
29
                    <run-dependency>
30
                        <release-version>2</release-version>
31
                        <specification-version>1.36</specification-version>
32
                    </run-dependency>
33
                </dependency>
34
                <dependency>
35
                    <code-name-base>org.openide.modules</code-name-base>
36
                    <build-prerequisite/>
37
                    <compile-dependency/>
38
                    <run-dependency>
39
                        <specification-version>7.32</specification-version>
40
                    </run-dependency>
41
                </dependency>
42
                <dependency>
43
                    <code-name-base>org.openide.util</code-name-base>
44
                    <build-prerequisite/>
45
                    <compile-dependency/>
46
                    <run-dependency>
47
                        <specification-version>8.24</specification-version>
48
                    </run-dependency>
49
                </dependency>
50
                <dependency>
51
                    <code-name-base>org.openide.util.lookup</code-name-base>
52
                    <build-prerequisite/>
53
                    <compile-dependency/>
54
                    <run-dependency>
55
                        <specification-version>8.15</specification-version>
56
                    </run-dependency>
57
                </dependency>
58
            </module-dependencies>
59
            <test-dependencies>
60
                <test-type>
61
                    <name>unit</name>
62
                    <test-dependency>
63
                        <code-name-base>org.netbeans.api.progress</code-name-base>
64
                        <compile-dependency/>
65
                    </test-dependency>
66
                    <test-dependency>
67
                        <code-name-base>org.netbeans.libs.junit4</code-name-base>
68
                        <compile-dependency/>
69
                    </test-dependency>
70
                    <test-dependency>
71
                        <code-name-base>org.netbeans.modules.nbjunit</code-name-base>
72
                        <recursive/>
73
                        <compile-dependency/>
74
                    </test-dependency>
75
                    <test-dependency>
76
                        <code-name-base>org.netbeans.modules.progress.ui</code-name-base>
77
                        <recursive/>
78
                        <compile-dependency/>
79
                    </test-dependency>
80
                    <test-dependency>
81
                        <code-name-base>org.openide.dialogs</code-name-base>
82
                        <compile-dependency/>
83
                    </test-dependency>
84
                    <test-dependency>
85
                        <code-name-base>org.openide.util</code-name-base>
86
                        <recursive/>
87
                        <compile-dependency/>
88
                    </test-dependency>
89
                    <test-dependency>
90
                        <code-name-base>org.openide.util.lookup</code-name-base>
91
                        <compile-dependency/>
92
                    </test-dependency>
93
                </test-type>
94
            </test-dependencies>
95
            <public-packages>
96
                <package>org.netbeans.modules.cnd.execution.api</package>
97
                <package>org.netbeans.modules.cnd.execution.api.config</package>
98
                <package>org.netbeans.modules.cnd.execution.api.process</package>
99
                <package>org.netbeans.modules.cnd.execution.spi</package>
100
                <package>org.netbeans.modules.cnd.execution.spi.support</package>
101
                <package>org.netbeans.modules.cnd.execution.util</package>
102
            </public-packages>
103
        </data>
104
        <spellchecker-wordlist xmlns="http://www.netbeans.org/ns/spellchecker-wordlist/1">
105
            <word>bitness</word>
106
        </spellchecker-wordlist>
107
    </configuration>
108
</project>
(-)a/cnd.execution/src/org/netbeans/modules/cnd/execution/ExecutionLogger.java (+188 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2012 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 2012 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.cnd.execution;
43
44
import java.util.Map;
45
import java.util.Set;
46
import java.util.WeakHashMap;
47
import java.util.logging.Level;
48
import java.util.logging.LogRecord;
49
import java.util.logging.Logger;
50
import java.util.logging.StreamHandler;
51
import javax.swing.SwingUtilities;
52
53
/**
54
 *
55
 * @author akrasny
56
 */
57
public final class ExecutionLogger extends Logger {
58
59
    private static final boolean assertionsEnabled;
60
    private static final ExecutionLogger instance = new ExecutionLogger();
61
    private static final Map<Ref, String> map = new WeakHashMap<Ref, String>();
62
63
    static {
64
        boolean ea = false;
65
        assert (ea = true);
66
        assertionsEnabled = ea;
67
        String level_str = System.getProperty("ide.execution.logger.level", "SEVERE").toUpperCase(); // NOI18N
68
        Level level = Level.SEVERE;
69
70
        try {
71
            level = Level.parse(level_str);
72
        } catch (IllegalArgumentException ex) {
73
        }
74
75
        instance.addHandler(new LoggerHandler());
76
        instance.setLevel(level);
77
    }
78
    private static final long startTimeMillis = System.currentTimeMillis();
79
80
    private static class LoggerHandler extends StreamHandler {
81
82
        public LoggerHandler() {
83
            setOutputStream(System.out);
84
        }
85
86
        @Override
87
        public void publish(LogRecord record) {
88
            record.setMessage("[" + (record.getMillis() - startTimeMillis) + " ms.] " + record.getMessage()); // NOI18N
89
            super.publish(record);
90
            super.flush();
91
        }
92
93
        @Override
94
        public void flush() {
95
        }
96
97
        @Override
98
        public void close() throws SecurityException {
99
        }
100
    }
101
102
    private ExecutionLogger() {
103
        super("nativeexecution.logger", null); // NOI18N
104
        setLevel(Level.ALL);
105
    }
106
107
    public static ExecutionLogger getInstance() {
108
        return instance;
109
    }
110
111
    public Ref reportStart(String descr) {
112
        Ref r = new Ref();
113
        log(Level.INFO, "{0} STARTED", descr); // NOI18N
114
        synchronized (map) {
115
            map.put(r, descr);
116
        }
117
        return r;
118
    }
119
120
    public void reportDone(Ref ref) {
121
        String descr;
122
        synchronized (map) {
123
            descr = map.remove(ref);
124
        }
125
        if (descr == null) {
126
            return;
127
        }
128
        log(Level.INFO, "{0} FINISHED in {1} ms.", new Object[]{descr, System.currentTimeMillis() - ref.ts}); // NOI18N
129
    }
130
131
    public static void assertTrue(boolean value) {
132
        if (assertionsEnabled && !value) {
133
            String message = "Assertion error"; // NOI18N
134
            instance.log(Level.SEVERE, message, new Exception(message));
135
        }
136
    }
137
138
    public static void assertTrue(boolean value, String message) {
139
        if (assertionsEnabled && !value) {
140
            instance.log(Level.SEVERE, message, new Exception(message));
141
        }
142
    }
143
144
    public static void assertFalse(boolean value) {
145
        if (assertionsEnabled && value) {
146
            String message = "Assertion error"; // NOI18N
147
            instance.log(Level.SEVERE, message, new Exception(message));
148
        }
149
    }
150
151
    public static void assertFalse(boolean value, String message) {
152
        if (assertionsEnabled && value) {
153
            instance.log(Level.SEVERE, message, new Exception(message));
154
        }
155
    }
156
157
    public static void assertNonUiThread(String message) {
158
        if (assertionsEnabled && SwingUtilities.isEventDispatchThread()) {
159
            instance.log(Level.FINE, message, new Exception(message));
160
        }
161
    }
162
163
    public static void assertNonUiThread() {
164
        assertNonUiThread("Should not be called from UI thread"); // NOI18N
165
    }
166
167
    public static void fullThreadDump(String title) {
168
        final Set<Map.Entry<Thread, StackTraceElement[]>> stack = Thread.getAllStackTraces().entrySet();
169
        System.err.printf("----- %s Start Thread Dump-----\n", title == null ? "" : title); // NOI18N
170
        for (Map.Entry<Thread, StackTraceElement[]> entry : stack) {
171
            System.err.println(entry.getKey().getName());
172
            for (StackTraceElement element : entry.getValue()) {
173
                System.err.println("\tat " + element.toString()); // NOI18N
174
            }
175
            System.err.println();
176
        }
177
        System.err.println("----- End Thread Dump-----"); // NOI18N
178
    }
179
180
    public static class Ref {
181
182
        private final long ts;
183
184
        private Ref() {
185
            this.ts = System.currentTimeMillis();
186
        }
187
    }
188
}
(-)a/cnd.execution/src/org/netbeans/modules/cnd/execution/NativeProcessFactory.java (+127 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2012 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 2012 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.cnd.execution;
43
44
import java.io.IOException;
45
import java.util.List;
46
import java.util.Map;
47
import org.netbeans.api.extexecution.Environment;
48
import org.netbeans.modules.cnd.execution.api.NativeExecutionException;
49
import org.netbeans.modules.cnd.execution.api.NativeProcessBuilder;
50
import org.netbeans.spi.extexecution.EnvironmentFactory;
51
import org.netbeans.spi.extexecution.EnvironmentImplementation;
52
import org.netbeans.spi.extexecution.ProcessBuilderImplementation2;
53
import org.netbeans.spi.extexecution.ProcessParameters;
54
import org.openide.util.Lookup;
55
56
/**
57
 *
58
 * @author Petr Hejl
59
 */
60
public class NativeProcessFactory implements ProcessBuilderImplementation2 {
61
62
    private final NativeProcessBuilder builder;
63
64
    private final Environment environment;
65
66
    public NativeProcessFactory(NativeProcessBuilder builder) {
67
        this.builder = builder;
68
        this.environment = EnvironmentFactory.createEnvironment(new NativeEnvironment());
69
    }
70
71
    @Override
72
    public Environment getEnvironment() {
73
        return environment;
74
    }
75
76
    @Override
77
    public Lookup getLookup() {
78
        return builder.getLookup();
79
    }
80
81
    @Override
82
    public Process createProcess(ProcessParameters parameters) throws IOException {
83
        builder.setCommand(parameters.getExecutable(),
84
                parameters.getArguments().toArray(new String[parameters.getArguments().size()]));
85
        builder.setWorkingDirectory(parameters.getWorkingDirectory());
86
        builder.redirectErrorStream(parameters.isRedirectErrorStream());
87
88
        try {
89
            return builder.call();
90
        } catch (NativeExecutionException ex) {
91
            throw new IOException(ex);
92
        }
93
    }
94
95
    private class NativeEnvironment implements EnvironmentImplementation {
96
97
        @Override
98
        public String getVariable(String name) {
99
            return builder.getEnvironmentMap().get(name);
100
        }
101
102
        @Override
103
        public void appendPath(String name, String value) {
104
            builder.getEnvironmentMap().appendPath(name, value, false);
105
        }
106
107
        @Override
108
        public void prependPath(String name, String value) {
109
            builder.getEnvironmentMap().prependPath(name, value, false);
110
        }
111
112
        @Override
113
        public void setVariable(String name, String value) {
114
            builder.getEnvironmentMap().put(name, value, false);
115
        }
116
117
        @Override
118
        public void removeVariable(String name) {
119
            builder.getEnvironmentMap().remove(name);
120
        }
121
122
        @Override
123
        public Map<String, String> values() {
124
            return builder.getEnvironmentMap().toMap();
125
        }
126
    }
127
}
(-)a/cnd.execution/src/org/netbeans/modules/cnd/execution/access/ConnectionAccessor.java (+86 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2012 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 2012 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.cnd.execution.access;
43
44
import org.netbeans.modules.cnd.execution.api.Connection;
45
import org.netbeans.modules.cnd.execution.spi.ConnectionImplementation;
46
import org.openide.util.Lookup;
47
48
/**
49
 *
50
 * @author akrasny
51
 */
52
public abstract class ConnectionAccessor {
53
54
    private static volatile ConnectionAccessor DEFAULT;
55
56
    public static void setDefault(ConnectionAccessor accessor) {
57
        if (DEFAULT != null) {
58
            throw new IllegalStateException(
59
                    "ConnectionManagerAccessor is already defined"); // NOI18N
60
        }
61
62
        DEFAULT = accessor;
63
    }
64
65
    public static synchronized ConnectionAccessor getDefault() {
66
        if (DEFAULT != null) {
67
            return DEFAULT;
68
        }
69
70
        try {
71
            Class.forName(Connection.class.getName(), true,
72
                    Connection.class.getClassLoader());
73
        } catch (ClassNotFoundException ex) {
74
        }
75
76
        return DEFAULT;
77
    }
78
79
    public abstract Connection createConnection(ConnectionImplementation impl);
80
81
    public abstract Lookup getConnectionLookup(Connection connection);
82
83
    public abstract void setImpl(Connection connection, ConnectionImplementation impl);
84
85
    public abstract ConnectionImplementation getImpl(Connection connection);
86
}
(-)a/cnd.execution/src/org/netbeans/modules/cnd/execution/access/EnvironmentMapAccessor.java (+88 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2012 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 2012 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.cnd.execution.access;
43
44
import java.util.Map;
45
import org.netbeans.modules.cnd.execution.api.EnvironmentMap;
46
47
/**
48
 *
49
 * @author akrasny
50
 */
51
public abstract class EnvironmentMapAccessor {
52
53
    private static volatile EnvironmentMapAccessor DEFAULT;
54
55
    public static void setDefault(EnvironmentMapAccessor accessor) {
56
        if (DEFAULT != null) {
57
            throw new IllegalStateException(
58
                    "ConnectionManagerAccessor is already defined"); // NOI18N
59
        }
60
61
        DEFAULT = accessor;
62
    }
63
64
    public static synchronized EnvironmentMapAccessor getDefault() {
65
        if (DEFAULT != null) {
66
            return DEFAULT;
67
        }
68
69
        try {
70
            Class.forName(EnvironmentMap.class.getName(), true,
71
                    EnvironmentMap.class.getClassLoader());
72
        } catch (ClassNotFoundException ex) {
73
        }
74
75
        return DEFAULT;
76
    }
77
78
//    public abstract void store(EnvironmentMap envMap, Preferences envprop) throws BackingStoreException;
79
//
80
//    public abstract EnvironmentMap load(Preferences envprop) throws BackingStoreException;
81
    public abstract Map<String, String> getModifiedVars(EnvironmentMap environmentMap);
82
83
    public abstract EnvironmentMap createBasedOn(EnvironmentMap map);
84
85
    public abstract EnvironmentMap createCasePreserving(char pathSeparator);
86
87
    public abstract EnvironmentMap createCaseSensitive(char pathSeparator);
88
}
(-)a/cnd.execution/src/org/netbeans/modules/cnd/execution/access/NativeProcessAccessor.java (+82 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2012 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 2012 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.cnd.execution.access;
43
44
import org.netbeans.modules.cnd.execution.api.Connection;
45
import org.netbeans.modules.cnd.execution.common.NativeProcess;
46
import org.netbeans.modules.cnd.execution.spi.NativeProcessParams;
47
48
/**
49
 *
50
 * @author akrasny
51
 */
52
public abstract class NativeProcessAccessor {
53
54
    private static volatile NativeProcessAccessor DEFAULT;
55
56
    public static void setDefault(NativeProcessAccessor accessor) {
57
        if (DEFAULT != null) {
58
            throw new IllegalStateException(
59
                    "NativeProcessAccessor is already defined"); // NOI18N
60
        }
61
62
        DEFAULT = accessor;
63
    }
64
65
    public static synchronized NativeProcessAccessor getDefault() {
66
        if (DEFAULT != null) {
67
            return DEFAULT;
68
        }
69
70
        try {
71
            Class.forName(NativeProcess.class.getName(), true,
72
                    NativeProcess.class.getClassLoader());
73
        } catch (ClassNotFoundException ex) {
74
        }
75
76
        return DEFAULT;
77
    }
78
79
    public abstract NativeProcessParams getProcessParams(final NativeProcess process);
80
81
    public abstract Connection getConnection(final NativeProcess process);
82
}
(-)a/cnd.execution/src/org/netbeans/modules/cnd/execution/access/NativeProcessBuilderFactory.java (+80 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2012 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 2012 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.cnd.execution.access;
43
44
import org.netbeans.modules.cnd.execution.api.Connection;
45
import org.netbeans.modules.cnd.execution.api.NativeProcessBuilder;
46
import org.netbeans.modules.cnd.execution.spi.NativeProcessCreator;
47
48
/**
49
 *
50
 * @author akrasny
51
 */
52
public abstract class NativeProcessBuilderFactory {
53
54
    private static volatile NativeProcessBuilderFactory DEFAULT;
55
56
    public static void setDefault(NativeProcessBuilderFactory accessor) {
57
        if (DEFAULT != null) {
58
            throw new IllegalStateException(
59
                    "NativeProcessBuilderFactory is already defined"); // NOI18N
60
        }
61
62
        DEFAULT = accessor;
63
    }
64
65
    public static synchronized NativeProcessBuilderFactory getDefault() {
66
        if (DEFAULT != null) {
67
            return DEFAULT;
68
        }
69
70
        try {
71
            Class.forName(NativeProcessBuilder.class.getName(), true,
72
                    NativeProcessBuilder.class.getClassLoader());
73
        } catch (ClassNotFoundException ex) {
74
        }
75
76
        return DEFAULT;
77
    }
78
79
    public abstract NativeProcessBuilder newProcessBuilder(NativeProcessCreator impl, Connection connection);
80
}
(-)a/cnd.execution/src/org/netbeans/modules/cnd/execution/access/NativeProcessParamsFactory.java (+85 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2012 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 2012 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.cnd.execution.access;
43
44
import java.util.List;
45
import java.util.Map;
46
import org.netbeans.modules.cnd.execution.api.Connection;
47
import org.netbeans.modules.cnd.execution.spi.NativeProcessParams;
48
import org.openide.util.Lookup;
49
50
/**
51
 *
52
 * @author akrasny
53
 */
54
public abstract class NativeProcessParamsFactory {
55
56
    private static volatile NativeProcessParamsFactory DEFAULT;
57
58
    public static void setDefault(NativeProcessParamsFactory accessor) {
59
        if (DEFAULT != null) {
60
            throw new IllegalStateException(
61
                    "NativeProcessParamsFactory is already defined"); // NOI18N
62
        }
63
64
        DEFAULT = accessor;
65
    }
66
67
    public static synchronized NativeProcessParamsFactory getDefault() {
68
        if (DEFAULT != null) {
69
            return DEFAULT;
70
        }
71
72
        try {
73
            Class.forName(NativeProcessParams.class.getName(), true,
74
                    NativeProcessParams.class.getClassLoader());
75
        } catch (ClassNotFoundException ex) {
76
        }
77
78
        return DEFAULT;
79
    }
80
81
    public abstract NativeProcessParams newNativeProcessParams(Connection connection,
82
            Map<String, String> connectionInfo, Map<String, String> environmentMap,
83
            List<String> command, String shell, String shellScript, boolean redirectError,
84
            String wdir, Lookup lookup);
85
}
(-)a/cnd.execution/src/org/netbeans/modules/cnd/execution/api/BrokenConnectionException.java (+62 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2012 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 2012 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.cnd.execution.api;
43
44
import java.net.URI;
45
46
/**
47
 * Extension of the ConnectionException that is thrown when some action that
48
 * requires an active connection is invoked on a dead one.
49
 *
50
 * @author akrasny
51
 */
52
public class BrokenConnectionException extends ConnectionException {
53
54
    /**
55
     * Constructs a new BrokenConnectionException.
56
     *
57
     * @param uri an URI of the broken connection.
58
     */
59
    public BrokenConnectionException(URI uri) {
60
        super(uri, "HOST_NOT_CONNECTED"); // NOI18N
61
    }
62
}
(-)a/cnd.execution/src/org/netbeans/modules/cnd/execution/api/Bundle.properties (+43 lines)
Line 0 Link Here
1
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
2
#
3
# Copyright 2012 Oracle and/or its affiliates. All rights reserved.
4
#
5
# Oracle and Java are registered trademarks of Oracle and/or its affiliates.
6
# Other names may be trademarks of their respective owners.
7
#
8
# The contents of this file are subject to the terms of either the GNU
9
# General Public License Version 2 only ("GPL") or the Common
10
# Development and Distribution License("CDDL") (collectively, the
11
# "License"). You may not use this file except in compliance with the
12
# License. You can obtain a copy of the License at
13
# http://www.netbeans.org/cddl-gplv2.html
14
# or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
15
# specific language governing permissions and limitations under the
16
# License.  When distributing the software, include this License Header
17
# Notice in each file and include the License file at
18
# nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
19
# particular file as subject to the "Classpath" exception as provided
20
# by Oracle in the GPL Version 2 section of the License file that
21
# accompanied this code. If applicable, add the following below the
22
# License Header, with the fields enclosed by brackets [] replaced by
23
# your own identifying information:
24
# "Portions Copyrighted [year] [name of copyright owner]"
25
#
26
# If you wish your version of this file to be governed by only the CDDL
27
# or only the GPL Version 2, indicate your decision by adding
28
# "[Contributor] elects to include this software in this distribution
29
# under the [CDDL or GPL Version 2] license." If you do not indicate a
30
# single choice of license, a recipient has the option to distribute
31
# your version of this file under either the CDDL, the GPL Version 2 or
32
# to extend the choice of license to its licensees as provided above.
33
# However, if you add GPL Version 2 code and therefore, elected the GPL
34
# Version 2 license, then the option applies only if the new code is
35
# made subject to such option by the copyright holder.
36
#
37
# Contributor(s):
38
#
39
# Portions Copyrighted 2012 Sun Microsystems, Inc.
40
41
ConnectionManager.progress.message=Connection progress
42
ConnectionManager.progress.connectTo=Connecting to {0}
43
ConnectionManager.progress.fetchingInfo=Getting connection info
(-)a/cnd.execution/src/org/netbeans/modules/cnd/execution/api/Connection.java (+207 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2012 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 2012 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.cnd.execution.api;
43
44
import java.io.IOException;
45
import java.io.InterruptedIOException;
46
import java.net.ConnectException;
47
import java.net.NoRouteToHostException;
48
import java.net.URI;
49
import org.netbeans.modules.cnd.execution.NativeProcessFactory;
50
import org.netbeans.modules.cnd.execution.access.ConnectionAccessor;
51
import org.netbeans.modules.cnd.execution.access.NativeProcessBuilderFactory;
52
import org.netbeans.modules.cnd.execution.spi.ConnectionImplementation;
53
import org.netbeans.modules.cnd.execution.spi.ConnectorImplementation;
54
import org.netbeans.modules.cnd.execution.spi.URIIdentifier;
55
import org.netbeans.spi.extexecution.ProcessBuilderFactory;
56
import org.openide.util.Lookup;
57
58
/**
59
 * A connection (execution session).
60
 *
61
 * <p> Connection provides an access to a {@link ProcessBuilder} in the context
62
 * of the associated session. One should use services provided by the
63
 * {@link ConnectionManager} class to get a Connection. </p>
64
 *
65
 * @author akrasny
66
 */
67
public final class Connection implements org.netbeans.api.extexecution.ProcessBuilder.Provider {
68
69
    private final Object implLock = new Object();
70
    private ConnectionImplementation impl;
71
72
    /**
73
     * Constructs a new API object for provided implementation.
74
     *
75
     * @param uri an URI this connection is associated with.
76
     */
77
    private Connection(ConnectionImplementation impl) {
78
        this.impl = impl;
79
    }
80
81
    /**
82
     * Returns an actual URI this connection is associated with.
83
     *
84
     * @return an URI this connection is associated with.
85
     * @see ConnectorImplementation
86
     * @see URIIdentifier
87
     */
88
    public URI getURI() {
89
        synchronized (implLock) {
90
            return impl.getURI();
91
        }
92
    }
93
94
    /**
95
     * Tests if the connection is alive.
96
     *
97
     * @return true if connection is established, false otherwise.
98
     */
99
    public boolean isConnected() {
100
        synchronized (implLock) {
101
            return impl == null ? false : impl.isConnected();
102
        }
103
    }
104
105
    /**
106
     * Creates a new {@link NativeProcessBuilder} to be used for starting
107
     * processes within this connection.
108
     *
109
     * @return a new not configured {@link NativeProcessBuilder}.
110
     * @throws NativeExecutionException if some problem occurred
111
     */
112
    public NativeProcessBuilder newNativeProcessBuilder() throws NativeExecutionException {
113
        synchronized (implLock) {
114
            if (!isConnected()) {
115
                throw new BrokenConnectionException(impl.getURI());
116
            }
117
118
            return NativeProcessBuilderFactory.getDefault().newProcessBuilder(impl.newProcessBuilderImpl(), this);
119
        }
120
    }
121
122
    /**
123
     * Creates a new {@link org.netbeans.api.extexecution.ProcessBuilder} to be used for starting
124
     * processes within this connection.
125
     * <p>
126
     * The returned process builder is <i>not thread safe</i>.
127
     *
128
     * @return new {@link org.netbeans.api.extexecution.ProcessBuilder}.
129
     * @throws ConnectException if the connection object is not actually connected
130
     * @throws InterruptedIOException if the user interrupted or canceled the
131
     *             communication
132
     * @throws NoRouteToHostException if there is problem with connection to host
133
     * @throws IOException if some problem occurred
134
     */
135
    @Override
136
    public org.netbeans.api.extexecution.ProcessBuilder getProcessBuilder()
137
            throws ConnectException, InterruptedIOException, NoRouteToHostException, IOException {
138
        synchronized (implLock) {
139
            if (!isConnected()) {
140
                throw new ConnectException(impl.getURI().toString());
141
            }
142
143
            return ProcessBuilderFactory.createProcessBuilder(
144
                    new NativeProcessFactory(NativeProcessBuilderFactory.getDefault().newProcessBuilder(impl.newProcessBuilderImpl(), this)),
145
                    getDisplayName());
146
        }
147
    }
148
149
    /**
150
     * Returns a human-readable string representation of the connection.
151
     *
152
     * @return a string representation of the connection.
153
     */
154
    @Override
155
    public String toString() {
156
        synchronized (implLock) {
157
            return impl.toString();
158
        }
159
    }
160
161
    public final boolean isLocal() {
162
        return this.equals(ConnectionManager.getLocalConnection());
163
    }
164
165
    public String getDisplayName() {
166
        return toString();
167
    }
168
169
    //<editor-fold defaultstate="collapsed" desc="Accessor & Private Classes">
170
    private static class ConnectionAccessorImpl extends ConnectionAccessor {
171
172
        @Override
173
        public Lookup getConnectionLookup(Connection connection) {
174
            ConnectionImplementation impl;
175
176
            synchronized (connection.implLock) {
177
                impl = connection.impl;
178
            }
179
180
            return impl == null ? Lookup.EMPTY : impl.getLookup();
181
        }
182
183
        @Override
184
        public Connection createConnection(ConnectionImplementation impl) {
185
            return new Connection(impl);
186
        }
187
188
        @Override
189
        public void setImpl(Connection connection, ConnectionImplementation impl) {
190
            synchronized (connection.implLock) {
191
                connection.impl = impl;
192
            }
193
        }
194
195
        @Override
196
        public ConnectionImplementation getImpl(Connection connection) {
197
            synchronized (connection.implLock) {
198
                return connection.impl;
199
            }
200
        }
201
    }
202
203
    static {
204
        ConnectionAccessor.setDefault(new ConnectionAccessorImpl());
205
    }
206
    //</editor-fold>
207
}
(-)a/cnd.execution/src/org/netbeans/modules/cnd/execution/api/ConnectionException.java (+96 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2012 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 2012 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.cnd.execution.api;
43
44
import java.net.URI;
45
46
/**
47
 * This exception is thrown if any connection-related problem occurs.
48
 *
49
 * @author akrasny
50
 */
51
public class ConnectionException extends NativeExecutionException {
52
53
    private final URI uri;
54
55
    /**
56
     * Constructs a ConnectionException with the specified detail message and
57
     * nested exception.
58
     *
59
     * @param uri an URI of the connection.
60
     * @param msg the detail message.
61
     * @param cause the nested exception.
62
     */
63
    public ConnectionException(URI uri, String msg, Throwable cause) {
64
        super(msg, cause);
65
        this.uri = uri;
66
    }
67
68
    /**
69
     * Constructs a ConnectionException with the specified detailed message.
70
     *
71
     * @param uri an URI of the connection.
72
     * @param msg the detail message.
73
     */
74
    public ConnectionException(URI uri, String msg) {
75
        this(uri, msg, null);
76
    }
77
78
    /**
79
     * Constructs a ConnectionException with the specified nested exception.
80
     *
81
     * @param uri an URI of the connection
82
     * @param cause the nested exception
83
     */
84
    public ConnectionException(URI uri, Throwable cause) {
85
        this(uri, cause == null ? null : cause.getMessage(), cause);
86
    }
87
88
    /**
89
     * Returns an URI of the connection destination.
90
     *
91
     * @return the URI of the connection destination.
92
     */
93
    public final URI getURI() {
94
        return uri;
95
    }
96
}
(-)a/cnd.execution/src/org/netbeans/modules/cnd/execution/api/ConnectionManager.java (+260 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2012 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 2012 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.cnd.execution.api;
43
44
import java.io.IOException;
45
import java.net.URI;
46
import org.netbeans.api.extexecution.ProcessBuilder;
47
import org.netbeans.modules.cnd.execution.access.ConnectionAccessor;
48
import org.netbeans.modules.cnd.execution.api.ConnectionStateChangeEvent.State;
49
import org.netbeans.modules.cnd.execution.common.ConnectionListeners;
50
import org.netbeans.modules.cnd.execution.common.ConnectionsPool;
51
import org.netbeans.modules.cnd.execution.common.Connector;
52
import org.netbeans.modules.cnd.execution.spi.AuthDataProvider;
53
import org.netbeans.modules.cnd.execution.spi.ConnectionImplementation;
54
import org.netbeans.modules.cnd.execution.spi.URIIdentifier;
55
import org.netbeans.modules.dlight.spi.terminal.ConnectionProvider;
56
import org.openide.util.Exceptions;
57
import org.openide.util.lookup.ServiceProvider;
58
59
/**
60
 * An entry-point class for getting a {@link Connection} to the desired
61
 * destination.
62
 *
63
 * <p>All ConnectionManager's methods are thread-safe.</p>
64
 *
65
 * @author akrasny
66
 */
67
public final class ConnectionManager {
68
69
    private static final Connection LOCAL_CONNECTION;
70
71
    static {
72
        Connection local = null;
73
        try {
74
            local = ConnectionManager.connect(new URI("localhost"), null); // NOI18N
75
        } catch (Throwable th) {
76
            Exceptions.printStackTrace(th);
77
        } finally {
78
            LOCAL_CONNECTION = local;
79
        }
80
    }
81
82
    private ConnectionManager() {
83
    }
84
85
    /**
86
     * Returns a connection to a local host.
87
     *
88
     * <p> This connection is always active (connected) and doesn't require any
89
     * authorization.</p>
90
     *
91
     * @return the connection to a localhost (current host, current user).
92
     */
93
    public static Connection getLocalConnection() {
94
        return LOCAL_CONNECTION;
95
    }
96
97
    /**
98
     *
99
     * Returns previously established {@link Connection} identified by the same
100
     * or equivalent URI.
101
     *
102
     * <p>This method is fast and could be invoked from the EDT.</p>
103
     *
104
     * <p>There is a notion of equivalent URIs that could verbally differ, but
105
     * denote the same destination. See {@link URIIdentifier}.</p>
106
     *
107
     *
108
     * @param uri the URI that identifies a connection to get.
109
     * @return previously established active connection or {@code null}, if no
110
     * active connection exists.
111
     *
112
     * @see URIIdentifier
113
     */
114
    public static Connection getConnection(final URI uri) {
115
        Connection connection = ConnectionsPool.get(uri);
116
117
        if (connection == null || !connection.isConnected()) {
118
            return null;
119
        }
120
121
        return connection;
122
    }
123
124
    /**
125
     * An implicit request to establish a connection with a destination
126
     * identified by the provided URI.
127
     *
128
     * <p>This method acts like {@code connect(uri, null)}</p>
129
     *
130
     * @param uri the URI of a desired connection destination.
131
     * @see #connect(URI, AuthDataProvider)
132
     * @throws NativeExecutionException if connection process was canceled or
133
     * failed by any other reason.
134
     */
135
    public static Connection connect(URI uri) throws IOException {
136
        return connect(uri, null);
137
    }
138
139
    /**
140
     * An implicit request to establish a connection with the destination
141
     * identified by the provided URI using provided additional source of
142
     * authentication data.
143
     *
144
     * <p>No new connection is established if a connection identified by this or
145
     * equivalent URI already exists. The existent one is returned instead.</p>
146
     *
147
     * <p>Infrastructure asks passed {@link AuthDataProvider} to provide any
148
     * authentication data needed for connection establishment. In case no
149
     * requested info is provided by the passed provider, the default one
150
     * (supplied by an SPI implementor) is queried. Each of these providers
151
     * could initiate user interaction in order to get needed information.</p>
152
     *
153
     * <p>This method could be called from any thread (including ETD). In latter
154
     * case a modal dialog with a progress bar is used to avoid UI
155
     * deadlocks.</p>
156
     *
157
     * <p>Note that provider may return a connection with an URI that is
158
     * absolutely different from the passed one. This could happen, for example,
159
     * when request connection to an URI that doesn't precisely identifies the
160
     * final destination - like {@code ssh://testhost}. In this case
161
     * AuthDataProvider could be asked to provide a user name and the URI of a
162
     * connection could be changed to {@code ssh://user@testhost}.</p>
163
     *
164
     * @param uri the URI of a desired connection destination.
165
     * @param authProvider provider of authentication data needed for connection
166
     * establishment.
167
     *
168
     * @throws NativeExecutionException if connection process was canceled or
169
     * failed by any other reason.
170
     */
171
    public static Connection connect(URI uri, AuthDataProvider authProvider) throws IOException {
172
        Connection connection = ConnectionsPool.get(uri);
173
174
        if (connection != null && connection.isConnected()) {
175
            return connection;
176
        }
177
178
        ConnectionAccessor access = ConnectionAccessor.getDefault();
179
        ConnectionImplementation impl = Connector.connect(uri, authProvider);
180
        assert impl != null;
181
182
        if (connection == null) {
183
            connection = access.createConnection(impl);
184
            ConnectionsPool.add(connection);
185
        } else {
186
            access.setImpl(connection, impl);
187
        }
188
189
        ConnectionStateChangeEvent ev = new ConnectionStateChangeEvent(connection.getURI(), State.CONNECTION_ESTABLISHED);
190
        ConnectionListeners.notifyListeners(connection.getURI(), ev);
191
        return connection;
192
    }
193
194
    /**
195
     * An implicit request to close previously established connection.
196
     *
197
     * @param c Connection to terminate
198
     */
199
    static void disconnect(Connection c) {
200
        if (!c.isConnected()) {
201
            return;
202
        }
203
204
        ConnectionListeners.stopTrackingTask();
205
        ConnectionAccessor access = ConnectionAccessor.getDefault();
206
        access.getImpl(c).disconnect();
207
        if (!c.isConnected()) {
208
            ConnectionStateChangeEvent ev = new ConnectionStateChangeEvent(c.getURI(), State.CONNECTION_CLOSED);
209
            ConnectionListeners.notifyListeners(c.getURI(), ev);
210
        }
211
    }
212
213
    /**
214
     * Adds a listener to state changes of a connection to a given URI.
215
     *
216
     * <p> It permits you to listen to a connection which is not established
217
     * yet, or continue listening to it after it is disconnected, reconnected,
218
     * etc.
219
     * <p/>
220
     * <p> A listener can listen to any number of URIs. Note that listeners are
221
     * always held weakly - if the listener is collected, it is quietly
222
     * removed.</p>
223
     *
224
     * @param listener ConnectionStateChangeListener to listen to changes in
225
     * Connection state.
226
     * @param uri URI of the Connection target (even not connected yet existing)
227
     */
228
    public static void addConnectionStateChangeListener(ConnectionStateChangeListener listener, URI uri) {
229
        ConnectionListeners.addConnectionStateChangeListener(listener, uri);
230
    }
231
232
    /**
233
     * Removes a listener to state changes of a given connection destination.
234
     *
235
     * @param listener ConnectionStateChangeListener to be removed
236
     * @param uri URI of the Connection target
237
     */
238
    public static void removeConnectionStateChangeListener(ConnectionStateChangeListener listener, URI uri) {
239
        ConnectionListeners.removeConnectionStateChangeListener(listener, uri);
240
    }
241
242
    @ServiceProvider(service=ConnectionProvider.class)
243
    public static class NativeConnectionProvider implements ConnectionProvider {
244
245
        @Override
246
        public ProcessBuilder.Provider getConnection(URI uri) throws IOException {
247
            Connection connection = ConnectionManager.getConnection(uri);
248
            if (connection == null) {
249
                connection = ConnectionManager.connect(uri);
250
            }
251
            return connection;
252
        }
253
254
        @Override
255
        public URI getLocal() {
256
            return ConnectionManager.getLocalConnection().getURI();
257
        }
258
259
    }
260
}
(-)a/cnd.execution/src/org/netbeans/modules/cnd/execution/api/ConnectionStateChangeEvent.java (+113 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2012 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 2012 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.cnd.execution.api;
43
44
import java.net.URI;
45
import java.util.EventObject;
46
47
/**
48
 * An Event object that provides information about the source of a
49
 * connection-related event.
50
 *
51
 * <p>
52
 * {@link ConnectionStateChangeEvent}s are sent to registered {@link ConnectionStateChangeListener}s
53
 * when status of some connection changes.</p>
54
 *
55
 * @see ConnectionManager
56
 *
57
 * @author akrasny
58
 */
59
public final class ConnectionStateChangeEvent extends EventObject {
60
61
    private static final long serialVersionUID = 1L;
62
    private final State state;
63
64
    /**
65
     * Constructs a new {@link ConnectionStateChangeEvent}.
66
     *
67
     * @param uri an URI of the connection this event belongs to.
68
     * @param state the new {@link State} of the connection.
69
     */
70
    public ConnectionStateChangeEvent(URI uri, State state) {
71
        super(uri);
72
        this.state = state;
73
    }
74
75
    /**
76
     * Returns a {@link State} this event was generated for.
77
     *
78
     * @return the {@link State} of the connection this event was issued for.
79
     */
80
    public State getState() {
81
        return state;
82
    }
83
84
    /**
85
     * Returns the {@link URI} this event relates to.
86
     *
87
     * @return the related {@link URI}.
88
     */
89
    @Override
90
    public URI getSource() {
91
        return (URI) super.getSource();
92
    }
93
94
    /**
95
     * Enumeration of possible {@link State}s that events are generated for.
96
     */
97
    public enum State {
98
99
        /**
100
         * Issued when a new connection is established.
101
         */
102
        CONNECTION_ESTABLISHED,
103
        /**
104
         * Issued when a connection is implicitly terminated.
105
         */
106
        CONNECTION_CLOSED,
107
        /**
108
         * Issued when infrastructure detects that connection is not active
109
         * while no implicit termination was performed.
110
         */
111
        CONNECTION_LOST
112
    }
113
}
(-)a/cnd.execution/src/org/netbeans/modules/cnd/execution/api/ConnectionStateChangeListener.java (+69 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2012 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 2012 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.cnd.execution.api;
43
44
import java.util.EventListener;
45
46
/**
47
 * Used to be notified about active connections state changes.
48
 *
49
 *
50
 * @author akrasny
51
 */
52
public interface ConnectionStateChangeListener extends EventListener {
53
54
    /**
55
     * Is invoked on connection state change.
56
     *
57
     * <p>It is guaranteed that events are delivered in the same order they
58
     * occur.</p>
59
     *
60
     * <p>For implicit actions (connect/disconnect) events are sent
61
     * synchronously and instantly. But there is an event that is asynchronous
62
     * by it's nature - it is when connection is lost. In this case there could
63
     * be a delay in event delivery until after infrastructure detects a broken
64
     * connection.</p>
65
     *
66
     * @param event the event that describes a state change.
67
     */
68
    public void connectionStateChanged(ConnectionStateChangeEvent event);
69
}
(-)a/cnd.execution/src/org/netbeans/modules/cnd/execution/api/EnvironmentMap.java (+461 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2012 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 2012 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.cnd.execution.api;
43
44
import java.io.PrintStream;
45
import java.text.Collator;
46
import java.text.ParseException;
47
import java.util.Arrays;
48
import java.util.Collections;
49
import java.util.Comparator;
50
import java.util.HashSet;
51
import java.util.LinkedHashMap;
52
import java.util.LinkedHashSet;
53
import java.util.Locale;
54
import java.util.Map;
55
import java.util.Map.Entry;
56
import java.util.Set;
57
import java.util.TreeMap;
58
import org.netbeans.modules.cnd.execution.access.EnvironmentMapAccessor;
59
import org.netbeans.modules.cnd.execution.util.MacroExpander;
60
61
/**
62
 * Map of key-value String pairs.
63
 *
64
 * An implementation of Map interface that can do macro expansion on insertion
65
 * and preserves an order of insertions.
66
 *
67
 * The following formats of macros are supported:
68
 * <pre>
69
 * ${NAME}
70
 * $NAME
71
 * </pre>
72
 *
73
 * Not thread safe
74
 *
75
 * @author akrasny
76
 */
77
public final class EnvironmentMap implements Cloneable {
78
79
    private final Comparator<? super String> comparator;
80
    private final EnvironmentMap baseMap;
81
    private final LinkedHashMap<String, String> ownMap = new LinkedHashMap<String, String>();
82
    private final HashSet<String> removedKeys = new HashSet<String>();
83
    private final char pathSeparator;
84
85
    static {
86
        EnvironmentMapAccessor.setDefault(new Accessor());
87
    }
88
89
    /**
90
     * Creates a new map with a specified keys comparator.
91
     *
92
     * @param comparator the comparator to be used in keys comparisons.
93
     */
94
    private EnvironmentMap(EnvironmentMap baseMap) {
95
        this.baseMap = baseMap;
96
        this.comparator = baseMap.comparator;
97
        this.pathSeparator = baseMap.pathSeparator;
98
    }
99
100
    private EnvironmentMap(Comparator<? super String> comparator, char pathSeparator) {
101
        this.baseMap = null;
102
        this.comparator = comparator;
103
        this.pathSeparator = pathSeparator;
104
    }
105
106
    /**
107
     * Adds a new key-value pair to the map.
108
     *
109
     * <p> The {@link #put(String, String)} method works as follows:
110
     *
111
     * <code>
112
     *   EnvironmentMap m = new EnvironmentMap()
113
     *   m.put("ANT_HOME", "/bin");
114
     *   m.put("PATH", "$ANT_HOME");
115
     *   m.put("PATH", "${PATH}:/usr/bin");
116
     * </code>
117
     *
118
     * as a result the key "PATH" will be associated with the value
119
     * "${ANT_HOME}:/usr/bin". </p>
120
     *
121
     * <p> The only (possibly) altered value on insertion is the inserted value
122
     * itself. The only macro that is expanded is the key-named macro. (See the
123
     * above example - $ANT_HOME is not expanded in the value of PATH) </p>
124
     *
125
     * <p> Comparator is used for comparing key. </p>
126
     *
127
     * @param key the key of an entry
128
     * @param value the new value of an entry
129
     * @return a previous value associated with the key
130
     */
131
    public final String put(final String key, final String value) {
132
        return put(key, value, true);
133
    }
134
135
    // XXX reduce visibility of this
136
    public final String put(final String key, final String value, boolean expand) {
137
        if (value == null) {
138
            throw new NullPointerException("Attempt to set a null value"); // NOI18N
139
        }
140
        String result = value;
141
142
143
        String fixedKey = fixKey(key);
144
145
        if (expand) {
146
            try {
147
                result = MacroExpander.expandMacros(value, toMap());
148
            } catch (ParseException ex) {
149
            }
150
        }
151
        removedKeys.remove(fixedKey);
152
        return ownMap.put(fixedKey, result);
153
154
    }
155
156
    protected Comparator<? super String> getComparator() {
157
        return comparator;
158
    }
159
160
    /**
161
     * Returns a value associated with a key.
162
     *
163
     * @param key the key to get value for or {@code null} if no value is
164
     * associated.
165
     * @return the value associated with a key.
166
     */
167
    public final String get(final String key) {
168
        String k = fixKey(key);
169
        return getImpl(k);
170
    }
171
172
    /**
173
     * Appends provided path to the value of the specified variable.
174
     *
175
     * <p> As a result a {@code path} will be appended to a value of variable
176
     * with the name {@code name}. If the same path was already in the list of
177
     * paths the value of the variable will remain unchanged.</p>
178
     *
179
     * <p> If the variable named {@code name} was not defined yet before this
180
     * method invocation, the variable will have the only entry - this new
181
     * path.</p>
182
     *
183
     * @param name the name of the variable to change.
184
     * @param path the path element to append to the list of path elements.
185
     * Could be {@code null}, but in this case method does nothing.
186
     */
187
    public void appendPath(String name, String path) {
188
        appendPath(name, path, true);
189
    }
190
191
    // XXX reduce visibility of this
192
    public void appendPath(String name, String path, boolean expand) {
193
        if (path == null) {
194
            return;
195
        }
196
197
        String oldpath = get(name);
198
        String newPath = (oldpath == null ? "" : oldpath + (pathSeparator)) + path; // NOI18N
199
        put(name, reducePath(newPath), expand);
200
    }
201
202
    /**
203
     * Prepends provided path to the value of the specified variable.
204
     *
205
     * <p>As a result a variable with the name {@code name} will contain {@code path}
206
     * at the first place. Also if the same path was already in the list of
207
     * paths, that 'old' entry will be removed to avoid unneeded
208
     * duplications.</p>
209
     *
210
     * <p>If specified variable was not defined yet before this method
211
     * invocation, it will have the only entry - this new path.</p>
212
     *
213
     * @param name the name of the variable to change.
214
     * @param path the path element to add to the list of path elements. Could
215
     * be {@code null}, but in this case method does nothing.
216
     */
217
    public void prependPath(String name, String path) {
218
        prependPath(name, path, true);
219
    }
220
221
    // XXX reduce visibility of this
222
    public void prependPath(String name, String path, boolean expand) {
223
        if (path == null) {
224
            return;
225
        }
226
227
        String oldpath = get(name);
228
        String newPath = path + (oldpath == null ? "" : (pathSeparator) + oldpath); // NOI18N
229
        put(name, reducePath(newPath), expand);
230
    }
231
232
    /**
233
     * A string representation of the map.
234
     *
235
     * @return the string representation.
236
     */
237
    @Override
238
    public final String toString() {
239
        StringBuilder buf = new StringBuilder();
240
        buf.append("{"); // NOI18N
241
242
        for (Map.Entry<String, String> entry : entrySet()) {
243
            buf.append(entry.getKey());
244
            buf.append(" = "); // NOI18N
245
            buf.append(entry.getValue());
246
            buf.append(", "); // NOI18N
247
        }
248
249
        buf.append("}"); // NOI18N
250
        return buf.toString();
251
    }
252
253
    /**
254
     * A convenient way for printing out the map.
255
     *
256
     * @param out stream to out map to.
257
     */
258
    public final void dump(PrintStream out) {
259
        out.println("---- Map Dump ----"); // NOI18N
260
        for (Map.Entry<String, String> entry : entrySet()) {
261
            out.println(entry.getKey() + " = " + entry.getValue()); // NOI18N
262
        }
263
        out.println("------------------"); // NOI18N
264
    }
265
266
    /**
267
     * Removes entry from the map.
268
     *
269
     * @param key the key to remove entry for.
270
     * @return a value previously associated with the key.
271
     */
272
    public final String remove(final String key) {
273
        String k = fixKey(key);
274
        String prevValue = getImpl(k);
275
        ownMap.remove(k);
276
        removedKeys.add(k);
277
        return prevValue;
278
    }
279
280
    /**
281
     * Returns an entry set of the map in the same order as they have been
282
     * added.
283
     *
284
     * @return the entry set.
285
     */
286
    public final Set<Entry<String, String>> entrySet() {
287
        Set<Entry<String, String>> result = new LinkedHashSet<Entry<String, String>>();
288
        if (baseMap != null) {
289
            for (Entry<String, String> entry : baseMap.entrySet()) {
290
                String k = entry.getKey();
291
                if (removedKeys.contains(k)) {
292
                    continue;
293
                }
294
                if (ownMap.containsKey(k)) {
295
                    continue;
296
                }
297
                result.add(entry);
298
            }
299
        }
300
301
        result.addAll(ownMap.entrySet());
302
        return result;
303
    }
304
305
    /**
306
     * Returns the number of key-value mappings in this map.
307
     *
308
     * @return the number of key-value mappings in this map
309
     */
310
    public final int size() {
311
        int baseSize = 0;
312
        if (baseMap != null) {
313
            for (Entry<String, String> entry : baseMap.entrySet()) {
314
                String k = entry.getKey();
315
                if (removedKeys.contains(k)) {
316
                    continue;
317
                }
318
                if (ownMap.containsKey(k)) {
319
                    continue;
320
                }
321
                baseSize++;
322
            }
323
        }
324
325
        return baseSize + ownMap.size();
326
    }
327
328
    /**
329
     * Returns {@code true} if this map contains no key-value mappings.
330
     *
331
     * @return {@code true} if this map contains no key-value mappings
332
     */
333
    public boolean isEmpty() {
334
        return size() == 0;
335
    }
336
337
    /**
338
     * Removes all entries from this map.
339
     *
340
     * The map becomes empty after this call returns.
341
     */
342
    public void clear() {
343
        ownMap.clear();
344
        removedKeys.clear();
345
        if (baseMap != null) {
346
            for (Entry<String, String> entry : baseMap.entrySet()) {
347
                removedKeys.add(entry.getKey());
348
            }
349
        }
350
    }
351
352
    /**
353
     * Returns an unmodifiable copy of this map as a {@code Map<String, String>}
354
     * collection.
355
     *
356
     * @return unmodifiable copy
357
     */
358
    public Map<String, String> toMap() {
359
        TreeMap<String, String> result = comparator == null
360
                ? new TreeMap<String, String>()
361
                : new TreeMap<String, String>(comparator);
362
363
        for (Entry<String, String> entry : entrySet()) {
364
            result.put(entry.getKey(), entry.getValue());
365
        }
366
367
        return Collections.unmodifiableMap(result);
368
    }
369
370
    private String fixKey(final String key) {
371
        if (comparator == null) {
372
            return key;
373
        }
374
375
        for (String k : ownMap.keySet()) {
376
            if (comparator.compare(k, key) == 0) {
377
                return k;
378
            }
379
        }
380
381
        // key was not found in the ownMap
382
        // perhaps it is in the base one?
383
        if (baseMap != null) {
384
            for (Entry<String, String> entry : baseMap.entrySet()) {
385
                String k = entry.getKey();
386
                if (comparator.compare(k, key) == 0) {
387
                    return k;
388
                }
389
            }
390
        }
391
392
        return key;
393
    }
394
395
    private String getImpl(final String fixedKey) {
396
        if (removedKeys.contains(fixedKey)) {
397
            return null;
398
        }
399
        String result = ownMap.get(fixedKey);
400
        if (result != null) {
401
            return result;
402
        }
403
        if (baseMap != null) {
404
            return baseMap.getImpl(fixedKey);
405
        }
406
        return null;
407
    }
408
409
    private String reducePath(String path) {
410
        if (path.isEmpty()) {
411
            return path;
412
        }
413
414
        LinkedHashSet<String> elems = new LinkedHashSet<String>();
415
        String e;
416
        elems.addAll(Arrays.asList(path.split("" + pathSeparator))); // NOI18N
417
        StringBuilder sb = new StringBuilder();
418
        for (String elem : elems) {
419
            e = elem.trim();
420
            if (e.isEmpty()) {
421
                continue;
422
            }
423
            sb.append(pathSeparator).append(e);
424
        }
425
        return sb.substring(1);
426
    }
427
428
    public void putAll(Set<Entry<String, String>> entrySet) {
429
        for (Entry<String, String> entry : entrySet) {
430
            put(entry.getKey(), entry.getValue());
431
        }
432
    }
433
434
    private static class Accessor extends EnvironmentMapAccessor {
435
436
        public Accessor() {
437
        }
438
439
        @Override
440
        public Map<String, String> getModifiedVars(EnvironmentMap environmentMap) {
441
            return Collections.unmodifiableMap(environmentMap.ownMap);
442
        }
443
444
        @Override
445
        public EnvironmentMap createBasedOn(EnvironmentMap map) {
446
            return new EnvironmentMap(map);
447
        }
448
449
        @Override
450
        public EnvironmentMap createCasePreserving(char pathSeparator) {
451
            Collator c = Collator.getInstance(Locale.US);
452
            c.setStrength(Collator.PRIMARY);
453
            return new EnvironmentMap(c, pathSeparator);
454
        }
455
456
        @Override
457
        public EnvironmentMap createCaseSensitive(char pathSeparator) {
458
            return new EnvironmentMap(null, pathSeparator);
459
        }
460
    }
461
}
(-)a/cnd.execution/src/org/netbeans/modules/cnd/execution/api/NativeExecutionException.java (+87 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2012 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 2012 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.cnd.execution.api;
43
44
import java.io.IOException;
45
46
/**
47
 * The root exception of all execution-related exceptions.
48
 *
49
 * This exception is thrown if any execution problem occurs.
50
 *
51
 * @author akrasny
52
 */
53
public class NativeExecutionException extends IOException {
54
55
    static final long serialVersionUID = 1L;
56
57
    /**
58
     * Constructs a NativeExecutionException with the specified, detailed
59
     * message.
60
     *
61
     * @param msg the detail message.
62
     */
63
    public NativeExecutionException(String msg) {
64
        super(msg);
65
    }
66
67
    /**
68
     * Constructs a NativeExecutionException with the specified detail message
69
     * and nested exception.
70
     *
71
     * @param msg the detail message.
72
     * @param cause the nested exception.
73
     */
74
    public NativeExecutionException(String msg, Throwable cause) {
75
        super(msg, cause);
76
    }
77
78
    /**
79
     * Constructs a NativeExecutionException with the specified nested
80
     * exception.
81
     *
82
     * @param cause the nested exception.
83
     */
84
    public NativeExecutionException(Throwable cause) {
85
        super(cause.getMessage(), cause);
86
    }
87
}
(-)a/cnd.execution/src/org/netbeans/modules/cnd/execution/api/NativeProcessBuilder.java (+331 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2012 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 2012 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.cnd.execution.api;
43
44
import java.util.ArrayList;
45
import java.util.Arrays;
46
import java.util.List;
47
import java.util.concurrent.Callable;
48
import java.util.concurrent.atomic.AtomicReference;
49
import java.util.concurrent.locks.ReentrantLock;
50
import org.netbeans.modules.cnd.execution.api.process.ProcessState.State;
51
import org.netbeans.modules.cnd.execution.access.EnvironmentMapAccessor;
52
import org.netbeans.modules.cnd.execution.access.NativeProcessBuilderFactory;
53
import org.netbeans.modules.cnd.execution.access.NativeProcessParamsFactory;
54
import org.netbeans.modules.cnd.execution.api.config.StateListenerConfiguration;
55
import org.netbeans.modules.cnd.execution.api.config.StateListenerConfiguration.ProcessStateChangeEvent;
56
import org.netbeans.modules.cnd.execution.api.config.StateListenerConfiguration.ProcessStateChangeListener;
57
import org.netbeans.modules.cnd.execution.common.ConnectionsInfo;
58
import org.netbeans.modules.cnd.execution.common.NativeProcess;
59
import org.netbeans.modules.cnd.execution.common.ProcessStateChangeNotifier;
60
import org.netbeans.modules.cnd.execution.spi.NativeProcessCreator;
61
import org.netbeans.modules.cnd.execution.spi.NativeProcessParams;
62
import org.netbeans.modules.cnd.execution.spi.support.ConnectionInfo;
63
import org.netbeans.modules.cnd.execution.util.HostInfo;
64
import org.netbeans.modules.dlight.spi.terminal.ShellConfiguration;
65
import org.openide.util.Lookup;
66
import org.openide.util.RequestProcessor;
67
import org.openide.util.lookup.Lookups;
68
import org.openide.util.lookup.ProxyLookup;
69
70
/**
71
 * This class is used to create an external processes.
72
 *
73
 * <p> Each NativeProcessBuilder instance manages a collection of process
74
 * attributes. The {@link #call()} method creates a new {@link NativeProcess}
75
 * instance with those attributes. The {@link #call()} method can be invoked
76
 * repeatedly from the same instance to create new processes with identical or
77
 * related attributes. </p>
78
 *
79
 * <p> There are several common attributes that could be configured directly by
80
 * invoking appropriate methods. Additional {@link Connection}-specific
81
 * attributes could be provided by a specific implementation. Access to those
82
 * attributes is done using {@link #getSupportedProperties()} and
83
 * {@link #setProperty(String, Object)} methods. </p>
84
 *
85
 * <p> Modifying a NativeProcessBuilder's attributes will affect processes
86
 * subsequently started by it's {@link #call()} method, but will never affect
87
 * previously started processes. </p>
88
 *
89
 * <p> This class is NOT thread-safe. </p>
90
 *
91
 * @see ConnectionManager
92
 * @author akrasny
93
 */
94
public final class NativeProcessBuilder implements Callable<Process>, Lookup.Provider {
95
96
    private final NativeProcessCreator creator;
97
    private final Connection connection;
98
    private final List<ProcessStateChangeListener> listeners = new ArrayList<ProcessStateChangeListener>();
99
    private final EnvironmentMap environmentMap;
100
    private final StateListenerConfiguration stateConfig = new StateListenerConfiguration(this);
101
    private final ShellConfiguration shellConfig = new ShellConfiguration() {
102
        @Override
103
        public String getShell() {
104
            return HostInfo.getFor(connection).getShell();
105
        }
106
    };
107
108
    private List<String> command;
109
    private boolean redirectError;
110
    private String shellScript;
111
    private String shell;
112
    private String wdir;
113
114
    /**
115
     * Creates a new instance of NativeProcessBuilder.
116
     *
117
     * @param connection the {@link Connection} to use for this builder.
118
     * @param supportedProperties a map of supported configurable properties.
119
     */
120
    private NativeProcessBuilder(NativeProcessCreator creator, Connection connection) {
121
        this.creator = creator;
122
        this.connection = connection;
123
124
        EnvironmentMapAccessor mapAccess = EnvironmentMapAccessor.getDefault();
125
        EnvironmentMap envMap = HostInfo.getEnvironmentMap(connection);
126
        environmentMap = envMap == null ? mapAccess.createCaseSensitive(':') : mapAccess.createBasedOn(envMap);
127
    }
128
129
    /**
130
     * Adds a listener to the list that is notified each time a state of any
131
     * {@link NativeProcess} created by this builder changes.
132
     *
133
     * <p> Added listener will be passed to every subsequently created
134
     * NativeProcess. Already running NativeProcess will not see any changes in
135
     * the listeners list. </p>
136
     *
137
     * @param listener the {@link ProcessStateChangeListener} to add.
138
     */
139
    public NativeProcessBuilder addProcessListener(ProcessStateChangeListener listener) {
140
        listeners.add(listener);
141
        return this;
142
    }
143
144
    public NativeProcessBuilder removeProcessListener(ProcessStateChangeListener listener) {
145
        listeners.remove(listener);
146
        return this;
147
    }
148
149
    /**
150
     * Sets the Command attribute.
151
     *
152
     * <p> Sets an executable and arguments of the process to start. This method
153
     * does a copy of the command list. No any validation is performed. </p>
154
     *
155
     * <p> Note that setting a command with this method erases any data
156
     * configured with the {@link #setShellScript(String, String)} method. </p>
157
     *
158
     *
159
     * @param executable the executable to start.
160
     * @param arguments the list of arguments that will be passed to the
161
     * executable.
162
     * @return This process builder.
163
     * @see #setShellScript(String, String)
164
     */
165
    public NativeProcessBuilder setCommand(String executable, String... arguments) {
166
        command = new ArrayList<String>(arguments.length + 1);
167
        command.add(executable);
168
        command.addAll(Arrays.asList(arguments));
169
        shell = null;
170
        shellScript = null;
171
        return this;
172
    }
173
174
    /**
175
     * Sets the ShellScript attribute.
176
     *
177
     *
178
     * <p> Defines a shell script (text) that should be interpreted by the
179
     * specified shell.</p>
180
     *
181
     * <p> In case of using {@code /bin/sh}, that would be the same as calling
182
     * {@code setCommand("/bin/sh", "-s")} and writing a script to it's input
183
     * stream.</p>
184
     *
185
     * <p> Note that setting a command with this method erases any data
186
     * configured with the {@link #setCommand(String, String[])} method.</p>
187
     *
188
     * @param shell the shell to use. If {@code null}, then default user's shell
189
     * is used.
190
     * @param script the script to be passed to the shell.
191
     * @return This process builder.
192
     * @see #setShellScript(String, String)
193
     */
194
    public NativeProcessBuilder setShellScript(String shell, String script) {
195
        this.shell = shell;
196
        this.shellScript = script;
197
        command = null;
198
        return this;
199
    }
200
201
    /**
202
     * Configures a working directory attribute.
203
     *
204
     * <p> Process subsequently created by the call() method on this builder
205
     * will be executed with this directory as a current working dir.</p>
206
     *
207
     * <p> The default value is undefined.<p>
208
     *
209
     * @param workingDirectory working directory to start a process in.
210
     * @return This process builder.
211
     */
212
    public NativeProcessBuilder setWorkingDirectory(String workingDirectory) {
213
        this.wdir = workingDirectory;
214
        return this;
215
    }
216
217
    /**
218
     * Configures a error stream redirection attribute.
219
     *
220
     * <p>If this property is true, then any error output generated by processes
221
     * subsequently started by this builder will be merged with the standard
222
     * output, so that both can be read using a stream returned by
223
     * {@code NativeProcess.getInputStream()} method.</p>
224
     *
225
     * <p>The initial value is false.</p>
226
     *
227
     * @param redirectErrorStream the new value of the attribute.
228
     * @return This process builder.
229
     */
230
    public NativeProcessBuilder redirectErrorStream(boolean redirectErrorStream) {
231
        this.redirectError = redirectErrorStream;
232
        return this;
233
    }
234
235
    /**
236
     * Returns a string map view of this process builder's environment.
237
     *
238
     * <p>Whenever a process builder is created, the environment is initialized
239
     * to a copy of the {@link Connection}'s environment (if applicable).
240
     * Processes subsequently started by this builder will use this map as their
241
     * environment.</p>
242
     *
243
     * @return This process builder's environment.
244
     */
245
    public EnvironmentMap getEnvironmentMap() {
246
        return environmentMap;
247
    }
248
249
    @Override
250
    public Lookup getLookup() {
251
        return new ProxyLookup(Lookups.fixed(stateConfig, shellConfig), creator.getLookup());
252
    }
253
254
    /**
255
     * Starts a new process using the attributes of this process builder.
256
     *
257
     * @return a new {@link NativeProcess}.
258
     * @throws NativeExecutionException if process cannot be created.
259
     */
260
    @Override
261
    public Process call() throws NativeExecutionException {
262
        if (!connection.isConnected()) {
263
            throw new BrokenConnectionException(connection.getURI());
264
        }
265
266
        final AtomicReference<NativeProcess> pref = new AtomicReference<NativeProcess>();
267
        final ReentrantLock lock = new ReentrantLock();
268
269
        ProcessStateChangeNotifier notifyer = null;
270
271
        if (!listeners.isEmpty()) {
272
            final List<ProcessStateChangeListener> ll = new ArrayList<ProcessStateChangeListener>(listeners);
273
            final RequestProcessor notificationThread = new RequestProcessor();
274
            notifyer = new ProcessStateChangeNotifier() {
275
                @Override
276
                public void notifyProcessStateChange(final State newProcessState) {
277
                    notificationThread.post(new Runnable() {
278
                        @Override
279
                        public void run() {
280
                            lock.lock();
281
                            try {
282
                                ProcessStateChangeEvent evt = new ProcessStateChangeEvent(pref.get(), newProcessState);
283
                                for (ProcessStateChangeListener l : ll) {
284
                                    l.processStateChanged(evt);
285
                                }
286
                            } finally {
287
                                lock.unlock();
288
                            }
289
                        }
290
                    });
291
                }
292
            };
293
        }
294
295
        ConnectionInfo connectionInfo = ConnectionsInfo.getConnectionInfo(connection.getURI());
296
297
        NativeProcessParams params = NativeProcessParamsFactory.getDefault().newNativeProcessParams(
298
                connection,
299
                connectionInfo == null ? null : connectionInfo.getProperties(),
300
                EnvironmentMapAccessor.getDefault().getModifiedVars(environmentMap),
301
                command,
302
                shell,
303
                shellScript,
304
                redirectError,
305
                wdir,
306
                creator.getLookup());
307
308
        lock.lock();
309
        try {
310
            NativeProcess result = new NativeProcess(creator, params, notifyer);
311
            pref.set(result);
312
            return result.start();
313
        } finally {
314
            lock.unlock();
315
        }
316
    }
317
318
    //<editor-fold defaultstate="collapsed" desc="Accessor">
319
    static {
320
        NativeProcessBuilderFactory.setDefault(new NativeProcessBuilderFactoryImpl());
321
    }
322
323
    private static class NativeProcessBuilderFactoryImpl extends NativeProcessBuilderFactory {
324
325
        @Override
326
        public NativeProcessBuilder newProcessBuilder(NativeProcessCreator impl, Connection connection) {
327
            return new NativeProcessBuilder(impl, connection);
328
        }
329
    }
330
    //</editor-fold>
331
}
(-)a/cnd.execution/src/org/netbeans/modules/cnd/execution/api/config/StateListenerConfiguration.java (+169 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2013 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 2013 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.cnd.execution.api.config;
43
44
import java.util.EventListener;
45
import java.util.EventObject;
46
import org.netbeans.modules.cnd.execution.api.NativeProcessBuilder;
47
import org.netbeans.modules.cnd.execution.api.process.ProcessState;
48
49
/**
50
 *
51
 * @author Petr Hejl
52
 */
53
public final class StateListenerConfiguration {
54
55
    private final NativeProcessBuilder npb;
56
57
    public StateListenerConfiguration(NativeProcessBuilder npb) {
58
        this.npb = npb;
59
    }
60
61
62
    public void addProcessListener(ProcessStateChangeListener listener) {
63
        this.npb.addProcessListener(listener);
64
    }
65
66
    public void removeProcessListener(ProcessStateChangeListener listener) {
67
        this.npb.removeProcessListener(listener);
68
    }
69
70
    /**
71
     * A listener that, added passed to a NativeProcessBuilders will be notified
72
     * on changes in a state of NativeProcesses created by those builder.
73
     *
74
     * @author akrasny
75
     */
76
    public interface ProcessStateChangeListener extends EventListener {
77
78
        /**
79
         * Is invoked once process has changed it's state.
80
         *
81
         * <pre>
82
         * Process has determinated order of states it can be set to:
83
         * INITIAL ---> STARTING ---> RUNNING  ---> FINISHED
84
         *          |-> CANCELLED |-> CENCELLED |-> CANCELLED
85
         *          |-> ERROR     |-> ERROR     |-> ERROR
86
         *
87
         * CANCELLED, ERROR and FINISHED are terminal states.
88
         * </pre>
89
         *
90
         * <p> It is guaranteed that: <ul> <li>listeners are notified in the
91
         * same (per process) not EDT thread;</li> <li>listener receives events
92
         * in the order they occur;</li> <li>once process reaches it's final
93
         * (terminal) state, no further events will be generated for that
94
         * process.</li> </ul> </p>
95
         *
96
         * <p> Note: listeners are notified asynchronously relative a process
97
         * itself. This means that at a time of event delivery the real state of
98
         * a process may already differ. </p>
99
         *
100
         * @param evt the event this notification is about
101
         */
102
        public void processStateChanged(ProcessStateChangeEvent evt);
103
    }
104
105
    /**
106
     * ProcessStateChangeEvent is used to notify interested parties that state
107
     * of the source's process has changed.
108
     *
109
     * @author akrasny
110
     */
111
    public static final class ProcessStateChangeEvent extends EventObject {
112
113
        private static final long serialVersionUID = 1L;
114
        private final ProcessState.State state;
115
        private final long ts;
116
117
        /**
118
         * Constructs a new ProcessStateChangeEvent event.
119
         *
120
         * @param process the process that originated the event.
121
         * @param state the new state of the process.
122
         */
123
        public ProcessStateChangeEvent(Process process, ProcessState.State state) {
124
            this(process, state, System.nanoTime());
125
        }
126
127
        /**
128
         * Constructs a new ProcessStateChangeEvent event.
129
         *
130
         * @param process the process that originated the event.
131
         * @param state the new state of the process.
132
         * @param nanoTime the exact time of the event.
133
         */
134
        public ProcessStateChangeEvent(Process process, ProcessState.State state, long nanoTime) {
135
            super(process);
136
            this.state = state;
137
            this.ts = nanoTime;
138
        }
139
140
        /**
141
         * Returns a state of the process on the moment of this event creation.
142
         *
143
         * @return the state of the process on the moment of this event
144
         * creation.
145
         */
146
        public ProcessState.State getState() {
147
            return state;
148
        }
149
150
        /**
151
         * Returns the source {@link Process} for this event.
152
         *
153
         * @return the event source
154
         */
155
        @Override
156
        public Process getSource() {
157
            return (Process) super.getSource();
158
        }
159
160
        /**
161
         * Returns the timestamp of when this event occurred.
162
         *
163
         * @return this event's timestamp.
164
         */
165
        public long getEventNanoTime() {
166
            return ts;
167
        }
168
    }
169
}
(-)a/cnd.execution/src/org/netbeans/modules/cnd/execution/api/process/ProcessState.java (+107 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2012 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 2012 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.cnd.execution.api.process;
43
44
import org.openide.util.Lookup;
45
46
/**
47
 *
48
 * @author Petr Hejl
49
 */
50
public abstract class ProcessState {
51
52
    private static ProcessState find(Process process) {
53
        if (process instanceof Lookup.Provider) {
54
            Lookup.Provider p = (Lookup.Provider) process;
55
            return p.getLookup().lookup(ProcessState.class);
56
        }
57
        return null;
58
    }
59
60
    public static boolean isSupported(Process process) {
61
        return find(process) != null;
62
    }
63
64
    public static State getState(Process process) {
65
        ProcessState processState = find(process);
66
        if (processState != null) {
67
            return processState.getState();
68
        }
69
        return null;
70
    }
71
72
    protected abstract State getState();
73
74
    /**
75
     * Enumerates all possible states of a {@link Process}.
76
     */
77
    public enum State {
78
79
        /**
80
         * Native process is in an Initial state. This means that it has not
81
         * been started yet.
82
         */
83
        INITIAL,
84
        /**
85
         * Native process is starting. This means that it has been submitted,
86
         * but no PID is received so far.
87
         */
88
        STARTING,
89
        /**
90
         * Native process runs. This means that process successfully started and
91
         * it's PID is already known.
92
         */
93
        RUNNING,
94
        /**
95
         * Native process is done, but exit status is not available yet.
96
         */
97
        FINISHING,
98
        /**
99
         * Native process exited.
100
         */
101
        FINISHED,
102
        /**
103
         * Native process submission failed due to some exception.
104
         */
105
        ERROR
106
    }
107
}
(-)a/cnd.execution/src/org/netbeans/modules/cnd/execution/api/process/package-info.java (+51 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
5
 *
6
 * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
7
 * Other names may be trademarks of their respective owners.
8
 *
9
 * The contents of this file are subject to the terms of either the GNU
10
 * General Public License Version 2 only ("GPL") or the Common
11
 * Development and Distribution License("CDDL") (collectively, the
12
 * "License"). You may not use this file except in compliance with the
13
 * License. You can obtain a copy of the License at
14
 * http://www.netbeans.org/cddl-gplv2.html
15
 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
16
 * specific language governing permissions and limitations under the
17
 * License.  When distributing the software, include this License Header
18
 * Notice in each file and include the License file at
19
 * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
20
 * particular file as subject to the "Classpath" exception as provided
21
 * by Oracle in the GPL Version 2 section of the License file that
22
 * accompanied this code. If applicable, add the following below the
23
 * License Header, with the fields enclosed by brackets [] replaced by
24
 * your own identifying information:
25
 * "Portions Copyrighted [year] [name of copyright owner]"
26
 *
27
 * Contributor(s):
28
 *
29
 * The Original Software is NetBeans. The Initial Developer of the Original
30
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
31
 * Microsystems, Inc. All Rights Reserved.
32
 *
33
 * If you wish your version of this file to be governed by only the CDDL
34
 * or only the GPL Version 2, indicate your decision by adding
35
 * "[Contributor] elects to include this software in this distribution
36
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
37
 * single choice of license, a recipient has the option to distribute
38
 * your version of this file under either the CDDL, the GPL Version 2 or
39
 * to extend the choice of license to its licensees as provided above.
40
 * However, if you add GPL Version 2 code and therefore, elected the GPL
41
 * Version 2 license, then the option applies only if the new code is
42
 * made subject to such option by the copyright holder.
43
 */
44
45
/**
46
 * The API supporting enhanced functionality for
47
 * a {@link java.lang.Process}. Could be moved to org.netbeans.api.extexecution.process
48
 * in future.
49
 */
50
package org.netbeans.modules.cnd.execution.api.process;
51
(-)a/cnd.execution/src/org/netbeans/modules/cnd/execution/common/Bundle.properties (+43 lines)
Line 0 Link Here
1
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
2
#
3
# Copyright 2012 Oracle and/or its affiliates. All rights reserved.
4
#
5
# Oracle and Java are registered trademarks of Oracle and/or its affiliates.
6
# Other names may be trademarks of their respective owners.
7
#
8
# The contents of this file are subject to the terms of either the GNU
9
# General Public License Version 2 only ("GPL") or the Common
10
# Development and Distribution License("CDDL") (collectively, the
11
# "License"). You may not use this file except in compliance with the
12
# License. You can obtain a copy of the License at
13
# http://www.netbeans.org/cddl-gplv2.html
14
# or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
15
# specific language governing permissions and limitations under the
16
# License.  When distributing the software, include this License Header
17
# Notice in each file and include the License file at
18
# nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
19
# particular file as subject to the "Classpath" exception as provided
20
# by Oracle in the GPL Version 2 section of the License file that
21
# accompanied this code. If applicable, add the following below the
22
# License Header, with the fields enclosed by brackets [] replaced by
23
# your own identifying information:
24
# "Portions Copyrighted [year] [name of copyright owner]"
25
#
26
# If you wish your version of this file to be governed by only the CDDL
27
# or only the GPL Version 2, indicate your decision by adding
28
# "[Contributor] elects to include this software in this distribution
29
# under the [CDDL or GPL Version 2] license." If you do not indicate a
30
# single choice of license, a recipient has the option to distribute
31
# your version of this file under either the CDDL, the GPL Version 2 or
32
# to extend the choice of license to its licensees as provided above.
33
# However, if you add GPL Version 2 code and therefore, elected the GPL
34
# Version 2 license, then the option applies only if the new code is
35
# made subject to such option by the copyright holder.
36
#
37
# Contributor(s):
38
#
39
# Portions Copyrighted 2012 Sun Microsystems, Inc.
40
41
Connector.progress.message=Connection progress
42
Connector.progress.connectTo=Connecting to {0} ...
43
Connector.progress.fetchingInfo=Getting connection info
(-)a/cnd.execution/src/org/netbeans/modules/cnd/execution/common/ConnectionListeners.java (+204 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2012 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 2012 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.cnd.execution.common;
43
44
import java.net.URI;
45
import java.util.ArrayList;
46
import java.util.HashMap;
47
import java.util.Iterator;
48
import java.util.List;
49
import java.util.Map;
50
import org.netbeans.modules.cnd.execution.api.Connection;
51
import org.netbeans.modules.cnd.execution.api.ConnectionManager;
52
import org.netbeans.modules.cnd.execution.api.ConnectionStateChangeEvent;
53
import org.netbeans.modules.cnd.execution.api.ConnectionStateChangeEvent.State;
54
import org.netbeans.modules.cnd.execution.api.ConnectionStateChangeListener;
55
import org.netbeans.modules.cnd.execution.util.URIMatcher;
56
import org.openide.util.RequestProcessor;
57
import org.openide.util.RequestProcessor.Task;
58
import org.openide.util.WeakSet;
59
60
/**
61
 *
62
 * @author akrasny
63
 */
64
public final class ConnectionListeners {
65
66
    private static final RequestProcessor RP = new RequestProcessor("ConnectionListeners", 1); // NOI18N
67
    private static final Map<URI, WeakSet<ConnectionStateChangeListener>> map =
68
            new HashMap<URI, WeakSet<ConnectionStateChangeListener>>();
69
    // always accessed from the single-thread RP
70
    private static final List<URI> active = new ArrayList<URI>();
71
    private static final Task ttask = RP.create(new TrackTask(), true);
72
73
    private ConnectionListeners() {
74
    }
75
76
    public static void addConnectionStateChangeListener(ConnectionStateChangeListener listener, URI uri) {
77
        URIMatcher m = new URIMatcher(uri);
78
79
        synchronized (map) {
80
            for (Map.Entry<URI, WeakSet<ConnectionStateChangeListener>> entry : map.entrySet()) {
81
                if (m.isIdenticalURI(entry.getKey())) {
82
                    entry.getValue().add(listener);
83
                    return;
84
                }
85
            }
86
87
            WeakSet<ConnectionStateChangeListener> set = new WeakSet<ConnectionStateChangeListener>();
88
            set.add(listener);
89
            map.put(uri, new WeakSet<ConnectionStateChangeListener>(set));
90
        }
91
92
        ttask.schedule(0);
93
    }
94
95
    public static void removeConnectionStateChangeListener(ConnectionStateChangeListener listener, URI uri) {
96
        URIMatcher m = new URIMatcher(uri);
97
98
        synchronized (map) {
99
            for (Map.Entry<URI, WeakSet<ConnectionStateChangeListener>> entry : map.entrySet()) {
100
                if (m.isIdenticalURI(entry.getKey())) {
101
                    entry.getValue().remove(listener);
102
                    return;
103
                }
104
            }
105
        }
106
    }
107
108
    public static void notifyListeners(URI uri, ConnectionStateChangeEvent ev) {
109
        RP.post(new NotificationTask(uri, ev)).waitFinished();
110
    }
111
112
    // When disconnect is called, first connection get closed and then listeners 
113
    // are notified. If at the same time tracking task is running, it may detect 
114
    // that connection is closed before it gets removed from the list of active 
115
    // connections and hence decide that connection was lost and notify 
116
    // listeners with CONNECTION_LOST event (which is wrong in this situation).
117
    // To avoid this - just stop the TrackingTask before doing real disconnect.
118
    // Called from ConnectionManager.
119
    // 
120
    public static void stopTrackingTask() {
121
        ttask.cancel();
122
        ttask.waitFinished();
123
    }
124
125
    private static class NotificationTask implements Runnable {
126
127
        private final URI uri;
128
        private final ConnectionStateChangeEvent ev;
129
130
        public NotificationTask(URI uri, ConnectionStateChangeEvent ev) {
131
            this.uri = uri;
132
            this.ev = ev;
133
        }
134
135
        @Override
136
        public void run() {
137
            URIMatcher m = new URIMatcher(uri);
138
            List<ConnectionStateChangeListener> toNotify = new ArrayList<ConnectionStateChangeListener>();
139
140
            synchronized (map) {
141
                for (Map.Entry<URI, WeakSet<ConnectionStateChangeListener>> entry : map.entrySet()) {
142
                    if (m.isIdenticalURI(entry.getKey())) {
143
                        WeakSet<ConnectionStateChangeListener> set = entry.getValue();
144
                        for (ConnectionStateChangeListener l : set) {
145
                            toNotify.add(l);
146
                        }
147
                    }
148
                }
149
            }
150
151
            for (ConnectionStateChangeListener l : toNotify) {
152
                l.connectionStateChanged(ev);
153
            }
154
155
            boolean activated = State.CONNECTION_ESTABLISHED.equals(ev.getState());
156
157
            Iterator<URI> it = active.iterator();
158
            while (it.hasNext()) {
159
                if (m.isIdenticalURI(it.next())) {
160
                    assert !activated;
161
                    it.remove();
162
                }
163
            }
164
165
            if (activated) {
166
                active.add(uri);
167
            }
168
169
            ttask.schedule(0);
170
        }
171
    }
172
173
    /**
174
     * This task periodically asks registered active connections for their state
175
     * and detects lost connections...
176
     */
177
    private static class TrackTask implements Runnable {
178
179
        @Override
180
        public void run() {
181
            List<URI> lost = new ArrayList<URI>();
182
183
            boolean restart = false;
184
185
            for (URI uri : active) {
186
                Connection c = ConnectionManager.getConnection(uri);
187
                if (c != null && c.isConnected()) {
188
                    restart = true;
189
                    continue;
190
                }
191
192
                lost.add(uri);
193
            }
194
195
            for (URI uri : lost) {
196
                notifyListeners(uri, new ConnectionStateChangeEvent(uri, State.CONNECTION_LOST));
197
            }
198
199
            if (restart) {
200
                ttask.schedule(1000);
201
            }
202
        }
203
    }
204
}
(-)a/cnd.execution/src/org/netbeans/modules/cnd/execution/common/ConnectionServiceLookup.java (+74 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2012 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 2012 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.cnd.execution.common;
43
44
import java.net.URI;
45
import org.openide.util.Lookup;
46
import org.openide.util.lookup.Lookups;
47
48
/**
49
 *
50
 * @author akrasny
51
 */
52
public final class ConnectionServiceLookup {
53
54
    private ConnectionServiceLookup() {
55
    }
56
57
    public static Lookup getServiceLookup(URI uri) {
58
        String scheme = uri.getScheme();
59
        if (scheme == null) {
60
            String src = uri.toString();
61
            StringBuilder sb = new StringBuilder();
62
            for (char c : src.toCharArray()) {
63
                if (Character.isLetterOrDigit(c)) {
64
                    sb.append(c);
65
                } else {
66
                    break;
67
                }
68
            }
69
            scheme = sb.toString();
70
        }
71
        Lookup lookup = Lookups.forPath("ConnectionService/" + scheme); // NOI18N
72
        return lookup;
73
    }
74
}
(-)a/cnd.execution/src/org/netbeans/modules/cnd/execution/common/ConnectionsInfo.java (+146 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2012 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 2012 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.cnd.execution.common;
43
44
import java.net.URI;
45
import java.util.Collection;
46
import java.util.HashMap;
47
import java.util.Map;
48
import org.netbeans.modules.cnd.execution.access.ConnectionAccessor;
49
import org.netbeans.modules.cnd.execution.access.EnvironmentMapAccessor;
50
import org.netbeans.modules.cnd.execution.api.Connection;
51
import org.netbeans.modules.cnd.execution.api.EnvironmentMap;
52
import org.netbeans.modules.cnd.execution.api.NativeExecutionException;
53
import org.netbeans.modules.cnd.execution.spi.support.ConnectionInfo;
54
import org.netbeans.modules.cnd.execution.spi.support.ConnectionInfoProvider;
55
import org.netbeans.modules.cnd.execution.util.HostInfo;
56
import org.netbeans.modules.cnd.execution.util.URIMatcher;
57
import org.openide.util.Lookup;
58
59
/**
60
 * An entry point for getting {@link Connection} information from providers.
61
 *
62
 * @author akrasny
63
 */
64
public final class ConnectionsInfo {
65
66
    private static final Map<URI, ConnectionInfo> infoCache = new HashMap<URI, ConnectionInfo>();
67
68
    private ConnectionsInfo() {
69
    }
70
71
    public static ConnectionInfo getConnectionInfo(URI uri) {
72
        synchronized (infoCache) {
73
            URIMatcher m = new URIMatcher(uri);
74
            for (Map.Entry<URI, ConnectionInfo> entry : infoCache.entrySet()) {
75
                if (m.isIdenticalURI(entry.getKey())) {
76
                    return entry.getValue();
77
                }
78
            }
79
        }
80
81
        return null;
82
    }
83
84
    public static void setConnectionInfo(URI uri, ConnectionInfo info) {
85
        synchronized (infoCache) {
86
            URIMatcher m = new URIMatcher(uri);
87
            for (Map.Entry<URI, ConnectionInfo> entry : infoCache.entrySet()) {
88
                if (m.isIdenticalURI(entry.getKey())) {
89
                    entry.setValue(info);
90
                    return;
91
                }
92
            }
93
            infoCache.put(uri, info);
94
        }
95
    }
96
97
    public static void refreshConnectionInfo(final Connection connection) {
98
        final ConnectionAccessor access = ConnectionAccessor.getDefault();
99
        final Lookup lookup = access.getConnectionLookup(connection);
100
101
        if (lookup == null) {
102
            return;
103
        }
104
105
        final Collection<? extends ConnectionInfoProvider> providers =
106
                lookup.lookupAll(ConnectionInfoProvider.class);
107
108
        final ProxyInfo info = new ProxyInfo();
109
110
        for (ConnectionInfoProvider provider : providers) {
111
            try {
112
                ConnectionInfo data = provider.getConnectionInfo(connection);
113
                if (data != null) {
114
                    Map<String, String> map = data.getEnvironmentMap();
115
                    if (map != null) {
116
                        info.env.putAll(data.getEnvironmentMap());
117
                    }
118
                    
119
                    Map<String, String> props = data.getProperties();
120
                    if (props != null) {
121
                        info.properties.putAll(props);
122
                    }
123
                }
124
            } catch (NativeExecutionException ex) {
125
            }
126
        }
127
128
        setConnectionInfo(connection.getURI(), info);
129
    }
130
131
    private static final class ProxyInfo implements ConnectionInfo {
132
133
        final Map<String, String> env = new HashMap<String, String>();
134
        final Map<String, String> properties = new HashMap<String, String>();
135
136
        @Override
137
        public Map<String, String> getEnvironmentMap() {
138
            return env;
139
        }
140
141
        @Override
142
        public Map<String, String> getProperties() {
143
            return properties;
144
        }
145
    }
146
}
(-)a/cnd.execution/src/org/netbeans/modules/cnd/execution/common/ConnectionsPool.java (+85 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2012 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 2012 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.cnd.execution.common;
43
44
import java.net.URI;
45
import org.netbeans.modules.cnd.execution.api.Connection;
46
import org.netbeans.modules.cnd.execution.util.URIMatcher;
47
import org.openide.util.WeakSet;
48
49
/**
50
 * In-memory pool of all ever-known at least once established connections.
51
 *
52
 * @author Andrew
53
 */
54
public final class ConnectionsPool {
55
56
    private static final WeakSet<Connection> pool = new WeakSet<Connection>();
57
58
    private ConnectionsPool() {
59
    }
60
61
    public static void add(Connection connection) {
62
        URIMatcher m = new URIMatcher(connection.getURI());
63
64
        synchronized (pool) {
65
            for (Connection c : pool) {
66
                if (m.isIdenticalURI(c.getURI())) {
67
                    return;
68
                }
69
            }
70
            pool.add(connection);
71
        }
72
    }
73
74
    public static Connection get(URI uri) {
75
        URIMatcher m = new URIMatcher(uri);
76
        synchronized (pool) {
77
            for (Connection c : pool) {
78
                if (m.isIdenticalURI(c.getURI())) {
79
                    return c;
80
                }
81
            }
82
        }
83
        return null;
84
    }
85
}
(-)a/cnd.execution/src/org/netbeans/modules/cnd/execution/common/ConnectionsRegistry.java (+302 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2012 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 2012 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.cnd.execution.common;
43
44
import java.net.URI;
45
import java.util.Arrays;
46
import java.util.HashMap;
47
import java.util.LinkedList;
48
import java.util.List;
49
import java.util.Map;
50
import java.util.concurrent.CopyOnWriteArraySet;
51
import java.util.concurrent.ExecutionException;
52
import java.util.concurrent.atomic.AtomicReference;
53
import java.util.prefs.BackingStoreException;
54
import java.util.prefs.Preferences;
55
import javax.swing.event.ChangeListener;
56
import org.netbeans.modules.cnd.execution.access.ConnectionAccessor;
57
import org.netbeans.modules.cnd.execution.access.EnvironmentMapAccessor;
58
import org.netbeans.modules.cnd.execution.api.Connection;
59
import org.netbeans.modules.cnd.execution.api.EnvironmentMap;
60
import org.netbeans.modules.cnd.execution.spi.support.ConnectionInfo;
61
import org.netbeans.modules.cnd.execution.util.URIMatcher;
62
import org.openide.util.ChangeSupport;
63
import org.openide.util.Exceptions;
64
import org.openide.util.NbPreferences;
65
import org.openide.util.RequestProcessor;
66
import org.openide.util.RequestProcessor.Task;
67
68
/**
69
 *
70
 * @author akrasny
71
 */
72
public final class ConnectionsRegistry {
73
//
74
//    private static final RequestProcessor RP = new RequestProcessor(ConnectionsRegistry.class.getName(), 1);
75
//    private static final ConnectionsRegistry instance = new ConnectionsRegistry();
76
//    private final AtomicReference<Task> restoreTask = new AtomicReference<Task>();
77
//    private final CopyOnWriteArraySet<Connection> connections = new CopyOnWriteArraySet<Connection>();
78
//    private final ChangeSupport cs = new ChangeSupport(this);
79
//    private final Task writeTask;
80
//
81
//    static {
82
//        instance.init();
83
//    }
84
//
85
//    private ConnectionsRegistry() {
86
//        writeTask = RP.create(new Runnable() {
87
//
88
//            @Override
89
//            public void run() {
90
//                storeImpl();
91
//            }
92
//        }, true);
93
//    }
94
//
95
//    private void init() {
96
//        restoreTask.set(RP.post(new Runnable() {
97
//
98
//            @Override
99
//            public void run() {
100
//                connections.addAll(restoreImpl());
101
//            }
102
//        }));
103
//    }
104
//
105
//    public static ConnectionsRegistry getInstance() {
106
//        Task r = instance.restoreTask.get();
107
//        if (r != null) {
108
//            r.waitFinished();
109
//            instance.restoreTask.set(null);
110
//        }
111
//        return instance;
112
//    }
113
//
114
//    public Connection getConnection(URI uri) {
115
//        URIMatcher matcher = new URIMatcher(uri);
116
//        for (Connection connection : connections) {
117
//            if (matcher.isIdenticalURI(connection.getURI())) {
118
//                return connection;
119
//            }
120
//        }
121
//        return null;
122
//    }
123
//
124
//    public List<Connection> getConnections() {
125
//        return Arrays.asList(connections.toArray(new Connection[connections.size()]));
126
//    }
127
//
128
//    public void addChangeListener(ChangeListener listener) {
129
//        cs.addChangeListener(listener);
130
//    }
131
//
132
//    public void removeChangeListener(ChangeListener listener) {
133
//        cs.addChangeListener(listener);
134
//    }
135
//
136
//    public void addConnection(Connection connection) {
137
//        connections.add(connection);
138
//        changed();
139
//    }
140
//
141
//    public void removeConnection(Connection connection) {
142
//        connections.remove(connection);
143
//        Connections.setConnectionInfo(connection.getURI(), null);
144
//        changed();
145
//    }
146
//
147
//    private void changed() {
148
//        writeTask.schedule(0);
149
//        cs.fireChange();
150
//    }
151
//
152
//    private void storeImpl() {
153
//        List<Connection> data = getConnections();
154
//        Preferences props = NbPreferences.forModule(ConnectionsRegistry.class);
155
//        try {
156
//            props.clear();
157
//
158
//            for (Connection connection : data) {
159
//                final URI uri = connection.getURI();
160
//                Preferences cprop = props.node(toFileName(uri));
161
//                ConnectionInfo info = Connections.getConnectionInfo(uri);
162
//                if (info != null) {
163
//                    EnvironmentMap envMap = info.getEnvironmentMap();
164
//                    if (envMap != null) {
165
//                        Preferences envprop = cprop.node("env"); // NOI18N
166
//                        EnvironmentMapAccessor.getDefault().store(envMap, envprop);
167
//                        envprop.flush();
168
//                    }
169
//
170
//                    Map<String, String> connprop = info.getProperties();
171
//                    if (connprop != null) {
172
//                        Preferences infoprop = cprop.node("props"); // NOI18N
173
//                        for (Map.Entry<String, String> entry : connprop.entrySet()) {
174
//                            infoprop.put(entry.getKey(), entry.getValue());
175
//                        }
176
//                        infoprop.flush();
177
//                    }
178
//                }
179
//                cprop.flush();
180
//            }
181
//
182
//            props.flush();
183
//        } catch (BackingStoreException ex) {
184
//            Exceptions.printStackTrace(ex);
185
//        }
186
//    }
187
//
188
//    private static List<Connection> restoreImpl() {
189
//        ConnectionAccessor access = ConnectionAccessor.getDefault();
190
//        Preferences props = NbPreferences.forModule(ConnectionsRegistry.class);
191
//        List<Connection> result = new LinkedList<Connection>();
192
//        try {
193
//            for (String fname : props.childrenNames()) {
194
//                URI uri = fromFileName(fname);
195
//                if (uri == null) {
196
//                    continue;
197
//                }
198
//
199
//                Connection connection = access.createConnection(uri);
200
//                Preferences cprops = props.node(fname);
201
//                Preferences envprop = cprops.node("env"); // NOI18N
202
//                final EnvironmentMap envmap = EnvironmentMapAccessor.getDefault().load(envprop);
203
//
204
//                Preferences infoprop = cprops.node("props"); // NOI18N
205
//                final Map<String, String> connprop = new HashMap<String, String>();
206
//                for (String key : infoprop.keys()) {
207
//                    connprop.put(key, infoprop.get(key, "")); // NOI18N
208
//                }
209
//
210
//                Connections.setConnectionInfo(uri, new ConnectionInfo() {
211
//
212
//                    @Override
213
//                    public EnvironmentMap getEnvironmentMap() {
214
//                        return envmap;
215
//                    }
216
//
217
//                    @Override
218
//                    public Map<String, String> getProperties() {
219
//                        return connprop;
220
//                    }
221
//                });
222
//
223
//                getInstance().addConnection(connection);
224
//            }
225
//        } catch (BackingStoreException ex) {
226
//            Exceptions.printStackTrace(ex);
227
//        }
228
//        return result;
229
//    }
230
//
231
//    private static String toFileName(URI uri) {
232
//        String id = uri.toString();
233
//        StringBuilder res = new StringBuilder();
234
//        for (char c : id.toCharArray()) {
235
//            switch (c) {
236
//                case '/':
237
//                    res.append("%s");
238
//                    break;
239
//                case ':':
240
//                    res.append("%c");
241
//                    break;
242
//                case '%':
243
//                    res.append("%%"); // NOI18N
244
//                    break;
245
//                default:
246
//                    res.append(c);
247
//            }
248
//        }
249
//        return res.toString();
250
//    }
251
//
252
//    private static URI fromFileName(String envName) {
253
//        StringBuilder res = new StringBuilder();
254
//        char[] chars = envName.toCharArray();
255
//        for (int i = 0; i < chars.length; i++) {
256
//            char c = chars[i];
257
//            if (c == '%') {
258
//                if (++i == chars.length) {
259
//                    return null;
260
//                }
261
//                switch (chars[i]) {
262
//                    case '%':
263
//                        res.append('%');
264
//                        break;
265
//                    case 'c':
266
//                        res.append(':');
267
//                        break;
268
//                    case 's':
269
//                        res.append('/');
270
//                        break;
271
//                }
272
//            } else {
273
//                res.append(c);
274
//            }
275
//        }
276
//
277
//        try {
278
//            return URI.create(res.toString());
279
//        } catch (IllegalArgumentException ex) {
280
//        }
281
//
282
//        return null;
283
//    }
284
//
285
//    void waitReady(final boolean shutdown) {
286
//        try {
287
//            RP.submit(new Runnable() {
288
//
289
//                @Override
290
//                public void run() {
291
//                    if (shutdown) {
292
//                        RP.shutdown();
293
//                    }
294
//                }
295
//            }).get();
296
//        } catch (InterruptedException ex) {
297
//            Exceptions.printStackTrace(ex);
298
//        } catch (ExecutionException ex) {
299
//            Exceptions.printStackTrace(ex);
300
//        }
301
//    }
302
}
(-)a/cnd.execution/src/org/netbeans/modules/cnd/execution/common/Connector.java (+192 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2012 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 2012 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.cnd.execution.common;
43
44
import java.io.IOException;
45
import java.io.InterruptedIOException;
46
import java.net.URI;
47
import java.util.concurrent.atomic.AtomicReference;
48
import javax.swing.SwingUtilities;
49
import org.netbeans.api.progress.ProgressHandle;
50
import org.netbeans.api.progress.ProgressHandleFactory;
51
import org.netbeans.api.progress.ProgressRunnable;
52
import org.netbeans.api.progress.ProgressUtils;
53
import org.netbeans.modules.cnd.execution.access.ConnectionAccessor;
54
import org.netbeans.modules.cnd.execution.api.Connection;
55
import org.netbeans.modules.cnd.execution.api.NativeExecutionException;
56
import org.netbeans.modules.cnd.execution.spi.AuthDataProvider;
57
import org.netbeans.modules.cnd.execution.spi.ConnectionImplementation;
58
import org.netbeans.modules.cnd.execution.spi.ConnectorImplementation;
59
import org.openide.util.Cancellable;
60
import org.openide.util.Lookup;
61
import org.openide.util.NbBundle;
62
63
/**
64
 *
65
 * @author akrasny
66
 */
67
public final class Connector {
68
69
    public static ConnectionImplementation connect(URI uri, AuthDataProvider authDataProvider) throws IOException {
70
        return connectImpl(uri, authDataProvider);
71
    }
72
73
    private static ConnectionImplementation connectImpl(final URI uri, final AuthDataProvider authDataProvider) throws IOException {
74
        final AtomicReference<ConnectionImplementation> resultRef = new AtomicReference<ConnectionImplementation>();
75
        final AtomicReference<IOException> exRef = new AtomicReference<IOException>();
76
        final String msg = NbBundle.getMessage(Connector.class, "Connector.progress.connectTo", uri.getHost()); // NOI18N
77
        final ProgressRunnableImpl connectionTask = new ProgressRunnableImpl(
78
                uri, authDataProvider, resultRef, exRef,
79
                SwingUtilities.isEventDispatchThread() ? null : Thread.currentThread());
80
81
        if (SwingUtilities.isEventDispatchThread()) {
82
            ProgressUtils.showProgressDialogAndRun(connectionTask, msg, true);
83
        } else {
84
            ProgressHandle progressHandle = ProgressHandleFactory.createHandle(msg, connectionTask);
85
            try {
86
                progressHandle.start();
87
                progressHandle.switchToIndeterminate();
88
                connectionTask.run(progressHandle);
89
            } finally {
90
                progressHandle.finish();
91
            }
92
        }
93
94
        IOException exception = exRef.get();
95
96
        if (exception != null) {
97
            throw exception;
98
        }
99
100
        return resultRef.get();
101
    }
102
103
    private static class ProxyAuthDataProvider implements AuthDataProvider {
104
105
        private final AuthDataProvider defaultProvider;
106
        private final AuthDataProvider origProvider;
107
108
        private ProxyAuthDataProvider(Lookup lookup, AuthDataProvider authDataProvider) {
109
            this.origProvider = authDataProvider;
110
            this.defaultProvider = lookup.lookup(AuthDataProvider.class);
111
        }
112
113
        @Override
114
        public <T> T getProperty(URI uri, Class<T> clazz, String name, Object... misc) {
115
            T result = origProvider == null ? null
116
                    : origProvider.getProperty(uri, clazz, name, misc);
117
            if (result == null && defaultProvider != null) {
118
                result = defaultProvider.getProperty(uri, clazz, name, misc);
119
            }
120
            return result;
121
        }
122
    }
123
124
    private static class ProgressRunnableImpl implements ProgressRunnable<Void>, Cancellable {
125
126
        private final URI uri;
127
        private final AuthDataProvider authDataProvider;
128
        private final AtomicReference<ConnectionImplementation> resultRef;
129
        private final AtomicReference<IOException> exRef;
130
        private final Thread thread;
131
132
        public ProgressRunnableImpl(URI uri, AuthDataProvider authDataProvider,
133
                AtomicReference<ConnectionImplementation> resultRef, AtomicReference<IOException> exRef,
134
                Thread thread) {
135
            this.uri = uri;
136
            this.authDataProvider = authDataProvider;
137
            this.resultRef = resultRef;
138
            this.exRef = exRef;
139
            this.thread = thread;
140
        }
141
142
        @Override
143
        public Void run(final ProgressHandle handle) {
144
            final ConnectionAccessor access = ConnectionAccessor.getDefault();
145
            final Lookup lookup = ConnectionServiceLookup.getServiceLookup(uri);
146
            final AuthDataProvider provider = new ProxyAuthDataProvider(lookup, authDataProvider);
147
148
            for (ConnectorImplementation connector : lookup.lookupAll(ConnectorImplementation.class)) {
149
                try {
150
                    ConnectionImplementation connectionImpl = connector.connectTo(uri, provider);
151
152
                    if (connectionImpl == null) {
153
                        continue;
154
                    }
155
156
                    // We create a new Connection, but without any registration
157
                    // in any registry... It's too early - need to get it's 
158
                    // info first (But for this we need a Connection, as getting
159
                    // info may require starting some processes using this 
160
                    // connection
161
                    Connection tmpConnection = access.createConnection(connectionImpl);
162
163
                    handle.setDisplayName(NbBundle.getMessage(Connector.class,
164
                            "Connector.progress.fetchingInfo")); // NOI18N
165
166
                    ConnectionsInfo.refreshConnectionInfo(tmpConnection);
167
                    resultRef.set(connectionImpl);
168
169
                    // done
170
                    return null;
171
                } catch (IOException ex) {
172
                    exRef.compareAndSet(null, ex);
173
                } catch (InterruptedException ex) {
174
                    exRef.compareAndSet(null, new InterruptedIOException(uri.toString()));
175
                    break;
176
                }
177
            }
178
179
            exRef.compareAndSet(null, new NativeExecutionException("Unsupported connection scheme: " + uri)); // NOI18N
180
            return null;
181
        }
182
183
        @Override
184
        public boolean cancel() {
185
            exRef.compareAndSet(null, new InterruptedIOException(uri.toString()));
186
            if (thread != null) {
187
                thread.interrupt();
188
            }
189
            return true;
190
        }
191
    }
192
}
(-)a/cnd.execution/src/org/netbeans/modules/cnd/execution/common/NativeProcess.java (+437 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2012 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 2012 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.cnd.execution.common;
43
44
import java.io.ByteArrayInputStream;
45
import java.io.ByteArrayOutputStream;
46
import java.io.InputStream;
47
import java.io.OutputStream;
48
import java.nio.charset.Charset;
49
import java.util.concurrent.Callable;
50
import java.util.concurrent.Future;
51
import java.util.concurrent.atomic.AtomicBoolean;
52
import java.util.concurrent.locks.ReentrantLock;
53
import java.util.logging.Level;
54
import org.netbeans.api.extexecution.process.ProcessCharset;
55
import org.netbeans.api.extexecution.process.ProcessId;
56
import org.netbeans.api.extexecution.process.ProcessSignal;
57
import org.netbeans.modules.cnd.execution.api.process.ProcessState;
58
import org.netbeans.modules.cnd.execution.api.process.ProcessState.State;
59
import org.netbeans.modules.cnd.execution.ExecutionLogger;
60
import org.netbeans.modules.cnd.execution.access.NativeProcessAccessor;
61
import org.netbeans.modules.cnd.execution.api.Connection;
62
import org.netbeans.modules.cnd.execution.api.NativeExecutionException;
63
import org.netbeans.modules.cnd.execution.spi.NativeProcessCreator;
64
import org.netbeans.modules.cnd.execution.spi.NativeProcessImplementation;
65
import org.netbeans.modules.cnd.execution.spi.NativeProcessParams;
66
import org.openide.util.Exceptions;
67
import org.openide.util.Lookup;
68
import org.openide.util.RequestProcessor;
69
import org.openide.util.lookup.Lookups;
70
import org.openide.util.lookup.ProxyLookup;
71
72
/**
73
 * An object that represents an external process.
74
 *
75
 * @author akrasny
76
 */
77
public final class NativeProcess extends Process implements Lookup.Provider {
78
79
    private static final RequestProcessor waitThreadPool = new RequestProcessor("Process waitThreadPool", 50); // NOI18N
80
    private final ReentrantLock stateLock = new ReentrantLock();
81
    private final ProcessStateChangeNotifier notifier;
82
    private final NativeProcessCreator creator;
83
    private final NativeProcessParams params;
84
    private final AtomicBoolean killed = new AtomicBoolean(false);
85
    private final Lookup fixedLookup;
86
    private Lookup lookup;
87
    private State state = State.INITIAL;
88
    private NativeProcessImplementation processImpl;
89
    private Future<Integer> waitTask = null;
90
    private InputStream inputStream;
91
    private InputStream errorStream;
92
    private OutputStream outputStream;
93
94
    static {
95
        NativeProcessAccessor.setDefault(new NativeProcessAccessorImpl());
96
    }
97
98
    public NativeProcess(NativeProcessCreator creator, NativeProcessParams params, ProcessStateChangeNotifier notifier) {
99
        this.creator = creator;
100
        this.params = params;
101
        this.notifier = notifier;
102
        inputStream = new ByteArrayInputStream(new byte[0]);
103
        errorStream = new ByteArrayInputStream(new byte[0]);
104
        outputStream = new ByteArrayOutputStream();
105
        fixedLookup = Lookups.fixed(
106
                new NativeProcessId(),
107
                new NativeProcessCharset(),
108
                new NativeProcessState(),
109
                new NativeProcessSignal());
110
    }
111
112
    public NativeProcess start() throws NativeExecutionException {
113
        try {
114
            setState(State.STARTING);
115
            processImpl = creator.createAndStart(params);
116
117
            if (processImpl instanceof Lookup.Provider) {
118
                Lookup.Provider provider = (Lookup.Provider) processImpl;
119
                lookup = new ProxyLookup(fixedLookup, provider.getLookup());
120
            } else {
121
                lookup = fixedLookup;
122
            }
123
124
            inputStream = processImpl.getInputStream();
125
            errorStream = processImpl.getErrorStream();
126
            outputStream = processImpl.getOutputStream();
127
128
            setState(State.RUNNING);
129
130
            waitTask = waitThreadPool.submit(new Callable<Integer>() {
131
132
                @Override
133
                public Integer call() throws Exception {
134
                    Thread.currentThread().setName("Waiting for " + processImpl.toString()); // NOI18N
135
                    int exitCode = -1;
136
137
                    try {
138
                        exitCode = processImpl.waitResult();
139
                        setState(State.FINISHED);
140
                    } catch (Throwable th) {
141
                        setState(State.ERROR);
142
                        killProcess();
143
                        throw new java.util.concurrent.ExecutionException(th);
144
                    }
145
146
                    return exitCode;
147
                }
148
            });
149
        } catch (Throwable ex) {
150
            throw new NativeExecutionException(ex);
151
        }
152
153
        return this;
154
    }
155
156
    private void killProcess() {
157
        if (killed.getAndSet(true)) {
158
            return;
159
        }
160
161
        processImpl.destroy();
162
    }
163
164
    /**
165
     * Returns a current state of the process.
166
     *
167
     * @return the current state.
168
     */
169
    public State getState() {
170
        State result;
171
        stateLock.lock();
172
        try {
173
            result = state;
174
        } finally {
175
            stateLock.unlock();
176
        }
177
        return result;
178
    }
179
180
    private boolean isFinalState(final State state) {
181
        return state == State.ERROR || state == State.FINISHED;
182
    }
183
184
    /**
185
     * Sets a current state of the process.
186
     *
187
     * There is a notion of a final state. Once a process was set into one of
188
     * the final state, it's state will not change.
189
     *
190
     * A final state is one of the CANCELLED, ERROR or FINISHED.
191
     *
192
     * @param state a new state of the process.
193
     */
194
    private void setState(final State state) {
195
        stateLock.lock();
196
        try {
197
            if (this.state == state || isFinalState(this.state)) {
198
                return;
199
            }
200
201
            this.state = state;
202
203
            if (notifier != null) {
204
                notifier.notifyProcessStateChange(state);
205
            }
206
        } finally {
207
            stateLock.unlock();
208
        }
209
    }
210
211
    /**
212
     * Returns a PID of the process.
213
     *
214
     * PID is provided by implementors of an SPI. By convention, if PID cannot
215
     * be provided, -1 is returned.
216
     *
217
     * @return the PID of the process or -1 if real PID cannot be provided.
218
     */
219
    public int getPID() {
220
        return processImpl.getPID();
221
    }
222
223
    /**
224
     * Gets the output stream of the process.
225
     *
226
     * <p>Output to the stream is piped into the standard input stream of the
227
     * process represented by this {@link NativeProcess} object.</p>
228
     *
229
     * @return the output stream connected to the normal input of the process.
230
     */
231
    @Override
232
    public OutputStream getOutputStream() {
233
        return outputStream;
234
    }
235
236
    /**
237
     * Gets the input stream of the process.
238
     *
239
     * <p>The stream obtains data piped from the standard output stream of the
240
     * process represented by this {@link NativeProcess} object. </p>
241
     *
242
     * @return the input stream connected to the normal output of the process.
243
     */
244
    @Override
245
    public InputStream getInputStream() {
246
        return inputStream;
247
    }
248
249
    /**
250
     * Gets the error stream of the process.
251
     *
252
     * <p>The stream obtains data piped from the error output stream of the
253
     * process represented by this {@link NativeProcess} object.</p>
254
     *
255
     * @return the input stream connected to the error stream of the process.
256
     */
257
    @Override
258
    public InputStream getErrorStream() {
259
        return errorStream;
260
    }
261
262
    /**
263
     * Causes the current thread to wait, if necessary, until the process
264
     * represented by this {@link NativeProcess} object has terminated.
265
     *
266
     * <p>This method returns immediately if the process has already terminated.
267
     * If the process has not yet terminated, the calling thread will be blocked
268
     * until the process exits.</p>
269
     *
270
     * @return the exit value of the process. By convention, 0 indicates normal
271
     * termination.
272
     * @throws InterruptedException if the current thread is interrupted by
273
     * another thread while it is waiting, then the wait is ended and an
274
     * InterruptedException is thrown.
275
     */
276
    @Override
277
    public int waitFor() throws InterruptedException {
278
        try {
279
            return waitTask.get();
280
        } catch (java.util.concurrent.ExecutionException ex) {
281
            // Should not happen. 
282
            // Exception here could mean that there are problems in 
283
            // implementation
284
            Exceptions.printStackTrace(ex);
285
            throw new InternalError(ex.toString());
286
        }
287
    }
288
289
    /**
290
     * Returns the exit value for the process.
291
     *
292
     * <p>{@link IllegalThreadStateException} is thrown if process is not
293
     * terminated yet.</p>
294
     *
295
     * @return the exit value of the process represented by this {@link NativeProcess}
296
     * object. By convention, the value {@code 0} indicates normal termination.
297
     */
298
    @Override
299
    public int exitValue() {
300
        if (!waitTask.isDone()) {
301
            // Process not started/finished yet...
302
            throw new IllegalThreadStateException();
303
        }
304
305
        try {
306
            return waitTask.get();
307
        } catch (InterruptedException ex) {
308
            // Should not happen
309
            Thread.interrupted();
310
            return -1;
311
        } catch (java.util.concurrent.ExecutionException ex) {
312
            // Should not happen. 
313
            // Exception here could mean that there are problems in 
314
            // implementation
315
            Exceptions.printStackTrace(ex);
316
            throw new InternalError(ex.toString());
317
        }
318
    }
319
320
    /**
321
     * Kills the subprocess.
322
     *
323
     * The subprocess represented by this {@link NativeProcess} object is
324
     * forcibly terminated.
325
     */
326
    @Override
327
    public void destroy() {
328
        killProcess();
329
    }
330
331
    /**
332
     * Returns a human-readable identification of the
333
     * {@link NativeProcess}.
334
     *
335
     * @return string that identifies the {@link NativeProcess}.
336
     */
337
    @Override
338
    public String toString() {
339
        return "/PID=" + getPID() + "/ " + processImpl.toString(); // NOI18N
340
    }
341
342
    @Override
343
    public Lookup getLookup() {
344
        return lookup;
345
    }
346
347
    private static Charset getProcessOutputCharset(Process process) {
348
        return getCharset("outputCharset", process); // NOI18N
349
    }
350
351
    private static Charset getProcessInputCharset(Process process) {
352
        return getCharset("inputCharset", process); // NOI18N
353
    }
354
355
    private static Charset getCharset(String paramName, Process process) {
356
357
        Charset charset = null;
358
359
        if (process instanceof NativeProcess) {
360
            NativeProcess np = (NativeProcess) process;
361
            NativeProcessAccessor access = NativeProcessAccessor.getDefault();
362
            NativeProcessParams params = access.getProcessParams(np);
363
            charset = null; // params.getProperty(Charset.class, paramName);
364
        }
365
366
        if (charset == null || !Charset.isSupported(charset.name())) {
367
            charset = Charset.isSupported("UTF-8") // NOI18N
368
                    ? Charset.forName("UTF-8") : // NOI18N
369
                    Charset.defaultCharset(); // NOI18N
370
            ExecutionLogger.getInstance().log(Level.FINE,
371
                    "{0} is not set or is not supported - use {1}", // NOI18N
372
                    new Object[]{paramName, charset.name()});
373
        }
374
375
        return charset;
376
    }
377
378
    private class NativeProcessId extends ProcessId {
379
380
        @Override
381
        protected Integer getId() {
382
            return NativeProcess.this.getPID();
383
        }
384
    }
385
386
    private class NativeProcessState extends ProcessState {
387
388
        @Override
389
        protected State getState() {
390
            return NativeProcess.this.getState();
391
        }
392
    }
393
394
    private class NativeProcessCharset extends ProcessCharset {
395
396
        @Override
397
        protected Charset getInputCharset() {
398
            return getProcessInputCharset(NativeProcess.this);
399
        }
400
401
        @Override
402
        protected Charset getOutputCharset() {
403
            return getProcessOutputCharset(NativeProcess.this);
404
        }
405
406
        @Override
407
        protected Charset getErrorCharset() {
408
            return getProcessOutputCharset(NativeProcess.this);
409
        }  
410
    }
411
412
    private class NativeProcessSignal extends ProcessSignal {
413
414
        @Override
415
        protected void signal(Signal signal) {
416
            SignalUtils.signal(NativeProcess.this, SignalUtils.translate(signal));
417
        }
418
419
        @Override
420
        protected void signalGroup(Signal signal) {
421
            SignalUtils.signalGrp(NativeProcess.this, SignalUtils.translate(signal));
422
        }
423
    }
424
425
    private static class NativeProcessAccessorImpl extends NativeProcessAccessor {
426
427
        @Override
428
        public Connection getConnection(NativeProcess process) {
429
            return process.params.getConnection();
430
        }
431
432
        @Override
433
        public NativeProcessParams getProcessParams(NativeProcess process) {
434
            return process.params;
435
        }
436
    }
437
}
(-)a/cnd.execution/src/org/netbeans/modules/cnd/execution/common/ProcessStateChangeNotifier.java (+53 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2012 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 2012 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.cnd.execution.common;
43
44
import org.netbeans.modules.cnd.execution.api.process.ProcessState.State;
45
46
/**
47
 *
48
 * @author akrasny
49
 */
50
public interface ProcessStateChangeNotifier {
51
52
    public void notifyProcessStateChange(final State newProcessState);
53
}
(-)a/cnd.execution/src/org/netbeans/modules/cnd/execution/common/SignalUtils.java (+285 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2012 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 2012 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.cnd.execution.common;
43
44
import java.net.URI;
45
import java.util.EnumMap;
46
import java.util.Map;
47
import org.netbeans.api.extexecution.process.ProcessSignal;
48
import org.netbeans.modules.cnd.execution.access.ConnectionAccessor;
49
import org.netbeans.modules.cnd.execution.access.NativeProcessAccessor;
50
import org.netbeans.modules.cnd.execution.api.Connection;
51
import org.netbeans.modules.cnd.execution.api.ConnectionManager;
52
import org.netbeans.modules.cnd.execution.spi.support.SignalSupport;
53
import org.netbeans.modules.cnd.execution.spi.support.SignalSupportProvider;
54
import org.netbeans.modules.cnd.execution.util.HostInfo;
55
import org.openide.util.Lookup;
56
57
/**
58
 * Some systems support Signal mechanism for sending asynchronous events to a
59
 * given process.
60
 *
61
 * This is an API class for delivering signals to a process.
62
 *
63
 * Note: signals-related functionality could be unavailable on some systems or
64
 * irrelevant to some processes.
65
 *
66
 * @author akrasny
67
 */
68
public final class SignalUtils {
69
70
    private static final NativeProcessAccessor access = NativeProcessAccessor.getDefault();
71
72
    private SignalUtils() {
73
    }
74
75
    /**
76
     * Send a specified signal to a process.
77
     *
78
     * @param process the process to signal
79
     * @param signal the signal to send
80
     * @throws UnsupportedOperationException
81
     */
82
    public static void signal(NativeProcess process, Signal signal) throws UnsupportedOperationException {
83
        Connection c = access.getConnection(process);
84
        SignalSupport ss = getSignalSupport(c);
85
        if (ss != null) {
86
            ss.signal(process, signal);
87
        }
88
    }
89
90
    /**
91
     * Send a signal with attached value to a process.
92
     *
93
     * @param process the process to signal
94
     * @param signal the signal to send
95
     * @param value the value to attach to a signal
96
     * @throws UnsupportedOperationException
97
     */
98
    public static void sigqueue(NativeProcess process, Signal signal, int value) throws UnsupportedOperationException {
99
        Connection c = access.getConnection(process);
100
        SignalSupport ss = getSignalSupport(c);
101
        if (ss != null) {
102
            ss.sigqueue(process, signal, value);
103
        }
104
    }
105
106
    /**
107
     * Send a signal to a whole group a process belongs to.
108
     *
109
     * @param process the process (and it's group) to signal
110
     * @param signal the signal to send
111
     * @throws UnsupportedOperationException
112
     */
113
    public static void signalGrp(NativeProcess process, SignalUtils.Signal signal) throws UnsupportedOperationException {
114
        Connection c = access.getConnection(process);
115
        SignalSupport ss = getSignalSupport(c);
116
        if (ss != null) {
117
            ss.signalGrp(process, signal);
118
        }
119
    }
120
121
    /**
122
     * Send a specified signal to a PID in context of the passed Connection.
123
     *
124
     * @param destination the context URI
125
     * @param pid the PID of the process to send signal to
126
     * @param signal the signal to send
127
     * @throws UnsupportedOperationException
128
     */
129
    public void signal(URI destination, int pid, SignalUtils.Signal signal) throws UnsupportedOperationException {
130
        SignalSupport ss = getSignalSupport(destination);
131
        if (ss != null) {
132
            ss.signal(pid, signal);
133
        }
134
    }
135
136
    /**
137
     * Send a specified signal with an attached value to a PID in context of the
138
     * passed Connection.
139
     *
140
     * @param destination the context URI
141
     * @param pid the PID of the process to send signal to
142
     * @param signal the signal to send
143
     * @param value the value to attach to the signal
144
     * @throws UnsupportedOperationException
145
     */
146
    public void sigqueue(URI destination, int pid, SignalUtils.Signal signal, int value) throws UnsupportedOperationException {
147
        SignalSupport ss = getSignalSupport(destination);
148
        if (ss != null) {
149
            ss.sigqueue(pid, signal, value);
150
        }
151
    }
152
153
    /**
154
     * Send a signal to a whole group a process identified by PID belongs to in
155
     * context of the passed Connection.
156
     *
157
     * @param destination the context URI
158
     * @param pid the PID of the process to send signal to (as well as to it's
159
     * group)
160
     * @param signal the signal to send
161
     * @throws UnsupportedOperationException
162
     */
163
    public void signalGrp(URI destination, int pid, SignalUtils.Signal signal) throws UnsupportedOperationException {
164
        SignalSupport ss = getSignalSupport(destination);
165
        if (ss != null) {
166
            ss.signalGrp(pid, signal);
167
        }
168
    }
169
170
    private static SignalSupport getSignalSupport(Connection connection) {
171
        Lookup lookup = ConnectionAccessor.getDefault().getConnectionLookup(connection);
172
        if (lookup == null) {
173
            throw new UnsupportedOperationException();
174
        }
175
176
        SignalSupportProvider signalSupportProvider = lookup.lookup(SignalSupportProvider.class);
177
        if (signalSupportProvider == null) {
178
            throw new UnsupportedOperationException();
179
        }
180
181
        return signalSupportProvider.getSignalSupport(connection);
182
    }
183
184
    private static SignalSupport getSignalSupport(URI destination) throws UnsupportedOperationException {
185
        Connection connection = ConnectionManager.getConnection(destination);
186
        if (connection == null) {
187
            return null;
188
        }
189
        return getSignalSupport(connection);
190
    }
191
192
    private static Map<ProcessSignal.Signal, Signal> translation;
193
194
    public synchronized static Signal translate(ProcessSignal.Signal signal) {
195
        if (translation == null) {
196
            translation = new EnumMap<ProcessSignal.Signal, Signal>(ProcessSignal.Signal.class);
197
            for (Signal sig : Signal.values()) {
198
                ProcessSignal.Signal api = sig.getApiSignal();
199
                if (api != null) {
200
                    translation.put(api, sig);
201
                }
202
            }
203
        }
204
        return translation.get(signal);
205
    }
206
207
    /**
208
     * Available signals
209
     */
210
    public enum Signal {
211
212
        NULL(0, ProcessSignal.Signal.NULL),
213
        SIGHUP(1, ProcessSignal.Signal.SIGHUP),
214
        SIGINT(2, ProcessSignal.Signal.SIGINT),
215
        SIGQUIT(3, ProcessSignal.Signal.SIGQUIT),
216
        SIGILL(4, ProcessSignal.Signal.SIGILL),
217
        SIGTRAP(5, ProcessSignal.Signal.SIGTRAP),
218
        SIGABRT(6, ProcessSignal.Signal.SIGABRT),
219
        SIGEMT(7, ProcessSignal.Signal.SIGEMT),
220
        SIGFPE(8, ProcessSignal.Signal.SIGFPE),
221
        SIGKILL(9, ProcessSignal.Signal.SIGKILL),
222
        SIGBUS(10, ProcessSignal.Signal.SIGBUS),
223
        SIGSEGV(11, ProcessSignal.Signal.SIGSEGV),
224
        SIGSYS(12, ProcessSignal.Signal.SIGSYS),
225
        SIGPIPE(13, ProcessSignal.Signal.SIGPIPE),
226
        SIGALRM(14, ProcessSignal.Signal.SIGALRM),
227
        SIGTERM(15, ProcessSignal.Signal.SIGTERM),
228
        SIGUSR1(16, ProcessSignal.Signal.SIGUSR1),
229
        SIGUSR2(17, ProcessSignal.Signal.SIGUSR2),
230
        SIGCHLD(18, ProcessSignal.Signal.SIGCHLD),
231
        SIGPWR(19, ProcessSignal.Signal.SIGPWR),
232
        SIGWINCH(20, ProcessSignal.Signal.SIGWINCH),
233
        SIGURG(21, ProcessSignal.Signal.SIGURG),
234
        SIGPOLL(22, ProcessSignal.Signal.SIGPOLL),
235
        SIGSTOP(23, ProcessSignal.Signal.SIGSTOP),
236
        SIGTSTP(24, ProcessSignal.Signal.SIGTSTP),
237
        SIGCONT(25, ProcessSignal.Signal.SIGCONT),
238
        SIGTTIN(26, ProcessSignal.Signal.SIGTTIN),
239
        SIGTTOU(27, ProcessSignal.Signal.SIGTTOU),
240
        SIGVTALRM(28, ProcessSignal.Signal.SIGVTALRM),
241
        SIGPROF(29, ProcessSignal.Signal.SIGPROF),
242
        SIGXCPU(30, ProcessSignal.Signal.SIGXCPU),
243
        SIGWAITING(32, ProcessSignal.Signal.SIGWAITING),
244
        SIGLWP(33, ProcessSignal.Signal.SIGLWP),
245
        SIGFREEZE(34, ProcessSignal.Signal.SIGFREEZE),
246
        SIGTHAW(35, ProcessSignal.Signal.SIGTHAW),
247
        SIGCANCEL(36, ProcessSignal.Signal.SIGCANCEL),
248
        SIGLOST(37, ProcessSignal.Signal.SIGLOST),
249
        SIGXRES(38, ProcessSignal.Signal.SIGXRES),
250
        SIGJVM1(39, ProcessSignal.Signal.SIGJVM1);
251
        private final int id;
252
253
        private final ProcessSignal.Signal apiSignal;
254
255
        private Signal(int id, ProcessSignal.Signal apiSignal) {
256
            this.id = id;
257
            this.apiSignal = apiSignal;
258
        }
259
260
        /**
261
         * Returns an integer value of the signal.
262
         *
263
         * This is OS-dependent value.
264
         *
265
         * @param os
266
         * @return a numeric value of the signal.
267
         */
268
        public int getID(HostInfo.OSFamily os) {
269
            return id;
270
        }
271
272
        /**
273
         * Returns signal name
274
         *
275
         * @return signal name
276
         */
277
        public String getID() {
278
            return id == 0 ? "0" : name().substring(4); // NOI18N
279
        }
280
281
        ProcessSignal.Signal getApiSignal() {
282
            return apiSignal;
283
        }
284
    }
285
}
(-)a/cnd.execution/src/org/netbeans/modules/cnd/execution/resources/Bundle.properties (+2 lines)
Line 0 Link Here
1
OpenIDE-Module-Name=Native Execution API
2
(-)a/cnd.execution/src/org/netbeans/modules/cnd/execution/spi/AuthDataProvider.java (+126 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2012 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 2012 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.cnd.execution.spi;
43
44
import java.net.URI;
45
import org.netbeans.modules.cnd.execution.common.Connector;
46
47
/**
48
 * An interface to be implemented to provide an authorization/authentication
49
 * data needed by a {@link ConnectorImplementation} to establish a {@link ConnectionImplementation}.
50
 *
51
 * <p> {@link AuthDataProvider} has a set of constants that represent commonly
52
 * used identifiers for some authorization/authentication info.</p>
53
 *
54
 * <p> The data that is required to establish a connection depends on a nature
55
 * of the connection and features supported by a {@link ConnectorImplementation}.
56
 * In a simple case this could be just a username and a password. In other cases
57
 * this could be a location of some secret file, passphrase or any other
58
 * data.</p>
59
 *
60
 * <p> In some cases implementor could extract needed information from the
61
 * destination URI. In other cases it could look into some database or ask user
62
 * to provide some input.</p>
63
 *
64
 * <p> Possible usage:
65
 * <pre>
66
 *     Connection c = ConnectionManager.connect(new URI("ssh://tester@testhost"), new AuthDataProvider {
67
 *
68
 *       public <T> T getProperty(URI uri, Class<T> clazz, String name, Object... misc) {
69
 *         Object result = null;
70
 *
71
 *         if (String.class.equals(clazz) && "KnownHostsFile".equals(name)) {
72
 *           result = System.getProperty("user.home") + "/.ssh/known_hosts";
73
 *         } else if (char[].class.equals(clazz) && AuthDataProvider.PASSWORD.equals(name)) {
74
 *           result = new char[]{'t', 'e', 's', 't', 'e', 'r'};
75
 *         }
76
 *
77
 *         return clazz.cast(result);
78
 *       }
79
 *     });
80
 *
81
 * </pre> </p>
82
 *
83
 * @author akrasny
84
 */
85
public interface AuthDataProvider {
86
87
    /**
88
     * Common identifier used for requesting a username.
89
     */
90
    public static final String USERNAME = "username"; // NOI18N
91
    /**
92
     * Common identifier used for requesting a user password.
93
     */
94
    public static final String PASSWORD = "password"; // NOI18N
95
    /**
96
     * Common identifier used for requesting a host name.
97
     */
98
    public static final String HOST = "host"; // NOI18N
99
    /**
100
     * Common identifier used for requesting a port number.
101
     */
102
    public static final String PORT = "port"; // NOI18N
103
    /**
104
     * Common identifier used for requesting a User Interaction facility.
105
     */
106
    public static final String USER_INTERACTION = "userinteraction"; // NOI18N
107
108
    /**
109
     * Returns a requested property of a specified class or {@code null} if no
110
     * property available and could not be retrieved.
111
     *
112
     * <p>It is guaranteed that this method is called from outside the EDT.<br/>
113
     * Implementor could initiate UI interaction with a user to get needed
114
     * input.</p>
115
     *
116
     * @param uri the URI of the connection destination.
117
     * @param clazz the expected class of the property.
118
     * @param name the name of the requested property.
119
     * @param misc any additional data that {@link Connector} may decide to
120
     * provide to the SPI implementor to make it easier/possible to provide
121
     * requested into.
122
     * @return a requested property of the requested type or {@code null}, if
123
     * property is not available.
124
     */
125
    public <T extends Object> T getProperty(URI uri, Class<T> clazz, String name, Object... misc);
126
}
(-)a/cnd.execution/src/org/netbeans/modules/cnd/execution/spi/ConnectionImplementation.java (+97 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2012 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 2012 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.cnd.execution.spi;
43
44
import java.net.URI;
45
import org.netbeans.modules.cnd.execution.api.NativeExecutionException;
46
import org.netbeans.modules.cnd.execution.spi.support.ConnectionInfoProvider;
47
import org.netbeans.modules.cnd.execution.spi.support.SignalSupportProvider;
48
import org.openide.util.Lookup;
49
50
/**
51
 * Interface to be implemented by SPI providers.
52
 *
53
 * @author akrasny
54
 */
55
public interface ConnectionImplementation {
56
57
    /**
58
     * Creates a new {@link NativeProcessCreator} instance.
59
     *
60
     * @return a new not configured {@link NativeProcessCreator}
61
     * @throws NativeExecutionException if some problem occurs
62
     */
63
    public NativeProcessCreator newProcessBuilderImpl() throws NativeExecutionException;
64
65
    /**
66
     * Returns a {@link Lookup} associated with the connection.
67
     *
68
     * <p> For now this lookup is not exposed to the API users. It is used by
69
     * the infrastructure to get implementation of SPI services providers for
70
     * the connection. </p>
71
     *
72
     * @return the {@link Lookup} associated with this connection.
73
     *
74
     * @see ConnectionInfoProvider
75
     * @see SignalSupportProvider
76
     */
77
    public Lookup getLookup();
78
79
    /**
80
     * A request to close the connection.
81
     */
82
    public void disconnect();
83
84
    /**
85
     * Returns an actual URI this connection is associated with.
86
     *
87
     * @return an URI this connection is associated with.
88
     */
89
    public URI getURI();
90
91
    /**
92
     * Tests if the connection is alive.
93
     *
94
     * @return true if connection is established, false otherwise.
95
     */
96
    public boolean isConnected();
97
}
(-)a/cnd.execution/src/org/netbeans/modules/cnd/execution/spi/ConnectorImplementation.java (+93 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2012 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 2012 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.cnd.execution.spi;
43
44
import java.io.IOException;
45
import java.net.URI;
46
import org.netbeans.modules.cnd.execution.api.Connection;
47
import org.netbeans.modules.cnd.execution.api.ConnectionManager;
48
import org.netbeans.modules.cnd.execution.api.NativeExecutionException;
49
50
/**
51
 * SPI for providing a way of {@link Connection} establishment.
52
 *
53
 * <p> SPI implementation must be registers in the global lookup within a
54
 * {@code "ConnectionService/<scheme>"} path.</p>
55
 *
56
 * <p> Once the {@link ConnectionManager} is asked to establish a new connection
57
 * with the destination identified by an URI, it extracts a <b>scheme</b> part
58
 * of the URI and looks for an implementor of this SPI in the corresponding
59
 * lookup path to pass control over to it.</p>
60
 *
61
 * @author akrasny
62
 */
63
public interface ConnectorImplementation {
64
65
    /**
66
     * A request to establish a new connection.
67
     *
68
     * <p> It is guaranteed that: <ul> <li>method is called from outside the
69
     * EDT;</li> <li>method is called non concurrently;</li> </ul></p>
70
     *
71
     * <p> Implementation should return a new instance on each subsequent
72
     * call.</p>
73
     *
74
     * <p>It is not required that ConnectorImplementation uses the originally passed URI
75
     * for establishing a connection. ConnectorImplementation may choose to re-direct a
76
     * request to a different connector with a different URI.</p>
77
     *
78
     * <p>Normally ConnectorImplementation should not directly interact with a user.
79
     * ConnectorImplementation just asks authDataProvider to provide all needed
80
     * information.</p>
81
     *
82
     *
83
     * @param uri an URI of the requested destination.
84
     * @param authDataProvider the provider of information needed for connection
85
     * establishment.
86
     * @return a new instance of {@link ConnectionImplementation} that represents newly
87
     * established connection.
88
     * @throws NativeExecutionException is thrown if connection cannot be
89
     * established for some reason.
90
     * @throws InterruptedException if calling thread was interrupted.
91
     */
92
    public ConnectionImplementation connectTo(final URI uri, final AuthDataProvider authDataProvider) throws InterruptedException, IOException;
93
}
(-)a/cnd.execution/src/org/netbeans/modules/cnd/execution/spi/NativeProcessCreator.java (+69 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2012 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 2012 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.cnd.execution.spi;
43
44
import org.netbeans.modules.cnd.execution.api.NativeExecutionException;
45
import org.netbeans.modules.cnd.execution.api.NativeProcessBuilder;
46
import org.openide.util.Lookup;
47
48
/**
49
 * An SPI interface for providing process creator implementation.
50
 *
51
 * @author akrasny
52
 */
53
public interface NativeProcessCreator extends Lookup.Provider {
54
55
    /**
56
     * Takes parameters configured by a {@link NativeProcessBuilder} and starts
57
     * a new process in accordance to that parameters.
58
     *
59
     * @param params parameters configured with a {@link NativeProcessBuilder}.
60
     * Never {@code null}.
61
     *
62
     * @return a new started process implementation.
63
     *
64
     * @throws NativeExecutionException is thrown if process cannot be started.
65
     */
66
    public NativeProcessImplementation createAndStart(
67
            final NativeProcessParams params) throws NativeExecutionException;
68
69
}
(-)a/cnd.execution/src/org/netbeans/modules/cnd/execution/spi/NativeProcessImplementation.java (+114 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2012 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 2012 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.cnd.execution.spi;
43
44
import java.io.InputStream;
45
import java.io.OutputStream;
46
47
/**
48
 *
49
 * @author akrasny
50
 */
51
public interface NativeProcessImplementation {
52
53
    /**
54
     * Returns a PID of the process.
55
     *
56
     * @return the PID of the process or -1 if real PID cannot be provided.
57
     */
58
    public int getPID();
59
60
    /**
61
     * Returns the output stream of the process.
62
     *
63
     * <p>Output to the stream should be piped into the input stream of the
64
     * process.</p>
65
     *
66
     * @return the output stream connected to the input of the process.
67
     */
68
    public OutputStream getOutputStream();
69
70
    /**
71
     * Returns the input stream of the process.
72
     *
73
     * <p>The stream should obtain data piped from the output stream of the
74
     * process. </p>
75
     *
76
     * @return the input stream connected to the output stream of the process.
77
     */
78
    public InputStream getInputStream();
79
80
    /**
81
     * Returns the error stream of the process.
82
     *
83
     * <p>The stream should obtain data piped from the error output stream of
84
     * the process.</p>
85
     *
86
     * @return the input stream connected to the error stream of the process.
87
     */
88
    public InputStream getErrorStream();
89
90
    /**
91
     * Implementation should cause the current thread to wait, if necessary,
92
     * until the process has terminated.
93
     *
94
     * <p>This method should return immediately if the process has already
95
     * terminated. If the process has not yet terminated, the calling thread
96
     * should be blocked until the process exits. </p>
97
     *
98
     * @return the exit value of the process. By convention, 0 indicates normal
99
     * termination.
100
     * @throws InterruptedException if the current thread is interrupted by
101
     * another thread while it is waiting, then the wait is ended and an
102
     * InterruptedException is thrown.
103
     */
104
    public int waitResult() throws InterruptedException;
105
106
    /**
107
     * Implementation-specific termination of the underlying system process.
108
     *
109
     * <p>It is guaranteed that this method is called only once. Implementation
110
     * should not (but may) wait for the actual termination before returning
111
     * from the call.</p>
112
     */
113
    public void destroy();
114
}
(-)a/cnd.execution/src/org/netbeans/modules/cnd/execution/spi/NativeProcessParams.java (+197 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2012 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 2012 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.cnd.execution.spi;
43
44
import java.util.Collections;
45
import java.util.List;
46
import java.util.Map;
47
import org.netbeans.modules.cnd.execution.access.NativeProcessParamsFactory;
48
import org.netbeans.modules.cnd.execution.api.Connection;
49
import org.netbeans.modules.cnd.execution.api.NativeProcessBuilder;
50
import org.netbeans.modules.cnd.execution.common.NativeProcess;
51
import org.openide.util.Lookup;
52
53
/**
54
 * Parameters constructed by a {@link NativeProcessBuilder} to be used for
55
 * {@link NativeProcess} creation.
56
 *
57
 * <p> This is an immutable object.</p>
58
 *
59
 * @author akrasny
60
 */
61
public final class NativeProcessParams implements Lookup.Provider {
62
63
    private final Connection connection;
64
    private final Map<String, String> connectionInfo;
65
    private final Map<String, String> environment;
66
    private final List<String> command;
67
    private final boolean redirectError;
68
    private final String shellScript;
69
    private final String shell;
70
    private final String wdir;
71
    private final Lookup lookup;
72
73
    private NativeProcessParams(Connection connection, Map<String, String> connectionInfo,
74
            Map<String, String> environmentMap,
75
            List<String> command, String shell, String shellScript,
76
            boolean redirectError, String wdir, Lookup lookup) {
77
        this.connection = connection;
78
        this.connectionInfo = connectionInfo;
79
        this.environment = environmentMap;
80
        this.command = command;
81
        this.shell = shell;
82
        this.shellScript = shellScript;
83
        this.redirectError = redirectError;
84
        this.wdir = wdir;
85
        this.lookup = lookup;
86
    }
87
88
    /**
89
     * Returns an immutable list of a command to be started and it's arguments.
90
     *
91
     * <p>There are two mutually exclusive attributes - a shell script and a
92
     * list of a command with it's arguments. Only one of these attributes could
93
     * be set.</p>
94
     *
95
     * @return an immutable list of a command and it's arguments.
96
     */
97
    public List<String> getCommand() {
98
        return Collections.unmodifiableList(command);
99
    }
100
101
    /**
102
     * Returns a shell script to be started.
103
     *
104
     * <p>There are two mutually exclusive attributes - a shell script and a
105
     * list of a command with it's arguments. Only one of these attributes could
106
     * be set.</p>
107
     *
108
     * @return a shell script to start.
109
     */
110
    public String getShellScript() {
111
        return shellScript;
112
    }
113
114
    /**
115
     * A shell to be used to start a specified shell script (if any).
116
     *
117
     * @see #getShellScript()
118
     * @return a path to the shell to be used to start a specified shell script.
119
     */
120
    public String getShell() {
121
        return shell;
122
    }
123
124
    /**
125
     * Returns an immutable map of all attributes associated with the current
126
     * {@link Connection}.
127
     *
128
     * @return an immutable map of all attributes associated with the current
129
     * {@link Connection}.
130
     */
131
    public Map<String, String> getConnectionInfo() {
132
        return Collections.unmodifiableMap(connectionInfo);
133
    }
134
135
    /**
136
     * A working directory process should be started in.
137
     *
138
     * @return the working directory where process should be started.
139
     */
140
    public String getWorkingDirectory() {
141
        return wdir;
142
    }
143
144
    /**
145
     * Tells whether standard error and standard output of a process should be
146
     * merged together.
147
     *
148
     * @return {@code true} if output and error streams should be merged.
149
     */
150
    public boolean isRedirectError() {
151
        return redirectError;
152
    }
153
154
    /**
155
     * Returns configured immutable map of environment variables to be set
156
     * before process creation.
157
     *
158
     * @return an immutable map of environment variables.
159
     */
160
    public Map<String, String> getEnvironment() {
161
        return Collections.unmodifiableMap(environment);
162
    }
163
164
    /**
165
     * Returns a {@link Connection} this process should be started in.
166
     *
167
     * @return the {@link Connection} this process should be started in.
168
     */
169
    public Connection getConnection() {
170
        return connection;
171
    }
172
173
    @Override
174
    public Lookup getLookup() {
175
        return lookup;
176
    }
177
178
179
    //<editor-fold defaultstate="collapsed" desc="Accessor">
180
    static {
181
        NativeProcessParamsFactory.setDefault(new NativeProcessParamsFactoryImpl());
182
    }
183
184
    private static class NativeProcessParamsFactoryImpl extends NativeProcessParamsFactory {
185
186
        @Override
187
        public NativeProcessParams newNativeProcessParams(Connection connection,
188
                Map<String, String> connectionInfo, Map<String, String> env,
189
                List<String> command, String shell, String shellScript,
190
                boolean redirectError, String wdir, Lookup lookup) {
191
            NativeProcessParams params = new NativeProcessParams(connection, connectionInfo, env,
192
                    command, shell, shellScript, redirectError, wdir, lookup);
193
            return params;
194
        }
195
    }
196
    //</editor-fold>
197
}
(-)a/cnd.execution/src/org/netbeans/modules/cnd/execution/spi/URIIdentifier.java (+73 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2012 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 2012 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.cnd.execution.spi;
43
44
import java.net.URI;
45
import org.netbeans.modules.cnd.execution.api.ConnectionManager;
46
47
/**
48
 * SPI provider may register an identifier for URIs of a certain kind (certain
49
 * scheme).
50
 *
51
 * <p>Should be registered in the global Lookup within a
52
 * {@code ConnectionService/<scheme>} path.</p>
53
 *
54
 * <p>{@link ConnectionManager} uses registered URIIdentifiers to compare URIs
55
 * equality. As an example URIs {@code ssh://user:password@host} and {@code ssh://user@host}
56
 * could denote the same connection end point.</p>
57
 *
58
 * <p>If no Identifier registered for a particular scheme, URI's equals() method
59
 * is used.</p>
60
 *
61
 * @author akrasny
62
 */
63
public interface URIIdentifier {
64
65
    /**
66
     * Tests whether these URIs denote the same connection.
67
     *
68
     * @param uri1 the first URI to compare
69
     * @param uri2 the second URI to compare
70
     * @return true if these URIs are the same from SPI provider point of view.
71
     */
72
    public boolean areIdentical(final URI uri1, final URI uri2);
73
}
(-)a/cnd.execution/src/org/netbeans/modules/cnd/execution/spi/UserInteraction.java (+55 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2012 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 2012 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.cnd.execution.spi;
43
44
import java.net.URI;
45
46
/**
47
 *
48
 * @author Andrew
49
 */
50
public interface UserInteraction {
51
52
    public boolean promptYesNo(URI uri, String message);
53
54
    public void notify(URI uri, String message);
55
}
(-)a/cnd.execution/src/org/netbeans/modules/cnd/execution/spi/support/ConnectionInfo.java (+84 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2012 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 2012 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.cnd.execution.spi.support;
43
44
import java.util.Map;
45
import org.netbeans.modules.cnd.execution.api.Connection;
46
import org.netbeans.modules.cnd.execution.api.EnvironmentMap;
47
import org.netbeans.modules.cnd.execution.spi.ConnectionImplementation;
48
import org.netbeans.modules.cnd.execution.util.HostInfo;
49
import org.openide.util.Lookup;
50
51
/**
52
 * Connection info is just a map of String-String properties and an initial
53
 * {@link EnvironmentMap} of the {@link Connection}.
54
 *
55
 * <p>{@link ConnectionImplementation} SPI implementors use this interface to provide a
56
 * map of connection-specific properties. For this implementations of {@link ConnectionInfoProvider}
57
 * should be put into connection's {@link Lookup} (See {@link ConnectionImplementation}).
58
 * Information from all SPI implementors is collected and merged altogether by
59
 * the execution infrastructure before making a final association with the {@link Connection}.</p>
60
 *
61
 * <p> Note: {@link HostInfo} is constructed from the known subset of these
62
 * properties. SPI implementor should make sure that expected properties are
63
 * provided if they want HostInfo service to provide a meaningful
64
 * information.</p>
65
 *
66
 * @see HostInfo
67
 */
68
public interface ConnectionInfo {
69
70
    /**
71
     * Returns an EnvironmentMap filled with variables discovered by the
72
     * implementation.
73
     *
74
     * @return the populated EnvironmentMap.
75
     */
76
    public Map<String, String> getEnvironmentMap();
77
78
    /**
79
     * Returns a map of attributes to be associated with the connection.
80
     *
81
     * @return the map of connection attributes.
82
     */
83
    public Map<String, String> getProperties();
84
}
(-)a/cnd.execution/src/org/netbeans/modules/cnd/execution/spi/support/ConnectionInfoProvider.java (+94 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2012 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 2012 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.cnd.execution.spi.support;
43
44
import org.netbeans.modules.cnd.execution.api.Connection;
45
import org.netbeans.modules.cnd.execution.api.NativeExecutionException;
46
import org.netbeans.modules.cnd.execution.util.HostInfo;
47
48
/**
49
 *
50
 * Provides a discovered list of connection-specific properties.
51
 *
52
 * <p>Among other usages, this information is used to construct a {@link HostInfo}
53
 * object to provide an easy access to the most common host-specific
54
 * attributes.</p>
55
 *
56
 * <p> Implementors of {@link ConnectionInfoProvider} could provide following
57
 * properties that are used by the {@link HostInfo} class:</p>
58
 *
59
 *
60
 * <pre>
61
 * ------------+------------------------------------------------------
62
 *    Name     |   Possible values (otherwise will be set to UNKNOWN)
63
 * ------------+------------------------------------------------------
64
 * CPUFAMILY   |  SPARC, X86
65
 * BITNESS     |  32, 64
66
 * OSFAMILY    |  SOLARIS, LINUX, WINDOWS, MACOSX
67
 * OSBUILD     |  &lt;any string&gt;
68
 * OSNAME      |  &lt;any string&gt;
69
 * CPUNUM      |  &lt;any positive integer&gt;
70
 * </pre>
71
 *
72
 * @author akrasny
73
 */
74
public interface ConnectionInfoProvider {
75
76
    /**
77
     * A method to be implemented by an SPI provider.
78
     *
79
     * <p> It is guaranteed that this method is invoked outside the EDT and not
80
     * concurrently for the same connection.</p>
81
     *
82
     * <p> Implementor should not do any caching of the collected data. This
83
     * method is called at least once during a connection establishment process,
84
     * but could be called again if implicit refresh is requested.</p>
85
     *
86
     * <p>Note: gathering {@link ConnectionInfo} from the SPI implementors is a
87
     * part of connection process and {@link Connection} is considered to be
88
     * established (and publicly available) when only after all providers are
89
     * done with this task.</p>
90
     *
91
     * @return a {@link ConnectionInfo} discovered by an implementor.
92
     */
93
    public ConnectionInfo getConnectionInfo(Connection connection) throws NativeExecutionException;
94
}
(-)a/cnd.execution/src/org/netbeans/modules/cnd/execution/spi/support/SignalSupport.java (+114 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2012 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 2012 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.cnd.execution.spi.support;
43
44
import org.netbeans.modules.cnd.execution.common.NativeProcess;
45
import org.netbeans.modules.cnd.execution.spi.ConnectionImplementation;
46
import org.netbeans.modules.cnd.execution.common.SignalUtils.Signal;
47
import org.openide.util.Lookup;
48
49
/**
50
 *
51
 * An extension point for providing a signals support.
52
 *
53
 * <p>Implementors of the {@link ConnectionImplementation} SPI could register their
54
 * implementation of the
55
 * {@link SignalSupportProvider} in the {@link Lookup} associated with the
56
 * connection. </p>
57
 *
58
 * <p> By convention if implementation cannot perform a task,
59
 * {@link UnsupportedOperationException} is thrown.</p>
60
 *
61
 * @author akrasny
62
 */
63
public interface SignalSupport {
64
65
    /**
66
     * A request to send a signal to a specific process.
67
     *
68
     * @param process {@link NativeProcess} to signal.
69
     * @param signal the {@link Signal} to be send.
70
     */
71
    public void signal(NativeProcess process, Signal signal);
72
73
    /**
74
     * A request to send a signal to a group the process belongs to.
75
     *
76
     * @param process {@link NativeProcess} which group should receive a signal.
77
     * @param signal the {@link Signal} to be send.
78
     */
79
    public void signalGrp(NativeProcess process, Signal signal);
80
81
    /**
82
     * A request to send a signal with an attached value to a specific process.
83
     *
84
     * @param process {@link NativeProcess} to signal.
85
     * @param signal the {@link Signal} to be send.
86
     * @param value the value to send together with the signal.
87
     */
88
    public void sigqueue(NativeProcess process, Signal signal, int value);
89
90
    /**
91
     * A request to send a signal to a specific process.
92
     *
93
     * @param pid a PID of a process to signal.
94
     * @param signal the {@link Signal} to be send.
95
     */
96
    public void signal(int pid, Signal signal);
97
98
    /**
99
     * A request to send a signal to a group the process belongs to.
100
     *
101
     * @param pid the PID of a process which group should receive a signal.
102
     * @param signal the {@link Signal} to be send.
103
     */
104
    public void signalGrp(int pid, Signal signal);
105
106
    /**
107
     * A request to send a signal with an attached value to a specific process.
108
     *
109
     * @param pid the PID of a process to signal.
110
     * @param signal the {@link Signal} to be send.
111
     * @param value the value to send together with the signal.
112
     */
113
    public void sigqueue(int pid, Signal signal, int value);
114
}
(-)a/cnd.execution/src/org/netbeans/modules/cnd/execution/spi/support/SignalSupportProvider.java (+67 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2012 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 2012 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.cnd.execution.spi.support;
43
44
import org.netbeans.modules.cnd.execution.api.Connection;
45
import org.netbeans.modules.cnd.execution.spi.ConnectionImplementation;
46
import org.openide.util.Lookup;
47
48
/**
49
 * Provider of {@link SignalSupport} for a specific {@link Connection}.
50
 *
51
 * <p>Implementors of the {@link ConnectionImplementation} SPI could register their
52
 * implementation of the {@link SignalSupportProvider} in the {@link Lookup}
53
 * associated with the connection.</p>
54
 *
55
 * @author akrasny
56
 */
57
public interface SignalSupportProvider {
58
59
    /**
60
     * Returns a {@link SignalSupport} implementation for a specific {@link Connection}.
61
     *
62
     * @param connection connection to get {@link SignalSupport} for.
63
     * @return the {@link SignalSupport} implementation for the specified {@link Connection}.
64
     *
65
     */
66
    public SignalSupport getSignalSupport(Connection connection);
67
}
(-)a/cnd.execution/src/org/netbeans/modules/cnd/execution/util/Computable.java (+69 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2010 Oracle and/or its affiliates. All rights reserved.
5
 *
6
 * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
7
 * Other names may be trademarks of their respective owners.
8
 *
9
 * The contents of this file are subject to the terms of either the GNU
10
 * General Public License Version 2 only ("GPL") or the Common
11
 * Development and Distribution License("CDDL") (collectively, the
12
 * "License"). You may not use this file except in compliance with the
13
 * License. You can obtain a copy of the License at
14
 * http://www.netbeans.org/cddl-gplv2.html
15
 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
16
 * specific language governing permissions and limitations under the
17
 * License.  When distributing the software, include this License Header
18
 * Notice in each file and include the License file at
19
 * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
20
 * particular file as subject to the "Classpath" exception as provided
21
 * by Oracle in the GPL Version 2 section of the License file that
22
 * accompanied this code. If applicable, add the following below the
23
 * License Header, with the fields enclosed by brackets [] replaced by
24
 * your own identifying information:
25
 * "Portions Copyrighted [year] [name of copyright owner]"
26
 *
27
 * If you wish your version of this file to be governed by only the CDDL
28
 * or only the GPL Version 2, indicate your decision by adding
29
 * "[Contributor] elects to include this software in this distribution
30
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
31
 * single choice of license, a recipient has the option to distribute
32
 * your version of this file under either the CDDL, the GPL Version 2 or
33
 * to extend the choice of license to its licensees as provided above.
34
 * However, if you add GPL Version 2 code and therefore, elected the GPL
35
 * Version 2 license, then the option applies only if the new code is
36
 * made subject to such option by the copyright holder.
37
 *
38
 * Contributor(s):
39
 *
40
 * Portions Copyrighted 2009 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.cnd.execution.util;
43
44
import org.netbeans.modules.cnd.execution.api.NativeExecutionException;
45
46
/**
47
 * An interface for calculating a result based on a single parameter.
48
 *
49
 * This interface is most useful in conjuction with the {@link TasksCachedProcessor}
50
 * class.
51
 *
52
 * @param <P> the parameter type.
53
 * @param <R> the result type.
54
 *
55
 * @see TasksCachedProcessor
56
 * @author akrasny
57
 */
58
public interface Computable<P, R> {
59
60
    /**
61
     * A method that does an actual computation.
62
     *
63
     * @param taskArguments the input parameter.
64
     * @return a result of a computation.
65
     * @throws NativeExecutionException in case of any problem occur during the
66
     * computation.
67
     */
68
    R compute(P taskArguments) throws NativeExecutionException;
69
}
(-)a/cnd.execution/src/org/netbeans/modules/cnd/execution/util/HostInfo.java (+413 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2012 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 2012 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.cnd.execution.util;
43
44
import java.net.URI;
45
import java.text.ParseException;
46
import java.util.HashMap;
47
import java.util.Map;
48
import java.util.logging.Level;
49
import org.netbeans.modules.cnd.execution.ExecutionLogger;
50
import org.netbeans.modules.cnd.execution.access.EnvironmentMapAccessor;
51
import org.netbeans.modules.cnd.execution.api.Connection;
52
import org.netbeans.modules.cnd.execution.api.EnvironmentMap;
53
import org.netbeans.modules.cnd.execution.common.ConnectionsInfo;
54
import org.netbeans.modules.cnd.execution.spi.support.ConnectionInfo;
55
import org.netbeans.modules.cnd.execution.spi.support.ConnectionInfoProvider;
56
import org.openide.util.Exceptions;
57
58
/**
59
 * Utility class to extract commonly used information about a host from data
60
 * provider by the {@link ConnectionInfoProvider} SPI implementors.
61
 *
62
 * <p>This class gives an easy access to the most common host-specific
63
 * attributes.</p>
64
 *
65
 * <p>Note: It is supposed that in most cases there is some host behind a
66
 * {@link Connection}. Theoretically there could be connections where host info
67
 * (entirely or partially) is not applicable. For such connections HostInfo
68
 * attributes will be set to {@code "UNKNOWN"} value.</p>
69
 *
70
 * @see ConnectionInfoProvider
71
 *
72
 * @author akrasny
73
 */
74
public final class HostInfo {
75
76
    public static final String UNKNOWN = "UNKNOWN"; // NOI18N
77
    private final URI connectionURI;
78
79
    private HostInfo(final URI connectionURI) {
80
        this.connectionURI = connectionURI;
81
    }
82
83
    /**
84
     * Getter of HostInfo object for a specified Connection.
85
     *
86
     * @param connection connection to get info for.
87
     * @return a HostInfo to the connection.
88
     */
89
    public static HostInfo getFor(final Connection connection) {
90
        return new HostInfo(connection.getURI());
91
    }
92
93
    public static EnvironmentMap getEnvironmentMap(Connection connection) {
94
        ConnectionInfo cinfo = ConnectionsInfo.getConnectionInfo(connection.getURI());
95
        if (cinfo == null) {
96
            return null;
97
        }
98
99
        HostInfo hinfo = getFor(connection);
100
        EnvironmentMap base;
101
        EnvironmentMapAccessor access = EnvironmentMapAccessor.getDefault();
102
        switch (hinfo.getOS().family) {
103
            case MACOSX:
104
                base = access.createCasePreserving(':');
105
                break;
106
            case WINDOWS:
107
                base = access.createCasePreserving(';');
108
                break;
109
            default:
110
                base = access.createCaseSensitive(':');
111
                break;
112
        }
113
        base.putAll(cinfo.getEnvironmentMap().entrySet());
114
        return base;
115
    }
116
117
    public String expandMacros(final String string) {
118
        try {
119
            return MacroExpander.expandMacros(string, getMacros());
120
        } catch (ParseException ex) {
121
            Exceptions.printStackTrace(ex);
122
        }
123
        return string;
124
    }
125
126
    /**
127
     * Returns an OS object
128
     *
129
     * @return the OS object
130
     */
131
    public OS getOS() {
132
        return new OS(
133
                get("OSFAMILY", OSFamily.UNKNOWN), // NOI18N
134
                get("OSNAME", UNKNOWN), // NOI18N
135
                get("OSVERSION", UNKNOWN), // NOI18N
136
                getBitness("BITNESS", Bitness._32)); // NOI18N
137
    }
138
139
    /**
140
     * Returns a number of CPUs on the host.
141
     *
142
     * @return the number of CPUs on the host.
143
     */
144
    public int getCpuNum() {
145
        return get("CPUNUM", 1); // NOI18N
146
    }
147
148
    /**
149
     * Returns CpuFamily information.
150
     *
151
     * @return CpuFamily information.
152
     */
153
    public CpuFamily getCpuFamily() {
154
        return get("CPUFAMILY", CpuFamily.UNKNOWN); // NOI18N
155
    }
156
157
    /**
158
     * Test weather this is a Windows system.
159
     *
160
     * @return true if and only if getOS().getFamily() is OSFamily.WINDOWS
161
     */
162
    public boolean isWindows() {
163
        return OSFamily.WINDOWS.equals(getOS().family);
164
    }
165
166
    /**
167
     * Tests weather this is a Unix-like system.
168
     *
169
     * @return true if OSFamily is one of LINUX, MACOSX or SOLARIS
170
     */
171
    public boolean isUnix() {
172
        return getOS().family.isUnix();
173
    }
174
175
    /**
176
     * Returns the login shell (as specified in /etc/passwd) of the connected
177
     * user.
178
     *
179
     * @return the login shell
180
     */
181
    public String getShell() {
182
        return get("SHELL", "/bin/sh"); // NOI18N
183
    }
184
185
    public String getTempDir() {
186
        return get("TMPDIRBASE", "/var/tmp"); // NOI18N;
187
    }
188
189
    /**
190
     * List of known CPU families property values.
191
     */
192
    public enum CpuFamily {
193
194
        SPARC, X86, UNKNOWN;
195
    }
196
197
    /**
198
     * List of known OS families property values.
199
     */
200
    public enum OSFamily {
201
202
        SOLARIS, LINUX, WINDOWS, MACOSX, UNKNOWN;
203
204
        public boolean isUnix() {
205
            switch (this) {
206
                case LINUX:
207
                case MACOSX:
208
                case SOLARIS:
209
                    return true;
210
                case WINDOWS:
211
                    return false;
212
                case UNKNOWN:
213
                    return false;
214
                default:
215
                    throw new IllegalStateException("Unexpected OSFamily: " + this); //NOI18N
216
            }
217
        }
218
219
        /**
220
         * Returns CamelCase name of the family.
221
         *
222
         * Like: SunOS; Linux; Windows; MacOSX.
223
         *
224
         * @return CamelCase name
225
         */
226
        public String cname() {
227
            switch (this) {
228
                case LINUX:
229
                    return "Linux"; // NOI18N
230
                case MACOSX:
231
                    return "MacOSX"; // NOI18N
232
                case SOLARIS:
233
                    return "SunOS"; // NOI18N
234
                case WINDOWS:
235
                    return "Windows"; // NOI18N
236
                case UNKNOWN:
237
                    return "UNKNOWN"; // NOI18N
238
                default:
239
                    throw new IllegalStateException("Unexpected OSFamily: " + this); //NOI18N
240
            }
241
        }
242
    }
243
244
    /**
245
     * Bitness of the OS kernel - either 32 or 64 bits.
246
     */
247
    public enum Bitness {
248
249
        _32,
250
        _64;
251
252
        static Bitness valueOf(int bitness) {
253
            return bitness == 64 ? _64 : _32;
254
        }
255
256
        @Override
257
        public String toString() {
258
            return (this == _32) ? "32" : "64"; // NOI18N
259
        }
260
    }
261
262
    /**
263
     * Information about an operating system.
264
     */
265
    public static final class OS {
266
267
        private final OSFamily family;
268
        private final String name;
269
        private final String version;
270
        private final Bitness bitness;
271
272
        /**
273
         * Constructs new OS object with provided attributes.
274
         *
275
         * @param family OS family
276
         * @param name OS name
277
         * @param version OS version string
278
         * @param bitness OS operating bitness mode.
279
         */
280
        private OS(OSFamily family, String name, String version, Bitness bitness) {
281
            this.family = family;
282
            this.name = name;
283
            this.version = version;
284
            this.bitness = bitness;
285
        }
286
287
        /**
288
         * Returns a bitness of the OS kernel.
289
         *
290
         * @return the bitness of the OS kernel
291
         */
292
        public Bitness getBitness() {
293
            return bitness;
294
        }
295
296
        /**
297
         * Returns an OS family attribute.
298
         *
299
         * @return the OS family attribute.
300
         */
301
        public OSFamily getFamily() {
302
            return family;
303
        }
304
305
        /**
306
         * Returns a name of the OS
307
         *
308
         * @return the name of OS.
309
         */
310
        public String getName() {
311
            return name;
312
        }
313
314
        /**
315
         * Returns a version string of the OS.
316
         *
317
         * @return the version string of the OS.
318
         */
319
        public String getVersion() {
320
            return version;
321
        }
322
    }
323
324
    //<editor-fold defaultstate="collapsed" desc="Private getters">
325
    private Map<String, String> getMacros() {
326
        Map<String, String> map = new HashMap<String, String>();
327
        String soext;
328
        final OS os = getOS();
329
        switch (os.family) {
330
            case WINDOWS:
331
                soext = "dll"; // NOI18N
332
                break;
333
            case MACOSX:
334
                soext = "dylib"; // NOI18N
335
                break;
336
            case SOLARIS:
337
            case LINUX:
338
            case UNKNOWN:
339
                soext = "so"; // NOI18N
340
                break;
341
            default:
342
                throw new IllegalStateException("Unexpected OSFamily: " + os.family); //NOI18N
343
        }
344
345
        map.put("soext", soext); // NOI18N
346
        map.put("osname", os.family.cname()); // NOI18N
347
        map.put("isa", os.getBitness().toString()); // NOI18N
348
        map.put("_isa", os.getBitness() == HostInfo.Bitness._64 ? "_64" : ""); // NOI18N
349
        map.put("platform", getCpuFamily().name().toLowerCase()); // NOI18N
350
351
        return map;
352
    }
353
354
    private String get(String key) {
355
        ConnectionInfo info = ConnectionsInfo.getConnectionInfo(connectionURI);
356
        if (info != null) {
357
            return info.getProperties().get(key);
358
        }
359
        return null;
360
    }
361
362
    @SuppressWarnings("unchecked")
363
    private <T extends Enum<?>> T get(String name, T defaultValue) {
364
        String val = get(name);
365
        if (val != null) {
366
            try {
367
                T result = (T) Enum.valueOf(defaultValue.getClass(), val.toUpperCase());
368
                return result;
369
            } catch (Throwable ex) {
370
                ExecutionLogger.getInstance().log(Level.WARNING,
371
                        "HostInfo: Invalid value for {0} - {1}", // NOI18N
372
                        new Object[]{name, val});
373
            }
374
        }
375
        return defaultValue;
376
    }
377
378
    private Bitness getBitness(String name, Bitness defaultValue) {
379
        String val = get(name);
380
        if (val != null) {
381
            if ("64".equals(val)) { // NOI18N
382
                return Bitness._64;
383
            }
384
            if ("32".equals(val)) { // NOI18N
385
                return Bitness._32;
386
            }
387
            ExecutionLogger.getInstance().log(Level.WARNING,
388
                    "HostInfo: Invalid value for Bitness - {0}", // NOI18N
389
                    val);
390
        }
391
        return defaultValue;
392
    }
393
394
    private String get(String name, String defaultValue) {
395
        String val = get(name);
396
        return val == null ? defaultValue : val;
397
    }
398
399
    private int get(String name, int defaultValue) {
400
        String val = get(name);
401
        if (val != null) {
402
            try {
403
                return Integer.parseInt(val);
404
            } catch (NumberFormatException ex) {
405
                ExecutionLogger.getInstance().log(Level.WARNING,
406
                        "HostInfo: Invalid value for {0} - {1}", // NOI18N
407
                        new Object[]{name, val});
408
            }
409
        }
410
        return defaultValue;
411
    }
412
    //</editor-fold>
413
}
(-)a/cnd.execution/src/org/netbeans/modules/cnd/execution/util/MacroExpander.java (+191 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2012 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 2012 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.cnd.execution.util;
43
44
import java.text.ParseException;
45
import java.util.Map;
46
47
/**
48
 * A simple class that expands all macros in a String using definitions taken
49
 * from a dictionary map.
50
 *
51
 * @author akrasny
52
 */
53
public final class MacroExpander {
54
55
    private static final int[][] ttable = new int[][]{
56
        {0, 0, 0, 1, 0, 0},
57
        {2, 3, 3, 10, 4, 3},
58
        {2, 2, 5, 6, 5, 5},
59
        {7, 7, 8, 8, 8, 9},
60
        {7, 3, 3, 3, 8, 8}
61
    };
62
63
    private MacroExpander() {
64
    }
65
66
    private static int getCharClass(char c) {
67
        if (c == '_' || (c >= 'A' && c <= 'Z') || c >= 'a' && c <= 'z') {
68
            return 0;
69
        }
70
71
        if (c >= '0' && c <= '9') {
72
            return 1;
73
        }
74
75
        if (c == '$') {
76
            return 3;
77
        }
78
79
        if (c == '{') {
80
            return 4;
81
        }
82
83
        if (c == '}') {
84
            return 5;
85
        }
86
87
        return 2;
88
    }
89
90
    private static String valueOf(String macro, Map<String, String> map) {
91
        String result = map.get(macro);
92
        return result == null ? "${" + macro + "}" : result; // NOI18N
93
    }
94
95
    /**
96
     * Parses the given string and replaces all it's macros with values from the
97
     * provided dictionary.
98
     *
99
     * <p> Macros in the form {@code $NAME} and {@code ${NAME}} are
100
     * supported.</p>
101
     *
102
     * <p> Any macro that is not in the dictionary is left in the string (in the
103
     * {@code ${NAME}} form).</p>
104
     *
105
     * <p> Current implementation does a single pass of expansion: <br/>
106
     *
107
     * the result of a string {@code "C=${B}"} expansion with a dictionary
108
     * {@code ["A=VALUE", "B=$A"]} is {@code "C=${A}"}.</p>
109
     *
110
     * @param stringToExpand string with macros to be expanded.
111
     * @param dictionary key-value pairs of macros definition.
112
     * @return a string with all macros substituted with their values taken from
113
     * the dictionary.
114
     * @throws ParseException if string cannot be parsed
115
     */
116
    public static String expandMacros(final String stringToExpand,
117
            final Map<String, String> dictionary) throws ParseException {
118
119
        if (stringToExpand == null || stringToExpand.length() == 0) {
120
            return stringToExpand;
121
        }
122
123
        StringBuilder res = new StringBuilder();
124
        StringBuilder buf = new StringBuilder();
125
126
        int state = 0, pos = 0, mpos = -1;
127
        int length = stringToExpand.length();
128
        char c;
129
130
        while (pos <= length) {
131
            c = pos == length ? 0 : stringToExpand.charAt(pos);
132
133
            switch (ttable[state][getCharClass(c)]) {
134
                case 0:
135
                    if (c != 0) {
136
                        res.append(c);
137
                    }
138
                    break;
139
                case 1:
140
                    mpos = pos;
141
                    buf.setLength(0);
142
                    state = 1;
143
                    break;
144
                case 2:
145
                    buf.append(c);
146
                    state = 2;
147
                    break;
148
                case 3:
149
                    res.append(stringToExpand.subSequence(mpos, pos + (c == 0 ? 0 : 1)));
150
                    buf.setLength(0);
151
                    state = 0;
152
                    break;
153
                case 4:
154
                    state = 4;
155
                    break;
156
                case 5:
157
                    res.append(valueOf(buf.toString().trim(), dictionary));
158
                    pos--;
159
                    buf.setLength(0);
160
                    state = 0;
161
                    break;
162
                case 6:
163
                    res.append(valueOf(buf.toString().trim(), dictionary));
164
                    mpos = pos;
165
                    buf.setLength(0);
166
                    state = 1;
167
                    break;
168
                case 7:
169
                    buf.append(c);
170
                    state = 3;
171
                    break;
172
                case 8:
173
                    throw new ParseException("Bad substitution", pos); // NOI18N
174
                case 9:
175
                    res.append(valueOf(buf.toString().trim(), dictionary));
176
                    buf.setLength(0);
177
                    state = 0;
178
                    break;
179
                case 10:
180
                    res.append(stringToExpand.subSequence(mpos, pos));
181
                    pos--;
182
                    buf.setLength(0);
183
                    state = 0;
184
                    break;
185
            }
186
            pos++;
187
        }
188
189
        return res.toString();
190
    }
191
}
(-)a/cnd.execution/src/org/netbeans/modules/cnd/execution/util/ProcessUtils.java (+124 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2012 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 2012 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.cnd.execution.util;
43
44
import org.netbeans.modules.cnd.execution.common.SignalUtils;
45
import java.util.concurrent.TimeUnit;
46
import org.netbeans.modules.cnd.execution.common.NativeProcess;
47
import org.netbeans.modules.cnd.execution.common.SignalUtils.Signal;
48
import org.openide.util.RequestProcessor;
49
50
/**
51
 * Useful utilities that handle starting of an external process, handling it's
52
 * streams and so on..
53
 *
54
 * All methods are static.
55
 *
56
 * @author akrasny
57
 */
58
public final class ProcessUtils {
59
60
    private static final RequestProcessor RP = new RequestProcessor("ProcessUtils", 50); // NOI18N
61
62
    private ProcessUtils() {
63
    }
64
65
    /**
66
     * Kills the subprocess.
67
     *
68
     * The subprocess represented by this Process object is forcibly terminated.
69
     *
70
     * This method tries to terminate a process in several ways. The first
71
     * attempt is to call it's {@code Process.destroy()} method. On some systems
72
     * this may fail (i.e. if the process is in the syscall). On failure this
73
     * method will try to send SIGTERM to the process's group (on systems that
74
     * support that). The last attempt is to send SIGKILL (in 5 seconds).
75
     *
76
     * This is not a (long) blocking method. Process may still remain alive on
77
     * return.
78
     *
79
     * @param process process to terminate (not necessarily NativeProcess)
80
     */
81
    public static void destroy(final Process process) {
82
        // First attempt is just call destroy() on the process
83
        process.destroy();
84
85
        // In case the process is in a system call (sleep, read, for example)
86
        // this will not have a desired effect - in this case
87
        // will send SIGTERM signal..
88
89
        try {
90
            process.exitValue();
91
            // No exception means successful termination
92
            return;
93
        } catch (IllegalThreadStateException ex) {
94
        }
95
96
        if (!(process instanceof NativeProcess)) {
97
            return;
98
        }
99
100
        final NativeProcess nativeProcess = (NativeProcess) process;
101
        try {
102
            SignalUtils.signalGrp(nativeProcess, Signal.SIGTERM);
103
            RP.schedule(new Runnable() {
104
105
                @Override
106
                public void run() {
107
                    try {
108
                        process.exitValue();
109
                        // No exception means successful termination
110
                        return;
111
                    } catch (IllegalThreadStateException ex) {
112
                    }
113
                    try {
114
                        SignalUtils.signalGrp(nativeProcess, Signal.SIGKILL);
115
                    } catch (UnsupportedOperationException ex) {
116
                        // ignore
117
                    }
118
                }
119
            }, 5, TimeUnit.SECONDS);
120
        } catch (UnsupportedOperationException ex) {
121
            // ignore
122
        }
123
    }
124
}
(-)a/cnd.execution/src/org/netbeans/modules/cnd/execution/util/TasksCachedProcessor.java (+160 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2010 Oracle and/or its affiliates. All rights reserved.
5
 *
6
 * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
7
 * Other names may be trademarks of their respective owners.
8
 *
9
 * The contents of this file are subject to the terms of either the GNU
10
 * General Public License Version 2 only ("GPL") or the Common
11
 * Development and Distribution License("CDDL") (collectively, the
12
 * "License"). You may not use this file except in compliance with the
13
 * License. You can obtain a copy of the License at
14
 * http://www.netbeans.org/cddl-gplv2.html
15
 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
16
 * specific language governing permissions and limitations under the
17
 * License.  When distributing the software, include this License Header
18
 * Notice in each file and include the License file at
19
 * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
20
 * particular file as subject to the "Classpath" exception as provided
21
 * by Oracle in the GPL Version 2 section of the License file that
22
 * accompanied this code. If applicable, add the following below the
23
 * License Header, with the fields enclosed by brackets [] replaced by
24
 * your own identifying information:
25
 * "Portions Copyrighted [year] [name of copyright owner]"
26
 *
27
 * If you wish your version of this file to be governed by only the CDDL
28
 * or only the GPL Version 2, indicate your decision by adding
29
 * "[Contributor] elects to include this software in this distribution
30
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
31
 * single choice of license, a recipient has the option to distribute
32
 * your version of this file under either the CDDL, the GPL Version 2 or
33
 * to extend the choice of license to its licensees as provided above.
34
 * However, if you add GPL Version 2 code and therefore, elected the GPL
35
 * Version 2 license, then the option applies only if the new code is
36
 * made subject to such option by the copyright holder.
37
 *
38
 * Contributor(s):
39
 *
40
 * Portions Copyrighted 2009 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.cnd.execution.util;
43
44
import java.util.concurrent.Callable;
45
import java.util.concurrent.ConcurrentHashMap;
46
import java.util.concurrent.ConcurrentMap;
47
import java.util.concurrent.Future;
48
import java.util.concurrent.FutureTask;
49
import org.netbeans.modules.cnd.execution.api.NativeExecutionException;
50
51
/**
52
 * A thread-safe implementation of {@link Computable} interface with an internal
53
 * results cache.
54
 *
55
 * P - task parameter type; R - result type
56
 *
57
 */
58
public final class TasksCachedProcessor<P, R> implements Computable<P, R> {
59
60
    private final ConcurrentMap<P, Future<R>> cache = new ConcurrentHashMap<P, Future<R>>();
61
    private final Computable<P, R> computable;
62
    private final boolean removeOnCompletion;
63
64
    /**
65
     * Creates a new instance of processor.
66
     *
67
     * @param computable a computable that does actual calculations
68
     * @param removeOnCompletion if true, the result will be removed from the
69
     * cache as soon as it gets available.
70
     */
71
    public TasksCachedProcessor(Computable<P, R> computable, boolean removeOnCompletion) {
72
        this.computable = computable;
73
        this.removeOnCompletion = removeOnCompletion;
74
    }
75
76
    public boolean isResultAvailable(final P arg) {
77
        Future<R> res = cache.get(arg);
78
79
        if (res == null) {
80
            return false;
81
        }
82
83
        return res.isDone() && !res.isCancelled();
84
    }
85
86
    @Override
87
    public R compute(final P arg) throws NativeExecutionException {
88
        Future<R> f = cache.get(arg);
89
90
        if (f == null) {
91
            Callable<R> evaluation = new Callable<R>() {
92
93
                @Override
94
                public R call() throws NativeExecutionException {
95
                    return computable.compute(arg);
96
                }
97
            };
98
99
            FutureTask<R> ft = new FutureTask<R>(evaluation);
100
            f = cache.putIfAbsent(arg, ft);
101
102
            if (f == null) {
103
                f = ft;
104
                ft.run();
105
            }
106
        }
107
108
        try {
109
            return f.get();
110
        } catch (Throwable th) {
111
            cache.remove(arg, f);
112
            if (th instanceof NativeExecutionException) {
113
                throw (NativeExecutionException) th;
114
            }
115
            if (th.getCause() instanceof NativeExecutionException) {
116
                throw (NativeExecutionException) th.getCause();
117
            }
118
            throw new NativeExecutionException("", th);
119
        } finally {
120
            if (removeOnCompletion) {
121
                cache.remove(arg, f);
122
            }
123
        }
124
    }
125
126
    /**
127
     * Force-remove cached result (if any) for the specified parameter.
128
     *
129
     * @param param the parameter to remove result for.
130
     */
131
    public void remove(P param) {
132
        Future<R> f = cache.get(param);
133
134
        if (f != null && !f.isDone()) {
135
            f.cancel(true);
136
        }
137
138
        cache.remove(param);
139
    }
140
141
    /**
142
     * Clear an internal results cache.
143
     */
144
    public void resetCache() {
145
        // Even if some tasks are in progress it's OK just to clear the cache.
146
        // Tasks will not be terminated though...
147
        cache.clear();
148
    }
149
150
    /**
151
     * Non-blocking getter for a future result of already running or done task
152
     * for the specified parameter.
153
     *
154
     * @param param - parameter to get future result for.
155
     * @return A future result of either currently running or already done task.
156
     */
157
    public Future<R> getFutureResult(P param) {
158
        return cache.get(param);
159
    }
160
}
(-)a/cnd.execution/src/org/netbeans/modules/cnd/execution/util/URIMatcher.java (+104 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2012 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 2012 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.cnd.execution.util;
43
44
import java.net.URI;
45
import java.util.concurrent.atomic.AtomicReference;
46
import org.netbeans.modules.cnd.execution.common.ConnectionServiceLookup;
47
import org.netbeans.modules.cnd.execution.spi.URIIdentifier;
48
import org.openide.util.Lookup;
49
50
/**
51
 * An utility class for testing URIs for equivalence.
52
 *
53
 * <p>There is a notion of URIs equivalence. Equivalent URIs could verbally
54
 * differ, but denote the same destination.</p>
55
 *
56
 * @author akrasny
57
 */
58
public final class URIMatcher {
59
60
    private final URI uri;
61
    private final AtomicReference<Lookup> lookupRef = new AtomicReference<Lookup>();
62
63
    /**
64
     * Constructs a new instance of the matcher for the specified URI.
65
     *
66
     * @param uri URI the matcher should be created for.
67
     */
68
    public URIMatcher(URI uri) {
69
        this.uri = uri;
70
    }
71
72
    /**
73
     * Tests weather the provided uri is equivalent to the uri this matcher was
74
     * created for.
75
     *
76
     * @param uri URI to test for equivalence with the uri this matcher was
77
     * created for.
78
     *
79
     * @return {@code true} if URIs are equivalent.
80
     */
81
    public boolean isIdenticalURI(final URI uri) {
82
        if (this.uri.equals(uri)) {
83
            return true;
84
        }
85
86
        Lookup lookup = lookupRef.get();
87
88
        if (lookup == null) {
89
            lookup = ConnectionServiceLookup.getServiceLookup(this.uri);
90
            Lookup old = lookupRef.getAndSet(lookup);
91
            if (old != null) {
92
                lookup = old;
93
            }
94
        }
95
96
        for (URIIdentifier identifiers : lookup.lookupAll(URIIdentifier.class)) {
97
            if (identifiers.areIdentical(this.uri, uri)) {
98
                return true;
99
            }
100
        }
101
102
        return false;
103
    }
104
}
(-)a/cnd.execution/test/unit/data/goldenfiles/org/netbeans/modules/nativeexecution/util/MacroMapTest/testPut.pass (+31 lines)
Line 0 Link Here
1
---- Map Dump ----
2
A = 1
3
C = 2
4
B = 3
5
------------------
6
---- Map Dump ----
7
A = 5
8
c = 2
9
b = 3
10
C = 4
11
------------------
12
---- Map Dump ----
13
A = 1
14
C = 2
15
B = 3
16
------------------
17
---- Map Dump ----
18
A = 5
19
c = 2
20
b = 3
21
C = 4
22
------------------
23
---- Map Dump ----
24
A = 1
25
C = 2
26
B = 3
27
------------------
28
---- Map Dump ----
29
c = 4
30
b = 3
31
------------------
(-)a/cnd.execution/test/unit/src/org/netbeans/modules/cnd/execution/api/ConnectionManagerTest.java (+249 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2012 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 2012 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.cnd.execution.api;
43
44
import org.netbeans.modules.cnd.execution.api.Connection;
45
import org.netbeans.modules.cnd.execution.api.ConnectionManager;
46
import java.net.URI;
47
import org.junit.After;
48
import org.junit.AfterClass;
49
import static org.junit.Assert.*;
50
import org.junit.Before;
51
import org.junit.BeforeClass;
52
import org.junit.Test;
53
54
/**
55
 *
56
 * @author Andrew
57
 */
58
public class ConnectionManagerTest {
59
60
    public ConnectionManagerTest() {
61
    }
62
63
    @BeforeClass
64
    public static void setUpClass() throws Exception {
65
    }
66
67
    @AfterClass
68
    public static void tearDownClass() throws Exception {
69
    }
70
71
    @Before
72
    public void setUp() {
73
    }
74
75
    @After
76
    public void tearDown() {
77
    }
78
79
    /**
80
     * Test that: <ul>
81
     *
82
     * <li>returned connection is never null</li>
83
     *
84
     * <li>same connection is returned in subsequent call</li>
85
     *
86
     * <li>same connection is returned for equivalent URIs</li>
87
     *
88
     * </ul>
89
     */
90
    @Test
91
    public void testGetConnection() throws Exception {
92
        final URI uri1 = new URI("test://tester@computer:22");
93
        final URI uri2 = new URI("test://tester:tester@computer:22");
94
95
        Connection c1, c2;
96
97
        c1 = ConnectionManager.getConnection(uri1);
98
        assertNull("ConnectionManager must return NULL if no ACTIVE connection with equivalent URI exists", c1);
99
100
        c2 = ConnectionManager.getConnection(uri2);
101
        assertNull("ConnectionManager must return NULL if no ACTIVE connection with equivalent URI exists", c2);
102
103
        try {
104
            c1 = ConnectionManager.connect(uri1, null);
105
            assertTrue("At this point connection should be in connected state", c1.isConnected());
106
            assertNotNull("Returned connection is NEVER null", c1);
107
            assertTrue("Returned connection is connected", c1.isConnected());
108
109
            c2 = ConnectionManager.connect(uri2, null);
110
            assertNotNull("Connection exists => returned connection should be not null", c2);
111
            assertTrue("Returned connection is connected", c2.isConnected());
112
113
            assertEquals("Now connections should be the same", c1, c2);
114
115
            ConnectionManager.disconnect(c2);
116
117
            assertFalse("connection must be disconnected", c1.isConnected());
118
            assertFalse("connection must be disconnected", c2.isConnected());
119
120
        } catch (Exception ex) {
121
            assertTrue("Unexpected exception", false);
122
        }
123
124
//        c2 = ConnectionManager.connect(uri2, null);
125
//        assertTrue("At this point connection should be in connected state", c2.isConnected());
126
//
127
//        assertTrue("Once connection was established, there should be a single Connection object for all equivalent URIs", c1 == c2);
128
//        assertTrue("Once connection was established, there should be a single Connection object for all equivalent URIs", c1 == ConnectionManager.getConnection(uri1));
129
//        assertTrue("Once connection was established, there should be a single Connection object for all equivalent URIs", c1 == ConnectionManager.getConnection(uri2));
130
//
131
//        ConnectionManager.disconnect(c1);
132
//
133
//        assertFalse("At this point connection should be in disconnected state", c1.isConnected());
134
//        assertFalse("At this point connection should be in disconnected state", c2.isConnected());
135
//
136
//        c2 = ConnectionManager.getConnection(uri2);
137
//        assertNotNull("ConnectionManager must always return not NULL connection", c2);
138
//
139
//        assertTrue("Even when connection was disconnected - the same object (if still refferenced) should be returned", c1 == c2);
140
//        System.out.println(System.identityHashCode(c1));
141
//        System.out.println(System.identityHashCode(c2));
142
//
143
//        c1 = null;
144
//        c2 = null;
145
//        connection1 = null;
146
//        System.gc();
147
//
148
//        c2 = ConnectionManager.getConnection(uri2);
149
//        c2 = ConnectionManager.connect(uri2, null);
150
//
151
//        System.out.println(System.identityHashCode(c2));
152
//        System.out.println("should be true: " + c2.isConnected());
153
//        c2 = null;
154
//        System.gc();
155
//        c2 = ConnectionManager.getConnection(uri2);
156
//        System.out.println("should be true: " + c2.isConnected());
157
    }
158
159
    /**
160
     * Test of getConnection method, of class ConnectionManager.
161
     */
162
    @Test
163
    public void testGetLocalConnection() throws Exception {
164
    }
165
//    @Test
166
//    public void testGetConnection() throws Exception {
167
//        final URI uri = new URI("test://tester@computer:22");
168
//        final AtomicInteger established = new AtomicInteger(0);
169
//        final AtomicInteger closed = new AtomicInteger(0);
170
//        final AtomicInteger lost = new AtomicInteger(0);
171
//        final AtomicInteger other = new AtomicInteger(0);
172
//
173
//        final ConnectionStateChangeListener listener = new ConnectionStateChangeListener() {
174
//
175
//            @Override
176
//            public void connectionStateChanged(ConnectionStateChangeEvent ce) {
177
//                switch (ce.getState()) {
178
//                    case CONNECTION_ESTABLISHED:
179
//                        established.incrementAndGet();
180
//                        break;
181
//                    case CONNECTION_CLOSED:
182
//                        closed.incrementAndGet();
183
//                        break;
184
//                    case CONNECTION_LOST:
185
//                        lost.incrementAndGet();
186
//                        break;
187
//                    default:
188
//                        other.incrementAndGet();
189
//                }
190
//            }
191
//        };
192
//
193
//
194
////        ConnectionsRegistryAccessor.addConnectionListener(listener);
195
//
196
//        JPanel panel = new JPanel(new BorderLayout());
197
//        JButton button = new JButton("Do it!");
198
//        button.addActionListener(new ActionListener() {
199
//
200
//            @Override
201
//            public void actionPerformed(ActionEvent e) {
202
//                try {
203
//                    Connection connection = ConnectionManager.getConnection(uri);
204
//                    connection.connect(new AuthDataProvider() {
205
//
206
//                        @Override
207
//                        public <T> T getProperty(final URI uri, Class<T> clazz, String name, Object... misc) throws InterruptedException {
208
//                            DialogDisplayer.getDefault().notify(new NotifyDescriptor.Confirmation("Enter something for: " + uri + " == " + name));
209
//                            Thread.sleep(100000);
210
//                            return null;
211
//                        }
212
//                    });
213
//
214
//                    if (connection != null && Connection.State.CONNECTED.equals(connection.getState())) {
215
//                        assertArrayEquals(new int[]{1, 0, 0, 0},
216
//                                new int[]{established.get(), closed.get(), lost.get(), other.get()});
217
//
218
//                    } else {
219
//                        fail("Should be connected");
220
//                    }
221
//
222
//                    //        new TestConnector().disconnect(connection);
223
//
224
//                    //        Thread.sleep(3000);
225
//                    System.out.println("HERE!");
226
//
227
//                    Connection connection2 = ConnectionManager.getConnection(uri);
228
//
229
//                    assertTrue(connection == connection2);
230
//
231
////                    ConnectionsRegistryAccessor.disconnect(connection2);
232
//
233
//                    assertArrayEquals(new int[]{1, 1, 0, 0},
234
//                            new int[]{established.get(), closed.get(), lost.get(), other.get()});
235
////                    ConnectionsRegistryAccessor.removeConnectionListener(listener);
236
//                } catch (ConnectionCancelledException ex) {
237
//                    System.out.println("Cancelled!");
238
//                } catch (NativeExecutionException ex) {
239
//                    Exceptions.printStackTrace(ex);
240
//                }
241
//            }
242
//        });
243
//
244
//        panel.add(button);
245
//        DialogDescriptor dd = new DialogDescriptor(panel, "Request");
246
//        Dialog dialog = DialogDisplayer.getDefault().createDialog(dd);
247
//        dialog.setVisible(true);
248
//    }
249
}
(-)a/cnd.execution/test/unit/src/org/netbeans/modules/cnd/execution/api/ConnectionTest.java (+177 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2012 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 2012 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.cnd.execution.api;
43
44
import org.netbeans.modules.cnd.execution.api.Connection;
45
import org.netbeans.modules.cnd.execution.api.ConnectionManager;
46
import org.netbeans.modules.cnd.execution.api.ConnectionStateChangeListener;
47
import org.netbeans.modules.cnd.execution.api.ConnectionStateChangeEvent;
48
import org.netbeans.modules.cnd.execution.api.NativeExecutionException;
49
import java.net.URI;
50
import java.net.URISyntaxException;
51
import java.util.concurrent.atomic.AtomicInteger;
52
import java.util.concurrent.atomic.AtomicReference;
53
import org.junit.After;
54
import org.junit.AfterClass;
55
import static org.junit.Assert.*;
56
import org.junit.Before;
57
import org.junit.BeforeClass;
58
import org.junit.Test;
59
import org.netbeans.modules.cnd.execution.util.HostInfo;
60
import org.netbeans.modules.cnd.execution.util.HostInfo.CpuFamily;
61
import org.netbeans.modules.cnd.execution.util.URIMatcher;
62
import org.openide.util.Exceptions;
63
64
/**
65
 *
66
 * @author Andrew
67
 */
68
public class ConnectionTest {
69
70
    public ConnectionTest() {
71
    }
72
73
    @BeforeClass
74
    public static void setUpClass() throws Exception {
75
    }
76
77
    @AfterClass
78
    public static void tearDownClass() throws Exception {
79
    }
80
81
    @Before
82
    public void setUp() {
83
    }
84
85
    @After
86
    public void tearDown() {
87
    }
88
89
    /**
90
     * Test of connect method, of class Connection.
91
     */
92
    @Test
93
    public void testConnectionListeners() throws Exception {
94
        try {
95
            final URI uri = new URI("test://tester@computer:22");
96
            Connection connection = ConnectionManager.getConnection(uri);
97
            assertNull("ConnectionManager must return NULL for not existent connection", connection);
98
99
            final AtomicReference<ConnectionStateChangeEvent.State> lstate =
100
                    new AtomicReference<ConnectionStateChangeEvent.State>();
101
102
            final AtomicInteger count = new AtomicInteger();
103
            final ConnectionStateChangeListener listener = new ConnectionStateChangeListener() {
104
105
                @Override
106
                public void connectionStateChanged(ConnectionStateChangeEvent event) {
107
                    URIMatcher m = new URIMatcher(uri);
108
                    assertTrue(m.isIdenticalURI(event.getSource()));
109
                    lstate.set(event.getState());
110
                    count.incrementAndGet();
111
                }
112
            };
113
114
            ConnectionManager.addConnectionStateChangeListener(listener, uri);
115
116
            // Test that listeners are added weakly
117
            ConnectionManager.addConnectionStateChangeListener(new ConnectionStateChangeListener() {
118
119
                @Override
120
                public void connectionStateChanged(ConnectionStateChangeEvent event) {
121
                    assertTrue("This listener should not be called!", false);
122
                }
123
            }, uri);
124
125
            System.gc();
126
127
            assertEquals(null, lstate.get());
128
129
            connection = ConnectionManager.connect(uri, null);
130
131
            HostInfo hostInfo = HostInfo.getFor(connection);
132
            assertNotNull("HostInfo is never null", hostInfo);
133
134
            assertEquals("After connection establishment must receive a CONNECTION_ESTABLISHED event",
135
                    ConnectionStateChangeEvent.State.CONNECTION_ESTABLISHED, lstate.get());
136
137
            assertTrue("After connection establishment must be in CONNECTED state",
138
                    connection.isConnected());
139
            assertEquals("Connected connection must have KNOWN host info", CpuFamily.X86, hostInfo.getCpuFamily());
140
141
            ConnectionManager.disconnect(connection);
142
143
            hostInfo = HostInfo.getFor(connection);
144
            assertEquals("When disconnected with an API call, must get CONNECTION_CLOSED event",
145
                    ConnectionStateChangeEvent.State.CONNECTION_CLOSED, lstate.get());
146
            assertFalse("When disconnected with an API call, must be in DISCONNECTED state",
147
                    connection.isConnected());
148
            assertEquals("Connected connection must have KNOWN host info", CpuFamily.X86, hostInfo.getCpuFamily());
149
150
            ConnectionManager.connect(uri, null);
151
            assertEquals("On reconnect must get CONNECTION_ESTABLISHED event",
152
                    ConnectionStateChangeEvent.State.CONNECTION_ESTABLISHED, lstate.get());
153
            assertTrue("On reconnect must appear in CONNECTED state",
154
                    connection.isConnected());
155
156
            // Emulate broken connection (disconnected not via API)
157
            TestConnector.lastTestConnection.get().disconnect();
158
            // Some time may be required to see that connection is broken ...
159
            Thread.sleep(1100);
160
161
            hostInfo = HostInfo.getFor(connection);
162
            assertEquals("When disconnected (non-API) must get CONNECTION_LOST event",
163
                    ConnectionStateChangeEvent.State.CONNECTION_LOST, lstate.get());
164
            assertFalse("When disconnected (non-API) must be in DISCONNECTED state",
165
                    connection.isConnected());
166
            assertEquals("Connected connection must have KNOWN host info", CpuFamily.X86, hostInfo.getCpuFamily());
167
168
            ConnectionManager.disconnect(connection);
169
            assertEquals("Total notifications. API call to diconnect must not send notification at this point",
170
                    4, count.get());
171
        } catch (NativeExecutionException ex) {
172
            Exceptions.printStackTrace(ex);
173
        } catch (URISyntaxException ex) {
174
            Exceptions.printStackTrace(ex);
175
        }
176
    }
177
}
(-)a/cnd.execution/test/unit/src/org/netbeans/modules/cnd/execution/api/TestConnectionIdentifier.java (+84 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2012 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 2012 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.cnd.execution.api;
43
44
import java.net.URI;
45
import org.netbeans.modules.cnd.execution.spi.URIIdentifier;
46
import org.openide.util.lookup.ServiceProvider;
47
48
/**
49
 *
50
 * @author akrasny
51
 */
52
@ServiceProvider(service = org.netbeans.modules.cnd.execution.spi.URIIdentifier.class, path = "ConnectionService/test", position = 10)
53
public class TestConnectionIdentifier implements URIIdentifier {
54
55
    @Override
56
    public boolean areIdentical(URI uri1, URI uri2) {
57
        if (!(uri1.getScheme().equals(uri2.getScheme()))) {
58
            return false;
59
        }
60
        
61
        String host1 = uri1.getHost();
62
        String host2 = uri2.getHost();
63
64
        if (host1 == null || host2 == null) {
65
            throw new NullPointerException("Test connection URI must define host");
66
        }
67
68
        String user1 = uri1.getUserInfo();
69
        String user2 = uri2.getUserInfo();
70
        if (user1 == null || user2 == null) {
71
            throw new NullPointerException("Test connection URI must define user");
72
        }
73
74
        int cpos;
75
        if ((cpos = user1.indexOf(':')) > 0) {
76
            user1 = user1.substring(0, cpos);
77
        }
78
        if ((cpos = user2.indexOf(':')) > 0) {
79
            user2 = user2.substring(0, cpos);
80
        }
81
82
        return host1.equals(host2) && user1.equals(user2);
83
    }
84
}
(-)a/cnd.execution/test/unit/src/org/netbeans/modules/cnd/execution/api/TestConnector.java (+150 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2012 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 2012 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.cnd.execution.api;
43
44
import java.net.URI;
45
import java.util.HashMap;
46
import java.util.Map;
47
import java.util.concurrent.atomic.AtomicReference;
48
import org.netbeans.modules.cnd.execution.spi.AuthDataProvider;
49
import org.netbeans.modules.cnd.execution.spi.ConnectionImplementation;
50
import org.netbeans.modules.cnd.execution.spi.ConnectorImplementation;
51
import org.netbeans.modules.cnd.execution.spi.NativeProcessCreator;
52
import org.netbeans.modules.cnd.execution.spi.NativeProcessImplementation;
53
import org.netbeans.modules.cnd.execution.spi.NativeProcessParams;
54
import org.netbeans.modules.cnd.execution.spi.support.ConnectionInfo;
55
import org.netbeans.modules.cnd.execution.spi.support.ConnectionInfoProvider;
56
import org.openide.util.Lookup;
57
import org.openide.util.lookup.Lookups;
58
import org.openide.util.lookup.ServiceProvider;
59
60
@ServiceProvider(service = org.netbeans.modules.cnd.execution.spi.ConnectorImplementation.class, path = "ConnectionService/test", position = 10)
61
public final class TestConnector implements ConnectorImplementation {
62
63
    public static final AtomicReference<TestConnection> lastTestConnection = new AtomicReference<TestConnection>();
64
65
    @Override
66
    public ConnectionImplementation connectTo(URI uri, AuthDataProvider authDataProvider) throws InterruptedException, NativeExecutionException {
67
        authDataProvider.getProperty(uri, String.class, "test");
68
        TestConnection cimpl = new TestConnection(uri);
69
        lastTestConnection.set(cimpl);
70
        return cimpl;
71
    }
72
73
    public static class TestConnection implements ConnectionImplementation {
74
75
        private boolean closed = false;
76
        private final String name;
77
        private final URI uri;
78
79
        private TestConnection(URI uri) {
80
            this.name = "Test connection to " + uri.toString();
81
            this.uri = uri;
82
        }
83
84
        @Override
85
        public void disconnect() {
86
            closed = true;
87
        }
88
89
        @Override
90
        public String toString() {
91
            return name;
92
        }
93
94
        @Override
95
        public NativeProcessCreator newProcessBuilderImpl() throws NativeExecutionException {
96
            return FakeProcessCreator.instance;
97
        }
98
99
        @Override
100
        public boolean isConnected() {
101
            return !closed;
102
        }
103
104
        @Override
105
        public Lookup getLookup() {
106
            return Lookups.fixed(new ConnectionInfoProvider() {
107
                @Override
108
                public ConnectionInfo getConnectionInfo(Connection connection) throws NativeExecutionException {
109
                    return new ConnectionInfo() {
110
                        @Override
111
                        public Map<String, String> getEnvironmentMap() {
112
                            HashMap<String, String> env = new HashMap<String, String>();
113
                            env.put("TEST_ENV", "flag");
114
                            return env;
115
                        }
116
117
                        @Override
118
                        public Map<String, String> getProperties() {
119
                            Map<String, String> result = new HashMap<String, String>();
120
                            result.put("CPUFAMILY", "X86");
121
                            return result;
122
                        }
123
                    };
124
                }
125
            });
126
        }
127
128
        @Override
129
        public URI getURI() {
130
            return uri;
131
        }
132
    }
133
134
    public static class FakeProcessCreator implements NativeProcessCreator {
135
136
        public static final FakeProcessCreator instance = new FakeProcessCreator();
137
        public NativeProcessParams params;
138
139
        @Override
140
        public NativeProcessImplementation createAndStart(NativeProcessParams params) throws NativeExecutionException {
141
            this.params = params;
142
            throw new NativeExecutionException("Not supported");
143
        }
144
145
        @Override
146
        public Lookup getLookup() {
147
            return Lookup.EMPTY;
148
        }
149
    }
150
}
(-)a/cnd.execution/test/unit/src/org/netbeans/modules/cnd/execution/common/ConnectionsRegistryTest.java (+82 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2012 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 2012 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.cnd.execution.common;
43
44
import org.junit.After;
45
import org.junit.AfterClass;
46
import org.junit.Before;
47
import org.junit.Test;
48
import org.junit.BeforeClass;
49
50
/**
51
 *
52
 * @author Andrew
53
 */
54
public class ConnectionsRegistryTest {
55
56
    public ConnectionsRegistryTest() {
57
    }
58
59
    @BeforeClass
60
    public static void setUpClass() throws Exception {
61
    }
62
63
    @AfterClass
64
    public static void tearDownClass() throws Exception {
65
    }
66
67
    @Before
68
    public void setUp() {
69
    }
70
71
    @After
72
    public void tearDown() {
73
    }
74
75
    /**
76
     * Test of fromFileName method, of class ConnectionsRegistry.
77
     */
78
    @Test
79
    public void test() {
80
     
81
    }
82
}
(-)a/cnd.execution/test/unit/src/org/netbeans/modules/cnd/execution/util/EnvironmentMapTest.java (+111 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2012 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 2012 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.cnd.execution.util;
43
44
import org.junit.After;
45
import org.junit.AfterClass;
46
import static org.junit.Assert.*;
47
import org.junit.Before;
48
import org.junit.BeforeClass;
49
import org.junit.Test;
50
import org.netbeans.modules.cnd.execution.access.EnvironmentMapAccessor;
51
import org.netbeans.modules.cnd.execution.api.EnvironmentMap;
52
53
/**
54
 *
55
 * @author Andrew
56
 */
57
public class EnvironmentMapTest {
58
59
    public EnvironmentMapTest() {
60
    }
61
62
    @BeforeClass
63
    public static void setUpClass() throws Exception {
64
    }
65
66
    @AfterClass
67
    public static void tearDownClass() throws Exception {
68
    }
69
70
    @Before
71
    public void setUp() {
72
    }
73
74
    @After
75
    public void tearDown() {
76
    }
77
78
    /**
79
     * Test of prependPath method, of class EnvironmentMap.
80
     */
81
    @Test
82
    public void testPrependPathVariable() {
83
        EnvironmentMap map = EnvironmentMapAccessor.getDefault().createCasePreserving(';');
84
        map.put("Path", "<first>");
85
        map.put("PATH", "${PATH};${UNKNOWN}");
86
        map.appendPath("path", "<last>");
87
88
        map.dump(System.out);
89
        assertEquals(1, map.size());
90
        assertEquals("<first>;${UNKNOWN};<last>", map.get("path"));
91
92
        String name = map.entrySet().iterator().next().getKey();
93
94
        // First time case was exactly Path - it should be preserved
95
        assertEquals("Path", name);
96
97
        
98
        map = EnvironmentMapAccessor.getDefault().createCaseSensitive(':');
99
        //        map.setDictionary(special);
100
        map.put("Path", "<first>");
101
        map.put("PATH", "${PATH}:${UNKNOWN}");
102
        map.appendPath("path", "<last>");
103
        map.prependPath("path", "<first>");
104
105
        map.dump(System.out);
106
        assertEquals(3, map.entrySet().size());
107
        assertEquals("<first>:<last>", map.get("path"));
108
        assertEquals("${PATH}:${UNKNOWN}", map.get("PATH"));
109
        assertEquals("<first>", map.get("Path"));
110
    }
111
}
(-)a/cnd.execution/test/unit/src/org/netbeans/modules/cnd/execution/util/HostInfoTest.java (+117 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2012 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 2012 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.cnd.execution.util;
43
44
import static org.junit.Assert.*;
45
import java.io.File;
46
import java.io.IOException;
47
import java.io.StringWriter;
48
import java.util.Collections;
49
import java.util.concurrent.ExecutionException;
50
import org.junit.After;
51
import org.junit.AfterClass;
52
import org.junit.Before;
53
import org.junit.BeforeClass;
54
import org.junit.Test;
55
import org.netbeans.api.extexecution.ExecutionService;
56
import org.netbeans.modules.cnd.execution.api.Connection;
57
import org.netbeans.modules.cnd.execution.api.ConnectionManager;
58
import org.openide.util.Exceptions;
59
60
/**
61
 *
62
 * @author akrasny
63
 */
64
public class HostInfoTest {
65
66
    public HostInfoTest() {
67
    }
68
69
    @BeforeClass
70
    public static void setUpClass() throws Exception {
71
    }
72
73
    @AfterClass
74
    public static void tearDownClass() throws Exception {
75
    }
76
77
    @Before
78
    public void setUp() {
79
    }
80
81
    @After
82
    public void tearDown() {
83
    }
84
85
    /**
86
     * Test of getFor method, of class HostInfo.
87
     */
88
    @Test
89
    public void testLocal() {
90
        Connection local = ConnectionManager.getLocalConnection();
91
        HostInfo info = HostInfo.getFor(local);
92
        System.out.println(info.getOS().getName());
93
94
        File f = new File("/usr/bin/uname");
95
        if (!f.canExecute()) {
96
            f = new File("/bin/uname");
97
            if (!f.canExecute()) {
98
                fail("uname not found");
99
            }
100
        }
101
        try {
102
            org.netbeans.api.extexecution.ProcessBuilder pb = local.getProcessBuilder();
103
            pb.setExecutable(f.getAbsolutePath());
104
            pb.setArguments(Collections.singletonList("-a"));
105
            StringWriter output = new StringWriter();
106
            ExecutionService.newService(pb, output, null).run().get();
107
            System.out.println(output.toString());
108
        } catch (ExecutionException ex) {
109
            Exceptions.printStackTrace(ex);
110
        } catch (IOException ex) {
111
            Exceptions.printStackTrace(ex);
112
        } catch (InterruptedException ex) {
113
            Exceptions.printStackTrace(ex);
114
        }
115
116
    }
117
}
(-)a/cnd.execution/test/unit/src/org/netbeans/modules/cnd/execution/util/MacroMapTest.java (+198 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2012 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 2012 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.cnd.execution.util;
43
44
import org.netbeans.modules.cnd.execution.api.EnvironmentMap;
45
import java.util.concurrent.Callable;
46
import java.util.concurrent.ExecutionException;
47
import java.util.concurrent.Future;
48
import java.util.concurrent.TimeUnit;
49
import java.util.concurrent.TimeoutException;
50
import org.junit.After;
51
import org.junit.AfterClass;
52
import org.junit.Before;
53
import org.junit.BeforeClass;
54
import org.junit.Test;
55
import org.netbeans.junit.NbTestCase;
56
import org.netbeans.modules.cnd.execution.access.EnvironmentMapAccessor;
57
import org.openide.util.Exceptions;
58
import org.openide.util.RequestProcessor;
59
60
/**
61
 *
62
 * @author akrasny
63
 */
64
public class MacroMapTest extends NbTestCase {
65
66
    public MacroMapTest(String name) {
67
        super(name);
68
    }
69
70
    @BeforeClass
71
    public static void setUpClass() throws Exception {
72
    }
73
74
    @AfterClass
75
    public static void tearDownClass() throws Exception {
76
    }
77
78
    @Before
79
    @Override
80
    public void setUp() {
81
    }
82
83
    @After
84
    @Override
85
    public void tearDown() {
86
    }
87
88
    @Test
89
    public void testX() {
90
        final RequestProcessor RP = new RequestProcessor("A", 10);
91
        RP.post(new Runnable() {
92
93
            @Override
94
            public void run() {
95
                Thread.currentThread().setName("Invoke thread");
96
                doit(RP);
97
            }
98
        }).waitFinished();
99
        System.out.println("ALL done");
100
101
    }
102
103
    private void doit(RequestProcessor RP) {
104
        Future<Void> fres = RP.submit(new Callable<Void>() {
105
106
            @Override
107
            public Void call() throws Exception {
108
                Thread.currentThread().setName("Process's thread");
109
                try {
110
                    Thread.sleep(100);
111
                } finally {
112
                    System.out.println("Process is DONE");
113
                }
114
115
                return null;
116
            }
117
        });
118
119
        try {
120
            fres.get();
121
            System.out.println("HERE is NO exception");
122
        } catch (InterruptedException ex) {
123
            Thread.interrupted();
124
            System.out.println("INVOKE THREAD WAS INTERRUPTED");
125
            fres.cancel(true);
126
            try {
127
                fres.get(1, TimeUnit.SECONDS);
128
            } catch (TimeoutException ex1) {
129
                System.out.println("FAILED TO STOP!!!!");
130
                Exceptions.printStackTrace(ex1);
131
            } catch (InterruptedException ex1) {
132
                Thread.interrupted();
133
                System.out.println("INTERRUPTED AGAIN!!!!");
134
                Exceptions.printStackTrace(ex1);
135
            } catch (ExecutionException ex1) {
136
                System.out.println("STOPPED!!!!");
137
                Exceptions.printStackTrace(ex1);
138
            }
139
        } catch (ExecutionException ex) {
140
            System.out.println("PROCESS's THREAD WAS INTERRUPTED");
141
            Exceptions.printStackTrace(ex);
142
        }
143
144
    }
145
146
    /**
147
     * Test of put method, of class EnvironmentMap.
148
     */
149
//    @Test
150
    public void _testPut() {
151
        EnvironmentMap map;
152
153
//        map = EnvironmentMapAccessor.getDefault().createCaseSensitive(':');
154
//        map.put("A", "1");
155
//        map.put("C", "2");
156
//        map.put("B", "3");
157
//        map.dump(getRef());
158
//
159
//        map = EnvironmentMapAccessor.getDefault().createCaseSensitive(':');
160
//        map.put("A", "1");
161
//        map.put("c", "2");
162
//        map.put("b", "3");
163
//        map.put("C", "4");
164
//        map.put("A", "5");
165
//        map.dump(getRef());
166
//
167
//        map = EnvironmentMapAccessor.getDefault().createCasePreserving(':');
168
//        map.put("A", "1");
169
//        map.put("C", "2");
170
//        map.put("B", "3");
171
//        map.dump(getRef());
172
//
173
//        map = EnvironmentMapAccessor.getDefault().createCasePreserving(':');
174
//        map.put("A", "1");
175
//        map.put("c", "2");
176
//        map.put("b", "3");
177
//        map.put("C", "4");
178
//        map.put("A", "5");
179
//        map.dump(getRef());
180
//
181
//        map = EnvironmentMapAccessor.getDefault().createCasePreserving(':');
182
//        map.put("A", "1");
183
//        map.put("C", "2");
184
//        map.put("B", "3");
185
//        map.dump(getRef());
186
//
187
//        map = EnvironmentMapAccessor.getDefault().createCasePreserving(':');
188
//        map.put("A", "1");
189
//        map.put("c", "2");
190
//        map.put("b", "3");
191
//        map.put("C", "4");
192
//        map.put("A", "5");
193
//        map.remove("a");
194
//        map.dump(getRef());
195
//
196
//        compareReferenceFiles();
197
    }
198
}
(-)a/cnd.makeproject/nbproject/project.xml (+16 lines)
Lines 67-72 Link Here
67
                        <specification-version>1.9.2</specification-version>
67
                        <specification-version>1.9.2</specification-version>
68
                    </run-dependency>
68
                    </run-dependency>
69
                </dependency>
69
                </dependency>
70
             <dependency>
71
                    <code-name-base>org.netbeans.modules.cnd.execution</code-name-base>
72
                    <build-prerequisite/>
73
                    <compile-dependency/>
74
                    <run-dependency>
75
                        <specification-version>1.0</specification-version>
76
                    </run-dependency>
77
                </dependency>
70
                <dependency>
78
                <dependency>
71
                    <code-name-base>org.netbeans.modules.cnd.source</code-name-base>
79
                    <code-name-base>org.netbeans.modules.cnd.source</code-name-base>
72
                    <build-prerequisite/>
80
                    <build-prerequisite/>
Lines 133-138 Link Here
133
                    </run-dependency>
141
                    </run-dependency>
134
                </dependency>
142
                </dependency>
135
                <dependency>
143
                <dependency>
144
                    <code-name-base>org.netbeans.modules.execmerge</code-name-base>
145
                    <build-prerequisite/>
146
                    <compile-dependency/>
147
                    <run-dependency>
148
                        <specification-version>1.0</specification-version>
149
                    </run-dependency>
150
                </dependency>
151
                <dependency>
136
                    <code-name-base>org.netbeans.modules.extexecution</code-name-base>
152
                    <code-name-base>org.netbeans.modules.extexecution</code-name-base>
137
                    <build-prerequisite/>
153
                    <build-prerequisite/>
138
                    <compile-dependency/>
154
                    <compile-dependency/>
(-)a/cnd.makeproject/src/org/netbeans/modules/cnd/makeproject/api/ProjectActionSupport.java (-1 / +6 lines)
Lines 61-66 Link Here
61
import java.util.prefs.Preferences;
61
import java.util.prefs.Preferences;
62
import javax.swing.AbstractAction;
62
import javax.swing.AbstractAction;
63
import javax.swing.Action;
63
import javax.swing.Action;
64
import org.netbeans.api.extexecution.ProcessBuilder;
64
import org.netbeans.api.progress.ProgressHandle;
65
import org.netbeans.api.progress.ProgressHandle;
65
import org.netbeans.api.progress.ProgressHandleFactory;
66
import org.netbeans.api.progress.ProgressHandleFactory;
66
import org.netbeans.api.project.Project;
67
import org.netbeans.api.project.Project;
Lines 73-78 Link Here
73
import org.netbeans.modules.cnd.api.remote.PathMap;
74
import org.netbeans.modules.cnd.api.remote.PathMap;
74
import org.netbeans.modules.cnd.api.remote.RemoteFileUtil;
75
import org.netbeans.modules.cnd.api.remote.RemoteFileUtil;
75
import org.netbeans.modules.cnd.api.remote.RemoteSyncSupport;
76
import org.netbeans.modules.cnd.api.remote.RemoteSyncSupport;
77
import org.netbeans.modules.cnd.execution.api.Connection;
76
import org.netbeans.modules.cnd.makeproject.MakeOptions;
78
import org.netbeans.modules.cnd.makeproject.MakeOptions;
77
import org.netbeans.modules.cnd.makeproject.api.BuildActionsProvider.BuildAction;
79
import org.netbeans.modules.cnd.makeproject.api.BuildActionsProvider.BuildAction;
78
import org.netbeans.modules.cnd.makeproject.api.BuildActionsProvider.OutputStreamHandler;
80
import org.netbeans.modules.cnd.makeproject.api.BuildActionsProvider.OutputStreamHandler;
Lines 92-97 Link Here
92
import org.netbeans.modules.cnd.utils.CndUtils;
94
import org.netbeans.modules.cnd.utils.CndUtils;
93
import org.netbeans.modules.cnd.utils.cache.CndFileUtils;
95
import org.netbeans.modules.cnd.utils.cache.CndFileUtils;
94
import org.netbeans.modules.dlight.api.terminal.TerminalSupport;
96
import org.netbeans.modules.dlight.api.terminal.TerminalSupport;
97
import org.netbeans.modules.execmerge.ConnectionUtils;
95
import org.netbeans.modules.nativeexecution.api.ExecutionEnvironment;
98
import org.netbeans.modules.nativeexecution.api.ExecutionEnvironment;
96
import org.netbeans.modules.nativeexecution.api.ExecutionListener;
99
import org.netbeans.modules.nativeexecution.api.ExecutionListener;
97
import org.netbeans.modules.nativeexecution.api.execution.IOTabsController;
100
import org.netbeans.modules.nativeexecution.api.execution.IOTabsController;
Lines 881-887 Link Here
881
                        }
884
                        }
882
                    }
885
                    }
883
                }
886
                }
884
                TerminalSupport.openTerminal(getString("TargetExecutor.TermAction.tabTitle", projectName, env.getDisplayName()), env, dir); // NOI18N
887
                
888
                TerminalSupport.openTerminal(getString("TargetExecutor.TermAction.tabTitle", projectName, env.getDisplayName()),
889
                        ConnectionUtils.ExecutionEnvironment2Connection(env), dir); // NOI18N
885
                break;
890
                break;
886
            }
891
            }
887
        }
892
        }
(-)a/cnd.remote.projectui/nbproject/project.xml (+8 lines)
Lines 67-72 Link Here
67
                    </run-dependency>
67
                    </run-dependency>
68
                </dependency>
68
                </dependency>
69
                <dependency>
69
                <dependency>
70
                    <code-name-base>org.netbeans.modules.cnd.execution</code-name-base>
71
                    <build-prerequisite/>
72
                    <compile-dependency/>
73
                    <run-dependency>
74
                        <specification-version>1.0</specification-version>
75
                    </run-dependency>
76
                </dependency>
77
                <dependency>
70
                    <code-name-base>org.netbeans.modules.cnd.makeproject</code-name-base>
78
                    <code-name-base>org.netbeans.modules.cnd.makeproject</code-name-base>
71
                    <build-prerequisite/>
79
                    <build-prerequisite/>
72
                    <compile-dependency/>
80
                    <compile-dependency/>
(-)a/cnd.remote/nbproject/project.xml (+16 lines)
Lines 69-74 Link Here
69
                    </run-dependency>
69
                    </run-dependency>
70
                </dependency>
70
                </dependency>
71
                <dependency>
71
                <dependency>
72
                    <code-name-base>org.netbeans.modules.cnd.execution</code-name-base>
73
                    <build-prerequisite/>
74
                    <compile-dependency/>
75
                    <run-dependency>
76
                        <specification-version>1.0</specification-version>
77
                    </run-dependency>
78
                </dependency>
79
                <dependency>
72
                    <code-name-base>org.netbeans.modules.cnd.makeproject</code-name-base>
80
                    <code-name-base>org.netbeans.modules.cnd.makeproject</code-name-base>
73
                    <build-prerequisite/>
81
                    <build-prerequisite/>
74
                    <compile-dependency/>
82
                    <compile-dependency/>
Lines 126-131 Link Here
126
                    </run-dependency>
134
                    </run-dependency>
127
                </dependency>
135
                </dependency>
128
                <dependency>
136
                <dependency>
137
                    <code-name-base>org.netbeans.modules.execmerge</code-name-base>
138
                    <build-prerequisite/>
139
                    <compile-dependency/>
140
                    <run-dependency>
141
                        <specification-version>1.0</specification-version>
142
                    </run-dependency>
143
                </dependency>
144
                <dependency>
129
                    <code-name-base>org.netbeans.modules.extexecution</code-name-base>
145
                    <code-name-base>org.netbeans.modules.extexecution</code-name-base>
130
                    <build-prerequisite/>
146
                    <build-prerequisite/>
131
                    <compile-dependency/>
147
                    <compile-dependency/>
(-)a/cnd.remote/src/org/netbeans/modules/remote/ui/OpenTerminalAction.java (-6 / +5 lines)
Lines 39-45 Link Here
39
 *
39
 *
40
 * Portions Copyrighted 2011 Sun Microsystems, Inc.
40
 * Portions Copyrighted 2011 Sun Microsystems, Inc.
41
 */
41
 */
42
43
package org.netbeans.modules.remote.ui;
42
package org.netbeans.modules.remote.ui;
44
43
45
import java.io.IOException;
44
import java.io.IOException;
Lines 48-53 Link Here
48
import javax.swing.SwingUtilities;
47
import javax.swing.SwingUtilities;
49
import org.netbeans.modules.cnd.remote.mapper.RemotePathMap;
48
import org.netbeans.modules.cnd.remote.mapper.RemotePathMap;
50
import org.netbeans.modules.dlight.api.terminal.TerminalSupport;
49
import org.netbeans.modules.dlight.api.terminal.TerminalSupport;
50
import org.netbeans.modules.execmerge.ConnectionUtils;
51
import org.netbeans.modules.nativeexecution.api.ExecutionEnvironment;
51
import org.netbeans.modules.nativeexecution.api.ExecutionEnvironment;
52
import org.netbeans.modules.nativeexecution.api.HostInfo;
52
import org.netbeans.modules.nativeexecution.api.HostInfo;
53
import org.netbeans.modules.nativeexecution.api.util.ConnectionManager;
53
import org.netbeans.modules.nativeexecution.api.util.ConnectionManager;
Lines 70-78 Link Here
70
 * @author Vladimir Voskresensky
70
 * @author Vladimir Voskresensky
71
 */
71
 */
72
@ActionID(id = "org.netbeans.modules.remote.ui.OpenTerminalAction", category = "NativeRemote")
72
@ActionID(id = "org.netbeans.modules.remote.ui.OpenTerminalAction", category = "NativeRemote")
73
@ActionRegistration(displayName = "OpenTerminalMenuItem")
73
@ActionRegistration(displayName = "OpenTerminalMenuItem", lazy = false)
74
@ActionReference(path = "Remote/Host/Actions", name = "OpenTerminalAction", position = 700)
74
@ActionReference(path = "Remote/Host/Actions", name = "OpenTerminalAction", position = 700)
75
public class OpenTerminalAction extends SingleHostAction {
75
public class OpenTerminalAction extends SingleHostAction {
76
76
    private JMenu remotePopupMenu;
77
    private JMenu remotePopupMenu;
77
    private JMenuItem localPopupMenu;
78
    private JMenuItem localPopupMenu;
78
    
79
    
Lines 88-94 Link Here
88
        Node[] activatedNodes = getActivatedNodes();
89
        Node[] activatedNodes = getActivatedNodes();
89
        if (activatedNodes != null && activatedNodes.length == 1 && !isRemote(activatedNodes[0])) {
90
        if (activatedNodes != null && activatedNodes.length == 1 && !isRemote(activatedNodes[0])) {
90
            SystemAction.get(AddHome.class).performAction(env, node);
91
            SystemAction.get(AddHome.class).performAction(env, node);
91
        }        
92
        }
92
    }
93
    }
93
94
94
    @Override
95
    @Override
Lines 175-181 Link Here
175
176
176
                        @Override
177
                        @Override
177
                        public void run() {
178
                        public void run() {
178
                            TerminalSupport.openTerminal(env.getDisplayName(), env, path);
179
                            TerminalSupport.openTerminal(env.getDisplayName(), ConnectionUtils.ExecutionEnvironment2Connection(env), path);
179
                        }
180
                        }
180
                    };
181
                    };
181
182
Lines 235-241 Link Here
235
        }
236
        }
236
        return null;
237
        return null;
237
    }
238
    }
238
    
239
239
240
    private static final class AddMirror extends AddPlace {
240
    private static final class AddMirror extends AddPlace {
241
241
Lines 249-253 Link Here
249
            return remoteSyncRoot;
249
            return remoteSyncRoot;
250
        }
250
        }
251
    }
251
    }
252
         
253
}
252
}
(-)a/cnd.search/nbproject/project.xml (-2 / +10 lines)
Lines 14-24 Link Here
14
                    </run-dependency>
14
                    </run-dependency>
15
                </dependency>
15
                </dependency>
16
                <dependency>
16
                <dependency>
17
                    <code-name-base>org.netbeans.modules.cnd.execution</code-name-base>
18
                    <build-prerequisite/>
19
                    <compile-dependency/>
20
                    <run-dependency>
21
                        <specification-version>1.0</specification-version>
22
                    </run-dependency>
23
                </dependency>
24
                <dependency>
17
                    <code-name-base>org.netbeans.modules.dlight.nativeexecution</code-name-base>
25
                    <code-name-base>org.netbeans.modules.dlight.nativeexecution</code-name-base>
18
                    <build-prerequisite/>
26
                    <build-prerequisite/>
19
                    <compile-dependency/>
27
                    <compile-dependency/>
20
                    <run-dependency>
28
                    <run-dependency>
21
                        <specification-version>1.14</specification-version>
29
                        <specification-version>1.21</specification-version>
22
                    </run-dependency>
30
                    </run-dependency>
23
                </dependency>
31
                </dependency>
24
                <dependency>
32
                <dependency>
Lines 35-41 Link Here
35
                    <compile-dependency/>
43
                    <compile-dependency/>
36
                    <run-dependency>
44
                    <run-dependency>
37
                        <release-version>2</release-version>
45
                        <release-version>2</release-version>
38
                        <specification-version>1.30</specification-version>
46
                        <specification-version>1.37</specification-version>
39
                    </run-dependency>
47
                    </run-dependency>
40
                </dependency>
48
                </dependency>
41
                <dependency>
49
                <dependency>
(-)a/cnd.search/src/org/netbeans/modules/cnd/search/SearchResult.java (-5 / +5 lines)
Lines 41-47 Link Here
41
 */
41
 */
42
package org.netbeans.modules.cnd.search;
42
package org.netbeans.modules.cnd.search;
43
43
44
import org.netbeans.modules.nativeexecution.api.ExecutionEnvironment;
44
import org.netbeans.modules.cnd.execution.api.Connection;
45
import org.netbeans.modules.remote.spi.FileSystemProvider;
45
import org.netbeans.modules.remote.spi.FileSystemProvider;
46
import org.openide.filesystems.FileObject;
46
import org.openide.filesystems.FileObject;
47
47
Lines 51-61 Link Here
51
 */
51
 */
52
public final class SearchResult {
52
public final class SearchResult {
53
53
54
    public final ExecutionEnvironment env;
54
    public final Connection connection;
55
    public final MatchingFileData data;
55
    public final MatchingFileData data;
56
56
57
    public SearchResult(ExecutionEnvironment env, MatchingFileData matchingFile) {
57
    public SearchResult(Connection connection, MatchingFileData matchingFile) {
58
        this.env = env;
58
        this.connection = connection;
59
        this.data = matchingFile;
59
        this.data = matchingFile;
60
    }
60
    }
61
61
Lines 64-69 Link Here
64
            return null;
64
            return null;
65
        }
65
        }
66
66
67
        return FileSystemProvider.getFileObject(env, data.getPath());
67
        return FileSystemProvider.getFileObject(connection, data.getPath());
68
    }
68
    }
69
}
69
}
(-)a/cnd.search/src/org/netbeans/modules/cnd/search/impl/SearchBrowseHostScope.java (-142 / +142 lines)
Lines 41-46 Link Here
41
 */
41
 */
42
package org.netbeans.modules.cnd.search.impl;
42
package org.netbeans.modules.cnd.search.impl;
43
43
44
import java.net.URI;
44
import java.util.Iterator;
45
import java.util.Iterator;
45
import java.util.List;
46
import java.util.List;
46
import java.util.concurrent.atomic.AtomicBoolean;
47
import java.util.concurrent.atomic.AtomicBoolean;
Lines 50-57 Link Here
50
import org.netbeans.api.search.provider.SearchInfoUtils;
51
import org.netbeans.api.search.provider.SearchInfoUtils;
51
import org.netbeans.api.search.provider.SearchListener;
52
import org.netbeans.api.search.provider.SearchListener;
52
import org.netbeans.modules.cnd.search.ui.DirectoryChooser;
53
import org.netbeans.modules.cnd.search.ui.DirectoryChooser;
53
import org.netbeans.modules.nativeexecution.api.ExecutionEnvironment;
54
import org.netbeans.modules.cnd.execution.api.ConnectionManager;
54
import org.netbeans.modules.nativeexecution.api.util.ConnectionManager;
55
import org.netbeans.modules.remote.spi.FileSystemProvider;
55
import org.netbeans.modules.remote.spi.FileSystemProvider;
56
import org.netbeans.spi.search.SearchInfoDefinition;
56
import org.netbeans.spi.search.SearchInfoDefinition;
57
import org.netbeans.spi.search.SearchScopeDefinition;
57
import org.netbeans.spi.search.SearchScopeDefinition;
Lines 64-207 Link Here
64
 * @author akrasny
64
 * @author akrasny
65
 */
65
 */
66
public final class SearchBrowseHostScope {
66
public final class SearchBrowseHostScope {
67
67
//
68
    private static FileObject root;
68
//    private static FileObject root;
69
    private final ExecutionEnvironment env;
69
//    private final URI uri;
70
    private SearchScopeDefinition browseScope = new BrowseHostScopeDefinition();
70
//    private SearchScopeDefinition browseScope = new BrowseHostScopeDefinition();
71
    private SearchScopeDefinition lastScope = new LastSearchBrowseHostScope();
71
//    private SearchScopeDefinition lastScope = new LastSearchBrowseHostScope();
72
72
//
73
    public SearchBrowseHostScope(ExecutionEnvironment env) {
73
//    public SearchBrowseHostScope(URI uri) {
74
        this.env = env;
74
//        this.uri = uri;
75
    }
75
//    }
76
76
//
77
    final class BrowseHostScopeDefinition extends SearchScopeDefinition {
77
//    final class BrowseHostScopeDefinition extends SearchScopeDefinition {
78
78
//
79
        private final SearchInfo searchInfo;
79
//        private final SearchInfo searchInfo;
80
80
//
81
        public BrowseHostScopeDefinition() {
81
//        public BrowseHostScopeDefinition() {
82
            searchInfo = SearchInfoUtils.createForDefinition(new BrowseHostInfoDefinition());
82
//            searchInfo = SearchInfoUtils.createForDefinition(new BrowseHostInfoDefinition());
83
        }
83
//        }
84
84
//
85
        @Override
85
//        @Override
86
        public String getTypeId() {
86
//        public String getTypeId() {
87
            return SearchBrowseHostScope.class.getName();
87
//            return SearchBrowseHostScope.class.getName();
88
        }
88
//        }
89
89
//
90
        @Override
90
//        @Override
91
        public String getDisplayName() {
91
//        public String getDisplayName() {
92
            return NbBundle.getMessage(SearchBrowseHostScope.class, "LBL_BrowseHostScopeDefinitionName", env.getDisplayName()); // NOI18N
92
//            return NbBundle.getMessage(SearchBrowseHostScope.class, "LBL_BrowseHostScopeDefinitionName", uri); // NOI18N
93
        }
93
//        }
94
94
//
95
        @Override
95
//        @Override
96
        public boolean isApplicable() {
96
//        public boolean isApplicable() {
97
            return ConnectionManager.getInstance().isConnectedTo(env);
97
//            return ConnectionManager.getConnection(uri) != null;
98
        }
98
//        }
99
99
//
100
        @Override
100
//        @Override
101
        public SearchInfo getSearchInfo() {
101
//        public SearchInfo getSearchInfo() {
102
            return searchInfo;
102
//            return searchInfo;
103
        }
103
//        }
104
104
//
105
        @Override
105
//        @Override
106
        public int getPriority() {
106
//        public int getPriority() {
107
            return 701;
107
//            return 701;
108
        }
108
//        }
109
109
//
110
        @Override
110
//        @Override
111
        public void clean() {
111
//        public void clean() {
112
        }
112
//        }
113
113
//
114
        @Override
114
//        @Override
115
        public void selected() {
115
//        public void selected() {
116
            chooseRoots();
116
//            chooseRoots();
117
            notifyListeners();
117
//            notifyListeners();
118
        }
118
//        }
119
119
//
120
        private FileObject[] chooseRoots() {
120
//        private FileObject[] chooseRoots() {
121
            FileObject dir = DirectoryChooser.chooseDirectory(WindowManager.getDefault().getMainWindow(), env, null);
121
//            FileObject dir = DirectoryChooser.chooseDirectory(WindowManager.getDefault().getMainWindow(), uri, null);
122
            if (dir != null) {
122
//            if (dir != null) {
123
                root = dir;
123
//                root = dir;
124
                return new FileObject[]{root};
124
//                return new FileObject[]{root};
125
            }
125
//            }
126
            return new FileObject[0];
126
//            return new FileObject[0];
127
        }
127
//        }
128
128
//
129
        private class BrowseHostInfoDefinition extends SearchInfoDefinition {
129
//        private class BrowseHostInfoDefinition extends SearchInfoDefinition {
130
130
//
131
            private SearchInfo delegate;
131
//            private SearchInfo delegate;
132
132
//
133
            @Override
133
//            @Override
134
            public boolean canSearch() {
134
//            public boolean canSearch() {
135
                return true;
135
//                return true;
136
            }
136
//            }
137
137
//
138
            @Override
138
//            @Override
139
            public Iterator<FileObject> filesToSearch(SearchScopeOptions options, SearchListener listener, AtomicBoolean terminated) {
139
//            public Iterator<FileObject> filesToSearch(SearchScopeOptions options, SearchListener listener, AtomicBoolean terminated) {
140
                return getDelegate().getFilesToSearch(options, listener, terminated).iterator();
140
//                return getDelegate().getFilesToSearch(options, listener, terminated).iterator();
141
            }
141
//            }
142
142
//
143
            @Override
143
//            @Override
144
            public List<SearchRoot> getSearchRoots() {
144
//            public List<SearchRoot> getSearchRoots() {
145
                return getDelegate().getSearchRoots();
145
//                return getDelegate().getSearchRoots();
146
            }
146
//            }
147
147
//
148
            private synchronized SearchInfo getDelegate() {
148
//            private synchronized SearchInfo getDelegate() {
149
                if (delegate == null) {
149
//                if (delegate == null) {
150
                    delegate = createDelegate();
150
//                    delegate = createDelegate();
151
                }
151
//                }
152
                return delegate;
152
//                return delegate;
153
            }
153
//            }
154
154
//
155
            private SearchInfo createDelegate() {
155
//            private SearchInfo createDelegate() {
156
                FileObject[] fileObjects = chooseRoots();
156
//                FileObject[] fileObjects = chooseRoots();
157
                return SearchInfoUtils.createSearchInfoForRoots(fileObjects);
157
//                return SearchInfoUtils.createSearchInfoForRoots(fileObjects);
158
            }
158
//            }
159
        }
159
//        }
160
    }
160
//    }
161
161
//
162
    private class LastSearchBrowseHostScope extends SearchScopeDefinition {
162
//    private class LastSearchBrowseHostScope extends SearchScopeDefinition {
163
163
//
164
        @Override
164
//        @Override
165
        public String getTypeId() {
165
//        public String getTypeId() {
166
            return SearchBrowseHostScope.class.getName();
166
//            return SearchBrowseHostScope.class.getName();
167
        }
167
//        }
168
168
//
169
        @Override
169
//        @Override
170
        public String getDisplayName() {
170
//        public String getDisplayName() {
171
            if (root != null) {
171
//            if (root != null) {
172
                return NbBundle.getMessage(SearchBrowseHostScope.class, "LBL_BrowseHostScopeBrowseName", // NOI18N
172
//                return NbBundle.getMessage(SearchBrowseHostScope.class, "LBL_BrowseHostScopeBrowseName", // NOI18N
173
                        root.getNameExt(),
173
//                        root.getNameExt(),
174
                        FileSystemProvider.getExecutionEnvironment(root).getDisplayName());
174
//                        FileSystemProvider.getExecutionEnvironment(root).getDisplayName());
175
            } else {
175
//            } else {
176
                return NbBundle.getMessage(SearchBrowseHostScope.class, "LBL_NoSelection"); // NOI18N
176
//                return NbBundle.getMessage(SearchBrowseHostScope.class, "LBL_NoSelection"); // NOI18N
177
            }
177
//            }
178
        }
178
//        }
179
179
//
180
        @Override
180
//        @Override
181
        public boolean isApplicable() {
181
//        public boolean isApplicable() {
182
            return root != null;
182
//            return root != null;
183
        }
183
//        }
184
184
//
185
        @Override
185
//        @Override
186
        public SearchInfo getSearchInfo() {
186
//        public SearchInfo getSearchInfo() {
187
            return SearchInfoUtils.createSearchInfoForRoots(new FileObject[]{root});
187
//            return SearchInfoUtils.createSearchInfoForRoots(new FileObject[]{root});
188
        }
188
//        }
189
189
//
190
        @Override
190
//        @Override
191
        public int getPriority() {
191
//        public int getPriority() {
192
            return 700;
192
//            return 700;
193
        }
193
//        }
194
194
//
195
        @Override
195
//        @Override
196
        public void clean() {
196
//        public void clean() {
197
        }
197
//        }
198
    }
198
//    }
199
199
//
200
    public SearchScopeDefinition getBrowseScope() {
200
//    public SearchScopeDefinition getBrowseScope() {
201
        return browseScope;
201
//        return browseScope;
202
    }
202
//    }
203
203
//
204
    public SearchScopeDefinition getLastScope() {
204
//    public SearchScopeDefinition getLastScope() {
205
        return lastScope;
205
//        return lastScope;
206
    }
206
//    }
207
}
207
}
(-)a/cnd.search/src/org/netbeans/modules/cnd/search/impl/spi/CNDSearchComposition.java (-98 / +68 lines)
Lines 41-49 Link Here
41
 */
41
 */
42
package org.netbeans.modules.cnd.search.impl.spi;
42
package org.netbeans.modules.cnd.search.impl.spi;
43
43
44
import java.io.BufferedReader;
45
import java.io.IOException;
44
import java.io.IOException;
45
import java.util.Arrays;
46
import java.util.concurrent.ExecutionException;
47
import java.util.concurrent.Future;
46
import java.util.concurrent.atomic.AtomicBoolean;
48
import java.util.concurrent.atomic.AtomicBoolean;
49
import org.netbeans.api.extexecution.ExecutionService;
50
import org.netbeans.api.extexecution.input.LineProcessor;
47
import org.netbeans.api.search.SearchRoot;
51
import org.netbeans.api.search.SearchRoot;
48
import org.netbeans.api.search.provider.SearchListener;
52
import org.netbeans.api.search.provider.SearchListener;
49
import org.netbeans.modules.cnd.search.MatchingFileData;
53
import org.netbeans.modules.cnd.search.MatchingFileData;
Lines 54-65 Link Here
54
import org.netbeans.modules.cnd.search.ui.SearchResultNode;
58
import org.netbeans.modules.cnd.search.ui.SearchResultNode;
55
import org.netbeans.modules.cnd.search.ui.SearchResultPropertySet;
59
import org.netbeans.modules.cnd.search.ui.SearchResultPropertySet;
56
import org.netbeans.modules.cnd.search.util.OutlineSupport;
60
import org.netbeans.modules.cnd.search.util.OutlineSupport;
57
import org.netbeans.modules.nativeexecution.api.ExecutionEnvironment;
61
import org.netbeans.modules.cnd.execution.api.Connection;
58
import org.netbeans.modules.nativeexecution.api.NativeProcess;
62
import org.netbeans.modules.cnd.execution.util.HostInfo;
59
import org.netbeans.modules.nativeexecution.api.NativeProcessBuilder;
60
import org.netbeans.modules.nativeexecution.api.util.ConnectionManager;
61
import org.netbeans.modules.nativeexecution.api.util.HostInfoUtils;
62
import org.netbeans.modules.nativeexecution.api.util.ProcessUtils;
63
import org.netbeans.modules.remote.spi.FileSystemProvider;
63
import org.netbeans.modules.remote.spi.FileSystemProvider;
64
import org.netbeans.spi.search.provider.DefaultSearchResultsDisplayer;
64
import org.netbeans.spi.search.provider.DefaultSearchResultsDisplayer;
65
import org.netbeans.spi.search.provider.SearchComposition;
65
import org.netbeans.spi.search.provider.SearchComposition;
Lines 69-77 Link Here
69
import org.netbeans.spi.search.provider.SearchResultsDisplayer.NodeDisplayer;
69
import org.netbeans.spi.search.provider.SearchResultsDisplayer.NodeDisplayer;
70
import org.openide.explorer.view.OutlineView;
70
import org.openide.explorer.view.OutlineView;
71
import org.openide.nodes.Node;
71
import org.openide.nodes.Node;
72
import org.openide.util.Cancellable;
72
import org.openide.util.Exceptions;
73
import org.openide.util.RequestProcessor;
74
import org.openide.util.RequestProcessor.Task;
75
73
76
/**
74
/**
77
 *
75
 *
Lines 79-91 Link Here
79
 */
77
 */
80
public final class CNDSearchComposition extends SearchComposition<SearchResult> {
78
public final class CNDSearchComposition extends SearchComposition<SearchResult> {
81
79
82
    private static final RequestProcessor RP = new RequestProcessor(CNDSearchComposition.class.getName(), 2);
83
    private final AtomicBoolean terminated = new AtomicBoolean(false);
80
    private final AtomicBoolean terminated = new AtomicBoolean(false);
84
    private final SearchParams params;
81
    private final SearchParams params;
85
    private DefaultSearchResultsDisplayer<SearchResult> displayer;
82
    private DefaultSearchResultsDisplayer<SearchResult> displayer;
86
    private final String title;
83
    private final String title;
87
    private final Presenter presenter;
84
    private final Presenter presenter;
88
    private Cancellable cancel;
85
    private Future<?> task;
89
86
90
    public CNDSearchComposition(String title, SearchProvider.Presenter presenter, SearchParams params) {
87
    public CNDSearchComposition(String title, SearchProvider.Presenter presenter, SearchParams params) {
91
        this.title = title;
88
        this.title = title;
Lines 109-117 Link Here
109
    @Override
106
    @Override
110
    public void terminate() {
107
    public void terminate() {
111
        if (terminated.compareAndSet(false, true)) {
108
        if (terminated.compareAndSet(false, true)) {
112
            if (cancel != null) {
109
            if (task != null) {
113
                cancel.cancel();
110
                task.cancel(true);
114
                cancel = null;
111
                task = null;
115
            }
112
            }
116
        }
113
        }
117
    }
114
    }
Lines 134-235 Link Here
134
    }
131
    }
135
132
136
    private void searchInRoot(SearchRoot root, final SearchListener listener) {
133
    private void searchInRoot(SearchRoot root, final SearchListener listener) {
137
        if (isTerminated()) {
134
        final Connection connection = FileSystemProvider.getConnection(root.getFileObject());
138
            return;
135
        if (!connection.isConnected()) {
139
        }
140
141
        final ExecutionEnvironment env = FileSystemProvider.getExecutionEnvironment(root.getFileObject());
142
143
        if (!ConnectionManager.getInstance().isConnectedTo(env)) {
144
            return;
145
        }
146
147
        if (env.isRemote() && HostInfoUtils.isHostInfoAvailable(env)) {
148
            return;
136
            return;
149
        }
137
        }
150
138
151
        final Searcher find;
139
        final Searcher find;
152
        try {
140
153
            if (HostInfoUtils.getHostInfo(env).getOSFamily().isUnix()) {
141
        if (HostInfo.getFor(connection).isUnix()) {
154
                find = new UnixFindBasedSearcher(root, params);
142
            find = new UnixFindBasedSearcher(root, params);
155
            } else {
143
        } else {
156
                find = null;
144
            find = null;
157
            }
158
        } catch (Exception ex) {
159
            return;
160
        }
145
        }
161
146
162
        if (find == null) {
147
        if (find == null) {
163
            return;
148
            return;
164
        }
149
        }
165
150
166
        NativeProcessBuilder npb = NativeProcessBuilder.newProcessBuilder(env);
151
        try {
167
        npb.setExecutable(find.getCommand()).setArguments(find.getCommandArguments());
152
            final org.netbeans.api.extexecution.ProcessBuilder npb = connection.getProcessBuilder();
153
            npb.setExecutable(find.getCommand());
154
            npb.setArguments(Arrays.asList(find.getCommandArguments()));
155
            task = ExecutionService.newService(npb, new LineProcessor() {
156
                @Override
157
                public void processLine(String line) {
158
                    if (isTerminated()) {
159
                        task.cancel(true);
160
                    }
161
162
                    MatchingFileData data = find.processOutputLine(line.toString().trim());
163
164
                    if (data != null) {
165
                        displayer.addMatchingObject(new SearchResult(connection, data));
166
                    }
167
                }
168
                @Override
169
                public void reset() {
170
                }
171
172
                @Override
173
                public void close() {
174
                }
175
            }, new LineProcessor() {
176
                @Override
177
                public void processLine(String line) {
178
                    if (isTerminated()) {
179
                        task.cancel(true);
180
                    }
181
182
                    Throwable ex = new Throwable(line.toString());
183
                    listener.generalError(ex);
184
                }
185
                @Override
186
                public void reset() {
187
                }
188
189
                @Override
190
                public void close() {
191
                }
192
            }, null).run();
193
        } catch (IOException ex) {
194
            Exceptions.printStackTrace(ex);
195
        }
168
196
169
        try {
197
        try {
170
            final NativeProcess process = npb.call();
198
            task.get();
171
            final Runnable readOutputTask = new Runnable() {
172
173
                @Override
174
                public void run() {
175
                    try {
176
                        BufferedReader br = ProcessUtils.getReader(process.getInputStream(), env.isRemote());
177
                        String line;
178
                        while (!isTerminated() && (line = br.readLine()) != null) {
179
                            MatchingFileData data = find.processOutputLine(line.trim());
180
181
                            if (data != null) {
182
                                displayer.addMatchingObject(new SearchResult(env, data));
183
                            }
184
                        }
185
                    } catch (IOException ex) {
186
                        if (!isTerminated()) {
187
                            listener.generalError(ex);
188
                        }
189
                    }
190
                }
191
            };
192
193
            final Runnable readErrorTask = new Runnable() {
194
195
                @Override
196
                public void run() {
197
                    try {
198
                        BufferedReader br = ProcessUtils.getReader(process.getErrorStream(), env.isRemote());
199
                        String line;
200
                        while (!isTerminated() && (line = br.readLine()) != null) {
201
                            Throwable ex = new Throwable(line);
202
                            listener.generalError(ex);
203
                        }
204
                    } catch (IOException ex) {
205
                        if (!isTerminated()) {
206
                            listener.generalError(ex);
207
                        }
208
                    }
209
                }
210
            };
211
212
            final Task outTask = RP.post(readOutputTask);
213
            final Task errTask = RP.post(readErrorTask);
214
215
            cancel = new Cancellable() {
216
217
                @Override
218
                public boolean cancel() {
219
                    process.destroy();
220
                    outTask.cancel();
221
                    errTask.cancel();
222
                    outTask.waitFinished();
223
                    errTask.waitFinished();
224
                    return true;
225
                }
226
            };
227
228
            process.waitFor();
229
        } catch (InterruptedException ex) {
199
        } catch (InterruptedException ex) {
230
            // Exceptions.printStackTrace(ex);
200
            Exceptions.printStackTrace(ex);
231
        } catch (IOException ex) {
201
        } catch (ExecutionException ex) {
232
            listener.generalError(ex);
202
            Exceptions.printStackTrace(ex);
233
        }
203
        }
234
    }
204
    }
235
205
(-)a/cnd.search/src/org/netbeans/modules/cnd/search/ui/CNDSearchPanel.java (-10 / +8 lines)
Lines 55-63 Link Here
55
import org.netbeans.api.search.ui.FileNameController;
55
import org.netbeans.api.search.ui.FileNameController;
56
import org.netbeans.api.search.ui.ScopeController;
56
import org.netbeans.api.search.ui.ScopeController;
57
import org.netbeans.api.search.ui.SearchPatternController;
57
import org.netbeans.api.search.ui.SearchPatternController;
58
import org.netbeans.modules.cnd.search.impl.SearchBrowseHostScope;
59
import org.netbeans.modules.nativeexecution.api.ExecutionEnvironment;
60
import org.netbeans.modules.nativeexecution.api.util.ConnectionManager;
61
import org.netbeans.spi.search.SearchScopeDefinition;
58
import org.netbeans.spi.search.SearchScopeDefinition;
62
import org.openide.util.ChangeSupport;
59
import org.openide.util.ChangeSupport;
63
import org.openide.util.NbBundle;
60
import org.openide.util.NbBundle;
Lines 222-234 Link Here
222
    private SearchScopeDefinition[] getAdditionalSearchScopes() {
219
    private SearchScopeDefinition[] getAdditionalSearchScopes() {
223
        List<SearchScopeDefinition> result = new ArrayList<SearchScopeDefinition>();
220
        List<SearchScopeDefinition> result = new ArrayList<SearchScopeDefinition>();
224
221
225
        List<ExecutionEnvironment> recentConnections = ConnectionManager.getInstance().getRecentConnections();
222
//        ConnectionManager.
226
223
//        List<ExecutionEnvironment> recentConnections = ConnectionManager.getInstance().getRecentConnections();
227
        for (ExecutionEnvironment env : recentConnections) {
224
//
228
            SearchBrowseHostScope scope = new SearchBrowseHostScope(env);
225
//        for (ExecutionEnvironment env : recentConnections) {
229
            result.add(scope.getBrowseScope());
226
//            SearchBrowseHostScope scope = new SearchBrowseHostScope(env);
230
            result.add(scope.getLastScope());
227
//            result.add(scope.getBrowseScope());
231
        }
228
//            result.add(scope.getLastScope());
229
//        }
232
230
233
        return result.toArray(new SearchScopeDefinition[result.size()]);
231
        return result.toArray(new SearchScopeDefinition[result.size()]);
234
    }
232
    }
(-)a/cnd.search/src/org/netbeans/modules/cnd/search/ui/DirectoryChooser.java (-6 / +6 lines)
Lines 50-56 Link Here
50
import java.io.File;
50
import java.io.File;
51
import javax.swing.*;
51
import javax.swing.*;
52
import javax.swing.filechooser.FileFilter;
52
import javax.swing.filechooser.FileFilter;
53
import org.netbeans.modules.nativeexecution.api.ExecutionEnvironment;
53
import org.netbeans.modules.cnd.execution.api.Connection;
54
import org.netbeans.modules.remote.api.ui.FileChooserBuilder;
54
import org.netbeans.modules.remote.api.ui.FileChooserBuilder;
55
import org.netbeans.modules.remote.spi.FileSystemProvider;
55
import org.netbeans.modules.remote.spi.FileSystemProvider;
56
import org.openide.DialogDescriptor;
56
import org.openide.DialogDescriptor;
Lines 71-82 Link Here
71
    private FileObject validatedFileObject = null;
71
    private FileObject validatedFileObject = null;
72
    private Dialog dialog;
72
    private Dialog dialog;
73
73
74
    public static FileObject chooseDirectory(Frame window, ExecutionEnvironment env, String initPath) {
74
    public static FileObject chooseDirectory(Frame window, Connection connection, String initPath) {
75
        DirectoryChooser chooser = new DirectoryChooser(env, initPath);
75
        DirectoryChooser chooser = new DirectoryChooser(connection, initPath);
76
        boolean cancelled = false;
76
        boolean cancelled = false;
77
77
78
        DialogDescriptor dd = new DialogDescriptor(chooser,
78
        DialogDescriptor dd = new DialogDescriptor(chooser,
79
                NbBundle.getMessage(DirectoryChooser.class, "DirectoryChooser.title", env.getDisplayName()), // NOI18N
79
                NbBundle.getMessage(DirectoryChooser.class, "DirectoryChooser.title", connection.toString()), // NOI18N
80
                true,
80
                true,
81
                new Object[]{chooser.selectButton, DialogDescriptor.CANCEL_OPTION},
81
                new Object[]{chooser.selectButton, DialogDescriptor.CANCEL_OPTION},
82
                chooser.selectButton, DialogDescriptor.DEFAULT_ALIGN, null, null, true);
82
                chooser.selectButton, DialogDescriptor.DEFAULT_ALIGN, null, null, true);
Lines 96-106 Link Here
96
    /**
96
    /**
97
     * Creates new form SearchRootChooser
97
     * Creates new form SearchRootChooser
98
     */
98
     */
99
    private DirectoryChooser(ExecutionEnvironment env, String path) {
99
    private DirectoryChooser(Connection connection, String path) {
100
        initComponents();
100
        initComponents();
101
        selectButton = new JButton();
101
        selectButton = new JButton();
102
        Mnemonics.setLocalizedText(selectButton, NbBundle.getMessage(DirectoryChooser.class, "DirectoryChooser.ok_button.text")); // NOI18N
102
        Mnemonics.setLocalizedText(selectButton, NbBundle.getMessage(DirectoryChooser.class, "DirectoryChooser.ok_button.text")); // NOI18N
103
        FileChooserBuilder fcBuilder = new FileChooserBuilder(env);
103
        FileChooserBuilder fcBuilder = new FileChooserBuilder(connection);
104
104
105
        chooser = fcBuilder.createFileChooser();
105
        chooser = fcBuilder.createFileChooser();
106
        chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
106
        chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
(-)a/cnd.search/src/org/netbeans/modules/cnd/search/ui/SearchResultNode.java (-2 / +2 lines)
Lines 97-104 Link Here
97
    public Image getIcon(int type) {
97
    public Image getIcon(int type) {
98
        Object dobRefProp = getValue(DOB_REF_PROP);
98
        Object dobRefProp = getValue(DOB_REF_PROP);
99
        if (dobRefProp instanceof WeakReference) {
99
        if (dobRefProp instanceof WeakReference) {
100
            WeakReference<DataObject> dobRef = (WeakReference<DataObject>)dobRefProp;
100
            WeakReference<?> dobRef = (WeakReference<?>)dobRefProp;
101
            DataObject dob = dobRef.get();
101
            DataObject dob = (DataObject) dobRef.get();
102
            if (dob != null) {
102
            if (dob != null) {
103
                return dob.getNodeDelegate().getIcon(type);
103
                return dob.getNodeDelegate().getIcon(type);
104
            }
104
            }
(-)a/cnd.toolchain/nbproject/project.xml (+8 lines)
Lines 91-96 Link Here
91
                    </run-dependency>
91
                    </run-dependency>
92
                </dependency>
92
                </dependency>
93
                <dependency>
93
                <dependency>
94
                    <code-name-base>org.netbeans.modules.cnd.execution</code-name-base>
95
                    <build-prerequisite/>
96
                    <compile-dependency/>
97
                    <run-dependency>
98
                        <specification-version>1.0</specification-version>
99
                    </run-dependency>
100
                </dependency>
101
                <dependency>
94
                    <code-name-base>org.netbeans.modules.options.api</code-name-base>
102
                    <code-name-base>org.netbeans.modules.options.api</code-name-base>
95
                    <build-prerequisite/>
103
                    <build-prerequisite/>
96
                    <compile-dependency/>
104
                    <compile-dependency/>
(-)a/dlight.nativeexecution/external/binaries-list (-1 / +1 lines)
Lines 1-2 Link Here
1
886018BFD299115709FB351D28D9C1F5A2C6F5FD exechlp-1.0.zip
1
7AA7A8C9DA31FCB920B0613EC8C49229801FB6C6 exechlp-1.1.zip
2
2
(-)a/dlight.nativeexecution/external/exechlp-1.0-license.txt (-19 lines)
Lines 1-19 Link Here
1
Name: exechlp
2
Version: 1.0
3
Description: binaries that used by dlight.nativeexecution module
4
License: TBD
5
OSR: -
6
Origin: -
7
Files: exechlp-1.0.zip contains killall process_start pty pty_open sigqueue stat unbuffer.so for different platforms
8
Source: -
9
Comment: needed for dlight.nativeexecution module to provide system-dependent services
10
11
process_start, pty, pty_open - used for dealing with pseude terminals
12
sigqueue, killall - sending signals to processes
13
stat - getting detailed file information
14
unbuffer.so - used when unbuffering is required
15
16
Use of exechlp version 1.0 is governed by the terms of the license below:
17
18
TBD
19
(-)a/dlight.nativeexecution/external/exechlp-1.1-license.txt (+19 lines)
Line 0 Link Here
1
Name: exechlp
2
Version: 1.1
3
Description: binaries that used by dlight.nativeexecution module
4
License: TBD
5
OSR: -
6
Origin: -
7
Files: exechlp-1.1.zip contains killall process_start pty pty_open sigqueue stat unbuffer.so for different platforms
8
Source: -
9
Comment: needed for dlight.nativeexecution module to provide system-dependent services
10
11
process_start, pty, pty_open - used for dealing with pseude terminals
12
sigqueue, killall - sending signals to processes
13
stat - getting detailed file information
14
unbuffer.so - used when unbuffering is required
15
16
Use of exechlp version 1.1 is governed by the terms of the license below:
17
18
TBD
19
(-)a/dlight.nativeexecution/nbproject/project.properties (-68 / +68 lines)
Lines 21-92 Link Here
21
    **/RegisterDerbyTest.class,\
21
    **/RegisterDerbyTest.class,\
22
    **/TerminalConfigurationProviderTest.class
22
    **/TerminalConfigurationProviderTest.class
23
23
24
release.external/exechlp-1.0.zip!/Linux-x86/process_start       = bin/nativeexecution/Linux-x86/process_start
24
release.external/exechlp-1.1.zip!/Linux-x86/process_start       = bin/nativeexecution/Linux-x86/process_start
25
release.external/exechlp-1.0.zip!/Linux-x86/pty                 = bin/nativeexecution/Linux-x86/pty
25
release.external/exechlp-1.1.zip!/Linux-x86/pty                 = bin/nativeexecution/Linux-x86/pty
26
release.external/exechlp-1.0.zip!/Linux-x86/pty_open            = bin/nativeexecution/Linux-x86/pty_open
26
release.external/exechlp-1.1.zip!/Linux-x86/pty_open            = bin/nativeexecution/Linux-x86/pty_open
27
release.external/exechlp-1.0.zip!/Linux-x86/sigqueue            = bin/nativeexecution/Linux-x86/sigqueue
27
release.external/exechlp-1.1.zip!/Linux-x86/sigqueue            = bin/nativeexecution/Linux-x86/sigqueue
28
release.external/exechlp-1.0.zip!/Linux-x86/stat                = bin/nativeexecution/Linux-x86/stat
28
release.external/exechlp-1.1.zip!/Linux-x86/stat                = bin/nativeexecution/Linux-x86/stat
29
release.external/exechlp-1.0.zip!/Linux-x86/unbuffer.so         = bin/nativeexecution/Linux-x86/unbuffer.so
29
release.external/exechlp-1.1.zip!/Linux-x86/unbuffer.so         = bin/nativeexecution/Linux-x86/unbuffer.so
30
release.external/exechlp-1.0.zip!/Linux-x86/killall             = bin/nativeexecution/Linux-x86/killall
30
release.external/exechlp-1.1.zip!/Linux-x86/killall             = bin/nativeexecution/Linux-x86/killall
31
release.external/exechlp-1.0.zip!/Linux-x86_64/process_start    = bin/nativeexecution/Linux-x86_64/process_start
31
release.external/exechlp-1.1.zip!/Linux-x86_64/process_start    = bin/nativeexecution/Linux-x86_64/process_start
32
release.external/exechlp-1.0.zip!/Linux-x86_64/pty              = bin/nativeexecution/Linux-x86_64/pty
32
release.external/exechlp-1.1.zip!/Linux-x86_64/pty              = bin/nativeexecution/Linux-x86_64/pty
33
release.external/exechlp-1.0.zip!/Linux-x86_64/pty_open         = bin/nativeexecution/Linux-x86_64/pty_open
33
release.external/exechlp-1.1.zip!/Linux-x86_64/pty_open         = bin/nativeexecution/Linux-x86_64/pty_open
34
release.external/exechlp-1.0.zip!/Linux-x86_64/sigqueue         = bin/nativeexecution/Linux-x86_64/sigqueue
34
release.external/exechlp-1.1.zip!/Linux-x86_64/sigqueue         = bin/nativeexecution/Linux-x86_64/sigqueue
35
release.external/exechlp-1.0.zip!/Linux-x86_64/stat             = bin/nativeexecution/Linux-x86_64/stat
35
release.external/exechlp-1.1.zip!/Linux-x86_64/stat             = bin/nativeexecution/Linux-x86_64/stat
36
release.external/exechlp-1.0.zip!/Linux-x86_64/unbuffer.so      = bin/nativeexecution/Linux-x86_64/unbuffer.so
36
release.external/exechlp-1.1.zip!/Linux-x86_64/unbuffer.so      = bin/nativeexecution/Linux-x86_64/unbuffer.so
37
release.external/exechlp-1.0.zip!/Linux-x86_64/killall          = bin/nativeexecution/Linux-x86_64/killall
37
release.external/exechlp-1.1.zip!/Linux-x86_64/killall          = bin/nativeexecution/Linux-x86_64/killall
38
release.external/exechlp-1.0.zip!/Windows-x86/process_start     = bin/nativeexecution/Windows-x86/process_start
38
release.external/exechlp-1.1.zip!/Windows-x86/process_start     = bin/nativeexecution/Windows-x86/process_start
39
release.external/exechlp-1.0.zip!/Windows-x86/pty               = bin/nativeexecution/Windows-x86/pty
39
release.external/exechlp-1.1.zip!/Windows-x86/pty               = bin/nativeexecution/Windows-x86/pty
40
release.external/exechlp-1.0.zip!/Windows-x86/pty_open          = bin/nativeexecution/Windows-x86/pty_open
40
release.external/exechlp-1.1.zip!/Windows-x86/pty_open          = bin/nativeexecution/Windows-x86/pty_open
41
release.external/exechlp-1.0.zip!/Windows-x86/sigqueue          = bin/nativeexecution/Windows-x86/sigqueue
41
release.external/exechlp-1.1.zip!/Windows-x86/sigqueue          = bin/nativeexecution/Windows-x86/sigqueue
42
release.external/exechlp-1.0.zip!/Windows-x86/unbuffer.dll      = bin/nativeexecution/Windows-x86/unbuffer.dll
42
release.external/exechlp-1.1.zip!/Windows-x86/unbuffer.dll      = bin/nativeexecution/Windows-x86/unbuffer.dll
43
release.external/exechlp-1.0.zip!/Windows-x86/killall           = bin/nativeexecution/Windows-x86/killall
43
release.external/exechlp-1.1.zip!/Windows-x86/killall           = bin/nativeexecution/Windows-x86/killall
44
release.external/exechlp-1.0.zip!/Windows-x86_64/process_start  = bin/nativeexecution/Windows-x86_64/process_start
44
release.external/exechlp-1.1.zip!/Windows-x86_64/process_start  = bin/nativeexecution/Windows-x86_64/process_start
45
release.external/exechlp-1.0.zip!/Windows-x86_64/pty            = bin/nativeexecution/Windows-x86_64/pty
45
release.external/exechlp-1.1.zip!/Windows-x86_64/pty            = bin/nativeexecution/Windows-x86_64/pty
46
release.external/exechlp-1.0.zip!/Windows-x86_64/pty_open       = bin/nativeexecution/Windows-x86_64/pty_open
46
release.external/exechlp-1.1.zip!/Windows-x86_64/pty_open       = bin/nativeexecution/Windows-x86_64/pty_open
47
release.external/exechlp-1.0.zip!/Windows-x86_64/sigqueue       = bin/nativeexecution/Windows-x86_64/sigqueue
47
release.external/exechlp-1.1.zip!/Windows-x86_64/sigqueue       = bin/nativeexecution/Windows-x86_64/sigqueue
48
release.external/exechlp-1.0.zip!/Windows-x86_64/killall        = bin/nativeexecution/Windows-x86_64/killall
48
release.external/exechlp-1.1.zip!/Windows-x86_64/killall        = bin/nativeexecution/Windows-x86_64/killall
49
release.external/exechlp-1.0.zip!/MacOSX-x86/process_start      = bin/nativeexecution/MacOSX-x86/process_start
49
release.external/exechlp-1.1.zip!/MacOSX-x86/process_start      = bin/nativeexecution/MacOSX-x86/process_start
50
release.external/exechlp-1.0.zip!/MacOSX-x86/pty                = bin/nativeexecution/MacOSX-x86/pty
50
release.external/exechlp-1.1.zip!/MacOSX-x86/pty                = bin/nativeexecution/MacOSX-x86/pty
51
release.external/exechlp-1.0.zip!/MacOSX-x86/pty_open           = bin/nativeexecution/MacOSX-x86/pty_open
51
release.external/exechlp-1.1.zip!/MacOSX-x86/pty_open           = bin/nativeexecution/MacOSX-x86/pty_open
52
release.external/exechlp-1.0.zip!/MacOSX-x86/stat               = bin/nativeexecution/MacOSX-x86/stat
52
release.external/exechlp-1.1.zip!/MacOSX-x86/stat               = bin/nativeexecution/MacOSX-x86/stat
53
release.external/exechlp-1.0.zip!/MacOSX-x86/unbuffer.dylib     = bin/nativeexecution/MacOSX-x86/unbuffer.dylib
53
release.external/exechlp-1.1.zip!/MacOSX-x86/unbuffer.dylib     = bin/nativeexecution/MacOSX-x86/unbuffer.dylib
54
release.external/exechlp-1.0.zip!/MacOSX-x86/killall            = bin/nativeexecution/MacOSX-x86/killall
54
release.external/exechlp-1.1.zip!/MacOSX-x86/killall            = bin/nativeexecution/MacOSX-x86/killall
55
release.external/exechlp-1.0.zip!/MacOSX-x86_64/process_start   = bin/nativeexecution/MacOSX-x86_64/process_start
55
release.external/exechlp-1.1.zip!/MacOSX-x86_64/process_start   = bin/nativeexecution/MacOSX-x86_64/process_start
56
release.external/exechlp-1.0.zip!/MacOSX-x86_64/pty             = bin/nativeexecution/MacOSX-x86_64/pty
56
release.external/exechlp-1.1.zip!/MacOSX-x86_64/pty             = bin/nativeexecution/MacOSX-x86_64/pty
57
release.external/exechlp-1.0.zip!/MacOSX-x86_64/pty_open        = bin/nativeexecution/MacOSX-x86_64/pty_open
57
release.external/exechlp-1.1.zip!/MacOSX-x86_64/pty_open        = bin/nativeexecution/MacOSX-x86_64/pty_open
58
release.external/exechlp-1.0.zip!/MacOSX-x86_64/stat            = bin/nativeexecution/MacOSX-x86_64/stat
58
release.external/exechlp-1.1.zip!/MacOSX-x86_64/stat            = bin/nativeexecution/MacOSX-x86_64/stat
59
release.external/exechlp-1.0.zip!/MacOSX-x86_64/unbuffer.dylib  = bin/nativeexecution/MacOSX-x86_64/unbuffer.dylib
59
release.external/exechlp-1.1.zip!/MacOSX-x86_64/unbuffer.dylib  = bin/nativeexecution/MacOSX-x86_64/unbuffer.dylib
60
release.external/exechlp-1.0.zip!/MacOSX-x86_64/killall         = bin/nativeexecution/MacOSX-x86_64/killall
60
release.external/exechlp-1.1.zip!/MacOSX-x86_64/killall         = bin/nativeexecution/MacOSX-x86_64/killall
61
release.external/exechlp-1.0.zip!/SunOS-sparc/privp             = bin/nativeexecution/SunOS-sparc/privp
61
release.external/exechlp-1.1.zip!/SunOS-sparc/privp             = bin/nativeexecution/SunOS-sparc/privp
62
release.external/exechlp-1.0.zip!/SunOS-sparc/process_start     = bin/nativeexecution/SunOS-sparc/process_start
62
release.external/exechlp-1.1.zip!/SunOS-sparc/process_start     = bin/nativeexecution/SunOS-sparc/process_start
63
release.external/exechlp-1.0.zip!/SunOS-sparc/pty               = bin/nativeexecution/SunOS-sparc/pty
63
release.external/exechlp-1.1.zip!/SunOS-sparc/pty               = bin/nativeexecution/SunOS-sparc/pty
64
release.external/exechlp-1.0.zip!/SunOS-sparc/pty_open          = bin/nativeexecution/SunOS-sparc/pty_open
64
release.external/exechlp-1.1.zip!/SunOS-sparc/pty_open          = bin/nativeexecution/SunOS-sparc/pty_open
65
release.external/exechlp-1.0.zip!/SunOS-sparc/sigqueue          = bin/nativeexecution/SunOS-sparc/sigqueue
65
release.external/exechlp-1.1.zip!/SunOS-sparc/sigqueue          = bin/nativeexecution/SunOS-sparc/sigqueue
66
release.external/exechlp-1.0.zip!/SunOS-sparc/stat              = bin/nativeexecution/SunOS-sparc/stat
66
release.external/exechlp-1.1.zip!/SunOS-sparc/stat              = bin/nativeexecution/SunOS-sparc/stat
67
release.external/exechlp-1.0.zip!/SunOS-sparc/unbuffer.so       = bin/nativeexecution/SunOS-sparc/unbuffer.so
67
release.external/exechlp-1.1.zip!/SunOS-sparc/unbuffer.so       = bin/nativeexecution/SunOS-sparc/unbuffer.so
68
release.external/exechlp-1.0.zip!/SunOS-sparc/killall           = bin/nativeexecution/SunOS-sparc/killall
68
release.external/exechlp-1.1.zip!/SunOS-sparc/killall           = bin/nativeexecution/SunOS-sparc/killall
69
release.external/exechlp-1.0.zip!/SunOS-sparc_64/privp          = bin/nativeexecution/SunOS-sparc_64/privp
69
release.external/exechlp-1.1.zip!/SunOS-sparc_64/privp          = bin/nativeexecution/SunOS-sparc_64/privp
70
release.external/exechlp-1.0.zip!/SunOS-sparc_64/process_start  = bin/nativeexecution/SunOS-sparc_64/process_start
70
release.external/exechlp-1.1.zip!/SunOS-sparc_64/process_start  = bin/nativeexecution/SunOS-sparc_64/process_start
71
release.external/exechlp-1.0.zip!/SunOS-sparc_64/pty            = bin/nativeexecution/SunOS-sparc_64/pty
71
release.external/exechlp-1.1.zip!/SunOS-sparc_64/pty            = bin/nativeexecution/SunOS-sparc_64/pty
72
release.external/exechlp-1.0.zip!/SunOS-sparc_64/pty_open       = bin/nativeexecution/SunOS-sparc_64/pty_open
72
release.external/exechlp-1.1.zip!/SunOS-sparc_64/pty_open       = bin/nativeexecution/SunOS-sparc_64/pty_open
73
release.external/exechlp-1.0.zip!/SunOS-sparc_64/sigqueue       = bin/nativeexecution/SunOS-sparc_64/sigqueue
73
release.external/exechlp-1.1.zip!/SunOS-sparc_64/sigqueue       = bin/nativeexecution/SunOS-sparc_64/sigqueue
74
release.external/exechlp-1.0.zip!/SunOS-sparc_64/stat           = bin/nativeexecution/SunOS-sparc_64/stat
74
release.external/exechlp-1.1.zip!/SunOS-sparc_64/stat           = bin/nativeexecution/SunOS-sparc_64/stat
75
release.external/exechlp-1.0.zip!/SunOS-sparc_64/unbuffer.so    = bin/nativeexecution/SunOS-sparc_64/unbuffer.so
75
release.external/exechlp-1.1.zip!/SunOS-sparc_64/unbuffer.so    = bin/nativeexecution/SunOS-sparc_64/unbuffer.so
76
release.external/exechlp-1.0.zip!/SunOS-sparc_64/killall        = bin/nativeexecution/SunOS-sparc_64/killall
76
release.external/exechlp-1.1.zip!/SunOS-sparc_64/killall        = bin/nativeexecution/SunOS-sparc_64/killall
77
release.external/exechlp-1.0.zip!/SunOS-x86/privp               = bin/nativeexecution/SunOS-x86/privp
77
release.external/exechlp-1.1.zip!/SunOS-x86/privp               = bin/nativeexecution/SunOS-x86/privp
78
release.external/exechlp-1.0.zip!/SunOS-x86/process_start       = bin/nativeexecution/SunOS-x86/process_start
78
release.external/exechlp-1.1.zip!/SunOS-x86/process_start       = bin/nativeexecution/SunOS-x86/process_start
79
release.external/exechlp-1.0.zip!/SunOS-x86/pty                 = bin/nativeexecution/SunOS-x86/pty
79
release.external/exechlp-1.1.zip!/SunOS-x86/pty                 = bin/nativeexecution/SunOS-x86/pty
80
release.external/exechlp-1.0.zip!/SunOS-x86/pty_open            = bin/nativeexecution/SunOS-x86/pty_open
80
release.external/exechlp-1.1.zip!/SunOS-x86/pty_open            = bin/nativeexecution/SunOS-x86/pty_open
81
release.external/exechlp-1.0.zip!/SunOS-x86/sigqueue            = bin/nativeexecution/SunOS-x86/sigqueue
81
release.external/exechlp-1.1.zip!/SunOS-x86/sigqueue            = bin/nativeexecution/SunOS-x86/sigqueue
82
release.external/exechlp-1.0.zip!/SunOS-x86/stat                = bin/nativeexecution/SunOS-x86/stat
82
release.external/exechlp-1.1.zip!/SunOS-x86/stat                = bin/nativeexecution/SunOS-x86/stat
83
release.external/exechlp-1.0.zip!/SunOS-x86/unbuffer.so         = bin/nativeexecution/SunOS-x86/unbuffer.so
83
release.external/exechlp-1.1.zip!/SunOS-x86/unbuffer.so         = bin/nativeexecution/SunOS-x86/unbuffer.so
84
release.external/exechlp-1.0.zip!/SunOS-x86/killall             = bin/nativeexecution/SunOS-x86/killall
84
release.external/exechlp-1.1.zip!/SunOS-x86/killall             = bin/nativeexecution/SunOS-x86/killall
85
release.external/exechlp-1.0.zip!/SunOS-x86_64/process_start    = bin/nativeexecution/SunOS-x86_64/process_start
85
release.external/exechlp-1.1.zip!/SunOS-x86_64/process_start    = bin/nativeexecution/SunOS-x86_64/process_start
86
release.external/exechlp-1.0.zip!/SunOS-x86_64/pty              = bin/nativeexecution/SunOS-x86_64/pty
86
release.external/exechlp-1.1.zip!/SunOS-x86_64/pty              = bin/nativeexecution/SunOS-x86_64/pty
87
release.external/exechlp-1.0.zip!/SunOS-x86_64/pty_open         = bin/nativeexecution/SunOS-x86_64/pty_open
87
release.external/exechlp-1.1.zip!/SunOS-x86_64/pty_open         = bin/nativeexecution/SunOS-x86_64/pty_open
88
release.external/exechlp-1.0.zip!/SunOS-x86_64/sigqueue         = bin/nativeexecution/SunOS-x86_64/sigqueue
88
release.external/exechlp-1.1.zip!/SunOS-x86_64/sigqueue         = bin/nativeexecution/SunOS-x86_64/sigqueue
89
release.external/exechlp-1.0.zip!/SunOS-x86_64/stat             = bin/nativeexecution/SunOS-x86_64/stat
89
release.external/exechlp-1.1.zip!/SunOS-x86_64/stat             = bin/nativeexecution/SunOS-x86_64/stat
90
release.external/exechlp-1.0.zip!/SunOS-x86_64/unbuffer.so      = bin/nativeexecution/SunOS-x86_64/unbuffer.so
90
release.external/exechlp-1.1.zip!/SunOS-x86_64/unbuffer.so      = bin/nativeexecution/SunOS-x86_64/unbuffer.so
91
release.external/exechlp-1.0.zip!/SunOS-x86_64/killall          = bin/nativeexecution/SunOS-x86_64/killall
91
release.external/exechlp-1.1.zip!/SunOS-x86_64/killall          = bin/nativeexecution/SunOS-x86_64/killall
92
92
(-)a/dlight.nativeexecution/nbproject/project.xml (-1 / +3 lines)
Lines 54-60 Link Here
54
                    <compile-dependency/>
54
                    <compile-dependency/>
55
                    <run-dependency>
55
                    <run-dependency>
56
                        <release-version>2</release-version>
56
                        <release-version>2</release-version>
57
                        <specification-version>1.13</specification-version>
57
                        <specification-version>1.37</specification-version>
58
                    </run-dependency>
58
                    </run-dependency>
59
                </dependency>
59
                </dependency>
60
                <dependency>
60
                <dependency>
Lines 276-281 Link Here
276
                <friend>org.netbeans.modules.dlight.uncover</friend>
276
                <friend>org.netbeans.modules.dlight.uncover</friend>
277
                <friend>org.netbeans.modules.dlight.util</friend>
277
                <friend>org.netbeans.modules.dlight.util</friend>
278
                <friend>org.netbeans.modules.dlight.webstack</friend>
278
                <friend>org.netbeans.modules.dlight.webstack</friend>
279
                <friend>org.netbeans.modules.execmerge</friend>
280
                <friend>org.netbeans.modules.nativeexecution.impl</friend>
279
                <friend>org.netbeans.nativeexecution.terminal</friend>
281
                <friend>org.netbeans.nativeexecution.terminal</friend>
280
                <package>org.netbeans.modules.nativeexecution.api</package>
282
                <package>org.netbeans.modules.nativeexecution.api</package>
281
                <package>org.netbeans.modules.nativeexecution.api.execution</package>
283
                <package>org.netbeans.modules.nativeexecution.api.execution</package>
(-)a/dlight.nativeexecution/src/org/netbeans/modules/nativeexecution/AbstractNativeProcess.java (-1 / +64 lines)
Lines 47-52 Link Here
47
import java.io.InputStream;
47
import java.io.InputStream;
48
import java.io.InterruptedIOException;
48
import java.io.InterruptedIOException;
49
import java.io.OutputStream;
49
import java.io.OutputStream;
50
import java.nio.charset.Charset;
50
import java.util.Arrays;
51
import java.util.Arrays;
51
import java.util.Collection;
52
import java.util.Collection;
52
import java.util.concurrent.Callable;
53
import java.util.concurrent.Callable;
Lines 59-64 Link Here
59
import java.util.logging.Level;
60
import java.util.logging.Level;
60
import javax.swing.event.ChangeEvent;
61
import javax.swing.event.ChangeEvent;
61
import javax.swing.event.ChangeListener;
62
import javax.swing.event.ChangeListener;
63
import org.netbeans.api.extexecution.process.ProcessCharset;
64
import org.netbeans.api.extexecution.process.ProcessId;
65
import org.netbeans.api.extexecution.process.ProcessSignal;
62
import org.netbeans.modules.nativeexecution.api.ExecutionEnvironment;
66
import org.netbeans.modules.nativeexecution.api.ExecutionEnvironment;
63
import org.netbeans.modules.nativeexecution.api.HostInfo;
67
import org.netbeans.modules.nativeexecution.api.HostInfo;
64
import org.netbeans.modules.nativeexecution.api.NativeProcess;
68
import org.netbeans.modules.nativeexecution.api.NativeProcess;
Lines 77-84 Link Here
77
import org.openide.util.Exceptions;
81
import org.openide.util.Exceptions;
78
import org.openide.util.Lookup;
82
import org.openide.util.Lookup;
79
import org.openide.util.NbBundle;
83
import org.openide.util.NbBundle;
84
import org.openide.util.lookup.Lookups;
80
85
81
public abstract class AbstractNativeProcess extends NativeProcess implements ExProcessInfoProvider {
86
public abstract class AbstractNativeProcess extends NativeProcess implements ExProcessInfoProvider, Lookup.Provider {
82
87
83
    protected final static java.util.logging.Logger LOG = Logger.getInstance();
88
    protected final static java.util.logging.Logger LOG = Logger.getInstance();
84
    private final static Integer PID_TIMEOUT =
89
    private final static Integer PID_TIMEOUT =
Lines 96-101 Link Here
96
    // Immutable listeners list.
101
    // Immutable listeners list.
97
    private final Collection<ChangeListener> listeners;
102
    private final Collection<ChangeListener> listeners;
98
    private final Object stateLock;
103
    private final Object stateLock;
104
105
    private final ProcessId processId = new ProcessId() {
106
        @Override
107
        protected Integer getId() {
108
            try {
109
                return getPID();
110
            } catch (IOException ex) {
111
                LOG.log(Level.INFO, null, ex);
112
            }
113
            return null;
114
        }
115
    };
116
    private final ProcessCharset processCharset = new ProcessCharset() {
117
118
        @Override
119
        protected Charset getInputCharset() {
120
            return info.getCharset();
121
        }
122
123
        @Override
124
        protected Charset getOutputCharset() {
125
            return info.getCharset();
126
        }
127
128
        @Override
129
        protected Charset getErrorCharset() {
130
            return info.getCharset();
131
        }
132
        
133
    };
134
    private final ProcessSignal processSignal = new ProcessSignal() {
135
136
        @Override
137
        protected void signal(ProcessSignal.Signal signal) throws IOException {
138
            try {
139
                SignalSupport.signalProcess(execEnv, getPID(),
140
                        SignalSupport.translate(signal));
141
            } catch (UnsupportedOperationException ex) {
142
                throw new IOException(ex);
143
            }
144
        }
145
146
        @Override
147
        protected void signalGroup(ProcessSignal.Signal signal) throws IOException {
148
            try {
149
                SignalSupport.signalProcessGroup(execEnv, getPID(),
150
                        SignalSupport.translate(signal));
151
            } catch (UnsupportedOperationException ex) {
152
                throw new IOException(ex);
153
            }
154
        }
155
    };
156
99
    private volatile State state;
157
    private volatile State state;
100
    private volatile int pid = 0;
158
    private volatile int pid = 0;
101
    private volatile boolean isInterrupted;
159
    private volatile boolean isInterrupted;
Lines 142-147 Link Here
142
        listeners = info.getListenersSnapshot();
200
        listeners = info.getListenersSnapshot();
143
    }
201
    }
144
202
203
    @Override
204
    public final Lookup getLookup() {
205
        return Lookups.fixed(processId, processCharset, processSignal);
206
    }
207
145
    public final NativeProcess createAndStart() {
208
    public final NativeProcess createAndStart() {
146
        try {
209
        try {
147
            if (hostInfo == null) {
210
            if (hostInfo == null) {
(-)a/dlight.nativeexecution/src/org/netbeans/modules/nativeexecution/api/util/Signal.java (-45 / +55 lines)
Lines 41-46 Link Here
41
 */
41
 */
42
package org.netbeans.modules.nativeexecution.api.util;
42
package org.netbeans.modules.nativeexecution.api.util;
43
43
44
import org.netbeans.api.extexecution.process.ProcessSignal;
45
44
/**
46
/**
45
 *
47
 *
46
 * @author ak119685
48
 * @author ak119685
Lines 48-101 Link Here
48
public enum Signal {
50
public enum Signal {
49
    // IDs are taken from signal_iso.h on Solaris
51
    // IDs are taken from signal_iso.h on Solaris
50
52
51
    NULL(0),
53
    NULL(0, ProcessSignal.Signal.NULL),
52
    SIGHUP(1),
54
    SIGHUP(1, ProcessSignal.Signal.SIGHUP),
53
    SIGINT(2),
55
    SIGINT(2, ProcessSignal.Signal.SIGINT),
54
    SIGQUIT(3),
56
    SIGQUIT(3, ProcessSignal.Signal.SIGQUIT),
55
    SIGILL(4),
57
    SIGILL(4, ProcessSignal.Signal.SIGILL),
56
    SIGTRAP(5),
58
    SIGTRAP(5, ProcessSignal.Signal.SIGTRAP),
57
    SIGIOT(6),
59
    SIGIOT(6, null),
58
    SIGABRT(6),
60
    SIGABRT(6, ProcessSignal.Signal.SIGABRT),
59
    SIGEMT(7),
61
    SIGEMT(7, ProcessSignal.Signal.SIGEMT),
60
    SIGFPE(8),
62
    SIGFPE(8, ProcessSignal.Signal.SIGFPE),
61
    SIGKILL(9),
63
    SIGKILL(9, ProcessSignal.Signal.SIGKILL),
62
    SIGBUS(10),
64
    SIGBUS(10, ProcessSignal.Signal.SIGBUS),
63
    SIGSEGV(11),
65
    SIGSEGV(11, ProcessSignal.Signal.SIGSEGV),
64
    SIGSYS(12),
66
    SIGSYS(12, ProcessSignal.Signal.SIGSYS),
65
    SIGPIPE(13),
67
    SIGPIPE(13, ProcessSignal.Signal.SIGPIPE),
66
    SIGALRM(14),
68
    SIGALRM(14, ProcessSignal.Signal.SIGALRM),
67
    SIGTERM(15),
69
    SIGTERM(15, ProcessSignal.Signal.SIGTERM),
68
    SIGUSR1(16),
70
    SIGUSR1(16, ProcessSignal.Signal.SIGUSR1),
69
    SIGUSR2(17),
71
    SIGUSR2(17, ProcessSignal.Signal.SIGUSR2),
70
    SIGCLD(18),
72
    SIGCLD(18, null),
71
    SIGCHLD(18),
73
    SIGCHLD(18, ProcessSignal.Signal.SIGCHLD),
72
    SIGPWR(19),
74
    SIGPWR(19, ProcessSignal.Signal.SIGPWR),
73
    SIGWINCH(20),
75
    SIGWINCH(20, ProcessSignal.Signal.SIGWINCH),
74
    SIGURG(21),
76
    SIGURG(21, ProcessSignal.Signal.SIGURG),
75
    SIGPOLL(22),
77
    SIGPOLL(22, ProcessSignal.Signal.SIGPOLL),
76
    SIGIO(22),
78
    SIGIO(22, null),
77
    SIGSTOP(23),
79
    SIGSTOP(23, ProcessSignal.Signal.SIGSTOP),
78
    SIGTSTP(24),
80
    SIGTSTP(24, ProcessSignal.Signal.SIGTSTP),
79
    SIGCONT(25),
81
    SIGCONT(25, ProcessSignal.Signal.SIGCONT),
80
    SIGTTIN(26),
82
    SIGTTIN(26, ProcessSignal.Signal.SIGTTIN),
81
    SIGTTOU(27),
83
    SIGTTOU(27, ProcessSignal.Signal.SIGTTOU),
82
    SIGVTALRM(28),
84
    SIGVTALRM(28, ProcessSignal.Signal.SIGVTALRM),
83
    SIGPROF(29),
85
    SIGPROF(29, ProcessSignal.Signal.SIGPROF),
84
    SIGXCPU(30),
86
    SIGXCPU(30, ProcessSignal.Signal.SIGXCPU),
85
    SIGXFSZ(31),
87
    SIGXFSZ(31, null),
86
    SIGWAITING(32),
88
    SIGWAITING(32, ProcessSignal.Signal.SIGWAITING),
87
    SIGLWP(33),
89
    SIGLWP(33, ProcessSignal.Signal.SIGLWP),
88
    SIGFREEZE(34),
90
    SIGFREEZE(34, ProcessSignal.Signal.SIGFREEZE),
89
    SIGTHAW(35),
91
    SIGTHAW(35, ProcessSignal.Signal.SIGTHAW),
90
    SIGCANCEL(36),
92
    SIGCANCEL(36, ProcessSignal.Signal.SIGCANCEL),
91
    SIGLOST(37),
93
    SIGLOST(37, ProcessSignal.Signal.SIGLOST),
92
    SIGXRES(38),
94
    SIGXRES(38, ProcessSignal.Signal.SIGXRES),
93
    SIGJVM1(39),
95
    SIGJVM1(39, ProcessSignal.Signal.SIGJVM1),
94
    SIGJVM2(40);
96
    SIGJVM2(40, null);
97
95
    private final int id;
98
    private final int id;
96
99
97
    private Signal(int id) {
100
    private final ProcessSignal.Signal apiSignal;
101
102
    private Signal(int id, ProcessSignal.Signal apiSignal) {
98
        this.id = id;
103
        this.id = id;
104
        this.apiSignal = apiSignal;
99
    }
105
    }
100
106
101
    /*
107
    /*
Lines 107-110 Link Here
107
    int getID() {
113
    int getID() {
108
        return id;
114
        return id;
109
    }
115
    }
116
117
    public ProcessSignal.Signal getApiSignal() {
118
        return apiSignal;
119
    }
110
}
120
}
(-)a/dlight.nativeexecution/src/org/netbeans/modules/nativeexecution/signals/SignalSupport.java (+18 lines)
Lines 42-47 Link Here
42
package org.netbeans.modules.nativeexecution.signals;
42
package org.netbeans.modules.nativeexecution.signals;
43
43
44
import java.util.Collection;
44
import java.util.Collection;
45
import java.util.EnumMap;
46
import java.util.Map;
47
import org.netbeans.api.extexecution.process.ProcessSignal;
45
import org.netbeans.modules.nativeexecution.api.ExecutionEnvironment;
48
import org.netbeans.modules.nativeexecution.api.ExecutionEnvironment;
46
import org.netbeans.modules.nativeexecution.api.util.Signal;
49
import org.netbeans.modules.nativeexecution.api.util.Signal;
47
import org.openide.util.Lookup;
50
import org.openide.util.Lookup;
Lines 140-143 Link Here
140
143
141
        return result;
144
        return result;
142
    }
145
    }
146
147
    private static Map<ProcessSignal.Signal, Signal> translation;
148
149
    public synchronized static Signal translate(ProcessSignal.Signal signal) {
150
        if (translation == null) {
151
            translation = new EnumMap<ProcessSignal.Signal, Signal>(ProcessSignal.Signal.class);
152
            for (Signal sig : Signal.values()) {
153
                ProcessSignal.Signal api = sig.getApiSignal();
154
                if (api != null) {
155
                    translation.put(api, sig);
156
                }
157
            }
158
        }
159
        return translation.get(signal);
160
    }
143
}
161
}
(-)a/dlight.nativeexecution/tools/pty/Makefile (-3 / +3 lines)
Lines 17-22 Link Here
17
	$(ROOT_DIR)/src/options.c \
17
	$(ROOT_DIR)/src/options.c \
18
	$(ROOT_DIR)/src/pty_fork.c \
18
	$(ROOT_DIR)/src/pty_fork.c \
19
	$(ROOT_DIR)/src/pty.c \
19
	$(ROOT_DIR)/src/pty.c \
20
	$(ROOT_DIR)/src/stty.c \
20
	$(ROOT_DIR)/src/util.c
21
	$(ROOT_DIR)/src/util.c
21
22
22
SRC_DIRS=\
23
SRC_DIRS=\
Lines 30-36 Link Here
30
31
31
EXEC=$(DIST_DIR)/$(PNAME)
32
EXEC=$(DIST_DIR)/$(PNAME)
32
33
33
34
CF_COMMON         = --std=c99 -s -O2
34
CF_COMMON         = --std=c99 -s -O2
35
CF_Linux-x86      = $(CF_COMMON) -DLINUX   -D_GNU_SOURCE -D_XOPEN_SOURCE=700 -m32
35
CF_Linux-x86      = $(CF_COMMON) -DLINUX   -D_GNU_SOURCE -D_XOPEN_SOURCE=700 -m32
36
CF_Linux-x86_64   = $(CF_COMMON) -DLINUX   -D_GNU_SOURCE -D_XOPEN_SOURCE=700 -m64
36
CF_Linux-x86_64   = $(CF_COMMON) -DLINUX   -D_GNU_SOURCE -D_XOPEN_SOURCE=700 -m64
Lines 40-47 Link Here
40
CF_SunOS-sparc_64 = $(CF_COMMON) -DSOLARIS -D__EXTENSIONS__ -m64
40
CF_SunOS-sparc_64 = $(CF_COMMON) -DSOLARIS -D__EXTENSIONS__ -m64
41
CF_SunOS-x86      = $(CF_COMMON) -DSOLARIS -D__EXTENSIONS__ -m32
41
CF_SunOS-x86      = $(CF_COMMON) -DSOLARIS -D__EXTENSIONS__ -m32
42
CF_SunOS-x86_64   = $(CF_COMMON) -DSOLARIS -D__EXTENSIONS__ -m64
42
CF_SunOS-x86_64   = $(CF_COMMON) -DSOLARIS -D__EXTENSIONS__ -m64
43
CF_Windows-x86    = $(CF_COMMON) -DWINDOWS -m32
43
CF_Windows-x86    = $(CF_COMMON) -DWINDOWS -m32 --std=gnu99
44
CF_Windows-x86_64 = $(CF_COMMON) -DWINDOWS -m32
44
CF_Windows-x86_64 = $(CF_COMMON) -DWINDOWS -m32 --std=gnu99
45
45
46
LF_Windows-x86    = --static-libgcc
46
LF_Windows-x86    = --static-libgcc
47
LF_Windows-x86_64 = --static-libgcc
47
LF_Windows-x86_64 = --static-libgcc
(-)a/dlight.nativeexecution/tools/pty/src/options.c (+3 lines)
Lines 35-40 Link Here
35
                }
35
                }
36
                opts->envfile = argv[idx];
36
                opts->envfile = argv[idx];
37
                return argc; // pretend that everything is parsed ... 
37
                return argc; // pretend that everything is parsed ... 
38
            } else if (strcmp(argv[idx], "--resize") == 0) {
39
                opts->resize = 1;
40
                nopt += 1;
38
            } else if (strcmp(argv[idx], "--") == 0) {
41
            } else if (strcmp(argv[idx], "--") == 0) {
39
                idx++;
42
                idx++;
40
                nopt += 2;
43
                nopt += 2;
(-)a/dlight.nativeexecution/tools/pty/src/options.h (+1 lines)
Lines 20-25 Link Here
20
        int set_erase_key;
20
        int set_erase_key;
21
        int redirect_error;
21
        int redirect_error;
22
        int waitSignal;
22
        int waitSignal;
23
        int resize;
23
        char *pty;
24
        char *pty;
24
        char *wdir;
25
        char *wdir;
25
        const char *envfile;
26
        const char *envfile;
(-)a/dlight.nativeexecution/tools/pty/src/pty.c (-4 / +12 lines)
Lines 79-87 Link Here
79
        //  --dumpenv   record current environment in a specified file
79
        //  --dumpenv   record current environment in a specified file
80
        //  --report    record process' and exit status information into 
80
        //  --report    record process' and exit status information into 
81
        //              specified file
81
        //              specified file
82
        //  --resize    send TIOCSWINSZ to a terminal with the specified sizes
82
83
83
        err_quit("\n\n"
84
        err_quit("\n\n"
84
                "usage: %s [-e] [--no-pty] [-w] [-p pts_name] [--set-erase-key]\n"
85
                "usage: %s\t[-e] [--no-pty] [-w] [-p pts_name] [--set-erase-key]\n"
85
                "\t\t[--readenv env_file] [[--env NAME=VALUE] ...] [--dir dir]\n"
86
                "\t\t[--readenv env_file] [[--env NAME=VALUE] ...] [--dir dir]\n"
86
                "\t\t[--redirect-error] [--report report_file] program [ arg ... ]\n\n"
87
                "\t\t[--redirect-error] [--report report_file] program [ arg ... ]\n\n"
87
                "\t-e\t\t turn echoing off\n"
88
                "\t-e\t\t turn echoing off\n"
Lines 92-100 Link Here
92
                "\t--dir\t\t change working directory for starting process\n"
93
                "\t--dir\t\t change working directory for starting process\n"
93
                "\t--redirect-error redirect stderror to stdout for starting process (makes sense if --no-pty only)\n"
94
                "\t--redirect-error redirect stderror to stdout for starting process (makes sense if --no-pty only)\n"
94
                "\t--report\t record process' and exit status information into specified file\n\n"
95
                "\t--report\t record process' and exit status information into specified file\n\n"
95
                "usage: %s --dumpenv env_file\n"
96
                "usage: %s\t--dumpenv env_file\n"
96
                "\t--dumpenv\t dump environment to a file\n"
97
                "\t--dumpenv\t dump environment to a file\n\n"
97
                , progname, progname);
98
                "usage: %s\t--resize -p pts_name cols,rows,xpixels,ypixels\n"
99
                "\t--resize\t send TIOCSWINSZ to a terminal with the specified sizes\n"
100
                "\t\t\t Zero or not specified size means no change\n"
101
                , progname, progname, progname);
98
        exit(-1);
102
        exit(-1);
99
    }
103
    }
100
104
Lines 107-112 Link Here
107
        dup2(STDOUT_FILENO, STDERR_FILENO);
111
        dup2(STDOUT_FILENO, STDERR_FILENO);
108
    }
112
    }
109
113
114
    if (params.resize) {
115
        return stty_winsz(params.pty, argv[0]);
116
    }
117
110
    if (params.nopty == 0) {
118
    if (params.nopty == 0) {
111
        if (params.pty != NULL) {
119
        if (params.pty != NULL) {
112
            pid = pty_fork1(params.pty);
120
            pid = pty_fork1(params.pty);
(-)a/dlight.nativeexecution/tools/pty/src/pty.h (+1 lines)
Lines 10-15 Link Here
10
#include "error.h"
10
#include "error.h"
11
#include "util.h"
11
#include "util.h"
12
#include "options.h"
12
#include "options.h"
13
#include "stty.h"
13
#include <sys/termios.h>
14
#include <sys/termios.h>
14
#include <sys/types.h>
15
#include <sys/types.h>
15
#include <sys/wait.h>
16
#include <sys/wait.h>
(-)a/dlight.nativeexecution/tools/pty/src/stty.c (+58 lines)
Line 0 Link Here
1
#include "stty.h"
2
#include "error.h"
3
#include <sys/termios.h>
4
#include <sys/ioctl.h>
5
#include <fcntl.h>
6
#include <unistd.h>
7
8
#if defined (__CYGWIN__) || defined (LINUX)
9
#include <pty.h>
10
#endif
11
12
#if defined (__CYGWIN__)
13
#include <sys/unistd.h>
14
#else
15
#include <stropts.h>
16
#endif
17
18
int stty_winsz(const char* pts, const char* sz) {
19
    if (pts == NULL) {
20
        err_quit("pts must be specified when --resize is used");
21
    }
22
    char* sizes = strdup(sz);
23
    if (sizes == (char *) NULL) {
24
        err_sys("strdup error");
25
    }
26
    char *t;
27
    char *lasts;
28
    struct winsize wsize, orig;
29
30
    int pty_fd;
31
    if ((pty_fd = open(pts, O_RDWR)) == -1) {
32
        err_sys("ERROR cannot open pty \"%s\" -- %s\n", pts, strerror(errno));
33
    }
34
35
    if (!isatty(pty_fd)) {
36
        err_quit("Not a terminal: %s\n", pts);
37
    }
38
39
    ioctl(pty_fd, TIOCGWINSZ, &orig);
40
41
    t = strtok_r(sizes, ",", &lasts);
42
    wsize.ws_col = t == NULL ? orig.ws_col : atoi(t);
43
    if (wsize.ws_col == 0) wsize.ws_col = orig.ws_col;
44
45
    t = strtok_r(NULL, ",", &lasts);
46
    wsize.ws_row = t == NULL ? orig.ws_row : atoi(t);
47
    if (wsize.ws_row == 0) wsize.ws_row = orig.ws_row;
48
49
    t = strtok_r(NULL, ",", &lasts);
50
    wsize.ws_xpixel = t == NULL ? orig.ws_xpixel : atoi(t);
51
    if (wsize.ws_xpixel == 0) wsize.ws_xpixel = orig.ws_xpixel;
52
53
    t = strtok_r(NULL, ",", &lasts);
54
    wsize.ws_ypixel = t == NULL ? orig.ws_ypixel : atoi(t);
55
    if (wsize.ws_ypixel == 0) wsize.ws_ypixel = orig.ws_ypixel;
56
57
    return ioctl(pty_fd, TIOCSWINSZ, &wsize);
58
}
(-)a/dlight.nativeexecution/tools/pty/src/stty.h (+20 lines)
Line 0 Link Here
1
/*
2
 * File:   stty.h
3
 * Author: akrasny
4
 */
5
6
#ifndef STTY_H
7
#define	STTY_H
8
9
#ifdef	__cplusplus
10
extern "C" {
11
#endif
12
13
    int stty_winsz(const char*, const char*);
14
15
#ifdef	__cplusplus
16
}
17
#endif
18
19
#endif	/* STTY_H */
20
(-)a/dlight.remote.impl/src/org/netbeans/modules/remote/impl/fileoperations/spi/FileOperationsProvider.java (-14 / +65 lines)
Lines 49-54 Link Here
49
import java.util.Map;
49
import java.util.Map;
50
import java.util.concurrent.ExecutionException;
50
import java.util.concurrent.ExecutionException;
51
import java.util.concurrent.Future;
51
import java.util.concurrent.Future;
52
import org.netbeans.api.extexecution.Environment;
52
import org.netbeans.api.extexecution.ProcessBuilder;
53
import org.netbeans.api.extexecution.ProcessBuilder;
53
import org.netbeans.modules.dlight.libs.common.PathUtilities;
54
import org.netbeans.modules.dlight.libs.common.PathUtilities;
54
import org.netbeans.modules.nativeexecution.api.ExecutionEnvironment;
55
import org.netbeans.modules.nativeexecution.api.ExecutionEnvironment;
Lines 62-69 Link Here
62
import org.netbeans.modules.remote.impl.fs.RemoteFileSystem;
63
import org.netbeans.modules.remote.impl.fs.RemoteFileSystem;
63
import org.netbeans.modules.remote.impl.fs.RemoteFileSystemManager;
64
import org.netbeans.modules.remote.impl.fs.RemoteFileSystemManager;
64
import org.netbeans.modules.remote.impl.fs.RemoteFileUrlMapper;
65
import org.netbeans.modules.remote.impl.fs.RemoteFileUrlMapper;
66
import org.netbeans.spi.extexecution.EnvironmentFactory;
67
import org.netbeans.spi.extexecution.EnvironmentImplementation;
65
import org.netbeans.spi.extexecution.ProcessBuilderFactory;
68
import org.netbeans.spi.extexecution.ProcessBuilderFactory;
66
import org.netbeans.spi.extexecution.ProcessBuilderImplementation;
69
import org.netbeans.spi.extexecution.ProcessBuilderImplementation2;
70
import org.netbeans.spi.extexecution.ProcessParameters;
67
import org.openide.filesystems.FileObject;
71
import org.openide.filesystems.FileObject;
68
import org.openide.filesystems.FileSystem;
72
import org.openide.filesystems.FileSystem;
69
import org.openide.util.Lookup;
73
import org.openide.util.Lookup;
Lines 378-384 Link Here
378
        }
382
        }
379
383
380
        protected ProcessBuilder createProcessBuilder(FileProxyO file) {
384
        protected ProcessBuilder createProcessBuilder(FileProxyO file) {
381
            return ProcessBuilderFactory.createProcessBuilder(new ProcessBuilderImplementationImpl(env), "RFS Process Builder"); // NOI18N
385
            return ProcessBuilderFactory.createProcessBuilder(new ProcessBuilderImplementationImpl2(env), "RFS Process Builder"); // NOI18N
382
        }
386
        }
383
        
387
        
384
        protected void refreshFor(FileProxyO ... files) {
388
        protected void refreshFor(FileProxyO ... files) {
Lines 462-484 Link Here
462
        return defaultProvider;
466
        return defaultProvider;
463
    }
467
    }
464
468
465
    private static final class ProcessBuilderImplementationImpl implements ProcessBuilderImplementation {
469
    private static final class ProcessBuilderImplementationImpl2 implements ProcessBuilderImplementation2 {
466
        private final ExecutionEnvironment env;
470
        private final ExecutionEnvironment env;
467
        private ProcessBuilderImplementationImpl(ExecutionEnvironment env) {
471
        private final NativeProcessBuilder pb;
472
        private final Environment environment;
473
        private ProcessBuilderImplementationImpl2(ExecutionEnvironment env) {
468
            this.env = env;
474
            this.env = env;
475
            this.pb = NativeProcessBuilder.newProcessBuilder(env);
476
            this.environment = EnvironmentFactory.createEnvironment(
477
                    new EnvironmentImplementationImpl(pb.getEnvironment()));
469
        }
478
        }
470
479
471
        @Override
480
        @Override
472
        public Process createProcess(String executable, String workingDirectory, List<String> arguments, List<String> paths, Map<String, String> environment, boolean redirectErrorStream) throws IOException {
481
        public Environment getEnvironment() {
473
            NativeProcessBuilder pb = NativeProcessBuilder.newProcessBuilder(env);
482
            return this.environment;
474
            pb.setExecutable(executable).setWorkingDirectory(workingDirectory).setArguments(arguments.toArray(new String[arguments.size()]));
483
        }
475
            MacroMap mm = MacroMap.forExecEnv(env);
484
476
            mm.putAll(environment);
485
        @Override
477
            pb.getEnvironment().putAll(mm);
486
        public Lookup getLookup() {
478
            for(String path : paths) {
487
            return Lookup.EMPTY;
479
                pb.getEnvironment().appendPathVariable("PATH", path); // NOI18N
488
        }
480
            }
489
481
            if (redirectErrorStream) {
490
        @Override
491
        public Process createProcess(ProcessParameters parameters) throws IOException {
492
            pb.setExecutable(parameters.getExecutable())
493
                    .setWorkingDirectory(parameters.getWorkingDirectory())
494
                    .setArguments(parameters.getArguments().toArray(new String[parameters.getArguments().size()]));
495
            if (parameters.isRedirectErrorStream()) {
482
                pb.redirectError();
496
                pb.redirectError();
483
            }
497
            }
484
            return pb.call();
498
            return pb.call();
Lines 489-494 Link Here
489
            return env.getDisplayName();
503
            return env.getDisplayName();
490
        }
504
        }
491
    }
505
    }
506
507
    private static final class EnvironmentImplementationImpl implements EnvironmentImplementation {
508
        private final MacroMap mm;
509
        public EnvironmentImplementationImpl(MacroMap mm) {
510
            this.mm = mm;
511
        }
512
513
        @Override
514
        public String getVariable(String name) {
515
            return mm.get(name);
516
        }
517
518
        @Override
519
        public void appendPath(String name, String value) {
520
            mm.appendPathVariable(name, value);
521
        }
522
523
        @Override
524
        public void prependPath(String name, String value) {
525
            mm.prependPathVariable(name, value);
526
        }
527
528
        @Override
529
        public void setVariable(String name, String value) {
530
            mm.put(name, value);
531
        }
532
533
        @Override
534
        public void removeVariable(String name) {
535
            mm.remove(name);
536
        }
537
538
        @Override
539
        public Map<String, String> values() {
540
            return mm.toMap();
541
        }
542
    }
492
    
543
    
493
    public interface FileProxyO {
544
    public interface FileProxyO {
494
545
(-)a/dlight.remote/manifest.mf (-1 / +1 lines)
Lines 3-7 Link Here
3
OpenIDE-Module: org.netbeans.modules.dlight.remote
3
OpenIDE-Module: org.netbeans.modules.dlight.remote
4
OpenIDE-Module-Implementation-Version: 1
4
OpenIDE-Module-Implementation-Version: 1
5
OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/remote/resources/Bundle.properties
5
OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/remote/resources/Bundle.properties
6
OpenIDE-Module-Needs: org.netbeans.modules.dlight.remote.spi.RemoteProviderToken
6
OpenIDE-Module-Needs: org.netbeans.modules.dlight.remote.spi.RemoteProviderToken, ConnectionService.localhost, ConnectionService.ssh
7
OpenIDE-Module-Recommends: org.netbeans.modules.remotefs.versioning
7
OpenIDE-Module-Recommends: org.netbeans.modules.remotefs.versioning
(-)a/dlight.remote/nbproject/project.xml (+16 lines)
Lines 15-20 Link Here
15
                    </run-dependency>
15
                    </run-dependency>
16
                </dependency>
16
                </dependency>
17
                <dependency>
17
                <dependency>
18
                    <code-name-base>org.netbeans.modules.cnd.execution</code-name-base>
19
                    <build-prerequisite/>
20
                    <compile-dependency/>
21
                    <run-dependency>
22
                        <specification-version>1.0</specification-version>
23
                    </run-dependency>
24
                </dependency>
25
                <dependency>
18
                    <code-name-base>org.netbeans.modules.dlight.libs.common</code-name-base>
26
                    <code-name-base>org.netbeans.modules.dlight.libs.common</code-name-base>
19
                    <build-prerequisite/>
27
                    <build-prerequisite/>
20
                    <compile-dependency/>
28
                    <compile-dependency/>
Lines 31-36 Link Here
31
                    </run-dependency>
39
                    </run-dependency>
32
                </dependency>
40
                </dependency>
33
                <dependency>
41
                <dependency>
42
                    <code-name-base>org.netbeans.modules.execmerge</code-name-base>
43
                    <build-prerequisite/>
44
                    <compile-dependency/>
45
                    <run-dependency>
46
                        <specification-version>1.0</specification-version>
47
                    </run-dependency>
48
                </dependency>
49
                <dependency>
34
                    <code-name-base>org.openide.awt</code-name-base>
50
                    <code-name-base>org.openide.awt</code-name-base>
35
                    <build-prerequisite/>
51
                    <build-prerequisite/>
36
                    <compile-dependency/>
52
                    <compile-dependency/>
(-)a/dlight.remote/src/org/netbeans/modules/remote/api/ui/FileChooserBuilder.java (-1 / +13 lines)
Lines 63-68 Link Here
63
import javax.swing.filechooser.FileSystemView;
63
import javax.swing.filechooser.FileSystemView;
64
import javax.swing.filechooser.FileView;
64
import javax.swing.filechooser.FileView;
65
import javax.swing.plaf.FileChooserUI;
65
import javax.swing.plaf.FileChooserUI;
66
import org.netbeans.modules.cnd.execution.api.Connection;
66
import org.netbeans.modules.nativeexecution.api.ExecutionEnvironment;
67
import org.netbeans.modules.nativeexecution.api.ExecutionEnvironment;
67
import org.netbeans.modules.nativeexecution.api.ExecutionEnvironmentFactory;
68
import org.netbeans.modules.nativeexecution.api.ExecutionEnvironmentFactory;
68
import org.netbeans.modules.remote.spi.FileSystemProvider;
69
import org.netbeans.modules.remote.spi.FileSystemProvider;
Lines 95-101 Link Here
95
        
96
        
96
97
97
        public abstract void setCurrentDirectory(FileObject dir);
98
        public abstract void setCurrentDirectory(FileObject dir);
99
98
        public abstract FileObject getSelectedFileObject();
100
        public abstract FileObject getSelectedFileObject();
101
99
        public abstract FileObject[] getSelectedFileObjects();
102
        public abstract FileObject[] getSelectedFileObjects();
100
103
101
        @Override
104
        @Override
Lines 139-148 Link Here
139
    private static final String readOnlyKey = "FileChooser.readOnly"; // NOI18N
142
    private static final String readOnlyKey = "FileChooser.readOnly"; // NOI18N
140
143
141
    private final ExecutionEnvironment env;
144
    private final ExecutionEnvironment env;
145
    private final Connection connection;
142
    private Preferences forModule;
146
    private Preferences forModule;
143
147
144
    public FileChooserBuilder(ExecutionEnvironment env) {
148
    public FileChooserBuilder(ExecutionEnvironment env) {
145
        this.env = env;
149
        this.env = env;
150
        this.connection = null;
151
    }
152
153
    public FileChooserBuilder(Connection connection) {
154
        this.connection = connection;
155
        this.env = null;
146
    }
156
    }
147
    
157
    
148
    public JFileChooserEx createFileChooser(Callable<String> selectedPath) {
158
    public JFileChooserEx createFileChooser(Callable<String> selectedPath) {
Lines 291-296 Link Here
291
301
292
    private static class RemoteFileChooserImpl extends JFileChooserEx
302
    private static class RemoteFileChooserImpl extends JFileChooserEx
293
            implements PropertyChangeListener {
303
            implements PropertyChangeListener {
304
294
        private final Preferences forModule;
305
        private final Preferences forModule;
295
        private final ExecutionEnvironment env;
306
        private final ExecutionEnvironment env;
296
307
Lines 411-417 Link Here
411
                    String path = getSelectedFile().getAbsolutePath();
422
                    String path = getSelectedFile().getAbsolutePath();
412
                    if (forModule != null) {
423
                    if (forModule != null) {
413
                        String envID = ExecutionEnvironmentFactory.toUniqueID(env);
424
                        String envID = ExecutionEnvironmentFactory.toUniqueID(env);
414
                        forModule.put("FileChooserPath"+envID, path); // NOI18N
425
                        forModule.put("FileChooserPath" + envID, path); // NOI18N
415
                    }
426
                    }
416
                }
427
                }
417
            }
428
            }
Lines 420-425 Link Here
420
    }
431
    }
421
432
422
    private static class CustomFileView extends FileView {
433
    private static class CustomFileView extends FileView {
434
423
        final FileSystemView view;
435
        final FileSystemView view;
424
436
425
        public CustomFileView(FileSystemView view) {
437
        public CustomFileView(FileSystemView view) {
(-)a/dlight.remote/src/org/netbeans/modules/remote/spi/FileSystemProvider.java (+25 lines)
Lines 45-54 Link Here
45
import java.io.File;
45
import java.io.File;
46
import java.io.FileFilter;
46
import java.io.FileFilter;
47
import java.io.IOException;
47
import java.io.IOException;
48
import java.net.URI;
48
import java.util.ArrayList;
49
import java.util.ArrayList;
49
import java.util.Collection;
50
import java.util.Collection;
50
import java.util.concurrent.Callable;
51
import java.util.concurrent.Callable;
51
import java.util.logging.Level;
52
import java.util.logging.Level;
53
import org.netbeans.modules.cnd.execution.api.Connection;
54
import org.netbeans.modules.execmerge.ConnectionUtils;
52
import org.netbeans.modules.nativeexecution.api.ExecutionEnvironment;
55
import org.netbeans.modules.nativeexecution.api.ExecutionEnvironment;
53
import org.netbeans.modules.nativeexecution.api.ExecutionEnvironmentFactory;
56
import org.netbeans.modules.nativeexecution.api.ExecutionEnvironmentFactory;
54
import org.netbeans.modules.remote.support.RemoteLogger;
57
import org.netbeans.modules.remote.support.RemoteLogger;
Lines 84-89 Link Here
84
        return getFileSystem(env, "/"); //NOI18N
87
        return getFileSystem(env, "/"); //NOI18N
85
    }
88
    }
86
89
90
    @Deprecated
87
    public static ExecutionEnvironment getExecutionEnvironment(FileSystem fileSystem) {
91
    public static ExecutionEnvironment getExecutionEnvironment(FileSystem fileSystem) {
88
        for (FileSystemProviderImplementation provider : ALL_PROVIDERS) {
92
        for (FileSystemProviderImplementation provider : ALL_PROVIDERS) {
89
            if (provider.isMine(fileSystem)) {
93
            if (provider.isMine(fileSystem)) {
Lines 93-98 Link Here
93
        return ExecutionEnvironmentFactory.getLocal();
97
        return ExecutionEnvironmentFactory.getLocal();
94
    }
98
    }
95
99
100
    @Deprecated
96
    public static ExecutionEnvironment getExecutionEnvironment(FileObject fileObject) {
101
    public static ExecutionEnvironment getExecutionEnvironment(FileObject fileObject) {
97
        try {
102
        try {
98
            return getExecutionEnvironment(fileObject.getFileSystem());
103
            return getExecutionEnvironment(fileObject.getFileSystem());
Lines 102-107 Link Here
102
        return ExecutionEnvironmentFactory.getLocal();
107
        return ExecutionEnvironmentFactory.getLocal();
103
    }
108
    }
104
109
110
    public static Connection getConnection(FileObject fileObject) {
111
        return ConnectionUtils.ExecutionEnvironment2Connection(getExecutionEnvironment(fileObject));
112
    }
113
114
    public static Connection getConnection(FileSystem fileSystem) {
115
        return ConnectionUtils.ExecutionEnvironment2Connection(getExecutionEnvironment(fileSystem));
116
    }
117
105
    public static FileSystem getFileSystem(ExecutionEnvironment env, String root) {
118
    public static FileSystem getFileSystem(ExecutionEnvironment env, String root) {
106
        for (FileSystemProviderImplementation provider : ALL_PROVIDERS) {
119
        for (FileSystemProviderImplementation provider : ALL_PROVIDERS) {
107
            if (provider.isMine(env)) {
120
            if (provider.isMine(env)) {
Lines 190-195 Link Here
190
        return FileUtil.toFileObject(FileUtil.normalizeFile(new File(absPath)));
203
        return FileUtil.toFileObject(FileUtil.normalizeFile(new File(absPath)));
191
    }
204
    }
192
205
206
    public static FileObject getFileObject(Connection connection, String absPath) {
207
        return getFileObject(Connection2ExecutionEnvironment(connection), absPath);
208
    }
209
    
210
    private static ExecutionEnvironment Connection2ExecutionEnvironment(Connection connection) {
211
        URI uri = connection.getURI();
212
        if ("localhost".equals(uri.getScheme())) { // NOI18N
213
            return ExecutionEnvironmentFactory.getLocal();
214
        }
215
        return ExecutionEnvironmentFactory.createNew(uri.getUserInfo(), uri.getHost());
216
    }
217
193
    public static FileObject getCanonicalFileObject(FileObject fileObject) throws IOException {
218
    public static FileObject getCanonicalFileObject(FileObject fileObject) throws IOException {
194
        for (FileSystemProviderImplementation provider : ALL_PROVIDERS) {
219
        for (FileSystemProviderImplementation provider : ALL_PROVIDERS) {
195
            if (provider.isMine(fileObject)) {
220
            if (provider.isMine(fileObject)) {
(-)a/dlight.terminal/manifest.mf (+1 lines)
Lines 4-7 Link Here
4
OpenIDE-Module-Implementation-Version: 1
4
OpenIDE-Module-Implementation-Version: 1
5
OpenIDE-Module-Layer: org/netbeans/modules/dlight/terminal/layer.xml
5
OpenIDE-Module-Layer: org/netbeans/modules/dlight/terminal/layer.xml
6
OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/dlight/terminal/Bundle.properties
6
OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/dlight/terminal/Bundle.properties
7
OpenIDE-Module-Recommends: org.netbeans.modules.dlight.spi.terminal.ConnectionProvider
7
8
(-)a/dlight.terminal/nbproject/project.xml (-2 / +23 lines)
Lines 23-33 Link Here
23
                    </run-dependency>
23
                    </run-dependency>
24
                </dependency>
24
                </dependency>
25
                <dependency>
25
                <dependency>
26
                    <code-name-base>org.netbeans.modules.dlight.nativeexecution</code-name-base>
26
                    <code-name-base>org.netbeans.modules.autoupdate.ui</code-name-base>
27
                    <build-prerequisite/>
27
                    <build-prerequisite/>
28
                    <compile-dependency/>
28
                    <compile-dependency/>
29
                    <run-dependency>
29
                    <run-dependency>
30
                        <specification-version>1.10.3</specification-version>
30
                        <specification-version>1.35</specification-version>
31
                    </run-dependency>
32
                </dependency>
33
                <dependency>
34
                    <code-name-base>org.netbeans.modules.extexecution</code-name-base>
35
                    <build-prerequisite/>
36
                    <compile-dependency/>
37
                    <run-dependency>
38
                        <release-version>2</release-version>
39
                        <specification-version>1.37</specification-version>
40
                    </run-dependency>
41
                </dependency>
42
                <dependency>
43
                    <code-name-base>org.netbeans.modules.options.api</code-name-base>
44
                    <build-prerequisite/>
45
                    <compile-dependency/>
46
                    <run-dependency>
47
                        <release-version>1</release-version>
48
                        <specification-version>1.32</specification-version>
31
                    </run-dependency>
49
                    </run-dependency>
32
                </dependency>
50
                </dependency>
33
                <dependency>
51
                <dependency>
Lines 105-113 Link Here
105
                <friend>com.sun.tools.ide.analysis.discover</friend>
123
                <friend>com.sun.tools.ide.analysis.discover</friend>
106
                <friend>com.sun.tools.ide.analysis.previse</friend>
124
                <friend>com.sun.tools.ide.analysis.previse</friend>
107
                <friend>com.sun.tools.ide.analysis.tha</friend>
125
                <friend>com.sun.tools.ide.analysis.tha</friend>
126
                <friend>org.netbeans.modules.cnd.execution</friend>
108
                <friend>org.netbeans.modules.cnd.makeproject</friend>
127
                <friend>org.netbeans.modules.cnd.makeproject</friend>
109
                <friend>org.netbeans.modules.cnd.remote</friend>
128
                <friend>org.netbeans.modules.cnd.remote</friend>
129
                <friend>org.netbeans.modules.nativeexecution.impl</friend>
110
                <package>org.netbeans.modules.dlight.api.terminal</package>
130
                <package>org.netbeans.modules.dlight.api.terminal</package>
131
                <package>org.netbeans.modules.dlight.spi.terminal</package>
111
            </friend-packages>
132
            </friend-packages>
112
        </data>
133
        </data>
113
    </configuration>
134
    </configuration>
(-)a/dlight.terminal/src/org/netbeans/modules/dlight/api/terminal/ProcessTerminal.java (+92 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2012 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 2012 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.dlight.api.terminal;
43
44
import java.awt.Dimension;
45
import java.util.concurrent.atomic.AtomicReference;
46
import org.openide.util.Lookup;
47
import org.openide.util.RequestProcessor;
48
import org.openide.util.RequestProcessor.Task;
49
50
/**
51
 *
52
 * @author akrasny
53
 */
54
public abstract class ProcessTerminal {
55
56
    private static final RequestProcessor RP = new RequestProcessor("ProcessTerminal resize", 1); // NOI18N
57
    private final AtomicReference<Dimension> sizeRef = new AtomicReference<Dimension>();
58
    private final AtomicReference<Dimension> pixelSizeRef = new AtomicReference<Dimension>();
59
    private final Task resizeTask = RP.create(new Runnable() {
60
        @Override
61
        public void run() {
62
            synchronized (resizeTask) {
63
                ttyResized(sizeRef.get(), pixelSizeRef.get());
64
            }
65
        }
66
    }, true);
67
68
    private static ProcessTerminal find(Process process) {
69
        if (process instanceof Lookup.Provider) {
70
            Lookup.Provider p = (Lookup.Provider) process;
71
            return p.getLookup().lookup(ProcessTerminal.class);
72
        }
73
        return null;
74
    }
75
76
    public static boolean isSupported(Process process) {
77
        return find(process) != null;
78
    }
79
80
    public static void ttyResized(Process process, Dimension size, Dimension pixelSize) {
81
        ProcessTerminal termInfo = find(process);
82
        if (termInfo != null) {
83
            synchronized (termInfo.resizeTask) {
84
                termInfo.sizeRef.set(size);
85
                termInfo.pixelSizeRef.set(pixelSize);
86
            }
87
            termInfo.resizeTask.schedule(500);
88
        }
89
    }
90
91
    protected abstract void ttyResized(Dimension size, Dimension pixelSize);
92
}
(-)a/dlight.terminal/src/org/netbeans/modules/dlight/api/terminal/TerminalSupport.java (-7 / +6 lines)
Lines 46-52 Link Here
46
import javax.swing.Action;
46
import javax.swing.Action;
47
import org.netbeans.modules.dlight.terminal.action.TerminalSupportImpl;
47
import org.netbeans.modules.dlight.terminal.action.TerminalSupportImpl;
48
import org.netbeans.modules.dlight.terminal.ui.TerminalContainerTopComponent;
48
import org.netbeans.modules.dlight.terminal.ui.TerminalContainerTopComponent;
49
import org.netbeans.modules.nativeexecution.api.ExecutionEnvironment;
50
import org.openide.windows.IOContainer;
49
import org.openide.windows.IOContainer;
51
50
52
/**
51
/**
Lines 63-70 Link Here
63
     * @param ioContainer
62
     * @param ioContainer
64
     * @param env 
63
     * @param env 
65
     */
64
     */
66
    public static void openTerminal(IOContainer ioContainer, String termTitle, ExecutionEnvironment env) {
65
    public static void openTerminal(IOContainer ioContainer, String termTitle, org.netbeans.api.extexecution.ProcessBuilder.Provider provider) {
67
        TerminalSupportImpl.openTerminalImpl(ioContainer, termTitle, env, null, false);
66
        TerminalSupportImpl.openTerminalImpl(ioContainer, termTitle, provider, null, false);
68
    }
67
    }
69
    
68
    
70
    /**
69
    /**
Lines 72-86 Link Here
72
     * @param ioContainer
71
     * @param ioContainer
73
     * @param env 
72
     * @param env 
74
     */
73
     */
75
    public static void openTerminal(IOContainer ioContainer, String termTitle, ExecutionEnvironment env, String dir) {
74
    public static void openTerminal(IOContainer ioContainer, String termTitle, org.netbeans.api.extexecution.ProcessBuilder.Provider provider, String dir) {
76
        TerminalSupportImpl.openTerminalImpl(ioContainer, termTitle, env, dir, false);
75
        TerminalSupportImpl.openTerminalImpl(ioContainer, termTitle, provider, dir, false);
77
    }
76
    }
78
77
79
    /**
78
    /**
80
     * opens terminal tab in default terminals container and change dir into specified directory
79
     * opens terminal tab in default terminals container and change dir into specified directory
81
     * @param env 
80
     * @param env 
82
     */
81
     */
83
    public static void openTerminal(String termTitle, ExecutionEnvironment env, String dir) {
82
    public static void openTerminal(String termTitle, org.netbeans.api.extexecution.ProcessBuilder.Provider provider, String dir) {
84
        final TerminalContainerTopComponent instance = TerminalContainerTopComponent.findInstance();
83
        final TerminalContainerTopComponent instance = TerminalContainerTopComponent.findInstance();
85
        Object prev = instance.getClientProperty(TerminalContainerTopComponent.AUTO_OPEN_LOCAL_PROPERTY);
84
        Object prev = instance.getClientProperty(TerminalContainerTopComponent.AUTO_OPEN_LOCAL_PROPERTY);
86
        instance.putClientProperty(TerminalContainerTopComponent.AUTO_OPEN_LOCAL_PROPERTY, Boolean.FALSE);
85
        instance.putClientProperty(TerminalContainerTopComponent.AUTO_OPEN_LOCAL_PROPERTY, Boolean.FALSE);
Lines 88-94 Link Here
88
            instance.open();
87
            instance.open();
89
            instance.requestActive();
88
            instance.requestActive();
90
            IOContainer ioContainer = instance.getIOContainer();
89
            IOContainer ioContainer = instance.getIOContainer();
91
            TerminalSupportImpl.openTerminalImpl(ioContainer, termTitle, env, dir, false);
90
            TerminalSupportImpl.openTerminalImpl(ioContainer, termTitle, provider, dir, false);
92
        } finally {
91
        } finally {
93
            instance.putClientProperty(TerminalContainerTopComponent.AUTO_OPEN_LOCAL_PROPERTY, prev);
92
            instance.putClientProperty(TerminalContainerTopComponent.AUTO_OPEN_LOCAL_PROPERTY, prev);
94
        }
93
        }
(-)a/dlight.terminal/src/org/netbeans/modules/dlight/spi/terminal/ConnectionProvider.java (+57 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2013 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 2013 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.dlight.spi.terminal;
43
44
import java.io.IOException;
45
import java.net.URI;
46
import org.netbeans.api.extexecution.ProcessBuilder;
47
48
/**
49
 *
50
 * @author Petr Hejl
51
 */
52
public interface ConnectionProvider {
53
54
    ProcessBuilder.Provider getConnection(URI uri) throws IOException;
55
56
    URI getLocal();
57
}
(-)a/dlight.terminal/src/org/netbeans/modules/dlight/spi/terminal/ShellConfiguration.java (+52 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2013 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 2013 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.dlight.spi.terminal;
43
44
/**
45
 *
46
 * @author Petr Hejl
47
 */
48
public interface ShellConfiguration {
49
50
    String getShell();
51
52
}
(-)a/dlight.terminal/src/org/netbeans/modules/dlight/spi/terminal/TerminalConfiguration.java (+58 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2013 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 2013 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.dlight.spi.terminal;
43
44
/**
45
 *
46
 * @author Petr Hejl
47
 */
48
public interface TerminalConfiguration {
49
50
    boolean isTerminalMode();
51
52
    void setTerminalMode(boolean terminalMode);
53
54
    String getEmulation();
55
56
    void setEmulation(String emulation);
57
58
}
(-)a/dlight.terminal/src/org/netbeans/modules/dlight/terminal/action/Bundle.properties (-1 lines)
Lines 1-7 Link Here
1
CTL_LocalTerminal=Terminal
1
CTL_LocalTerminal=Terminal
2
CTL_RemoteTerminalAction=Remote Terminal
2
CTL_RemoteTerminalAction=Remote Terminal
3
RemoteConnectionTitle=SSH Connection
3
RemoteConnectionTitle=SSH Connection
4
TerminalAction.FailedToStart.text=Failed to start terminal: {0}
5
RemoteTerminalShortDescr=Create New Remote Terminal Tab
4
RemoteTerminalShortDescr=Create New Remote Terminal Tab
6
LocalTerminalShortDescr=Create New Local Terminal Tab
5
LocalTerminalShortDescr=Create New Local Terminal Tab
7
CTL_ShowTerminalAction=T&erminal
6
CTL_ShowTerminalAction=T&erminal
(-)a/dlight.terminal/src/org/netbeans/modules/dlight/terminal/action/LocalTerminalAction.java (-5 / +6 lines)
Lines 41-53 Link Here
41
 */
41
 */
42
package org.netbeans.modules.dlight.terminal.action;
42
package org.netbeans.modules.dlight.terminal.action;
43
43
44
import java.net.URI;
45
import org.netbeans.modules.dlight.spi.terminal.ConnectionProvider;
44
import org.netbeans.modules.dlight.terminal.ui.TerminalContainerTopComponent;
46
import org.netbeans.modules.dlight.terminal.ui.TerminalContainerTopComponent;
45
import org.netbeans.modules.nativeexecution.api.ExecutionEnvironment;
46
import org.netbeans.modules.nativeexecution.api.ExecutionEnvironmentFactory;
47
import org.openide.awt.ActionID;
47
import org.openide.awt.ActionID;
48
import org.openide.awt.ActionReference;
48
import org.openide.awt.ActionReference;
49
import org.openide.awt.ActionRegistration;
49
import org.openide.awt.ActionRegistration;
50
import org.openide.util.ImageUtilities;
50
import org.openide.util.ImageUtilities;
51
import org.openide.util.Lookup;
51
import org.openide.util.NbBundle;
52
import org.openide.util.NbBundle;
52
53
53
/**
54
/**
Lines 55-61 Link Here
55
 * @author Vladimir Voskresensky
56
 * @author Vladimir Voskresensky
56
 */
57
 */
57
@ActionID(id = "LocalTerminalAction", category = "Window")
58
@ActionID(id = "LocalTerminalAction", category = "Window")
58
@ActionRegistration(iconInMenu = true, displayName = "#CTL_LocalTerminal", iconBase = "org/netbeans/modules/dlight/terminal/action/local_term.png")
59
@ActionRegistration(iconInMenu = true, lazy = false, displayName = "#CTL_LocalTerminal", iconBase = "org/netbeans/modules/dlight/terminal/action/local_term.png")
59
@ActionReference(path = TerminalAction.TERMINAL_ACTIONS_PATH, name = "org-netbeans-modules-dlight-terminal-action-LocalTerminalAction", position = 100)
60
@ActionReference(path = TerminalAction.TERMINAL_ACTIONS_PATH, name = "org-netbeans-modules-dlight-terminal-action-LocalTerminalAction", position = 100)
60
public final class LocalTerminalAction extends TerminalAction {
61
public final class LocalTerminalAction extends TerminalAction {
61
62
Lines 65-71 Link Here
65
    }
66
    }
66
67
67
    @Override
68
    @Override
68
    protected ExecutionEnvironment getEnvironment() {
69
    protected URI getConnectionURI() {
69
        return ExecutionEnvironmentFactory.getLocal();
70
        return Lookup.getDefault().lookup(ConnectionProvider.class).getLocal();
70
    }
71
    }
71
}
72
}
(-)a/dlight.terminal/src/org/netbeans/modules/dlight/terminal/action/RemoteTerminalAction.java (-6 / +7 lines)
Lines 42-55 Link Here
42
package org.netbeans.modules.dlight.terminal.action;
42
package org.netbeans.modules.dlight.terminal.action;
43
43
44
import java.awt.Dialog;
44
import java.awt.Dialog;
45
import java.net.URI;
46
import org.netbeans.modules.dlight.spi.terminal.ConnectionProvider;
45
import org.netbeans.modules.dlight.terminal.ui.RemoteInfoDialog;
47
import org.netbeans.modules.dlight.terminal.ui.RemoteInfoDialog;
46
import org.netbeans.modules.nativeexecution.api.ExecutionEnvironment;
47
import org.openide.DialogDescriptor;
48
import org.openide.DialogDescriptor;
48
import org.openide.DialogDisplayer;
49
import org.openide.DialogDisplayer;
49
import org.openide.awt.ActionID;
50
import org.openide.awt.ActionID;
50
import org.openide.awt.ActionReference;
51
import org.openide.awt.ActionReference;
51
import org.openide.awt.ActionRegistration;
52
import org.openide.awt.ActionRegistration;
52
import org.openide.util.ImageUtilities;
53
import org.openide.util.ImageUtilities;
54
import org.openide.util.Lookup;
53
import org.openide.util.NbBundle;
55
import org.openide.util.NbBundle;
54
56
55
/**
57
/**
Lines 57-63 Link Here
57
 * @author Vladimir Voskresensky
59
 * @author Vladimir Voskresensky
58
 */
60
 */
59
@ActionID(id = "RemoteTerminalAction", category = "Window")
61
@ActionID(id = "RemoteTerminalAction", category = "Window")
60
@ActionRegistration(iconInMenu = true, displayName = "#CTL_RemoteTerminalAction", iconBase = "org/netbeans/modules/dlight/terminal/action/remote_term.png")
62
@ActionRegistration(iconInMenu = true, lazy = false, displayName = "#CTL_RemoteTerminalAction", iconBase = "org/netbeans/modules/dlight/terminal/action/remote_term.png")
61
@ActionReference(path = TerminalAction.TERMINAL_ACTIONS_PATH, name = "org-netbeans-modules-dlight-terminal-action-RemoteTerminalAction", position = 200)
63
@ActionReference(path = TerminalAction.TERMINAL_ACTIONS_PATH, name = "org-netbeans-modules-dlight-terminal-action-RemoteTerminalAction", position = 200)
62
public final class RemoteTerminalAction extends TerminalAction {
64
public final class RemoteTerminalAction extends TerminalAction {
63
65
Lines 70-76 Link Here
70
    }
72
    }
71
73
72
    @Override
74
    @Override
73
    protected ExecutionEnvironment getEnvironment() {
75
    protected URI getConnectionURI() {
74
        String title = NbBundle.getMessage(RemoteTerminalAction.class, "RemoteConnectionTitle");
76
        String title = NbBundle.getMessage(RemoteTerminalAction.class, "RemoteConnectionTitle");
75
        cfgPanel.init();
77
        cfgPanel.init();
76
        DialogDescriptor dd = new DialogDescriptor(cfgPanel, title, // NOI18N
78
        DialogDescriptor dd = new DialogDescriptor(cfgPanel, title, // NOI18N
Lines 78-84 Link Here
78
                DialogDescriptor.OK_OPTION, null);
80
                DialogDescriptor.OK_OPTION, null);
79
81
80
        Dialog cfgDialog = DialogDisplayer.getDefault().createDialog(dd);
82
        Dialog cfgDialog = DialogDisplayer.getDefault().createDialog(dd);
81
        
83
82
        try {
84
        try {
83
            cfgDialog.setVisible(true);
85
            cfgDialog.setVisible(true);
84
        } catch (Throwable th) {
86
        } catch (Throwable th) {
Lines 94-100 Link Here
94
            return null;
96
            return null;
95
        }
97
        }
96
98
97
        final ExecutionEnvironment env = cfgPanel.getExecutionEnvironment();
99
        return cfgPanel.getConnectionURI();
98
        return env;
99
    }
100
    }
100
}
101
}
(-)a/dlight.terminal/src/org/netbeans/modules/dlight/terminal/action/ShowTerminalAction.java (+3 lines)
Lines 59-64 Link Here
59
public class ShowTerminalAction implements ActionListener {
59
public class ShowTerminalAction implements ActionListener {
60
    @Override
60
    @Override
61
    public void actionPerformed(ActionEvent e) {
61
    public void actionPerformed(ActionEvent e) {
62
        if (!TerminalAction.checkInstalled()) {
63
            return;
64
        }
62
        final TerminalContainerTopComponent instance = TerminalContainerTopComponent.findInstance();
65
        final TerminalContainerTopComponent instance = TerminalContainerTopComponent.findInstance();
63
        instance.open();
66
        instance.open();
64
        instance.requestActive();
67
        instance.requestActive();
(-)a/dlight.terminal/src/org/netbeans/modules/dlight/terminal/action/TerminalAction.java (-7 / +70 lines)
Lines 43-53 Link Here
43
43
44
import java.awt.Component;
44
import java.awt.Component;
45
import java.awt.event.ActionEvent;
45
import java.awt.event.ActionEvent;
46
import java.io.IOException;
47
import java.io.InterruptedIOException;
48
import java.net.NoRouteToHostException;
49
import java.net.URI;
46
import javax.swing.AbstractAction;
50
import javax.swing.AbstractAction;
47
import javax.swing.Action;
51
import javax.swing.Action;
48
import javax.swing.ImageIcon;
52
import javax.swing.ImageIcon;
53
import org.netbeans.modules.autoupdate.ui.api.PluginManager;
54
import org.netbeans.modules.dlight.spi.terminal.ConnectionProvider;
49
import org.netbeans.modules.dlight.terminal.ui.TerminalContainerTopComponent;
55
import org.netbeans.modules.dlight.terminal.ui.TerminalContainerTopComponent;
50
import org.netbeans.modules.nativeexecution.api.ExecutionEnvironment;
56
import org.openide.DialogDisplayer;
57
import org.openide.NotifyDescriptor;
58
import org.openide.util.Exceptions;
59
import org.openide.util.Lookup;
60
import org.openide.util.NbBundle;
61
import org.openide.util.NbBundle.Messages;
51
import org.openide.util.actions.Presenter;
62
import org.openide.util.actions.Presenter;
52
import org.openide.windows.IOContainer;
63
import org.openide.windows.IOContainer;
53
import org.openide.windows.IOProvider;
64
import org.openide.windows.IOProvider;
Lines 60-65 Link Here
60
    
71
    
61
    public static final String TERMINAL_ACTIONS_PATH = "Terminal/Actions"; // NOI18N
72
    public static final String TERMINAL_ACTIONS_PATH = "Terminal/Actions"; // NOI18N
62
73
74
    private static final String NATIVE_EXECUTION = "org.netbeans.modules.cnd.execution"; // NOI18N
75
63
    public TerminalAction(String name, String descr, ImageIcon icon) {
76
    public TerminalAction(String name, String descr, ImageIcon icon) {
64
        putValue(Action.NAME, name);
77
        putValue(Action.NAME, name);
65
        putValue(Action.SMALL_ICON, icon);
78
        putValue(Action.SMALL_ICON, icon);
Lines 67-83 Link Here
67
    }
80
    }
68
81
69
    @Override
82
    @Override
83
    @Messages({
84
        "# {0} - host",
85
        "UnreachableHostError=Host {0} cannot be reached. Please verify proxy settings."
86
    })
70
    public void actionPerformed(final ActionEvent e) {
87
    public void actionPerformed(final ActionEvent e) {
88
        if (!checkInstalled()) {
89
            return;
90
        }
91
71
        final TerminalContainerTopComponent instance = TerminalContainerTopComponent.findInstance();
92
        final TerminalContainerTopComponent instance = TerminalContainerTopComponent.findInstance();
72
        instance.open();
93
        instance.open();
73
        instance.requestActive();
94
        instance.requestActive();
74
        final IOContainer ioContainer = instance.getIOContainer();
95
        final IOContainer ioContainer = instance.getIOContainer();
75
        final IOProvider term = IOProvider.get("Terminal"); // NOI18N
96
        final IOProvider term = IOProvider.get("Terminal"); // NOI18N
76
        if (term != null) {
97
        assert term != null;
77
            final ExecutionEnvironment env = getEnvironment();
98
78
            if (env != null) {
99
        boolean silentMode = TerminalContainerTopComponent.SILENT_MODE_COMMAND.equals(e.getActionCommand());
79
                TerminalSupportImpl.openTerminalImpl(ioContainer, env.getDisplayName(), env, null, TerminalContainerTopComponent.SILENT_MODE_COMMAND.equals(e.getActionCommand()));
100
80
            }
101
        final URI connectionURI = getConnectionURI();
102
        if (connectionURI == null) {
103
            return;
104
        }
105
106
        try {
107
            ConnectionProvider provider = Lookup.getDefault().lookup(ConnectionProvider.class);
108
109
            // XXX disable action when lookup empty
110
            final org.netbeans.api.extexecution.ProcessBuilder.Provider pbp =
111
                    provider.getConnection(connectionURI);
112
113
            TerminalSupportImpl.openTerminalImpl(
114
                    ioContainer,
115
                    null,
116
                    pbp,
117
                    null, /* dir */
118
                    silentMode);
119
        } catch (InterruptedIOException ex) {
120
            return;
121
        } catch (NoRouteToHostException ex) {
122
            DialogDisplayer.getDefault().notify(new NotifyDescriptor.Message(
123
                    Bundle.UnreachableHostError(connectionURI.getHost()),
124
                    NotifyDescriptor.ERROR_MESSAGE));
125
        } catch (IOException ex) {
126
            Exceptions.printStackTrace(ex);
81
        }
127
        }
82
    }
128
    }
83
129
Lines 86-90 Link Here
86
        return TerminalSupportImpl.getToolbarPresenter(this);
132
        return TerminalSupportImpl.getToolbarPresenter(this);
87
    }
133
    }
88
134
89
    protected abstract ExecutionEnvironment getEnvironment();
135
    protected abstract URI getConnectionURI();
136
137
    @NbBundle.Messages({
138
            "module install_title=Native Execution API installation",
139
            "module_install_question=Terminal requires Native Execution API support. Do you want to install it now?",
140
            "native_execution=Native Execution API"
141
    })
142
    public static boolean checkInstalled() {
143
        if (Lookup.getDefault().lookup(ConnectionProvider.class) != null) {
144
            return true;
145
        }
146
        NotifyDescriptor d = new NotifyDescriptor.Confirmation(Bundle.module_install_question(),
147
                Bundle.module_install_title(), NotifyDescriptor.YES_NO_OPTION);
148
        if (DialogDisplayer.getDefault().notify(d) == NotifyDescriptor.YES_OPTION) {
149
            return null == PluginManager.installSingle(NATIVE_EXECUTION, Bundle.native_execution());
150
        }
151
        return false;
152
    }
90
}
153
}
(-)a/dlight.terminal/src/org/netbeans/modules/dlight/terminal/action/TerminalSupportImpl.java (-166 / +71 lines)
Lines 39-82 Link Here
39
 *
39
 *
40
 * Portions Copyrighted 2011 Sun Microsystems, Inc.
40
 * Portions Copyrighted 2011 Sun Microsystems, Inc.
41
 */
41
 */
42
43
package org.netbeans.modules.dlight.terminal.action;
42
package org.netbeans.modules.dlight.terminal.action;
44
43
45
import java.awt.Component;
44
import java.awt.Component;
46
import java.beans.PropertyChangeEvent;
45
import java.beans.PropertyChangeEvent;
47
import java.beans.PropertyChangeListener;
46
import java.beans.PropertyChangeListener;
48
import java.io.IOException;
47
import java.io.IOException;
49
import java.util.concurrent.ExecutionException;
48
import java.net.ConnectException;
50
import java.util.concurrent.Future;
51
import java.util.concurrent.TimeUnit;
52
import java.util.concurrent.TimeoutException;
53
import java.util.concurrent.atomic.AtomicBoolean;
54
import java.util.concurrent.atomic.AtomicReference;
55
import javax.swing.Action;
49
import javax.swing.Action;
56
import javax.swing.Icon;
50
import javax.swing.Icon;
57
import javax.swing.JButton;
51
import javax.swing.JButton;
58
import javax.swing.SwingUtilities;
52
import org.netbeans.modules.dlight.api.terminal.ProcessTerminal;
59
import javax.swing.event.ChangeEvent;
53
import org.netbeans.modules.dlight.spi.terminal.ShellConfiguration;
60
import javax.swing.event.ChangeListener;
54
import org.netbeans.modules.dlight.spi.terminal.TerminalConfiguration;
61
import org.netbeans.modules.nativeexecution.api.ExecutionEnvironment;
55
import org.netbeans.modules.terminal.api.IOEmulation;
62
import org.netbeans.modules.nativeexecution.api.HostInfo;
63
import org.netbeans.modules.nativeexecution.api.NativeProcess;
64
import org.netbeans.modules.nativeexecution.api.NativeProcessBuilder;
65
import org.netbeans.modules.nativeexecution.api.execution.NativeExecutionDescriptor;
66
import org.netbeans.modules.nativeexecution.api.execution.NativeExecutionService;
67
import org.netbeans.modules.nativeexecution.api.pty.PtySupport;
68
import org.netbeans.modules.nativeexecution.api.util.ConnectionManager;
69
import org.netbeans.modules.nativeexecution.api.util.ConnectionManager.CancellationException;
70
import org.netbeans.modules.nativeexecution.api.util.HostInfoUtils;
71
import org.netbeans.modules.terminal.api.IONotifier;
56
import org.netbeans.modules.terminal.api.IONotifier;
57
import org.netbeans.modules.terminal.api.IOResizable;
58
import org.netbeans.modules.terminal.api.IOTerm;
72
import org.netbeans.modules.terminal.api.IOVisibility;
59
import org.netbeans.modules.terminal.api.IOVisibility;
73
import org.openide.DialogDisplayer;
74
import org.openide.NotifyDescriptor;
75
import org.openide.util.Exceptions;
60
import org.openide.util.Exceptions;
76
import org.openide.util.ImageUtilities;
61
import org.openide.util.ImageUtilities;
77
import org.openide.util.NbBundle;
78
import org.openide.util.RequestProcessor;
62
import org.openide.util.RequestProcessor;
79
import org.openide.util.WeakListeners;
80
import org.openide.windows.IOContainer;
63
import org.openide.windows.IOContainer;
81
import org.openide.windows.IOProvider;
64
import org.openide.windows.IOProvider;
82
import org.openide.windows.InputOutput;
65
import org.openide.windows.InputOutput;
Lines 86-96 Link Here
86
 * @author Vladimir Voskresensky
69
 * @author Vladimir Voskresensky
87
 */
70
 */
88
public final class TerminalSupportImpl {
71
public final class TerminalSupportImpl {
72
89
    private static final RequestProcessor RP = new RequestProcessor("Terminal Action RP", 100); // NOI18N
73
    private static final RequestProcessor RP = new RequestProcessor("Terminal Action RP", 100); // NOI18N
90
74
91
    private TerminalSupportImpl() {
75
    private TerminalSupportImpl() {
76
        super();
92
    }
77
    }
93
    
78
94
    public static Component getToolbarPresenter(Action action) {
79
    public static Component getToolbarPresenter(Action action) {
95
        JButton button = new JButton(action);
80
        JButton button = new JButton(action);
96
        button.setBorderPainted(false);
81
        button.setBorderPainted(false);
Lines 107-269 Link Here
107
        button.setDisabledIcon(ImageUtilities.createDisabledIcon((Icon) icon));
92
        button.setDisabledIcon(ImageUtilities.createDisabledIcon((Icon) icon));
108
        return button;
93
        return button;
109
    }
94
    }
110
    
95
111
    public static void openTerminalImpl(final IOContainer ioContainer, final String tabTitle, final ExecutionEnvironment env, final String dir, final boolean silentMode) {
96
    public static void openTerminalImpl(final IOContainer ioContainer, final String title,
97
            final org.netbeans.api.extexecution.ProcessBuilder.Provider provider, final String dir, final boolean silentMode) {
98
112
        final IOProvider term = IOProvider.get("Terminal"); // NOI18N
99
        final IOProvider term = IOProvider.get("Terminal"); // NOI18N
113
        if (term != null) {
114
            final AtomicBoolean destroyed = new AtomicBoolean(false);
115
            Runnable runnable = new Runnable() {
116
100
117
                @Override
101
        if (term == null) {
118
                public void run() {
102
            return;
119
                    if (SwingUtilities.isEventDispatchThread()) {
120
                        ioContainer.requestActive();
121
                    } else {
122
                        doWork();
123
                    }
124
                }
125
126
                private void doWork() {
127
                    if (!ConnectionManager.getInstance().isConnectedTo(env)) {
128
                        try {
129
                            ConnectionManager.getInstance().connectTo(env);
130
                        } catch (IOException ex) {
131
                            if (!destroyed.get()) {
132
                                String error = ex.getCause() == null ? ex.getMessage() : ex.getCause().getMessage();
133
                                String msg = NbBundle.getMessage(TerminalSupportImpl.class, "TerminalAction.FailedToStart.text", error); // NOI18N
134
                                DialogDisplayer.getDefault().notify(new NotifyDescriptor.Message(msg, NotifyDescriptor.ERROR_MESSAGE));
135
                            }
136
                            return;
137
                        } catch (CancellationException ex) {
138
                            return;
139
                        }
140
                    }
141
142
                    final HostInfo hostInfo;
143
                    try {
144
                        hostInfo = HostInfoUtils.getHostInfo(env);
145
                        boolean isSupported = PtySupport.isSupportedFor(env);
146
                        if (!isSupported) {
147
                            if (!silentMode) {
148
                                String message;
149
150
                                if (hostInfo.getOSFamily() == HostInfo.OSFamily.WINDOWS) {
151
                                    message = NbBundle.getMessage(TerminalSupportImpl.class, "LocalTerminalNotSupported.error.nocygwin"); // NOI18N
152
                                } else {
153
                                    message = NbBundle.getMessage(TerminalSupportImpl.class, "LocalTerminalNotSupported.error"); // NOI18N
154
                                }
155
156
                                NotifyDescriptor nd = new NotifyDescriptor.Message(message, NotifyDescriptor.INFORMATION_MESSAGE);
157
                                DialogDisplayer.getDefault().notify(nd);
158
                            }
159
                            return;
160
                        }
161
                    } catch (IOException ex) {
162
                        Exceptions.printStackTrace(ex);
163
                        return;
164
                    } catch (CancellationException ex) {
165
                        Exceptions.printStackTrace(ex);
166
                        return;
167
                    }
168
169
                    final AtomicReference<InputOutput> ioRef = new AtomicReference<InputOutput>();
170
                    try {
171
                        ioRef.set(term.getIO(tabTitle, null, ioContainer));
172
173
                        NativeProcessBuilder npb = NativeProcessBuilder.newProcessBuilder(env);
174
                        npb.addNativeProcessListener(new NativeProcessListener(ioRef.get(), destroyed));
175
176
                        String shell = hostInfo.getLoginShell();
177
                        if (dir != null) {
178
                            npb.setWorkingDirectory(dir);
179
                        }
180
//                            npb.setWorkingDirectory("${HOME}");
181
                        npb.setExecutable(shell);
182
                        NativeExecutionDescriptor descr;
183
                        descr = new NativeExecutionDescriptor().controllable(true).frontWindow(true).inputVisible(true).inputOutput(ioRef.get());
184
                        descr.postExecution(new Runnable() {
185
186
                            @Override
187
                            public void run() {
188
                                ioRef.get().closeInputOutput();
189
                            }
190
                        });
191
                        NativeExecutionService es = NativeExecutionService.newService(npb, descr, "Terminal Emulator"); // NOI18N
192
                        Future<Integer> result = es.run();
193
                        // ask terminal to become active
194
                        SwingUtilities.invokeLater(this);
195
196
                        try {
197
                            // if terminal can not be started then ExecutionException should be thrown
198
                            // wait one second to see if terminal can not be started. otherwise it's OK to exit by TimeOut
199
                            result.get(1, TimeUnit.SECONDS);
200
                        } catch (TimeoutException ex) {
201
                            // we should be there
202
                        } catch (InterruptedException ex) {
203
                            Exceptions.printStackTrace(ex);
204
                        } catch (ExecutionException ex) {
205
                            if (!destroyed.get()) {
206
                                String error = ex.getCause() == null ? ex.getMessage() : ex.getCause().getMessage();
207
                                String msg = NbBundle.getMessage(TerminalSupportImpl.class, "TerminalAction.FailedToStart.text", error); // NOI18N
208
                                DialogDisplayer.getDefault().notify(new NotifyDescriptor.Message(msg, NotifyDescriptor.ERROR_MESSAGE));
209
                            }
210
                        }
211
                    } catch (java.util.concurrent.CancellationException ex) { // VK: don't quite understand who can throw it?
212
                        Exceptions.printStackTrace(ex);
213
                        reportInIO(ioRef.get(), ex);
214
                    }
215
                }
216
217
                private void reportInIO(InputOutput io, Exception ex) {
218
                    if (io != null && ex != null) {
219
                        io.getErr().print(ex.getLocalizedMessage());
220
                    }
221
                }
222
            };
223
            RP.post(runnable);
224
        }
225
    }
226
227
    private final static class NativeProcessListener implements ChangeListener, PropertyChangeListener {
228
229
        private final AtomicReference<NativeProcess> processRef;
230
        private final AtomicBoolean destroyed;
231
232
        public NativeProcessListener(InputOutput io, AtomicBoolean destroyed) {
233
            assert destroyed != null;
234
            this.destroyed = destroyed;
235
            this.processRef = new AtomicReference<NativeProcess>();
236
            IONotifier.addPropertyChangeListener(io, WeakListeners.propertyChange(NativeProcessListener.this, io));
237
        }
103
        }
238
104
239
        @Override
105
        try {
240
        public void stateChanged(ChangeEvent e) {
106
            org.netbeans.api.extexecution.ProcessBuilder pb;
241
            NativeProcess process = processRef.get();
107
            try {
242
            if (process == null && e.getSource() instanceof NativeProcess) {
108
                pb = provider.getProcessBuilder();
243
                processRef.compareAndSet(null, (NativeProcess) e.getSource());
109
            } catch (ConnectException ex) {
110
                return;
244
            }
111
            }
245
        }
246
112
247
        @Override
113
            final InputOutput termIO = term.getIO(title != null ? title : pb.getDescription(),
248
        public void propertyChange(PropertyChangeEvent evt) {
114
                    null, ioContainer);
249
            if (IOVisibility.PROP_VISIBILITY.equals(evt.getPropertyName()) && Boolean.FALSE.equals(evt.getNewValue())) {
115
250
                if (destroyed.compareAndSet(false, true)) {
116
            ShellConfiguration shellConfiguration = pb.getLookup().lookup(ShellConfiguration.class);
251
                    // term is closing => destroy process
117
            if (shellConfiguration == null) {
252
                    final NativeProcess proc = processRef.get();
118
                throw new IllegalStateException("No shell provided by the builder: " + pb.getDescription());
253
                    if (proc != null) {
119
            }
120
            pb.setExecutable(shellConfiguration.getShell());
121
            TerminalConfiguration tcc = pb.getLookup().lookup(TerminalConfiguration.class);
122
123
            if (tcc != null) {
124
                tcc.setTerminalMode(true);
125
                tcc.setEmulation(IOEmulation.getEmulation(termIO));
126
            }
127
128
            if (dir != null) {
129
                pb.setWorkingDirectory(dir);
130
            }
131
132
            final Process shell = pb.call();
133
134
            IOTerm.connect(termIO, shell.getOutputStream(), shell.getInputStream(), shell.getErrorStream());
135
            IONotifier.addPropertyChangeListener(termIO, new PropertyChangeListener() {
136
                @Override
137
                public void propertyChange(PropertyChangeEvent evt) {
138
                    if (IOVisibility.PROP_VISIBILITY.equals(evt.getPropertyName()) && Boolean.FALSE.equals(evt.getNewValue())) {
254
                        RP.submit(new Runnable() {
139
                        RP.submit(new Runnable() {
255
256
                            @Override
140
                            @Override
257
                            public void run() {
141
                            public void run() {
258
                                try {
142
                                try {
259
                                    proc.destroy();
143
                                    shell.destroy();
260
                                } catch (Throwable th) {
144
                                } catch (Throwable th) {
261
                                }
145
                                }
262
                            }
146
                            }
263
                        });
147
                        });
148
                    } else if (IOResizable.PROP_SIZE.equals(evt.getPropertyName())) {
149
                        IOResizable.Size size = (IOResizable.Size) evt.getNewValue();
150
                        ProcessTerminal.ttyResized(shell, size.cells, size.pixels);
264
                    }
151
                    }
265
                }
152
                }
266
            }
153
            });
154
155
            ioContainer.requestActive();
156
            termIO.select();
157
158
            RP.post(new Runnable() {
159
                @Override
160
                public void run() {
161
                    try {
162
                        shell.waitFor();
163
                    } catch (InterruptedException ex) {
164
                        Exceptions.printStackTrace(ex);
165
                    } finally {
166
                        termIO.closeInputOutput();
167
                    }
168
                }
169
            });
170
        } catch (IOException ex) {
171
            Exceptions.printStackTrace(ex);
267
        }
172
        }
268
    }
173
    }
269
}
174
}
(-)a/dlight.terminal/src/org/netbeans/modules/dlight/terminal/ui/RemoteInfoDialog.java (-14 / +21 lines)
Lines 49-62 Link Here
49
49
50
import java.awt.Component;
50
import java.awt.Component;
51
import java.awt.Toolkit;
51
import java.awt.Toolkit;
52
import java.net.URI;
53
import java.net.URISyntaxException;
52
import java.util.prefs.Preferences;
54
import java.util.prefs.Preferences;
53
import javax.swing.InputVerifier;
55
import javax.swing.InputVerifier;
54
import javax.swing.JComponent;
56
import javax.swing.JComponent;
55
import javax.swing.JTextField;
57
import javax.swing.JTextField;
56
import javax.swing.text.JTextComponent;
58
import javax.swing.text.JTextComponent;
57
import org.netbeans.modules.nativeexecution.api.ExecutionEnvironment;
59
import org.openide.util.Exceptions;
58
import org.netbeans.modules.nativeexecution.api.ExecutionEnvironmentFactory;
59
import org.netbeans.modules.nativeexecution.api.util.ConnectionManager;
60
import org.openide.util.NbPreferences;
60
import org.openide.util.NbPreferences;
61
61
62
/**
62
/**
Lines 233-242 Link Here
233
    private javax.swing.JTextField userField;
233
    private javax.swing.JTextField userField;
234
    // End of variables declaration//GEN-END:variables
234
    // End of variables declaration//GEN-END:variables
235
235
236
    private ExecutionEnvironment last;
236
    private URI last;
237
    public ExecutionEnvironment getExecutionEnvironment() {
237
    public URI getConnectionURI() {
238
        if (btnKnownHosts.isSelected()) {
238
        if (btnKnownHosts.isSelected()) {
239
            last = (ExecutionEnvironment) cbKnownHosts.getSelectedItem();
239
            last = (URI) cbKnownHosts.getSelectedItem();
240
        } else {
240
        } else {
241
            if (userField.getText().isEmpty() || hostField.getText().isEmpty()) {
241
            if (userField.getText().isEmpty() || hostField.getText().isEmpty()) {
242
                return null;
242
                return null;
Lines 250-268 Link Here
250
                } catch (NumberFormatException ex) {
250
                } catch (NumberFormatException ex) {
251
                }
251
                }
252
            }
252
            }
253
253
            try {
254
            last = ExecutionEnvironmentFactory.createNew(userField.getText(), hostField.getText(), port);
254
                last = new URI("ssh://" + userField.getText() + '@' + hostField.getText() + ':' + port);
255
            } catch (URISyntaxException ex) {
256
                Exceptions.printStackTrace(ex);
257
            }
255
        }
258
        }
256
        Preferences prefs = NbPreferences.forModule(RemoteInfoDialog.class);
259
        Preferences prefs = NbPreferences.forModule(RemoteInfoDialog.class);
257
        prefs.put(LAST_SELECTED_HOST, ExecutionEnvironmentFactory.toUniqueID(last));
260
        prefs.put(LAST_SELECTED_HOST, last.toString());
258
        return last;
261
        return last;
259
    }
262
    }
260
263
261
    private void fillHosts() {
264
    private void fillHosts() {
262
        cbKnownHosts.removeAllItems();
265
        cbKnownHosts.removeAllItems();        
263
        for (ExecutionEnvironment ee : ConnectionManager.getInstance().getRecentConnections()) {
266
//        for (ExecutionEnvironment ee : ConnectionManager.getInstance().getRecentConnections()) {
264
            cbKnownHosts.addItem(ee);
267
//            cbKnownHosts.addItem(ee);
265
        }
268
//        }
266
        boolean hasKnown = cbKnownHosts.getItemCount() > 0;
269
        boolean hasKnown = cbKnownHosts.getItemCount() > 0;
267
        btnKnownHosts.setEnabled(hasKnown);
270
        btnKnownHosts.setEnabled(hasKnown);
268
        if (hasKnown) {
271
        if (hasKnown) {
Lines 289-295 Link Here
289
            Preferences prefs = NbPreferences.forModule(RemoteInfoDialog.class);
292
            Preferences prefs = NbPreferences.forModule(RemoteInfoDialog.class);
290
            String eeID = prefs.get(LAST_SELECTED_HOST, "");
293
            String eeID = prefs.get(LAST_SELECTED_HOST, "");
291
            if (!eeID.isEmpty()) {
294
            if (!eeID.isEmpty()) {
292
                last = ExecutionEnvironmentFactory.fromUniqueID(eeID);
295
                try {
296
                    last = new URI(eeID);
297
                } catch (URISyntaxException ex) {
298
                    Exceptions.printStackTrace(ex);
299
                }
293
            }
300
            }
294
        }
301
        }
295
        fillHosts();
302
        fillHosts();
(-)a/execmerge/build.xml (+5 lines)
Line 0 Link Here
1
<?xml version="1.0" encoding="UTF-8"?>
2
<project basedir="." default="netbeans" name="execmerge">
3
    <description>Builds, tests, and runs the project org.netbeans.modules.execmerge</description>
4
    <import file="../nbbuild/templates/projectized.xml"/>
5
</project>
(-)a/execmerge/manifest.mf (+5 lines)
Line 0 Link Here
1
Manifest-Version: 1.0
2
OpenIDE-Module: org.netbeans.modules.execmerge
3
OpenIDE-Module-Implementation-Version: 1
4
OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/execmerge/resources/Bundle.properties
5
AutoUpdate-Show-In-Client: false
(-)a/execmerge/nbproject/project.properties (+3 lines)
Line 0 Link Here
1
javac.source=1.6
2
javac.compilerargs=-Xlint -Xlint:-serial
3
spec.version.base=1.0
(-)a/execmerge/nbproject/project.xml (+38 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.modules.execmerge</code-name-base>
7
            <module-dependencies>
8
                <dependency>
9
                    <code-name-base>org.netbeans.modules.cnd.execution</code-name-base>
10
                    <build-prerequisite/>
11
                    <compile-dependency/>
12
                    <run-dependency>
13
                        <specification-version>1.0</specification-version>
14
                    </run-dependency>
15
                </dependency>
16
                <dependency>
17
                    <code-name-base>org.netbeans.modules.dlight.nativeexecution</code-name-base>
18
                    <build-prerequisite/>
19
                    <compile-dependency/>
20
                    <run-dependency>
21
                        <specification-version>1.26</specification-version>
22
                    </run-dependency>
23
                </dependency>
24
                <dependency>
25
                    <code-name-base>org.openide.util</code-name-base>
26
                    <build-prerequisite/>
27
                    <compile-dependency/>
28
                    <run-dependency>
29
                        <specification-version>8.28</specification-version>
30
                    </run-dependency>
31
                </dependency>
32
            </module-dependencies>
33
            <public-packages>
34
                <package>org.netbeans.modules.execmerge</package>
35
            </public-packages>
36
        </data>
37
    </configuration>
38
</project>
(-)a/execmerge/src/org/netbeans/modules/execmerge/ConnectionUtils.java (+79 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2012 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 2012 Sun Microsystems, Inc.
41
 */
42
43
package org.netbeans.modules.execmerge;
44
45
import java.io.IOException;
46
import java.net.URI;
47
import java.net.URISyntaxException;
48
import org.netbeans.modules.cnd.execution.api.Connection;
49
import org.netbeans.modules.cnd.execution.api.ConnectionManager;
50
import org.netbeans.modules.nativeexecution.api.ExecutionEnvironment;
51
import org.openide.util.Exceptions;
52
53
/**
54
 *
55
 * @author akrasny
56
 */
57
public final class ConnectionUtils {
58
59
    private ConnectionUtils() {
60
    }
61
    
62
    public static Connection ExecutionEnvironment2Connection(ExecutionEnvironment env) {
63
        if (env.isLocal()) {
64
            return ConnectionManager.getLocalConnection();
65
        }
66
        
67
        try {
68
            URI uri = new URI("ssh://" + env.getUser() + "@" + env.getHost()); // NOI18N
69
            return ConnectionManager.connect(uri);
70
        } catch (IOException ex) {
71
            Exceptions.printStackTrace(ex);
72
        } catch (URISyntaxException ex) {
73
            Exceptions.printStackTrace(ex);
74
        }
75
        
76
        return ConnectionManager.getLocalConnection();
77
    }
78
79
}
(-)a/execmerge/src/org/netbeans/modules/execmerge/resources/Bundle.properties (+1 lines)
Line 0 Link Here
1
OpenIDE-Module-Name=Temp Module for Execution Merge
(-)a/extexecution/apichanges.xml (-1 / +45 lines)
Lines 104-109 Link Here
104
        <apidef name="extexecution_api">External Execution API</apidef>
104
        <apidef name="extexecution_api">External Execution API</apidef>
105
        <apidef name="extexecution_api_input">External Execution Input API</apidef>
105
        <apidef name="extexecution_api_input">External Execution Input API</apidef>
106
        <apidef name="extexecution_api_print">External Execution Input Printing API</apidef>
106
        <apidef name="extexecution_api_print">External Execution Input Printing API</apidef>
107
        <apidef name="extexecution_api_process">External Execution Process API</apidef>
107
        <apidef name="extexecution_api_startup">External Execution Startup Arguments API</apidef>
108
        <apidef name="extexecution_api_startup">External Execution Startup Arguments API</apidef>
108
        <apidef name="extexecution_spi">External Execution SPI</apidef>
109
        <apidef name="extexecution_spi">External Execution SPI</apidef>
109
        <apidef name="extexecution_spi_destroy">External Execution Process Destroy SPI</apidef>
110
        <apidef name="extexecution_spi_destroy">External Execution Process Destroy SPI</apidef>
Lines 115-121 Link Here
115
    <!-- ACTUAL CHANGES BEGIN HERE: -->
116
    <!-- ACTUAL CHANGES BEGIN HERE: -->
116
117
117
    <changes>
118
    <changes>
118
119
        <change>
120
            <summary>Enhance API and SPI to make it usable as a proxy to native execution</summary>
121
            <version major="1" minor="37"/>
122
            <date day="1" month="9" year="2013"/>
123
            <author login="phejl"/>
124
            <compatibility addition="yes"/>
125
            <description>
126
                <p>
127
                There is new SPI for <code>ProcessBuilder</code> named
128
                <code>ProcessBuilderImplementation2</code> which now implements
129
                <code>Lookup.Provider</code> to be extensible and provides
130
                a separate <code>Environment</code> object represented by
131
                the <code>EnvironmentImplementation</code> in the SPI.
132
                The <code>ProcessBuilder</code> itself allows access to those
133
                new features via <code>getLookup()</code> and
134
                <code>getEnvironment()</code> methods and it now also
135
                implements <code>Lookup.Provider</code>. The utility class
136
                <code>ProcessParameters</code> wraps up the parameters passed
137
                to the SPI for process creation. Instances of
138
                <code>Environment</code> API are created via
139
                <code>EnvironmentFactory</code> support class.
140
                </p>
141
                <p>
142
                There are also new classes extending a <code>Process</code>
143
                functionality named <code>ProcessCharset</code>,
144
                <code>ProcessId</code> and <code>ProcessSignal</code> allowing
145
                client to get the charset, to get ID and to send signal to
146
                a process. This might not be always supported and the support
147
                may be pre-checked.
148
                </p>
149
            </description>
150
            <class package="org.netbeans.api.extexecution" name="Environment"/>
151
            <class package="org.netbeans.api.extexecution" name="ExecutionService"/>
152
            <class package="org.netbeans.api.extexecution" name="ProcessBuilder"/>
153
            <class package="org.netbeans.api.extexecution.process" name="ProcessCharset"/>
154
            <class package="org.netbeans.api.extexecution.process" name="ProcessId"/>
155
            <class package="org.netbeans.api.extexecution.process" name="ProcessSignal"/>
156
            <class package="org.netbeans.spi.extexecution" name="EnvironmentFactory"/>
157
            <class package="org.netbeans.spi.extexecution" name="EnvironmentImplementation"/>
158
            <class package="org.netbeans.spi.extexecution" name="ProcessBuilderFactory"/>
159
            <class package="org.netbeans.spi.extexecution" name="ProcessBuilderImplementation2"/>
160
            <class package="org.netbeans.spi.extexecution" name="ProcessParameters"/>
161
            <issue number="232434"/>
162
        </change>
119
        <change>
163
        <change>
120
            <api name="extexecution_spi"/>
164
            <api name="extexecution_spi"/>
121
            <summary>Advice to throw UserQuestionException</summary>
165
            <summary>Advice to throw UserQuestionException</summary>
(-)a/extexecution/arch.xml (-5 / +20 lines)
Lines 67-72 Link Here
67
   <code>org.openide.windows.OutputWriter</code>. API provides common implementations too.
67
   <code>org.openide.windows.OutputWriter</code>. API provides common implementations too.
68
  </p>
68
  </p>
69
  <p>
69
  <p>
70
   The support API/SPI
71
   <api group="java" name="ExternalExecutionProcessAPI" type="export" category="stable" url="@TOP@org/netbeans/api/extexecution/process/package-summary.html"/>
72
   allows enhancement of process with additional data such as ID, character set
73
   and ability to send signals. Client can later easily check the feature is
74
   supported and perform the query or action.
75
  </p>
76
  <p>
70
   The SPI
77
   The SPI
71
   <api group="java" name="ExternalExecutionSPI" type="export" category="stable" url="@TOP@org/netbeans/spi/extexecution/package-summary.html"/>
78
   <api group="java" name="ExternalExecutionSPI" type="export" category="stable" url="@TOP@org/netbeans/spi/extexecution/package-summary.html"/>
72
   allows different implementations of process builder.
79
   allows different implementations of process builder.
Lines 170-177 Link Here
170
   <p>
177
   <p>
171
    The creation of the external process is supported by
178
    The creation of the external process is supported by
172
    <a href="@TOP@org/netbeans/api/extexecution/ExternalProcessBuilder.html">ExternalProcessBuilder</a>
179
    <a href="@TOP@org/netbeans/api/extexecution/ExternalProcessBuilder.html">ExternalProcessBuilder</a>
180
    and <a href="@TOP@org/netbeans/api/extexecution/ProcessBuilder.html">ProcessBuilder</a>
173
    to make things easier.
181
    to make things easier.
174
   </p>
182
   </p>
183
   <p>
184
    The process returned by default or custom builders may support additional
185
    features. To do so the process must be a Lookup.Provider and put
186
    the implementation of the feature to lookup. The possible extensions are
187
    located in <a href="@TOP@org/netbeans/api/extexecution/process/package-summary.html">org.netbeans.api.extexecution.process</a>
188
    package. The client then use static methods on respective classes in order
189
    to use the extended functionality.
190
   </p>
175
  </usecase>
191
  </usecase>
176
  <usecase id="handle-input" name="Processing the input">
192
  <usecase id="handle-input" name="Processing the input">
177
   <p>
193
   <p>
Lines 232-239 Link Here
232
    </p>
248
    </p>
233
    <p>
249
    <p>
234
      In order to do so it will implement
250
      In order to do so it will implement
235
      <a href="@TOP@org/netbeans/spi/extexecution/ProcessBuilderImplementation.html">
251
      <a href="@TOP@org/netbeans/spi/extexecution/ProcessBuilderImplementation2.html">
236
       ProcessBuilderImplementation</a> and pass
252
       ProcessBuilderImplementation2</a> and pass
237
      <a href="@TOP@org/netbeans/api/extexecution/ProcessBuilder.html">
253
      <a href="@TOP@org/netbeans/api/extexecution/ProcessBuilder.html">
238
       ProcessBuilder</a> to its clients. The API instances are created with
254
       ProcessBuilder</a> to its clients. The API instances are created with
239
      help of
255
      help of
Lines 510-518 Link Here
510
-->
526
-->
511
 <answer id="dep-platform">
527
 <answer id="dep-platform">
512
  <p>
528
  <p>
513
   No known platform dependencies. In future there could be need for native code
529
   No known platform dependencies. The platform dependent way of process
514
   in order to terminate the whole process tree created by execution of external
530
   termination is in a separate implementation module.
515
   process.
516
  </p>
531
  </p>
517
 </answer>
532
 </answer>
518
533
(-)a/extexecution/nbproject/project.xml (+1 lines)
Lines 88-93 Link Here
88
            <public-packages>
88
            <public-packages>
89
                <package>org.netbeans.api.extexecution</package>
89
                <package>org.netbeans.api.extexecution</package>
90
                <package>org.netbeans.api.extexecution.print</package>
90
                <package>org.netbeans.api.extexecution.print</package>
91
                <package>org.netbeans.api.extexecution.process</package>
91
                <package>org.netbeans.api.extexecution.input</package>
92
                <package>org.netbeans.api.extexecution.input</package>
92
                <package>org.netbeans.api.extexecution.startup</package>
93
                <package>org.netbeans.api.extexecution.startup</package>
93
                <package>org.netbeans.spi.extexecution</package>
94
                <package>org.netbeans.spi.extexecution</package>
(-)a/extexecution/src/org/netbeans/api/extexecution/Environment.java (+156 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2012 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 2012 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.api.extexecution;
43
44
import java.util.Map;
45
import org.netbeans.api.annotations.common.CheckForNull;
46
import org.netbeans.api.annotations.common.NonNull;
47
import org.netbeans.modules.extexecution.EnvironmentAccessor;
48
import org.netbeans.spi.extexecution.EnvironmentImplementation;
49
import org.openide.util.Parameters;
50
51
/**
52
 * The class that provides an access to environment variables.
53
 *
54
 * @see ProcessBuilder#getEnvironment()
55
 * @see EnvironmentImplementation
56
 * @author Petr Hejl
57
 * @since 1.37
58
 */
59
public final class Environment {
60
61
    private final EnvironmentImplementation implementation;
62
63
    static {
64
        EnvironmentAccessor.setDefault(new EnvironmentAccessor() {
65
66
            @Override
67
            public Environment createEnvironment(EnvironmentImplementation impl) {
68
                return new Environment(impl);
69
            }
70
        });
71
    }
72
73
    private Environment(EnvironmentImplementation implementation) {
74
        this.implementation = implementation;
75
    }
76
77
    /**
78
     * Returns the value of the variable or <code>null</code>.
79
     *
80
     * @param name the name of the variable
81
     * @return the value of the variable or <code>null</code>
82
     */
83
    @CheckForNull
84
    public String getVariable(@NonNull String name) {
85
        Parameters.notNull("name", name);
86
87
        return implementation.getVariable(name);
88
    }
89
90
    /**
91
     * Appends a path to a path-like variable. The proper path separator is used
92
     * to separate the new value.
93
     *
94
     * @param name the name of the variable such as for example
95
     *             <code>PATH</code> or <code>LD_LIBRARY_PATH</code>
96
     * @param value the value (path to append)
97
     */
98
    public void appendPath(@NonNull String name, @NonNull String value) {
99
        Parameters.notNull("name", name);
100
        Parameters.notNull("value", value);
101
102
        implementation.appendPath(name, value);
103
    }
104
105
    /**
106
     * Prepends a path to a path-like variable. The proper path separator is used
107
     * to separate the new value.
108
     *
109
     * @param name the name of the variable such as for example
110
     *             <code>PATH</code> or <code>LD_LIBRARY_PATH</code>
111
     * @param value the value (path to prepend)
112
     */
113
    public void prependPath(@NonNull String name, @NonNull String value) {
114
        Parameters.notNull("name", name);
115
        Parameters.notNull("value", value);
116
117
        implementation.prependPath(name, value);
118
    }
119
120
    /**
121
     * Sets a value for a variable with the given name.
122
     *
123
     * @param name the name of the variable
124
     * @param value the value
125
     */
126
    public void setVariable(@NonNull String name, @NonNull String value) {
127
        Parameters.notNull("name", name);
128
        Parameters.notNull("value", value);
129
130
        implementation.setVariable(name, value);
131
    }
132
133
    /**
134
     * Removes a variable with the given name. The subsequent call to
135
     * {@link #getVariable(java.lang.String)} with the same argument will return
136
     * <code>null</code>.
137
     * 
138
     * @param name the name of the variable
139
     */
140
    public void removeVariable(@NonNull String name) {
141
        Parameters.notNull("name", name);
142
143
        implementation.removeVariable(name);
144
    }
145
146
    /**
147
     * Returns all variable names and associated values as a {@link Map}.
148
     * Changes to the map are not propagated back to the {@link Environment}.
149
     *
150
     * @return all variable names and associated values
151
     */
152
    @NonNull
153
    public Map<String, String> values() {
154
        return implementation.values();
155
    }
156
}
(-)a/extexecution/src/org/netbeans/api/extexecution/ExecutionService.java (-42 / +220 lines)
Lines 52-57 Link Here
52
import java.io.OutputStream;
52
import java.io.OutputStream;
53
import java.io.OutputStreamWriter;
53
import java.io.OutputStreamWriter;
54
import java.io.Reader;
54
import java.io.Reader;
55
import java.io.Writer;
55
import java.nio.charset.Charset;
56
import java.nio.charset.Charset;
56
import java.security.AccessController;
57
import java.security.AccessController;
57
import java.security.PrivilegedAction;
58
import java.security.PrivilegedAction;
Lines 66-75 Link Here
66
import java.util.concurrent.Future;
67
import java.util.concurrent.Future;
67
import java.util.concurrent.FutureTask;
68
import java.util.concurrent.FutureTask;
68
import java.util.concurrent.TimeUnit;
69
import java.util.concurrent.TimeUnit;
70
import java.util.concurrent.atomic.AtomicInteger;
69
import java.util.logging.Level;
71
import java.util.logging.Level;
70
import java.util.logging.Logger;
72
import java.util.logging.Logger;
71
import javax.swing.AbstractAction;
73
import javax.swing.AbstractAction;
72
import org.netbeans.api.annotations.common.NonNull;
74
import org.netbeans.api.annotations.common.NonNull;
75
import org.netbeans.api.annotations.common.NullAllowed;
73
import org.netbeans.api.progress.ProgressHandle;
76
import org.netbeans.api.progress.ProgressHandle;
74
import org.netbeans.api.progress.ProgressHandleFactory;
77
import org.netbeans.api.progress.ProgressHandleFactory;
75
import org.netbeans.modules.extexecution.ProcessInputStream;
78
import org.netbeans.modules.extexecution.ProcessInputStream;
Lines 79-85 Link Here
79
import org.netbeans.api.extexecution.input.InputProcessors;
82
import org.netbeans.api.extexecution.input.InputProcessors;
80
import org.netbeans.api.extexecution.input.InputReaderTask;
83
import org.netbeans.api.extexecution.input.InputReaderTask;
81
import org.netbeans.api.extexecution.input.InputReaders;
84
import org.netbeans.api.extexecution.input.InputReaders;
85
import org.netbeans.api.extexecution.input.LineProcessor;
82
import org.netbeans.api.extexecution.input.LineProcessors;
86
import org.netbeans.api.extexecution.input.LineProcessors;
87
import org.netbeans.api.extexecution.process.ProcessCharset;
83
import org.openide.util.Cancellable;
88
import org.openide.util.Cancellable;
84
import org.openide.util.Mutex;
89
import org.openide.util.Mutex;
85
import org.openide.util.NbBundle;
90
import org.openide.util.NbBundle;
Lines 91-110 Link Here
91
 * Execution service provides the facility to execute the process while
96
 * Execution service provides the facility to execute the process while
92
 * displaying the output and handling the input.
97
 * displaying the output and handling the input.
93
 * <p>
98
 * <p>
94
 * It will execute the program with an associated I/O window, with stop and
99
 * It will execute the program with an associated I/O window, possibly with
95
 * restart buttons. It will also obey various descriptor properties such as
100
 * stop and restart buttons. It will also obey various descriptor properties
96
 * whether or not to show a progress bar.
101
 * such as whether or not to show a progress bar.
97
 * <p>
102
 * <p>
98
 * All processes launched by this class are terminated on VM exit (if
103
 * All processes launched by this class are terminated on VM exit (if
99
 * these are not finished or terminated earlier).
104
 * these are not finished or terminated earlier).
100
 * <p>
105
 * <p>
101
 * Note that once service is run for the first time, subsequents runs can be
106
 * Note that once service is run for the first time, subsequent runs can be
102
 * invoked by the user (rerun button) if it is allowed to do so
107
 * invoked by the user (rerun button) if it is allowed to do so
103
 * ({@link ExecutionDescriptor#isControllable()}).
108
 * ({@link ExecutionDescriptor#isControllable()}).
104
 *
109
 *
105
 * <div class="nonnormative">
110
 * <div class="nonnormative">
106
 * <p>
111
 * <p>
107
 * Sample usage - executing ls command:
112
 * Sample usage (ls command):
108
 * <pre>
113
 * <pre>
109
 *     ExecutionDescriptor descriptor = new ExecutionDescriptor()
114
 *     ExecutionDescriptor descriptor = new ExecutionDescriptor()
110
 *          .frontWindow(true).controllable(true);
115
 *          .frontWindow(true).controllable(true);
Lines 114-119 Link Here
114
 *     ExecutionService service = ExecutionService.newService(processBuilder, descriptor, "ls command");
119
 *     ExecutionService service = ExecutionService.newService(processBuilder, descriptor, "ls command");
115
 *     Future&lt;Integer&gt task = service.run();
120
 *     Future&lt;Integer&gt task = service.run();
116
 * </pre>
121
 * </pre>
122
 * <p>
123
 * Even simpler usage but without displaying output (ls command):
124
 * <pre>
125
 *     ExternalProcessBuilder processBuilder = new ExternalProcessBuilder("ls");
126
 *
127
 *     ExecutionService service = ExecutionService.newService(processBuilder, null, null);
128
 *     Future&lt;Integer&gt task = service.run();
129
 * </pre>
117
 * </div>
130
 * </div>
118
 *
131
 *
119
 * @author Petr Hejl
132
 * @author Petr Hejl
Lines 130-135 Link Here
130
143
131
    private static final ExecutorService EXECUTOR_SERVICE = new RequestProcessor(ExecutionService.class.getName(), Integer.MAX_VALUE);
144
    private static final ExecutorService EXECUTOR_SERVICE = new RequestProcessor(ExecutionService.class.getName(), Integer.MAX_VALUE);
132
145
146
    private static final InputProcessor NULL_PROCESSOR = new InputProcessor() {
147
148
        @Override
149
        public void processInput(char[] chars) throws IOException {
150
        }
151
152
        @Override
153
        public void reset() throws IOException {
154
        }
155
156
        @Override
157
        public void close() throws IOException {
158
        }
159
    };
160
133
    static {
161
    static {
134
        // rerun accessor
162
        // rerun accessor
135
        RerunAction.Accessor.setDefault(new RerunAction.Accessor() {
163
        RerunAction.Accessor.setDefault(new RerunAction.Accessor() {
Lines 156-171 Link Here
156
        });
184
        });
157
    }
185
    }
158
186
159
    private final Callable<Process> processCreator;
187
    private final Callable<? extends Process> processCreator;
160
188
161
    private final ExecutionDescriptor descriptor;
189
    private final ExecutionDescriptor descriptor;
162
190
163
    private final String originalDisplayName;
191
    private final String originalDisplayName;
164
192
165
    private ExecutionService(Callable<Process> processCreator, String displayName, ExecutionDescriptor descriptor) {
193
    private final Reader processInput;
194
195
    private final boolean rerunAllowed;
196
197
    private final AtomicInteger runCount = new AtomicInteger();
198
199
    private ExecutionService(Callable<? extends Process> processCreator, String displayName,
200
            ExecutionDescriptor descriptor, Reader processInput, boolean rerunAllowed) {
166
        this.processCreator = processCreator;
201
        this.processCreator = processCreator;
167
        this.originalDisplayName = displayName;
202
        this.originalDisplayName = displayName;
168
        this.descriptor = descriptor;
203
        this.descriptor = descriptor;
204
        this.processInput = processInput;
205
        this.rerunAllowed = rerunAllowed;
169
    }
206
    }
170
207
171
    /**
208
    /**
Lines 178-201 Link Here
178
     * @return new execution service
215
     * @return new execution service
179
     */
216
     */
180
    @NonNull
217
    @NonNull
181
    public static ExecutionService newService(@NonNull Callable<Process> processCreator,
218
    public static ExecutionService newService(@NonNull Callable<? extends Process> processCreator,
182
            @NonNull ExecutionDescriptor descriptor, @NonNull String displayName) {
219
            @NonNull ExecutionDescriptor descriptor, @NonNull String displayName) {
183
        return new ExecutionService(processCreator, displayName, descriptor);
220
        return new ExecutionService(processCreator, displayName, descriptor, null, true);
221
    }
222
223
    /**
224
     * Creates new execution service. Service will wrap up the processes
225
     * created by <code>processCreator</code> and will manage them. The service
226
     * <i>may not</i> be run more than once otherwise {@link IllegalStateException}
227
     * is thrown on {@link #run()}. No UI will be displayed.
228
     * <p>
229
     * Passed processInput will be implicitly closed when the execution (invoked by
230
     * {@link #run()}) is finished. The client should not use the reader passed
231
     * as argument anymore or the reader should be designed thread safe.
232
     *
233
     * @param processCreator callable returning the process to wrap up
234
     * @param outputProcessor processor processing lines of standard output;
235
     *             may be <code>null</code>
236
     * @param errorProcessor processor processing lines of standard error
237
     *             output; may be <code>null</code>
238
     * @param processorInput reader providing input for standard input of
239
     *             the created process. Once passed it either should not be
240
     *             used anymore or it should be designed to be thread safe.
241
     *             May be <code>null</code>.
242
     * @return new execution service
243
     * @since 1.37
244
     */
245
    @NonNull
246
    public static ExecutionService newService(@NonNull Callable<? extends Process> processCreator,
247
            @NullAllowed final LineProcessor outputProcessor, @NullAllowed final LineProcessor errorProcessor,
248
            @NullAllowed final Reader processorInput) {
249
        ExecutionDescriptor descriptor = new ExecutionDescriptor()
250
                .inputOutput(InputOutput.NULL);
251
252
        if (outputProcessor != null) {
253
            descriptor = descriptor.outProcessorFactory(new InputProcessorFactory() {
254
                @Override
255
                public InputProcessor newInputProcessor(InputProcessor defaultProcessor) {
256
                    return InputProcessors.bridge(outputProcessor);
257
                }
258
            });
259
        }
260
        if (errorProcessor != null) {
261
            descriptor = descriptor.errProcessorFactory(new InputProcessorFactory() {
262
                @Override
263
                public InputProcessor newInputProcessor(InputProcessor defaultProcessor) {
264
                    return InputProcessors.bridge(errorProcessor);
265
                }
266
            });
267
        }
268
269
        return new ExecutionService(processCreator, null, descriptor, processorInput, false);
270
    }
271
272
    /**
273
     * Creates new execution service. Service will wrap up the processes
274
     * created by <code>processCreator</code> and will manage them. The service
275
     * <i>may not</i> be run more than once otherwise {@link IllegalStateException}
276
     * is thrown on {@link #run()}. No UI will be displayed.
277
     * <p>
278
     * Passed inputWriter and errorWriter will be implicitly closed when the
279
     * execution (invoked by {@link #run()}) is finished. The client either
280
     * <i>should not use the passed writers anymore or these should be designed
281
     * to be thread safe</i>.
282
     *
283
     * @param processCreator callable returning the process to wrap up
284
     * @param outputWriter where to write standard output of the process. Once
285
     *             passed it either should not be used anymore or it should
286
     *             be designed to be thread safe. May be <code>null</code>.
287
     * @param errorWriter where to write standard error output of the process.
288
     *             Once passed it either should not be used anymore or it should
289
     *             be designed to be thread safe. May be <code>null</code>.
290
     * @return new execution service
291
     * @since 1.37
292
     */
293
    public static ExecutionService newService(@NonNull Callable<? extends Process> processCreator,
294
            @NullAllowed final Writer outputWriter, @NullAllowed final Writer errorWriter) {
295
        ExecutionDescriptor descriptor = new ExecutionDescriptor()
296
                .inputOutput(InputOutput.NULL);
297
298
        if (outputWriter != null) {
299
            descriptor = descriptor.outProcessorFactory(new InputProcessorFactory() {
300
                @Override
301
                public InputProcessor newInputProcessor(InputProcessor defaultProcessor) {
302
                    return InputProcessors.copying(outputWriter);
303
                }
304
            });
305
        }
306
        if (errorWriter != null) {
307
            descriptor = descriptor.errProcessorFactory(new InputProcessorFactory() {
308
                @Override
309
                public InputProcessor newInputProcessor(InputProcessor defaultProcessor) {
310
                    return InputProcessors.copying(errorWriter);
311
                }
312
            });
313
        }
314
315
        return new ExecutionService(processCreator, null, descriptor, null, false);
184
    }
316
    }
185
317
186
    /**
318
    /**
187
     * Runs the process described by this service. The call does not block
319
     * Runs the process described by this service. The call does not block
188
     * and the task is represented by the returned value. Integer returned
320
     * and the task is represented by the returned value. Integer returned
189
     * as a result of the {@link Future} is exit code of the process.
321
     * as a result of the {@link Future} is exit code of the process.
322
     * The ability to call this method multiple times depends on a way
323
     * in which the service has been created. Only service created by
324
     * {@link #newService(java.util.concurrent.Callable, org.netbeans.api.extexecution.ExecutionDescriptor, java.lang.String)}
325
     * may be run more than once.
190
     * <p>
326
     * <p>
191
     * The output tabs are reused (if caller does not use the custom one,
327
     * The output tabs are reused (if caller does not use the custom one,
192
     * see {@link ExecutionDescriptor#getInputOutput()}) - the tab to reuse
328
     * see {@link ExecutionDescriptor#getInputOutput()} or if it is not being
193
     * (if any) is selected by having the same name and same buttons
329
     * run without output tab, see {@link #newService(java.util.concurrent.Callable, org.netbeans.api.extexecution.input.LineProcessor, org.netbeans.api.extexecution.input.LineProcessor, java.io.Reader)})
194
     * (control and option). If there is no output tab to reuse new one
330
     * - the tab to reuse (if any) is selected by having the same name
195
     * is opened.
331
     * and same buttons (control and option). If there is no output tab to
332
     * reuse new one is opened.
196
     * <p>
333
     * <p>
197
     * This method can be invoked multiple times returning the different and
334
     * If the service has been created by {@link #newService(java.util.concurrent.Callable, org.netbeans.api.extexecution.input.LineProcessor, org.netbeans.api.extexecution.input.LineProcessor, java.io.Reader)}
198
     * unrelated {@link Future}s. On each call <code>Callable&lt;Process&gt;</code>
335
     * this method may be called only once. Subsequent calls will cause an
336
     * {@link IllegalStateException} to be thrown.
337
     * If the service has been created by {@link #newService(java.util.concurrent.Callable, org.netbeans.api.extexecution.ExecutionDescriptor, java.lang.String)}
338
     * this method can be invoked multiple times returning the different and
339
     * unrelated {@link Future}s.
340
     * <p>
341
     * On each call <code>Callable&lt;Process&gt;</code>
199
     * passed to {@link #newService(java.util.concurrent.Callable, org.netbeans.api.extexecution.ExecutionDescriptor, java.lang.String)}
342
     * passed to {@link #newService(java.util.concurrent.Callable, org.netbeans.api.extexecution.ExecutionDescriptor, java.lang.String)}
200
     * is invoked in order to create the process. If the process creation fails
343
     * is invoked in order to create the process. If the process creation fails
201
     * (throwing an exception) returned <code>Future</code> will throw
344
     * (throwing an exception) returned <code>Future</code> will throw
Lines 213-218 Link Here
213
    }
356
    }
214
357
215
    private Future<Integer> run(InputOutput required) {
358
    private Future<Integer> run(InputOutput required) {
359
        if (!rerunAllowed && runCount.incrementAndGet() > 1) {
360
            throw new IllegalStateException("Run invoked multimple times");
361
        }
362
216
        final InputOutputManager.InputOutputData ioData = getInputOutput(required);
363
        final InputOutputManager.InputOutputData ioData = getInputOutput(required);
217
364
218
        final String displayName = ioData.getDisplayName();
365
        final String displayName = ioData.getDisplayName();
Lines 220-228 Link Here
220
        final ProgressHandle handle = createProgressHandle(ioData.getInputOutput(), displayName, cancellable);
367
        final ProgressHandle handle = createProgressHandle(ioData.getInputOutput(), displayName, cancellable);
221
        final InputOutput io = ioData.getInputOutput();
368
        final InputOutput io = ioData.getInputOutput();
222
369
223
        final OutputWriter out = io.getOut();
370
        assert processInput == null || io == InputOutput.NULL;
224
        final OutputWriter err = io.getErr();
371
225
        final Reader in = io.getIn();
372
        final Reader in;
373
        if (processInput != null) {
374
            in = processInput;
375
        } else if (descriptor.isInputVisible() && io != InputOutput.NULL) {
376
            in = io.getIn();
377
        } else {
378
            in = null;
379
        }
226
380
227
        final CountDownLatch finishedLatch = new CountDownLatch(1);
381
        final CountDownLatch finishedLatch = new CountDownLatch(1);
228
382
Lines 267-289 Link Here
267
                    outStream = new ProcessInputStream(process, process.getInputStream());
421
                    outStream = new ProcessInputStream(process, process.getInputStream());
268
                    errStream = new ProcessInputStream(process, process.getErrorStream());
422
                    errStream = new ProcessInputStream(process, process.getErrorStream());
269
423
270
                    executor = Executors.newFixedThreadPool(descriptor.isInputVisible() ? 3 : 2);
424
                    executor = Executors.newFixedThreadPool(in != null ? 3 : 2);
271
425
272
                    Charset charset = descriptor.getCharset();
426
                    Charset charset = descriptor.getCharset();
427
                    Charset inputCharset = charset;
428
                    Charset outputCharset = charset;
429
                    Charset errorCharset = charset;
273
                    if (charset == null) {
430
                    if (charset == null) {
274
                        charset = Charset.defaultCharset();
431
                        inputCharset = ProcessCharset.getInputCharset(process);
432
                        outputCharset = ProcessCharset.getOutputCharset(process);
433
                        errorCharset = ProcessCharset.getErrorCharset(process);
434
                    }
435
                    if (inputCharset == null) {
436
                        inputCharset = Charset.defaultCharset();
437
                    }
438
                    if (outputCharset == null) {
439
                        outputCharset = Charset.defaultCharset();
440
                    }
441
                    if (errorCharset == null) {
442
                        errorCharset = Charset.defaultCharset();
275
                    }
443
                    }
276
444
277
                    tasks.add(InputReaderTask.newDrainingTask(
445
                    tasks.add(InputReaderTask.newDrainingTask(
278
                        InputReaders.forStream(new BufferedInputStream(outStream), charset),
446
                        InputReaders.forStream(new BufferedInputStream(outStream), outputCharset),
279
                        createOutProcessor(out)));
447
                        createOutProcessor(io)));
280
                    tasks.add(InputReaderTask.newDrainingTask(
448
                    tasks.add(InputReaderTask.newDrainingTask(
281
                        InputReaders.forStream(new BufferedInputStream(errStream), charset),
449
                        InputReaders.forStream(new BufferedInputStream(errStream), errorCharset),
282
                        createErrProcessor(err)));
450
                        createErrProcessor(io)));
283
                    if (descriptor.isInputVisible()) {
451
                    if (in != null) {
284
                        tasks.add(InputReaderTask.newTask(
452
                        tasks.add(InputReaderTask.newTask(
285
                            InputReaders.forReader(in),
453
                            InputReaders.forReader(in),
286
                            createInProcessor(process.getOutputStream())));
454
                            createInProcessor(process.getOutputStream(), inputCharset)));
287
                    }
455
                    }
288
                    for (InputReaderTask task : tasks) {
456
                    for (InputReaderTask task : tasks) {
289
                        executor.submit(task);
457
                        executor.submit(task);
Lines 568-582 Link Here
568
        Mutex.EVENT.readAccess(ui);
736
        Mutex.EVENT.readAccess(ui);
569
    }
737
    }
570
738
571
    private InputProcessor createOutProcessor(OutputWriter writer) {
739
    private InputProcessor createOutProcessor(InputOutput io) {
572
        LineConvertorFactory convertorFactory = descriptor.getOutConvertorFactory();
573
        InputProcessor outProcessor = null;
740
        InputProcessor outProcessor = null;
574
        if (descriptor.isOutLineBased()) {
741
        if (io != InputOutput.NULL) {
575
            outProcessor = InputProcessors.bridge(LineProcessors.printing(writer,
742
            LineConvertorFactory convertorFactory = descriptor.getOutConvertorFactory();
576
                    convertorFactory != null ? convertorFactory.newLineConvertor() : null, true));
743
            OutputWriter writer = io.getOut();
744
            if (descriptor.isOutLineBased()) {
745
                outProcessor = InputProcessors.bridge(LineProcessors.printing(writer,
746
                        convertorFactory != null ? convertorFactory.newLineConvertor() : null, true));
747
            } else {
748
                outProcessor = InputProcessors.printing(writer,
749
                        convertorFactory != null ? convertorFactory.newLineConvertor() : null, true);
750
            }
577
        } else {
751
        } else {
578
            outProcessor = InputProcessors.printing(writer,
752
            outProcessor = NULL_PROCESSOR;
579
                    convertorFactory != null ? convertorFactory.newLineConvertor() : null, true);
580
        }
753
        }
581
754
582
        InputProcessorFactory descriptorOutFactory = descriptor.getOutProcessorFactory();
755
        InputProcessorFactory descriptorOutFactory = descriptor.getOutProcessorFactory();
Lines 587-601 Link Here
587
        return outProcessor;
760
        return outProcessor;
588
    }
761
    }
589
762
590
    private InputProcessor createErrProcessor(OutputWriter writer) {
763
    private InputProcessor createErrProcessor(InputOutput io) {
591
        LineConvertorFactory convertorFactory = descriptor.getErrConvertorFactory();
592
        InputProcessor errProcessor = null;
764
        InputProcessor errProcessor = null;
593
        if (descriptor.isErrLineBased()) {
765
        if (io != InputOutput.NULL) {
594
            errProcessor = InputProcessors.bridge(LineProcessors.printing(writer,
766
            LineConvertorFactory convertorFactory = descriptor.getErrConvertorFactory();
595
                    convertorFactory != null ? convertorFactory.newLineConvertor() : null, false));
767
            OutputWriter writer = io.getErr();
768
            if (descriptor.isErrLineBased()) {
769
                errProcessor = InputProcessors.bridge(LineProcessors.printing(writer,
770
                        convertorFactory != null ? convertorFactory.newLineConvertor() : null, false));
771
            } else {
772
                errProcessor = InputProcessors.printing(writer,
773
                        convertorFactory != null ? convertorFactory.newLineConvertor() : null, false);
774
            }
596
        } else {
775
        } else {
597
            errProcessor = InputProcessors.printing(writer,
776
            errProcessor = NULL_PROCESSOR;
598
                    convertorFactory != null ? convertorFactory.newLineConvertor() : null, false);
599
        }
777
        }
600
778
601
        InputProcessorFactory descriptorErrFactory = descriptor.getErrProcessorFactory();
779
        InputProcessorFactory descriptorErrFactory = descriptor.getErrProcessorFactory();
Lines 606-613 Link Here
606
        return errProcessor;
784
        return errProcessor;
607
    }
785
    }
608
786
609
    private InputProcessor createInProcessor(OutputStream os) {
787
    private InputProcessor createInProcessor(OutputStream os, Charset charset) {
610
        return InputProcessors.copying(new OutputStreamWriter(os));
788
        return InputProcessors.copying(new OutputStreamWriter(os, charset));
611
    }
789
    }
612
790
613
    private static class ProgressCancellable implements Cancellable {
791
    private static class ProgressCancellable implements Cancellable {
(-)a/extexecution/src/org/netbeans/api/extexecution/ExternalProcessBuilder.java (-13 / +63 lines)
Lines 100-105 Link Here
100
100
101
    private final Map<String, String> envVariables = new HashMap<String, String>();
101
    private final Map<String, String> envVariables = new HashMap<String, String>();
102
102
103
    private final boolean emptySystemVariables;
104
103
    /**
105
    /**
104
     * Creates the new builder that will create the process by running
106
     * Creates the new builder that will create the process by running
105
     * given executable. Arguments must not be part of the string.
107
     * given executable. Arguments must not be part of the string.
Lines 117-122 Link Here
117
        this.arguments.addAll(builder.arguments);
119
        this.arguments.addAll(builder.arguments);
118
        this.paths.addAll(builder.paths);
120
        this.paths.addAll(builder.paths);
119
        this.envVariables.putAll(builder.envVariables);
121
        this.envVariables.putAll(builder.envVariables);
122
        this.emptySystemVariables = builder.emptySystemVariables;
120
    }
123
    }
121
124
122
    /**
125
    /**
Lines 286-292 Link Here
286
        }
289
        }
287
290
288
        Map<String, String> pbEnv = pb.environment();
291
        Map<String, String> pbEnv = pb.environment();
289
        Map<String, String> env = buildEnvironment(pbEnv);
292
        Map<String, String> env;
293
        if (emptySystemVariables) {
294
            pbEnv.clear();
295
            env = new HashMap<String, String>();
296
        } else {
297
            env = buildEnvironment(pbEnv);
298
        }
290
        pbEnv.putAll(env);
299
        pbEnv.putAll(env);
291
        String uuid = UUID.randomUUID().toString();
300
        String uuid = UUID.randomUUID().toString();
292
        pbEnv.put(WrapperProcess.KEY_UUID, uuid);
301
        pbEnv.put(WrapperProcess.KEY_UUID, uuid);
Lines 297-302 Link Here
297
        return wp;
306
        return wp;
298
    }
307
    }
299
308
309
    ExternalProcessBuilder emptySystemVariables(boolean emptySystemVariables) {
310
        BuilderData builder = new BuilderData(this);
311
        return new ExternalProcessBuilder(builder.emptySystemVariables(emptySystemVariables));
312
    }
313
300
    /**
314
    /**
301
     * Logs the given <code>pb</code> using the given <code>level</code>.
315
     * Logs the given <code>pb</code> using the given <code>level</code>.
302
     *
316
     *
Lines 331-348 Link Here
331
345
332
        // Find PATH environment variable - on Windows it can be some other
346
        // Find PATH environment variable - on Windows it can be some other
333
        // case and we should use whatever it has.
347
        // case and we should use whatever it has.
334
        String pathName = "PATH"; // NOI18N
348
        String pathName = getPathName(original);
335
336
        if (Utilities.isWindows()) {
337
            pathName = "Path"; // NOI18N
338
339
            for (String key : ret.keySet()) {
340
                if ("PATH".equals(key.toUpperCase(Locale.ENGLISH))) { // NOI18N
341
                    pathName = key;
342
                    break;
343
                }
344
            }
345
        }
346
349
347
        // TODO use StringBuilder
350
        // TODO use StringBuilder
348
        String currentPath = ret.get(pathName);
351
        String currentPath = ret.get(pathName);
Lines 362-367 Link Here
362
        return ret;
365
        return ret;
363
    }
366
    }
364
367
368
365
    // package level for unit testing
369
    // package level for unit testing
366
    List<String> buildArguments() {
370
    List<String> buildArguments() {
367
        if (!Utilities.isWindows()) {
371
        if (!Utilities.isWindows()) {
Lines 378-383 Link Here
378
        return result;
382
        return result;
379
    }
383
    }
380
384
385
    static void putPath(File path, String pathName, boolean prepend, Map<String, String> current) {
386
        String currentPath = current.get(pathName);
387
388
        if (currentPath == null) {
389
            currentPath = "";
390
        }
391
392
        if (prepend) {
393
            currentPath = path.getAbsolutePath().replace(" ", "\\ ") //NOI18N
394
                    + File.pathSeparator + currentPath;
395
        } else {
396
            currentPath = currentPath + File.pathSeparator
397
                    + path.getAbsolutePath().replace(" ", "\\ "); //NOI18N
398
        }
399
400
        if (!"".equals(currentPath.trim())) {
401
            current.put(pathName, currentPath);
402
        }
403
    }
404
405
    static String getPathName(Map<String, String> systemEnv) {
406
        // Find PATH environment variable - on Windows it can be some other
407
        // case and we should use whatever it has.
408
        String pathName = "PATH"; // NOI18N
409
410
        if (Utilities.isWindows()) {
411
            pathName = "Path"; // NOI18N
412
413
            for (String keySystem : systemEnv.keySet()) {
414
                if ("PATH".equals(keySystem.toUpperCase(Locale.ENGLISH))) { // NOI18N
415
                    pathName = keySystem;
416
                    break;
417
                }
418
            }
419
        }
420
        return pathName;
421
    }
422
381
    private static String escapeString(String s) {
423
    private static String escapeString(String s) {
382
        if (s.length() == 0) {
424
        if (s.length() == 0) {
383
            return "\"\""; // NOI18N
425
            return "\"\""; // NOI18N
Lines 475-480 Link Here
475
517
476
        private Map<String, String> envVariables = new HashMap<String, String>();
518
        private Map<String, String> envVariables = new HashMap<String, String>();
477
519
520
        private boolean emptySystemVariables;
521
478
        public BuilderData(String executable) {
522
        public BuilderData(String executable) {
479
            this.executable = executable;
523
            this.executable = executable;
480
        }
524
        }
Lines 486-491 Link Here
486
            this.arguments.addAll(builder.arguments);
530
            this.arguments.addAll(builder.arguments);
487
            this.paths.addAll(builder.paths);
531
            this.paths.addAll(builder.paths);
488
            this.envVariables.putAll(builder.envVariables);
532
            this.envVariables.putAll(builder.envVariables);
533
            this.emptySystemVariables = builder.emptySystemVariables;
489
        }
534
        }
490
535
491
        public BuilderData workingDirectory(File workingDirectory) {
536
        public BuilderData workingDirectory(File workingDirectory) {
Lines 521-526 Link Here
521
            envVariables.put(name, value);
566
            envVariables.put(name, value);
522
            return this;
567
            return this;
523
        }
568
        }
569
570
        public BuilderData emptySystemVariables(boolean emptySystemVariables) {
571
            this.emptySystemVariables = emptySystemVariables;
572
            return this;
573
        }
524
    }
574
    }
525
575
526
576
(-)a/extexecution/src/org/netbeans/api/extexecution/ProcessBuilder.java (-36 / +293 lines)
Lines 46-57 Link Here
46
import java.util.ArrayList;
46
import java.util.ArrayList;
47
import java.util.HashMap;
47
import java.util.HashMap;
48
import java.util.List;
48
import java.util.List;
49
import java.util.Locale;
49
import java.util.Map;
50
import java.util.Map;
50
import java.util.concurrent.Callable;
51
import java.util.concurrent.Callable;
51
import org.netbeans.api.annotations.common.NonNull;
52
import org.netbeans.api.annotations.common.NonNull;
52
import org.netbeans.api.annotations.common.NullAllowed;
53
import org.netbeans.api.annotations.common.NullAllowed;
53
import org.netbeans.modules.extexecution.ProcessBuilderAccessor;
54
import org.netbeans.modules.extexecution.ProcessBuilderAccessor;
55
import org.netbeans.modules.extexecution.ProcessParametersAccessor;
56
import org.netbeans.spi.extexecution.EnvironmentFactory;
57
import org.netbeans.spi.extexecution.EnvironmentImplementation;
54
import org.netbeans.spi.extexecution.ProcessBuilderImplementation;
58
import org.netbeans.spi.extexecution.ProcessBuilderImplementation;
59
import org.netbeans.spi.extexecution.ProcessBuilderImplementation2;
60
import org.netbeans.spi.extexecution.ProcessParameters;
61
import org.openide.util.Lookup;
55
import org.openide.util.NbBundle;
62
import org.openide.util.NbBundle;
56
import org.openide.util.Parameters;
63
import org.openide.util.Parameters;
57
import org.openide.util.UserQuestionException;
64
import org.openide.util.UserQuestionException;
Lines 68-102 Link Here
68
 * for creating the local machine OS processes.
75
 * for creating the local machine OS processes.
69
 * <p>
76
 * <p>
70
 * <i>Thread safety</i> of this class depends on thread safety of
77
 * <i>Thread safety</i> of this class depends on thread safety of
71
 * the {@link ProcessBuilderImplementation} the class is using. If it is thread
78
 * the implementation class.
79
 * <p>
80
 * If the {@link ProcessBuilderImplementation} is used and it is thread
72
 * safe (if possible the implementation should be even stateless) this class
81
 * safe (if possible the implementation should be even stateless) this class
73
 * is thread safe as well.
82
 * is thread safe as well.
83
 * <p>
84
 * If the {@link ProcessBuilderImplementation2} is used and it is (including
85
 * {@link EnvironmentImplementation}) thread safe and does not have any mutable
86
 * configuration accessible via {@link ProcessBuilderImplementation2#getLookup()}
87
 * it is thread safe as well. Otherwise it is not thread safe.
88
 * <p>
89
 * The synchronization mechanism use in this object is the {@link ProcessBuilderImplementation}
90
 * or {@link ProcessBuilderImplementation2} object monitor.
74
 *
91
 *
75
 * @author Petr Hejl
92
 * @author Petr Hejl
76
 * @since 1.28
93
 * @since 1.28
77
 */
94
 */
78
public final class ProcessBuilder implements Callable<Process> {
95
public final class ProcessBuilder implements Callable<Process>, Lookup.Provider {
79
96
80
    private final ProcessBuilderImplementation implementation;
97
    private final ProcessBuilderImplementation implementation;
81
98
99
    private final ProcessBuilderImplementation2 implementation2;
100
101
    private final Object lock;
102
82
    private final String description;
103
    private final String description;
83
104
84
    /**<i>GuardedBy("this")</i>*/
105
    /**<i>GuardedBy("lock")</i>*/
85
    private String executable;
106
    private String executable;
86
107
87
    /**<i>GuardedBy("this")</i>*/
108
    /**<i>GuardedBy("lock")</i>*/
88
    private String workingDirectory;
109
    private String workingDirectory;
89
110
90
    /**<i>GuardedBy("this")</i>*/
111
    /**<i>GuardedBy("lock")</i>*/
91
    private List<String> arguments = new ArrayList<String>();
112
    private List<String> arguments = new ArrayList<String>();
92
113
93
    /**<i>GuardedBy("this")</i>*/
114
    /**<i>GuardedBy("lock")</i>*/
94
    private List<String> paths = new ArrayList<String>();
115
    private List<String> paths = new ArrayList<String>();
95
116
96
    /**<i>GuardedBy("this")</i>*/
117
    /**<i>GuardedBy("lock")</i>*/
97
    private Map<String, String> envVariables = new HashMap<String, String>();
118
    private Map<String, String> envVariables = new HashMap<String, String>();
98
119
99
    /**<i>GuardedBy("this")</i>*/
120
    /**<i>GuardedBy("lock")</i>*/
100
    private boolean redirectErrorStream;
121
    private boolean redirectErrorStream;
101
122
102
    static {
123
    static {
Lines 106-117 Link Here
106
            public ProcessBuilder createProcessBuilder(ProcessBuilderImplementation impl, String description) {
127
            public ProcessBuilder createProcessBuilder(ProcessBuilderImplementation impl, String description) {
107
                return new ProcessBuilder(impl, description);
128
                return new ProcessBuilder(impl, description);
108
            }
129
            }
130
131
            @Override
132
            public ProcessBuilder createProcessBuilder(ProcessBuilderImplementation2 impl, String description) {
133
                return new ProcessBuilder(impl, description);
134
            }
109
        });
135
        });
110
    }
136
    }
111
137
112
    private ProcessBuilder(ProcessBuilderImplementation implementation, String description) {
138
    private ProcessBuilder(ProcessBuilderImplementation implementation, String description) {
139
        this(implementation, null, description);
140
    }
141
142
    private ProcessBuilder(ProcessBuilderImplementation2 implementation2, String description) {
143
        this(null, implementation2, description);
144
    }
145
146
    private ProcessBuilder(ProcessBuilderImplementation implementation, ProcessBuilderImplementation2 implementation2, String description) {
147
        assert implementation == null || implementation2 == null;
113
        this.implementation = implementation;
148
        this.implementation = implementation;
149
        this.implementation2 = implementation2;
114
        this.description = description;
150
        this.description = description;
151
        if (implementation != null) {
152
            lock = implementation;
153
        } else {
154
            lock = implementation2;
155
        }
115
    }
156
    }
116
157
117
    /**
158
    /**
Lines 122-128 Link Here
122
     *             machine
163
     *             machine
123
     */
164
     */
124
    public static ProcessBuilder getLocal() {
165
    public static ProcessBuilder getLocal() {
125
        return new ProcessBuilder(new LocalProcessFactory(),
166
        return new ProcessBuilder(new LocalProcessBuilder(),
126
                NbBundle.getMessage(ProcessBuilder.class, "LocalProcessBuilder"));
167
                NbBundle.getMessage(ProcessBuilder.class, "LocalProcessBuilder"));
127
    }
168
    }
128
169
Lines 146-152 Link Here
146
    public void setExecutable(@NonNull String executable) {
187
    public void setExecutable(@NonNull String executable) {
147
        Parameters.notNull("executable", executable);
188
        Parameters.notNull("executable", executable);
148
189
149
        synchronized (this) {
190
        synchronized (lock) {
150
            this.executable = executable;
191
            this.executable = executable;
151
        }
192
        }
152
    }
193
    }
Lines 158-164 Link Here
158
     * @param workingDirectory the working directory of the process
199
     * @param workingDirectory the working directory of the process
159
     */
200
     */
160
    public void setWorkingDirectory(@NullAllowed String workingDirectory) {
201
    public void setWorkingDirectory(@NullAllowed String workingDirectory) {
161
        synchronized (this) {
202
        synchronized (lock) {
162
            this.workingDirectory = workingDirectory;
203
            this.workingDirectory = workingDirectory;
163
        }
204
        }
164
    }
205
    }
Lines 172-178 Link Here
172
    public void setArguments(@NonNull List<String> arguments) {
213
    public void setArguments(@NonNull List<String> arguments) {
173
        Parameters.notNull("arguments", arguments);
214
        Parameters.notNull("arguments", arguments);
174
215
175
        synchronized (this) {
216
        synchronized (lock) {
176
            this.arguments.clear();
217
            this.arguments.clear();
177
            this.arguments.addAll(arguments);
218
            this.arguments.addAll(arguments);
178
        }
219
        }
Lines 184-194 Link Here
184
     * exception of <code>PATH</code> possibly configured by {@link #setPaths(java.util.List)}.
225
     * exception of <code>PATH</code> possibly configured by {@link #setPaths(java.util.List)}.
185
     *
226
     *
186
     * @param envVariables the environment variables for the process
227
     * @param envVariables the environment variables for the process
228
     * @deprecated use {@link Environment#setVariable(java.lang.String, java.lang.String)}
229
     *             on object received by {@link #getEnvironment()} call
187
     */
230
     */
188
    public void setEnvironmentVariables(@NonNull Map<String, String> envVariables) {
231
    public void setEnvironmentVariables(@NonNull Map<String, String> envVariables) {
189
        Parameters.notNull("envVariables", envVariables);
232
        Parameters.notNull("envVariables", envVariables);
190
233
191
        synchronized (this) {
234
        if (implementation2 != null) {
235
            for (Map.Entry<String, String> entry : envVariables.entrySet()) {
236
                implementation2.getEnvironment().setVariable(entry.getKey(), entry.getValue());
237
            }
238
            return;
239
        }
240
241
        synchronized (lock) {
192
            this.envVariables.clear();
242
            this.envVariables.clear();
193
            this.envVariables.putAll(envVariables);
243
            this.envVariables.putAll(envVariables);
194
        }
244
        }
Lines 196-210 Link Here
196
246
197
    /**
247
    /**
198
     * Sets the additional paths to be included in <code>PATH</code> environment
248
     * Sets the additional paths to be included in <code>PATH</code> environment
199
     * variable for the process.
249
     * variable for the process. The paths are prepended to the PATH variable
250
     * one by one as specified in the list so in fact the last path in
251
     * the list will be the first one in the PATH variable.
252
     * <p>
253
     * This method is <i>semi-deprecated</i>. If {@link #getEnvironment()} is not
254
     * <code>null</code> this call adds paths one by one by call to
255
     * {@link Environment#prependPath(java.lang.String, java.lang.String)}
256
     * on returned object.
200
     *
257
     *
201
     * @param paths the additional paths to be included in <code>PATH</code>
258
     * @param paths the additional paths to be included in <code>PATH</code>
202
     *             environment variable
259
     *             environment variable
260
     * @deprecated use {@link Environment#prependPath(java.lang.String, java.lang.String)}
261
     *             on object received by {@link #getEnvironment()} call, with
262
     *             the first argument being <code>PATH</code>
203
     */
263
     */
204
    public void setPaths(@NonNull List<String> paths) {
264
    public void setPaths(@NonNull List<String> paths) {
205
        Parameters.notNull("paths", paths);
265
        Parameters.notNull("paths", paths);
206
266
207
        synchronized (this) {
267
        if (implementation2 != null) {
268
            for (String path : paths) {
269
                implementation2.getEnvironment().prependPath("PATH", path); // NOI18N
270
            }
271
            return;
272
        }
273
274
        synchronized (lock) {
208
            this.paths.clear();
275
            this.paths.clear();
209
            this.paths.addAll(paths);
276
            this.paths.addAll(paths);
210
        }
277
        }
Lines 218-229 Link Here
218
     * @param redirectErrorStream the error stream redirection
285
     * @param redirectErrorStream the error stream redirection
219
     */
286
     */
220
    public void setRedirectErrorStream(boolean redirectErrorStream) {
287
    public void setRedirectErrorStream(boolean redirectErrorStream) {
221
        synchronized (this) {
288
        synchronized (lock) {
222
            this.redirectErrorStream = redirectErrorStream;
289
            this.redirectErrorStream = redirectErrorStream;
223
        }
290
        }
224
    }
291
    }
225
292
226
    /**
293
    /**
294
     * Returns the object for environment variables manipulation.
295
     *
296
     * @return the object for environment variables manipulation
297
     * @since 1.37
298
     */
299
    @NonNull
300
    public Environment getEnvironment() {
301
        if (implementation2 != null) {
302
            return implementation2.getEnvironment();
303
        }
304
        return EnvironmentFactory.createEnvironment(new EnvironmentImplementation() {
305
306
            @Override
307
            public void prependPath(String name, String value) {
308
                if (!name.equalsIgnoreCase("PATH")) { // NOI18N
309
                    throw new UnsupportedOperationException("The deprecated implementation "
310
                            + implementation.getClass().getName() + "does not support this method for a non PATH variable.");
311
                }
312
                synchronized (lock) {
313
                    paths.add(0, value);
314
                }
315
            }
316
317
            @Override
318
            public void setVariable(String name, String value) {
319
                synchronized (lock) {
320
                    envVariables.put(name, value);
321
                }
322
            }
323
324
            @Override
325
            public String getVariable(String name) {
326
                throw new UnsupportedOperationException("The deprecated implementation "
327
                        + implementation.getClass().getName() + "does not support this method.");
328
            }
329
330
            @Override
331
            public void appendPath(String name, String value) {
332
                throw new UnsupportedOperationException("The deprecated implementation "
333
                        + implementation.getClass().getName() + "does not support this method.");
334
            }
335
336
            @Override
337
            public void removeVariable(String name) {
338
                throw new UnsupportedOperationException("The deprecated implementation "
339
                        + implementation.getClass().getName() + "does not support this method.");
340
            }
341
342
            @Override
343
            public Map<String, String> values() {
344
                throw new UnsupportedOperationException("The deprecated implementation "
345
                        + implementation.getClass().getName() + "does not support this method.");
346
            }
347
        });
348
    }
349
350
    /**
351
     * Returns the associated {@link Lookup}. Extension point provided by
352
     * {@link ProcessBuilderImplementation2}.
353
     *
354
     * @return the associated {@link Lookup}.
355
     * @see ProcessBuilderImplementation2#getLookup()
356
     * @since 1.37
357
     */
358
    @Override
359
    public Lookup getLookup() {
360
        if (implementation2 != null) {
361
            return implementation2.getLookup();
362
        }
363
        return Lookup.EMPTY;
364
    }
365
366
367
    /**
227
     * Creates the new {@link Process} based on the properties configured
368
     * Creates the new {@link Process} based on the properties configured
228
     * in this builder.
369
     * in this builder.
229
     * <p>
370
     * <p>
Lines 232-238 Link Here
232
     * <p>
373
     * <p>
233
     * Since version 1.35 implementors of this method are advised to throw
374
     * Since version 1.35 implementors of this method are advised to throw
234
     * a {@link UserQuestionException} in case the execution cannot be
375
     * a {@link UserQuestionException} in case the execution cannot be
235
     * performed and requires additional user confirmation, or configuration. 
376
     * performed and requires additional user confirmation, or configuration.
236
     * Callers of this method may check for this exception and handle it
377
     * Callers of this method may check for this exception and handle it
237
     * appropriately.
378
     * appropriately.
238
     *
379
     *
Lines 248-299 Link Here
248
    @NonNull
389
    @NonNull
249
    @Override
390
    @Override
250
    public Process call() throws IOException {
391
    public Process call() throws IOException {
251
        String currentExecutable = null;
392
        String currentExecutable;
252
        String currentWorkingDirectory = null;
393
        String currentWorkingDirectory;
253
        List<String> currentArguments = new ArrayList<String>();
394
        List<String> currentArguments = new ArrayList<String>();
254
        List<String> currentPaths = new ArrayList<String>();
395
        List<String> currentPaths = new ArrayList<String>();
255
        Map<String, String> currentEnvVariables = new HashMap<String, String>();
396
        Map<String, String> currentVariables = new HashMap<String, String>();
256
        boolean currentRedirectErrorStream = false;
397
        boolean currentRedirectErrorStream;
257
398
258
        synchronized (this) {
399
        synchronized (lock) {
259
            currentExecutable = executable;
400
            currentExecutable = executable;
260
            currentWorkingDirectory = workingDirectory;
401
            currentWorkingDirectory = workingDirectory;
261
            currentArguments.addAll(arguments);
402
            currentArguments.addAll(arguments);
262
            currentPaths.addAll(paths);
403
            currentPaths.addAll(paths);
263
            currentEnvVariables.putAll(envVariables);
264
            currentRedirectErrorStream = redirectErrorStream;
404
            currentRedirectErrorStream = redirectErrorStream;
405
            if (implementation2 != null) {
406
                currentVariables.putAll(getEnvironment().values());
407
            } else {
408
                currentVariables.putAll(envVariables);
409
            }
265
        }
410
        }
266
411
267
        if (currentExecutable == null) {
412
        if (currentExecutable == null) {
268
            throw new IllegalStateException("The executable has not been configured");
413
            throw new IllegalStateException("The executable has not been configured");
269
        }
414
        }
270
415
416
        if (implementation2 != null) {
417
            ProcessParameters params = ProcessParametersAccessor.getDefault().createProcessParameters(
418
                    currentExecutable, currentWorkingDirectory, currentArguments,
419
                    currentRedirectErrorStream, currentVariables);
420
            return implementation2.createProcess(params);
421
        }
422
271
        return implementation.createProcess(currentExecutable, currentWorkingDirectory, currentArguments,
423
        return implementation.createProcess(currentExecutable, currentWorkingDirectory, currentArguments,
272
                currentPaths, currentEnvVariables, currentRedirectErrorStream);
424
                currentPaths, currentVariables, currentRedirectErrorStream);
273
    }
425
    }
274
426
275
    private static class LocalProcessFactory implements ProcessBuilderImplementation {
427
    /**
428
     * Marks an object from which it is possible to get a {@link ProcessBuilder}.
429
     *
430
     * @since 1.37
431
     */
432
    public static interface Provider {
433
434
        /**
435
         * Returns the {@link ProcessBuilder} for the object.
436
         *
437
         * @return the {@link ProcessBuilder} for the object
438
         * @throws IOException if there was a problem with the provision
439
         */
440
        ProcessBuilder getProcessBuilder() throws IOException;
441
442
    }
443
444
    private static class LocalProcessBuilder implements ProcessBuilderImplementation2 {
445
446
        private final Environment environment = EnvironmentFactory.createEnvironment(
447
                new LocalEnvironment(this, System.getenv()));
276
448
277
        @Override
449
        @Override
278
        public Process createProcess(String executable, String workingDirectory, List<String> arguments,
450
        public Environment getEnvironment() {
279
                List<String> paths, Map<String, String> environment, boolean redirectErrorStream) throws IOException {
451
            return environment;
452
        }
280
453
281
            ExternalProcessBuilder builder = new ExternalProcessBuilder(executable);
454
        @Override
282
            if (workingDirectory != null) {
455
        public Lookup getLookup() {
283
                builder = builder.workingDirectory(new File(workingDirectory));
456
            return Lookup.EMPTY;
457
        }
458
459
        @Override
460
        public Process createProcess(ProcessParameters parameters) throws IOException {
461
            ExternalProcessBuilder builder = new ExternalProcessBuilder(parameters.getExecutable());
462
            String workingDir = parameters.getWorkingDirectory();
463
            if (workingDir != null) {
464
                builder = builder.workingDirectory(new File(workingDir));
284
            }
465
            }
285
            for (String argument : arguments) {
466
            for (String argument : parameters.getArguments()) {
286
                builder = builder.addArgument(argument);
467
                builder = builder.addArgument(argument);
287
            }
468
            }
288
            for (String path : paths) {
469
            builder = builder.redirectErrorStream(parameters.isRedirectErrorStream());
289
                builder = builder.prependPath(new File(path));
470
290
            }
471
            builder = builder.emptySystemVariables(true);
291
            for (Map.Entry<String, String> entry : environment.entrySet()) {
472
            for (Map.Entry<String, String> entry : parameters.getEnvironmentVariables().entrySet()) {
292
                builder = builder.addEnvironmentVariable(entry.getKey(), entry.getValue());
473
                builder = builder.addEnvironmentVariable(entry.getKey(), entry.getValue());
293
            }
474
            }
294
            builder = builder.redirectErrorStream(redirectErrorStream);
295
475
296
            return builder.call();
476
            return builder.call();
297
        }
477
        }
298
    }
478
    }
479
480
    private static class LocalEnvironment implements EnvironmentImplementation {
481
482
        private final LocalProcessBuilder builder;
483
484
        private final Map<String, String> systemEnvironment;
485
486
        private final String pathName;
487
488
        public LocalEnvironment(LocalProcessBuilder builder, Map<String, String> systemEnvironment) {
489
            this.builder = builder;
490
            this.systemEnvironment = new HashMap<String, String>(systemEnvironment);
491
            this.pathName = ExternalProcessBuilder.getPathName(systemEnvironment);
492
        }
493
494
        @Override
495
        public String getVariable(String name) {
496
            synchronized (builder) {
497
                if ("PATH".equals(name.toUpperCase(Locale.ENGLISH))) { // NOI18N
498
                    return systemEnvironment.get(pathName);
499
                } else {
500
                    return systemEnvironment.get(name);
501
                }
502
            }
503
        }
504
505
        @Override
506
        public void appendPath(String name, String value) {
507
            putPath(name, value, false);
508
        }
509
510
        @Override
511
        public void prependPath(String name, String value) {
512
            putPath(name, value, true);
513
        }
514
515
        @Override
516
        public void setVariable(String name, String value) {
517
            synchronized (builder) {
518
                if ("PATH".equals(name.toUpperCase(Locale.ENGLISH))) { // NOI18N
519
                    systemEnvironment.put(pathName, value);
520
                } else {
521
                    systemEnvironment.put(name, value);
522
                }
523
            }
524
        }
525
526
        @Override
527
        public void removeVariable(String name) {
528
            synchronized (builder) {
529
                if ("PATH".equals(name.toUpperCase(Locale.ENGLISH))) { // NOI18N
530
                    systemEnvironment.remove(pathName);
531
                } else {
532
                    systemEnvironment.remove(name);
533
                }
534
            }
535
        }
536
537
        @Override
538
        public Map<String, String> values() {
539
            synchronized (builder) {
540
                return new HashMap<String, String>(systemEnvironment);
541
            }
542
        }
543
544
        private void putPath(String name, String value, boolean prepend) {
545
            synchronized (builder) {
546
                if ("PATH".equals(name.toUpperCase(Locale.ENGLISH))) { // NOI18N
547
                    ExternalProcessBuilder.putPath(new File(value), pathName,
548
                            prepend, systemEnvironment);
549
                } else {
550
                    ExternalProcessBuilder.putPath(new File(value), name,
551
                            prepend, systemEnvironment);
552
                }
553
            }
554
        }
555
    }
299
}
556
}
(-)a/extexecution/src/org/netbeans/api/extexecution/input/InputReaders.java (+7 lines)
Lines 46-51 Link Here
46
import java.io.InputStream;
46
import java.io.InputStream;
47
import java.io.InputStreamReader;
47
import java.io.InputStreamReader;
48
import java.io.Reader;
48
import java.io.Reader;
49
import java.io.StringReader;
49
import java.nio.charset.Charset;
50
import java.nio.charset.Charset;
50
import org.netbeans.api.annotations.common.CheckForNull;
51
import org.netbeans.api.annotations.common.CheckForNull;
51
import org.netbeans.api.annotations.common.NonNull;
52
import org.netbeans.api.annotations.common.NonNull;
Lines 82-87 Link Here
82
     */
83
     */
83
    @NonNull
84
    @NonNull
84
    public static InputReader forReader(@NonNull Reader reader) {
85
    public static InputReader forReader(@NonNull Reader reader) {
86
        if (reader instanceof StringReader) {
87
            // unfortunatelly the string reader is always
88
            // ready (isReady() returns true) which I would consider a bug
89
            // when end of string is reached
90
            return new DefaultInputReader(reader, false);
91
        }
85
        return new DefaultInputReader(reader, true);
92
        return new DefaultInputReader(reader, true);
86
    }
93
    }
87
94
(-)a/extexecution/src/org/netbeans/api/extexecution/process/ProcessCharset.java (+169 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2012 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 2012 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.api.extexecution.process;
43
44
import java.nio.charset.Charset;
45
import org.netbeans.api.annotations.common.CheckForNull;
46
import org.netbeans.api.annotations.common.NonNull;
47
import org.openide.util.Lookup;
48
import org.openide.util.Parameters;
49
50
/**
51
 * This class allows client to get input and output charset of
52
 * the {@link Process}. Though the process charsets might not be always
53
 * supported.
54
 * <p>
55
 * If the {@link Process} implementation wants to support charsets it has to
56
 * implement {@link Lookup.Provider} and there has to be instance of this class
57
 * in the returned {@link Lookup}. The functionality itself is implemented in
58
 * methods {@link #getInputCharset()} and {@link #getOutputCharset()}.
59
 *
60
 * @author Petr Hejl
61
 * @since 1.37
62
 */
63
public abstract class ProcessCharset {
64
65
    private static ProcessCharset find(Process process) {
66
        if (process instanceof Lookup.Provider) {
67
            Lookup.Provider p = (Lookup.Provider) process;
68
            return p.getLookup().lookup(ProcessCharset.class);
69
        }
70
        return null;
71
    }
72
73
    /**
74
     * Checks whether the getting of charsets of the {@link Process} is supported.
75
     * If the return value is <code>false</code> methods
76
     * {@link #getInputCharset(java.lang.Process)} and {@link #getOutputCharset(java.lang.Process)}
77
     * will return <code>null</code> for sure.
78
     *
79
     * @param process the process to check
80
     * @return <code>true</code> if process charsets can be received <code>false</code>
81
     *             otherwise
82
     */
83
    public static boolean isSupported(@NonNull Process process) {
84
        Parameters.notNull("process", process);
85
86
        return find(process) != null;
87
    }
88
89
    /**
90
     * Returns the input charset of the process if supported. In case it is not
91
     * supported or the process can't determine the charset <code>null</code> is
92
     * returned.
93
     *
94
     * @param process the process
95
     * @return the input charset of the process or <code>null</code>
96
     */
97
    @CheckForNull
98
    public static Charset getInputCharset(@NonNull Process process) {
99
        Parameters.notNull("process", process);
100
101
        ProcessCharset processCharset = find(process);
102
        if (processCharset != null) {
103
            return processCharset.getInputCharset();
104
        }
105
        return null;
106
    }
107
108
    /**
109
     * Returns the output charset of the process if supported. In case it is not
110
     * supported or the process can't determine the charset <code>null</code> is
111
     * returned.
112
     *
113
     * @param process the process
114
     * @return the output charset of the process or <code>null</code>
115
     */
116
    @CheckForNull
117
    public static Charset getOutputCharset(@NonNull Process process) {
118
        Parameters.notNull("process", process);
119
120
        ProcessCharset processCharset = find(process);
121
        if (processCharset != null) {
122
            return processCharset.getOutputCharset();
123
        }
124
        return null;
125
    }
126
127
    /**
128
     * Returns the error output charset of the process if supported. In case it
129
     * is not supported or the process can't determine the charset <code>null</code>
130
     * is returned.
131
     *
132
     * @param process the process
133
     * @return the error output charset of the process or <code>null</code>
134
     */
135
    @CheckForNull
136
    public static Charset getErrorCharset(@NonNull Process process) {
137
        Parameters.notNull("process", process);
138
139
        ProcessCharset processCharset = find(process);
140
        if (processCharset != null) {
141
            return processCharset.getErrorCharset();
142
        }
143
        return null;
144
    }
145
146
    /**
147
     * Returns the input charset of a process or <code>null</code>.
148
     *
149
     * @return input charset of a process or <code>null</code>
150
     */
151
    @CheckForNull
152
    protected abstract Charset getInputCharset();
153
154
    /**
155
     * Returns the output charset of a process or <code>null</code>.
156
     *
157
     * @return output charset of a process or <code>null</code>
158
     */
159
    @CheckForNull
160
    protected abstract Charset getOutputCharset();
161
162
    /**
163
     * Returns the error output charset of a process or <code>null</code>.
164
     *
165
     * @return error output charset of a process or <code>null</code>
166
     */
167
    @CheckForNull
168
    protected abstract Charset getErrorCharset();
169
}
(-)a/extexecution/src/org/netbeans/api/extexecution/process/ProcessId.java (+111 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2012 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 2012 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.api.extexecution.process;
43
44
import org.netbeans.api.annotations.common.CheckForNull;
45
import org.netbeans.api.annotations.common.NonNull;
46
import org.openide.util.Lookup;
47
import org.openide.util.Parameters;
48
49
/**
50
 * This class allows client to request ID of the {@link Process}. Though
51
 * the process ID might not be always supported.
52
 * <p>
53
 * If the {@link Process} implementation wants to support the ID it has to
54
 * implement {@link Lookup.Provider} and there has to be instance of this class
55
 * in the returned {@link Lookup}. The functionality itself is implemented in
56
 * method {@link #getId()}.
57
 *
58
 * @author Petr Hejl
59
 * @since 1.37
60
 */
61
public abstract class ProcessId {
62
63
    private static ProcessId find(Process process) {
64
        if (process instanceof Lookup.Provider) {
65
            Lookup.Provider p = (Lookup.Provider) process;
66
            return p.getLookup().lookup(ProcessId.class);
67
        }
68
        return null;
69
    }
70
71
    /**
72
     * Checks whether the getting of the ID of the {@link Process} is supported.
73
     * If the return value is <code>false</code> the {@link #getId(java.lang.Process)}
74
     * will return <code>null</code> for sure.
75
     *
76
     * @param process the process to check
77
     * @return <code>true</code> if the ID can be received <code>false</code>
78
     *             otherwise
79
     */
80
    public static boolean isSupported(@NonNull Process process) {
81
        Parameters.notNull("process", process);
82
        
83
        return find(process) != null;
84
    }
85
86
    /**
87
     * Returns the ID of the process if supported. In case it is not supported
88
     * or the process can't determine its ID <code>null</code> is returned.
89
     *
90
     * @param process the process
91
     * @return the process ID or <code>null</code>
92
     */
93
    @CheckForNull
94
    public static Integer getId(@NonNull Process process) {
95
        Parameters.notNull("process", process);
96
97
        ProcessId processId = find(process);
98
        if (processId != null) {
99
            return processId.getId();
100
        }
101
        return null;
102
    }
103
104
    /**
105
     * Returns the ID of a process or <code>null</code>.
106
     *
107
     * @return ID of a process or <code>null</code>
108
     */
109
    @CheckForNull
110
    protected abstract Integer getId();
111
}
(-)a/extexecution/src/org/netbeans/api/extexecution/process/ProcessSignal.java (+181 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2012 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 2012 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.api.extexecution.process;
43
44
import java.io.IOException;
45
import org.netbeans.api.annotations.common.NonNull;
46
import org.openide.util.Lookup;
47
import org.openide.util.Parameters;
48
49
/**
50
 * This class allows client send a signal to the {@link Process} or to whole
51
 * its group. Though signal sending might not be always supported.
52
 * <p>
53
 * If the {@link Process} implementation wants to support the signal sending
54
 * it has to implement {@link Lookup.Provider} and there has to be instance
55
 * of this class in the returned {@link Lookup}. The functionality itself is
56
 * implemented in methods {@link #signal(org.netbeans.api.extexecution.process.ProcessSignal.Signal)}
57
 * and {@link #signalGroup(org.netbeans.api.extexecution.process.ProcessSignal.Signal)}.
58
 *
59
 * @author Petr Hejl
60
 * @since 1.37
61
 */
62
public abstract class ProcessSignal {
63
64
    private static ProcessSignal find(Process process) {
65
        if (process instanceof Lookup.Provider) {
66
            Lookup.Provider p = (Lookup.Provider) process;
67
            return p.getLookup().lookup(ProcessSignal.class);
68
        }
69
        return null;
70
    }
71
72
    /**
73
     * Checks whether the signal sending is supported for the {@link Process}.
74
     * If the return value is <code>false</code> the signal operations are
75
     * effectively noops.
76
     *
77
     * @param process the process to check
78
     * @return <code>true</code> if the signals can be send <code>false</code>
79
     *             otherwise
80
     */
81
    public static boolean isSupported(@NonNull Process process) {
82
        Parameters.notNull("process", process);
83
84
        return find(process) != null;
85
    }
86
87
    /**
88
     * Sends a signal to the process. If the signal sending is not supported
89
     * this is effectively noop.
90
     *
91
     * @param process the process where to send signal
92
     * @param signal the signal to send
93
     * @throws IOException if problem with signal sending occurs
94
     */
95
    public static void signal(@NonNull Process process, @NonNull Signal signal) throws IOException {
96
        Parameters.notNull("process", process);
97
        Parameters.notNull("signal", signal);
98
99
        ProcessSignal processSignal = find(process);
100
        if (processSignal != null) {
101
            processSignal.signal(signal);
102
        }
103
    }
104
105
    /**
106
     * Sends a signal to the group the process belongs to. If the signal sending
107
     * is not supported this is effectively noop.
108
     *
109
     * @param process the process marking the group where to send signal
110
     * @param signal the signal to send
111
     * @throws IOException if problem with signal sending occurs
112
     */
113
    public static void signalGroup(@NonNull Process process, @NonNull Signal signal) throws IOException {
114
        Parameters.notNull("process", process);
115
        Parameters.notNull("signal", signal);
116
117
        ProcessSignal processSignal = find(process);
118
        if (processSignal != null) {
119
            processSignal.signalGroup(signal);
120
        }
121
    }
122
123
    /**
124
     * Sends a given signal to the process.
125
     *
126
     * @param signal the signal to send
127
     * @throws IOException if problem with signal sending occurs
128
     */
129
    protected abstract void signal(@NonNull Signal signal) throws IOException;
130
131
    /**
132
     * Sends a given signal to the group the process belongs to.
133
     *
134
     * @param signal the signal to send
135
     * @throws IOException if problem with signal sending occurs
136
     */
137
    protected abstract void signalGroup(@NonNull Signal signal) throws IOException;
138
139
    public enum Signal {
140
141
        NULL,
142
        SIGHUP,
143
        SIGINT,
144
        SIGQUIT,
145
        SIGILL,
146
        SIGTRAP,
147
        SIGABRT,
148
        SIGEMT,
149
        SIGFPE,
150
        SIGKILL,
151
        SIGBUS,
152
        SIGSEGV,
153
        SIGSYS,
154
        SIGPIPE,
155
        SIGALRM,
156
        SIGTERM,
157
        SIGUSR1,
158
        SIGUSR2,
159
        SIGCHLD,
160
        SIGPWR,
161
        SIGWINCH,
162
        SIGURG,
163
        SIGPOLL,
164
        SIGSTOP,
165
        SIGTSTP,
166
        SIGCONT,
167
        SIGTTIN,
168
        SIGTTOU,
169
        SIGVTALRM,
170
        SIGPROF,
171
        SIGXCPU,
172
        SIGWAITING,
173
        SIGLWP,
174
        SIGFREEZE,
175
        SIGTHAW,
176
        SIGCANCEL,
177
        SIGLOST,
178
        SIGXRES,
179
        SIGJVM1;
180
    }
181
}
(-)a/extexecution/src/org/netbeans/api/extexecution/process/package-info.java (+50 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
5
 *
6
 * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
7
 * Other names may be trademarks of their respective owners.
8
 *
9
 * The contents of this file are subject to the terms of either the GNU
10
 * General Public License Version 2 only ("GPL") or the Common
11
 * Development and Distribution License("CDDL") (collectively, the
12
 * "License"). You may not use this file except in compliance with the
13
 * License. You can obtain a copy of the License at
14
 * http://www.netbeans.org/cddl-gplv2.html
15
 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
16
 * specific language governing permissions and limitations under the
17
 * License.  When distributing the software, include this License Header
18
 * Notice in each file and include the License file at
19
 * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
20
 * particular file as subject to the "Classpath" exception as provided
21
 * by Oracle in the GPL Version 2 section of the License file that
22
 * accompanied this code. If applicable, add the following below the
23
 * License Header, with the fields enclosed by brackets [] replaced by
24
 * your own identifying information:
25
 * "Portions Copyrighted [year] [name of copyright owner]"
26
 *
27
 * Contributor(s):
28
 *
29
 * The Original Software is NetBeans. The Initial Developer of the Original
30
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
31
 * Microsystems, Inc. All Rights Reserved.
32
 *
33
 * If you wish your version of this file to be governed by only the CDDL
34
 * or only the GPL Version 2, indicate your decision by adding
35
 * "[Contributor] elects to include this software in this distribution
36
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
37
 * single choice of license, a recipient has the option to distribute
38
 * your version of this file under either the CDDL, the GPL Version 2 or
39
 * to extend the choice of license to its licensees as provided above.
40
 * However, if you add GPL Version 2 code and therefore, elected the GPL
41
 * Version 2 license, then the option applies only if the new code is
42
 * made subject to such option by the copyright holder.
43
 */
44
45
/**
46
 * The API supporting enhanced functionality for
47
 * a {@link java.lang.Process}.
48
 */
49
package org.netbeans.api.extexecution.process;
50
(-)a/extexecution/src/org/netbeans/modules/extexecution/EnvironmentAccessor.java (+81 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2012 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 2012 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.extexecution;
43
44
import org.netbeans.api.extexecution.Environment;
45
import org.netbeans.spi.extexecution.EnvironmentImplementation;
46
47
/**
48
 *
49
 * @author Petr Hejl
50
 */
51
public abstract class EnvironmentAccessor {
52
53
    private static volatile EnvironmentAccessor DEFAULT;
54
55
    public static EnvironmentAccessor getDefault() {
56
        EnvironmentAccessor a = DEFAULT;
57
        if (a != null) {
58
            return a;
59
        }
60
61
        // invokes static initializer of Environment.class
62
        // that will assign value to the DEFAULT field above
63
        Class c = Environment.class;
64
        try {
65
            Class.forName(c.getName(), true, c.getClassLoader());
66
        } catch (ClassNotFoundException ex) {
67
            assert false : ex;
68
        }
69
        return DEFAULT;
70
    }
71
72
    public static void setDefault(EnvironmentAccessor accessor) {
73
        if (DEFAULT != null) {
74
            throw new IllegalStateException();
75
        }
76
77
        DEFAULT = accessor;
78
    }
79
80
    public abstract Environment createEnvironment(EnvironmentImplementation impl);
81
}
(-)a/extexecution/src/org/netbeans/modules/extexecution/ProcessBuilderAccessor.java (+4 lines)
Lines 42-47 Link Here
42
package org.netbeans.modules.extexecution;
42
package org.netbeans.modules.extexecution;
43
43
44
import org.netbeans.spi.extexecution.ProcessBuilderImplementation;
44
import org.netbeans.spi.extexecution.ProcessBuilderImplementation;
45
import org.netbeans.spi.extexecution.ProcessBuilderImplementation2;
45
46
46
/**
47
/**
47
 *
48
 *
Lines 78-81 Link Here
78
79
79
    public abstract org.netbeans.api.extexecution.ProcessBuilder createProcessBuilder(
80
    public abstract org.netbeans.api.extexecution.ProcessBuilder createProcessBuilder(
80
            ProcessBuilderImplementation impl, String description);
81
            ProcessBuilderImplementation impl, String description);
82
83
    public abstract org.netbeans.api.extexecution.ProcessBuilder createProcessBuilder(
84
            ProcessBuilderImplementation2 impl, String description);
81
}
85
}
(-)a/extexecution/src/org/netbeans/modules/extexecution/ProcessParametersAccessor.java (+84 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2012 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 2012 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.extexecution;
43
44
import java.util.List;
45
import java.util.Map;
46
import org.netbeans.spi.extexecution.ProcessParameters;
47
48
/**
49
 *
50
 * @author Petr Hejl
51
 */
52
public abstract class ProcessParametersAccessor {
53
54
    private static volatile ProcessParametersAccessor DEFAULT;
55
56
    public static ProcessParametersAccessor getDefault() {
57
        ProcessParametersAccessor a = DEFAULT;
58
        if (a != null) {
59
            return a;
60
        }
61
62
        // invokes static initializer of ProcessParameters.class
63
        // that will assign value to the DEFAULT field above
64
        Class c = ProcessParameters.class;
65
        try {
66
            Class.forName(c.getName(), true, c.getClassLoader());
67
        } catch (ClassNotFoundException ex) {
68
            assert false : ex;
69
        }
70
        return DEFAULT;
71
    }
72
73
    public static void setDefault(ProcessParametersAccessor accessor) {
74
        if (DEFAULT != null) {
75
            throw new IllegalStateException();
76
        }
77
78
        DEFAULT = accessor;
79
    }
80
81
    public abstract ProcessParameters createProcessParameters(String executable,
82
            String workingDirectory, List<String> arguments, boolean redirectErrorStream,
83
            Map<String, String> environmentVariables);
84
}
(-)a/extexecution/src/org/netbeans/spi/extexecution/EnvironmentFactory.java (+69 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2011 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 2011 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.spi.extexecution;
43
44
import org.netbeans.api.extexecution.Environment;
45
import org.netbeans.modules.extexecution.EnvironmentAccessor;
46
47
/**
48
 * The factory allowing SPI implementors of {@link EnvironmentImplementation}
49
 * to create its API instances {@link Environment}.
50
 *
51
 * @author Petr Hejl
52
 * @since 1.37
53
 */
54
public class EnvironmentFactory {
55
56
    private EnvironmentFactory() {
57
        super();
58
    }
59
60
    /**
61
     * Creates the instance of {@link Environment} from its SPI representation.
62
     *
63
     * @param impl SPI representation
64
     * @return the API instance
65
     */
66
    public static Environment createEnvironment(EnvironmentImplementation impl) {
67
        return EnvironmentAccessor.getDefault().createEnvironment(impl);
68
    }
69
}
(-)a/extexecution/src/org/netbeans/spi/extexecution/EnvironmentImplementation.java (+114 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2012 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 2012 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.spi.extexecution;
43
44
import java.util.Map;
45
import org.netbeans.api.annotations.common.CheckForNull;
46
import org.netbeans.api.annotations.common.NonNull;
47
import org.netbeans.api.extexecution.Environment;
48
49
/**
50
 * The interface representing the implementation
51
 * of {@link org.netbeans.api.extexecution.Environment}.
52
 *
53
 * @see Environment
54
 * @author Petr Hejl
55
 * @since 1.37
56
 */
57
public interface EnvironmentImplementation {
58
59
    /**
60
     * Returns the value of the variable or <code>null</code>.
61
     *
62
     * @param name the name of the variable
63
     * @return the value of the variable or <code>null</code>
64
     */
65
    @CheckForNull
66
    String getVariable(@NonNull String name);
67
68
    /**
69
     * Appends a path to a path-like variable. The proper path separator should
70
     * be used to separate the new value.
71
     *
72
     * @param name the name of the variable such as for example
73
     *             <code>PATH</code> or <code>LD_LIBRARY_PATH</code>
74
     * @param value the value (path to append)
75
     */
76
    void appendPath(@NonNull String name, @NonNull String value);
77
78
    /**
79
     * Prepends a path to a path-like variable. The proper path separator should
80
     * be used to separate the new value.
81
     *
82
     * @param name the name of the variable such as for example
83
     *             <code>PATH</code> or <code>LD_LIBRARY_PATH</code>
84
     * @param value the value (path to prepend)
85
     */
86
    void prependPath(@NonNull String name, @NonNull String value);
87
88
    /**
89
     * Sets a value for a variable with the given name.
90
     *
91
     * @param name the name of the variable
92
     * @param value the value
93
     */
94
    void setVariable(@NonNull String name, @NonNull String value);
95
96
    /**
97
     * Removes a variable with the given name. The subsequent call to
98
     * {@link #getVariable(java.lang.String)} with the same argument should
99
     * return <code>null</code>.
100
     *
101
     * @param name the name of the variable
102
     */
103
    void removeVariable(@NonNull String name);
104
105
    /**
106
     * Returns all variable names and associated values as a {@link Map}.
107
     * Changes to the map must not be propagated back to the {@link Environment}.
108
     *
109
     * @return all variable names and associated values
110
     */
111
    @NonNull
112
    Map<String, String> values();
113
114
}
(-)a/extexecution/src/org/netbeans/spi/extexecution/ProcessBuilderFactory.java (+15 lines)
Lines 63-71 Link Here
63
     * @param impl SPI representation
63
     * @param impl SPI representation
64
     * @param description human readable description of the builder
64
     * @param description human readable description of the builder
65
     * @return the API instance
65
     * @return the API instance
66
     * @deprecated use {@link #createProcessBuilder(org.netbeans.spi.extexecution.ProcessBuilderImplementation2, java.lang.String)}
66
     */
67
     */
67
    public static org.netbeans.api.extexecution.ProcessBuilder createProcessBuilder(
68
    public static org.netbeans.api.extexecution.ProcessBuilder createProcessBuilder(
68
            ProcessBuilderImplementation impl, String description) {
69
            ProcessBuilderImplementation impl, String description) {
69
        return ProcessBuilderAccessor.getDefault().createProcessBuilder(impl, description);
70
        return ProcessBuilderAccessor.getDefault().createProcessBuilder(impl, description);
70
    }
71
    }
72
73
    /**
74
     * Creates the instance of {@link org.netbeans.api.extexecution.ProcessBuilder}
75
     * from its SPI representation.
76
     *
77
     * @param impl SPI representation
78
     * @param description human readable description of the builder
79
     * @return the API instance
80
     * @since 1.37
81
     */
82
    public static org.netbeans.api.extexecution.ProcessBuilder createProcessBuilder(
83
            ProcessBuilderImplementation2 impl, String description) {
84
        return ProcessBuilderAccessor.getDefault().createProcessBuilder(impl, description);
85
    }
71
}
86
}
(-)a/extexecution/src/org/netbeans/spi/extexecution/ProcessBuilderImplementation.java (-1 / +2 lines)
Lines 62-67 Link Here
62
 * @see org.netbeans.api.extexecution.ProcessBuilder
62
 * @see org.netbeans.api.extexecution.ProcessBuilder
63
 * @author Petr Hejl
63
 * @author Petr Hejl
64
 * @since 1.28
64
 * @since 1.28
65
 * @deprecated use {@link ProcessBuilderImplementation2}
65
 */
66
 */
66
public interface ProcessBuilderImplementation {
67
public interface ProcessBuilderImplementation {
67
68
Lines 80-86 Link Here
80
     *             the process should be redirected to standard output stream
81
     *             the process should be redirected to standard output stream
81
     * @return a process created with specified parameters and environment
82
     * @return a process created with specified parameters and environment
82
     *             configuration
83
     *             configuration
83
     * @throws IOException IOException if the process could not be created
84
     * @throws IOException if the process could not be created
84
     * @throws UserQuestionException in case there is a need to interact with
85
     * @throws UserQuestionException in case there is a need to interact with
85
     *    user, don't be afraid to throw a subclass of 
86
     *    user, don't be afraid to throw a subclass of 
86
     *    {@link UserQuestionException} with overriden {@link UserQuestionException#confirmed()}
87
     *    {@link UserQuestionException} with overriden {@link UserQuestionException#confirmed()}
(-)a/extexecution/src/org/netbeans/spi/extexecution/ProcessBuilderImplementation2.java (+93 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2012 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 2012 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.spi.extexecution;
43
44
import java.io.IOException;
45
import org.netbeans.api.annotations.common.NonNull;
46
import org.netbeans.api.extexecution.Environment;
47
import org.openide.util.Lookup;
48
49
/**
50
 * The interface representing the implementation
51
 * of {@link org.netbeans.api.extexecution.ProcessBuilder}.
52
 * 
53
 * @see org.netbeans.api.extexecution.ProcessBuilder
54
 * @author Petr Hejl
55
 * @since 1.37
56
 */
57
public interface ProcessBuilderImplementation2 extends Lookup.Provider {
58
59
    /**
60
     * Returns the object for environment variables manipulation.
61
     *
62
     * @return the object for environment variables manipulation
63
     */
64
    @NonNull
65
    Environment getEnvironment();
66
67
    /**
68
     * Provides an extension point to the implementors. One may enhance the
69
     * functionality of {@link org.netbeans.api.extexecution.ProcessBuilder}
70
     * by this as the content of this {@link Lookup} is included in
71
     * {@link org.netbeans.api.extexecution.ProcessBuilder#getLookup()}
72
     *
73
     * @return a lookup providing an extension point
74
     */
75
    @Override
76
    Lookup getLookup();
77
78
    /**
79
     * Creates a process using the specified parameters.
80
     * <p>
81
     * The environment variables stored in parameters are acquired by call to
82
     * {@link Environment#values()}. So if the implementation does not aim to be
83
     * or can't thread safe it may check or use the {@link Environment}
84
     * directly.
85
     *
86
     * @param parameters the instance describing the process parameters
87
     * @return a process created with specified parameters
88
     * @throws IOException if the process could not be created
89
     */
90
    @NonNull
91
    Process createProcess(@NonNull ProcessParameters parameters) throws IOException;
92
93
}
(-)a/extexecution/src/org/netbeans/spi/extexecution/ProcessParameters.java (+142 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2013 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 2013 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.spi.extexecution;
43
44
import java.util.List;
45
import java.util.Map;
46
import org.netbeans.api.annotations.common.CheckForNull;
47
import org.netbeans.api.annotations.common.NonNull;
48
import org.netbeans.modules.extexecution.ProcessParametersAccessor;
49
50
/**
51
 * The parameters configured for process creation.
52
 *
53
 * @see ProcessBuilderImplementation2
54
 * @author Petr Hejl
55
 * @since 1.37
56
 */
57
public final class ProcessParameters {
58
59
    private final String executable;
60
61
    private final String workingDirectory;
62
63
    private final List<String> arguments;
64
65
    private final boolean redirectErrorStream;
66
67
    private final Map<String, String> environmentVariables;
68
69
    static {
70
        ProcessParametersAccessor.setDefault(new ProcessParametersAccessor() {
71
72
            @Override
73
            public ProcessParameters createProcessParameters(String executable, String workingDirectory,
74
                    List<String> arguments, boolean redirectErrorStream, Map<String, String> environmentVariables) {
75
                return new ProcessParameters(executable, workingDirectory, arguments,
76
                        redirectErrorStream, environmentVariables);
77
            }
78
        });
79
    }
80
81
    private ProcessParameters(String executable, String workingDirectory, List<String> arguments,
82
            boolean redirectErrorStream, Map<String, String> environmentVariables) {
83
        this.executable = executable;
84
        this.workingDirectory = workingDirectory;
85
        this.arguments = arguments;
86
        this.redirectErrorStream = redirectErrorStream;
87
        this.environmentVariables = environmentVariables;
88
    }
89
90
    /**
91
     * Returns the configured executable.
92
     *
93
     * @return the configured executable
94
     */
95
    @NonNull
96
    public String getExecutable() {
97
        return executable;
98
    }
99
100
    /**
101
     * Returns the configured working directory or <code>null</code> in case it
102
     * was not configured.
103
     *
104
     * @return the configured working directory or <code>null</code> in case it
105
     *             was not configured
106
     */
107
    @CheckForNull
108
    public String getWorkingDirectory() {
109
        return workingDirectory;
110
    }
111
112
    /**
113
     * Returns the arguments configured for the process.
114
     *
115
     * @return the arguments configured for the process
116
     */
117
    @NonNull
118
    public List<String> getArguments() {
119
        return arguments;
120
    }
121
122
    /**
123
     * Returns <code>true</code> if standard error stream should be redirected
124
     * to standard output stream.
125
     *
126
     * @return <code>true</code> if standard error stream should be redirected
127
     *             to standard output stream
128
     */
129
    public boolean isRedirectErrorStream() {
130
        return redirectErrorStream;
131
    }
132
133
    /**
134
     * Returns the environment variables configured for the process.
135
     *
136
     * @return the environment variables configured for the process
137
     */
138
    @NonNull
139
    public Map<String, String> getEnvironmentVariables() {
140
        return environmentVariables;
141
    }
142
}
(-)a/extexecution/test/unit/src/org/netbeans/api/extexecution/ExecutionServiceTest.java (-3 / +129 lines)
Lines 42-52 Link Here
42
42
43
package org.netbeans.api.extexecution;
43
package org.netbeans.api.extexecution;
44
44
45
import java.io.ByteArrayInputStream;
45
import java.io.FilterInputStream;
46
import java.io.FilterInputStream;
46
import java.io.IOException;
47
import java.io.IOException;
47
import java.io.InputStream;
48
import java.io.InputStream;
48
import java.io.OutputStream;
49
import java.io.OutputStream;
49
import java.io.Reader;
50
import java.io.Reader;
51
import java.io.StringWriter;
52
import java.io.Writer;
50
import java.lang.reflect.InvocationTargetException;
53
import java.lang.reflect.InvocationTargetException;
51
import java.nio.charset.Charset;
54
import java.nio.charset.Charset;
52
import java.util.LinkedList;
55
import java.util.LinkedList;
Lines 358-364 Link Here
358
        final String[] lines = new String[] {"Process line \u1234", "Process line \u1235", "Process line \u1236"};
361
        final String[] lines = new String[] {"Process line \u1234", "Process line \u1235", "Process line \u1236"};
359
362
360
        TestInputStream is = new TestInputStream(TestInputUtils.prepareInputStream(lines, "\n", charset, true));
363
        TestInputStream is = new TestInputStream(TestInputUtils.prepareInputStream(lines, "\n", charset, true));
361
        TestProcess process = new TestProcess(0, is);
364
        TestProcess process = new TestProcess(0, is, null);
362
        is.setProcess(process);
365
        is.setProcess(process);
363
366
364
        TestCallable callable = new TestCallable();
367
        TestCallable callable = new TestCallable();
Lines 536-541 Link Here
536
        assertFalse(val.get());
539
        assertFalse(val.get());
537
    }
540
    }
538
541
542
    public void testWriterService() throws InterruptedException, ExecutionException {
543
        TestProcess process = new TestProcess(0,
544
                new ByteArrayInputStream("testing input".getBytes()),
545
                new ByteArrayInputStream("testing error".getBytes()));
546
        TestCallable callable = new TestCallable();
547
        callable.addProcess(process);
548
549
        StringWriter in = new StringWriter();
550
        StringWriter err = new StringWriter();
551
        ExecutionService service = ExecutionService.newService(callable, in, err);
552
        Future<Integer> task = service.run();
553
        assertNotNull(task);
554
555
        process.waitStarted();
556
557
        process.destroy();
558
        process.waitFor();
559
        assertTrue(process.isFinished());
560
561
        assertEquals(0, task.get().intValue());
562
        assertEquals("testing input", in.toString());
563
        assertEquals("testing error", err.toString());
564
    }
565
566
    public void testWriterServiceOnce() throws InterruptedException, ExecutionException {
567
        TestProcess process = new TestProcess(0,
568
                new ByteArrayInputStream(new byte[0]), null);
569
        TestCallable callable = new TestCallable();
570
        callable.addProcess(process);
571
572
        ExecutionService service = ExecutionService.newService(callable,
573
                (Writer) null, (Writer) null);
574
        Future<Integer> task = service.run();
575
        assertNotNull(task);
576
577
        process.waitStarted();
578
579
        process.destroy();
580
        process.waitFor();
581
        assertTrue(process.isFinished());
582
583
        assertEquals(0, task.get().intValue());
584
585
        try {
586
            service.run();
587
            fail("Multiple run should fail with ISE");
588
        } catch (IllegalStateException ex) {
589
            // expected
590
        }
591
    }
592
593
    public void testLineService() throws InterruptedException, ExecutionException {
594
        final String[] linesIn = new String[] {"Process line 1", "Process line 2", "Process line 3"};
595
        final String[] linesErr = new String[] {"Error line 1", "Error line 2", "Error line 3"};
596
597
        TestInputStream in = new TestInputStream(
598
                TestInputUtils.prepareInputStream(linesIn, "\n", Charset.defaultCharset(), true));
599
        TestInputStream err = new TestInputStream(
600
                TestInputUtils.prepareInputStream(linesErr, "\n", Charset.defaultCharset(), true));
601
        TestProcess process = new TestProcess(0, in, err);
602
        TestCallable callable = new TestCallable();
603
        callable.addProcess(process);
604
605
        TestLineProcessor inProcessor = new TestLineProcessor(false);
606
        TestLineProcessor errProcessor = new TestLineProcessor(false);
607
        ExecutionService service = ExecutionService.newService(callable,
608
                inProcessor, errProcessor, null);
609
        Future<Integer> task = service.run();
610
        assertNotNull(task);
611
612
        process.waitStarted();
613
614
        process.destroy();
615
        process.waitFor();
616
        assertTrue(process.isFinished());
617
618
        assertEquals(0, task.get().intValue());
619
620
        List<String> processed = inProcessor.getLinesProcessed();
621
        assertEquals(linesIn.length, processed.size());
622
        for (int i = 0; i < linesIn.length; i++) {
623
            assertEquals(linesIn[i], processed.get(i));
624
        }
625
        processed = errProcessor.getLinesProcessed();
626
        assertEquals(linesErr.length, processed.size());
627
        for (int i = 0; i < linesErr.length; i++) {
628
            assertEquals(linesErr[i], processed.get(i));
629
        }
630
    }
631
632
    public void testLineServiceOnce() throws InterruptedException, ExecutionException {
633
        TestProcess process = new TestProcess(0,
634
                new ByteArrayInputStream(new byte[0]), null);
635
        TestCallable callable = new TestCallable();
636
        callable.addProcess(process);
637
638
        ExecutionService service = ExecutionService.newService(callable,
639
                null, null, null);
640
        Future<Integer> task = service.run();
641
        assertNotNull(task);
642
643
        process.waitStarted();
644
645
        process.destroy();
646
        process.waitFor();
647
        assertTrue(process.isFinished());
648
649
        assertEquals(0, task.get().intValue());
650
651
        try {
652
            service.run();
653
            fail("Multiple run should fail with ISE");
654
        } catch (IllegalStateException ex) {
655
            // expected
656
        }
657
    }
658
539
    private static InputOutputManager.InputOutputData getInputOutput(String name,
659
    private static InputOutputManager.InputOutputData getInputOutput(String name,
540
            boolean actions, String optionsPath) {
660
            boolean actions, String optionsPath) {
541
661
Lines 579-584 Link Here
579
699
580
        private final InputStream is;
700
        private final InputStream is;
581
701
702
        private final InputStream err;
703
582
        private boolean finished;
704
        private boolean finished;
583
705
584
        private boolean started;
706
        private boolean started;
Lines 586-597 Link Here
586
        public TestProcess(int returnValue) {
708
        public TestProcess(int returnValue) {
587
            this(returnValue, TestInputUtils.prepareInputStream(
709
            this(returnValue, TestInputUtils.prepareInputStream(
588
                    new String[] {"Process line 1", "Process line 2", "Process line 3"}, "\n",
710
                    new String[] {"Process line 1", "Process line 2", "Process line 3"}, "\n",
589
                    Charset.defaultCharset(), true));
711
                    Charset.defaultCharset(), true), null);
590
        }
712
        }
591
713
592
        public TestProcess(int returnValue, InputStream is) {
714
        public TestProcess(int returnValue, InputStream is, InputStream err) {
593
            this.returnValue = returnValue;
715
            this.returnValue = returnValue;
594
            this.is = is;
716
            this.is = is;
717
            this.err = err;
595
        }
718
        }
596
719
597
        public void start() {
720
        public void start() {
Lines 637-642 Link Here
637
760
638
        @Override
761
        @Override
639
        public InputStream getErrorStream() {
762
        public InputStream getErrorStream() {
763
            if (err != null) {
764
                return err;
765
            }
640
            return new InputStream() {
766
            return new InputStream() {
641
                @Override
767
                @Override
642
                public int read() throws IOException {
768
                public int read() throws IOException {
(-)a/extexecution/test/unit/src/org/netbeans/api/extexecution/ProcessBuilderTest.java (-2 / +211 lines)
Lines 48-55 Link Here
48
import java.util.List;
48
import java.util.List;
49
import java.util.Map;
49
import java.util.Map;
50
import org.netbeans.junit.NbTestCase;
50
import org.netbeans.junit.NbTestCase;
51
import org.netbeans.spi.extexecution.EnvironmentFactory;
52
import org.netbeans.spi.extexecution.EnvironmentImplementation;
51
import org.netbeans.spi.extexecution.ProcessBuilderFactory;
53
import org.netbeans.spi.extexecution.ProcessBuilderFactory;
52
import org.netbeans.spi.extexecution.ProcessBuilderImplementation;
54
import org.netbeans.spi.extexecution.ProcessBuilderImplementation;
55
import org.netbeans.spi.extexecution.ProcessBuilderImplementation2;
56
import org.netbeans.spi.extexecution.ProcessParameters;
57
import org.openide.util.Lookup;
53
58
54
/**
59
/**
55
 *
60
 *
Lines 166-172 Link Here
166
        assertEquals("test2", testBuilder.getPaths().get(0));
171
        assertEquals("test2", testBuilder.getPaths().get(0));
167
    }
172
    }
168
173
169
    public void testEnvironment() throws IOException {
174
    public void testEnvironmentVariables() throws IOException {
170
        TestProcessBuilder testBuilder = new TestProcessBuilder();
175
        TestProcessBuilder testBuilder = new TestProcessBuilder();
171
        ProcessBuilder builder = ProcessBuilderFactory.createProcessBuilder(testBuilder, "Test builder");
176
        ProcessBuilder builder = ProcessBuilderFactory.createProcessBuilder(testBuilder, "Test builder");
172
        builder.setExecutable("ls");
177
        builder.setExecutable("ls");
Lines 201-206 Link Here
201
        assertEquals("value2", testBuilder.getEnvironment().get("key2"));
206
        assertEquals("value2", testBuilder.getEnvironment().get("key2"));
202
    }
207
    }
203
208
209
    public void testEnvironment() throws IOException {
210
        TestProcessBuilder2 testBuilder = new TestProcessBuilder2();
211
        ProcessBuilder builder = ProcessBuilderFactory.createProcessBuilder(testBuilder, "Test builder");
212
        builder.setExecutable("ls");
213
214
        builder.getEnvironment().setVariable("key1", "value1");
215
        builder.getEnvironment().setVariable("key2", "value2");
216
217
        assertEquals("value1", testBuilder.getEnvironment().getVariable("key1"));
218
        assertEquals("value2", testBuilder.getEnvironment().getVariable("key2"));
219
220
        builder.call();
221
        assertEquals(2, testBuilder.getParameters().getEnvironmentVariables().size());
222
        assertEquals("value1", testBuilder.getParameters().getEnvironmentVariables().get("key1"));
223
        assertEquals("value2", testBuilder.getParameters().getEnvironmentVariables().get("key2"));
224
225
        builder.getEnvironment().prependPath("PATH", "/test1");
226
        builder.getEnvironment().prependPath("PATH", "/test2");
227
228
        builder.call();
229
        assertEquals(3, testBuilder.getParameters().getEnvironmentVariables().size());
230
        assertEquals("/test2:/test1",
231
                testBuilder.getParameters().getEnvironmentVariables().get("PATH"));
232
233
        builder.getEnvironment().appendPath("PATH", "/test3");
234
235
        builder.call();
236
        assertEquals(3, testBuilder.getParameters().getEnvironmentVariables().size());
237
        assertEquals("/test2:/test1:/test3",
238
                testBuilder.getParameters().getEnvironmentVariables().get("PATH"));
239
240
        builder.getEnvironment().removeVariable("PATH");
241
        assertNull(builder.getEnvironment().getVariable("PATH"));
242
243
        builder.call();
244
        assertEquals(2, testBuilder.getParameters().getEnvironmentVariables().size());
245
        assertNull(testBuilder.getParameters().getEnvironmentVariables().get("PATH"));
246
    }
247
248
    public void testFallbackEnvironment() throws IOException {
249
        TestProcessBuilder testBuilder = new TestProcessBuilder();
250
        ProcessBuilder builder = ProcessBuilderFactory.createProcessBuilder(testBuilder, "Test builder");
251
        builder.setExecutable("ls");
252
253
        builder.getEnvironment().setVariable("key1", "value1");
254
        builder.getEnvironment().setVariable("key2", "value2");
255
256
        builder.call();
257
        assertEquals(2, testBuilder.getEnvironment().size());
258
        assertEquals("value1", testBuilder.getEnvironment().get("key1"));
259
        assertEquals("value2", testBuilder.getEnvironment().get("key2"));
260
261
        builder.getEnvironment().prependPath("PATH", "/test1");
262
        builder.getEnvironment().prependPath("Path", "/test2");
263
264
        builder.call();
265
        assertEquals(2, testBuilder.getPaths().size());
266
        assertEquals("/test2", testBuilder.getPaths().get(0));
267
        assertEquals("/test1", testBuilder.getPaths().get(1));
268
269
        try {
270
            builder.getEnvironment().prependPath("LD_LIBRARY_PATH", "/test");
271
            fail("Prepend of unknown path does not throw exception");
272
        } catch (UnsupportedOperationException ex) {
273
            // expected
274
        }
275
276
        try {
277
            builder.getEnvironment().appendPath("PATH", "/test");
278
            fail("Append of any path does not throw exception");
279
        } catch (UnsupportedOperationException ex) {
280
            // expected
281
        }
282
283
        try {
284
            builder.getEnvironment().getVariable("PATH");
285
            fail("getVariable() does not throw exception");
286
        } catch (UnsupportedOperationException ex) {
287
            // expected
288
        }
289
290
        try {
291
            builder.getEnvironment().removeVariable("PATH");
292
            fail("removeVariable() does not throw exception");
293
        } catch (UnsupportedOperationException ex) {
294
            // expected
295
        }
296
297
        try {
298
            builder.getEnvironment().values();
299
            fail("values() does not throw exception");
300
        } catch (UnsupportedOperationException ex) {
301
            // expected
302
        }
303
    }
304
305
    public void testFallbackEnvironmentCombined() throws IOException {
306
        TestProcessBuilder testBuilder = new TestProcessBuilder();
307
        ProcessBuilder builder = ProcessBuilderFactory.createProcessBuilder(testBuilder, "Test builder");
308
        builder.setExecutable("ls");
309
310
        builder.getEnvironment().setVariable("key1", "value1");
311
        builder.getEnvironment().setVariable("key2", "value2");
312
313
        builder.call();
314
        assertEquals(2, testBuilder.getEnvironment().size());
315
        assertEquals("value1", testBuilder.getEnvironment().get("key1"));
316
        assertEquals("value2", testBuilder.getEnvironment().get("key2"));
317
318
        builder.setEnvironmentVariables(Collections.singletonMap("key3", "value3"));
319
320
        builder.call();
321
        assertEquals(1, testBuilder.getEnvironment().size());
322
        assertEquals("value3", testBuilder.getEnvironment().get("key3"));
323
324
        builder.getEnvironment().prependPath("PATH", "/test1");
325
        builder.getEnvironment().prependPath("Path", "/test2");
326
327
        builder.call();
328
        assertEquals(2, testBuilder.getPaths().size());
329
        assertEquals("/test2", testBuilder.getPaths().get(0));
330
        assertEquals("/test1", testBuilder.getPaths().get(1));
331
332
        builder.setPaths(Collections.singletonList("/test3"));
333
334
        builder.call();
335
        assertEquals(1, testBuilder.getPaths().size());
336
        assertEquals("/test3", testBuilder.getPaths().get(0));
337
    }
338
204
    public void testRedirectErrorStream() throws IOException {
339
    public void testRedirectErrorStream() throws IOException {
205
        TestProcessBuilder testBuilder = new TestProcessBuilder();
340
        TestProcessBuilder testBuilder = new TestProcessBuilder();
206
        ProcessBuilder builder = ProcessBuilderFactory.createProcessBuilder(testBuilder, "Test builder");
341
        ProcessBuilder builder = ProcessBuilderFactory.createProcessBuilder(testBuilder, "Test builder");
Lines 216-222 Link Here
216
        assertTrue(testBuilder.isRedirectErrorStream());
351
        assertTrue(testBuilder.isRedirectErrorStream());
217
    }
352
    }
218
353
219
    private class TestProcessBuilder implements ProcessBuilderImplementation {
354
    private static class TestProcessBuilder implements ProcessBuilderImplementation {
220
355
221
        private String executable;
356
        private String executable;
222
357
Lines 267-272 Link Here
267
        public String getWorkingDirectory() {
402
        public String getWorkingDirectory() {
268
            return workingDirectory;
403
            return workingDirectory;
269
        }
404
        }
405
    }
270
406
407
    private static class TestProcessBuilder2 implements ProcessBuilderImplementation2 {
408
409
        private final Environment environment = EnvironmentFactory.createEnvironment(new TestEnvironment());
410
411
        private ProcessParameters parameters;
412
413
        @Override
414
        public Environment getEnvironment() {
415
            return environment;
416
        }
417
418
        @Override
419
        public Lookup getLookup() {
420
            return Lookup.EMPTY;
421
        }
422
423
        @Override
424
        public Process createProcess(ProcessParameters parameters) throws IOException {
425
            this.parameters = parameters;
426
427
            return null;
428
        }
429
430
        public ProcessParameters getParameters() {
431
            return parameters;
432
        }
433
    }
434
435
    private static class TestEnvironment implements EnvironmentImplementation {
436
437
        private final Map<String, String> values = new HashMap<String, String>();
438
439
        @Override
440
        public String getVariable(String name) {
441
            return values.get(name);
442
        }
443
444
        @Override
445
        public void appendPath(String name, String value) {
446
            String orig = values.get(name);
447
            if (orig == null || orig.isEmpty()) {
448
                values.put(name, value);
449
            } else {
450
                // intentionally hardcoded for tests
451
                values.put(name, orig + ":" + value);
452
            }
453
        }
454
455
        @Override
456
        public void prependPath(String name, String value) {
457
            String orig = values.get(name);
458
            if (orig == null || orig.isEmpty()) {
459
                values.put(name, value);
460
            } else {
461
                // intentionally hardcoded for tests
462
                values.put(name, value + ":" + orig);
463
            }
464
        }
465
466
        @Override
467
        public void setVariable(String name, String value) {
468
            values.put(name, value);
469
        }
470
471
        @Override
472
        public void removeVariable(String name) {
473
            values.remove(name);
474
        }
475
476
        @Override
477
        public Map<String, String> values() {
478
            return new HashMap<String, String>(values);
479
        }
271
    }
480
    }
272
}
481
}
(-)a/extexecution/test/unit/src/org/netbeans/api/extexecution/input/InputReadersReaderTest.java (+19 lines)
Lines 47-52 Link Here
47
import java.io.IOException;
47
import java.io.IOException;
48
import java.io.InputStreamReader;
48
import java.io.InputStreamReader;
49
import java.io.Reader;
49
import java.io.Reader;
50
import java.io.StringReader;
50
import java.nio.charset.Charset;
51
import java.nio.charset.Charset;
51
import java.util.Arrays;
52
import java.util.Arrays;
52
import org.netbeans.junit.NbTestCase;
53
import org.netbeans.junit.NbTestCase;
Lines 85-88 Link Here
85
86
86
        assertTrue(Arrays.equals(TEST_CHARS, processor.getCharsProcessed()));
87
        assertTrue(Arrays.equals(TEST_CHARS, processor.getCharsProcessed()));
87
    }
88
    }
89
90
    public void testReadStringReader() throws IOException {
91
        Reader reader = new StringReader(new String(TEST_CHARS));
92
        InputReader inputReader = InputReaders.forReader(reader);
93
        TestInputProcessor processor = new TestInputProcessor(false);
94
95
        int read = 0;
96
        int retries = 0;
97
        while (read < TEST_CHARS.length && retries < MAX_RETRIES) {
98
            read += inputReader.readInput(processor);
99
            retries++;
100
        }
101
102
        assertEquals(read, TEST_CHARS.length);
103
        assertEquals(0, processor.getResetCount());
104
105
        assertTrue(Arrays.equals(TEST_CHARS, processor.getCharsProcessed()));
106
    }
88
}
107
}
(-)a/extexecution/test/unit/src/org/netbeans/api/extexecution/process/ProcessCharsetTest.java (+91 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2013 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 2013 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.api.extexecution.process;
43
44
import java.nio.charset.Charset;
45
import org.netbeans.junit.NbTestCase;
46
import org.openide.util.Lookup;
47
import org.openide.util.lookup.Lookups;
48
49
/**
50
 *
51
 * @author Petr Hejl
52
 */
53
public class ProcessCharsetTest extends NbTestCase {
54
55
    public ProcessCharsetTest(String name) {
56
        super(name);
57
    }
58
59
    public void testProcessCharset() {
60
        assertFalse(ProcessCharset.isSupported(new TestProcess(Lookup.EMPTY)));
61
62
        assertNull(ProcessCharset.getOutputCharset(new TestProcess(Lookup.EMPTY)));
63
        assertNull(ProcessCharset.getInputCharset(new TestProcess(Lookup.EMPTY)));
64
        assertNull(ProcessCharset.getErrorCharset(new TestProcess(Lookup.EMPTY)));
65
66
        TestProcessCharset charset = new TestProcessCharset();
67
        TestProcess process = new TestProcess(Lookups.fixed(charset));
68
        assertTrue(ProcessCharset.isSupported(process));
69
        assertEquals(charset.getOutputCharset(), ProcessCharset.getOutputCharset(process));
70
        assertEquals(charset.getInputCharset(), ProcessCharset.getInputCharset(process));
71
        assertEquals(charset.getErrorCharset(), ProcessCharset.getErrorCharset(process));
72
    }
73
74
    private static class TestProcessCharset extends ProcessCharset {
75
76
        @Override
77
        protected Charset getInputCharset() {
78
            return Charset.forName("US-ASCII");
79
        }
80
81
        @Override
82
        protected Charset getOutputCharset() {
83
            return Charset.forName("ISO-8859-1");
84
        }
85
86
        @Override
87
        protected Charset getErrorCharset() {
88
            return Charset.forName("UTF-8");
89
        }
90
    }
91
}
(-)a/extexecution/test/unit/src/org/netbeans/api/extexecution/process/ProcessIdTest.java (+76 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2013 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 2013 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.api.extexecution.process;
43
44
import org.netbeans.junit.NbTestCase;
45
import org.openide.util.Lookup;
46
import org.openide.util.lookup.Lookups;
47
48
/**
49
 *
50
 * @author Petr Hejl
51
 */
52
public class ProcessIdTest extends NbTestCase {
53
54
    public ProcessIdTest(String name) {
55
        super(name);
56
    }
57
58
    public void testProcessId() {
59
        assertFalse(ProcessId.isSupported(new TestProcess(Lookup.EMPTY)));
60
61
        assertNull(ProcessId.getId(new TestProcess(Lookup.EMPTY)));
62
        
63
        TestProcessId id = new TestProcessId();
64
        TestProcess process = new TestProcess(Lookups.fixed(id));
65
        assertTrue(ProcessId.isSupported(process));
66
        assertEquals(id.getId(), ProcessId.getId(process));
67
    }
68
69
    private static class TestProcessId extends ProcessId {
70
71
        @Override
72
        protected Integer getId() {
73
            return 1;
74
        }
75
    }
76
}
(-)a/extexecution/test/unit/src/org/netbeans/api/extexecution/process/ProcessSignalTest.java (+116 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2013 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 2013 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.api.extexecution.process;
43
44
import java.io.IOException;
45
import org.netbeans.junit.NbTestCase;
46
import org.openide.util.Lookup;
47
import org.openide.util.lookup.Lookups;
48
49
/**
50
 *
51
 * @author Petr Hejl
52
 */
53
public class ProcessSignalTest extends NbTestCase {
54
55
    public ProcessSignalTest(String name) {
56
        super(name);
57
    }
58
59
    public void testProcessSignal() throws IOException {
60
        assertFalse(ProcessSignal.isSupported(new TestProcess(Lookup.EMPTY)));
61
62
        TestProcessSignal signal = new TestProcessSignal();
63
        TestProcess process = new TestProcess(Lookups.fixed(signal));
64
        assertTrue(ProcessSignal.isSupported(process));
65
66
        ProcessSignal.signal(process, ProcessSignal.Signal.SIGALRM);
67
        ProcessSignal.signalGroup(process, ProcessSignal.Signal.SIGCANCEL);
68
69
        assertEquals(ProcessSignal.Signal.SIGALRM, signal.getSignal());
70
        assertEquals(ProcessSignal.Signal.SIGCANCEL, signal.getGroupSignal());
71
72
        try {
73
            ProcessSignal.signal(process, ProcessSignal.Signal.NULL);
74
            fail("No exception propagated");
75
        } catch (IOException ex) {
76
            // expected
77
        }
78
        try {
79
            ProcessSignal.signalGroup(process, ProcessSignal.Signal.NULL);
80
            fail("No exception propagated");
81
        } catch (IOException ex) {
82
            // expected
83
        }
84
    }
85
86
    private static class TestProcessSignal extends ProcessSignal {
87
88
        private Signal signal;
89
90
        private Signal groupSignal;
91
92
        @Override
93
        protected void signal(Signal signal) throws IOException {
94
            if (this.signal != null) {
95
                throw new IOException("Test");
96
            }
97
            this.signal = signal;
98
        }
99
100
        @Override
101
        protected void signalGroup(Signal signal) throws IOException {
102
            if (this.groupSignal != null) {
103
                throw new IOException("Test");
104
            }
105
            this.groupSignal = signal;
106
        }
107
108
        public Signal getSignal() {
109
            return signal;
110
        }
111
112
        public Signal getGroupSignal() {
113
            return groupSignal;
114
        }
115
    }
116
}
(-)a/extexecution/test/unit/src/org/netbeans/api/extexecution/process/TestProcess.java (+94 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2013 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 2013 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.api.extexecution.process;
43
44
import java.io.InputStream;
45
import java.io.OutputStream;
46
import org.openide.util.Lookup;
47
48
/**
49
 *
50
 * @author Petr Hejl
51
 */
52
public class TestProcess extends Process implements Lookup.Provider {
53
54
    private final Lookup lookup;
55
56
    public TestProcess(Lookup lookup) {
57
        this.lookup = lookup;
58
    }
59
60
    @Override
61
    public Lookup getLookup() {
62
        return lookup;
63
    }
64
65
    @Override
66
    public OutputStream getOutputStream() {
67
        throw new UnsupportedOperationException("Not supported yet.");
68
    }
69
70
    @Override
71
    public InputStream getInputStream() {
72
        throw new UnsupportedOperationException("Not supported yet.");
73
    }
74
75
    @Override
76
    public InputStream getErrorStream() {
77
        throw new UnsupportedOperationException("Not supported yet.");
78
    }
79
80
    @Override
81
    public int waitFor() throws InterruptedException {
82
        throw new UnsupportedOperationException("Not supported yet.");
83
    }
84
85
    @Override
86
    public int exitValue() {
87
        throw new UnsupportedOperationException("Not supported yet.");
88
    }
89
90
    @Override
91
    public void destroy() {
92
        throw new UnsupportedOperationException("Not supported yet.");
93
    }
94
}
(-)a/extexecution/test/unit/src/org/netbeans/spi/extexecution/ProcessParametersTest.java (+79 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2013 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 2013 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.spi.extexecution;
43
44
import java.util.Collections;
45
import java.util.HashMap;
46
import java.util.Map;
47
import org.netbeans.junit.NbTestCase;
48
import org.netbeans.modules.extexecution.ProcessParametersAccessor;
49
50
/**
51
 *
52
 * @author Petr Hejl
53
 */
54
public class ProcessParametersTest extends NbTestCase {
55
56
    public ProcessParametersTest(String name) {
57
        super(name);
58
    }
59
60
    public void testParameters() {
61
        Map<String, String> variables = new HashMap<String, String>();
62
        variables.put("key1", "value1");
63
        variables.put("key2", "value2");
64
65
        ProcessParameters params = ProcessParametersAccessor.getDefault().createProcessParameters(
66
                "ls", "/home", Collections.singletonList("argument"), true, variables);
67
68
        assertEquals("ls", params.getExecutable());
69
        assertEquals("/home", params.getWorkingDirectory());
70
        assertTrue(params.isRedirectErrorStream());
71
72
        assertEquals(1, params.getArguments().size());
73
        assertEquals("argument", params.getArguments().get(0));
74
75
        assertEquals(2, params.getEnvironmentVariables().size());
76
        assertEquals("value1", params.getEnvironmentVariables().get("key1"));
77
        assertEquals("value2", params.getEnvironmentVariables().get("key2"));
78
    }
79
}
(-)a/j2ee.weblogic9/nbproject/project.xml (-1 / +1 lines)
Lines 105-111 Link Here
105
                    <compile-dependency/>
105
                    <compile-dependency/>
106
                    <run-dependency>
106
                    <run-dependency>
107
                        <release-version>2</release-version>
107
                        <release-version>2</release-version>
108
                        <specification-version>1.13</specification-version>
108
                        <specification-version>1.37</specification-version>
109
                    </run-dependency>
109
                    </run-dependency>
110
                </dependency>
110
                </dependency>
111
                <dependency>
111
                <dependency>
(-)a/j2ee.weblogic9/src/org/netbeans/modules/j2ee/weblogic9/deploy/CommandBasedDeployer.java (-16 / +16 lines)
Lines 66-77 Link Here
66
import javax.enterprise.deploy.spi.Target;
66
import javax.enterprise.deploy.spi.Target;
67
import javax.enterprise.deploy.spi.TargetModuleID;
67
import javax.enterprise.deploy.spi.TargetModuleID;
68
import javax.enterprise.deploy.spi.status.ProgressObject;
68
import javax.enterprise.deploy.spi.status.ProgressObject;
69
import org.netbeans.api.extexecution.ExecutionDescriptor;
70
import org.netbeans.api.extexecution.ExecutionService;
69
import org.netbeans.api.extexecution.ExecutionService;
71
import org.netbeans.api.extexecution.ExternalProcessBuilder;
70
import org.netbeans.api.extexecution.ExternalProcessBuilder;
72
import org.netbeans.api.extexecution.input.InputProcessor;
73
import org.netbeans.api.extexecution.input.InputProcessors;
74
import org.netbeans.api.extexecution.input.LineProcessor;
71
import org.netbeans.api.extexecution.input.LineProcessor;
72
import org.netbeans.api.extexecution.input.LineProcessors;
75
import org.netbeans.api.java.platform.JavaPlatform;
73
import org.netbeans.api.java.platform.JavaPlatform;
76
import org.netbeans.api.java.platform.JavaPlatformManager;
74
import org.netbeans.api.java.platform.JavaPlatformManager;
77
import org.netbeans.modules.j2ee.dd.api.application.Application;
75
import org.netbeans.modules.j2ee.dd.api.application.Application;
Lines 88-101 Link Here
88
import org.netbeans.modules.j2ee.weblogic9.config.WLMessageDestination;
86
import org.netbeans.modules.j2ee.weblogic9.config.WLMessageDestination;
89
import org.netbeans.modules.j2ee.weblogic9.dd.model.WebApplicationModel;
87
import org.netbeans.modules.j2ee.weblogic9.dd.model.WebApplicationModel;
90
import org.netbeans.modules.j2ee.weblogic9.ui.FailedAuthenticationSupport;
88
import org.netbeans.modules.j2ee.weblogic9.ui.FailedAuthenticationSupport;
91
import org.netbeans.spi.java.classpath.support.ClassPathSupport;
92
import org.openide.filesystems.FileObject;
89
import org.openide.filesystems.FileObject;
93
import org.openide.filesystems.FileUtil;
90
import org.openide.filesystems.FileUtil;
94
import org.openide.filesystems.JarFileSystem;
91
import org.openide.filesystems.JarFileSystem;
95
import org.openide.util.NbBundle;
92
import org.openide.util.NbBundle;
96
import org.openide.util.RequestProcessor;
93
import org.openide.util.RequestProcessor;
97
import org.openide.util.Utilities;
94
import org.openide.util.Utilities;
98
import org.openide.windows.InputOutput;
99
import org.xml.sax.InputSource;
95
import org.xml.sax.InputSource;
100
import org.xml.sax.SAXException;
96
import org.xml.sax.SAXException;
101
97
Lines 110-117 Link Here
110
106
111
    private static final RequestProcessor URL_WAIT_RP = new RequestProcessor("Weblogic URL Wait", 10); // NOI18N
107
    private static final RequestProcessor URL_WAIT_RP = new RequestProcessor("Weblogic URL Wait", 10); // NOI18N
112
108
113
    private static final boolean SHOW_CONSOLE = Boolean.getBoolean(CommandBasedDeployer.class.getName() + ".showConsole");;
114
115
    public CommandBasedDeployer(WLDeploymentManager deploymentManager) {
109
    public CommandBasedDeployer(WLDeploymentManager deploymentManager) {
116
        super(deploymentManager);
110
        super(deploymentManager);
117
    }
111
    }
Lines 668-686 Link Here
668
            builder = builder.addArgument(param);
662
            builder = builder.addArgument(param);
669
        }
663
        }
670
664
671
        ExecutionDescriptor descriptor = new ExecutionDescriptor().inputVisible(true).outLineBased(true);
665
        LineProcessor realProcessor = processor;
672
        if (processor != null) {
666
        if (LOGGER.isLoggable(Level.FINE)) {
673
            descriptor = descriptor.outProcessorFactory(new ExecutionDescriptor.InputProcessorFactory() {
667
            realProcessor = LineProcessors.proxy(processor, new LineProcessor() {
674
668
675
                public InputProcessor newInputProcessor(InputProcessor defaultProcessor) {
669
                @Override
676
                    return InputProcessors.proxy(defaultProcessor, InputProcessors.bridge(processor));
670
                public void processLine(String line) {
671
                    LOGGER.log(Level.FINE, line);
672
                }
673
674
                @Override
675
                public void reset() {
676
                }
677
678
                @Override
679
                public void close() {
677
                }
680
                }
678
            });
681
            });
679
        }
682
        }
680
        if (!SHOW_CONSOLE) {
683
        return ExecutionService.newService(builder, realProcessor, null, null);
681
            descriptor = descriptor.inputOutput(InputOutput.NULL);
682
        }
683
        return ExecutionService.newService(builder, descriptor, "weblogic.Deployer " + command);
684
    }
684
    }
685
685
686
    private String getClassPath() {
686
    private String getClassPath() {
(-)a/libs.jna/nbproject/project.xml (+1 lines)
Lines 88-93 Link Here
88
                <friend>org.netbeans.modules.masterfs.macosx</friend>
88
                <friend>org.netbeans.modules.masterfs.macosx</friend>
89
                <friend>org.netbeans.modules.masterfs.solaris</friend>
89
                <friend>org.netbeans.modules.masterfs.solaris</friend>
90
                <friend>org.netbeans.modules.masterfs.windows</friend>
90
                <friend>org.netbeans.modules.masterfs.windows</friend>
91
                <friend>org.netbeans.modules.nativeexecution.impl</friend>
91
                <friend>org.netbeans.modules.python.qshell</friend>
92
                <friend>org.netbeans.modules.python.qshell</friend>
92
                <package>com.sun.jna</package>
93
                <package>com.sun.jna</package>
93
                <package>com.sun.jna.ptr</package>
94
                <package>com.sun.jna.ptr</package>
(-)a/nativeexecution.impl/build.xml (+5 lines)
Line 0 Link Here
1
<?xml version="1.0" encoding="UTF-8"?>
2
<project basedir="." default="netbeans" name="nativeexecution.impl">
3
    <description>Builds, tests, and runs the project org.netbeans.modules.nativeexecution.impl</description>
4
    <import file="../nbbuild/templates/projectized.xml"/>
5
</project>
(-)a/nativeexecution.impl/manifest.mf (+6 lines)
Line 0 Link Here
1
Manifest-Version: 1.0
2
AutoUpdate-Show-In-Client: false
3
OpenIDE-Module: org.netbeans.modules.nativeexecution.impl
4
OpenIDE-Module-Implementation-Version: 1
5
OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/nativeexecution/impl/resources/Bundle.properties
6
OpenIDE-Module-Provides: ConnectionService.localhost, ConnectionService.ssh
(-)a/nativeexecution.impl/nbproject/project.properties (+5 lines)
Line 0 Link Here
1
is.autoload=true
2
javac.source=1.6
3
javac.compilerargs=-Xlint -Xlint:-serial
4
spec.version.base=1.0
5
(-)a/nativeexecution.impl/nbproject/project.xml (+115 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.modules.nativeexecution.impl</code-name-base>
7
            <module-dependencies>
8
                <dependency>
9
                    <code-name-base>com.jcraft.jsch</code-name-base>
10
                    <build-prerequisite/>
11
                    <compile-dependency/>
12
                    <run-dependency>
13
                        <specification-version>0.1.43</specification-version>
14
                    </run-dependency>
15
                </dependency>
16
                <dependency>
17
                    <code-name-base>org.netbeans.libs.jna</code-name-base>
18
                    <build-prerequisite/>
19
                    <compile-dependency/>
20
                    <run-dependency>
21
                        <release-version>1</release-version>
22
                        <specification-version>1.4</specification-version>
23
                    </run-dependency>
24
                </dependency>
25
                <dependency>
26
                    <code-name-base>org.netbeans.modules.cnd.execution</code-name-base>
27
                    <build-prerequisite/>
28
                    <compile-dependency/>
29
                    <run-dependency>
30
                        <implementation-version/>
31
                    </run-dependency>
32
                </dependency>
33
                <!--
34
                    this is temporary because of binaries we depend on
35
                    binaries should be present here
36
                -->
37
                <dependency>
38
                    <code-name-base>org.netbeans.modules.dlight.nativeexecution</code-name-base>
39
                    <build-prerequisite/>
40
                    <compile-dependency/>
41
                    <run-dependency>
42
                        <specification-version>1.26</specification-version>
43
                    </run-dependency>
44
                </dependency>
45
                <dependency>
46
                    <code-name-base>org.netbeans.modules.dlight.terminal</code-name-base>
47
                    <build-prerequisite/>
48
                    <compile-dependency/>
49
                    <run-dependency>
50
                        <specification-version>1.14</specification-version>
51
                    </run-dependency>
52
                </dependency>
53
                <dependency>
54
                    <code-name-base>org.netbeans.modules.extexecution</code-name-base>
55
                    <build-prerequisite/>
56
                    <compile-dependency/>
57
                    <run-dependency>
58
                        <release-version>2</release-version>
59
                        <specification-version>1.37</specification-version>
60
                    </run-dependency>
61
                </dependency>
62
                <dependency>
63
                    <code-name-base>org.openide.modules</code-name-base>
64
                    <build-prerequisite/>
65
                    <compile-dependency/>
66
                    <run-dependency>
67
                        <specification-version>7.35</specification-version>
68
                    </run-dependency>
69
                </dependency>
70
                <dependency>
71
                    <code-name-base>org.openide.util</code-name-base>
72
                    <build-prerequisite/>
73
                    <compile-dependency/>
74
                    <run-dependency>
75
                        <specification-version>8.24</specification-version>
76
                    </run-dependency>
77
                </dependency>
78
                <dependency>
79
                    <code-name-base>org.openide.util.lookup</code-name-base>
80
                    <build-prerequisite/>
81
                    <compile-dependency/>
82
                    <run-dependency>
83
                        <specification-version>8.15</specification-version>
84
                    </run-dependency>
85
                </dependency>
86
            </module-dependencies>
87
            <test-dependencies>
88
                <test-type>
89
                    <name>unit</name>
90
                    <test-dependency>
91
                        <code-name-base>org.netbeans.bootstrap</code-name-base>
92
                        <compile-dependency/>
93
                    </test-dependency>
94
                    <test-dependency>
95
                        <code-name-base>org.netbeans.core.startup</code-name-base>
96
                        <compile-dependency/>
97
                    </test-dependency>
98
                    <test-dependency>
99
                        <code-name-base>org.netbeans.insane</code-name-base>
100
                        <compile-dependency/>
101
                    </test-dependency>
102
                    <test-dependency>
103
                        <code-name-base>org.netbeans.libs.junit4</code-name-base>
104
                        <compile-dependency/>
105
                    </test-dependency>
106
                    <test-dependency>
107
                        <code-name-base>org.netbeans.modules.nbjunit</code-name-base>
108
                        <compile-dependency/>
109
                    </test-dependency>
110
                </test-type>
111
            </test-dependencies>
112
            <public-packages/>
113
        </data>
114
    </configuration>
115
</project>
(-)a/nativeexecution.impl/src/org/netbeans/modules/nativeexecution/impl/common/AbstractNativeProcessImpl.java (+198 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2012 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 2012 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.nativeexecution.impl.common;
43
44
import java.io.InputStream;
45
import java.io.OutputStream;
46
import java.util.List;
47
import org.netbeans.modules.cnd.execution.api.NativeExecutionException;
48
import org.netbeans.modules.cnd.execution.spi.NativeProcessImplementation;
49
import org.netbeans.modules.cnd.execution.spi.NativeProcessParams;
50
import org.openide.util.Utilities;
51
52
/**
53
 *
54
 * @author akrasny
55
 */
56
public abstract class AbstractNativeProcessImpl implements NativeProcessImplementation {
57
58
    private final NativeProcessParams params;
59
    private InputStream inputStream;
60
    private InputStream errorStream;
61
    private OutputStream outputStream;
62
    private int pid;
63
64
    public AbstractNativeProcessImpl(NativeProcessParams params) {
65
        this.params = params;
66
    }
67
68
    public final NativeProcessImplementation createAndStart() throws NativeExecutionException {
69
        ProcessStreams streams;
70
71
        try {
72
            String shellScript = params.getShellScript();
73
74
            if (shellScript != null) {
75
                streams = create(params.getShell(), params.getShellScript());
76
            } else {
77
                streams = create(params.getCommand());
78
            }
79
80
            inputStream = streams.is;
81
            errorStream = streams.es;
82
            outputStream = streams.os;
83
            pid = streams.pid;
84
        } catch (Throwable ex) {
85
            throw new NativeExecutionException(ex);
86
        }
87
88
        return this;
89
    }
90
91
    protected final NativeProcessParams getParams() {
92
        return params;
93
    }
94
95
    abstract protected ProcessStreams create(List<String> command) throws NativeExecutionException;
96
97
    abstract protected ProcessStreams create(String shell, String script) throws NativeExecutionException;
98
99
    @Override
100
    public int getPID() {
101
        return pid;
102
    }
103
104
    @Override
105
    public OutputStream getOutputStream() {
106
        return outputStream;
107
    }
108
109
    @Override
110
    public InputStream getInputStream() {
111
        return inputStream;
112
    }
113
114
    @Override
115
    public InputStream getErrorStream() {
116
        return errorStream;
117
    }
118
119
    protected String commandToCommandLine(final List<String> cmd) {
120
        /**
121
         * See IZ#168186 - Wrongly interpreted "$" symbol in arguments
122
         *
123
         * The magic below is all about making run/debug act identically in case
124
         * of ExternalTerminal
125
         */
126
        StringBuilder sb = new StringBuilder();
127
128
        String exec = cmd.get(0);
129
130
        sb.append(quoteSpecialChars(exec)).append(' ');
131
132
        String[] sarg = new String[1];
133
134
        boolean escape;
135
136
        for (int i = 1; i < cmd.size(); i++) {
137
            String arg = cmd.get(i);
138
            escape = false;
139
            sarg[0] = arg;
140
            arg = Utilities.escapeParameters(sarg);
141
142
            sb.append('"');
143
144
            if ((arg.startsWith("'") && arg.endsWith("'")) || // NOI18N
145
                    (arg.startsWith("\"") && arg.endsWith("\""))) { // NOI18N
146
                arg = arg.substring(1, arg.length() - 1);
147
                escape = true;
148
            }
149
150
            if (escape) {
151
                char pc = 'x';
152
153
                for (char c : arg.toCharArray()) {
154
                    if (c == '$' && pc != '\\') {
155
                        sb.append('\\');
156
                    }
157
                    sb.append(c);
158
                    pc = c;
159
                }
160
            } else {
161
                sb.append(arg);
162
            }
163
164
            sb.append("\" "); // NOI18N
165
        }
166
167
        return sb.toString().trim();
168
    }
169
170
    private String quoteSpecialChars(String orig) {
171
        StringBuilder sb = new StringBuilder();
172
        String escapeChars = " &\"'()!"; // NOI18N
173
174
        for (char c : orig.toCharArray()) {
175
            if (escapeChars.indexOf(c) >= 0) { // NOI18N
176
                sb.append('\\');
177
            }
178
            sb.append(c);
179
        }
180
181
        return sb.toString();
182
    }
183
184
    protected static final class ProcessStreams {
185
186
        private final InputStream is;
187
        private final InputStream es;
188
        private final OutputStream os;
189
        private final int pid;
190
191
        public ProcessStreams(InputStream is, InputStream es, OutputStream os, int pid) {
192
            this.is = is;
193
            this.es = es;
194
            this.os = os;
195
            this.pid = pid;
196
        }
197
    }
198
}
(-)a/nativeexecution.impl/src/org/netbeans/modules/nativeexecution/impl/common/HelperUtility.java (+169 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2010 Oracle and/or its affiliates. All rights reserved.
5
 *
6
 * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
7
 * Other names may be trademarks of their respective owners.
8
 *
9
 * The contents of this file are subject to the terms of either the GNU
10
 * General Public License Version 2 only ("GPL") or the Common
11
 * Development and Distribution License("CDDL") (collectively, the
12
 * "License"). You may not use this file except in compliance with the
13
 * License. You can obtain a copy of the License at
14
 * http://www.netbeans.org/cddl-gplv2.html
15
 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
16
 * specific language governing permissions and limitations under the
17
 * License.  When distributing the software, include this License Header
18
 * Notice in each file and include the License file at
19
 * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
20
 * particular file as subject to the "Classpath" exception as provided
21
 * by Oracle in the GPL Version 2 section of the License file that
22
 * accompanied this code. If applicable, add the following below the
23
 * License Header, with the fields enclosed by brackets [] replaced by
24
 * your own identifying information:
25
 * "Portions Copyrighted [year] [name of copyright owner]"
26
 *
27
 * If you wish your version of this file to be governed by only the CDDL
28
 * or only the GPL Version 2, indicate your decision by adding
29
 * "[Contributor] elects to include this software in this distribution
30
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
31
 * single choice of license, a recipient has the option to distribute
32
 * your version of this file under either the CDDL, the GPL Version 2 or
33
 * to extend the choice of license to its licensees as provided above.
34
 * However, if you add GPL Version 2 code and therefore, elected the GPL
35
 * Version 2 license, then the option applies only if the new code is
36
 * made subject to such option by the copyright holder.
37
 *
38
 * Contributor(s):
39
 *
40
 * Portions Copyrighted 2010 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.nativeexecution.impl.common;
43
44
import java.io.File;
45
import java.io.IOException;
46
import java.net.URI;
47
import java.util.HashMap;
48
import java.util.MissingResourceException;
49
import java.util.logging.Level;
50
import org.netbeans.modules.cnd.execution.ExecutionLogger;
51
import org.netbeans.modules.cnd.execution.access.ConnectionAccessor;
52
import org.netbeans.modules.cnd.execution.api.Connection;
53
import org.netbeans.modules.nativeexecution.impl.util.FileOperationsSupport;
54
import org.netbeans.modules.cnd.execution.util.HostInfo;
55
import org.openide.modules.InstalledFileLocator;
56
import org.openide.util.Lookup;
57
58
/**
59
 *
60
 * @author ak119685
61
 */
62
public class HelperUtility {
63
64
    protected static final ExecutionLogger log = ExecutionLogger.getInstance();
65
    private final HashMap<URI, String> cache = new HashMap<URI, String>();
66
    private final String pattern;
67
    protected final String codeNameBase;
68
69
    public HelperUtility(String searchPattern) {
70
        this("org.netbeans.modules.nativeexecution.impl.common", searchPattern); // NOI18N
71
    }
72
73
    public HelperUtility(String codeNameBase, String searchPattern) {
74
        this.codeNameBase = codeNameBase;
75
        pattern = searchPattern;
76
    }
77
78
    /**
79
     *
80
     * @param connection
81
     * @return the ready-to-use remote path for the utility
82
     * @throws IOException
83
     */
84
    public final String getPath(final Connection connection) throws IOException {
85
        return getPath(connection, null);
86
    }
87
88
    private String getPath(final Connection connection, final HostInfo hostInfo) throws IOException {
89
        if (!connection.isConnected()) {
90
            throw new IllegalStateException("Connection " + // NOI18N
91
                    connection.getURI() + " is broken"); // NOI18N
92
        }
93
94
        String result;
95
96
        synchronized (cache) {
97
            result = cache.get(connection.getURI());
98
99
            if (result == null) {
100
                ConnectionAccessor access = ConnectionAccessor.getDefault();
101
                Lookup lookup = access.getConnectionLookup(connection);
102
                FileOperationsSupport fos = lookup.lookup(FileOperationsSupport.class);
103
                if (fos == null) {
104
                    log.log(Level.WARNING,
105
                            "FileOperationsSupport is not provided for {0}",
106
                            connection.getURI()); // NOI18N
107
                    return null;
108
                }
109
110
                final HostInfo info = (hostInfo == null)
111
                        ? HostInfo.getFor(connection)
112
                        : hostInfo;
113
114
                if (!isSupported(info)) {
115
                    log.log(Level.INFO, "Utility {0} is not supported for {1}",
116
                            new Object[]{pattern, connection.getURI()}); // NOI18N
117
                    return null;
118
                }
119
120
                try {
121
                    File localFile = getLocalFileFor(info);
122
123
                    // Construct destination: {tmpbase}/{hash}/{name}
124
125
                    // hash - a string unique to pair: 
126
                    //        local file location and connection
127
                    String key = localFile.getAbsolutePath().concat(connection.getURI().toString());
128
                    String hash = Integer.toString(key.hashCode()).replace('-', '0');
129
130
131
                    String fileName = localFile.getName();
132
                    String dstFile = info.getTempDir() + '/' + hash + '/' + fileName;
133
134
                    result = fos.uploadFile(localFile, dstFile, 0700);
135
136
                    cache.put(connection.getURI(), result);
137
                } catch (MissingResourceException ex) {
138
                    return null;
139
                } catch (IOException ex) {
140
                    throw ex;
141
                } catch (Exception ex) {
142
                    if (ex.getCause() instanceof IOException) {
143
                        throw (IOException) ex.getCause();
144
                    }
145
                    throw new IOException(ex);
146
                }
147
            }
148
        }
149
150
        return result;
151
    }
152
153
    protected File getLocalFileFor(final HostInfo info) throws MissingResourceException {
154
        String path = info.expandMacros(pattern);
155
156
        InstalledFileLocator fl = InstalledFileLocator.getDefault();
157
        File file = fl.locate(path, codeNameBase, false);
158
159
        if (file == null || !file.exists()) {
160
            throw new MissingResourceException(path, null, null); //NOI18N
161
        }
162
163
        return file;
164
    }
165
166
    protected boolean isSupported(HostInfo hostInfo) {
167
        return true;
168
    }
169
}
(-)a/nativeexecution.impl/src/org/netbeans/modules/nativeexecution/impl/common/ShellBasedConnectionInfoProvider.java (+198 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2012 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 2012 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.nativeexecution.impl.common;
43
44
import java.io.BufferedReader;
45
import java.io.IOException;
46
import java.io.InputStream;
47
import java.io.InputStreamReader;
48
import java.io.Reader;
49
import java.io.StringReader;
50
import java.net.InetAddress;
51
import java.net.UnknownHostException;
52
import java.util.HashMap;
53
import java.util.Map;
54
import java.util.concurrent.ExecutionException;
55
import org.netbeans.api.extexecution.ExecutionService;
56
import org.netbeans.api.extexecution.input.LineProcessor;
57
import org.netbeans.modules.cnd.execution.api.Connection;
58
import org.netbeans.modules.cnd.execution.api.NativeExecutionException;
59
import org.netbeans.modules.cnd.execution.api.NativeProcessBuilder;
60
import org.netbeans.modules.cnd.execution.spi.support.ConnectionInfo;
61
import org.netbeans.modules.cnd.execution.spi.support.ConnectionInfoProvider;
62
import org.openide.util.Exceptions;
63
64
/**
65
 *
66
 * @author Andrew
67
 */
68
public final class ShellBasedConnectionInfoProvider implements ConnectionInfoProvider {
69
    @Override
70
    public ConnectionInfo getConnectionInfo(Connection connection) throws NativeExecutionException {
71
        NativeProcessBuilder npb = connection.newNativeProcessBuilder();
72
        npb.setShellScript("/bin/sh", "/bin/sh -s"); // NOI18N
73
        final Map<String, String> env = new HashMap<String, String>();
74
        final Map<String, String> info = new HashMap<String, String>();
75
76
        // FIXME change this to piped/proxy reader/writer
77
        StringBuilder sb = new StringBuilder();
78
        sb.append("NB_KEY=").append(getNBKey()).append('\n'); // NOI18N
79
        InputStream in = getClass().getClassLoader().getResourceAsStream("org/netbeans/modules/nativeexecution/impl/resources/hostinfo.sh"); // NOI18N
80
        BufferedReader br = new BufferedReader(new InputStreamReader(in));
81
        try {
82
            String line;
83
            while ((line = br.readLine()) != null) {
84
                sb.append(line).append('\n');
85
            }
86
        } catch (IOException ex) {
87
            Exceptions.printStackTrace(ex);
88
        } finally {
89
            try {
90
                br.close();
91
            } catch (IOException ex) {
92
                Exceptions.printStackTrace(ex);
93
            }
94
        }
95
        Reader processInput = new StringReader(sb.toString());
96
        try {
97
            ExecutionService.newService(npb, new LineProcessor() {
98
99
                FetcherState state = FetcherState.NONE;
100
101
                @Override
102
                /**
103
                 * This method relies on the contract: - each property is a SINGLE
104
                 * line in format NAME=VALUE - '=' MUST be present on each line
105
                 */
106
                public void processLine(String line) {
107
                    int idx = 0;
108
                    int length = line.length();
109
110
                    if (length == 0) {
111
                        return;
112
                    }
113
114
                    if ("@@@@@INFO".equals(line)) { // NOI18N
115
                        state = FetcherState.INFO;
116
                        return;
117
                    }
118
119
                    if ("@@@@@ENV".equals(line)) { // NOI18N
120
                        state = FetcherState.ENV;
121
                        return;
122
                    }
123
124
                    if (state == FetcherState.NONE) {
125
                        return;
126
                    }
127
128
                    while (idx < length && line.charAt(idx) != '=') {
129
                        idx++;
130
                    }
131
132
                    if (idx >= length) {
133
                        return;
134
    //                    throw new InternalError("Bad line: '" + line + "'"); // NOI18N
135
                    }
136
137
                    String name = line.subSequence(0, idx).toString();
138
                    String value = line.subSequence(idx + 1, length).toString();
139
140
                    switch (state) {
141
                        case ENV:
142
                            env.put(name, value);
143
                            break;
144
                        case INFO:
145
                            info.put(name, value);
146
                            break;
147
                    }
148
                }
149
                @Override
150
                public void reset() {
151
                }
152
153
                @Override
154
                public void close() {
155
                }
156
            }, null, processInput).run().get();
157
        } catch (InterruptedException ex) {
158
            Thread.currentThread().interrupt();
159
            throw new NativeExecutionException(ex);
160
        } catch (ExecutionException ex) {
161
            throw new NativeExecutionException(ex);
162
        }
163
164
        return new ConnectionInfo() {
165
166
            @Override
167
            public Map<String, String> getEnvironmentMap() {
168
                return env;
169
            }
170
171
            @Override
172
            public Map<String, String> getProperties() {
173
                return info;
174
            }
175
        };
176
    }
177
178
    /**
179
     * @return unique key of the current NB instance, introduced to fix bug
180
     * #176526
181
     */
182
    private String getNBKey() {
183
        // use NB userdir to prevent local collisions
184
        int hashCode = System.getProperty("netbeans.user", "").hashCode();
185
        try {
186
            // use host name to prevent remote collisions
187
            InetAddress localhost = InetAddress.getLocalHost();
188
            hashCode = 3 * hashCode + 5 * localhost.getHostName().hashCode();
189
        } catch (UnknownHostException ex) {
190
        }
191
        return Integer.toHexString(hashCode);
192
    }
193
194
    private enum FetcherState {
195
196
        INFO, ENV, NONE
197
    }
198
}
(-)a/nativeexecution.impl/src/org/netbeans/modules/nativeexecution/impl/jsch/Bundle.properties (+42 lines)
Line 0 Link Here
1
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
2
#
3
# Copyright 2012 Oracle and/or its affiliates. All rights reserved.
4
#
5
# Oracle and Java are registered trademarks of Oracle and/or its affiliates.
6
# Other names may be trademarks of their respective owners.
7
#
8
# The contents of this file are subject to the terms of either the GNU
9
# General Public License Version 2 only ("GPL") or the Common
10
# Development and Distribution License("CDDL") (collectively, the
11
# "License"). You may not use this file except in compliance with the
12
# License. You can obtain a copy of the License at
13
# http://www.netbeans.org/cddl-gplv2.html
14
# or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
15
# specific language governing permissions and limitations under the
16
# License.  When distributing the software, include this License Header
17
# Notice in each file and include the License file at
18
# nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
19
# particular file as subject to the "Classpath" exception as provided
20
# by Oracle in the GPL Version 2 section of the License file that
21
# accompanied this code. If applicable, add the following below the
22
# License Header, with the fields enclosed by brackets [] replaced by
23
# your own identifying information:
24
# "Portions Copyrighted [year] [name of copyright owner]"
25
#
26
# If you wish your version of this file to be governed by only the CDDL
27
# or only the GPL Version 2, indicate your decision by adding
28
# "[Contributor] elects to include this software in this distribution
29
# under the [CDDL or GPL Version 2] license." If you do not indicate a
30
# single choice of license, a recipient has the option to distribute
31
# your version of this file under either the CDDL, the GPL Version 2 or
32
# to extend the choice of license to its licensees as provided above.
33
# However, if you add GPL Version 2 code and therefore, elected the GPL
34
# Version 2 license, then the option applies only if the new code is
35
# made subject to such option by the copyright holder.
36
#
37
# Contributor(s):
38
#
39
# Portions Copyrighted 2012 Sun Microsystems, Inc.
40
41
MSG_PasswordInteractive={0} {1}
42
JSchPasswordPromptPanel.pwdField.text=jPasswordField1
(-)a/nativeexecution.impl/src/org/netbeans/modules/nativeexecution/impl/jsch/JSchChannelsSupport.java (+349 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
5
 *
6
 * The contents of this file are subject to the terms of either the GNU
7
 * General Public License Version 2 only ("GPL") or the Common
8
 * Development and Distribution License("CDDL") (collectively, the
9
 * "License"). You may not use this file except in compliance with the
10
 * License. You can obtain a copy of the License at
11
 * http://www.netbeans.org/cddl-gplv2.html
12
 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
13
 * specific language governing permissions and limitations under the
14
 * License.  When distributing the software, include this License Header
15
 * Notice in each file and include the License file at
16
 * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
17
 * particular file as subject to the "Classpath" exception as provided
18
 * by Sun in the GPL Version 2 section of the License file that
19
 * accompanied this code. If applicable, add the following below the
20
 * License Header, with the fields enclosed by brackets [] replaced by
21
 * your own identifying information:
22
 * "Portions Copyrighted [year] [name of copyright owner]"
23
 *
24
 * If you wish your version of this file to be governed by only the CDDL
25
 * or only the GPL Version 2, indicate your decision by adding
26
 * "[Contributor] elects to include this software in this distribution
27
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
28
 * single choice of license, a recipient has the option to distribute
29
 * your version of this file under either the CDDL, the GPL Version 2 or
30
 * to extend the choice of license to its licensees as provided above.
31
 * However, if you add GPL Version 2 code and therefore, elected the GPL
32
 * Version 2 license, then the option applies only if the new code is
33
 * made subject to such option by the copyright holder.
34
 *
35
 * Contributor(s):
36
 *
37
 * Portions Copyrighted 2010 Sun Microsystems, Inc.
38
 */
39
package org.netbeans.modules.nativeexecution.impl.jsch;
40
41
import com.jcraft.jsch.Channel;
42
import com.jcraft.jsch.JSch;
43
import com.jcraft.jsch.JSchException;
44
import com.jcraft.jsch.Session;
45
import com.jcraft.jsch.UserInfo;
46
import java.io.InterruptedIOException;
47
import java.net.URI;
48
import java.util.ArrayList;
49
import java.util.HashMap;
50
import java.util.HashSet;
51
import java.util.List;
52
import java.util.Map.Entry;
53
import java.util.Set;
54
import java.util.concurrent.ConcurrentHashMap;
55
import java.util.concurrent.atomic.AtomicInteger;
56
import java.util.concurrent.locks.Condition;
57
import java.util.concurrent.locks.ReentrantLock;
58
import java.util.logging.Level;
59
import org.netbeans.modules.cnd.execution.ExecutionLogger;
60
import org.netbeans.modules.cnd.execution.api.ConnectionException;
61
import org.netbeans.modules.cnd.execution.spi.AuthDataProvider;
62
import org.netbeans.modules.cnd.execution.spi.UserInteraction;
63
import org.openide.util.Exceptions;
64
65
/**
66
 *
67
 * @author ak119685
68
 */
69
public final class JSchChannelsSupport {
70
71
    private static final ExecutionLogger log = ExecutionLogger.getInstance();
72
    private static final int JSCH_CONNECTION_RETRY = Integer.getInteger("jsch.connection.retry", 3); // NOI18N
73
    private static final int JSCH_CONNECTION_TIMEOUT = Integer.getInteger("jsch.connection.timeout", 10000); // NOI18N
74
    private static final int JSCH_SESSIONS_PER_ENV = Integer.getInteger("jsch.sessions.per.env", 10); // NOI18N
75
    private static final int JSCH_CHANNELS_PER_SESSION = Integer.getInteger("jsch.channels.per.session", 10); // NOI18N
76
    private static final boolean USE_JZLIB = Boolean.getBoolean("jzlib"); // NOI18N
77
    private static final HashMap<String, String> jschSessionConfig = new HashMap<String, String>();
78
    private final JSch jsch;
79
    private final String user;
80
    private final String host;
81
    private final int port;
82
    private final UserInfo userInfo;
83
    private final ReentrantLock sessionsLock = new ReentrantLock();
84
    private final Condition sessionAvailable = sessionsLock.newCondition();
85
    // AtomicInteger stores a number of available channels for the session
86
    // We use ConcurrentHashMap to be able to provide fast isConnected() check; 
87
    // in most other cases sessions variable is guarded by "this"
88
    private final ConcurrentHashMap<Session, AtomicInteger> sessions = new ConcurrentHashMap<Session, AtomicInteger>();
89
    private final Set<Channel> knownChannels = new HashSet<Channel>();
90
91
    static {
92
        Set<Entry<Object, Object>> data = new HashSet<Entry<Object, Object>>(System.getProperties().entrySet());
93
94
        for (Entry<Object, Object> prop : data) {
95
            String var = prop.getKey().toString();
96
            String val = prop.getValue().toString();
97
            if (var != null && val != null) {
98
                if (var.startsWith("jsch.session.cfg.")) { // NOI18N
99
                    jschSessionConfig.put(var.substring(17), val);
100
                }
101
                if (var.startsWith("jsch.cfg.")) { // NOI18N
102
                    JSch.setConfig(var.substring(9), val);
103
                    jschSessionConfig.put(var.substring(9), val);
104
                }
105
            }
106
        }
107
    }
108
    private final URI uri;
109
110
    private JSchChannelsSupport(JSch jsch, URI uri, String user, String host, Integer port, UserInfo userInfo) {
111
        this.jsch = jsch;
112
        this.uri = uri;
113
        this.user = user;
114
        this.host = host;
115
        this.port = port;
116
        this.userInfo = userInfo;
117
    }
118
119
    public static JSchChannelsSupport get(URI uri, AuthDataProvider dataProvider) throws InterruptedException {
120
        String user_ = dataProvider.getProperty(uri, String.class, AuthDataProvider.USERNAME);
121
        String host_ = dataProvider.getProperty(uri, String.class, AuthDataProvider.HOST);
122
        Integer port_ = dataProvider.getProperty(uri, Integer.class, AuthDataProvider.PORT);
123
        UserInteraction userInteraction = dataProvider.getProperty(uri, UserInteraction.class, AuthDataProvider.USER_INTERACTION);
124
        UserInfo userInfo_ = new RemoteUserInfo(uri, dataProvider, userInteraction);
125
        JSch jsch_ = new JSch();
126
        initJsch(jsch_, uri, dataProvider);
127
128
        return new JSchChannelsSupport(jsch_, uri, user_, host_, port_, userInfo_);
129
    }
130
131
    private static void initJsch(JSch jsch, URI uri, AuthDataProvider dataProvider) throws InterruptedException {
132
        try {
133
            jsch.removeAllIdentity();
134
            String authType = dataProvider.getProperty(uri, String.class, "AuthType");
135
            String knownHostsFile = dataProvider.getProperty(uri, String.class, "KnownHostsFile");
136
            String sshKeyFile = dataProvider.getProperty(uri, String.class, "SSHKeyFile");
137
138
            if (knownHostsFile != null) {
139
                jsch.setKnownHosts(knownHostsFile);
140
            }
141
142
            if ("SSHKey".equals(authType) && sshKeyFile != null) {
143
                jsch.addIdentity(sshKeyFile);
144
            }
145
        } catch (JSchException ex) {
146
            Exceptions.printStackTrace(ex);
147
        }
148
    }
149
150
    public synchronized Channel acquireChannel(String type, boolean waitIfNoAvailable) throws ConnectionException, InterruptedIOException {
151
        JSchException exception = null;
152
153
        for (int i = 0; i < JSCH_CONNECTION_RETRY; i++) {
154
            Session session = findFreeSession();
155
156
            if (session == null) {
157
                if (sessions.size() >= JSCH_SESSIONS_PER_ENV) {
158
                    if (waitIfNoAvailable) {
159
                        try {
160
                            sessionsLock.lock();
161
                            while (session == null) {
162
                                try {
163
                                    sessionAvailable.await();
164
                                } catch (InterruptedException ex) {
165
                                    Thread.interrupted();
166
                                    throw new InterruptedIOException(uri.toString());
167
                                }
168
                                session = findFreeSession();
169
                            }
170
                        } finally {
171
                            sessionsLock.unlock();
172
                        }
173
                    } else {
174
                        throw new ConnectionException(uri, "All " + JSCH_SESSIONS_PER_ENV + " sessions for " + host + " are fully loaded"); // NOI18N
175
                    }
176
                }
177
            }
178
179
            try {
180
                if (session == null) {
181
                    session = startNewSession(true);
182
                }
183
184
                Channel result = session.openChannel(type);
185
                if (result != null) {
186
                    log.log(Level.FINE, "Acquired channel [{0}] from session [{1}].", new Object[]{System.identityHashCode(result), System.identityHashCode(session)}); // NOI18N
187
188
                    knownChannels.add(result);
189
190
                    return result;
191
                }
192
            } catch (JSchException ex) {
193
                exception = ex;
194
            }
195
196
            if (session != null && !session.isConnected()) {
197
                sessions.remove(session);
198
            }
199
        }
200
201
        // It is either JSCH_CONNECTION_RETRY times we got JSchException =>
202
        // exception is set; or there was another exception => it was thrown
203
        // already
204
        assert exception != null;
205
        throw new ConnectionException(uri, exception);
206
    }
207
208
    public boolean isConnected() {
209
        // ConcurrentHashMap.keySet() never throws ConcurrentModificationException
210
        for (Session s : sessions.keySet()) {
211
            if (s.isConnected()) {
212
                return true;
213
            }
214
        }
215
216
        return false;
217
    }
218
219
//    public synchronized void reconnect(ExecutionEnvironment env) throws ConnectionException {
220
//        disconnect();
221
//        connect();
222
//    }
223
    private Session findFreeSession() {
224
        for (Entry<Session, AtomicInteger> entry : sessions.entrySet()) {
225
            Session s = entry.getKey();
226
            AtomicInteger availableChannels = entry.getValue();
227
            if (s.isConnected() && availableChannels.get() > 0) {
228
                log.log(Level.FINE, "availableChannels == {0}", new Object[]{availableChannels.get()}); // NOI18N
229
                int remains = availableChannels.decrementAndGet();
230
                log.log(Level.FINE, "Reuse session [{0}]. {1} channels remains...", new Object[]{System.identityHashCode(s), remains}); // NOI18N
231
                return s;
232
            }
233
        }
234
235
        return null;
236
    }
237
238
    public synchronized void connect() throws ConnectionException, InterruptedIOException {
239
        if (isConnected()) {
240
            return;
241
        }
242
243
        startNewSession(false);
244
    }
245
246
    public synchronized void disconnect() {
247
        for (Session s : sessions.keySet()) {
248
            s.disconnect();
249
        }
250
    }
251
252
    private Session startNewSession(boolean acquireChannel) throws InterruptedIOException, ConnectionException {
253
        Session newSession = null;
254
        try {
255
            newSession = jsch.getSession(user, host, port);
256
            newSession.setUserInfo(userInfo);
257
258
            for (Entry<String, String> entry : jschSessionConfig.entrySet()) {
259
                newSession.setConfig(entry.getKey(), entry.getValue());
260
            }
261
262
            if (USE_JZLIB) {
263
                newSession.setConfig("compression.s2c", "zlib@openssh.com,zlib,none"); // NOI18N
264
                newSession.setConfig("compression.c2s", "zlib@openssh.com,zlib,none"); // NOI18N
265
                newSession.setConfig("compression_level", "9"); // NOI18N
266
            }
267
268
            newSession.connect(JSCH_CONNECTION_TIMEOUT);
269
        } catch (JSchException ex) {
270
            if (ex.getCause() instanceof InterruptedIOException) {
271
                throw new InterruptedIOException(uri.toString());
272
            }
273
            throw new ConnectionException(uri, ex);
274
        } finally {
275
            // TODO: notify that password could be eraised
276
        }
277
278
        sessions.put(newSession, new AtomicInteger(JSCH_CHANNELS_PER_SESSION - (acquireChannel ? 1 : 0)));
279
280
        log.log(Level.FINE, "New session [{0}] started.", new Object[]{System.identityHashCode(newSession)}); // NOI18N
281
        return newSession;
282
    }
283
284
    public synchronized void releaseChannel(final Channel channel) throws JSchException {
285
        if (!knownChannels.remove(channel)) {
286
            // Means it was not in the collection
287
            return;
288
        }
289
290
        Session s = channel.getSession();
291
292
        log.log(Level.FINE, "Releasing channel [{0}] for session [{1}].", new Object[]{System.identityHashCode(channel), System.identityHashCode(s)}); // NOI18N
293
        channel.disconnect();
294
295
        int count = sessions.get(s).incrementAndGet();
296
297
        List<Session> sessionsToRemove = new ArrayList<Session>();
298
299
        if (count == JSCH_CHANNELS_PER_SESSION) {
300
            // No more channels in this session ...
301
            // Do we have other ready-to-serve sessions?
302
            // In this case will close this one.
303
            for (Entry<Session, AtomicInteger> entry : sessions.entrySet()) {
304
                if (entry.getKey() == s) {
305
                    continue;
306
                }
307
                if (entry.getValue().get() > 0) {
308
                    log.log(Level.FINE, "Found another session [{0}] with {1} free slots. Will remove this one [{2}].", // NOI18N
309
                            new Object[]{
310
                                System.identityHashCode(entry.getKey()),
311
                                entry.getValue().get(),
312
                                System.identityHashCode(s)});
313
314
                    sessionsToRemove.add(s);
315
                    break;
316
                }
317
            }
318
        } else {
319
            // This sessions is capable to provide a channel on next request
320
            // Perhaps we have empty sessions that can be closed then?
321
            for (Entry<Session, AtomicInteger> entry : sessions.entrySet()) {
322
                if (entry.getKey() == s) {
323
                    continue;
324
                }
325
326
                if (entry.getValue().get() == JSCH_CHANNELS_PER_SESSION) {
327
                    log.log(Level.FINE, "Found empty session [{0}] while this one is also has free slots [{1}].", // NOI18N
328
                            new Object[]{
329
                                System.identityHashCode(entry.getKey()),
330
                                System.identityHashCode(s)});
331
                    sessionsToRemove.add(entry.getKey());
332
                }
333
            }
334
        }
335
336
        for (Session sr : sessionsToRemove) {
337
            log.log(Level.FINE, "Closing session [{0}].", new Object[]{System.identityHashCode(s)}); // NOI18N
338
            sr.disconnect();
339
            sessions.remove(sr);
340
        }
341
342
        try {
343
            sessionsLock.lock();
344
            sessionAvailable.signalAll();
345
        } finally {
346
            sessionsLock.unlock();
347
        }
348
    }
349
}
(-)a/nativeexecution.impl/src/org/netbeans/modules/nativeexecution/impl/jsch/JSchConnection.java (+142 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2012 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 2012 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.nativeexecution.impl.jsch;
43
44
import com.jcraft.jsch.Channel;
45
import com.jcraft.jsch.ChannelExec;
46
import com.jcraft.jsch.ChannelSftp;
47
import com.jcraft.jsch.ChannelShell;
48
import com.jcraft.jsch.JSchException;
49
import java.io.InterruptedIOException;
50
import java.net.URI;
51
import org.netbeans.modules.cnd.execution.api.BrokenConnectionException;
52
import org.netbeans.modules.cnd.execution.api.ConnectionException;
53
import org.netbeans.modules.cnd.execution.api.NativeExecutionException;
54
import org.netbeans.modules.cnd.execution.common.ConnectionsInfo;
55
import org.netbeans.modules.nativeexecution.impl.common.ShellBasedConnectionInfoProvider;
56
import org.netbeans.modules.cnd.execution.spi.ConnectionImplementation;
57
import org.netbeans.modules.cnd.execution.spi.NativeProcessCreator;
58
import org.netbeans.modules.nativeexecution.impl.nbstart.NbStartProcessCreator;
59
import org.netbeans.modules.nativeexecution.impl.nbstart.NbStartUtility;
60
import org.openide.util.Lookup;
61
import org.openide.util.lookup.Lookups;
62
63
/**
64
 *
65
 * @author akrasny
66
 */
67
public final class JSchConnection implements ConnectionImplementation {
68
69
    private final JSchChannelsSupport cs;
70
    private final String name;
71
    private final URI uri;
72
    private final Lookup lookup;
73
74
    public JSchConnection(URI uri, JSchChannelsSupport cs) {
75
        String user = uri.getUserInfo();
76
        StringBuilder sb = new StringBuilder();
77
        sb.append(uri.getScheme()).append("://").append(user.replaceAll(":.*", ":***")).append("@").append(uri.getHost()); // NOI18N
78
        name = sb.toString();
79
        this.cs = cs;
80
        this.uri = uri;
81
        this.lookup = Lookups.fixed(
82
                new JSchFileOperationsSupport(this),
83
                new ShellBasedConnectionInfoProvider());
84
    }
85
86
    @Override
87
    public NativeProcessCreator newProcessBuilderImpl() throws NativeExecutionException {
88
        if (!cs.isConnected()) {
89
            throw new BrokenConnectionException(uri);
90
        }
91
92
        if (NbStartUtility.isSupported(ConnectionsInfo.getConnectionInfo(uri))) {
93
            return new NbStartProcessCreator();
94
        } else {
95
            return new JSchProcessCreator(this);
96
        }
97
    }
98
99
    @Override
100
    public boolean isConnected() {
101
        return cs.isConnected();
102
    }
103
104
    @SuppressWarnings("Unchecked")
105
    ChannelExec getChannelExec(boolean waitIfNoAvailable) throws ConnectionException, InterruptedIOException {
106
        return (ChannelExec) cs.acquireChannel("exec", waitIfNoAvailable); // NOI18N
107
    }
108
109
    @SuppressWarnings("Unchecked")
110
    ChannelShell getChannelShell(boolean waitIfNoAvailable) throws ConnectionException, InterruptedIOException {
111
        return (ChannelShell) cs.acquireChannel("shell", waitIfNoAvailable); // NOI18N
112
    }
113
114
    @SuppressWarnings("Unchecked")
115
    ChannelSftp getChannelSftp(boolean waitIfNoAvailable) throws ConnectionException, InterruptedIOException {
116
        return (ChannelSftp) cs.acquireChannel("sftp", waitIfNoAvailable); // NOI18N
117
    }
118
119
    @Override
120
    public String toString() {
121
        return name;
122
    }
123
124
    public void releaseChannel(Channel channel) throws JSchException {
125
        cs.releaseChannel(channel);
126
    }
127
128
    @Override
129
    public Lookup getLookup() {
130
        return lookup;
131
    }
132
133
    @Override
134
    public void disconnect() {
135
        cs.disconnect();
136
    }
137
138
    @Override
139
    public URI getURI() {
140
        return uri;
141
    }
142
}
(-)a/nativeexecution.impl/src/org/netbeans/modules/nativeexecution/impl/jsch/JSchConnector.java (+156 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2012 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 2012 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.nativeexecution.impl.jsch;
43
44
import java.io.IOException;
45
import java.net.InetSocketAddress;
46
import java.net.NoRouteToHostException;
47
import java.net.Socket;
48
import java.net.SocketAddress;
49
import java.net.URI;
50
import java.util.concurrent.Callable;
51
import java.util.concurrent.ExecutionException;
52
import java.util.concurrent.Future;
53
import java.util.concurrent.TimeUnit;
54
import java.util.concurrent.TimeoutException;
55
import org.netbeans.modules.cnd.execution.ExecutionLogger;
56
import org.netbeans.modules.cnd.execution.ExecutionLogger.Ref;
57
import org.netbeans.modules.cnd.execution.spi.AuthDataProvider;
58
import org.netbeans.modules.cnd.execution.spi.ConnectionImplementation;
59
import org.netbeans.modules.cnd.execution.spi.ConnectorImplementation;
60
import org.openide.util.RequestProcessor;
61
import org.openide.util.lookup.ServiceProvider;
62
63
/**
64
 *
65
 * @author akrasny
66
 */
67
@ServiceProvider(service = org.netbeans.modules.cnd.execution.spi.ConnectorImplementation.class, path = "ConnectionService/ssh", position = 10)
68
public final class JSchConnector implements ConnectorImplementation {
69
70
    private static final ExecutionLogger log = ExecutionLogger.getInstance();
71
    private static final int SOCKET_CREATION_TIMEOUT = Integer.getInteger("socket.connection.timeout", 10000); // NOI18N
72
73
    @Override
74
    public ConnectionImplementation connectTo(final URI uri, final AuthDataProvider authDataProvider) throws InterruptedException, IOException {
75
        Ref start = log.reportStart("Connecting to " + uri);
76
        try {
77
78
            String host = authDataProvider.getProperty(uri, String.class, AuthDataProvider.HOST);
79
            Integer port = authDataProvider.getProperty(uri, Integer.class, AuthDataProvider.PORT);
80
81
            if (!isReachable(host, port)) {
82
                throw new NoRouteToHostException(uri.toString());
83
            }
84
85
            JSchChannelsSupport cs = JSchChannelsSupport.get(uri, authDataProvider);
86
            cs.connect();
87
88
            // OK. Connection established.
89
            return new JSchConnection(uri, cs);
90
        } finally {
91
            log.reportDone(start);
92
        }
93
    }
94
95
    private boolean isReachable(final String host, final Integer port) {
96
        // TODO: review!
97
        // This ping-thread-related work makes sense if there are systems
98
        // where interrupting a thread that is in socket.connect() doesn't
99
        // work as expected. Do we know such systems?
100
101
        // IZ#165591 - Trying to connect to wrong host breaks remote host setup (for other hosts)
102
        // To prevent this first try to just open a socket and
103
        // go to the jsch code in case of success only.
104
105
        // The important thing here is that we still need to be interruptable
106
        // In case of wrong IP address (unreachable) the SocketImpl's connect()
107
        // method may hang in system call for a long period of time, being
108
        // insensitive to interrupts.
109
        // So do this in a separate thread...
110
111
        Callable<Boolean> checker = new Callable<Boolean>() {
112
113
            @Override
114
            public Boolean call() throws Exception {
115
                final Socket socket = new Socket();
116
                final SocketAddress addressToConnect = new InetSocketAddress(host, port);
117
                try {
118
                    socket.connect(addressToConnect, SOCKET_CREATION_TIMEOUT);
119
                } catch (Exception ioe) {
120
                    return false;
121
                } finally {
122
                    socket.close();
123
                }
124
                return true;
125
            }
126
        };
127
128
        RequestProcessor pingThread = new RequestProcessor("ping " + host + ":" + port, 1); // NOI18N
129
        final Future<Boolean> task = pingThread.submit(checker); // NOI18N
130
131
        while (!task.isDone()) {
132
            try {
133
                task.get(500, TimeUnit.MILLISECONDS);
134
            } catch (InterruptedException ex) {
135
                Thread.interrupted();
136
                task.cancel(true);
137
            } catch (ExecutionException ex) {
138
                // normally should never happen
139
            } catch (TimeoutException ex) {
140
                // OK.. still be waiting
141
            }
142
        }
143
144
        boolean result = false;
145
146
        if (task.isDone()) {
147
            try {
148
                result = task.get();
149
            } catch (Exception ex) {
150
                // normally should never happen
151
            }
152
        }
153
154
        return result;
155
    }
156
}
(-)a/nativeexecution.impl/src/org/netbeans/modules/nativeexecution/impl/jsch/JSchDefaultAuthDataProvider.java (+115 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2012 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 2012 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.nativeexecution.impl.jsch;
43
44
import java.io.File;
45
import java.net.URI;
46
import org.netbeans.modules.cnd.execution.spi.AuthDataProvider;
47
import org.openide.util.lookup.ServiceProvider;
48
49
/**
50
 *
51
 * @author akrasny
52
 */
53
@ServiceProvider(service = org.netbeans.modules.cnd.execution.spi.AuthDataProvider.class, path = "ConnectionService/ssh", position = 10)
54
public final class JSchDefaultAuthDataProvider implements AuthDataProvider {
55
56
    @Override
57
    public <T> T getProperty(URI uri, Class<T> clazz, final String name, Object... misc) {
58
        if (String.class.equals(clazz) && AuthDataProvider.USERNAME.equals(name)) {
59
            String userinfo = uri.getUserInfo();
60
            if (userinfo == null) {
61
                return null;
62
            }
63
            int pos = userinfo.indexOf(':');
64
            return clazz.cast(pos < 0 ? userinfo : userinfo.substring(0, pos));
65
        }
66
67
        if (String.class.equals(clazz) && AuthDataProvider.HOST.equals(name)) {
68
            return clazz.cast(uri.getHost());
69
        }
70
71
        if (Integer.class.equals(clazz) && AuthDataProvider.PORT.equals(name)) {
72
            int port = uri.getPort();
73
            if (port <= 0) {
74
                port = 22;
75
            }
76
            return clazz.cast(Integer.valueOf(port));
77
        }
78
79
        if (char[].class.equals(clazz) && AuthDataProvider.PASSWORD.equals(name)) {
80
            if ("password".equals(misc[0])) {
81
                String userinfo = uri.getUserInfo();
82
                int pos = userinfo.indexOf(':');
83
                if (pos > 0) {
84
                    return clazz.cast(userinfo.substring(pos + 1).toCharArray());
85
                }
86
            }
87
        }
88
89
        if (String.class.equals(clazz) && "KnownHostsFile".equals(name)) { // NOI18N
90
            File dir = new File(System.getProperty("user.home"), ".ssh"); // NOI18N
91
            File file = new File(dir, "known_hosts"); // NOI18N
92
            if (file.canRead()) {
93
                return clazz.cast(file.getAbsolutePath()); // NOI18N
94
            }
95
        }
96
97
        if (String.class.equals(clazz) && "AuthType".equals(name)) { // NOI18N
98
            return clazz.cast("SSHKey"); // NOI18N
99
        }
100
101
        if (String.class.equals(clazz) && "SSHKeyFile".equals(name)) { // NOI18N
102
            File dir = new File(System.getProperty("user.home"), ".ssh"); // NOI18N
103
            File file = new File(dir, "id_dsa"); // NOI18N
104
            if (file.canRead()) {
105
                return clazz.cast(file.getAbsolutePath()); // NOI18N
106
            }
107
            file = new File(dir, "id_rsa"); // NOI18N
108
            if (file.canRead()) {
109
                return clazz.cast(file.getAbsolutePath()); // NOI18N
110
            }
111
        }
112
113
        return null;
114
    }
115
}
(-)a/nativeexecution.impl/src/org/netbeans/modules/nativeexecution/impl/jsch/JSchFileOperationsSupport.java (+129 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2012 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 2012 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.nativeexecution.impl.jsch;
43
44
import com.jcraft.jsch.ChannelSftp;
45
import com.jcraft.jsch.JSchException;
46
import com.jcraft.jsch.SftpATTRS;
47
import com.jcraft.jsch.SftpException;
48
import java.io.File;
49
import java.io.IOException;
50
import java.util.logging.Level;
51
import org.netbeans.modules.cnd.execution.ExecutionLogger;
52
import org.netbeans.modules.nativeexecution.impl.util.FileOperationsSupport;
53
import org.openide.util.Exceptions;
54
55
/**
56
 *
57
 * @author Andrew
58
 */
59
public class JSchFileOperationsSupport implements FileOperationsSupport {
60
61
    private static final ExecutionLogger log = ExecutionLogger.getInstance();
62
    private final JSchConnection connection;
63
64
    public JSchFileOperationsSupport(JSchConnection connection) {
65
        this.connection = connection;
66
    }
67
68
    @Override
69
    public String uploadFile(File localFile, String remoteFile, int mode) throws IOException {
70
        ChannelSftp channel = null;
71
        long remoteSize = -1;
72
        long localSize = localFile.length();
73
74
        try {
75
            channel = connection.getChannelSftp(true);
76
77
            if (channel == null) {
78
                return null;
79
            }
80
81
            channel.connect();
82
83
            try {
84
                SftpATTRS rstat = channel.stat(remoteFile);
85
                remoteSize = rstat.getSize();
86
            } catch (SftpException ex) {
87
                // No such file ...
88
            }
89
90
            if (remoteSize >= 0 && localSize != remoteSize) {
91
                // Remote file exists, but it has different size
92
                // Remove it first (otherwise channel.put() will
93
                // fail if this file is opened for reading.
94
                // (Any better idea?)
95
                channel.rm(remoteFile);
96
                remoteSize = -1;
97
            }
98
99
            if (remoteSize < 0) {
100
                String dir = new File(remoteFile).getParent();
101
                channel.mkdir(dir);
102
                channel.put(localFile.getAbsolutePath(), remoteFile);
103
                channel.chmod(mode, remoteFile);
104
            }
105
106
            return remoteFile;
107
        } catch (Exception ex) {
108
            log.log(Level.WARNING, "Failed to upload {0}", localFile.getName()); // NOI18N
109
110
            if (remoteSize >= 0) {
111
                log.log(Level.WARNING, "File {0} exists, but cannot be updated. Used by other process?", remoteFile); // NOI18N
112
            } else {
113
                log.log(Level.WARNING, "File {0} doesn't exist, and cannot be uploaded. Do you have enough privileges?", remoteFile); // NOI18N
114
            }
115
116
            log.log(Level.WARNING, "You could try to use -J-Dcnd.tmpbase=<other base location> to re-define default one."); // NOI18N
117
            Exceptions.printStackTrace(ex);
118
            throw new IOException(ex);
119
        } finally {
120
            if (channel != null) {
121
                try {
122
                    connection.releaseChannel(channel);
123
                } catch (JSchException ex) {
124
                    Exceptions.printStackTrace(ex);
125
                }
126
            }
127
        }
128
    }
129
}
(-)a/nativeexecution.impl/src/org/netbeans/modules/nativeexecution/impl/jsch/JSchProcessCreator.java (+77 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2012 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 2012 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.nativeexecution.impl.jsch;
43
44
import org.netbeans.modules.cnd.execution.api.NativeExecutionException;
45
import org.netbeans.modules.cnd.execution.spi.NativeProcessCreator;
46
import org.netbeans.modules.cnd.execution.spi.NativeProcessImplementation;
47
import org.netbeans.modules.cnd.execution.spi.NativeProcessParams;
48
import org.openide.util.Lookup;
49
50
/**
51
 *
52
 * @author akrasny
53
 */
54
public final class JSchProcessCreator implements NativeProcessCreator {
55
56
    private final JSchConnection connectionImpl;
57
58
    public JSchProcessCreator(JSchConnection impl) {
59
        this.connectionImpl = impl;
60
    }
61
62
    @Override
63
    public NativeProcessImplementation createAndStart(NativeProcessParams params) throws NativeExecutionException {
64
        if (params.getShellScript() == null && params.getCommand() == null) {
65
            throw new NullPointerException("Command is not specified"); // NOI18N
66
        }
67
68
        RemoteProcessImpl processImpl = new RemoteProcessImpl(connectionImpl, params);
69
        return processImpl.createAndStart();
70
    }
71
72
    @Override
73
    public Lookup getLookup() {
74
        return Lookup.EMPTY;
75
    }
76
77
}
(-)a/nativeexecution.impl/src/org/netbeans/modules/nativeexecution/impl/jsch/JSchSupport.java (+265 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2010 Oracle and/or its affiliates. All rights reserved.
5
 *
6
 * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
7
 * Other names may be trademarks of their respective owners.
8
 *
9
 * The contents of this file are subject to the terms of either the GNU
10
 * General Public License Version 2 only ("GPL") or the Common
11
 * Development and Distribution License("CDDL") (collectively, the
12
 * "License"). You may not use this file except in compliance with the
13
 * License. You can obtain a copy of the License at
14
 * http://www.netbeans.org/cddl-gplv2.html
15
 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
16
 * specific language governing permissions and limitations under the
17
 * License.  When distributing the software, include this License Header
18
 * Notice in each file and include the License file at
19
 * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
20
 * particular file as subject to the "Classpath" exception as provided
21
 * by Oracle in the GPL Version 2 section of the License file that
22
 * accompanied this code. If applicable, add the following below the
23
 * License Header, with the fields enclosed by brackets [] replaced by
24
 * your own identifying information:
25
 * "Portions Copyrighted [year] [name of copyright owner]"
26
 *
27
 * If you wish your version of this file to be governed by only the CDDL
28
 * or only the GPL Version 2, indicate your decision by adding
29
 * "[Contributor] elects to include this software in this distribution
30
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
31
 * single choice of license, a recipient has the option to distribute
32
 * your version of this file under either the CDDL, the GPL Version 2 or
33
 * to extend the choice of license to its licensees as provided above.
34
 * However, if you add GPL Version 2 code and therefore, elected the GPL
35
 * Version 2 license, then the option applies only if the new code is
36
 * made subject to such option by the copyright holder.
37
 *
38
 * Contributor(s):
39
 *
40
 * Portions Copyrighted 2010 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.nativeexecution.impl.jsch;
43
44
import com.jcraft.jsch.Channel;
45
import com.jcraft.jsch.ChannelExec;
46
import com.jcraft.jsch.JSchException;
47
import java.io.IOException;
48
import java.io.InputStream;
49
import java.io.OutputStream;
50
import java.util.logging.Logger;
51
import org.netbeans.modules.cnd.execution.ExecutionLogger;
52
import org.netbeans.modules.cnd.execution.api.NativeExecutionException;
53
54
/**
55
 *
56
 * @author ak119685
57
 */
58
public final class JSchSupport {
59
60
    private static final int JSCH_CONNECTION_TIMEOUT = Integer.getInteger("jsch.connection.timeout", 10000); // NOI18N
61
    private final static Logger log = ExecutionLogger.getInstance();
62
63
    private JSchSupport() {
64
    }
65
66
    /**
67
     * Starts the specified command (executable + params) within the specified
68
     * jsch connection.
69
     *
70
     * @param connection - connection to execute in
71
     * @param command - executable + params to execute
72
     * @param params - (optional) channel params. May be null.
73
     * @return I/O streams and opened execution JSch channel. Never returns
74
     * NULL.
75
     * @throws IOException - if unable to aquire an execution channel
76
     * @throws JSchException - if JSch exception occurred
77
     * @throws InterruptedException - if the thread was interrupted
78
     */
79
    public static ChannelStreams startCommand(final JSchConnection connection, final String command, final ChannelParams params)
80
            throws IOException {
81
82
        JSchWorker<ChannelStreams> worker = new JSchWorker<ChannelStreams>() {
83
84
            @Override
85
            public ChannelStreams call() throws IOException {
86
                ChannelExec echannel = connection.getChannelExec(true);
87
88
89
                if (echannel == null) {
90
                    throw new NativeExecutionException("Cannot open exec channel on " + connection.toString() + " for " + command); // NOI18N
91
                }
92
93
                echannel.setCommand(command);
94
                echannel.setXForwarding(params == null ? false : params.x11forward);
95
                try {
96
                    InputStream is = echannel.getInputStream();
97
                    InputStream es = echannel.getErrStream();
98
                    OutputStream os = new ProtectedOutputStream(echannel, echannel.getOutputStream());
99
                    echannel.connect(JSCH_CONNECTION_TIMEOUT);
100
                    return new ChannelStreams(echannel, is, es, os);
101
                } catch (JSchException ex) {
102
                    throw new NativeExecutionException(ex);
103
                } catch (IOException ex) {
104
                    throw new NativeExecutionException(ex);
105
                }
106
            }
107
108
            @Override
109
            public String toString() {
110
                return command;
111
            }
112
        };
113
114
        return start(worker, connection, 2);
115
    }
116
117
//    public static ChannelStreams startLoginShellSession(final ExecutionEnvironment env) throws IOException, JSchException, InterruptedException {
118
//        JSchWorker<ChannelStreams> worker = new JSchWorker<ChannelStreams>() {
119
//            @Override
120
//            public ChannelStreams call() throws InterruptedException, JSchException, IOException {
121
//                ChannelShell shell = (ChannelShell) ConnectionManagerAccessor.getDefault().openAndAcquireChannel(env, "shell", true); // NOI18N
122
//
123
//                if (shell == null) {
124
//                    throw new IOException("Cannot open shell channel on " + env); // NOI18N
125
//                }
126
//
127
//                shell.setPty(false);
128
//                InputStream is = shell.getInputStream();
129
//                InputStream es = new ByteArrayInputStream(new byte[0]);
130
//                OutputStream os = shell.getOutputStream();
131
//                shell.connect(JSCH_CONNECTION_TIMEOUT);
132
//                return new ChannelStreams(shell, is, es, os);
133
//            }
134
//
135
//            @Override
136
//            public String toString() {
137
//                return "shell session for " + env.getDisplayName(); // NOI18N
138
//            }
139
//        };
140
//
141
//        return start(worker, env, 2);
142
//    }
143
    private synchronized static ChannelStreams start(final JSchWorker<ChannelStreams> worker, final JSchConnection connection, final int attempts) throws IOException {
144
        int retry = attempts;
145
146
        while (retry-- > 0) {
147
            return worker.call();
148
        }
149
//
150
//        int retry = attempts;
151
//
152
//        while (retry-- > 0) {
153
//            try {
154
//                return worker.call();
155
//            } catch (JSchException ex) {
156
//                String message = ex.getMessage();
157
//                Throwable cause = ex.getCause();
158
//                if (cause != null && cause instanceof NullPointerException) {
159
//                    // Jsch bug... retry?
160
//                    log.log(Level.INFO, "JSch exception opening channel to " + env + ". Retrying", ex); // NOI18N
161
//                } else if ("java.io.InterruptedIOException".equals(message)) { // NOI18N
162
//                    log.log(Level.INFO, "JSch exception opening channel to " + env + ". Retrying in 0.5 seconds", ex); // NOI18N
163
//                    try {
164
//                        Thread.sleep(500);
165
//                    } catch (InterruptedException ex1) {
166
//                        Thread.currentThread().interrupt();
167
//                        break;
168
//                    }
169
//                } else if ("channel is not opened.".equals(message)) { // NOI18N
170
//                    log.log(Level.INFO, "JSch exception opening channel to " + env + ". Reconnecting and retrying", ex); // NOI18N
171
//                    // Now reconnect disconnects old session and creates new, so this might help
172
//                    ConnectionManagerAccessor.getDefault().reconnect(env);
173
//
174
//                } else {
175
//                    throw ex;
176
//                }
177
//            } catch (NullPointerException npe) {
178
//                // Jsch bug... retry? ;)
179
//                log.log(Level.FINE, "Exception from JSch", npe); // NOI18N
180
//            }
181
//        }
182
//
183
//        throw new IOException("Failed to execute " + worker.toString()); // NOI18N
184
        throw new NativeExecutionException("Failed to execute " + worker.toString()); // NOI18N
185
    }
186
187
    public final static class ChannelStreams {
188
189
        public final InputStream out;
190
        public final InputStream err;
191
        public final OutputStream in;
192
        public final Channel channel;
193
194
        public ChannelStreams(Channel channel, InputStream out,
195
                InputStream err, OutputStream in) {
196
            this.channel = channel;
197
            this.out = out;
198
            this.err = err;
199
            this.in = in;
200
        }
201
    }
202
203
    public static final class ChannelParams {
204
205
        private boolean x11forward = false;
206
207
        public void setX11Forwarding(boolean forward) {
208
            this.x11forward = forward;
209
        }
210
    }
211
212
    private static interface JSchWorker<T> {
213
214
        T call() throws IOException;
215
    }
216
217
    private static class ProtectedOutputStream extends OutputStream {
218
219
        private final ChannelExec channel;
220
        private final OutputStream stream;
221
222
        private ProtectedOutputStream(ChannelExec channel, OutputStream stream) {
223
            this.stream = stream;
224
            this.channel = channel;
225
        }
226
227
        @Override
228
        public void write(int b) throws IOException {
229
            checkAlive();
230
            stream.write(b);
231
        }
232
233
        @Override
234
        public void write(byte[] b) throws IOException {
235
            checkAlive();
236
            stream.write(b);
237
        }
238
239
        @Override
240
        public void write(byte[] b, int off, int len) throws IOException {
241
            checkAlive();
242
            stream.write(b, off, len);
243
        }
244
245
        @Override
246
        public void flush() throws IOException {
247
            checkAlive();
248
            stream.flush();
249
        }
250
251
        @Override
252
        public void close() throws IOException {
253
            if (!channel.isConnected()) {
254
                return;
255
            }
256
            stream.close();
257
        }
258
259
        private void checkAlive() throws IOException {
260
            if (!channel.isConnected()) {
261
                throw new IOException("Channel is already closed"); // NOI18N
262
            }
263
        }
264
    }
265
}
(-)a/nativeexecution.impl/src/org/netbeans/modules/nativeexecution/impl/jsch/RemoteProcessImpl.java (+196 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2012 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 2012 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.nativeexecution.impl.jsch;
43
44
import com.jcraft.jsch.Channel;
45
import com.jcraft.jsch.JSchException;
46
import java.io.IOException;
47
import java.io.InputStream;
48
import java.io.OutputStreamWriter;
49
import java.nio.charset.Charset;
50
import java.util.Arrays;
51
import java.util.List;
52
import java.util.Random;
53
import org.netbeans.modules.cnd.execution.ExecutionLogger;
54
import org.netbeans.modules.cnd.execution.ExecutionLogger.Ref;
55
import org.netbeans.modules.cnd.execution.api.NativeExecutionException;
56
import org.netbeans.modules.nativeexecution.impl.common.AbstractNativeProcessImpl;
57
import org.netbeans.modules.nativeexecution.impl.jsch.JSchSupport.ChannelParams;
58
import org.netbeans.modules.nativeexecution.impl.jsch.JSchSupport.ChannelStreams;
59
import org.netbeans.modules.nativeexecution.impl.util.EnvironmentMapWriter;
60
import org.netbeans.modules.cnd.execution.spi.NativeProcessParams;
61
import org.netbeans.modules.cnd.execution.common.SignalUtils;
62
import org.openide.util.Exceptions;
63
64
/**
65
 *
66
 * @author akrasny
67
 */
68
final class RemoteProcessImpl extends AbstractNativeProcessImpl {
69
    
70
    private final JSchConnection connection;
71
    private final Charset commandCharset;
72
    private Channel channel;
73
    private String displayName = ""; // NOI18N
74
75
    RemoteProcessImpl(JSchConnection connection, NativeProcessParams params) {
76
        super(params);
77
        this.connection = connection;
78
        commandCharset = Charset.forName("UTF-8"); //JSchProcessParams.getCommandCharset(params);
79
    }
80
81
    @Override
82
    protected ProcessStreams create(List<String> command) throws NativeExecutionException {
83
        displayName = Arrays.toString(command.toArray(new String[command.size()]));
84
        return createImpl("exec " + commandToCommandLine(command)); // NOI18N
85
    }
86
87
    @Override
88
    protected ProcessStreams create(String shell, String script) throws NativeExecutionException {
89
        displayName = script;
90
        return createImpl(script + "; exit"); // NOI18N
91
    }
92
93
    private ProcessStreams createImpl(String cmdLine) throws NativeExecutionException {
94
        try {
95
            ChannelParams params = new ChannelParams();
96
            ChannelStreams streams = JSchSupport.startCommand(connection, "/bin/sh -s", params); // NOI18N
97
            channel = streams.channel;
98
            OutputStreamWriter writer = new OutputStreamWriter(streams.in, commandCharset);
99
100
            // 1. get the PID of the shell
101
            int token = 1000000 + new Random().nextInt(1000000);
102
            write(writer, "echo " + token + "$$"); // NOI18N
103
104
            ProcessStreams result = new ProcessStreams(streams.out, streams.err, streams.in, readPID(token, streams.out));
105
106
            final String workingDirectory = getParams().getWorkingDirectory();
107
108
            // 2. cd to working directory
109
            if (workingDirectory != null) {
110
                write(writer, "cd \"" + workingDirectory + "\" || exit 1"); // NOI18N
111
            }
112
113
            if (!channel.isConnected()) {
114
                // Wrong directory ...
115
                return result;
116
            }
117
118
            // 3. set environment
119
            EnvironmentMapWriter.write(writer, getParams().getEnvironment());
120
121
            if (getParams().isRedirectError()) {
122
                write(writer, "exec 2>&1"); // NOI18N
123
            }
124
            
125
            // 5. finally do exec
126
            write(writer, cmdLine);
127
128
            return result;
129
        } catch (IOException ex) {
130
            throw new NativeExecutionException(ex);
131
        }
132
    }
133
134
    @Override
135
    public int waitResult() throws InterruptedException {
136
        Ref logRef = ExecutionLogger.getInstance().reportStart(toString());
137
        try {
138
            while (channel.isConnected()) {
139
                Thread.sleep(200);
140
            }
141
142
            return channel.getExitStatus();
143
        } finally {
144
            try {
145
                connection.releaseChannel(channel);
146
            } catch (JSchException ex) {
147
                Exceptions.printStackTrace(ex);
148
            }
149
            ExecutionLogger.getInstance().reportDone(logRef);
150
        }
151
    }
152
153
    private int readPID(int token, final InputStream is) throws IOException {
154
        int c, pid = 0;
155
        boolean found = false;
156
157
        while (true) {
158
            c = is.read();
159
160
            if (c >= '0' && c <= '9') {
161
                pid = pid * 10 + (c - '0');
162
                if (pid == token) {
163
                    pid = 0;
164
                    found = true;
165
                }
166
            } else {
167
                if (found) {
168
                    break;
169
                }
170
            }
171
        }
172
173
        return pid;
174
    }
175
176
    private void write(OutputStreamWriter writer, String data) throws IOException {
177
        writer.write(data);
178
        writer.write("\n");
179
        writer.flush();
180
    }
181
182
    @Override
183
    public void destroy() {
184
//        try {
185
//            channel.sendSignal(SignalUtils.Signal.SIGTERM.name());
186
//        } catch (Exception ex) {
187
//            // Exceptions.printStackTrace(ex);
188
//        }
189
        channel.disconnect();
190
    }
191
192
    @Override
193
    public String toString() {
194
        return displayName;
195
    }
196
}
(-)a/nativeexecution.impl/src/org/netbeans/modules/nativeexecution/impl/jsch/RemoteUserInfo.java (+153 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2010 Oracle and/or its affiliates. All rights reserved.
5
 *
6
 * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
7
 * Other names may be trademarks of their respective owners.
8
 *
9
 * The contents of this file are subject to the terms of either the GNU
10
 * General Public License Version 2 only ("GPL") or the Common
11
 * Development and Distribution License("CDDL") (collectively, the
12
 * "License"). You may not use this file except in compliance with the
13
 * License. You can obtain a copy of the License at
14
 * http://www.netbeans.org/cddl-gplv2.html
15
 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
16
 * specific language governing permissions and limitations under the
17
 * License.  When distributing the software, include this License Header
18
 * Notice in each file and include the License file at
19
 * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
20
 * particular file as subject to the "Classpath" exception as provided
21
 * by Oracle in the GPL Version 2 section of the License file that
22
 * accompanied this code. If applicable, add the following below the
23
 * License Header, with the fields enclosed by brackets [] replaced by
24
 * your own identifying information:
25
 * "Portions Copyrighted [year] [name of copyright owner]"
26
 *
27
 * If you wish your version of this file to be governed by only the CDDL
28
 * or only the GPL Version 2, indicate your decision by adding
29
 * "[Contributor] elects to include this software in this distribution
30
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
31
 * single choice of license, a recipient has the option to distribute
32
 * your version of this file under either the CDDL, the GPL Version 2 or
33
 * to extend the choice of license to its licensees as provided above.
34
 * However, if you add GPL Version 2 code and therefore, elected the GPL
35
 * Version 2 license, then the option applies only if the new code is
36
 * made subject to such option by the copyright holder.
37
 *
38
 * Contributor(s):
39
 *
40
 * Portions Copyrighted 2009 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.nativeexecution.impl.jsch;
43
44
import com.jcraft.jsch.UIKeyboardInteractive;
45
import com.jcraft.jsch.UserInfo;
46
import java.net.URI;
47
import java.util.Arrays;
48
import javax.security.auth.callback.PasswordCallback;
49
import org.netbeans.modules.cnd.execution.spi.AuthDataProvider;
50
import org.netbeans.modules.cnd.execution.spi.UserInteraction;
51
import org.openide.util.NbBundle;
52
53
final public class RemoteUserInfo implements UserInfo, UIKeyboardInteractive {
54
55
    private final AuthDataProvider dataProvider;
56
    private final URI uri;
57
    private final UserInteraction ui;
58
    private PasswordCallback callback;
59
60
    public RemoteUserInfo(URI uri, AuthDataProvider dataProvider, UserInteraction ui) {
61
        this.uri = uri;
62
        this.dataProvider = dataProvider;
63
        this.ui = ui;
64
    }
65
66
    @Override
67
    public String getPassphrase() {
68
        if (callback == null || callback.getPassword() == null) {
69
            return null;
70
        }
71
72
        char[] pwd = callback.getPassword();
73
        // jsch interface requires a String object ;(
74
        String passphrase = new String(pwd);
75
        Arrays.fill(pwd, 'x');
76
        return passphrase;
77
    }
78
79
    @Override
80
    public String getPassword() {
81
        if (callback == null || callback.getPassword() == null) {
82
            return null;
83
        }
84
85
        char[] pwd = callback.getPassword();
86
        // jsch interface requires a String object ;(
87
        String password = new String(pwd);
88
        Arrays.fill(pwd, 'x');
89
        return password;
90
    }
91
92
    @Override
93
    public boolean promptPassword(String message) {
94
        callback = new PasswordCallback(message, false);
95
        char[] pwd = dataProvider.getProperty(uri, char[].class, AuthDataProvider.PASSWORD, "password", message); // NOI18N
96
        if (pwd != null) {
97
            callback.setPassword(pwd);
98
            return true;
99
        }
100
101
        return false;
102
    }
103
104
    @Override
105
    public boolean promptPassphrase(String message) {
106
        callback = new PasswordCallback(message, false);
107
        char[] pwd = dataProvider.getProperty(uri, char[].class, AuthDataProvider.PASSWORD, "passphrase", message); // NOI18N
108
        if (pwd != null) {
109
            callback.setPassword(pwd);
110
            return true;
111
        }
112
113
        return false;
114
    }
115
116
    @Override
117
    public boolean promptYesNo(String message) {
118
        return (ui == null) ? false : ui.promptYesNo(uri, message);
119
    }
120
121
    @Override
122
    public void showMessage(String message) {
123
        if (ui != null) {
124
            ui.notify(uri, message);
125
        }
126
    }
127
128
    @Override
129
    public String[] promptKeyboardInteractive(String destination,
130
            String name,
131
            String instruction,
132
            String[] prompt,
133
            boolean[] echo) {
134
135
        if (prompt.length == 1 && !echo[0]) {
136
            // this is a password request
137
            if (!promptPassword(NbBundle.getMessage(RemoteUserInfo.class, "MSG_PasswordInteractive", // NOI18N
138
                    destination, prompt[0]))) {
139
                return null;
140
            } else {
141
                return new String[]{getPassword()};
142
            }
143
        } else {
144
            // AK:
145
            // What else it could ask about?
146
            // There was a code here that constructed dialog with all prompts
147
            // based on promt / echo arrays.
148
            // As I don't know usecases for it, I removed it ;)
149
150
            return null;
151
        }
152
    }
153
}
(-)a/nativeexecution.impl/src/org/netbeans/modules/nativeexecution/impl/local/LocalConnection.java (+120 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2012 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 2012 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.nativeexecution.impl.local;
43
44
import java.net.InetAddress;
45
import java.net.URI;
46
import org.netbeans.modules.cnd.execution.api.NativeExecutionException;
47
import org.netbeans.modules.cnd.execution.common.ConnectionsInfo;
48
import org.netbeans.modules.nativeexecution.impl.common.ShellBasedConnectionInfoProvider;
49
import org.netbeans.modules.cnd.execution.spi.ConnectionImplementation;
50
import org.netbeans.modules.cnd.execution.spi.NativeProcessCreator;
51
import org.netbeans.modules.nativeexecution.impl.nbstart.NbStartConnectionInfoProvider;
52
import org.netbeans.modules.nativeexecution.impl.nbstart.NbStartProcessCreator;
53
import org.netbeans.modules.nativeexecution.impl.nbstart.NbStartUtility;
54
import org.openide.util.Lookup;
55
import org.openide.util.lookup.Lookups;
56
57
/**
58
 *
59
 * @author akrasny
60
 */
61
public final class LocalConnection implements ConnectionImplementation {
62
63
    private static final LocalConnection instance = new LocalConnection();
64
    private final Lookup lookup;
65
    private final URI uri;
66
67
    private LocalConnection() {
68
        URI localuri = null;
69
        try {
70
            String user = System.getProperty("user.name"); // NOI18N
71
            InetAddress addr = InetAddress.getLocalHost();
72
            String hostname = addr.getHostName();
73
            localuri = new URI("localhost://" + user + "@" + hostname); // NOI18N
74
        } catch (Exception ex) {
75
            throw new InternalError("Unable to detect localhost's URI"); // NOI18N
76
        } finally {
77
            uri = localuri;
78
        }
79
        lookup = Lookups.fixed(LocalFileOperationsSupport.getInstance(),
80
                new ShellBasedConnectionInfoProvider(), 
81
                new NbStartConnectionInfoProvider());
82
    }
83
84
    static LocalConnection getInstance() {
85
        return instance;
86
    }
87
88
    @Override
89
    public boolean isConnected() {
90
        return true;
91
    }
92
93
    @Override
94
    public NativeProcessCreator newProcessBuilderImpl() throws NativeExecutionException {
95
      if (NbStartUtility.isSupported(ConnectionsInfo.getConnectionInfo(uri))) {
96
          return new NbStartProcessCreator();
97
      } else {
98
          return new LocalProcessCreator();
99
      }
100
    }
101
102
    @Override
103
    public String toString() {
104
        return "localhost";
105
    }
106
107
    @Override
108
    public Lookup getLookup() {
109
        return lookup;
110
    }
111
112
    @Override
113
    public void disconnect() {
114
    }
115
116
    @Override
117
    public URI getURI() {
118
        return uri;
119
    }
120
}
(-)a/nativeexecution.impl/src/org/netbeans/modules/nativeexecution/impl/local/LocalConnector.java (+80 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2012 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 2012 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.nativeexecution.impl.local;
43
44
import java.io.IOException;
45
import java.net.URI;
46
import java.net.URISyntaxException;
47
import org.netbeans.modules.nativeexecution.impl.jsch.JSchConnector;
48
import org.netbeans.modules.cnd.execution.spi.AuthDataProvider;
49
import org.netbeans.modules.cnd.execution.spi.ConnectionImplementation;
50
import org.netbeans.modules.cnd.execution.spi.ConnectorImplementation;
51
import org.netbeans.modules.cnd.execution.util.URIMatcher;
52
import org.openide.util.lookup.Lookups;
53
import org.openide.util.lookup.ServiceProvider;
54
55
/**
56
 *
57
 * @author akrasny
58
 */
59
@ServiceProvider(service = org.netbeans.modules.cnd.execution.spi.ConnectorImplementation.class, path = "ConnectionService/localhost", position = 10)
60
public final class LocalConnector implements ConnectorImplementation {
61
62
    @Override
63
    public ConnectionImplementation connectTo(final URI uri, final AuthDataProvider authDataProvider) throws InterruptedException, IOException {
64
        LocalConnection local = LocalConnection.getInstance();
65
66
        if (new URIMatcher(local.getURI()).isIdenticalURI(uri)) {
67
            return local;
68
        }
69
70
        try {
71
            // TODO: Maybe ask user what to do...
72
            URI remoteSSH = new URI("ssh://" + uri.getUserInfo() + "@" + uri.getHost() + ":22"); // NOI18N
73
            JSchConnector jschConnector = Lookups.forPath("ConnectionService/ssh").lookup(JSchConnector.class); // NOI18N
74
            return jschConnector.connectTo(remoteSSH, authDataProvider);
75
        } catch (URISyntaxException ex) {
76
        }
77
78
        return null;
79
    }
80
}
(-)a/nativeexecution.impl/src/org/netbeans/modules/nativeexecution/impl/local/LocalFileOperationsSupport.java (+93 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2012 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 2012 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.nativeexecution.impl.local;
43
44
import java.io.File;
45
import java.io.FileInputStream;
46
import java.io.FileOutputStream;
47
import java.io.IOException;
48
import java.nio.channels.FileChannel;
49
import org.netbeans.modules.nativeexecution.impl.util.FileOperationsSupport;
50
51
public final class LocalFileOperationsSupport implements FileOperationsSupport {
52
53
    private static final LocalFileOperationsSupport instance = new LocalFileOperationsSupport();
54
55
    private LocalFileOperationsSupport() {
56
    }
57
58
    public static LocalFileOperationsSupport getInstance() {
59
        return instance;
60
    }
61
62
    @Override
63
    public String uploadFile(File srcLocalFile, String dstRemoteFile, int mode) throws IOException {
64
        copyFile(srcLocalFile, new File(dstRemoteFile));
65
        return dstRemoteFile;
66
    }
67
68
    private static void copyFile(final File srcFile, final File dstFile) throws IOException {
69
        if (dstFile.exists()) {
70
            dstFile.delete();
71
        }
72
73
        dstFile.getParentFile().mkdirs();
74
        dstFile.createNewFile();
75
76
        FileChannel source = null;
77
        FileChannel destination = null;
78
79
        try {
80
            source = new FileInputStream(srcFile).getChannel();
81
            destination = new FileOutputStream(dstFile).getChannel();
82
            destination.transferFrom(source, 0, source.size());
83
            dstFile.setExecutable(true);
84
        } finally {
85
            if (source != null) {
86
                source.close();
87
            }
88
            if (destination != null) {
89
                destination.close();
90
            }
91
        }
92
    }
93
}
(-)a/nativeexecution.impl/src/org/netbeans/modules/nativeexecution/impl/local/LocalProcessCreator.java (+68 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2012 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 2012 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.nativeexecution.impl.local;
43
44
import org.netbeans.modules.cnd.execution.api.NativeExecutionException;
45
import org.netbeans.modules.cnd.execution.spi.NativeProcessCreator;
46
import org.netbeans.modules.cnd.execution.spi.NativeProcessImplementation;
47
import org.netbeans.modules.cnd.execution.spi.NativeProcessParams;
48
import org.openide.util.Lookup;
49
50
/**
51
 *
52
 * @author akrasny
53
 */
54
final class LocalProcessCreator implements NativeProcessCreator {
55
56
    @Override
57
    public NativeProcessImplementation createAndStart(NativeProcessParams params) throws NativeExecutionException {
58
        if (params.getShellScript() == null && params.getCommand() == null) {
59
            throw new NullPointerException("Command is not specified"); // NOI18N
60
        }
61
        return new LocalProcessImpl(params).createAndStart();
62
    }
63
64
    @Override
65
    public Lookup getLookup() {
66
        return Lookup.EMPTY;
67
    }
68
}
(-)a/nativeexecution.impl/src/org/netbeans/modules/nativeexecution/impl/local/LocalProcessImpl.java (+119 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2012 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 2012 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.nativeexecution.impl.local;
43
44
import com.sun.jna.Pointer;
45
import java.io.IOException;
46
import java.lang.reflect.Field;
47
import java.util.Arrays;
48
import java.util.List;
49
import java.util.Map;
50
import org.netbeans.modules.cnd.execution.api.NativeExecutionException;
51
import org.netbeans.modules.nativeexecution.impl.common.AbstractNativeProcessImpl;
52
import org.netbeans.modules.cnd.execution.spi.NativeProcessParams;
53
54
/**
55
 *
56
 * @author akrasny
57
 */
58
final class LocalProcessImpl extends AbstractNativeProcessImpl {
59
60
    private Process process;
61
62
    LocalProcessImpl(final NativeProcessParams params) {
63
        super(params);
64
    }
65
66
    @Override
67
    protected ProcessStreams create(List<String> command) throws NativeExecutionException {
68
        ProcessBuilder pb = new ProcessBuilder(command);
69
        Map<String, String> env = getParams().getEnvironment();
70
        if (!env.isEmpty()) {
71
            Map<String, String> penv = pb.environment();
72
            penv.clear();
73
            penv.putAll(env);
74
        }
75
        try {
76
            process = pb.start();
77
        } catch (IOException ex) {
78
            throw new NativeExecutionException(ex);
79
        }
80
81
        int pid = -1;
82
83
        try {
84
            String className = process.getClass().getName();
85
            if ("java.lang.Win32Process".equals(className) || "java.lang.ProcessImpl".equals(className)) { // NOI18N
86
                Field f = process.getClass().getDeclaredField("handle"); // NOI18N
87
                f.setAccessible(true);
88
                long phandle = f.getLong(process);
89
90
                Win32APISupport kernel = Win32APISupport.instance;
91
                Win32APISupport.HANDLE handle = new Win32APISupport.HANDLE();
92
                handle.setPointer(Pointer.createConstant(phandle));
93
                pid = kernel.GetProcessId(handle);
94
            } else if ("java.lang.UNIXProcess".equals(className)) { // NOI18N
95
                Field f = process.getClass().getDeclaredField("pid"); // NOI18N
96
                f.setAccessible(true);
97
                pid = f.getInt(process);
98
            }
99
        } catch (Throwable e) {
100
        }
101
102
        return new ProcessStreams(process.getInputStream(), process.getErrorStream(), process.getOutputStream(), pid);
103
    }
104
105
    @Override
106
    protected ProcessStreams create(String shell, String script) throws NativeExecutionException {
107
        return create(Arrays.asList(shell, "-c", script)); // NOI18N
108
    }
109
110
    @Override
111
    public void destroy() {
112
        process.destroy();
113
    }
114
115
    @Override
116
    public int waitResult() throws InterruptedException {
117
        return process.waitFor();
118
    }
119
}
(-)a/nativeexecution.impl/src/org/netbeans/modules/nativeexecution/impl/local/LocalURIIdentifier.java (+78 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2012 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 2012 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.nativeexecution.impl.local;
43
44
import java.net.URI;
45
import org.netbeans.modules.cnd.execution.spi.URIIdentifier;
46
import org.openide.util.lookup.ServiceProvider;
47
48
/**
49
 *
50
 * @author akrasny
51
 */
52
@ServiceProvider(service = org.netbeans.modules.cnd.execution.spi.URIIdentifier.class, path = "ConnectionService/localhost", position = 100)
53
public class LocalURIIdentifier implements URIIdentifier {
54
55
    private final URI localhost = LocalConnection.getInstance().getURI();
56
57
    @Override
58
    public boolean areIdentical(URI uri1, URI uri2) {
59
        String host1 = uri1.getHost();
60
        String host2 = uri2.getHost();
61
        if (host1 == null) {
62
            host1 = localhost.getHost();
63
        }
64
        if (host2 == null) {
65
            host2 = localhost.getHost();
66
        }
67
68
        String user1 = uri1.getUserInfo();
69
        String user2 = uri2.getUserInfo();
70
        if (user1 == null) {
71
            user1 = localhost.getUserInfo();
72
        }
73
        if (user2 == null) {
74
            user2 = localhost.getUserInfo();
75
        }
76
        return host1.equals(host2) && user1.equals(user2);
77
    }
78
}
(-)a/nativeexecution.impl/src/org/netbeans/modules/nativeexecution/impl/local/Win32APISupport.java (+97 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2010 Oracle and/or its affiliates. All rights reserved.
5
 *
6
 * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
7
 * Other names may be trademarks of their respective owners.
8
 *
9
 * The contents of this file are subject to the terms of either the GNU
10
 * General Public License Version 2 only ("GPL") or the Common
11
 * Development and Distribution License("CDDL") (collectively, the
12
 * "License"). You may not use this file except in compliance with the
13
 * License. You can obtain a copy of the License at
14
 * http://www.netbeans.org/cddl-gplv2.html
15
 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
16
 * specific language governing permissions and limitations under the
17
 * License.  When distributing the software, include this License Header
18
 * Notice in each file and include the License file at
19
 * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
20
 * particular file as subject to the "Classpath" exception as provided
21
 * by Oracle in the GPL Version 2 section of the License file that
22
 * accompanied this code. If applicable, add the following below the
23
 * License Header, with the fields enclosed by brackets [] replaced by
24
 * your own identifying information:
25
 * "Portions Copyrighted [year] [name of copyright owner]"
26
 *
27
 * If you wish your version of this file to be governed by only the CDDL
28
 * or only the GPL Version 2, indicate your decision by adding
29
 * "[Contributor] elects to include this software in this distribution
30
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
31
 * single choice of license, a recipient has the option to distribute
32
 * your version of this file under either the CDDL, the GPL Version 2 or
33
 * to extend the choice of license to its licensees as provided above.
34
 * However, if you add GPL Version 2 code and therefore, elected the GPL
35
 * Version 2 license, then the option applies only if the new code is
36
 * made subject to such option by the copyright holder.
37
 *
38
 * Contributor(s):
39
 *
40
 * Portions Copyrighted 2009 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.nativeexecution.impl.local;
43
44
import com.sun.jna.FromNativeContext;
45
import com.sun.jna.Native;
46
import com.sun.jna.Pointer;
47
import com.sun.jna.PointerType;
48
import com.sun.jna.win32.StdCallLibrary;
49
import com.sun.jna.win32.W32APIFunctionMapper;
50
import com.sun.jna.win32.W32APITypeMapper;
51
import java.util.Collections;
52
import java.util.HashMap;
53
import java.util.Map;
54
/* https://jna.dev.java.net/ */
55
/* http://golesny.de/wiki/code:javahowtogetpid */
56
57
public interface Win32APISupport extends StdCallLibrary {
58
59
    final Map<Object, Object> DEFAULT_OPTIONS = Collections.unmodifiableMap(new HashMap<Object, Object>() {
60
61
        {
62
            put(OPTION_TYPE_MAPPER, W32APITypeMapper.UNICODE);
63
            put(OPTION_FUNCTION_MAPPER, W32APIFunctionMapper.UNICODE);
64
        }
65
    });
66
    final Win32APISupport instance = (Win32APISupport) Native.loadLibrary("kernel32", Win32APISupport.class, DEFAULT_OPTIONS); // NOI18N
67
68
    /* http://msdn.microsoft.com/en-us/library/ms683179(VS.85).aspx */
69
    HANDLE GetCurrentProcess();
70
71
    /* http://msdn.microsoft.com/en-us/library/ms683215.aspx */
72
    int GetProcessId(HANDLE process);
73
74
    public class HANDLE extends PointerType {
75
76
        @Override
77
        public Object fromNative(Object nativeValue, FromNativeContext context) {
78
            Object o = super.fromNative(nativeValue, context);
79
            if (InvalidHandle.equals(o)) {
80
                return InvalidHandle;
81
            }
82
            return o;
83
        }
84
    }
85
    public final static HANDLE InvalidHandle = new HANDLE() {
86
87
        {
88
            super.setPointer(Pointer.createConstant(-1));
89
        }
90
91
        @Override
92
        public void setPointer(Pointer p) {
93
            throw new UnsupportedOperationException();
94
        }
95
    };
96
}
97
    
(-)a/nativeexecution.impl/src/org/netbeans/modules/nativeexecution/impl/nbstart/NbStartConnectionInfoProvider.java (+72 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2012 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 2012 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.nativeexecution.impl.nbstart;
43
44
import java.util.Map;
45
import org.netbeans.modules.cnd.execution.api.Connection;
46
import org.netbeans.modules.cnd.execution.api.NativeExecutionException;
47
import org.netbeans.modules.cnd.execution.spi.NativeProcessParams;
48
import org.netbeans.modules.cnd.execution.spi.support.ConnectionInfo;
49
import org.netbeans.modules.cnd.execution.spi.support.ConnectionInfoProvider;
50
51
/**
52
 *
53
 * @author akrasny
54
 */
55
public final class NbStartConnectionInfoProvider implements ConnectionInfoProvider {
56
57
    private final static String NBENV_FILE = "nbenvfile"; // NOI18N
58
59
    @Override
60
    public ConnectionInfo getConnectionInfo(Connection connection) throws NativeExecutionException {
61
        return null;
62
    }
63
64
    // methods for easy access...
65
    static String getEnvironmentFile(NativeProcessParams params) {
66
        Map<String, String> info = params.getConnectionInfo();
67
        if (info == null || !info.containsKey(NBENV_FILE)) {
68
            return null;
69
        }
70
        return info.get(NBENV_FILE);
71
    }
72
}
(-)a/nativeexecution.impl/src/org/netbeans/modules/nativeexecution/impl/nbstart/NbStartLocalProcessImpl.java (+75 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2012 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 2012 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.nativeexecution.impl.nbstart;
43
44
import java.io.IOException;
45
import org.netbeans.modules.cnd.execution.spi.NativeProcessParams;
46
47
/**
48
 *
49
 * @author akrasny
50
 */
51
public final class NbStartLocalProcessImpl extends NbStartProcessImpl {
52
53
    private Process process = null;
54
55
    public NbStartLocalProcessImpl(final NativeProcessParams params) {
56
        super(params);
57
    }
58
59
    @Override
60
    protected IOStreams createProcessImpl() throws IOException {
61
        ProcessBuilder pb = new ProcessBuilder(getCommand());
62
        process = pb.start();
63
        return new IOStreams(process.getOutputStream(), process.getInputStream(), process.getErrorStream());
64
    }
65
66
    @Override
67
    public void destroy() {
68
        process.destroy();
69
    }
70
71
    @Override
72
    protected int waitResultImpl() throws InterruptedException {
73
        return process.waitFor();
74
    }
75
}
(-)a/nativeexecution.impl/src/org/netbeans/modules/nativeexecution/impl/nbstart/NbStartProcessCreator.java (+88 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2012 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 2012 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.nativeexecution.impl.nbstart;
43
44
import java.io.IOException;
45
import org.netbeans.modules.cnd.execution.api.Connection;
46
import org.netbeans.modules.cnd.execution.api.NativeExecutionException;
47
import org.netbeans.modules.cnd.execution.spi.NativeProcessCreator;
48
import org.netbeans.modules.cnd.execution.spi.NativeProcessImplementation;
49
import org.netbeans.modules.cnd.execution.spi.NativeProcessParams;
50
import org.openide.util.Exceptions;
51
import org.openide.util.Lookup;
52
import org.openide.util.lookup.Lookups;
53
54
/**
55
 *
56
 * @author akrasny
57
 */
58
public final class NbStartProcessCreator implements NativeProcessCreator {
59
60
    private final TerminalConfigurationImpl config = new TerminalConfigurationImpl();
61
62
    @Override
63
    public NativeProcessImplementation createAndStart(final NativeProcessParams params) throws NativeExecutionException {
64
        Connection connection = params.getConnection();
65
66
        if (!NbStartUtility.isSupported(connection)) {
67
            return null;
68
        }
69
70
        NbStartProcessImpl processImpl = connection.isLocal()
71
                ? new NbStartLocalProcessImpl(params)
72
                : new NbStartRemoteProcessImpl(params);
73
74
        try {
75
            processImpl.createAndStart();
76
        } catch (IOException ex) {
77
            Exceptions.printStackTrace(ex);
78
            throw new NativeExecutionException(ex);
79
        }
80
81
        return processImpl;
82
    }
83
84
    @Override
85
    public Lookup getLookup() {
86
        return Lookups.fixed(config);
87
    }
88
}
(-)a/nativeexecution.impl/src/org/netbeans/modules/nativeexecution/impl/nbstart/NbStartProcessImpl.java (+306 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2012 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 2012 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.nativeexecution.impl.nbstart;
43
44
import java.awt.Dimension;
45
import java.io.IOException;
46
import java.io.InputStream;
47
import java.io.OutputStream;
48
import java.util.ArrayList;
49
import java.util.Arrays;
50
import java.util.List;
51
import java.util.Map;
52
import java.util.concurrent.ConcurrentHashMap;
53
import org.netbeans.api.extexecution.ProcessBuilder;
54
import org.netbeans.modules.cnd.execution.ExecutionLogger;
55
import org.netbeans.modules.cnd.execution.spi.NativeProcessImplementation;
56
import org.netbeans.modules.cnd.execution.spi.NativeProcessParams;
57
import org.netbeans.modules.cnd.execution.util.HostInfo;
58
import org.netbeans.modules.dlight.api.terminal.ProcessTerminal;
59
import org.netbeans.modules.dlight.spi.terminal.TerminalConfiguration;
60
import org.openide.util.Exceptions;
61
import org.openide.util.Lookup;
62
import org.openide.util.RequestProcessor;
63
import org.openide.util.lookup.AbstractLookup;
64
import org.openide.util.lookup.InstanceContent;
65
66
/**
67
 *
68
 * @author akrasny
69
 */
70
abstract class NbStartProcessImpl implements NativeProcessImplementation, Lookup.Provider {
71
72
    private static final RequestProcessor rp = new RequestProcessor("NbStartProcessImplResize", 1); // NOI18N
73
    private static final ExecutionLogger log = ExecutionLogger.getInstance();
74
    private final ConcurrentHashMap<String, String> processInfo = new ConcurrentHashMap<String, String>();
75
    protected final NativeProcessParams params;
76
    private int pid;
77
    private IOStreams streams;
78
    private final InstanceContent ic = new InstanceContent();
79
    private final Lookup lookup = new AbstractLookup(ic);
80
81
    NbStartProcessImpl(NativeProcessParams params) {
82
        this.params = params;
83
    }
84
85
    protected List<String> getCommand() throws IOException {
86
        HostInfo hostInfo = HostInfo.getFor(params.getConnection());
87
        List<String> command = new ArrayList<String>();
88
89
        command.add(NbStartUtility.getInstance().getPath(params.getConnection()));
90
91
        String wdir = params.getWorkingDirectory();
92
        if (wdir != null && !wdir.isEmpty()) {
93
            command.add("--dir"); // NOI18N
94
            command.add(wdir);
95
        }
96
97
        boolean isTerminalMode = false;
98
        String terminalEmulation = null;
99
100
        TerminalConfiguration termConfig = params.getLookup().lookup(TerminalConfiguration.class);
101
        if (termConfig != null && termConfig.isTerminalMode()) {
102
            isTerminalMode = true;
103
            terminalEmulation = termConfig.getEmulation();
104
        }
105
106
        if (!isTerminalMode) {
107
            command.add("--no-pty"); // NOI18N
108
        } else {
109
//            Pty pty = info.getPty();
110
//            if (pty != null) {
111
//                command.add("-p"); // NOI18N
112
//                command.add(pty.getSlaveName());
113
//            }
114
        }
115
116
//        if (!isPtyMode && info.isUnbuffer()) {
117
//            try {
118
//                UnbufferSupport.initUnbuffer(info.getExecutionEnvironment(), info.getEnvironment());
119
//            } catch (IOException ex) {
120
//                Logger.getInstance().log(Level.FINE, "initUnbuffer failed", ex); // NOI18N
121
//            }
122
//        }
123
124
//        if (info.getInitialSuspend()) {
125
//            command.add("-w"); // NOI18N
126
//        }
127
128
        boolean getStatus = false; // NbStartProcessParams.isStatusEx(params);
129
        if (getStatus) {
130
            command.add("--report"); // NOI18N
131
            command.add(hostInfo.getTempDir() + "/status"); // NOI18N
132
        }
133
134
        String envFile = NbStartConnectionInfoProvider.getEnvironmentFile(params);
135
        if (envFile != null) {
136
            command.add("--readenv"); // NOI18N
137
            command.add(envFile);
138
        }
139
140
        Map<String, String> env = params.getEnvironment();
141
142
        if (env != null) {
143
//            Map<String, String> userDefinedMap = userEnv.getUserDefinedMap();
144
145
            for (Map.Entry<String, String> entry : env.entrySet()) {
146
//                if (isWindows() && entry.getKey().equalsIgnoreCase("PATH")) { // NOI18N
147
//                    command.add("--env"); // NOI18N
148
//                    command.add(entry.getKey() + "=" + WindowsSupport.getInstance().convertToAllShellPaths(entry.getValue())); // NOI18N
149
//                    continue;
150
//                }
151
                command.add("--env"); // NOI18N
152
                command.add(entry.getKey() + "=" + entry.getValue()); // NOI18N
153
            }
154
        }
155
156
        if (terminalEmulation != null) {
157
            command.add("--env"); // NOI18N
158
            command.add("TERM=" + terminalEmulation); // NOI18N
159
        }
160
161
        if (params.isRedirectError()) {
162
            command.add("--redirect-error"); // NOI18N
163
        }
164
165
        final String shellScript = params.getShellScript();
166
        if (shellScript != null) {
167
            command.add(params.getShell());
168
            command.add("-c"); // NOI18N
169
            command.add("exec " + params.getShellScript()); // NOI18N
170
        } else {
171
            command.addAll(params.getCommand());
172
        }
173
        return command;
174
    }
175
176
    @Override
177
    public int getPID() {
178
        return pid;
179
    }
180
181
    public final void createAndStart() throws IOException {
182
        streams = createProcessImpl();
183
        readProcessInfo(getInputStream());
184
        final String tty = getProcessInfo("TTY"); // NOI18N
185
186
        if (tty != null) {
187
            ic.add(new ProcessTerminal() {
188
                @Override
189
                protected void ttyResized(Dimension size, Dimension pixelSize) {
190
                    try {
191
                        String pty = NbStartUtility.getInstance().getPath(params.getConnection());
192
                        ProcessBuilder pb = params.getConnection().getProcessBuilder();
193
                        pb.setExecutable(pty);
194
                        pb.setArguments(Arrays.asList("-p", tty, // NOI18N
195
                                "--resize", // NOI18N
196
                                size.width + "," + size.height + "," // NOI18N
197
                                + pixelSize.width + "," + pixelSize.height)); // NOI18N
198
                        pb.call();
199
                    } catch (IOException ex) {
200
                        Exceptions.printStackTrace(ex);
201
                    }
202
                }
203
            });
204
        }
205
    }
206
207
    @Override
208
    public Lookup getLookup() {
209
        return lookup;
210
    }
211
212
//    @Override
213
//    public <T extends Capability> T getCapability(Class<T> clazz) {
214
//        if (clazz.isAssignableFrom(TerminalCapability.class)) {
215
//            return clazz.cast(terminalCapability);
216
//        }
217
//        
218
//        return clazz.cast(null);
219
//    }
220
    protected abstract int waitResultImpl() throws InterruptedException;
221
222
    @Override
223
    public final int waitResult() throws InterruptedException {
224
        return waitResultImpl();
225
    }
226
227
    @Override
228
    public final InputStream getErrorStream() {
229
        return streams.err;
230
    }
231
232
    @Override
233
    public final InputStream getInputStream() {
234
        return streams.out;
235
    }
236
237
    @Override
238
    public final OutputStream getOutputStream() {
239
        return streams.in;
240
    }
241
242
    protected abstract IOStreams createProcessImpl() throws IOException;
243
244
    private void readProcessInfo(InputStream fromProcessStream) throws IOException {
245
        String line;
246
247
        while (!(line = readLine(fromProcessStream).trim()).isEmpty()) {
248
            addProcessInfo(line);
249
        }
250
251
        String pidProperty = getProcessInfo("PID"); // NOI18N
252
253
        if (pidProperty == null) {
254
            InputStream error = getErrorStream();
255
            while (!(line = readLine(error).trim()).isEmpty()) {
256
                log.fine(line);
257
            }
258
            throw new InternalError("Failed to get process PID"); // NOI18N
259
        }
260
261
        pid = Integer.parseInt(pidProperty);
262
    }
263
264
    private String readLine(final InputStream is) throws IOException {
265
        int c;
266
        StringBuilder sb = new StringBuilder(20);
267
268
        //      while (!isInterrupted()) {
269
        while (true) {
270
            c = is.read();
271
272
            if (c < 0 || c == '\n') {
273
                break;
274
            }
275
276
            sb.append((char) c);
277
        }
278
279
        return sb.toString().trim();
280
    }
281
282
    protected void addProcessInfo(String info) {
283
        int spos = info.indexOf('=');
284
        if (spos < 0) {
285
            throw new IllegalArgumentException("info must be in format NAME=VALUE - was " + info); // NOI18N
286
        }
287
        processInfo.put(info.substring(0, spos), info.substring(spos + 1));
288
    }
289
290
    protected String getProcessInfo(final String string) {
291
        return processInfo.get(string);
292
    }
293
294
    protected final class IOStreams {
295
296
        private final OutputStream in;
297
        private final InputStream out;
298
        private final InputStream err;
299
300
        public IOStreams(OutputStream in, InputStream out, InputStream err) {
301
            this.in = in;
302
            this.out = out;
303
            this.err = err;
304
        }
305
    }
306
}
(-)a/nativeexecution.impl/src/org/netbeans/modules/nativeexecution/impl/nbstart/NbStartRemoteProcessImpl.java (+128 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2012 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 2012 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.nativeexecution.impl.nbstart;
43
44
import com.jcraft.jsch.JSchException;
45
import java.io.IOException;
46
import org.netbeans.modules.cnd.execution.access.ConnectionAccessor;
47
import org.netbeans.modules.cnd.execution.api.Connection;
48
import org.netbeans.modules.cnd.execution.api.NativeExecutionException;
49
import org.netbeans.modules.cnd.execution.common.SignalUtils;
50
import org.netbeans.modules.cnd.execution.spi.ConnectionImplementation;
51
import org.netbeans.modules.cnd.execution.spi.NativeProcessParams;
52
import org.netbeans.modules.nativeexecution.impl.jsch.JSchConnection;
53
import org.netbeans.modules.nativeexecution.impl.jsch.JSchSupport;
54
import org.netbeans.modules.nativeexecution.impl.jsch.JSchSupport.ChannelStreams;
55
import org.openide.util.Exceptions;
56
57
/**
58
 *
59
 * @author akrasny
60
 */
61
public final class NbStartRemoteProcessImpl extends NbStartProcessImpl {
62
63
    private JSchConnection jschConnection;
64
    private ChannelStreams jschStreams;
65
66
    public NbStartRemoteProcessImpl(final NativeProcessParams params) {
67
        super(params);
68
    }
69
70
    @Override
71
    protected IOStreams createProcessImpl() throws IOException {
72
        JSchSupport.ChannelParams chParams = new JSchSupport.ChannelParams();
73
        chParams.setX11Forwarding(false /*NbStartProcessParams.isX11Forwarding(params)*/);
74
75
        StringBuilder sb = new StringBuilder();
76
77
        for (String arg : getCommand()) {
78
            sb.append('\'').append(arg).append('\'').append(' '); // NOI18N
79
        }
80
81
        Connection connection = params.getConnection();
82
        ConnectionImplementation cimpl = ConnectionAccessor.getDefault().getImpl(connection);
83
        jschConnection = (JSchConnection) cimpl;
84
85
        try {
86
            jschStreams = JSchSupport.startCommand(jschConnection, sb.toString(), chParams);
87
        } catch (NativeExecutionException ex) {
88
            Exceptions.printStackTrace(ex);
89
            throw new IOException(ex);
90
        }
91
        return new IOStreams(jschStreams.in, jschStreams.out, jschStreams.err);
92
    }
93
94
    @Override
95
    protected int waitResultImpl() throws InterruptedException {
96
        if (jschStreams == null || jschStreams.channel == null) {
97
            return -1;
98
        }
99
100
        try {
101
            while (jschStreams.channel.isConnected()) {
102
                Thread.sleep(200);
103
            }
104
105
//            finishing();
106
107
            return jschStreams.channel.getExitStatus();
108
        } finally {
109
            if (jschStreams != null) {
110
                try {
111
                    jschConnection.releaseChannel(jschStreams.channel);
112
                } catch (JSchException ex) {
113
                    Exceptions.printStackTrace(ex);
114
                }
115
            }
116
        }
117
    }
118
119
    @Override
120
    public void destroy() {
121
//        try {
122
//            jschStreams.channel.sendSignal(SignalUtils.Signal.SIGTERM.name());
123
//        } catch (Exception ex) {
124
//            // Exceptions.printStackTrace(ex);
125
//        }
126
        jschStreams.channel.disconnect();
127
    }
128
}
(-)a/nativeexecution.impl/src/org/netbeans/modules/nativeexecution/impl/nbstart/NbStartUtility.java (+108 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2012 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 2012 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.nativeexecution.impl.nbstart;
43
44
import org.netbeans.modules.cnd.execution.api.Connection;
45
import org.netbeans.modules.cnd.execution.spi.support.ConnectionInfo;
46
import org.netbeans.modules.cnd.execution.util.HostInfo;
47
import org.netbeans.modules.nativeexecution.impl.common.HelperUtility;
48
49
/**
50
 *
51
 * @author Andrew
52
 */
53
public class NbStartUtility extends HelperUtility {
54
55
    private static final boolean ENABLED = Boolean.parseBoolean(System.getProperty("enable.nbstart", "true")); // NOI18N
56
    private final static NbStartUtility instance = new NbStartUtility();
57
58
    public NbStartUtility() {
59
        super("bin/nativeexecution/${osname}-${platform}${_isa}/pty"); // NOI18N
60
    }
61
62
    public static NbStartUtility getInstance() {
63
        return instance;
64
    }
65
66
    public static boolean isSupported(Connection connection) {
67
        return instance.isSupported(HostInfo.getFor(connection));
68
    }
69
70
    public static boolean isSupported(final ConnectionInfo info) {
71
        if (!ENABLED) {
72
            return false;
73
        }
74
        if (info == null) {
75
            return false;
76
        }
77
        return true;
78
    }
79
80
    @Override
81
    public boolean isSupported(HostInfo hostInfo) {
82
        if (!ENABLED) {
83
            return false;
84
        }
85
86
        try {
87
            switch (hostInfo.getOS().getFamily()) {
88
                case MACOSX:
89
                case SOLARIS:
90
                case LINUX:
91
                    return true;
92
                case WINDOWS:
93
                    // For now will disable it on Windows, as there are some
94
                    // side-effects with paths (need deeper studying)
95
//                    Shell activeShell = WindowsSupport.getInstance().getActiveShell();
96
//                    if (activeShell == null || !Shell.ShellType.CYGWIN.equals(activeShell.type)) {
97
//                        return false;
98
//                    }
99
//                    return getPath(executionEnvironment) != null;
100
                    return false;
101
                default:
102
                    return false;
103
            }
104
        } catch (Exception ex) {
105
            return false;
106
        }
107
    }
108
}
(-)a/nativeexecution.impl/src/org/netbeans/modules/nativeexecution/impl/nbstart/TerminalConfigurationImpl.java (+76 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2012 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 2012 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.nativeexecution.impl.nbstart;
43
44
import org.netbeans.modules.dlight.spi.terminal.TerminalConfiguration;
45
46
/**
47
 *
48
 * @author Andrew
49
 */
50
public final class TerminalConfigurationImpl implements TerminalConfiguration {
51
52
    private boolean terminalMode;
53
54
    private String emulation;
55
56
    public TerminalConfigurationImpl() {
57
        super();
58
    }
59
60
    public boolean isTerminalMode() {
61
        return terminalMode;
62
    }
63
64
    public void setTerminalMode(boolean terminalMode) {
65
        this.terminalMode = terminalMode;
66
    }
67
68
    public String getEmulation() {
69
        return emulation;
70
    }
71
72
    public void setEmulation(String emulation) {
73
        this.emulation = emulation;
74
    }
75
76
}
(-)a/nativeexecution.impl/src/org/netbeans/modules/nativeexecution/impl/resources/Bundle.properties (+2 lines)
Line 0 Link Here
1
OpenIDE-Module-Name=Native Execution Implementation
2
(-)a/nativeexecution.impl/src/org/netbeans/modules/nativeexecution/impl/resources/hostinfo.sh (+130 lines)
Line 0 Link Here
1
#!/bin/sh
2
3
PATH=/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin
4
HOSTNAME=`uname -n`
5
OS=`uname -s`
6
CPUTYPE=`uname -p`
7
BITNESS=32
8
9
LS=/bin/ls
10
OSFAMILY=
11
DATETIME=`date -u +'%Y-%m-%d %H:%M:%S'`
12
13
if [ "${OS}" = "SunOS" ]; then
14
   BITNESS=`isainfo -b`
15
   OSFAMILY="SOLARIS"
16
   OSNAME="SunOS"
17
   OSBUILD=`head -1 /etc/release | sed -e "s/^ *//"`
18
   CPUNUM=`/usr/sbin/psrinfo -v | grep "^Status of" | wc -l | sed 's/^ *//'`
19
else
20
   if [ "${OS}" = "Darwin" ]; then
21
      sysctl hw.cpu64bit_capable | grep -q "1$"
22
      if [ $? -eq 0 ]; then
23
         BITNESS=64
24
      fi
25
   else
26
      uname -a | egrep "x86_64|WOW64" >/dev/null
27
      if [ $? -eq 0 ]; then
28
         BITNESS=64
29
      fi
30
   fi
31
32
   if [ -f "/etc/sun-release" ]; then
33
      OSNAME="${OS}-JDS"
34
      OSBUILD=`head -1 /etc/sun-release`
35
   elif [ -f /etc/SuSE-release ]; then
36
      OSNAME="${OS}-SuSE"
37
      OSBUILD=`cat /etc/SuSE-release | tr "\n" " "`;
38
   elif [ -f /etc/redhat-release ]; then
39
      OSNAME="${OS}-Redhat"
40
      OSBUILD=`head -1 /etc/redhat-release`
41
   elif [ -f /etc/gentoo-release ]; then
42
      OSNAME="${OS}-Gentoo"
43
      OSBUILD=`head -1 /etc/gentoo-release`
44
   elif [ -f /etc/lsb-release ]; then
45
      OSNAME="${OS}-"`cat /etc/lsb-release | grep DISTRIB_ID | sed 's/.*=//'`
46
      OSBUILD=`cat /etc/lsb-release | grep DISTRIB_DESCRIPTION | sed 's/.*=//' | sed 's/"//g'`
47
   fi
48
fi
49
50
OSFAMILY=${OSFAMILY:-`echo ${OS} | grep _NT- >/dev/null && echo WINDOWS`}
51
OSFAMILY=${OSFAMILY:-`test "$OS" = "Darwin" && echo MACOSX`}
52
OSFAMILY=${OSFAMILY:-`test "$OS" = "Linux" && echo LINUX`}
53
OSFAMILY=${OSFAMILY:-${OS}}
54
55
CPUFAMILY=`(echo ${CPUTYPE} | egrep "^i|x86_64|athlon|Intel" >/dev/null && echo x86) || echo ${CPUTYPE}`
56
if [ "${CPUFAMILY}" != "x86" -a "${CPUFAMILY}" != "sparc" ]; then
57
   CPUTYPE=`uname -m`
58
fi
59
CPUFAMILY=`(echo ${CPUTYPE} | egrep "^i|x86_64|athlon|Intel" >/dev/null && echo x86) || echo ${CPUTYPE}`
60
61
USERDIRBASE=${HOME}
62
63
if [ "${OSFAMILY}" = "LINUX" ]; then
64
   CPUNUM=`cat /proc/cpuinfo | grep processor | wc -l | sed 's/^ *//'`
65
elif [ "${OSFAMILY}" = "WINDOWS" ]; then
66
   CPUNUM=$NUMBER_OF_PROCESSORS
67
   OSNAME=`uname`
68
   USERDIRBASE=${USERPROFILE}
69
elif [ "${OSFAMILY}" = "MACOSX" ]; then
70
   CPUNUM=`hostinfo | awk '/processor.*logical/{print $1}'`
71
   OSNAME="MacOSX"
72
   OSBUILD=`hostinfo | sed -n '/kernel version/{n;p;}' | sed 's/[	 ]*\([^:]*\).*/\1/'`
73
fi
74
75
USER=${USER:-`logname 2>/dev/null`}
76
USER=${USER:-${USERNAME}}
77
TMPBASE=${TMPBASE:-/var/tmp}
78
79
SUFFIX=0
80
TMPDIRBASE=${TMPBASE}/nbexec_${USER}
81
mkdir -p ${TMPDIRBASE}
82
while [ ! -w ${TMPDIRBASE} -a ${SUFFIX} -lt 5 ]; do
83
    echo "Warning: ${TMPDIRBASE} is not writable">&2
84
    SUFFIX=`expr 1 + ${SUFFIX}`
85
    TMPDIRBASE=${TMPBASE}/nbexec_${USER}_${SUFFIX}
86
    /bin/mkdir -p ${TMPDIRBASE} 2>/dev/null
87
done
88
89
if [ -w ${TMPDIRBASE} ]; then
90
    SUFFIX=0
91
    TMPBASE=${TMPDIRBASE}
92
    TMPDIRBASE=${TMPBASE}/${NB_KEY}
93
    mkdir -p ${TMPDIRBASE}
94
    while [ ! -w ${TMPDIRBASE} -a ${SUFFIX} -lt 5 ]; do
95
        echo "Warning: ${TMPDIRBASE} is not writable">&2
96
        SUFFIX=`expr 1 + ${SUFFIX}`
97
        TMPDIRBASE=${TMPBASE}/${NB_KEY}_${SUFFIX}
98
        /bin/mkdir -p ${TMPDIRBASE} 2>/dev/null
99
    done
100
fi
101
102
if [ ! -w ${TMPDIRBASE} ]; then
103
    TMPDIRBASE=${TMPBASE}
104
fi
105
106
if [ ! -w ${TMPDIRBASE} ]; then
107
    echo "Error: {TMPDIRBASE} is not writable">&2
108
fi
109
110
ID=`LC_MESSAGES=C /usr/bin/id`
111
112
echo
113
echo @@@@@INFO
114
echo BITNESS=${BITNESS}
115
echo CPUFAMILY=${CPUFAMILY}
116
echo CPUNUM=${CPUNUM}
117
echo CPUTYPE=${CPUTYPE}
118
echo HOSTNAME=${HOSTNAME}
119
echo OSNAME=${OSNAME}
120
echo OSBUILD=${OSBUILD}
121
echo OSFAMILY=${OSFAMILY}
122
echo USER=${USER}
123
echo SHELL=${SHELL}
124
echo USERDIRBASE=${USERDIRBASE}
125
echo TMPDIRBASE=${TMPDIRBASE}
126
echo DATETIME=${DATETIME}
127
echo ID=${ID}
128
echo @@@@@ENV
129
env
130
exit 0
(-)a/nativeexecution.impl/src/org/netbeans/modules/nativeexecution/impl/util/EnvironmentMapWriter.java (+97 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2012 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 2012 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.nativeexecution.impl.util;
43
44
import java.io.IOException;
45
import java.io.OutputStreamWriter;
46
import java.util.Arrays;
47
import java.util.HashSet;
48
import java.util.Map;
49
import java.util.logging.Level;
50
import java.util.regex.Pattern;
51
import org.netbeans.modules.cnd.execution.ExecutionLogger;
52
53
/**
54
 *
55
 * @author akrasny
56
 */
57
public final class EnvironmentMapWriter {
58
59
    public static final HashSet<String> varsNotForExport = new HashSet<String>(Arrays.asList(
60
            "SSH_AUTH_SOCK", "SSH_CONNECTION", "SSH_CLIENT", "SSH_TTY", "TZ", "HZ", "SHELL" // NOI18N
61
            ));
62
63
    private EnvironmentMapWriter() {
64
    }
65
66
    public static void write(OutputStreamWriter writer, Map<String, String> environmentMap) throws IOException {
67
        if (environmentMap.entrySet().isEmpty()) {
68
            return;
69
        }
70
        // Very simple sanity check of vars...
71
        Pattern pattern = Pattern.compile("[a-zA-Z0-9_]+"); // NOI18N
72
73
        for (Map.Entry<String, String> entry : environmentMap.entrySet()) {
74
            String name = entry.getKey();
75
76
            if (varsNotForExport.contains(name)) {
77
                continue;
78
            }
79
80
            String value = entry.getValue();
81
            // check capitalized key by pattern
82
            if (!pattern.matcher(name).matches()) {
83
                ExecutionLogger.getInstance().log(Level.WARNING,
84
                        "Will not pass environment variable named {0} as it contains non alpha-numeric characters", name); // NOI18N
85
                continue;
86
            }
87
88
            if (value.indexOf('"') >= 0) { // NOI18N
89
                value = value.replace("\"", "\\\""); // NOI18N
90
            }
91
92
            writer.write(name + "=\"" + value + "\" && export " + name + "\n"); // NOI18N
93
        }
94
95
        writer.flush();
96
    }
97
}
(-)a/nativeexecution.impl/src/org/netbeans/modules/nativeexecution/impl/util/FileOperationsSupport.java (+54 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2012 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 2012 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.nativeexecution.impl.util;
43
44
import java.io.File;
45
import java.io.IOException;
46
47
/**
48
 *
49
 * @author Andrew
50
 */
51
public interface FileOperationsSupport {
52
53
    public String uploadFile(File srcLocalFile, String dstRemoteFile, int mode) throws IOException;
54
}
(-)a/nativeexecution.impl/test/unit/src/org/netbeans/modules/nativeexecution/impl/ExecutionTestCase.java (+60 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2012 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 2012 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.nativeexecution.impl;
43
44
import org.netbeans.junit.NbTestCase;
45
46
/**
47
 *
48
 * @author Andrew
49
 */
50
public abstract class ExecutionTestCase extends NbTestCase {
51
52
    static {
53
        // Setting netbeans.dirs makes installedFileLocator work properly
54
        System.setProperty("netbeans.dirs", NbClustersInfoProvider.getClusters());
55
    }
56
57
    public ExecutionTestCase(String name) {
58
        super(name);
59
    }
60
}
(-)a/nativeexecution.impl/test/unit/src/org/netbeans/modules/nativeexecution/impl/NbClustersInfoProvider.java (+121 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2012 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 2012 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.nativeexecution.impl;
43
44
import java.io.File;
45
import java.io.FileFilter;
46
import java.util.TreeSet;
47
import junit.framework.Assert;
48
import org.netbeans.junit.NbModuleSuite;
49
50
/**
51
 *
52
 * @author akrasny
53
 */
54
public final class NbClustersInfoProvider {
55
56
    private NbClustersInfoProvider() {
57
    }
58
59
    public static String getClusters() {
60
        // Setting netbeans.dirs makes installedFileLocator work properly
61
        File[] clusters = findClusters();
62
        StringBuilder sb = new StringBuilder();
63
        for (File cluster : clusters) {
64
            if (sb.length() > 0) {
65
                sb.append(File.pathSeparator);
66
            }
67
            sb.append(cluster.getPath());
68
        }
69
        return sb.toString();
70
    }
71
72
    // it's like what org.netbeans.junit.NbModuleSuite does,
73
    // but reusing NbModuleSuite will cause too massive changes in existing CND tests
74
    private static File[] findClusters() {
75
        File netbeans = findNetbeans();
76
        assert netbeans != null;
77
        File[] clusters = netbeans.listFiles(new FileFilter() {
78
79
            @Override
80
            public boolean accept(File dir) {
81
                if (dir.isDirectory()) {
82
                    File m = new File(new File(dir, "config"), "Modules");
83
                    return m.exists();
84
                }
85
                return false;
86
            }
87
        });
88
        return clusters;
89
    }
90
91
    // it's like what org.netbeans.junit.NbModuleSuite does,
92
    // but reusing NbModuleSuite will cause too massive changes in existing CND tests
93
    private static File findNetbeans() {
94
        try {
95
            Class<?> lookup = Class.forName("org.openide.util.Lookup"); // NOI18N
96
            File util = new File(lookup.getProtectionDomain().getCodeSource().getLocation().toURI());
97
            Assert.assertTrue("Util exists: " + util, util.exists());
98
            return util.getParentFile().getParentFile().getParentFile();
99
        } catch (Exception ex) {
100
            try {
101
                File nbjunit = new File(NbModuleSuite.class.getProtectionDomain().getCodeSource().getLocation().toURI());
102
                File harness = nbjunit.getParentFile().getParentFile();
103
                Assert.assertEquals("NbJUnit is in harness", "harness", harness.getName());
104
                TreeSet<File> sorted = new TreeSet<File>();
105
                File[] listFiles = harness.getParentFile().listFiles();
106
                if (listFiles != null) {
107
                    for (File p : listFiles) {
108
                        if (p.getName().startsWith("platform")) {
109
                            sorted.add(p);
110
                        }
111
                    }
112
                }
113
                Assert.assertFalse("Platform shall be found in " + harness.getParent(), sorted.isEmpty());
114
                return sorted.last();
115
            } catch (Exception ex2) {
116
                Assert.fail("Cannot find utilities JAR: " + ex + " and: " + ex2);
117
            }
118
            return null;
119
        }
120
    }
121
}
(-)a/nativeexecution.impl/test/unit/src/org/netbeans/modules/nativeexecution/impl/common/HelperUtilityTest.java (+103 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2012 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 2012 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.nativeexecution.impl.common;
43
44
import java.net.URI;
45
import org.junit.After;
46
import org.junit.AfterClass;
47
import org.junit.Before;
48
import org.junit.BeforeClass;
49
import org.junit.Test;
50
import org.netbeans.modules.cnd.execution.api.Connection;
51
import org.netbeans.modules.cnd.execution.api.ConnectionManager;
52
import org.netbeans.modules.nativeexecution.impl.ExecutionTestCase;
53
import org.netbeans.modules.cnd.execution.util.HostInfo;
54
55
/**
56
 *
57
 * @author Andrew
58
 */
59
public class HelperUtilityTest extends ExecutionTestCase {
60
61
    public HelperUtilityTest(String name) {
62
        super(name);
63
    }
64
65
    @BeforeClass
66
    public static void setUpClass() {
67
    }
68
69
    @AfterClass
70
    public static void tearDownClass() {
71
    }
72
73
    @Before
74
    @Override
75
    public void setUp() throws Exception {
76
        super.setUp();
77
    }
78
79
    @After
80
    @Override
81
    public void tearDown() throws Exception {
82
        super.tearDown();
83
    }
84
85
    /**
86
     * Test of getPath method, of class HelperUtility.
87
     */
88
    @Test
89
    public void testGetPath() throws Exception {
90
        HelperUtility test = new HelperUtility("bin/nativeexecution/$osname-${platform}$_isa/pty_open");
91
        Connection localConnection = ConnectionManager.getLocalConnection();
92
        HostInfo info = HostInfo.getFor(localConnection);
93
        System.out.println(test.getLocalFileFor(info).getAbsolutePath());
94
        System.out.println(test.getPath(localConnection));
95
        String rurl = System.getProperty("test.remote.url");
96
        if (rurl != null) {
97
            Connection remote = ConnectionManager.connect(new URI(rurl));
98
            System.out.println(test.getPath(remote));
99
        } else {
100
            System.out.println("test.remote.url property is not defined...");
101
        }
102
    }
103
}
(-)a/dlight.nativeexecution/test/unit/src/org/netbeans/modules/nativeexecution/RedirectErrorTest.java (-62 / +101 lines)
Lines 39-115 Link Here
39
 *
39
 *
40
 * Portions Copyrighted 2012 Sun Microsystems, Inc.
40
 * Portions Copyrighted 2012 Sun Microsystems, Inc.
41
 */
41
 */
42
package org.netbeans.modules.nativeexecution;
42
package org.netbeans.modules.nativeexecution.impl.common;
43
43
44
import junit.framework.Test;
44
import java.io.StringWriter;
45
import org.junit.After;
45
import java.io.Writer;
46
import org.junit.Before;
46
import java.net.URI;
47
import org.netbeans.modules.nativeexecution.api.ExecutionEnvironment;
47
import java.net.URISyntaxException;
48
import org.netbeans.modules.nativeexecution.api.ExecutionEnvironmentFactory;
48
import java.util.concurrent.ExecutionException;
49
import org.netbeans.modules.nativeexecution.api.NativeProcessBuilder;
49
import org.netbeans.api.extexecution.ExecutionService;
50
import org.netbeans.modules.nativeexecution.api.util.ConnectionManager;
50
import org.netbeans.api.extexecution.input.LineProcessor;
51
import org.netbeans.modules.nativeexecution.api.util.ProcessUtils;
51
import org.netbeans.modules.cnd.execution.api.Connection;
52
import org.netbeans.modules.nativeexecution.api.util.ProcessUtils.ExitStatus;
52
import org.netbeans.modules.cnd.execution.api.ConnectionManager;
53
import org.netbeans.modules.nativeexecution.test.ForAllEnvironments;
53
import org.netbeans.modules.cnd.execution.api.NativeExecutionException;
54
import org.netbeans.modules.nativeexecution.test.NativeExecutionBaseTestCase;
54
import org.netbeans.modules.cnd.execution.api.NativeProcessBuilder;
55
import org.netbeans.modules.nativeexecution.test.NativeExecutionBaseTestSuite;
55
import org.netbeans.modules.cnd.execution.spi.AuthDataProvider;
56
import org.netbeans.modules.nativeexecution.impl.ExecutionTestCase;
57
import org.openide.util.Exceptions;
56
58
57
/**
59
/**
58
 *
60
 *
59
 * @author akrasny
61
 * @author akrasny
60
 */
62
 */
61
public final class RedirectErrorTest extends NativeExecutionBaseTestCase {
63
public final class RedirectErrorTest extends ExecutionTestCase {
64
65
    private URI remoteURI = null;
62
66
63
    public RedirectErrorTest(String name) {
67
    public RedirectErrorTest(String name) {
64
        super(name);
68
        super(name);
65
    }
66
69
67
    public RedirectErrorTest(String name, ExecutionEnvironment execEnv) {
70
        String testURI = System.getProperty("ne.remote.uri"); // NOI18N
68
        super(name, execEnv);
71
        if (testURI != null) {
69
    }
72
            try {
70
73
                remoteURI = new URI(testURI);
71
    public static Test suite() {
74
            } catch (URISyntaxException ex) {
72
        return new NativeExecutionBaseTestSuite(RedirectErrorTest.class);
75
                Exceptions.printStackTrace(ex);
73
    }
76
            }
74
75
    @Before
76
    @Override
77
    protected void setUp() throws Exception {
78
        super.setUp();
79
        ExecutionEnvironment env = getTestExecutionEnvironment();
80
        if (env != null) {
81
            ConnectionManager.getInstance().connect(env);
82
        }
77
        }
83
    }
78
    }
84
79
85
    @After
80
    @org.junit.Test
86
    @Override
81
    public void testRedirectError_remote() throws Exception {
87
    protected void tearDown() throws Exception {
82
        if (remoteURI != null) {
88
        ExecutionEnvironment env = getTestExecutionEnvironment();
83
            doTestRedirectError(ConnectionManager.connect(remoteURI, new AuthDataProviderImpl()));
89
        if (env != null) {
90
            ConnectionManager.getInstance().disconnect(env);
91
        }
84
        }
92
        super.tearDown();
93
    }
94
95
    @org.junit.Test
96
    @ForAllEnvironments(section = "remote.platforms")
97
    public void testRedirectError_remote() throws Exception {
98
        doTestRedirectError(getTestExecutionEnvironment());
99
    }
85
    }
100
86
101
    @org.junit.Test
87
    @org.junit.Test
102
    public void testRedirectError_local() throws Exception {
88
    public void testRedirectError_local() throws Exception {
103
        doTestRedirectError(ExecutionEnvironmentFactory.getLocal());
89
        doTestRedirectError(ConnectionManager.getLocalConnection());
104
    }
90
    }
105
91
106
    private void doTestRedirectError(ExecutionEnvironment env, boolean cmdLine, boolean tty, boolean redirectError) {
92
    private void doTestRedirectError(Connection connection, boolean cmdLine, boolean tty, boolean redirectError) throws NativeExecutionException {
107
        if (env == null) {
93
        if (connection == null || !connection.isConnected()) {
108
            return;
94
            return;
109
        }
95
        }
110
96
111
        System.out.println();
97
        System.out.println();
112
        System.out.println("RedirectErrorTest @ " + env.getDisplayName()); // NOI18N
98
        System.out.println("RedirectErrorTest @ " + connection.getDisplayName()); // NOI18N
113
        System.out.println("\tconfigure builder using " + (cmdLine ? "setCommandLine()" : "setExecutable()")); // NOI18N
99
        System.out.println("\tconfigure builder using " + (cmdLine ? "setCommandLine()" : "setExecutable()")); // NOI18N
114
        System.out.println("\tconfigure builder " + (redirectError ? "" : "not ") + "to do redirectError()"); // NOI18N
100
        System.out.println("\tconfigure builder " + (redirectError ? "" : "not ") + "to do redirectError()"); // NOI18N
115
        System.out.println("\tconfigure builder " + (tty ? "" : "not ") + "to be started in a pseudo-terminal"); // NOI18N
101
        System.out.println("\tconfigure builder " + (tty ? "" : "not ") + "to be started in a pseudo-terminal"); // NOI18N
Lines 117-137 Link Here
117
        boolean errorRedirect = (tty || redirectError) ? true : false;
103
        boolean errorRedirect = (tty || redirectError) ? true : false;
118
        System.out.println("Extected that error goes to " + (errorRedirect ? "output" : "error")); // NOI18N
104
        System.out.println("Extected that error goes to " + (errorRedirect ? "output" : "error")); // NOI18N
119
105
120
        NativeProcessBuilder npb = NativeProcessBuilder.newProcessBuilder(env);
106
        NativeProcessBuilder npb = connection.newNativeProcessBuilder();
121
107
122
        if (cmdLine) {
108
        if (cmdLine) {
123
            npb.setCommandLine("wrong"); // NOI18N
109
            npb.setShellScript("/bin/sh", "wrong"); // NOI18N
124
        } else {
110
        } else {
125
            npb.setExecutable("wrong"); // NOI18N
111
            npb.setCommand("wrong"); // NOI18N
126
        }
112
        }
127
113
128
        npb.setUsePty(tty);
114
//        npb.setUsePty(tty);
129
115
130
        if (redirectError) {
116
        if (redirectError) {
131
            npb.redirectError();
117
            npb.redirectErrorStream(true);
132
        }
118
        }
133
119
134
        ExitStatus status = ProcessUtils.execute(npb);
120
        ExitStatus status = exec(npb);
121
135
        System.out.println("Result is: "); // NOI18N
122
        System.out.println("Result is: "); // NOI18N
136
        System.out.println(status.toString());
123
        System.out.println(status.toString());
137
124
Lines 142-155 Link Here
142
        }
129
        }
143
    }
130
    }
144
131
145
    private void doTestRedirectError(ExecutionEnvironment env) {
132
    private void doTestRedirectError(Connection connection) throws NativeExecutionException {
146
        doTestRedirectError(env, false, false, false);
133
        doTestRedirectError(connection, false, false, false);
147
        doTestRedirectError(env, false, false, true);
134
        doTestRedirectError(connection, false, false, true);
148
        doTestRedirectError(env, false, true, false);
135
//        doTestRedirectError(connection, false, true, false);
149
        doTestRedirectError(env, false, true, true);
136
//        doTestRedirectError(connection, false, true, true);
150
        doTestRedirectError(env, true, false, false);
137
        doTestRedirectError(connection, true, false, false);
151
        doTestRedirectError(env, true, false, true);
138
        doTestRedirectError(connection, true, false, true);
152
        doTestRedirectError(env, true, true, false);
139
//        doTestRedirectError(connection, true, true, false);
153
        doTestRedirectError(env, true, true, true);
140
//        doTestRedirectError(connection, true, true, true);
141
    }
142
143
    private ExitStatus exec(NativeProcessBuilder npb) {
144
        try {
145
            Writer outWriter = new StringWriter();
146
            Writer errWriter = new StringWriter();
147
            ExecutionService execService = ExecutionService.newService(npb, outWriter, errWriter);
148
            Integer rc = execService.run().get();
149
            return new ExitStatus(rc, outWriter.toString(), errWriter.toString());
150
        } catch (InterruptedException ex) {
151
            Exceptions.printStackTrace(ex);
152
        } catch (ExecutionException ex) {
153
            Exceptions.printStackTrace(ex);
154
        }
155
156
        return new ExitStatus(-1, "Internal Error: FAILED", "Internal Error: FAILED"); // NOI18N
157
    }
158
159
    private static class AuthDataProviderImpl implements AuthDataProvider {
160
161
        @Override
162
        public <T> T getProperty(URI uri, Class<T> clazz, String name, Object... misc) {
163
            Object result = null;
164
165
            if (String.class.equals(clazz) && "KnownHostsFile".equals(name)) {
166
                result = System.getProperty("user.home") + "/.ssh/known_hosts";
167
            }
168
169
            if (String.class.equals(clazz) && "AuthType".equals(name)) { // NOI18N
170
                result = "password"; // NOI18N
171
            }
172
            
173
            return clazz.cast(result);
174
        }
175
    }
176
177
    private static class ExitStatus {
178
179
        private final Integer rc;
180
        private final String output;
181
        private final String error;
182
183
        private ExitStatus(Integer rc, String out, String err) {
184
            this.rc = rc;
185
            this.output = out;
186
            this.error = err;
187
        }
188
189
        @Override
190
        public String toString() {
191
            return "ExitCode: " + rc + "; Output: " + output + "; Error: " + error; // NOI18N
192
        }
154
    }
193
    }
155
}
194
}
(-)a/nativeexecution.impl/test/unit/src/org/netbeans/modules/nativeexecution/impl/jsch/RemoteProcessImplTest.java (+148 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2012 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 2012 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.nativeexecution.impl.jsch;
43
44
import java.io.StringWriter;
45
import java.net.URI;
46
import java.net.URISyntaxException;
47
import org.junit.After;
48
import org.junit.AfterClass;
49
import static org.junit.Assert.*;
50
import org.junit.Before;
51
import org.junit.BeforeClass;
52
import org.junit.Test;
53
import org.netbeans.api.extexecution.ExecutionService;
54
import org.netbeans.modules.cnd.execution.access.ConnectionAccessor;
55
import org.netbeans.modules.cnd.execution.api.Connection;
56
import org.netbeans.modules.cnd.execution.api.ConnectionManager;
57
import org.netbeans.modules.cnd.execution.api.EnvironmentMap;
58
import org.netbeans.modules.cnd.execution.api.NativeProcessBuilder;
59
import org.netbeans.modules.cnd.execution.spi.AuthDataProvider;
60
import org.openide.util.Exceptions;
61
62
/**
63
 *
64
 * @author Andrew
65
 */
66
public class RemoteProcessImplTest {
67
68
    private URI remoteURI = null;
69
70
    public RemoteProcessImplTest() {
71
        String testURI = System.getProperty("ne.remote.uri"); // NOI18N
72
        if (testURI != null) {
73
            try {
74
                remoteURI = new URI(testURI);
75
            } catch (URISyntaxException ex) {
76
                Exceptions.printStackTrace(ex);
77
            }
78
        }
79
    }
80
81
    @BeforeClass
82
    public static void setUpClass() throws Exception {
83
    }
84
85
    @AfterClass
86
    public static void tearDownClass() throws Exception {
87
    }
88
89
    @Before
90
    public void setUp() {
91
    }
92
93
    @After
94
    public void tearDown() {
95
    }
96
97
    @Test
98
    public void testEnvironmentMap() throws Exception {
99
        if (remoteURI == null) {
100
            System.out.println("Skipped. To proceed, please use -Dne.remote.host=<remote_host> in test.run.args parameters list.");
101
            System.out.println("It is expected that host can be logged in by user 'tester' with a password 'tester'.");
102
            return;
103
        }
104
105
        Connection c = null;
106
        try {
107
            c = ConnectionManager.connect(remoteURI, new AuthDataProviderImpl());
108
            NativeProcessBuilder pb = c.newNativeProcessBuilder();
109
            EnvironmentMap env = pb.getEnvironmentMap();
110
            assertNotNull("EnvironmentMap is never NULL", env);
111
            assertFalse("Environment map should not be empty", env.isEmpty());
112
            env.put("testEnvironmentMap", "some-value");
113
114
            assertNull("testEnvironmentMap should NOT be in the map of other process builder",
115
                    c.newNativeProcessBuilder().getEnvironmentMap().get("testEnvironmentMap"));
116
117
            assertTrue("testEnvironmentMap should be in the map", "some-value".equals(env.get("testEnvironmentMap")));
118
            assertTrue("testEnvironmentMap should be in the map", "some-value".equals(pb.getEnvironmentMap().get("testEnvironmentMap")));
119
120
            pb.setCommand("env");
121
            StringWriter output = new StringWriter();
122
            ExecutionService.newService(pb, output, null).run().get();
123
            String data = "\n" + output.toString() + "\n";
124
            String[] split = data.split("\n");
125
126
            assertTrue(Math.abs(100 - (split.length * 100 / env.size())) < 10);
127
            assertTrue("testEnvironmentMap should be in the env", data.indexOf("\ntestEnvironmentMap=some-value\n") > 0);
128
        } finally {
129
            if (c != null) {
130
                ConnectionAccessor.getDefault().getImpl(c).disconnect();
131
            }
132
        }
133
    }
134
135
    private static class AuthDataProviderImpl implements AuthDataProvider {
136
137
        @Override
138
        public <T> T getProperty(URI uri, Class<T> clazz, String name, Object... misc) {
139
            Object result = null;
140
141
            if (String.class.equals(clazz) && "KnownHostsFile".equals(name)) {
142
                result = System.getProperty("user.home") + "/.ssh/known_hosts";
143
            }
144
145
            return clazz.cast(result);
146
        }
147
    }
148
}
(-)a/nativeexecution.impl/test/unit/src/org/netbeans/modules/nativeexecution/impl/local/LocalProcessTest.java (+149 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2012 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 2012 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.nativeexecution.impl.local;
43
44
import java.io.StringWriter;
45
import java.net.URI;
46
import org.junit.After;
47
import org.junit.AfterClass;
48
import static org.junit.Assert.*;
49
import org.junit.Before;
50
import org.junit.BeforeClass;
51
import org.junit.Test;
52
import org.netbeans.api.extexecution.ExecutionService;
53
import org.netbeans.modules.cnd.execution.api.Connection;
54
import org.netbeans.modules.cnd.execution.api.ConnectionManager;
55
import org.netbeans.modules.cnd.execution.api.EnvironmentMap;
56
import org.netbeans.modules.cnd.execution.api.NativeProcessBuilder;
57
import org.netbeans.modules.nativeexecution.impl.ExecutionTestCase;
58
59
/**
60
 *
61
 * @author akrasny
62
 */
63
public class LocalProcessTest extends ExecutionTestCase {
64
65
    public LocalProcessTest(String name) {
66
        super(name);
67
    }
68
69
    @BeforeClass
70
    public static void setUpClass() throws Exception {
71
    }
72
73
    @AfterClass
74
    public static void tearDownClass() throws Exception {
75
    }
76
77
    @Before
78
    @Override
79
    public void setUp() {
80
    }
81
82
    @After
83
    @Override
84
    public void tearDown() {
85
    }
86
87
    /**
88
     * Test of create method, of class LocalProcess.
89
     */
90
    @Test
91
    public void testCreate() throws Exception {
92
        Connection connection1 = ConnectionManager.getConnection(new URI("localhost"));
93
        Connection connection2 = ConnectionManager.getConnection(connection1.getURI());
94
        Connection connection3 = ConnectionManager.getLocalConnection();
95
96
        assertEquals(connection1, connection2);
97
        assertEquals(connection2, connection3);
98
99
        assertTrue(connection1 == connection2);
100
        assertTrue(connection2 == connection3);
101
102
        assertTrue(connection1.isConnected());
103
        assertTrue(connection2.isConnected());
104
        assertTrue(connection3.isConnected());
105
    }
106
107
    @Test
108
    public void testEnvironmentMap() throws Exception {
109
        Connection c = ConnectionManager.getLocalConnection();
110
        NativeProcessBuilder pb = c.newNativeProcessBuilder();
111
        EnvironmentMap env = pb.getEnvironmentMap();
112
        assertNotNull("EnvironmentMap is never NULL", env);
113
        assertFalse("Environment map should not be empty", env.isEmpty());
114
        env.put("testEnvironmentMap", "some-value");
115
116
        assertNull("testEnvironmentMap should NOT be in the map of other process builder",
117
                c.newNativeProcessBuilder().getEnvironmentMap().get("testEnvironmentMap"));
118
119
        assertTrue("testEnvironmentMap should be in the map", "some-value".equals(env.get("testEnvironmentMap")));
120
        assertTrue("testEnvironmentMap should be in the map", "some-value".equals(pb.getEnvironmentMap().get("testEnvironmentMap")));
121
122
        pb.setCommand("env");
123
        StringWriter output = new StringWriter();
124
        ExecutionService.newService(pb, output, null).run().get();
125
        String data = "\n" + output.toString() + "\n";
126
        System.out.println(data);
127
        String[] split = data.split("\n");
128
129
        assertTrue(Math.abs(100 - (split.length * 100 / env.size())) < 10);
130
        assertTrue("testEnvironmentMap should be in the env", data.indexOf("\ntestEnvironmentMap=some-value\n") > 0);
131
    }
132
//    
133
//    @Test
134
//    public void testEnvironmentMap() throws Exception {
135
//        Connection c = ConnectionManager.getLocalConnection();
136
//        NativeProcessBuilder pb = c.newProcessBuilder().setCommand("/bin/ls", "/tmp");
137
//        ExitStatus result = ProcessUtils.execute(pb);
138
//        System.out.println(result.output);
139
//
140
//        pb.getEnvironmentMap().dump(System.out);
141
//        System.out.println("----");
142
//        Map<String, String> environment = new ProcessBuilder("").environment();
143
//        for (Map.Entry<String, String> entry : environment.entrySet()) {
144
//            System.out.println(entry.getKey() + " = " + entry.getValue());
145
//        }
146
//
147
//        ConnectionManager.getLocalConnection();
148
//    }
149
}
(-)a/nbbuild/cluster.properties (-1 / +4 lines)
Lines 269-275 Link Here
269
        defaults,\
269
        defaults,\
270
        derby,\
270
        derby,\
271
        diff,\
271
        diff,\
272
        dlight.nativeexecution,\
273
        dlight.terminal,\
272
        dlight.terminal,\
274
        editor,\
273
        editor,\
275
        editor.actions,\
274
        editor.actions,\
Lines 991-1000 Link Here
991
        nb.cluster.platform,\
990
        nb.cluster.platform,\
992
        nb.cluster.ide
991
        nb.cluster.ide
993
nb.cluster.dlight=\
992
nb.cluster.dlight=\
993
        cnd.execution,\
994
        dlight.kit,\
994
        dlight.kit,\
995
        dlight.libs.common,\
995
        dlight.libs.common,\
996
        dlight.nativeexecution,\
996
        dlight.remote,\
997
        dlight.remote,\
997
        dlight.remote.impl,\
998
        dlight.remote.impl,\
999
        execmerge,\
1000
        nativeexecution.impl,\
998
        remotefs.versioning
1001
        remotefs.versioning
999
1002
1000
1003

Return to bug 232434