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

(-)a/java.j2seproject/nbproject/project.xml (-1 / +1 lines)
Lines 55-61 Link Here
55
                    <compile-dependency/>
55
                    <compile-dependency/>
56
                    <run-dependency>
56
                    <run-dependency>
57
                        <release-version>3</release-version>
57
                        <release-version>3</release-version>
58
                        <specification-version>3.73</specification-version>
58
                        <specification-version>3.84</specification-version>
59
                    </run-dependency>
59
                    </run-dependency>
60
                </dependency>
60
                </dependency>
61
                <dependency>
61
                <dependency>
(-)a/java.j2seproject/src/org/netbeans/modules/java/j2seproject/Bundle.properties (+2 lines)
Lines 94-96 Link Here
94
J2SEProject.too_new=This version of the IDE is too old to read metadata in {0}.
94
J2SEProject.too_new=This version of the IDE is too old to read metadata in {0}.
95
95
96
96
97
#J2SEActionProvider
98
LBL_CompileOnSaveUpdate=Compile on Save Update
(-)a/java.j2seproject/src/org/netbeans/modules/java/j2seproject/J2SEActionProvider.java (-3 / +41 lines)
Lines 67-80 Link Here
67
import java.util.Set;
67
import java.util.Set;
68
import java.util.WeakHashMap;
68
import java.util.WeakHashMap;
69
import java.util.concurrent.atomic.AtomicReference;
69
import java.util.concurrent.atomic.AtomicReference;
70
import java.util.function.Predicate;
70
import java.util.logging.Level;
71
import java.util.logging.Level;
71
import java.util.logging.Logger;
72
import java.util.logging.Logger;
72
import java.util.stream.Stream;
73
import java.util.stream.Stream;
73
import javax.swing.event.ChangeListener;
74
import javax.swing.event.ChangeListener;
74
import org.apache.tools.ant.module.api.AntProjectCookie;
75
import org.apache.tools.ant.module.api.AntProjectCookie;
76
import org.apache.tools.ant.module.api.AntTargetExecutor;
75
import org.apache.tools.ant.module.api.support.ActionUtils;
77
import org.apache.tools.ant.module.api.support.ActionUtils;
78
import org.apache.tools.ant.module.api.support.AntScriptUtils;
76
import org.netbeans.api.annotations.common.CheckForNull;
79
import org.netbeans.api.annotations.common.CheckForNull;
77
import org.netbeans.api.annotations.common.NonNull;
80
import org.netbeans.api.annotations.common.NonNull;
81
import org.netbeans.api.annotations.common.NullAllowed;
78
import org.netbeans.api.java.classpath.ClassPath;
82
import org.netbeans.api.java.classpath.ClassPath;
79
import org.netbeans.api.java.project.JavaProjectConstants;
83
import org.netbeans.api.java.project.JavaProjectConstants;
80
import org.netbeans.api.java.source.BuildArtifactMapper;
84
import org.netbeans.api.java.source.BuildArtifactMapper;
Lines 109-114 Link Here
109
import org.openide.util.ChangeSupport;
113
import org.openide.util.ChangeSupport;
110
import org.openide.util.Exceptions;
114
import org.openide.util.Exceptions;
111
import org.openide.util.Lookup;
115
import org.openide.util.Lookup;
116
import org.openide.util.NbBundle;
112
import org.openide.util.Pair;
117
import org.openide.util.Pair;
113
import org.openide.util.Parameters;
118
import org.openide.util.Parameters;
114
import org.openide.util.RequestProcessor;
119
import org.openide.util.RequestProcessor;
Lines 466-476 Link Here
466
                    if (buildXml != null) {
471
                    if (buildXml != null) {
467
                        if (checkImportantFiles(buildXml)) {
472
                        if (checkImportantFiles(buildXml)) {
468
                            try {
473
                            try {
469
                                    ActionUtils.runTarget(
474
                                    runTargetInDedicatedTab(
475
                                        NbBundle.getMessage(J2SEActionProvider.class, "LBL_CompileOnSaveUpdate"),
470
                                        buildXml,
476
                                        buildXml,
471
                                        new String[] {target},
477
                                        new String[] {target},
472
                                        null,
478
                                        null,
473
                                            null);
479
                                        null);
474
                            } catch (IOException ioe) {
480
                            } catch (IOException ioe) {
475
                                LOG.log(
481
                                LOG.log(
476
                                        Level.WARNING,
482
                                        Level.WARNING,
Lines 625-631 Link Here
625
                                props.setProperty(COS_CUSTOM, getUpdatedFileSetProperty());
631
                                props.setProperty(COS_CUSTOM, getUpdatedFileSetProperty());
626
                                RUNNER.execute(()-> {
632
                                RUNNER.execute(()-> {
627
                                    try {
633
                                    try {
628
                                        final ExecutorTask task = ActionUtils.runTarget(
634
                                        final ExecutorTask task = runTargetInDedicatedTab(
635
                                                NbBundle.getMessage(J2SEActionProvider.class, "LBL_CompileOnSaveUpdate"),
629
                                                cosScript,
636
                                                cosScript,
630
                                                new String[] {TARGET},
637
                                                new String[] {TARGET},
631
                                                props,
638
                                                props,
Lines 764-769 Link Here
764
            }
771
            }
765
        }
772
        }
766
773
774
        @NonNull
775
        private static ExecutorTask runTargetInDedicatedTab(
776
                @NullAllowed final String tabName,
777
                @NonNull final FileObject buildXml,
778
                @NullAllowed final String[] targetNames,
779
                @NullAllowed final Properties properties,
780
                @NullAllowed final Set<String> concealedProperties) throws IOException, IllegalArgumentException {
781
            Parameters.notNull("buildXml", buildXml);   //NOI18N
782
            if (targetNames != null && targetNames.length == 0) {
783
                throw new IllegalArgumentException("No targets supplied"); // NOI18N
784
            }
785
            final AntProjectCookie apc = AntScriptUtils.antProjectCookieFor(buildXml);
786
            final AntTargetExecutor.Env execenv = new AntTargetExecutor.Env();
787
            if (properties != null) {
788
                Properties p = execenv.getProperties();
789
                p.putAll(properties);
790
                execenv.setProperties(p);
791
            }
792
            if (concealedProperties != null) {
793
                execenv.setConcealedProperties(concealedProperties);
794
            }
795
            execenv.setSaveAllDocuments(false);
796
            execenv.setPreferredName(tabName);
797
            final Predicate<String> p = (s) -> tabName == null ?
798
                    true :
799
                    tabName.equals(s);
800
            execenv.setTabReplaceStrategy(p, p);
801
            return AntTargetExecutor.createTargetExecutor(execenv)
802
                    .execute(apc, targetNames);
803
        }
804
767
        @CheckForNull
805
        @CheckForNull
768
        private static String createIncludes(
806
        private static String createIncludes(
769
                @NonNull final File root,
807
                @NonNull final File root,
(-)a/o.apache.tools.ant.module/apichanges.xml (+17 lines)
Lines 110-115 Link Here
110
110
111
    <changes>
111
    <changes>
112
112
113
        <change id="tabReplacePolicy">
114
            <api name="general"/>
115
            <summary>Added methods to override the default tab replacement policy into the <code>AntTargetExecutor.Env</code></summary>
116
            <version major="3" minor="84"/>
117
            <date year="2017" month="4" day="27"/>
118
            <author login="tzezula"/>
119
            <compatibility addition="yes"/>
120
            <description>
121
                <p>
122
                    When the IDE is set to the automatic close tabs mode the tabs created by the previous
123
                    run of the <code>AntTargetExecutor</code> are closed by successive run.
124
                    Added a support to override this behavior.
125
                </p>
126
            </description>
127
            <class package="org.apache.tools.ant.module.api" name="AntTargetExecutor"/>
128
        </change>
129
113
        <change id="setConcealedProperties">
130
        <change id="setConcealedProperties">
114
            <api name="general"/>
131
            <api name="general"/>
115
            <summary>Added <code>AntTargetExecutor.Env.setConcealedProperties</code></summary>
132
            <summary>Added <code>AntTargetExecutor.Env.setConcealedProperties</code></summary>
(-)a/o.apache.tools.ant.module/nbproject/project.properties (-2 / +2 lines)
Lines 41-48 Link Here
41
# made subject to such option by the copyright holder.
41
# made subject to such option by the copyright holder.
42
42
43
javac.compilerargs=-Xlint:unchecked
43
javac.compilerargs=-Xlint:unchecked
44
javac.source=1.7
44
javac.source=1.8
45
spec.version.base=3.83.0
45
spec.version.base=3.84.0
46
compile.ant.jar=${ant.core.lib}
46
compile.ant.jar=${ant.core.lib}
47
compile.ant-launcher.jar=${ant.core.lib}/../ant-launcher.jar
47
compile.ant-launcher.jar=${ant.core.lib}/../ant-launcher.jar
48
src-bridge.cp.extra=build/classes:${compile.ant.jar}:${compile.ant-launcher.jar}
48
src-bridge.cp.extra=build/classes:${compile.ant.jar}:${compile.ant-launcher.jar}
(-)a/o.apache.tools.ant.module/src/org/apache/tools/ant/module/api/AntTargetExecutor.java (-1 / +52 lines)
Lines 50-58 Link Here
50
import java.util.HashSet;
50
import java.util.HashSet;
51
import java.util.Properties;
51
import java.util.Properties;
52
import java.util.Set;
52
import java.util.Set;
53
import java.util.function.Predicate;
53
import org.apache.tools.ant.module.AntSettings;
54
import org.apache.tools.ant.module.AntSettings;
54
import org.apache.tools.ant.module.run.TargetExecutor;
55
import org.apache.tools.ant.module.run.TargetExecutor;
55
import org.netbeans.api.annotations.common.NonNull;
56
import org.netbeans.api.annotations.common.NonNull;
57
import org.netbeans.api.annotations.common.NullAllowed;
56
import org.openide.execution.ExecutorTask;
58
import org.openide.execution.ExecutorTask;
57
import org.openide.util.NbCollections;
59
import org.openide.util.NbCollections;
58
import org.openide.util.Parameters;
60
import org.openide.util.Parameters;
Lines 108-113 Link Here
108
        te.setVerbosity(env.getVerbosity());
110
        te.setVerbosity(env.getVerbosity());
109
        te.setProperties(NbCollections.checkedMapByCopy(env.getProperties(), String.class, String.class, true));
111
        te.setProperties(NbCollections.checkedMapByCopy(env.getProperties(), String.class, String.class, true));
110
        te.setConcealedProperties(env.getConcealedProperties());
112
        te.setConcealedProperties(env.getConcealedProperties());
113
        if (env.shouldSaveAllDocs != null) {
114
            te.setSaveAllDocuments(env.shouldSaveAllDocs);
115
        }
116
        te.setDisplayName(env.preferredName);
117
        if (env.canReplace != null) {
118
            assert env.canBeReplaced != null;
119
            te.setTabReplaceStrategy(env.canReplace,env.canBeReplaced);
120
        }
111
        if (env.getLogger() == null) {
121
        if (env.getLogger() == null) {
112
            return te.execute();
122
            return te.execute();
113
        } else {
123
        } else {
Lines 125-130 Link Here
125
        private Properties properties;
135
        private Properties properties;
126
        private OutputStream outputStream;
136
        private OutputStream outputStream;
127
        private volatile Set<String> concealedProperties;
137
        private volatile Set<String> concealedProperties;
138
        private Boolean shouldSaveAllDocs;
139
        private String preferredName;
140
        private Predicate<String> canReplace;
141
        private Predicate<String> canBeReplaced;
128
142
129
        /** Create instance of Env class describing environment for Ant target execution.
143
        /** Create instance of Env class describing environment for Ant target execution.
130
         */
144
         */
Lines 207-212 Link Here
207
        public Set<String> getConcealedProperties() {
221
        public Set<String> getConcealedProperties() {
208
            return concealedProperties;
222
            return concealedProperties;
209
        }
223
        }
224
225
        /**
226
         * Overrides the default save all behavior.
227
         * @param shouldSave if true all modified documents are saved before running Ant.
228
         * @since 3.84
229
         */
230
        public void setSaveAllDocuments(final boolean shouldSave) {
231
            this.shouldSaveAllDocs = shouldSave;
232
        }
233
234
        /**
235
         * Sets the preferred name for output windows.
236
         * @param name the preferred name in case of null the name is assigned automatically
237
         * @since 3.84
238
         */
239
        public void setPreferredName(@NullAllowed final String name) {
240
            this.preferredName = name;
241
        }
242
243
        /**
244
         * Sets the output tab replacement strategy.
245
         * When the IDE is set to the automatic close tabs mode the tabs created by the previous
246
         * run of the {@link AntTargetExecutor} are closed by successive run. This behavior can be overridden
247
         * by this method.
248
         * @param canReplace the {@link Predicate} used to decide if this execution
249
         * can replace existing tab. The predicate parameter is a name of tab being replaced.
250
         * @param canBeReplaced the {@link Predicate} used to decide if tab can be
251
         * replaced by a new execution. The predicate parameter is a name of a tab being created.
252
         * @since 3.84
253
         */
254
        public void setTabReplaceStrategy(
255
                @NonNull final Predicate<String> canReplace,
256
            @NonNull final Predicate<String> canBeReplaced) {
257
            Parameters.notNull("canReplace", canReplace);   //NOI18N
258
            Parameters.notNull("canBeReplaced", canBeReplaced); //NOI18N
259
            this.canReplace = canReplace;
260
            this.canBeReplaced = canBeReplaced;
261
        }
210
    }
262
    }
211
    
212
}
263
}
(-)a/o.apache.tools.ant.module/src/org/apache/tools/ant/module/run/TargetExecutor.java (-9 / +31 lines)
Lines 61-66 Link Here
61
import java.util.WeakHashMap;
61
import java.util.WeakHashMap;
62
import java.util.concurrent.atomic.AtomicBoolean;
62
import java.util.concurrent.atomic.AtomicBoolean;
63
import java.util.concurrent.atomic.AtomicReference;
63
import java.util.concurrent.atomic.AtomicReference;
64
import java.util.function.Predicate;
64
import java.util.logging.Level;
65
import java.util.logging.Level;
65
import java.util.logging.Logger;
66
import java.util.logging.Logger;
66
import javax.swing.AbstractAction;
67
import javax.swing.AbstractAction;
Lines 91-96 Link Here
91
import org.openide.util.Cancellable;
92
import org.openide.util.Cancellable;
92
import org.openide.util.Mutex;
93
import org.openide.util.Mutex;
93
import org.openide.util.NbBundle;
94
import org.openide.util.NbBundle;
95
import org.openide.util.Pair;
94
import org.openide.util.Parameters;
96
import org.openide.util.Parameters;
95
import org.openide.util.RequestProcessor;
97
import org.openide.util.RequestProcessor;
96
import org.openide.util.io.ReaderInputStream;
98
import org.openide.util.io.ReaderInputStream;
Lines 112-118 Link Here
112
     * Map from tab to tab display name.
114
     * Map from tab to tab display name.
113
     * @see "#43001"
115
     * @see "#43001"
114
     */
116
     */
115
    private static final Map<InputOutput,String> freeTabs = new WeakHashMap<InputOutput,String>();
117
    private static final Map<InputOutput,Pair<String,Predicate<String>>> freeTabs = new WeakHashMap<>();
116
    
118
    
117
    /**
119
    /**
118
     * Display names of currently active processes.
120
     * Display names of currently active processes.
Lines 129-134 Link Here
129
    /** used for the tab etc. */
131
    /** used for the tab etc. */
130
    private String displayName;
132
    private String displayName;
131
    private String suggestedDisplayName;
133
    private String suggestedDisplayName;
134
    private Boolean shouldSaveAllDocs;
135
    private Predicate<String> canBeReplaced = (s) -> true;
136
    private Predicate<String> canReplace = (s) -> true;
132
    private volatile Set<String> concealedProperties;
137
    private volatile Set<String> concealedProperties;
133
138
134
    /** targets may be null to indicate default target */
139
    /** targets may be null to indicate default target */
Lines 151-158 Link Here
151
        this.concealedProperties = Collections.unmodifiableSet(new HashSet<String>(concealedProperties));
156
        this.concealedProperties = Collections.unmodifiableSet(new HashSet<String>(concealedProperties));
152
    }
157
    }
153
158
154
    void setDisplayName(String n) {
159
    public void setSaveAllDocuments(boolean shouldSaveAllDocs) {
155
        suggestedDisplayName = n;
160
        this.shouldSaveAllDocs = shouldSaveAllDocs;
161
    }
162
163
    public void setDisplayName(String n) {
164
        this.suggestedDisplayName = n;
165
    }
166
167
    public void setTabReplaceStrategy(
168
            @NonNull final Predicate<String> canReplace,
169
            @NonNull final Predicate<String> canBeReplaced) {
170
        Parameters.notNull("canReplace", canReplace);   //NOI18N
171
        Parameters.notNull("canBeReplaced", canBeReplaced); //NOI18N
172
        this.canReplace = canReplace;
173
        this.canBeReplaced = canBeReplaced;
156
    }
174
    }
157
    
175
    
158
    private static String getProcessDisplayName(AntProjectCookie pcookie, List<String> targetNames) {
176
    private static String getProcessDisplayName(AntProjectCookie pcookie, List<String> targetNames) {
Lines 364-386 Link Here
364
            // OutputWindow
382
            // OutputWindow
365
            if (AntSettings.getAutoCloseTabs()) { // #47753
383
            if (AntSettings.getAutoCloseTabs()) { // #47753
366
            synchronized (freeTabs) {
384
            synchronized (freeTabs) {
367
                for (Map.Entry<InputOutput,String> entry : freeTabs.entrySet()) {
385
                final Set<InputOutput> retained = new HashSet<>();
386
                for (Map.Entry<InputOutput,Pair<String,Predicate<String>>> entry : freeTabs.entrySet()) {
368
                    InputOutput free = entry.getKey();
387
                    InputOutput free = entry.getKey();
369
                    String freeName = entry.getValue();
388
                    String freeName = entry.getValue().first();
389
                    Predicate<String> freePredicate = entry.getValue().second();
370
                    if (io == null && freeName.equals(displayName)) {
390
                    if (io == null && freeName.equals(displayName)) {
371
                        // Reuse it.
391
                        // Reuse it.
372
                        io = free;
392
                        io = free;
373
                        io.getOut().reset();
393
                        io.getOut().reset();
374
                        // Apparently useless and just prints warning: io.getErr().reset();
394
                        // Apparently useless and just prints warning: io.getErr().reset();
375
                        // useless: io.flushReader();
395
                        // useless: io.flushReader();
376
                    } else {
396
                    } else if (canReplace.test(freeName) && freePredicate.test(displayName)) {
377
                        // Discard it.
397
                        // Discard it.
378
                        free.closeInputOutput();
398
                        free.closeInputOutput();
379
                        stopActions.remove(free);
399
                        stopActions.remove(free);
380
                        rerunActions.remove(free);
400
                        rerunActions.remove(free);
401
                    } else {
402
                        retained.add(free);
381
                    }
403
                    }
382
                }
404
                }
383
                freeTabs.clear();
405
                freeTabs.keySet().retainAll(retained);
384
            }
406
            }
385
            }
407
            }
386
            if (io == null) {
408
            if (io == null) {
Lines 466-472 Link Here
466
            }
488
            }
467
        }
489
        }
468
        
490
        
469
        if (AntSettings.getSaveAll()) {
491
        if (shouldSaveAllDocs != null ? shouldSaveAllDocs : AntSettings.getSaveAll()) {
470
            LifecycleManager.getDefault ().saveAll ();
492
            LifecycleManager.getDefault ().saveAll ();
471
        }
493
        }
472
        
494
        
Lines 557-563 Link Here
557
        } finally {
579
        } finally {
558
            if (io != null) {
580
            if (io != null) {
559
                synchronized (freeTabs) {
581
                synchronized (freeTabs) {
560
                    freeTabs.put(io, displayName);
582
                    freeTabs.put(io, Pair.of(displayName,canBeReplaced));
561
                }
583
                }
562
            }
584
            }
563
            if (thisExec[0] != null) {
585
            if (thisExec[0] != null) {

Return to bug 270506