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

(-)a/java.j2seproject/src/org/netbeans/modules/java/j2seproject/J2SEProject.java (-1 / +6 lines)
Lines 663-669 Link Here
663
                    }
663
                    }
664
                    J2SELogicalViewProvider physicalViewProvider = getLookup().lookup(J2SELogicalViewProvider.class);
664
                    J2SELogicalViewProvider physicalViewProvider = getLookup().lookup(J2SELogicalViewProvider.class);
665
                    if (physicalViewProvider != null &&  physicalViewProvider.hasBrokenLinks()) {
665
                    if (physicalViewProvider != null &&  physicalViewProvider.hasBrokenLinks()) {
666
                        BrokenReferencesSupport.showAlert();
666
                        BrokenReferencesSupport.showAlert(
667
                                helper,
668
                                refHelper,
669
                                eval,
670
                                physicalViewProvider.getBreakableProperties(),
671
                                physicalViewProvider.getPlatformProperties());
667
                    }
672
                    }
668
                }
673
                }
669
            });
674
            });
(-)a/java.j2seproject/src/org/netbeans/modules/java/j2seproject/ui/J2SELogicalViewProvider.java (-2 / +6 lines)
Lines 261-267 Link Here
261
         return !J2SEProjectUtil.isCompileOnSaveEnabled(project) && J2SEProjectUtil.isCompileOnSaveSupported(project);
261
         return !J2SEProjectUtil.isCompileOnSaveEnabled(project) && J2SEProjectUtil.isCompileOnSaveSupported(project);
262
    }
262
    }
263
    
263
    
264
    private String[] getBreakableProperties() {
264
    public String[] getBreakableProperties() {
265
        SourceRoots roots = this.project.getSourceRoots();
265
        SourceRoots roots = this.project.getSourceRoots();
266
        String[] srcRootProps = roots.getRootProperties();
266
        String[] srcRootProps = roots.getRootProperties();
267
        roots = this.project.getTestSourceRoots();
267
        roots = this.project.getTestSourceRoots();
Lines 272-277 Link Here
272
        System.arraycopy(testRootProps, 0, result, BREAKABLE_PROPERTIES.length + srcRootProps.length, testRootProps.length);
272
        System.arraycopy(testRootProps, 0, result, BREAKABLE_PROPERTIES.length + srcRootProps.length, testRootProps.length);
273
        return result;
273
        return result;
274
    }
274
    }
275
276
    public String[] getPlatformProperties() {
277
        return new String[] {J2SEProjectProperties.JAVA_PLATFORM};
278
    }
275
    
279
    
276
    private static Image brokenProjectBadge = ImageUtilities.loadImage("org/netbeans/modules/java/j2seproject/ui/resources/brokenProjectBadge.gif", true);
280
    private static Image brokenProjectBadge = ImageUtilities.loadImage("org/netbeans/modules/java/j2seproject/ui/resources/brokenProjectBadge.gif", true);
277
    private static final String COMPILE_ON_SAVE_DISABLED_BADGE_PATH = "org/netbeans/modules/java/j2seproject/ui/resources/compileOnSaveDisabledBadge.gif";
281
    private static final String COMPILE_ON_SAVE_DISABLED_BADGE_PATH = "org/netbeans/modules/java/j2seproject/ui/resources/compileOnSaveDisabledBadge.gif";
Lines 456-462 Link Here
456
        public void actionPerformed(ActionEvent e) {
460
        public void actionPerformed(ActionEvent e) {
457
            try {
461
            try {
458
                helper.requestUpdate();
462
                helper.requestUpdate();
459
                BrokenReferencesSupport.showCustomizer(helper.getAntProjectHelper(), resolver, getBreakableProperties(), new String[] {J2SEProjectProperties.JAVA_PLATFORM});
463
                BrokenReferencesSupport.showCustomizer(helper.getAntProjectHelper(), resolver, getBreakableProperties(), getPlatformProperties());
460
                testBroken();
464
                testBroken();
461
            } catch (IOException ioe) {
465
            } catch (IOException ioe) {
462
                ErrorManager.getDefault().notify(ioe);
466
                ErrorManager.getDefault().notify(ioe);
(-)a/java.project/apichanges.xml (+16 lines)
Lines 109-114 Link Here
109
    <!-- ACTUAL CHANGES BEGIN HERE: -->
109
    <!-- ACTUAL CHANGES BEGIN HERE: -->
110
110
111
    <changes>
111
    <changes>
112
        <change id="BrokenReferencesSupport-showAlert">
113
            <api name="general"/>
114
            <summary>Added <code>showAlert</code> method into the<code>BrokenReferencesSupport</code></summary>
115
            <version major="1" minor="37"/>
116
            <date day="5" month="3" year="2011"/>
117
            <author login="tzezula"/>
118
            <compatibility addition="yes"/>
119
            <description>
120
                <p>
121
                    Added showAlert method having project context allowing the broken references alert to do
122
                    the broken references resolution.
123
                </p>
124
            </description>
125
            <class package="org.netbeans.spi.java.project.support.ui" name="BrokenReferencesSupport"/>
126
            <issue number="195249"/>
127
        </change>
112
        <change id="LibraryDefiner">
128
        <change id="LibraryDefiner">
113
            <api name="general"/>
129
            <api name="general"/>
114
            <summary>Added <code>LibraryDefiner</code></summary>
130
            <summary>Added <code>LibraryDefiner</code></summary>
(-)a/java.project/manifest.mf (-1 / +1 lines)
Lines 3-9 Link Here
3
OpenIDE-Module-Layer: org/netbeans/modules/java/project/layer.xml
3
OpenIDE-Module-Layer: org/netbeans/modules/java/project/layer.xml
4
OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/java/project/Bundle.properties
4
OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/java/project/Bundle.properties
5
OpenIDE-Module-Needs: javax.script.ScriptEngine.freemarker
5
OpenIDE-Module-Needs: javax.script.ScriptEngine.freemarker
6
OpenIDE-Module-Specification-Version: 1.36
6
OpenIDE-Module-Specification-Version: 1.37
7
OpenIDE-Module-Recommends: org.netbeans.spi.java.project.runner.JavaRunnerImplementation
7
OpenIDE-Module-Recommends: org.netbeans.spi.java.project.runner.JavaRunnerImplementation
8
AutoUpdate-Show-In-Client: false
8
AutoUpdate-Show-In-Client: false
9
9
(-)a/java.project/src/org/netbeans/modules/java/project/BrokenReferencesCustomizer.java (-2 / +13 lines)
Lines 58-63 Link Here
58
58
59
import org.netbeans.api.java.platform.PlatformsCustomizer;
59
import org.netbeans.api.java.platform.PlatformsCustomizer;
60
import org.netbeans.api.project.libraries.LibrariesCustomizer;
60
import org.netbeans.api.project.libraries.LibrariesCustomizer;
61
import org.netbeans.api.project.libraries.LibraryManager;
61
import org.netbeans.spi.project.support.ant.ui.VariablesSupport;
62
import org.netbeans.spi.project.support.ant.ui.VariablesSupport;
62
import org.netbeans.spi.project.ui.support.ProjectChooser;
63
import org.netbeans.spi.project.ui.support.ProjectChooser;
63
import org.openide.util.ImageUtilities;
64
import org.openide.util.ImageUtilities;
Lines 193-199 Link Here
193
            or.getType() == BrokenReferencesModel.RefType.LIBRARY_CONTENT) {
194
            or.getType() == BrokenReferencesModel.RefType.LIBRARY_CONTENT) {
194
            fix.setEnabled(false);
195
            fix.setEnabled(false);
195
            try {
196
            try {
196
                LibrariesCustomizer.showCustomizer(null, model.getProjectLibraryManager());
197
                final LibraryManager lm = model.getProjectLibraryManager(or);
198
                if (lm == null) {
199
                    //Closed and freed project
200
                    return;
201
                }
202
                LibrariesCustomizer.showCustomizer(null,lm);
197
            } finally {
203
            } finally {
198
                fix.setEnabled(true);
204
                fix.setEnabled(true);
199
            }
205
            }
Lines 213-219 Link Here
213
                    } catch (Exception x) {
219
                    } catch (Exception x) {
214
                        LOG.log(Level.INFO, null, x);
220
                        LOG.log(Level.INFO, null, x);
215
                        // fallback: user may need to create library manually
221
                        // fallback: user may need to create library manually
216
                        LibrariesCustomizer.showCustomizer(null, model.getProjectLibraryManager());
222
                        final LibraryManager lm = model.getProjectLibraryManager(or);
223
                        if (lm == null) {
224
                            //Closed and freed project
225
                            return;
226
                        }
227
                        LibrariesCustomizer.showCustomizer(null, lm);
217
                    } finally {
228
                    } finally {
218
                        SwingUtilities.invokeLater(new Runnable() {
229
                        SwingUtilities.invokeLater(new Runnable() {
219
                            @Override
230
                            @Override
(-)a/java.project/src/org/netbeans/modules/java/project/BrokenReferencesModel.java (-32 / +163 lines)
Lines 46-56 Link Here
46
46
47
import java.io.File;
47
import java.io.File;
48
import java.io.IOException;
48
import java.io.IOException;
49
import java.lang.ref.Reference;
50
import java.lang.ref.WeakReference;
49
import java.net.URI;
51
import java.net.URI;
50
import java.net.URL;
52
import java.net.URL;
51
import java.util.ArrayList;
53
import java.util.ArrayList;
54
import java.util.Arrays;
55
import java.util.Collections;
52
import java.util.HashSet;
56
import java.util.HashSet;
53
import java.util.LinkedHashSet;
57
import java.util.LinkedHashSet;
58
import java.util.LinkedList;
54
import java.util.List;
59
import java.util.List;
55
import java.util.Map;
60
import java.util.Map;
56
import java.util.Set;
61
import java.util.Set;
Lines 60-67 Link Here
60
import java.util.regex.Matcher;
65
import java.util.regex.Matcher;
61
import java.util.regex.Pattern;
66
import java.util.regex.Pattern;
62
import javax.swing.AbstractListModel;
67
import javax.swing.AbstractListModel;
68
import javax.swing.event.ChangeEvent;
69
import javax.swing.event.ChangeListener;
70
import org.netbeans.api.annotations.common.NonNull;
63
import org.netbeans.api.java.platform.JavaPlatform;
71
import org.netbeans.api.java.platform.JavaPlatform;
64
import org.netbeans.api.java.platform.JavaPlatformManager;
72
import org.netbeans.api.java.platform.JavaPlatformManager;
73
import org.netbeans.api.project.FileOwnerQuery;
65
import org.netbeans.api.project.Project;
74
import org.netbeans.api.project.Project;
66
import org.netbeans.api.project.ProjectManager;
75
import org.netbeans.api.project.ProjectManager;
67
import org.netbeans.api.project.libraries.Library;
76
import org.netbeans.api.project.libraries.Library;
Lines 74-79 Link Here
74
import org.netbeans.spi.project.support.ant.PropertyUtils;
83
import org.netbeans.spi.project.support.ant.PropertyUtils;
75
import org.netbeans.spi.project.support.ant.ReferenceHelper;
84
import org.netbeans.spi.project.support.ant.ReferenceHelper;
76
import org.openide.filesystems.FileObject;
85
import org.openide.filesystems.FileObject;
86
import org.openide.util.ChangeSupport;
77
import org.openide.util.Exceptions;
87
import org.openide.util.Exceptions;
78
import org.openide.util.Lookup;
88
import org.openide.util.Lookup;
79
import static org.netbeans.modules.java.project.Bundle.*;
89
import static org.netbeans.modules.java.project.Bundle.*;
Lines 83-110 Link Here
83
93
84
    private static final Logger LOG = Logger.getLogger(BrokenReferencesModel.class.getName());
94
    private static final Logger LOG = Logger.getLogger(BrokenReferencesModel.class.getName());
85
95
86
    private String[] props;
96
    final Context ctx;
87
    private String[] platformsProps;
88
    private AntProjectHelper helper;
89
    private ReferenceHelper resolver;
90
    private List<OneReference> references;
97
    private List<OneReference> references;
91
98
92
    public BrokenReferencesModel(AntProjectHelper helper, 
99
    public BrokenReferencesModel(AntProjectHelper helper, 
93
            ReferenceHelper resolver, String[] props, String[] platformsProps) {
100
            ReferenceHelper resolver, String[] props, String[] platformsProps) {
94
        this.props = props.clone();
101
        this(new Context(new BrokenProject(helper, resolver, helper.getStandardPropertyEvaluator(), props, platformsProps)));
95
        this.platformsProps = platformsProps.clone();
102
    }
96
        this.resolver = resolver;
103
97
        this.helper = helper;
104
    public BrokenReferencesModel(final @NonNull Context ctx) {
105
        assert ctx != null;
106
        this.ctx = ctx;
98
        references = new ArrayList<OneReference>();
107
        references = new ArrayList<OneReference>();
99
        refresh();
108
        refresh();
109
        ctx.addChangeListener(new ChangeListener() {
110
            @Override
111
            public void stateChanged(ChangeEvent e) {
112
                refresh();
113
            }
114
        });
100
    }
115
    }
101
116
102
    public void refresh() {
117
    public void refresh() {
103
        Set<OneReference> all = new LinkedHashSet<OneReference>();
118
        Set<OneReference> all = new LinkedHashSet<OneReference>();
104
        Set<OneReference> s = getReferences(helper, resolver, helper.getStandardPropertyEvaluator(), props, false);
119
        for (BrokenProject bprj : ctx.getBrokenProjects()) {
105
        all.addAll(s);
120
            Set<OneReference> s = getReferences(bprj, false);
106
        s = getPlatforms(helper.getStandardPropertyEvaluator(), platformsProps, false);
121
            all.addAll(s);
107
        all.addAll(s);
122
            s = getPlatforms(bprj, false);
123
            all.addAll(s);
124
        }
108
        updateReferencesList(references, all);
125
        updateReferencesList(references, all);
109
        this.fireContentsChanged(this, 0, getSize());
126
        this.fireContentsChanged(this, 0, getSize());
110
    }
127
    }
Lines 158-176 Link Here
158
    }
175
    }
159
176
160
    public static boolean isBroken(AntProjectHelper helper, ReferenceHelper refHelper, PropertyEvaluator evaluator, String[] props, String[] platformsProps) {
177
    public static boolean isBroken(AntProjectHelper helper, ReferenceHelper refHelper, PropertyEvaluator evaluator, String[] props, String[] platformsProps) {
161
        Set<OneReference> s = getReferences(helper, refHelper, evaluator, props, true);
178
        final BrokenProject bprj = new BrokenProject(helper, refHelper, evaluator, props, platformsProps);
179
        Set<OneReference> s = getReferences(bprj, true);
162
        if (s.size() > 0) {
180
        if (s.size() > 0) {
163
            return true;
181
            return true;
164
        }
182
        }
165
        s = getPlatforms(evaluator, platformsProps, true);
183
        s = getPlatforms(bprj, true);
166
        return s.size() > 0;
184
        return s.size() > 0;
167
    }
185
    }
168
186
169
    private static Set<OneReference> getReferences(AntProjectHelper helper, ReferenceHelper refHelper, PropertyEvaluator evaluator, String[] ps, boolean abortAfterFirstProblem) {
187
    private static Set<OneReference> getReferences(final BrokenProject bprj, final boolean abortAfterFirstProblem) {
170
        Set<OneReference> set = new LinkedHashSet<OneReference>();
188
        Set<OneReference> set = new LinkedHashSet<OneReference>();
171
        StringBuilder all = new StringBuilder();
189
        StringBuilder all = new StringBuilder();
172
        // this call waits for list of libraries to be refreshhed
190
        // this call waits for list of libraries to be refreshhed
173
        LibraryManager.getDefault().getLibraries();
191
        LibraryManager.getDefault().getLibraries();
192
        final AntProjectHelper helper = bprj.getAntProjectHelper();
193
        final PropertyEvaluator evaluator = bprj.getEvaluator();
194
        final ReferenceHelper refHelper = bprj.getReferenceHelper();
195
        if (helper == null || evaluator == null || refHelper == null) {
196
            return set;
197
        }
198
        final String[] ps = bprj.getProperties();
174
        EditableProperties ep = helper.getProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH);
199
        EditableProperties ep = helper.getProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH);
175
        for (String p : ps) {
200
        for (String p : ps) {
176
            // evaluate given property and tokenize it
201
            // evaluate given property and tokenize it
Lines 193-199 Link Here
193
                if (v.startsWith("${project.")) { // NOI18N
218
                if (v.startsWith("${project.")) { // NOI18N
194
                    // something in the form: "${project.<projID>}/dist/foo.jar"
219
                    // something in the form: "${project.<projID>}/dist/foo.jar"
195
                    String val = v.substring(2, v.indexOf('}')); // NOI18N
220
                    String val = v.substring(2, v.indexOf('}')); // NOI18N
196
                    set.add(new OneReference(RefType.PROJECT, val, true));
221
                    set.add(new OneReference(bprj, RefType.PROJECT, val, true));
197
                } else {
222
                } else {
198
                    RefType type = RefType.LIBRARY;
223
                    RefType type = RefType.LIBRARY;
199
                    if (v.startsWith("${file.reference")) { // NOI18N
224
                    if (v.startsWith("${file.reference")) { // NOI18N
Lines 202-208 Link Here
202
                        type = RefType.VARIABLE;
227
                        type = RefType.VARIABLE;
203
                    }
228
                    }
204
                    String val = v.substring(2, v.length() - 1);
229
                    String val = v.substring(2, v.length() - 1);
205
                    set.add(new OneReference(type, val, true));
230
                    set.add(new OneReference(bprj, type, val, true));
206
                }
231
                }
207
                if (abortAfterFirstProblem) {
232
                if (abortAfterFirstProblem) {
208
                    break;
233
                    break;
Lines 229-235 Link Here
229
                        if (f.exists()) {
254
                        if (f.exists()) {
230
                            continue;
255
                            continue;
231
                        }
256
                        }
232
                        set.add(new OneReference(RefType.VARIABLE_CONTENT, v, true));
257
                        set.add(new OneReference(bprj, RefType.VARIABLE_CONTENT, v, true));
233
                    }
258
                    }
234
                }
259
                }
235
            }
260
            }
Lines 260-266 Link Here
260
                if (all.indexOf(value) == -1) {
285
                if (all.indexOf(value) == -1) {
261
                    continue;
286
                    continue;
262
                }
287
                }
263
                set.add(new OneReference(RefType.PROJECT, key, true));
288
                set.add(new OneReference(bprj, RefType.PROJECT, key, true));
264
            }
289
            }
265
            else if (key.startsWith("file.reference")) {    //NOI18N
290
            else if (key.startsWith("file.reference")) {    //NOI18N
266
                File f = getFile(helper, evaluator, value);
291
                File f = getFile(helper, evaluator, value);
Lines 269-275 Link Here
269
                if (f.exists() || all.indexOf(value) == -1 || alreadyChecked) { // NOI18N
294
                if (f.exists() || all.indexOf(value) == -1 || alreadyChecked) { // NOI18N
270
                    continue;
295
                    continue;
271
                }
296
                }
272
                set.add(new OneReference(RefType.FILE, key, true));
297
                set.add(new OneReference(bprj, RefType.FILE, key, true));
273
            }
298
            }
274
        }
299
        }
275
        
300
        
Lines 292-298 Link Here
292
            Library lib = refHelper.findLibrary(libraryName);
317
            Library lib = refHelper.findLibrary(libraryName);
293
            if (lib == null) {
318
            if (lib == null) {
294
                // Should already have been caught before?
319
                // Should already have been caught before?
295
                set.add(new OneReference(RefType.LIBRARY, libraryRef, true));
320
                set.add(new OneReference(bprj, RefType.LIBRARY, libraryRef, true));
296
            }
321
            }
297
            else {
322
            else {
298
                //XXX: Should check all the volumes (sources, javadoc, ...)?
323
                //XXX: Should check all the volumes (sources, javadoc, ...)?
Lines 303-309 Link Here
303
                    }
328
                    }
304
                    FileObject fo = LibrariesSupport.resolveLibraryEntryFileObject(lib.getManager().getLocation(), uri2);
329
                    FileObject fo = LibrariesSupport.resolveLibraryEntryFileObject(lib.getManager().getLocation(), uri2);
305
                    if (null == fo && !canResolveEvaluatedUri(helper.getStandardPropertyEvaluator(), lib.getManager().getLocation(), uri2)) {
330
                    if (null == fo && !canResolveEvaluatedUri(helper.getStandardPropertyEvaluator(), lib.getManager().getLocation(), uri2)) {
306
                        set.add(new OneReference(RefType.LIBRARY_CONTENT, libraryRef, true));
331
                        set.add(new OneReference(bprj, RefType.LIBRARY_CONTENT, libraryRef, true));
307
                        break;
332
                        break;
308
                    }
333
                    }
309
                }
334
                }
Lines 344-352 Link Here
344
        }
369
        }
345
    }
370
    }
346
371
347
    private static Set<OneReference> getPlatforms(PropertyEvaluator evaluator, String[] platformsProps, boolean abortAfterFirstProblem) {
372
    private static Set<OneReference> getPlatforms(final BrokenProject bprj, boolean abortAfterFirstProblem) {
348
        Set<OneReference> set = new LinkedHashSet<OneReference>();
373
        final Set<OneReference> set = new LinkedHashSet<OneReference>();
349
        for (String pprop : platformsProps) {
374
        final PropertyEvaluator evaluator = bprj.getEvaluator();
375
        if (evaluator == null) {
376
            return set;
377
        }
378
        for (String pprop : bprj.getPlatformProperties()) {
350
            String prop = evaluator.getProperty(pprop);
379
            String prop = evaluator.getProperty(pprop);
351
            if (prop == null) {
380
            if (prop == null) {
352
                continue;
381
                continue;
Lines 360-366 Link Here
360
                    prop = evaluator.getProperty(pprop + ".description"); // NOI18N
389
                    prop = evaluator.getProperty(pprop + ".description"); // NOI18N
361
                }
390
                }
362
                
391
                
363
                set.add(new OneReference(RefType.PLATFORM, prop, true));
392
                set.add(new OneReference(bprj, RefType.PLATFORM, prop, true));
364
            }
393
            }
365
            if (set.size() > 0 && abortAfterFirstProblem) {
394
            if (set.size() > 0 && abortAfterFirstProblem) {
366
                break;
395
                break;
Lines 425-431 Link Here
425
    }
454
    }
426
    
455
    
427
    private void updateReference0(int index, File file) {
456
    private void updateReference0(int index, File file) {
428
        final String reference = getOneReference(index).ID;
457
        final OneReference ref = getOneReference(index);
458
        final String reference = ref.ID;
459
        final AntProjectHelper helper = ref.bprj.getAntProjectHelper();
460
        if (helper == null) {
461
            //Closed and freed project, ignore
462
            return;
463
        }
429
        FileObject myProjDirFO = helper.getProjectDirectory();
464
        FileObject myProjDirFO = helper.getProjectDirectory();
430
        final String propertiesFile = AntProjectHelper.PRIVATE_PROPERTIES_PATH;
465
        final String propertiesFile = AntProjectHelper.PRIVATE_PROPERTIES_PATH;
431
        final String path = file.getAbsolutePath();
466
        final String path = file.getAbsolutePath();
Lines 457-465 Link Here
457
    }
492
    }
458
    
493
    
459
    /** @return non-null library manager */
494
    /** @return non-null library manager */
460
    LibraryManager getProjectLibraryManager() {
495
    LibraryManager getProjectLibraryManager(@NonNull final OneReference or) {
461
        return resolver.getProjectLibraryManager() != null ? 
496
        assert or != null;
462
            resolver.getProjectLibraryManager() : LibraryManager.getDefault();
497
        final ReferenceHelper resolver = or.bprj.getReferenceHelper();
498
        return resolver == null ? null :
499
                resolver.getProjectLibraryManager() != null ?
500
                    resolver.getProjectLibraryManager() : LibraryManager.getDefault();
463
    }
501
    }
464
502
465
    enum RefType {
503
    enum RefType {
Lines 474-486 Link Here
474
    }
512
    }
475
513
476
    public static final class OneReference {
514
    public static final class OneReference {
477
        
515
516
        private final BrokenProject bprj;
478
        private final RefType type;
517
        private final RefType type;
479
        private boolean broken;
518
        private boolean broken;
480
        private final String ID;
519
        private final String ID;
481
        private final Callable<Library> definer;
520
        private final Callable<Library> definer;
482
521
483
        public OneReference(RefType type, String ID, boolean broken) {
522
        OneReference(
523
            @NonNull final BrokenProject bprj,
524
            @NonNull RefType type,
525
            @NonNull final String ID,
526
            final boolean broken) {
527
            assert bprj != null;
484
            Callable<Library> _definer = null;
528
            Callable<Library> _definer = null;
485
            if (type == RefType.LIBRARY) {
529
            if (type == RefType.LIBRARY) {
486
                String name = ID.substring(5, ID.length() - 10);
530
                String name = ID.substring(5, ID.length() - 10);
Lines 492-497 Link Here
492
                    }
536
                    }
493
                }
537
                }
494
            }
538
            }
539
            this.bprj = bprj;
495
            this.type = type;
540
            this.type = type;
496
            this.ID = ID;
541
            this.ID = ID;
497
            this.broken = broken;
542
            this.broken = broken;
Lines 560-564 Link Here
560
        }
605
        }
561
        
606
        
562
    }
607
    }
608
609
    public static final class BrokenProject {
610
        private final Reference<AntProjectHelper> helper;
611
        private final Reference<ReferenceHelper> referenceHelper;
612
        private final Reference<PropertyEvaluator> evaluator;
613
        private final String[] properties;
614
        private final String[] platformProperties;
615
616
        public BrokenProject(
617
            @NonNull final AntProjectHelper helper,
618
            @NonNull final ReferenceHelper referenceHelper,
619
            @NonNull final PropertyEvaluator evaluator,
620
            @NonNull final String[] properties,
621
            @NonNull final String[] platformProperties) {
622
            assert helper != null;
623
            assert referenceHelper != null;
624
            assert properties != null;
625
            assert platformProperties != null;
626
            this.helper = new WeakReference<AntProjectHelper>(helper);
627
            this.referenceHelper = new WeakReference<ReferenceHelper>(referenceHelper);
628
            this.evaluator = new WeakReference<PropertyEvaluator>(evaluator);
629
            this.properties = Arrays.copyOf(properties, properties.length);
630
            this.platformProperties = Arrays.copyOf(platformProperties, platformProperties.length);
631
        }
632
633
        AntProjectHelper getAntProjectHelper() {
634
            return helper.get();
635
        }
636
637
        ReferenceHelper getReferenceHelper() {
638
            return referenceHelper.get();
639
        }
640
641
        PropertyEvaluator getEvaluator() {            
642
            return evaluator.get();
643
        }
644
645
        String[] getProperties() {
646
            return this.properties;
647
        }
648
649
        String[] getPlatformProperties() {
650
            return this.platformProperties;
651
        }
652
    }
653
654
    public static final class Context {
655
        private final List<BrokenProject> toResolve;
656
        private final ChangeSupport support;
657
658
        public Context() {
659
            toResolve = Collections.synchronizedList(new LinkedList<BrokenProject>());
660
            support = new ChangeSupport(this);
661
        }
662
663
        private Context(final @NonNull BrokenProject broken) {
664
            this();
665
            this.offer(broken);
666
        }
667
668
        public void offer(final BrokenProject broken) {
669
            assert broken != null;
670
            this.toResolve.add(broken);
671
            support.fireChange();
672
        }
673
674
        public boolean isEmpty() {
675
            return this.toResolve.isEmpty();
676
        }
677
678
        public BrokenProject[] getBrokenProjects() {
679
            synchronized (toResolve) {
680
                return toResolve.toArray(new BrokenProject[toResolve.size()]);
681
            }
682
        }
683
684
        public void addChangeListener(final @NonNull ChangeListener listener) {
685
            assert listener != null;
686
            support.addChangeListener(listener);
687
        }
688
689
        public void removeChangeListener(final @NonNull ChangeListener listener) {
690
            assert listener != null;
691
            support.removeChangeListener(listener);
692
        }
693
    }
563
    
694
    
564
}
695
}
(-)a/java.project/src/org/netbeans/spi/java/project/support/ui/BrokenReferencesSupport.java (-71 / +133 lines)
Lines 44-57 Link Here
44
44
45
package org.netbeans.spi.java.project.support.ui;
45
package org.netbeans.spi.java.project.support.ui;
46
46
47
import javax.swing.event.ChangeEvent;
48
import javax.swing.event.ChangeListener;
47
import java.awt.Dialog;
49
import java.awt.Dialog;
48
import java.awt.Frame;
49
import java.awt.event.WindowAdapter;
50
import java.io.IOException;
50
import java.io.IOException;
51
import java.util.concurrent.Callable;
51
import java.util.concurrent.Callable;
52
import javax.swing.JButton;
52
import javax.swing.JButton;
53
import javax.swing.SwingUtilities;
54
import org.netbeans.api.annotations.common.CheckForNull;
53
import org.netbeans.api.annotations.common.CheckForNull;
54
import org.netbeans.api.annotations.common.NonNull;
55
import org.netbeans.api.annotations.common.NullAllowed;
55
import org.netbeans.api.project.Project;
56
import org.netbeans.api.project.Project;
56
import org.netbeans.api.project.ProjectManager;
57
import org.netbeans.api.project.ProjectManager;
57
import org.netbeans.api.project.ProjectUtils;
58
import org.netbeans.api.project.ProjectUtils;
Lines 61-72 Link Here
61
import org.netbeans.modules.java.project.BrokenReferencesModel;
62
import org.netbeans.modules.java.project.BrokenReferencesModel;
62
import org.netbeans.modules.java.project.JavaProjectSettings;
63
import org.netbeans.modules.java.project.JavaProjectSettings;
63
import org.netbeans.spi.project.support.ant.AntProjectHelper;
64
import org.netbeans.spi.project.support.ant.AntProjectHelper;
65
import org.netbeans.spi.project.support.ant.PropertyEvaluator;
64
import org.netbeans.spi.project.support.ant.ReferenceHelper;
66
import org.netbeans.spi.project.support.ant.ReferenceHelper;
65
import org.openide.DialogDescriptor;
67
import org.openide.DialogDescriptor;
66
import org.openide.DialogDisplayer;
68
import org.openide.DialogDisplayer;
67
import org.openide.util.Exceptions;
69
import org.openide.util.Exceptions;
68
import org.openide.util.NbBundle.Messages;
70
import org.openide.util.NbBundle.Messages;
69
import org.openide.util.Parameters;
71
import org.openide.util.Parameters;
72
import org.openide.util.RequestProcessor;
70
import org.openide.util.lookup.ServiceProvider;
73
import org.openide.util.lookup.ServiceProvider;
71
import org.openide.windows.WindowManager;
74
import org.openide.windows.WindowManager;
72
import static org.netbeans.spi.java.project.support.ui.Bundle.*;
75
import static org.netbeans.spi.java.project.support.ui.Bundle.*;
Lines 87-97 Link Here
87
 */
90
 */
88
public class BrokenReferencesSupport {
91
public class BrokenReferencesSupport {
89
92
90
    /** Last time in ms when the Broken References alert was shown. */
93
    private static final RequestProcessor RP = new RequestProcessor(BrokenReferencesSupport.class);
91
    private static long brokenAlertLastTime = 0;
92
    
94
    
93
    /** Is Broken References alert shown now? */
95
    /** Is Broken References alert shown now? */
94
    private static boolean brokenAlertShown = false;
96
    private static BrokenReferencesModel.Context context;
97
98
    private static RequestProcessor.Task rpTask;
95
99
96
    /** Timeout within which request to show alert will be ignored. */
100
    /** Timeout within which request to show alert will be ignored. */
97
    private static int BROKEN_ALERT_TIMEOUT = 1000;
101
    private static int BROKEN_ALERT_TIMEOUT = 1000;
Lines 180-261 Link Here
180
     * once for several subsequent calls during a timeout.
184
     * once for several subsequent calls during a timeout.
181
     * The alert box has also "show this warning again" check box.
185
     * The alert box has also "show this warning again" check box.
182
     */
186
     */
187
    public static void showAlert() {
188
        showAlertImpl(null);
189
    }
190
191
    /**
192
     * Show alert message box informing user that a project has broken
193
     * references. This method can be safely called from any thread, e.g. during
194
     * the project opening, and it will take care about showing message box only
195
     * once for several subsequent calls during a timeout.
196
     * The alert box has also "show this warning again" check box and provides resolve
197
     * broken references option
198
     * @param projectHelper the {@link AntProjectHelper} used to resolve broken references
199
     * @param referenceHelper the {@link ReferenceHelper} used to resolve broken references
200
     * @param evaluator the {@link PropertyEvaluator} used to resolve broken references
201
     * @param properties array of property names which values hold
202
     *    references which may be broken. For example for J2SE project
203
     *    the property names will be: "javac.classpath", "run.classpath", etc.
204
     * @param platformProperties array of property names which values hold
205
     *    name of the platform(s) used by the project. These platforms will be
206
     *    checked for existence. For example for J2SE project the property
207
     *    name is one and it is "platform.active". The name of the default
208
     *    platform is expected to be "default_platform" and this platform
209
     *    always exists.
210
     * @since 1.37
211
     */
212
    
213
    public static void showAlert(
214
            @NonNull final AntProjectHelper projectHelper,
215
            @NonNull final ReferenceHelper referenceHelper,
216
            @NonNull final PropertyEvaluator evaluator,
217
            @NonNull final String[] properties,
218
            @NonNull final String[] platformProperties) {
219
        Parameters.notNull("projectHelper", projectHelper);             //NOI18N
220
        Parameters.notNull("referenceHelper", referenceHelper);         //NOI18N
221
        Parameters.notNull("evaluator", evaluator);                     //NOI18N
222
        Parameters.notNull("properties", properties);                   //NOI18N
223
        Parameters.notNull("platformProperties", platformProperties);   //NOI18N
224
        showAlertImpl(new BrokenReferencesModel.BrokenProject(projectHelper, referenceHelper, evaluator, properties, platformProperties));
225
    }
226
227
183
    @Messages({
228
    @Messages({
229
        "CTL_Broken_References_Resolve=Resolve",
230
        "AD_Broken_References_Resolve=N/A",
184
        "CTL_Broken_References_Close=Close",
231
        "CTL_Broken_References_Close=Close",
185
        "AD_Broken_References_Close=N/A",
232
        "AD_Broken_References_Close=N/A",
186
        "MSG_Broken_References_Title=Open Project"
233
        "MSG_Broken_References_Title=Open Project",
234
        "LBL_Broken_References_Resolve_Panel_Close=Close",
235
        "AD_Broken_References_Resolve_Panel_Close=N/A",
236
        "LBL_Broken_References_Resolve_Panel_Title=Broken References"
187
    })
237
    })
188
    public static synchronized void showAlert() {
238
    private static synchronized void showAlertImpl(@NullAllowed final BrokenReferencesModel.BrokenProject broken) {        
189
        // Do not show alert if it is already shown or if it was shown
239
        if (!JavaProjectSettings.isShowAgainBrokenRefAlert()) {
190
        // in last BROKEN_ALERT_TIMEOUT milliseconds or if user do not wish it.
191
        if (brokenAlertShown || 
192
                brokenAlertLastTime+BROKEN_ALERT_TIMEOUT > System.currentTimeMillis() ||
193
                !JavaProjectSettings.isShowAgainBrokenRefAlert()) {
194
            return;
240
            return;
195
        }
241
        } else if (context == null) {
196
        brokenAlertShown = true;
242
            assert rpTask == null;
197
        final Runnable task = new Runnable() {
243
198
            public @Override void run() {
244
            final Runnable task = new Runnable() {
199
                try {
245
                public @Override void run() {
200
                    JButton closeOption = new JButton (CTL_Broken_References_Close());
201
                    closeOption.getAccessibleContext().setAccessibleDescription(AD_Broken_References_Close());
202
                    DialogDescriptor dd = new DialogDescriptor(new BrokenReferencesAlertPanel(),
203
                        MSG_Broken_References_Title(),
204
                        true,
205
                        new Object[] {closeOption},
206
                        closeOption,
207
                        DialogDescriptor.DEFAULT_ALIGN,
208
                        null,
209
                        null); // NOI18N
210
                    dd.setMessageType(DialogDescriptor.WARNING_MESSAGE);
211
                    Dialog dlg = DialogDisplayer.getDefault().createDialog(dd);
212
                    dlg.setVisible(true);
213
                } finally {
214
                    synchronized (BrokenReferencesSupport.class) {
246
                    synchronized (BrokenReferencesSupport.class) {
215
                        brokenAlertLastTime = System.currentTimeMillis();
247
                        rpTask = null;
216
                        brokenAlertShown = false;
248
                    }
249
                    try {
250
                        final JButton resolveOption = new JButton(CTL_Broken_References_Resolve());
251
                        resolveOption.getAccessibleContext().setAccessibleDescription(AD_Broken_References_Resolve());
252
                        JButton closeOption = new JButton (CTL_Broken_References_Close());
253
                        closeOption.getAccessibleContext().setAccessibleDescription(AD_Broken_References_Close());
254
                        DialogDescriptor dd = new DialogDescriptor(new BrokenReferencesAlertPanel(),
255
                            MSG_Broken_References_Title(),
256
                            true,
257
                            new Object[] {resolveOption, closeOption},
258
                            closeOption,
259
                            DialogDescriptor.DEFAULT_ALIGN,
260
                            null,
261
                            null);
262
                        dd.setMessageType(DialogDescriptor.WARNING_MESSAGE);
263
                        context.addChangeListener(new ChangeListener() {
264
                            @Override
265
                            public void stateChanged(ChangeEvent e) {
266
                                resolveOption.setVisible(!context.isEmpty());
267
                            }
268
                        });
269
                        resolveOption.setVisible(!context.isEmpty());
270
                        if (DialogDisplayer.getDefault().notify(dd) == resolveOption) {
271
                            final BrokenReferencesModel model = new BrokenReferencesModel(context);
272
                            final BrokenReferencesCustomizer customizer = new BrokenReferencesCustomizer(model);
273
                            JButton close = new JButton (Bundle.LBL_Broken_References_Resolve_Panel_Close());
274
                            close.getAccessibleContext ().setAccessibleDescription (Bundle.AD_Broken_References_Resolve_Panel_Close());
275
                            dd = new DialogDescriptor(customizer,
276
                                Bundle.LBL_Broken_References_Resolve_Panel_Title(),
277
                                true,
278
                                new Object[] {DialogDescriptor.CANCEL_OPTION},
279
                                DialogDescriptor.CANCEL_OPTION,
280
                                DialogDescriptor.DEFAULT_ALIGN,
281
                                null,
282
                                null);
283
                            Dialog dlg = null;
284
                            try {
285
                                dlg = DialogDisplayer.getDefault().createDialog(dd);
286
                                dlg.setVisible(true);
287
                            } finally {
288
                                if (dlg != null) {
289
                                    dlg.dispose();
290
                                }
291
                            }
292
                        }
293
                    } finally {
294
                        synchronized (BrokenReferencesSupport.class) {
295
                            //Clean seen references and start from empty list
296
                            //Is it what we good from UI point of view?
297
                            context = null;
298
                        }
217
                    }
299
                    }
218
                }
300
                }
219
            }
301
            };
220
        };
302
221
        SwingUtilities.invokeLater(new Runnable() {
303
            context = new BrokenReferencesModel.Context();
222
            @SuppressWarnings("ResultOfObjectAllocationIgnored")
304
            rpTask = RP.create(new Runnable() {
223
            public @Override void run() {
305
                @Override
224
                Frame f = WindowManager.getDefault().getMainWindow();
306
                public void run() {
225
                if (f == null || f.isShowing()) {
307
                    WindowManager.getDefault().invokeWhenUIReady(task);
226
                    task.run();
227
                }
308
                }
228
                else {
309
            });
229
                    new MainWindowListener (f,task);
230
                }
231
            }
232
        });
233
    }
234
    
235
    
236
    private static class MainWindowListener extends WindowAdapter {
237
        
238
        private Frame frame;
239
        private Runnable task;
240
        
241
        /**
242
         * Has to be called by the event thread!
243
         *
244
         */
245
        public MainWindowListener (Frame frame, Runnable task) {
246
            assert frame != null && task != null;
247
            assert SwingUtilities.isEventDispatchThread();
248
            this.frame = frame;
249
            this.task = task;
250
            frame.addWindowListener(this);
251
        }
310
        }
252
        
311
253
        public @Override void windowOpened(java.awt.event.WindowEvent e) {
312
        assert context != null;        
254
            MainWindowListener.this.frame.removeWindowListener (this);
313
        if (broken != null) {
255
            SwingUtilities.invokeLater(this.task);
314
            context.offer(broken);
256
        }
315
        }
257
    }
316
        if (rpTask != null) {
258
    
317
            //Not yet shown, move
318
            rpTask.schedule(BROKEN_ALERT_TIMEOUT);
319
        }
320
    }            
259
    /**
321
    /**
260
     * Service which may be {@linkplain ServiceProvider registered} to download remote libraries or otherwise define them.
322
     * Service which may be {@linkplain ServiceProvider registered} to download remote libraries or otherwise define them.
261
     * @since org.netbeans.modules.java.project/1 1.35
323
     * @since org.netbeans.modules.java.project/1 1.35

Return to bug 195942