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

(-)a/j2ee.clientproject/nbproject/project.xml (+9 lines)
Lines 161-166 made subject to such option by the copyr Link Here
161
                    <run-dependency>
161
                    <run-dependency>
162
                        <release-version>4</release-version>
162
                        <release-version>4</release-version>
163
                        <specification-version>1.29</specification-version>
163
                        <specification-version>1.29</specification-version>
164
                    </run-dependency>
165
                </dependency>
166
                <dependency>
167
                    <code-name-base>org.netbeans.modules.java.api.common</code-name-base>
168
                    <build-prerequisite/>
169
                    <compile-dependency/>
170
                    <run-dependency>
171
                        <release-version>0-1</release-version>
172
                        <specification-version>1.0</specification-version>
164
                    </run-dependency>
173
                    </run-dependency>
165
                </dependency>
174
                </dependency>
166
                <dependency>
175
                <dependency>
(-)a/j2ee.clientproject/src/org/netbeans/modules/j2ee/clientproject/AppClientActionProvider.java (-1 / +2 lines)
Lines 77-82 import org.netbeans.modules.j2ee.deploym Link Here
77
import org.netbeans.modules.j2ee.deployment.devmodules.spi.J2eeModuleProvider;
77
import org.netbeans.modules.j2ee.deployment.devmodules.spi.J2eeModuleProvider;
78
import org.netbeans.modules.j2ee.deployment.plugins.api.InstanceProperties;
78
import org.netbeans.modules.j2ee.deployment.plugins.api.InstanceProperties;
79
import org.netbeans.modules.j2ee.deployment.plugins.api.ServerDebugInfo;
79
import org.netbeans.modules.j2ee.deployment.plugins.api.ServerDebugInfo;
80
import org.netbeans.modules.java.api.common.ant.UpdateHelper;
80
import org.netbeans.spi.project.ActionProvider;
81
import org.netbeans.spi.project.ActionProvider;
81
import org.netbeans.spi.project.support.ant.AntProjectHelper;
82
import org.netbeans.spi.project.support.ant.AntProjectHelper;
82
import org.netbeans.spi.project.support.ant.EditableProperties;
83
import org.netbeans.spi.project.support.ant.EditableProperties;
Lines 342-348 class AppClientActionProvider implements Link Here
342
                    result=isSetMainClass(project.getSourceRoots().getRoots(), mainClass);
343
                    result=isSetMainClass(project.getSourceRoots().getRoots(), mainClass);
343
                } while (result != MainClassStatus.SET_AND_VALID);
344
                } while (result != MainClassStatus.SET_AND_VALID);
344
                try {
345
                try {
345
                    if (updateHelper.requestSave()) {
346
                    if (updateHelper.requestUpdate()) {
346
                        updateHelper.putProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH,ep);
347
                        updateHelper.putProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH,ep);
347
                        ProjectManager.getDefault().saveProject(project);
348
                        ProjectManager.getDefault().saveProject(project);
348
                    } else {
349
                    } else {
(-)a/j2ee.clientproject/src/org/netbeans/modules/j2ee/clientproject/AppClientFileBuiltQuery.java (-107 lines)
Lines 1-107 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 1997-2007 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
 * Contributor(s):
25
 *
26
 * The Original Software is NetBeans. The Initial Developer of the Original
27
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
28
 * Microsystems, Inc. All Rights Reserved.
29
 *
30
 * If you wish your version of this file to be governed by only the CDDL
31
 * or only the GPL Version 2, indicate your decision by adding
32
 * "[Contributor] elects to include this software in this distribution
33
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
34
 * single choice of license, a recipient has the option to distribute
35
 * your version of this file under either the CDDL, the GPL Version 2 or
36
 * to extend the choice of license to its licensees as provided above.
37
 * However, if you add GPL Version 2 code and therefore, elected the GPL
38
 * Version 2 license, then the option applies only if the new code is
39
 * made subject to such option by the copyright holder.
40
 */
41
package org.netbeans.modules.j2ee.clientproject;
42
43
import java.beans.PropertyChangeEvent;
44
import java.beans.PropertyChangeListener;
45
import org.openide.filesystems.FileObject;
46
import org.netbeans.api.queries.FileBuiltQuery;
47
import org.netbeans.spi.queries.FileBuiltQueryImplementation;
48
import org.netbeans.spi.project.support.ant.AntProjectHelper;
49
import org.netbeans.spi.project.support.ant.PropertyEvaluator;
50
import org.netbeans.modules.j2ee.clientproject.ui.customizer.AppClientProjectProperties;
51
52
53
54
55
56
public class AppClientFileBuiltQuery implements FileBuiltQueryImplementation, PropertyChangeListener {
57
58
    private FileBuiltQueryImplementation delegate;
59
    private final AntProjectHelper helper;
60
    private final PropertyEvaluator evaluator;
61
    private final SourceRoots sourceRoots;
62
    private final SourceRoots testRoots;
63
64
    AppClientFileBuiltQuery (AntProjectHelper helper, PropertyEvaluator evaluator,
65
                        SourceRoots sourceRoots, SourceRoots testRoots) {
66
        assert helper != null && evaluator != null && sourceRoots != null && testRoots != null;
67
        this.helper = helper;
68
        this.evaluator = evaluator;
69
        this.sourceRoots = sourceRoots;
70
        this.testRoots = testRoots;
71
        this.sourceRoots.addPropertyChangeListener (this);
72
        this.testRoots.addPropertyChangeListener (this);
73
    }
74
75
    public synchronized FileBuiltQuery.Status getStatus(FileObject file) {
76
        if (this.delegate == null) {
77
            this.delegate = createDelegate ();
78
        }
79
        return this.delegate.getStatus (file);
80
    }
81
82
83
    private FileBuiltQueryImplementation createDelegate () {
84
        String[] srcRoots = this.sourceRoots.getRootProperties();
85
        String[] tstRoots = this.testRoots.getRootProperties();
86
        String[] from = new String [srcRoots.length + tstRoots.length];
87
        String[] to = new String [srcRoots.length + tstRoots.length];
88
        for (int i=0; i< srcRoots.length; i++) {
89
            from[i] = "${" + srcRoots[i] + "}/*.java"; // NOI18N
90
            to[i] = "${" + AppClientProjectProperties.BUILD_CLASSES_DIR + "}/*.class"; // NOI18N
91
        }
92
        for (int i=0; i<tstRoots.length; i++) {
93
            from[srcRoots.length+i] = "${" + tstRoots[i] + "}/*.java"; // NOI18N
94
            to[srcRoots.length+i] = "${" + AppClientProjectProperties.BUILD_TEST_CLASSES_DIR + "}/*.class"; // NOI18N
95
        }
96
        return helper.createGlobFileBuiltQuery(evaluator, from, to);    //Safe to pass APH
97
    }
98
99
    public void propertyChange(PropertyChangeEvent evt) {
100
        if (SourceRoots.PROP_ROOT_PROPERTIES.equals (evt.getPropertyName())) {
101
            synchronized(this) {
102
                this.delegate = null;
103
                ///XXX: What to do with already returned Statuses
104
            }
105
        }
106
    }
107
}
(-)a/j2ee.clientproject/src/org/netbeans/modules/j2ee/clientproject/AppClientProject.java (-16 / +17 lines)
Lines 69-79 import org.netbeans.modules.j2ee.clientp Link Here
69
import org.netbeans.modules.j2ee.clientproject.classpath.AppClientProjectClassPathExtender;
69
import org.netbeans.modules.j2ee.clientproject.classpath.AppClientProjectClassPathExtender;
70
import org.netbeans.modules.j2ee.clientproject.classpath.ClassPathProviderImpl;
70
import org.netbeans.modules.j2ee.clientproject.classpath.ClassPathProviderImpl;
71
import org.netbeans.modules.j2ee.clientproject.classpath.ClassPathSupport;
71
import org.netbeans.modules.j2ee.clientproject.classpath.ClassPathSupport;
72
import org.netbeans.modules.j2ee.clientproject.queries.AppClientProjectEncodingQueryImpl;
73
import org.netbeans.modules.j2ee.clientproject.queries.CompiledSourceForBinaryQuery;
74
import org.netbeans.modules.j2ee.clientproject.queries.JavadocForBinaryQueryImpl;
75
import org.netbeans.modules.j2ee.clientproject.queries.SourceLevelQueryImpl;
76
import org.netbeans.modules.j2ee.clientproject.queries.UnitTestForSourceQueryImpl;
77
import org.netbeans.modules.j2ee.clientproject.ui.AppClientLogicalViewProvider;
72
import org.netbeans.modules.j2ee.clientproject.ui.AppClientLogicalViewProvider;
78
import org.netbeans.modules.j2ee.clientproject.ui.customizer.AppClientProjectProperties;
73
import org.netbeans.modules.j2ee.clientproject.ui.customizer.AppClientProjectProperties;
79
import org.netbeans.modules.j2ee.clientproject.ui.customizer.CustomizerProviderImpl;
74
import org.netbeans.modules.j2ee.clientproject.ui.customizer.CustomizerProviderImpl;
Lines 85-90 import org.netbeans.modules.j2ee.deploym Link Here
85
import org.netbeans.modules.j2ee.deployment.devmodules.api.Deployment;
80
import org.netbeans.modules.j2ee.deployment.devmodules.api.Deployment;
86
import org.netbeans.modules.j2ee.deployment.devmodules.api.J2eePlatform;
81
import org.netbeans.modules.j2ee.deployment.devmodules.api.J2eePlatform;
87
import org.netbeans.modules.j2ee.spi.ejbjar.CarFactory;
82
import org.netbeans.modules.j2ee.spi.ejbjar.CarFactory;
83
import org.netbeans.modules.java.api.common.SourceRoots;
84
import org.netbeans.modules.java.api.common.SourceRootsSupport;
85
import org.netbeans.modules.java.api.common.ant.UpdateHelper;
86
import org.netbeans.modules.java.api.common.ant.UpdateImplementation;
87
import org.netbeans.modules.java.api.common.queries.QuerySupport;
88
import org.netbeans.modules.websvc.api.client.WebServicesClientSupport;
88
import org.netbeans.modules.websvc.api.client.WebServicesClientSupport;
89
import org.netbeans.modules.websvc.api.jaxws.client.JAXWSClientSupport;
89
import org.netbeans.modules.websvc.api.jaxws.client.JAXWSClientSupport;
90
import org.netbeans.modules.websvc.api.jaxws.project.WSUtils;
90
import org.netbeans.modules.websvc.api.jaxws.project.WSUtils;
Lines 177-184 public final class AppClientProject impl Link Here
177
        refHelper = new ReferenceHelper(helper, aux, eval);
177
        refHelper = new ReferenceHelper(helper, aux, eval);
178
        buildExtender = AntBuildExtenderFactory.createAntExtender(new AppClientExtenderImplementation());
178
        buildExtender = AntBuildExtenderFactory.createAntExtender(new AppClientExtenderImplementation());
179
        genFilesHelper = new GeneratedFilesHelper(helper, buildExtender);
179
        genFilesHelper = new GeneratedFilesHelper(helper, buildExtender);
180
        this.updateHelper = new UpdateHelper(this, this.helper, this.aux, this.genFilesHelper,
180
        UpdateImplementation updateProject = new UpdateProjectImpl(this, this.helper, aux);
181
                UpdateHelper.createDefaultNotifier());
181
        this.updateHelper = new UpdateHelper(updateProject, helper);
182
        carProjectWebServicesClientSupport = new AppClientProjectWebServicesClientSupport(this, helper, refHelper);
182
        carProjectWebServicesClientSupport = new AppClientProjectWebServicesClientSupport(this, helper, refHelper);
183
        jaxWsClientSupport = new AppClientProjectJAXWSClientSupport(this, helper);
183
        jaxWsClientSupport = new AppClientProjectJAXWSClientSupport(this, helper);
184
        apiWebServicesClientSupport = WebServicesClientSupportFactory.createWebServicesClientSupport(carProjectWebServicesClientSupport);
184
        apiWebServicesClientSupport = WebServicesClientSupportFactory.createWebServicesClientSupport(carProjectWebServicesClientSupport);
Lines 255-271 public final class AppClientProject impl Link Here
255
            // new J2SECustomizerProvider(this, this.updateHelper, evaluator(), refHelper),
255
            // new J2SECustomizerProvider(this, this.updateHelper, evaluator(), refHelper),
256
            new CustomizerProviderImpl(this, this.updateHelper, evaluator(), refHelper, this.genFilesHelper),
256
            new CustomizerProviderImpl(this, this.updateHelper, evaluator(), refHelper, this.genFilesHelper),
257
            new ClassPathProviderMerger(cpProvider),
257
            new ClassPathProviderMerger(cpProvider),
258
            new CompiledSourceForBinaryQuery(this.helper, evaluator(),getSourceRoots(),getTestSourceRoots()), //Does not use APH to get/put properties/cfgdata
258
            QuerySupport.createCompiledSourceForBinaryQuery(helper, evaluator(), getSourceRoots(),getTestSourceRoots()),
259
            new JavadocForBinaryQueryImpl(this.helper, evaluator()), //Does not use APH to get/put properties/cfgdata
259
            QuerySupport.createJavadocForBinaryQuery(helper, evaluator()),
260
            new AntArtifactProviderImpl(),
260
            new AntArtifactProviderImpl(),
261
            new ProjectXmlSavedHookImpl(),
261
            new ProjectXmlSavedHookImpl(),
262
            UILookupMergerSupport.createProjectOpenHookMerger(new ProjectOpenedHookImpl()),
262
            UILookupMergerSupport.createProjectOpenHookMerger(new ProjectOpenedHookImpl()),
263
            new UnitTestForSourceQueryImpl(getSourceRoots(),getTestSourceRoots()),
263
            QuerySupport.createUnitTestForSourceQuery(getSourceRoots(),getTestSourceRoots()),
264
            new SourceLevelQueryImpl(evaluator()),
264
            QuerySupport.createSourceLevelQuery(evaluator()),
265
            new AppClientSources(this.helper, evaluator(), getSourceRoots(), getTestSourceRoots()),
265
            new AppClientSources(this.helper, evaluator(), getSourceRoots(), getTestSourceRoots()),
266
            new AppClientSharabilityQuery(this.helper, evaluator(), getSourceRoots(), getTestSourceRoots()), //Does not use APH to get/put properties/cfgdata
266
            QuerySupport.createSharabilityQuery(helper, evaluator(), getSourceRoots(), getTestSourceRoots(),
267
            new AppClientFileBuiltQuery(this.helper, evaluator(),getSourceRoots(),getTestSourceRoots()), //Does not use APH to get/put properties/cfgdata
267
                    AppClientProjectProperties.META_INF),
268
            new AppClientProjectEncodingQueryImpl(evaluator()),
268
            QuerySupport.createFileBuiltQuery(helper,  evaluator(), getSourceRoots(), getTestSourceRoots()),
269
            QuerySupport.createFileEncodingQuery(evaluator(), AppClientProjectProperties.SOURCE_ENCODING),
269
            new RecommendedTemplatesImpl(this.updateHelper),
270
            new RecommendedTemplatesImpl(this.updateHelper),
270
            classpathExtender,
271
            classpathExtender,
271
            buildExtender,
272
            buildExtender,
Lines 310-323 public final class AppClientProject impl Link Here
310
     */
311
     */
311
    public synchronized SourceRoots getSourceRoots() {
312
    public synchronized SourceRoots getSourceRoots() {
312
        if (this.sourceRoots == null) { //Local caching, no project metadata access
313
        if (this.sourceRoots == null) { //Local caching, no project metadata access
313
            this.sourceRoots = new SourceRoots(this.updateHelper, evaluator(), getReferenceHelper(), "source-roots", false, "src.{0}{1}.dir"); //NOI18N
314
            this.sourceRoots = SourceRootsSupport.create(updateHelper, evaluator(), getReferenceHelper(), AppClientProjectType.PROJECT_CONFIGURATION_NAMESPACE, "source-roots", false, "src.{0}{1}.dir"); //NOI18N
314
        }
315
        }
315
        return this.sourceRoots;
316
        return this.sourceRoots;
316
    }
317
    }
317
    public synchronized SourceRoots getTestSourceRoots() {
318
    public synchronized SourceRoots getTestSourceRoots() {
318
        if (this.testRoots == null) { //Local caching, no project metadata access
319
        if (this.testRoots == null) { //Local caching, no project metadata access
319
            this.testRoots = new SourceRoots(this.updateHelper, evaluator(), getReferenceHelper(), "test-roots", true, "test.{0}{1}.dir"); //NOI18N
320
            this.testRoots = SourceRootsSupport.create(this.updateHelper, evaluator(), getReferenceHelper(), AppClientProjectType.PROJECT_CONFIGURATION_NAMESPACE, "test-roots", true, "test.{0}{1}.dir"); //NOI18N
320
        }
321
        }
321
        return this.testRoots;
322
        return this.testRoots;
322
    }
323
    }
(-)a/j2ee.clientproject/src/org/netbeans/modules/j2ee/clientproject/AppClientProjectOperations.java (-1 / +2 lines)
Lines 55-60 import org.netbeans.modules.j2ee.clientp Link Here
55
import org.netbeans.modules.j2ee.clientproject.ui.customizer.AppClientProjectProperties;
55
import org.netbeans.modules.j2ee.clientproject.ui.customizer.AppClientProjectProperties;
56
import org.netbeans.modules.j2ee.dd.api.client.AppClient;
56
import org.netbeans.modules.j2ee.dd.api.client.AppClient;
57
import org.netbeans.modules.j2ee.dd.api.client.DDProvider;
57
import org.netbeans.modules.j2ee.dd.api.client.DDProvider;
58
import org.netbeans.modules.java.api.common.SourceRoots;
58
import org.netbeans.spi.project.ActionProvider;
59
import org.netbeans.spi.project.ActionProvider;
59
import org.netbeans.spi.project.CopyOperationImplementation;
60
import org.netbeans.spi.project.CopyOperationImplementation;
60
import org.netbeans.spi.project.DeleteOperationImplementation;
61
import org.netbeans.spi.project.DeleteOperationImplementation;
Lines 184-190 public class AppClientProjectOperations Link Here
184
    }
185
    }
185
    public void notifyMoving() throws IOException {
186
    public void notifyMoving() throws IOException {
186
        if (!this.project.getUpdateHelper().requestSave()) {
187
        if (!this.project.getUpdateHelper().requestUpdate()) {
187
            throw new IOException(NbBundle.getMessage(AppClientProjectOperations.class,
188
            throw new IOException(NbBundle.getMessage(AppClientProjectOperations.class,
188
                    "MSG_OldProjectMetadata")); // NOI18N
189
                    "MSG_OldProjectMetadata")); // NOI18N
189
        }
190
        }
(-)a/j2ee.clientproject/src/org/netbeans/modules/j2ee/clientproject/AppClientSharabilityQuery.java (-136 lines)
Lines 1-136 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 1997-2007 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
 * Contributor(s):
25
 *
26
 * The Original Software is NetBeans. The Initial Developer of the Original
27
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
28
 * Microsystems, Inc. All Rights Reserved.
29
 *
30
 * If you wish your version of this file to be governed by only the CDDL
31
 * or only the GPL Version 2, indicate your decision by adding
32
 * "[Contributor] elects to include this software in this distribution
33
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
34
 * single choice of license, a recipient has the option to distribute
35
 * your version of this file under either the CDDL, the GPL Version 2 or
36
 * to extend the choice of license to its licensees as provided above.
37
 * However, if you add GPL Version 2 code and therefore, elected the GPL
38
 * Version 2 license, then the option applies only if the new code is
39
 * made subject to such option by the copyright holder.
40
 */
41
42
package org.netbeans.modules.j2ee.clientproject;
43
44
45
import java.io.File;
46
import java.beans.PropertyChangeEvent;
47
import java.beans.PropertyChangeListener;
48
import org.openide.util.Mutex;
49
import org.netbeans.api.project.ProjectManager;
50
import org.netbeans.spi.queries.SharabilityQueryImplementation;
51
import org.netbeans.spi.project.support.ant.AntProjectHelper;
52
import org.netbeans.spi.project.support.ant.PropertyEvaluator;
53
import org.netbeans.modules.j2ee.clientproject.ui.customizer.AppClientProjectProperties;
54
55
56
57
58
/**
59
 * SharabilityQueryImplementation for j2seproject with multiple sources
60
 */
61
public class AppClientSharabilityQuery implements SharabilityQueryImplementation, PropertyChangeListener {
62
63
    private final AntProjectHelper helper;
64
    private final PropertyEvaluator evaluator;
65
    private final SourceRoots srcRoots;
66
    private final SourceRoots testRoots;
67
    private SharabilityQueryImplementation delegate;
68
69
70
    /**
71
     * Creates new AppClientSharabilityQuery
72
     *
73
     * @param helper AntProjectHelper
74
     * @param evaluator PropertyEvaluator
75
     * @param srcRoots sources
76
     * @param testRoots tests
77
     */
78
    AppClientSharabilityQuery (AntProjectHelper helper, PropertyEvaluator evaluator, SourceRoots srcRoots, SourceRoots testRoots) {
79
        this.helper = helper;
80
        this.evaluator = evaluator;
81
        this.srcRoots = srcRoots;
82
        this.testRoots = testRoots;
83
        this.srcRoots.addPropertyChangeListener(this);
84
        this.testRoots.addPropertyChangeListener(this);
85
    }
86
87
88
    /**
89
     * Check whether a file or directory should be shared.
90
     * If it is, it ought to be committed to a VCS if the user is using one.
91
     * If it is not, it is either a disposable build product, or a per-user
92
     * private file which is important but should not be shared.
93
     * @param file a file to check for sharability (may or may not yet exist)
94
     * @return one of {@link org.netbeans.api.queries.SharabilityQuery}'s constants
95
     */
96
    public int getSharability(final File file) {
97
        Integer ret = ProjectManager.mutex().readAccess(new Mutex.Action<Integer>() {
98
            public Integer run() {
99
                synchronized (AppClientSharabilityQuery.this) {
100
                    if (delegate == null) {
101
                        delegate = createDelegate ();
102
                    }
103
                    return new Integer(delegate.getSharability (file));
104
                }
105
            }
106
        });
107
        return ret.intValue();
108
    }
109
110
    public void propertyChange(PropertyChangeEvent evt) {
111
        if (SourceRoots.PROP_ROOT_PROPERTIES.equals(evt.getPropertyName())) {
112
            synchronized (this) {
113
                this.delegate = null;
114
            }
115
        }
116
    }
117
118
    private SharabilityQueryImplementation createDelegate () {
119
        String[] srcProps = srcRoots.getRootProperties();
120
        String[] testProps = testRoots.getRootProperties();
121
        String[] props = new String [srcProps.length + testProps.length + 1];
122
        for (int i=0; i<srcProps.length; i++) {
123
            props[i] = "${"+srcProps[i]+"}"; // NOI18N
124
        }
125
        for (int i=0; i<testProps.length; i++) {
126
            props[srcProps.length+i] = "${"+testProps[i]+"}"; // NOI18N
127
        }
128
        props[props.length - 1] = "${" + AppClientProjectProperties.META_INF + "}"; // NOI18N
129
        return helper.createSharabilityQuery(this.evaluator, props,
130
            new String[] {
131
                "${" + AppClientProjectProperties.DIST_DIR + "}", // NOI18N
132
                "${" + AppClientProjectProperties.BUILD_DIR + "}", // NOI18N
133
            });
134
    }
135
136
}
(-)a/j2ee.clientproject/src/org/netbeans/modules/j2ee/clientproject/AppClientSources.java (+1 lines)
Lines 57-62 import org.netbeans.api.project.FileOwne Link Here
57
import org.netbeans.api.project.FileOwnerQuery;
57
import org.netbeans.api.project.FileOwnerQuery;
58
import org.netbeans.api.java.project.JavaProjectConstants;
58
import org.netbeans.api.java.project.JavaProjectConstants;
59
import org.netbeans.modules.j2ee.clientproject.ui.AppClientLogicalViewProvider;
59
import org.netbeans.modules.j2ee.clientproject.ui.AppClientLogicalViewProvider;
60
import org.netbeans.modules.java.api.common.SourceRoots;
60
import org.netbeans.spi.project.support.ant.SourcesHelper;
61
import org.netbeans.spi.project.support.ant.SourcesHelper;
61
import org.netbeans.spi.project.support.ant.AntProjectHelper;
62
import org.netbeans.spi.project.support.ant.AntProjectHelper;
62
import org.netbeans.spi.project.support.ant.PropertyEvaluator;
63
import org.netbeans.spi.project.support.ant.PropertyEvaluator;
(-)a/j2ee.clientproject/src/org/netbeans/modules/j2ee/clientproject/MainClassUpdater.java (+1 lines)
Lines 45-50 import org.openide.util.RequestProcessor Link Here
45
import org.openide.util.RequestProcessor;
45
import org.openide.util.RequestProcessor;
46
import org.netbeans.api.java.classpath.ClassPath;
46
import org.netbeans.api.java.classpath.ClassPath;
47
import org.netbeans.api.project.Project;
47
import org.netbeans.api.project.Project;
48
import org.netbeans.modules.java.api.common.ant.UpdateHelper;
48
import org.netbeans.spi.project.support.ant.PropertyEvaluator;
49
import org.netbeans.spi.project.support.ant.PropertyEvaluator;
49
//TODO: RETOUCHE almost complete rewrite needed
50
//TODO: RETOUCHE almost complete rewrite needed
(-)a/j2ee.clientproject/src/org/netbeans/modules/j2ee/clientproject/SourceRoots.java (-449 lines)
Lines 1-449 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 1997-2007 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
 * Contributor(s):
25
 *
26
 * The Original Software is NetBeans. The Initial Developer of the Original
27
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
28
 * Microsystems, Inc. All Rights Reserved.
29
 *
30
 * If you wish your version of this file to be governed by only the CDDL
31
 * or only the GPL Version 2, indicate your decision by adding
32
 * "[Contributor] elects to include this software in this distribution
33
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
34
 * single choice of license, a recipient has the option to distribute
35
 * your version of this file under either the CDDL, the GPL Version 2 or
36
 * to extend the choice of license to its licensees as provided above.
37
 * However, if you add GPL Version 2 code and therefore, elected the GPL
38
 * Version 2 license, then the option applies only if the new code is
39
 * made subject to such option by the copyright holder.
40
 */
41
42
package org.netbeans.modules.j2ee.clientproject;
43
44
import java.beans.PropertyChangeEvent;
45
import java.beans.PropertyChangeListener;
46
import java.beans.PropertyChangeSupport;
47
import java.io.File;
48
import java.net.MalformedURLException;
49
import java.net.URL;
50
import java.net.URI;
51
import java.util.Arrays;
52
import java.util.ArrayList;
53
import java.util.Collections;
54
import java.util.Iterator;
55
import java.util.List;
56
import java.util.Map;
57
import java.util.HashMap;
58
import java.text.MessageFormat;
59
import org.openide.filesystems.FileObject;
60
import org.openide.filesystems.FileUtil;
61
import org.openide.util.WeakListeners;
62
import org.openide.util.Mutex;
63
import org.openide.util.NbBundle;
64
import org.w3c.dom.Element;
65
import org.w3c.dom.NodeList;
66
import org.w3c.dom.Document;
67
import org.netbeans.spi.project.support.ant.AntProjectHelper;
68
import org.netbeans.spi.project.support.ant.AntProjectEvent;
69
import org.netbeans.spi.project.support.ant.AntProjectListener;
70
import org.netbeans.spi.project.support.ant.EditableProperties;
71
import org.netbeans.spi.project.support.ant.PropertyEvaluator;
72
import org.netbeans.spi.project.support.ant.ReferenceHelper;
73
import org.netbeans.api.project.ProjectManager;
74
import org.netbeans.api.java.project.JavaProjectConstants;
75
import org.openide.util.Exceptions;
76
77
/**
78
 * This class represents a project source roots. It is used to obtain roots as Ant properties, FileObject's
79
 * or URLs.
80
 * @author Tomas Zezula
81
 */
82
public final class SourceRoots {
83
84
    public static final String PROP_ROOT_PROPERTIES = "rootProperties";    //NOI18N
85
    public static final String PROP_ROOTS = "roots";   //NOI18N
86
87
    public static final String DEFAULT_SOURCE_LABEL = NbBundle.getMessage(SourceRoots.class, "NAME_src.dir");
88
    public static final String DEFAULT_TEST_LABEL = NbBundle.getMessage(SourceRoots.class, "NAME_test.src.dir");
89
90
    private final UpdateHelper helper;
91
    private final PropertyEvaluator evaluator;
92
    private final ReferenceHelper refHelper;
93
    private final String elementName;
94
    private final String newRootNameTemplate;
95
    private List<String> sourceRootProperties;
96
    private List<String> sourceRootNames;
97
    private List<FileObject> sourceRoots;
98
    private List<URL> sourceRootURLs;
99
    private final PropertyChangeSupport support;
100
    private final ProjectMetadataListener listener;
101
    private final boolean isTest;
102
    private final File projectDir;
103
104
    /**
105
     * Creates new SourceRoots
106
     * @param helper
107
     * @param evaluator
108
     * @param elementName the name of XML element under which are declared the roots
109
     * @param newRootNameTemplate template for new property name of source root
110
     */
111
    SourceRoots (UpdateHelper helper, PropertyEvaluator evaluator, ReferenceHelper refHelper, String elementName, boolean isTest, String newRootNameTemplate) {
112
        assert helper != null && evaluator != null && refHelper != null && elementName != null && newRootNameTemplate != null;
113
        this.helper = helper;
114
        this.evaluator = evaluator;
115
        this.refHelper = refHelper;
116
        this.elementName = elementName;
117
        this.isTest = isTest;
118
        this.newRootNameTemplate = newRootNameTemplate;
119
        this.projectDir = FileUtil.toFile(this.helper.getAntProjectHelper().getProjectDirectory());
120
        this.support = new PropertyChangeSupport(this);
121
        this.listener = new ProjectMetadataListener();
122
        this.evaluator.addPropertyChangeListener (WeakListeners.propertyChange(this.listener,this.evaluator));
123
        this.helper.getAntProjectHelper().addAntProjectListener(WeakListeners.create(AntProjectListener.class, this.listener,this.helper));
124
    }
125
126
127
    /**
128
     * Returns the display names of soruce roots
129
     * The returned array has the same length as an array returned by the getRootProperties.
130
     * It may contain empty strings but not null.
131
     * @return an array of String
132
     */
133
    public String[] getRootNames() {
134
        return ProjectManager.mutex().readAccess(new Mutex.Action<String[]>() {
135
            public String[] run() {
136
                synchronized (SourceRoots.this) {
137
                    if (sourceRootNames == null) {
138
                        readProjectMetadata();
139
                    }
140
                }
141
                return sourceRootNames.toArray(new String[sourceRootNames.size()]);
142
            }
143
        });
144
    }
145
146
    /**
147
     * Returns names of Ant properties in the project.properties file holding the source roots.
148
     * @return an array of String
149
     */
150
    public String[] getRootProperties () {
151
        return ProjectManager.mutex().readAccess(new Mutex.Action<String[]>() {
152
            public String[] run() {
153
                synchronized (SourceRoots.this) {
154
                    if (sourceRootProperties == null) {
155
                        readProjectMetadata();
156
                    }
157
                }
158
                return sourceRootProperties.toArray(new String[sourceRootProperties.size()]);
159
            }
160
        });
161
    }
162
163
    /**
164
     * Returns the source roots
165
     * @return an array of FileObject
166
     */
167
    public FileObject[] getRoots () {
168
        return ProjectManager.mutex().readAccess(new Mutex.Action<FileObject[]>() {
169
                public FileObject[] run () {
170
                    synchronized (this) {
171
                        //Local caching
172
                        if (sourceRoots == null) {
173
                            String[] srcProps = getRootProperties();
174
                            List<FileObject> result = new ArrayList<FileObject>();
175
                            for (int i = 0; i<srcProps.length; i++) {
176
                                String prop = evaluator.getProperty(srcProps[i]);
177
                                if (prop != null) {
178
                                    FileObject f = helper.getAntProjectHelper().resolveFileObject(prop);
179
                                    if (f == null) {
180
                                        continue;
181
                                    }
182
                                    if (FileUtil.isArchiveFile(f)) {
183
                                        f = FileUtil.getArchiveRoot(f);
184
                                    }
185
                                    result.add(f);
186
                                }
187
                            }
188
                            sourceRoots = Collections.unmodifiableList(result);
189
                        }
190
                    }
191
                    return sourceRoots.toArray(new FileObject[sourceRoots.size()]);
192
                }
193
        });
194
    }
195
196
    /**
197
     * Returns the source roots as URLs.
198
     * @return an array of URL
199
     */
200
    public URL[] getRootURLs() {
201
        return ProjectManager.mutex().readAccess(new Mutex.Action<URL[]>() {
202
            public URL[] run() {
203
                synchronized (this) {
204
                    //Local caching
205
                    if (sourceRootURLs == null) {
206
                        String[] srcProps = getRootProperties();
207
                        List<URL> result = new ArrayList<URL>();
208
                        for (int i = 0; i<srcProps.length; i++) {
209
                            String prop = evaluator.getProperty(srcProps[i]);
210
                            if (prop != null) {
211
                                File f = helper.getAntProjectHelper().resolveFile(prop);
212
                                try {
213
                                    URL url = f.toURI().toURL();
214
                                    if (!f.exists()) {
215
                                        url = new URL(url.toExternalForm() + "/"); // NOI18N
216
                                    }
217
                                    result.add(url);
218
                                } catch (MalformedURLException e) {
219
                                    Exceptions.printStackTrace(e);
220
                                }
221
                            }
222
                        }
223
                        sourceRootURLs = Collections.unmodifiableList(result);
224
                    }
225
                }
226
                return sourceRootURLs.toArray(new URL[sourceRootURLs.size()]);
227
            }
228
        });
229
    }
230
231
    /**
232
     * Adds PropertyChangeListener
233
     * @param listener
234
     */
235
    public void addPropertyChangeListener (PropertyChangeListener listener) {
236
        this.support.addPropertyChangeListener (listener);
237
    }
238
239
    /**
240
     * Removes PropertyChangeListener
241
     * @param listener
242
     */
243
    public void removePropertyChangeListener (PropertyChangeListener listener) {
244
        this.support.removePropertyChangeListener (listener);
245
    }
246
247
248
    /**
249
     * Replaces the current roots by the new ones
250
     * @param roots the URLs of new roots
251
     * @param labels the names of roots
252
     */
253
    public void putRoots (final URL[] roots, final String[] labels) {
254
        ProjectManager.mutex().writeAccess(new Runnable() {
255
                public void run() {
256
                    String[] originalProps = getRootProperties();
257
                    URL[] originalRoots = getRootURLs();
258
                    Map<URL, String> oldRoots2props = new HashMap<URL, String>();
259
                    for (int i=0; i<originalProps.length;i++) {
260
                        oldRoots2props.put (originalRoots[i],originalProps[i]);
261
                    }
262
                    Map<URL,String> newRoots2lab = new HashMap<URL,String>();
263
                    for (int i=0; i<roots.length;i++) {
264
                        newRoots2lab.put (roots[i],labels[i]);
265
                    }
266
                    Element cfgEl = helper.getPrimaryConfigurationData(true);
267
                    NodeList nl = cfgEl.getElementsByTagNameNS(AppClientProjectType.PROJECT_CONFIGURATION_NAMESPACE, elementName);
268
                    assert nl.getLength() == 1 : "Illegal project.xml"; //NOI18N
269
                    Element ownerElement = (Element) nl.item(0);
270
                    //Remove all old roots
271
                    NodeList rootsNodes = ownerElement.getElementsByTagNameNS(AppClientProjectType.PROJECT_CONFIGURATION_NAMESPACE, "root");    //NOI18N
272
                    while (rootsNodes.getLength()>0) {
273
                        Element root = (Element) rootsNodes.item(0);
274
                        ownerElement.removeChild(root);
275
                    }
276
                    //Remove all unused root properties
277
                    List newRoots = Arrays.asList(roots);
278
                    Map<URL, String> propsToRemove = new HashMap<URL, String>(oldRoots2props);
279
                    propsToRemove.keySet().removeAll(newRoots);
280
                    EditableProperties props = helper.getProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH);
281
                    for (Iterator<String> it = propsToRemove.values().iterator(); it.hasNext();) {
282
                        String propName = it.next();
283
                        props.remove(propName);
284
                    }
285
                    helper.putProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH,props);
286
                    //Add the new roots
287
                    Document doc = ownerElement.getOwnerDocument();
288
                    oldRoots2props.keySet().retainAll(newRoots);
289
                    for (Iterator it = newRoots.iterator(); it.hasNext();) {
290
                        URL newRoot = (URL) it.next ();
291
                        String rootName = oldRoots2props.get (newRoot);
292
                        if (rootName == null) {
293
                            //Root is new generate property for it
294
                            props = helper.getProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH);
295
                            String[] names = newRoot.getPath().split("/");  //NOI18N
296
                            rootName = MessageFormat.format(newRootNameTemplate,new Object[]{names[names.length-1],""});    //NOI18N
297
                            int rootIndex = 1;
298
                            while (props.containsKey(rootName)) {
299
                                rootIndex++;
300
                                rootName = MessageFormat.format(newRootNameTemplate,new Object[]{names[names.length-1],new Integer(rootIndex)});
301
                            }
302
                            File f = FileUtil.normalizeFile(new File(URI.create(newRoot.toExternalForm())));
303
                            File projDir = FileUtil.toFile(helper.getAntProjectHelper().getProjectDirectory());
304
                            String path = f.getAbsolutePath();
305
                            String prjPath = projDir.getAbsolutePath()+File.separatorChar;
306
                            if (path.startsWith(prjPath)) {
307
                                path = path.substring(prjPath.length());
308
                            }
309
                            else {
310
                                path = refHelper.createForeignFileReference(f, JavaProjectConstants.SOURCES_TYPE_JAVA);
311
                                props = helper.getProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH);
312
                            }
313
                            props.put(rootName,path);
314
                            helper.putProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH,props);
315
                        }
316
                        Element newRootNode = doc.createElementNS(AppClientProjectType.PROJECT_CONFIGURATION_NAMESPACE, "root"); //NOI18N
317
                        newRootNode.setAttribute("id",rootName);    //NOI18N
318
                        String label = newRoots2lab.get (newRoot);
319
                        if (label != null && label.length()>0 && !label.equals (getRootDisplayName(null,rootName))) { //NOI18N
320
                            newRootNode.setAttribute("name",label); //NOI18N
321
                        }
322
                        ownerElement.appendChild (newRootNode);
323
                    }
324
                    helper.putPrimaryConfigurationData(cfgEl,true);
325
                }
326
            }
327
        );
328
    }
329
330
    /**
331
     * Translates root name into display name of source/test root
332
     * @param rootName the name of root got from {@link SourceRoots#getRootNames}
333
     * @param propName the name of property the root is stored in
334
     * @return the label to be displayed
335
     */
336
    public String getRootDisplayName (String rootName, String propName) {
337
        if (rootName == null || rootName.length() ==0) {
338
            //If the prop is src.dir use the default name
339
            if (isTest && "test.src.dir".equals(propName)) {    //NOI18N
340
                rootName = DEFAULT_TEST_LABEL;
341
            }
342
            else if (!isTest && "src.dir".equals(propName)) {   //NOI18N
343
                rootName = DEFAULT_SOURCE_LABEL;
344
            }
345
            else {
346
                //If the name is not given, it should be either a relative path in the project dir
347
                //or absolute path when the root is not under the project dir
348
                String propValue = evaluator.getProperty(propName);
349
                File sourceRoot = propValue == null ? null : helper.getAntProjectHelper().resolveFile(propValue);
350
                rootName = createInitialDisplayName(sourceRoot);
351
            }
352
        }
353
        return rootName;
354
    }
355
356
    /**
357
     * Creates initial display name of source/test root
358
     * @param sourceRoot the source root
359
     * @return the label to be displayed
360
     */
361
    public String createInitialDisplayName (File sourceRoot) {
362
        String rootName;
363
        if (sourceRoot != null) {
364
        String srPath = sourceRoot.getAbsolutePath();
365
        String pdPath = projectDir.getAbsolutePath() + File.separatorChar;
366
        if (srPath.startsWith(pdPath)) {
367
            rootName = srPath.substring(pdPath.length());
368
        }
369
        else {
370
            rootName = sourceRoot.getAbsolutePath();
371
        }
372
        }
373
        else {
374
            rootName = isTest ? DEFAULT_TEST_LABEL : DEFAULT_SOURCE_LABEL;
375
        }
376
        return rootName;
377
    }
378
379
    /**
380
     * Returns true if this SourceRoots instance represents source roots belonging to
381
     * the tests compilation unit.
382
     * @return boolean
383
     */
384
    public boolean isTest () {
385
        return this.isTest;
386
    }
387
388
    private void resetCache (boolean isXMLChange, String propName) {
389
        boolean fire = false;
390
        synchronized (this) {
391
            //In case of change reset local cache
392
            if (isXMLChange) {
393
                this.sourceRootProperties = null;
394
                this.sourceRootNames = null;
395
                this.sourceRoots = null;
396
                this.sourceRootURLs = null;
397
                fire = true;
398
            } else if (propName == null || (sourceRootProperties != null && sourceRootProperties.contains(propName))) {
399
                this.sourceRoots = null;
400
                this.sourceRootURLs = null;
401
                fire = true;
402
            }
403
        }
404
        if (fire) {
405
            if (isXMLChange) {
406
                this.support.firePropertyChange (PROP_ROOT_PROPERTIES,null,null);
407
            }
408
            this.support.firePropertyChange (PROP_ROOTS,null,null);
409
        }
410
    }
411
412
    private void readProjectMetadata () {
413
        Element cfgEl = helper.getPrimaryConfigurationData(true);
414
        NodeList nl = cfgEl.getElementsByTagNameNS(AppClientProjectType.PROJECT_CONFIGURATION_NAMESPACE, elementName);
415
        assert nl.getLength() == 0 || nl.getLength() == 1 : "Illegal project.xml"; //NOI18N
416
        List<String> rootProps = new ArrayList<String>();
417
        List<String> rootNames = new ArrayList<String>();
418
        // It can be 0 in the case when the project is created by J2SEProjectGenerator and not yet customized
419
        if (nl.getLength()==1) {
420
            NodeList roots = ((Element)nl.item(0)).getElementsByTagNameNS(AppClientProjectType.PROJECT_CONFIGURATION_NAMESPACE, "root");    //NOI18N
421
            for (int i=0; i<roots.getLength(); i++) {
422
                Element root = (Element) roots.item(i);
423
                String value = root.getAttribute("id");  //NOI18N
424
                assert value.length() > 0 : "Illegal project.xml";
425
                rootProps.add(value);
426
                value = root.getAttribute("name");  //NOI18N
427
                rootNames.add (value);
428
            }
429
        }
430
        this.sourceRootProperties = Collections.unmodifiableList(rootProps);
431
        this.sourceRootNames = Collections.unmodifiableList(rootNames);
432
    }
433
434
    private class ProjectMetadataListener implements PropertyChangeListener,AntProjectListener {
435
436
        public void propertyChange(PropertyChangeEvent evt) {
437
            resetCache (false,evt.getPropertyName());
438
        }
439
440
        public void configurationXmlChanged(AntProjectEvent ev) {
441
            resetCache (true,null);
442
        }
443
444
        public void propertiesChanged(AntProjectEvent ev) {
445
            //Handled by propertyChange
446
        }
447
    }
448
449
}
(-)a/j2ee.clientproject/src/org/netbeans/modules/j2ee/clientproject/UpdateHelper.java (-399 lines)
Lines 1-399 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 1997-2007 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
 * Contributor(s):
25
 *
26
 * The Original Software is NetBeans. The Initial Developer of the Original
27
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
28
 * Microsystems, Inc. All Rights Reserved.
29
 *
30
 * If you wish your version of this file to be governed by only the CDDL
31
 * or only the GPL Version 2, indicate your decision by adding
32
 * "[Contributor] elects to include this software in this distribution
33
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
34
 * single choice of license, a recipient has the option to distribute
35
 * your version of this file under either the CDDL, the GPL Version 2 or
36
 * to extend the choice of license to its licensees as provided above.
37
 * However, if you add GPL Version 2 code and therefore, elected the GPL
38
 * Version 2 license, then the option applies only if the new code is
39
 * made subject to such option by the copyright holder.
40
 */
41
42
package org.netbeans.modules.j2ee.clientproject;
43
44
import java.io.IOException;
45
import javax.swing.JButton;
46
import org.netbeans.modules.j2ee.clientproject.api.AppClientProjectGenerator;
47
import org.netbeans.modules.j2ee.clientproject.ui.customizer.AppClientProjectProperties;
48
import org.netbeans.spi.project.support.ant.GeneratedFilesHelper;
49
import org.w3c.dom.Comment;
50
import org.w3c.dom.Document;
51
import org.w3c.dom.Element;
52
import org.w3c.dom.NamedNodeMap;
53
import org.w3c.dom.Node;
54
import org.w3c.dom.NodeList;
55
import org.w3c.dom.Text;
56
import org.openide.DialogDisplayer;
57
import org.openide.NotifyDescriptor;
58
import org.openide.util.NbBundle;
59
import org.openide.util.Mutex;
60
import org.netbeans.api.project.Project;
61
import org.netbeans.api.project.ProjectManager;
62
import org.netbeans.spi.project.AuxiliaryConfiguration;
63
import org.netbeans.spi.project.support.ant.AntProjectHelper;
64
import org.netbeans.spi.project.support.ant.EditableProperties;
65
import org.openide.util.Exceptions;
66
67
68
/**
69
 * Proxy for the AntProjectHelper which defers the update of the project metadata
70
 * to explicit user action. Currently it is hard coded for update from
71
 * "http://www.netbeans.org/ns/j2se-project/1" to "http://www.netbeans.org/ns/j2se-project/2".
72
 * In future it should define plugable SPI.
73
 */
74
public class UpdateHelper {
75
76
    private static final boolean TRANSPARENT_UPDATE = Boolean.getBoolean("carproject.transparentUpdate");
77
    private static final String BUILD_NUMBER = System.getProperty("netbeans.buildnumber"); // NOI18N
78
    private static final String MINIMUM_ANT_VERSION_ELEMENT = "minimum-ant-version"; // NOI18N
79
80
    private final Project project;
81
    private final AntProjectHelper helper;
82
    private final AuxiliaryConfiguration cfg;
83
    private final GeneratedFilesHelper genFileHelper;
84
    private final Notifier notifier;
85
    private boolean alreadyAskedInWriteAccess;
86
    private Boolean isCurrent;
87
    private Element cachedElement;
88
89
    /**
90
     * Creates new UpdateHelper
91
     * @param project
92
     * @param helper AntProjectHelper
93
     * @param cfg AuxiliaryConfiguration
94
     * @param genFileHelper GeneratedFilesHelper
95
     * @param notifier used to ask user about project update
96
     */
97
    UpdateHelper (Project project, AntProjectHelper helper, AuxiliaryConfiguration cfg, GeneratedFilesHelper genFileHelper, Notifier notifier) {
98
        assert project != null && helper != null && cfg != null && genFileHelper != null && notifier != null;
99
        this.project = project;
100
        this.helper = helper;
101
        this.cfg = cfg;
102
        this.genFileHelper = genFileHelper;
103
        this.notifier = notifier;
104
    }
105
106
    /**
107
     * Returns the AntProjectHelper.getProperties(), {@link AntProjectHelper#getProperties(String)}
108
     * @param path a relative URI in the project directory.
109
     * @return a set of properties
110
     */
111
    public EditableProperties getProperties (final String path) {
112
        //Properties are the same in both j2seproject/1 and j2seproject/2
113
        return ProjectManager.mutex().readAccess(new Mutex.Action<EditableProperties>(){
114
            public EditableProperties run() {
115
                if (!isCurrent() && AntProjectHelper.PROJECT_PROPERTIES_PATH.equals(path)) { //Only project properties were changed
116
                    return getUpdatedProjectProperties ();
117
                }
118
                else {
119
                    return helper.getProperties(path);
120
                }
121
            }
122
        });
123
    }
124
125
    /**
126
     * In the case that the project is of current version or the properties are not {@link AntProjectHelper#PROJECT_PROPERTIES_PATH}
127
     * it calls AntProjectHelper.putProperties(), {@link AntProjectHelper#putProperties(String, EditableProperties)}
128
     * otherwise it asks user to updata project. If the user agrees with the project update, it does the update and calls
129
     * AntProjectHelper.putProperties().
130
     * @param path a relative URI in the project directory.
131
     * @param props a set of properties
132
     */
133
    public void putProperties(final String path, final EditableProperties props) {
134
        ProjectManager.mutex().writeAccess(new Runnable() {
135
            public void run() {
136
                if (isCurrent() || !AntProjectHelper.PROJECT_PROPERTIES_PATH.equals(path)) {  //Only project props should cause update
137
                    helper.putProperties(path,props);
138
                } else if (canUpdate()) {
139
                    try {
140
                        saveUpdate();
141
                        helper.putProperties(path,props);
142
                    } catch (IOException ioe) {
143
                        Exceptions.printStackTrace(ioe);
144
                    }
145
                }
146
            }
147
        });
148
    }
149
150
    /**
151
     * In the case that the project is of current version or shared is false it delegates to
152
     * AntProjectHelper.getPrimaryConfigurationData(), {@link AntProjectHelper#getPrimaryConfigurationData(boolean)}.
153
     * Otherwise it creates an in memory update of shared configuration data and returns it.
154
     * @param shared if true, refers to <code>project.xml</code>, else refers to
155
     *               <code>private.xml</code>
156
     * @return the configuration data that is available
157
     */
158
    public Element getPrimaryConfigurationData (final boolean shared) {
159
        return ProjectManager.mutex().readAccess(new Mutex.Action<Element>(){
160
            public Element run() {
161
                if (!shared || isCurrent()) { //Only shared props should cause update
162
                    return helper.getPrimaryConfigurationData(shared);
163
                }
164
                return getUpdatedSharedConfigurationData ();
165
            }
166
        });
167
    }
168
169
    /**
170
     * In the case that the project is of current version or shared is false it calls AntProjectHelper.putPrimaryConfigurationData(),
171
     * {@link AntProjectHelper#putPrimaryConfigurationData(Element, boolean)}.
172
     * Otherwise it asks user to update the project. If the user agrees with the project update, it does the update and calls
173
     * AntProjectHelper.PrimaryConfigurationData().
174
     * @param element the configuration data
175
     * @param shared if true, refers to <code>project.xml</code>, else refers to
176
     * <code>private.xml</code>
177
     */
178
    public void putPrimaryConfigurationData(final Element element, final boolean shared) {
179
        ProjectManager.mutex().writeAccess(new Runnable() {
180
            public void run() {
181
                if (!shared || isCurrent()) {
182
                    helper.putPrimaryConfigurationData(element, shared);
183
                } else if (canUpdate()) {
184
                    try {
185
                        saveUpdate();
186
                        helper.putPrimaryConfigurationData(element, shared);
187
                    } catch (IOException ioe) {
188
                        Exceptions.printStackTrace(ioe);
189
                    }
190
                }
191
            }
192
        });
193
    }
194
195
    /**
196
     * Returns an AntProjectHelper. The helper may not be used for accessing/storing project metadata.
197
     * For project metadata manipulation the UpdateHelper must be used.
198
     * @return AntProjectHelper
199
     */
200
    public AntProjectHelper getAntProjectHelper () {
201
        return this.helper;
202
    }
203
204
    /**
205
     * Request an saving of update. If the project is not of current version the user will be asked to update the project.
206
     * If the user agrees with an update the project is updated.
207
     * @return true if the metadata are of current version or updated
208
     */
209
    public boolean requestSave () throws IOException{
210
        if (isCurrent()) {
211
            return true;
212
        }
213
        if (!canUpdate()) {
214
            return false;
215
        }
216
        saveUpdate ();
217
        return true;
218
    }
219
220
    /**
221
     * Returns true if the project is of current version.
222
     * @return true if the project is of current version, otherwise false.
223
     */
224
    public synchronized boolean isCurrent () {
225
        /*
226
        if (this.isCurrent == null) {
227
            if ((this.cfg.getConfigurationFragment("data","http://www.netbeans.org/ns/j2se-project/1",true) != null) ||
228
                (this.cfg.getConfigurationFragment("data","http://www.netbeans.org/ns/j2se-project/2",true) != null)) {
229
                this.isCurrent = Boolean.FALSE;
230
            } else {
231
                this.isCurrent = Boolean.TRUE;
232
            }
233
        }
234
        return isCurrent.booleanValue();
235
         */
236
        //there are no other versions yet => we can always return true
237
        return true;
238
    }
239
240
    private boolean canUpdate () {
241
        if (TRANSPARENT_UPDATE) {
242
            return true;
243
        }
244
        //Ask just once under a single write access
245
        if (alreadyAskedInWriteAccess) {
246
            return false;
247
        }
248
        else {
249
            boolean canUpdate = this.notifier.canUpdate();
250
            if (!canUpdate) {
251
                alreadyAskedInWriteAccess = true;
252
                ProjectManager.mutex().postReadRequest(new Runnable() {
253
                    public void run() {
254
                        alreadyAskedInWriteAccess = false;
255
                    }
256
                });
257
            }
258
            return canUpdate;
259
        }
260
    }
261
262
    private void saveUpdate () throws IOException {
263
        this.helper.putPrimaryConfigurationData(getUpdatedSharedConfigurationData(),true);
264
        this.cfg.removeConfigurationFragment("data","http://www.netbeans.org/ns/j2se-project/1",true); //NOI18N
265
        this.cfg.removeConfigurationFragment("data","http://www.netbeans.org/ns/j2se-project/2",true); //NOI18N
266
        ProjectManager.getDefault().saveProject (this.project);
267
        synchronized(this) {
268
            this.isCurrent = Boolean.TRUE;
269
        }
270
    }
271
272
    private synchronized Element getUpdatedSharedConfigurationData () {
273
        if (cachedElement == null) {
274
            Element  oldRoot = this.cfg.getConfigurationFragment("data","http://www.netbeans.org/ns/j2se-project/1",true);    //NOI18N
275
            if (oldRoot != null) {
276
                Document doc = oldRoot.getOwnerDocument();
277
                Element newRoot = doc.createElementNS (AppClientProjectType.PROJECT_CONFIGURATION_NAMESPACE,"data"); //NOI18N
278
                copyDocument (doc, oldRoot, newRoot);
279
                Element sourceRoots = doc.createElementNS(AppClientProjectType.PROJECT_CONFIGURATION_NAMESPACE,"source-roots");  //NOI18N
280
                Element root = doc.createElementNS (AppClientProjectType.PROJECT_CONFIGURATION_NAMESPACE,"root");   //NOI18N
281
                root.setAttribute ("id","src.dir");   //NOI18N
282
                sourceRoots.appendChild(root);
283
                newRoot.appendChild (sourceRoots);
284
                Element testRoots = doc.createElementNS(AppClientProjectType.PROJECT_CONFIGURATION_NAMESPACE,"test-roots");  //NOI18N
285
                root = doc.createElementNS (AppClientProjectType.PROJECT_CONFIGURATION_NAMESPACE,"root");   //NOI18N
286
                root.setAttribute ("id","test.src.dir");   //NOI18N
287
                testRoots.appendChild (root);
288
                newRoot.appendChild (testRoots);
289
                cachedElement = updateMinAntVersion (newRoot, doc);
290
            } else {
291
                oldRoot = this.cfg.getConfigurationFragment("data","http://www.netbeans.org/ns/j2se-project/2",true);    //NOI18N
292
                if (oldRoot != null) {
293
                    Document doc = oldRoot.getOwnerDocument();
294
                    Element newRoot = doc.createElementNS (AppClientProjectType.PROJECT_CONFIGURATION_NAMESPACE,"data"); //NOI18N
295
                    copyDocument (doc, oldRoot, newRoot);
296
                    cachedElement = updateMinAntVersion (newRoot, doc);
297
                }
298
            }
299
        }
300
        return cachedElement;
301
    }
302
303
    private synchronized EditableProperties getUpdatedProjectProperties () {
304
        EditableProperties cachedProperties = this.helper.getProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH);
305
        //The javadoc.additionalparam was not in NB 4.0
306
        if (cachedProperties.get (AppClientProjectProperties.JAVADOC_ADDITIONALPARAM)==null) {
307
            cachedProperties.put (AppClientProjectProperties.JAVADOC_ADDITIONALPARAM,"");    //NOI18N
308
        }
309
        if (cachedProperties.get ("build.generated.dir")==null) { //NOI18N
310
            cachedProperties.put ("build.generated.dir","${build.dir}/generated"); //NOI18N
311
        }
312
         if (cachedProperties.get (AppClientProjectProperties.META_INF)==null) { //NOI18N
313
            cachedProperties.put (AppClientProjectProperties.META_INF,"${src.dir}/conf"); //NOI18N
314
        }
315
        return cachedProperties;
316
    }
317
318
    private static void copyDocument (Document doc, Element from, Element to) {
319
        NodeList nl = from.getChildNodes();
320
        int length = nl.getLength();
321
        for (int i=0; i< length; i++) {
322
            Node node = nl.item (i);
323
            Node newNode = null;
324
            switch (node.getNodeType()) {
325
                case Node.ELEMENT_NODE:
326
                    Element oldElement = (Element) node;
327
                    newNode = doc.createElementNS(AppClientProjectType.PROJECT_CONFIGURATION_NAMESPACE,oldElement.getTagName());
328
                    NamedNodeMap m = oldElement.getAttributes();
329
                    Element newElement = (Element) newNode;
330
                    for (int index = 0; index < m.getLength(); index++) {
331
                        Node attr = m.item(index);
332
                          newElement.setAttribute(attr.getNodeName(), attr.getNodeValue());
333
                    }
334
                    copyDocument(doc,oldElement,newElement);
335
                    break;
336
                case Node.TEXT_NODE:
337
                    Text oldText = (Text) node;
338
                    newNode = doc.createTextNode(oldText.getData());
339
                    break;
340
                case Node.COMMENT_NODE:
341
                    Comment oldComment = (Comment) node;
342
                    newNode = doc.createComment(oldComment.getData());
343
                    break;
344
            }
345
            if (newNode != null) {
346
                to.appendChild (newNode);
347
            }
348
        }
349
    }
350
351
    private static Element updateMinAntVersion (final Element root, final Document doc) {
352
        NodeList list = root.getElementsByTagNameNS (AppClientProjectType.PROJECT_CONFIGURATION_NAMESPACE,MINIMUM_ANT_VERSION_ELEMENT);
353
        if (list.getLength() == 1) {
354
            Element me = (Element) list.item(0);
355
            list = me.getChildNodes();
356
            if (list.getLength() == 1) {
357
                me.replaceChild (doc.createTextNode(AppClientProjectGenerator.MINIMUM_ANT_VERSION), list.item(0));
358
                return root;
359
            }
360
        }
361
        assert false : "Invalid project file"; //NOI18N
362
        return root;
363
    }
364
365
    /**
366
     * Creates an default Notifier. The default notifier displays a dialog warning user about project update.
367
     * @return notifier
368
     */
369
    public static Notifier createDefaultNotifier () {
370
        return new Notifier() {
371
            public boolean canUpdate() {
372
                JButton updateOption = new JButton (NbBundle.getMessage(UpdateHelper.class, "CTL_UpdateOption"));
373
                updateOption.getAccessibleContext().setAccessibleDescription(NbBundle.getMessage(UpdateHelper.class, "AD_UpdateOption"));
374
                return DialogDisplayer.getDefault().notify(
375
                    new NotifyDescriptor (NbBundle.getMessage(UpdateHelper.class,"TXT_ProjectUpdate", BUILD_NUMBER),
376
                        NbBundle.getMessage(UpdateHelper.class,"TXT_ProjectUpdateTitle"),
377
                        NotifyDescriptor.DEFAULT_OPTION,
378
                        NotifyDescriptor.WARNING_MESSAGE,
379
                        new Object[] {
380
                            updateOption,
381
                            NotifyDescriptor.CANCEL_OPTION
382
                        },
383
                        updateOption)) == updateOption;
384
            }
385
        };
386
    }
387
388
    /**
389
     * Interface used by the UpdateHelper to ask user about
390
     * the project update.
391
     */
392
    public static interface Notifier {
393
        /**
394
         * Asks user to update the project
395
         * @return true if the project should be updated
396
         */
397
        public boolean canUpdate ();
398
    }
399
}
(-)a/j2ee.clientproject/src/org/netbeans/modules/j2ee/clientproject/UpdateProjectImpl.java (+251 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 1997-2007 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 2008 Sun Microsystems, Inc.
38
 */
39
40
package org.netbeans.modules.j2ee.clientproject;
41
42
import java.io.IOException;
43
import javax.swing.JButton;
44
import org.netbeans.api.project.Project;
45
import org.netbeans.api.project.ProjectManager;
46
import org.netbeans.modules.j2ee.clientproject.api.AppClientProjectGenerator;
47
import org.netbeans.modules.j2ee.clientproject.ui.customizer.AppClientProjectProperties;
48
import org.netbeans.modules.java.api.common.ant.UpdateHelper;
49
import org.netbeans.modules.java.api.common.ant.UpdateImplementation;
50
import org.netbeans.spi.project.AuxiliaryConfiguration;
51
import org.netbeans.spi.project.support.ant.AntProjectHelper;
52
import org.netbeans.spi.project.support.ant.EditableProperties;
53
import org.openide.DialogDisplayer;
54
import org.openide.NotifyDescriptor;
55
import org.openide.util.NbBundle;
56
import org.w3c.dom.Comment;
57
import org.w3c.dom.Document;
58
import org.w3c.dom.Element;
59
import org.w3c.dom.NamedNodeMap;
60
import org.w3c.dom.Node;
61
import org.w3c.dom.NodeList;
62
import org.w3c.dom.Text;
63
64
/**
65
 *
66
 * @author Tomas Mysik
67
 */
68
public class UpdateProjectImpl implements UpdateImplementation {
69
70
    private static final boolean TRANSPARENT_UPDATE = Boolean.getBoolean("carproject.transparentUpdate");
71
    private static final String BUILD_NUMBER = System.getProperty("netbeans.buildnumber"); // NOI18N
72
    private static final String MINIMUM_ANT_VERSION_ELEMENT = "minimum-ant-version"; // NOI18N
73
74
    private final Project project;
75
    private final AntProjectHelper helper;
76
    private final AuxiliaryConfiguration cfg;
77
    private boolean alreadyAskedInWriteAccess;
78
    private boolean isCurrent;
79
    private Element cachedElement;
80
81
    /**
82
     * Creates new UpdateHelper
83
     * @param project
84
     * @param helper AntProjectHelper
85
     * @param cfg AuxiliaryConfiguration
86
     * @param genFileHelper GeneratedFilesHelper
87
     * @param notifier used to ask user about project update
88
     */
89
    UpdateProjectImpl(Project project, AntProjectHelper helper, AuxiliaryConfiguration cfg) {
90
        assert project != null && helper != null && cfg != null;
91
        this.project = project;
92
        this.helper = helper;
93
        this.cfg = cfg;
94
    }
95
96
    public boolean isCurrent() {
97
        /*
98
        if (this.isCurrent == null) {
99
            if ((this.cfg.getConfigurationFragment("data","http://www.netbeans.org/ns/j2se-project/1",true) != null) ||
100
                (this.cfg.getConfigurationFragment("data","http://www.netbeans.org/ns/j2se-project/2",true) != null)) {
101
                this.isCurrent = Boolean.FALSE;
102
            } else {
103
                this.isCurrent = Boolean.TRUE;
104
            }
105
        }
106
        return isCurrent.booleanValue();
107
         */
108
        //there are no other versions yet => we can always return true
109
        return true;
110
    }
111
112
    public boolean canUpdate() {
113
        if (TRANSPARENT_UPDATE) {
114
            return true;
115
        }
116
        //Ask just once under a single write access
117
        if (alreadyAskedInWriteAccess) {
118
            return false;
119
        }
120
        else {
121
            boolean canUpdate = showUpdateDialog();
122
            if (!canUpdate) {
123
                alreadyAskedInWriteAccess = true;
124
                ProjectManager.mutex().postReadRequest(new Runnable() {
125
                    public void run() {
126
                        alreadyAskedInWriteAccess = false;
127
                    }
128
                });
129
            }
130
            return canUpdate;
131
        }
132
    }
133
134
    public void saveUpdate(EditableProperties props) throws IOException {
135
        this.helper.putPrimaryConfigurationData(getUpdatedSharedConfigurationData(),true);
136
        this.cfg.removeConfigurationFragment("data","http://www.netbeans.org/ns/j2se-project/1",true); //NOI18N
137
        this.cfg.removeConfigurationFragment("data","http://www.netbeans.org/ns/j2se-project/2",true); //NOI18N
138
        ProjectManager.getDefault().saveProject (this.project);
139
        synchronized(this) {
140
            this.isCurrent = Boolean.TRUE;
141
        }
142
    }
143
144
    public Element getUpdatedSharedConfigurationData() {
145
        if (cachedElement == null) {
146
            Element  oldRoot = this.cfg.getConfigurationFragment("data","http://www.netbeans.org/ns/j2se-project/1",true);    //NOI18N
147
            if (oldRoot != null) {
148
                Document doc = oldRoot.getOwnerDocument();
149
                Element newRoot = doc.createElementNS (AppClientProjectType.PROJECT_CONFIGURATION_NAMESPACE,"data"); //NOI18N
150
                copyDocument (doc, oldRoot, newRoot);
151
                Element sourceRoots = doc.createElementNS(AppClientProjectType.PROJECT_CONFIGURATION_NAMESPACE,"source-roots");  //NOI18N
152
                Element root = doc.createElementNS (AppClientProjectType.PROJECT_CONFIGURATION_NAMESPACE,"root");   //NOI18N
153
                root.setAttribute ("id","src.dir");   //NOI18N
154
                sourceRoots.appendChild(root);
155
                newRoot.appendChild (sourceRoots);
156
                Element testRoots = doc.createElementNS(AppClientProjectType.PROJECT_CONFIGURATION_NAMESPACE,"test-roots");  //NOI18N
157
                root = doc.createElementNS (AppClientProjectType.PROJECT_CONFIGURATION_NAMESPACE,"root");   //NOI18N
158
                root.setAttribute ("id","test.src.dir");   //NOI18N
159
                testRoots.appendChild (root);
160
                newRoot.appendChild (testRoots);
161
                cachedElement = updateMinAntVersion (newRoot, doc);
162
            } else {
163
                oldRoot = this.cfg.getConfigurationFragment("data","http://www.netbeans.org/ns/j2se-project/2",true);    //NOI18N
164
                if (oldRoot != null) {
165
                    Document doc = oldRoot.getOwnerDocument();
166
                    Element newRoot = doc.createElementNS (AppClientProjectType.PROJECT_CONFIGURATION_NAMESPACE,"data"); //NOI18N
167
                    copyDocument (doc, oldRoot, newRoot);
168
                    cachedElement = updateMinAntVersion (newRoot, doc);
169
                }
170
            }
171
        }
172
        return cachedElement;
173
    }
174
175
    public EditableProperties getUpdatedProjectProperties() {
176
        EditableProperties cachedProperties = this.helper.getProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH);
177
        //The javadoc.additionalparam was not in NB 4.0
178
        if (cachedProperties.get (AppClientProjectProperties.JAVADOC_ADDITIONALPARAM)==null) {
179
            cachedProperties.put (AppClientProjectProperties.JAVADOC_ADDITIONALPARAM,"");    //NOI18N
180
        }
181
        if (cachedProperties.get ("build.generated.dir")==null) { //NOI18N
182
            cachedProperties.put ("build.generated.dir","${build.dir}/generated"); //NOI18N
183
        }
184
         if (cachedProperties.get (AppClientProjectProperties.META_INF)==null) { //NOI18N
185
            cachedProperties.put (AppClientProjectProperties.META_INF,"${src.dir}/conf"); //NOI18N
186
        }
187
        return cachedProperties;
188
    }
189
190
    private static void copyDocument (Document doc, Element from, Element to) {
191
        NodeList nl = from.getChildNodes();
192
        int length = nl.getLength();
193
        for (int i=0; i< length; i++) {
194
            Node node = nl.item (i);
195
            Node newNode = null;
196
            switch (node.getNodeType()) {
197
                case Node.ELEMENT_NODE:
198
                    Element oldElement = (Element) node;
199
                    newNode = doc.createElementNS(AppClientProjectType.PROJECT_CONFIGURATION_NAMESPACE,oldElement.getTagName());
200
                    NamedNodeMap m = oldElement.getAttributes();
201
                    Element newElement = (Element) newNode;
202
                    for (int index = 0; index < m.getLength(); index++) {
203
                        Node attr = m.item(index);
204
                          newElement.setAttribute(attr.getNodeName(), attr.getNodeValue());
205
                    }
206
                    copyDocument(doc,oldElement,newElement);
207
                    break;
208
                case Node.TEXT_NODE:
209
                    Text oldText = (Text) node;
210
                    newNode = doc.createTextNode(oldText.getData());
211
                    break;
212
                case Node.COMMENT_NODE:
213
                    Comment oldComment = (Comment) node;
214
                    newNode = doc.createComment(oldComment.getData());
215
                    break;
216
            }
217
            if (newNode != null) {
218
                to.appendChild (newNode);
219
            }
220
        }
221
    }
222
223
    private static Element updateMinAntVersion (final Element root, final Document doc) {
224
        NodeList list = root.getElementsByTagNameNS (AppClientProjectType.PROJECT_CONFIGURATION_NAMESPACE,MINIMUM_ANT_VERSION_ELEMENT);
225
        if (list.getLength() == 1) {
226
            Element me = (Element) list.item(0);
227
            list = me.getChildNodes();
228
            if (list.getLength() == 1) {
229
                me.replaceChild (doc.createTextNode(AppClientProjectGenerator.MINIMUM_ANT_VERSION), list.item(0));
230
                return root;
231
            }
232
        }
233
        assert false : "Invalid project file"; //NOI18N
234
        return root;
235
    }
236
237
    private boolean showUpdateDialog() {
238
        JButton updateOption = new JButton (NbBundle.getMessage(UpdateProjectImpl.class, "CTL_UpdateOption"));
239
        updateOption.getAccessibleContext().setAccessibleDescription(NbBundle.getMessage(UpdateHelper.class, "AD_UpdateOption"));
240
        return DialogDisplayer.getDefault().notify(
241
            new NotifyDescriptor (NbBundle.getMessage(UpdateProjectImpl.class,"TXT_ProjectUpdate", BUILD_NUMBER),
242
                NbBundle.getMessage(UpdateProjectImpl.class,"TXT_ProjectUpdateTitle"),
243
                NotifyDescriptor.DEFAULT_OPTION,
244
                NotifyDescriptor.WARNING_MESSAGE,
245
                new Object[] {
246
                    updateOption,
247
                    NotifyDescriptor.CANCEL_OPTION
248
                },
249
                updateOption)) == updateOption;
250
    }
251
}
(-)a/j2ee.clientproject/src/org/netbeans/modules/j2ee/clientproject/api/AppClientProjectGenerator.java (-3 / +3 lines)
Lines 58-67 import org.netbeans.modules.j2ee.clientp Link Here
58
import org.netbeans.modules.j2ee.clientproject.AppClientProject;
58
import org.netbeans.modules.j2ee.clientproject.AppClientProject;
59
import org.netbeans.modules.j2ee.clientproject.AppClientProjectType;
59
import org.netbeans.modules.j2ee.clientproject.AppClientProjectType;
60
import org.netbeans.modules.j2ee.clientproject.AppClientProvider;
60
import org.netbeans.modules.j2ee.clientproject.AppClientProvider;
61
import org.netbeans.modules.j2ee.clientproject.UpdateHelper;
62
import org.netbeans.modules.j2ee.clientproject.Utils;
61
import org.netbeans.modules.j2ee.clientproject.Utils;
63
import org.netbeans.modules.j2ee.clientproject.ui.customizer.AppClientProjectProperties;
62
import org.netbeans.modules.j2ee.clientproject.ui.customizer.AppClientProjectProperties;
64
import org.netbeans.modules.j2ee.clientproject.ui.customizer.PlatformUiSupport;
65
import org.netbeans.modules.j2ee.dd.api.client.AppClient;
63
import org.netbeans.modules.j2ee.dd.api.client.AppClient;
66
import org.netbeans.modules.j2ee.dd.api.client.DDProvider;
64
import org.netbeans.modules.j2ee.dd.api.client.DDProvider;
67
import org.netbeans.modules.j2ee.deployment.devmodules.api.AntDeploymentHelper;
65
import org.netbeans.modules.j2ee.deployment.devmodules.api.AntDeploymentHelper;
Lines 69-74 import org.netbeans.modules.j2ee.deploym Link Here
69
import org.netbeans.modules.j2ee.deployment.devmodules.api.J2eeModule;
67
import org.netbeans.modules.j2ee.deployment.devmodules.api.J2eeModule;
70
import org.netbeans.modules.j2ee.deployment.devmodules.api.J2eePlatform;
68
import org.netbeans.modules.j2ee.deployment.devmodules.api.J2eePlatform;
71
import org.netbeans.modules.j2ee.deployment.plugins.api.InstanceProperties;
69
import org.netbeans.modules.j2ee.deployment.plugins.api.InstanceProperties;
70
import org.netbeans.modules.java.api.common.ant.UpdateHelper;
71
import org.netbeans.modules.java.api.common.ui.PlatformUiSupport;
72
import org.netbeans.modules.websvc.api.client.WebServicesClientConstants;
72
import org.netbeans.modules.websvc.api.client.WebServicesClientConstants;
73
import org.netbeans.spi.project.support.ant.AntProjectHelper;
73
import org.netbeans.spi.project.support.ant.AntProjectHelper;
74
import org.netbeans.spi.project.support.ant.EditableProperties;
74
import org.netbeans.spi.project.support.ant.EditableProperties;
Lines 637-643 public class AppClientProjectGenerator { Link Here
637
                                if (sourceLevel.equals("1.6") || sourceLevel.equals("1.7")) {
637
                                if (sourceLevel.equals("1.6") || sourceLevel.equals("1.7")) {
638
                                    srcLevel = "1.5";
638
                                    srcLevel = "1.5";
639
                                }
639
                                }
640
                                PlatformUiSupport.storePlatform(ep, updateHelper, finalPlatformName, srcLevel != null ? new SpecificationVersion(srcLevel) : null);
640
                                PlatformUiSupport.storePlatform(ep, updateHelper, AppClientProjectType.PROJECT_CONFIGURATION_NAMESPACE, finalPlatformName, srcLevel != null ? new SpecificationVersion(srcLevel) : null);
641
                                helper.putProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH, ep);
641
                                helper.putProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH, ep);
642
                                ProjectManager.getDefault().saveProject(ProjectManager.getDefault().findProject(helper.getProjectDirectory()));
642
                                ProjectManager.getDefault().saveProject(ProjectManager.getDefault().findProject(helper.getProjectDirectory()));
643
                            } catch (IOException e) {
643
                            } catch (IOException e) {
(-)a/j2ee.clientproject/src/org/netbeans/modules/j2ee/clientproject/classpath/AppClientProjectClassPathExtender.java (-1 / +1 lines)
Lines 62-69 import org.netbeans.spi.project.support. Link Here
62
import org.netbeans.spi.project.support.ant.ReferenceHelper;
62
import org.netbeans.spi.project.support.ant.ReferenceHelper;
63
import org.netbeans.spi.project.support.ant.PropertyEvaluator;
63
import org.netbeans.spi.project.support.ant.PropertyEvaluator;
64
import org.netbeans.spi.project.support.ant.EditableProperties;
64
import org.netbeans.spi.project.support.ant.EditableProperties;
65
import org.netbeans.modules.j2ee.clientproject.UpdateHelper;
66
import org.netbeans.modules.j2ee.clientproject.ui.customizer.AntArtifactChooser;
65
import org.netbeans.modules.j2ee.clientproject.ui.customizer.AntArtifactChooser;
66
import org.netbeans.modules.java.api.common.ant.UpdateHelper;
67
import org.openide.util.Exceptions;
67
import org.openide.util.Exceptions;
68
import org.openide.util.RequestProcessor;
68
import org.openide.util.RequestProcessor;
(-)a/j2ee.clientproject/src/org/netbeans/modules/j2ee/clientproject/classpath/ClassPathProviderImpl.java (-1 / +1 lines)
Lines 53-60 import org.netbeans.spi.java.project.cla Link Here
53
import org.netbeans.spi.java.project.classpath.support.ProjectClassPathSupport;
53
import org.netbeans.spi.java.project.classpath.support.ProjectClassPathSupport;
54
import org.netbeans.spi.project.support.ant.AntProjectHelper;
54
import org.netbeans.spi.project.support.ant.AntProjectHelper;
55
import org.netbeans.spi.project.support.ant.PropertyEvaluator;
55
import org.netbeans.spi.project.support.ant.PropertyEvaluator;
56
import org.netbeans.modules.j2ee.clientproject.SourceRoots;
57
import org.netbeans.modules.j2ee.clientproject.ui.customizer.AppClientProjectProperties;
56
import org.netbeans.modules.j2ee.clientproject.ui.customizer.AppClientProjectProperties;
57
import org.netbeans.modules.java.api.common.SourceRoots;
58
import org.openide.filesystems.FileObject;
58
import org.openide.filesystems.FileObject;
59
import org.openide.filesystems.FileUtil;
59
import org.openide.filesystems.FileUtil;
60
import org.openide.util.WeakListeners;
60
import org.openide.util.WeakListeners;
(-)a/j2ee.clientproject/src/org/netbeans/modules/j2ee/clientproject/classpath/SourcePathImplementation.java (-1 / +1 lines)
Lines 49-58 import java.beans.PropertyChangeListener Link Here
49
import java.beans.PropertyChangeListener;
49
import java.beans.PropertyChangeListener;
50
import java.beans.PropertyChangeSupport;
50
import java.beans.PropertyChangeSupport;
51
import java.net.URL;
51
import java.net.URL;
52
import org.netbeans.modules.java.api.common.SourceRoots;
52
import org.netbeans.spi.java.classpath.ClassPathImplementation;
53
import org.netbeans.spi.java.classpath.ClassPathImplementation;
53
import org.netbeans.spi.java.classpath.PathResourceImplementation;
54
import org.netbeans.spi.java.classpath.PathResourceImplementation;
54
import org.netbeans.spi.java.classpath.support.ClassPathSupport;
55
import org.netbeans.spi.java.classpath.support.ClassPathSupport;
55
import org.netbeans.modules.j2ee.clientproject.SourceRoots;
56
import org.netbeans.spi.project.support.ant.AntProjectHelper;
56
import org.netbeans.spi.project.support.ant.AntProjectHelper;
57
import org.netbeans.spi.project.support.ant.PropertyEvaluator;
57
import org.netbeans.spi.project.support.ant.PropertyEvaluator;
58
import org.openide.util.Exceptions;
58
import org.openide.util.Exceptions;
(-)a/j2ee.clientproject/src/org/netbeans/modules/j2ee/clientproject/queries/AppClientProjectEncodingQueryImpl.java (-99 lines)
Lines 1-99 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 1997-2007 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
 * Contributor(s):
25
 *
26
 * The Original Software is NetBeans. The Initial Developer of the Original
27
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
28
 * Microsystems, Inc. All Rights Reserved.
29
 *
30
 * If you wish your version of this file to be governed by only the CDDL
31
 * or only the GPL Version 2, indicate your decision by adding
32
 * "[Contributor] elects to include this software in this distribution
33
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
34
 * single choice of license, a recipient has the option to distribute
35
 * your version of this file under either the CDDL, the GPL Version 2 or
36
 * to extend the choice of license to its licensees as provided above.
37
 * However, if you add GPL Version 2 code and therefore, elected the GPL
38
 * Version 2 license, then the option applies only if the new code is
39
 * made subject to such option by the copyright holder.
40
 */
41
42
package org.netbeans.modules.j2ee.clientproject.queries;
43
44
import java.beans.PropertyChangeEvent;
45
import java.beans.PropertyChangeListener;
46
import java.nio.charset.Charset;
47
import java.nio.charset.IllegalCharsetNameException;
48
import org.netbeans.modules.j2ee.clientproject.ui.customizer.AppClientProjectProperties;
49
import org.netbeans.spi.queries.FileEncodingQueryImplementation;
50
import org.netbeans.spi.project.support.ant.PropertyEvaluator;
51
import org.openide.filesystems.FileObject;
52
53
/**
54
 *
55
 * @author Tomas Zezula
56
 */
57
public class AppClientProjectEncodingQueryImpl extends FileEncodingQueryImplementation implements PropertyChangeListener {
58
59
60
    private final PropertyEvaluator eval;
61
    private Charset cache;
62
63
    /** Creates a new instance of J2SEProjectEncodingQueryImpl */
64
    public AppClientProjectEncodingQueryImpl(final PropertyEvaluator eval) {
65
        assert eval != null;
66
        this.eval = eval;
67
        this.eval.addPropertyChangeListener(this);
68
    }
69
70
    public Charset getEncoding(FileObject file) {
71
        assert file != null;
72
        synchronized (this) {
73
            if (cache != null) {
74
                return cache;
75
            }
76
        }
77
        String enc = eval.getProperty(AppClientProjectProperties.SOURCE_ENCODING);
78
        synchronized (this) {
79
            if (cache == null) {
80
                try {
81
                    cache = enc == null ? Charset.defaultCharset() : Charset.forName(enc);
82
                } catch (IllegalCharsetNameException exception) {
83
                    return null;
84
                }
85
            }
86
            return cache;
87
        }
88
    }
89
90
    public void propertyChange(PropertyChangeEvent event) {
91
        String propName = event.getPropertyName();
92
        if (propName == null || propName.equals(AppClientProjectProperties.SOURCE_ENCODING)) {
93
            synchronized (this) {
94
                cache = null;
95
            }
96
        }
97
    }
98
99
}
(-)a/j2ee.clientproject/src/org/netbeans/modules/j2ee/clientproject/queries/CompiledSourceForBinaryQuery.java (-185 lines)
Lines 1-185 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 1997-2007 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
 * Contributor(s):
25
 *
26
 * The Original Software is NetBeans. The Initial Developer of the Original
27
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
28
 * Microsystems, Inc. All Rights Reserved.
29
 *
30
 * If you wish your version of this file to be governed by only the CDDL
31
 * or only the GPL Version 2, indicate your decision by adding
32
 * "[Contributor] elects to include this software in this distribution
33
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
34
 * single choice of license, a recipient has the option to distribute
35
 * your version of this file under either the CDDL, the GPL Version 2 or
36
 * to extend the choice of license to its licensees as provided above.
37
 * However, if you add GPL Version 2 code and therefore, elected the GPL
38
 * Version 2 license, then the option applies only if the new code is
39
 * made subject to such option by the copyright holder.
40
 */
41
package org.netbeans.modules.j2ee.clientproject.queries;
42
43
import java.io.File;
44
import org.netbeans.spi.java.queries.SourceForBinaryQueryImplementation;
45
import org.netbeans.spi.project.support.ant.AntProjectHelper;
46
import org.openide.filesystems.FileObject;
47
import org.openide.filesystems.FileUtil;
48
49
import java.net.URL;
50
import java.net.MalformedURLException;
51
import java.beans.PropertyChangeListener;
52
import java.beans.PropertyChangeEvent;
53
import java.util.ArrayList;
54
import java.util.Iterator;
55
import java.util.Map;
56
import java.util.HashMap;
57
import javax.swing.event.ChangeListener;
58
import javax.swing.event.ChangeEvent;
59
60
import org.netbeans.api.java.queries.SourceForBinaryQuery;
61
import org.netbeans.spi.project.support.ant.PropertyEvaluator;
62
import org.netbeans.modules.j2ee.clientproject.SourceRoots;
63
import org.netbeans.modules.j2ee.clientproject.ui.customizer.AppClientProjectProperties;
64
import org.openide.util.Exceptions;
65
66
/**
67
 * Finds sources corresponding to binaries in a J2SE project.
68
 * @author Jesse Glick, Tomas Zezula
69
 */
70
public class CompiledSourceForBinaryQuery implements SourceForBinaryQueryImplementation {
71
72
    private final AntProjectHelper helper;
73
    private final PropertyEvaluator evaluator;
74
    private final SourceRoots sourceRoots;
75
    private final SourceRoots testRoots;
76
    private Map<URL,SourceForBinaryQuery.Result> cache = new HashMap<URL,SourceForBinaryQuery.Result>();
77
78
    public CompiledSourceForBinaryQuery(AntProjectHelper helper, PropertyEvaluator evaluator, SourceRoots srcRoots, SourceRoots testRoots) {
79
        this.helper = helper;
80
        this.evaluator = evaluator;
81
        this.sourceRoots = srcRoots;
82
        this.testRoots = testRoots;
83
    }
84
85
    public SourceForBinaryQuery.Result findSourceRoots(URL binaryRoot) {
86
        if (FileUtil.getArchiveFile(binaryRoot) != null) {
87
            binaryRoot = FileUtil.getArchiveFile(binaryRoot);
88
            // XXX check whether this is really the root
89
        }
90
        SourceForBinaryQuery.Result res = cache.get(binaryRoot);
91
        if (res != null) {
92
            return res;
93
        }
94
        SourceRoots src = null;
95
        if (hasSources(binaryRoot, AppClientProjectProperties.BUILD_CLASSES_DIR)) {
96
            src = this.sourceRoots;
97
        } else if (hasSources(binaryRoot, AppClientProjectProperties.DIST_JAR)) {
98
            src = this.sourceRoots;
99
        } else if (hasSources(binaryRoot, AppClientProjectProperties.BUILD_TEST_CLASSES_DIR)) {
100
            src = this.testRoots;
101
        }
102
        if (src == null) {
103
            return null;
104
        } else {
105
            res = new Result(src);
106
            cache.put(binaryRoot, res);
107
            return res;
108
        }
109
    }
110
111
112
    private boolean hasSources(URL binaryRoot, String binaryProperty) {
113
        try {
114
            String outDir = evaluator.getProperty(binaryProperty);
115
            if (outDir != null) {
116
                File f = helper.resolveFile(outDir);
117
                URL url = f.toURI().toURL();
118
                if (!f.exists() && !f.getPath().toLowerCase().endsWith(".jar")) { // NOI18N
119
                    // non-existing
120
                    assert !url.toExternalForm().endsWith("/") : f; // NOI18N
121
                    url = new URL(url.toExternalForm() + "/"); // NOI18N
122
                }
123
                if (url.equals(binaryRoot)) {
124
                    return true;
125
                }
126
            }
127
        } catch (MalformedURLException malformedURL) {
128
            Exceptions.printStackTrace(malformedURL);
129
        }
130
        return false;
131
    }
132
133
    private static class Result implements SourceForBinaryQuery.Result, PropertyChangeListener {
134
135
        private ArrayList<ChangeListener> listeners;
136
        private SourceRoots sourceRoots;
137
138
        public Result(SourceRoots sourceRoots) {
139
            this.sourceRoots = sourceRoots;
140
            this.sourceRoots.addPropertyChangeListener(this);
141
        }
142
143
        public FileObject[] getRoots() {
144
            return this.sourceRoots.getRoots(); //No need to cache it, SourceRoots does
145
        }
146
147
        public synchronized void addChangeListener(ChangeListener l) {
148
            if (this.listeners == null) {
149
                this.listeners = new ArrayList<ChangeListener>();
150
            }
151
            this.listeners.add(l);
152
        }
153
154
        public synchronized void removeChangeListener(ChangeListener l) {
155
            if (this.listeners == null) {
156
                return;
157
            }
158
            this.listeners.remove(l);
159
        }
160
161
        public void propertyChange(PropertyChangeEvent evt) {
162
            if (SourceRoots.PROP_ROOTS.equals(evt.getPropertyName())) {
163
                this.fireChange();
164
            }
165
        }
166
167
        private void fireChange() {
168
            Iterator<ChangeListener> it;
169
            synchronized (this) {
170
                if (this.listeners == null) {
171
                    return;
172
                }
173
                @SuppressWarnings("unchecked")
174
                ArrayList<ChangeListener> cloned = (ArrayList) this.listeners.clone();
175
                it = cloned.iterator();
176
            }
177
            ChangeEvent event = new ChangeEvent(this);
178
            while (it.hasNext()) {
179
                (it.next()).stateChanged(event);
180
            }
181
        }
182
183
    }
184
185
}
(-)a/j2ee.clientproject/src/org/netbeans/modules/j2ee/clientproject/queries/JavadocForBinaryQueryImpl.java (-206 lines)
Lines 1-206 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 1997-2007 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
 * Contributor(s):
25
 *
26
 * The Original Software is NetBeans. The Initial Developer of the Original
27
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
28
 * Microsystems, Inc. All Rights Reserved.
29
 *
30
 * If you wish your version of this file to be governed by only the CDDL
31
 * or only the GPL Version 2, indicate your decision by adding
32
 * "[Contributor] elects to include this software in this distribution
33
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
34
 * single choice of license, a recipient has the option to distribute
35
 * your version of this file under either the CDDL, the GPL Version 2 or
36
 * to extend the choice of license to its licensees as provided above.
37
 * However, if you add GPL Version 2 code and therefore, elected the GPL
38
 * Version 2 license, then the option applies only if the new code is
39
 * made subject to such option by the copyright holder.
40
 */
41
package org.netbeans.modules.j2ee.clientproject.queries;
42
43
import java.beans.PropertyChangeEvent;
44
import java.beans.PropertyChangeListener;
45
import java.io.File;
46
import java.util.ArrayList;
47
import java.util.List;
48
import javax.swing.event.ChangeEvent;
49
import org.netbeans.spi.project.support.ant.AntProjectHelper;
50
import org.openide.filesystems.FileUtil;
51
import java.net.URL;
52
import java.net.MalformedURLException;
53
import javax.swing.event.ChangeListener;
54
import org.netbeans.api.java.queries.JavadocForBinaryQuery;
55
import org.netbeans.modules.j2ee.clientproject.ui.customizer.AppClientProjectProperties;
56
import org.netbeans.spi.java.queries.JavadocForBinaryQueryImplementation;
57
import org.netbeans.spi.project.support.ant.PropertyEvaluator;
58
import org.openide.util.Exceptions;
59
import org.openide.util.WeakListeners;
60
61
/**
62
 * Finds Javadoc (if it is built) corresponding to binaries in J2SE project.
63
 * @author David Konecny, Jesse Glick
64
 */
65
public class JavadocForBinaryQueryImpl implements JavadocForBinaryQueryImplementation {
66
67
    private static final String PROP_JAVADOC_DIR = "dist.javadoc.dir";  //NOI18N
68
69
    private final AntProjectHelper helper;
70
    private final PropertyEvaluator evaluator;
71
72
    public JavadocForBinaryQueryImpl(AntProjectHelper helper, PropertyEvaluator evaluator) {
73
        this.helper = helper;
74
        this.evaluator = evaluator;
75
    }
76
77
    public JavadocForBinaryQuery.Result findJavadoc(final URL binaryRoot) {
78
79
        class R implements JavadocForBinaryQuery.Result, PropertyChangeListener  {
80
81
            private List<ChangeListener> listeners;
82
            private URL[] result;
83
84
            public R () {
85
                JavadocForBinaryQueryImpl.this.evaluator.addPropertyChangeListener (WeakListeners.propertyChange(this,JavadocForBinaryQueryImpl.this.evaluator));
86
            }
87
88
            public synchronized URL[] getRoots() {
89
                if (this.result == null) {
90
                    String javadocDir = evaluator.getProperty(AppClientProjectProperties.DIST_JAVADOC_DIR);
91
                    if (javadocDir != null) {
92
                        File f = helper.resolveFile(javadocDir);
93
                        try {
94
                            URL url = f.toURI().toURL();
95
                            if (!f.exists()) {
96
                                assert !url.toExternalForm().endsWith("/") : f; // NOI18N
97
                                url = new URL(url.toExternalForm() + "/"); // NOI18N
98
                            }
99
                            this.result = new URL[] {url};
100
                        } catch (MalformedURLException e) {
101
                            this.result = new URL[0];
102
                            Exceptions.printStackTrace(e);
103
                        }
104
                    }
105
                    else {
106
                        this.result = new URL[0];
107
                    }
108
                }
109
                return this.result;
110
            }
111
            public synchronized void addChangeListener(final ChangeListener l) {
112
                assert l != null;
113
                if (this.listeners == null) {
114
                    this.listeners = new ArrayList<ChangeListener>();
115
                }
116
                this.listeners.add (l);
117
            }
118
            public synchronized void removeChangeListener(final ChangeListener l) {
119
                assert l != null;
120
                if (this.listeners == null) {
121
                    return;
122
                }
123
                this.listeners.remove (l);
124
            }
125
126
            public void propertyChange (final PropertyChangeEvent event) {
127
                if (AppClientProjectProperties.DIST_JAVADOC_DIR.equals(event.getPropertyName())) {
128
                    synchronized (this) {
129
                        result = null;
130
                    }
131
                    this.fireChange ();
132
                }
133
            }
134
135
            private void fireChange () {
136
                ChangeListener[] _listeners;
137
                synchronized (this) {
138
                    if (this.listeners == null) {
139
                        return;
140
                    }
141
                    _listeners = this.listeners.toArray (new ChangeListener[this.listeners.size()]);
142
                }
143
                ChangeEvent event = new ChangeEvent (this);
144
                for (int i=0; i<_listeners.length; i++) {
145
                    _listeners[i].stateChanged(event);
146
                }
147
            }
148
        }
149
        if (isRootOwner(binaryRoot, AppClientProjectProperties.BUILD_CLASSES_DIR) || isRootOwner (binaryRoot, AppClientProjectProperties.DIST_JAR)) { //NOI18N
150
            return new R();
151
        }
152
        return null;
153
    }
154
155
    private boolean isRootOwner (URL binaryRoot, String binaryProperty) {
156
        try {
157
            if (FileUtil.getArchiveFile(binaryRoot) != null) {
158
                binaryRoot = FileUtil.getArchiveFile(binaryRoot);
159
                // XXX check whether this is really the root
160
            }
161
            String outDir = evaluator.getProperty(binaryProperty);
162
            if (outDir != null) {
163
                File f = helper.resolveFile (outDir);
164
                URL url = f.toURI().toURL();
165
                if (!f.exists() && !f.getPath().toLowerCase().endsWith(".jar")) { // NOI18N
166
                    assert !url.toExternalForm().endsWith("/") : f; // NOI18N
167
                    url = new URL(url.toExternalForm() + "/"); // NOI18N
168
                }
169
                return url.equals(binaryRoot) ||
170
                        binaryRoot.toExternalForm().startsWith(url.toExternalForm());
171
            }
172
        } catch (MalformedURLException malformedURL) {
173
            Exceptions.printStackTrace(malformedURL);
174
        }
175
        return false;
176
    }
177
178
//    private URL getJavadoc(URL binaryRoot, String binaryProperty, String javadocProperty) {
179
//        try {
180
//            if (FileUtil.getArchiveFile(binaryRoot) != null) {
181
//                binaryRoot = FileUtil.getArchiveFile(binaryRoot);
182
//            }
183
//            String outDir = evaluator.getProperty(binaryProperty);
184
//            if (outDir != null) {
185
//                File f = helper.resolveFile (outDir);
186
//                URL url = f.toURI().toURL();
187
//                if (!f.exists() && !f.getPath().toLowerCase().endsWith(".jar")) {
188
//                    assert !url.toExternalForm().endsWith("/") : f;
189
//                    url = new URL(url.toExternalForm() + "/");
190
//                }
191
//                if (url.equals(binaryRoot) ||
192
//                        binaryRoot.toExternalForm().startsWith(url.toExternalForm())) {
193
//                    String javadocDir = evaluator.getProperty(javadocProperty);
194
//                    if (javadocDir != null) {
195
//                        f = helper.resolveFile(javadocDir);
196
//                        return f.toURI().toURL();
197
//                    }
198
//                }
199
//            }
200
//        } catch (MalformedURLException malformedURL) {
201
//            ErrorManager.getDefault().notify(malformedURL);
202
//        }
203
//        return null;
204
//    }
205
206
}
(-)a/j2ee.clientproject/src/org/netbeans/modules/j2ee/clientproject/queries/SourceLevelQueryImpl.java (-84 lines)
Lines 1-84 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 1997-2007 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
 * Contributor(s):
25
 *
26
 * The Original Software is NetBeans. The Initial Developer of the Original
27
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
28
 * Microsystems, Inc. All Rights Reserved.
29
 *
30
 * If you wish your version of this file to be governed by only the CDDL
31
 * or only the GPL Version 2, indicate your decision by adding
32
 * "[Contributor] elects to include this software in this distribution
33
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
34
 * single choice of license, a recipient has the option to distribute
35
 * your version of this file under either the CDDL, the GPL Version 2 or
36
 * to extend the choice of license to its licensees as provided above.
37
 * However, if you add GPL Version 2 code and therefore, elected the GPL
38
 * Version 2 license, then the option applies only if the new code is
39
 * made subject to such option by the copyright holder.
40
 */
41
package org.netbeans.modules.j2ee.clientproject.queries;
42
43
import org.netbeans.modules.j2ee.clientproject.AppClientProjectUtil;
44
import org.netbeans.modules.j2ee.clientproject.ui.customizer.AppClientProjectProperties;
45
import org.netbeans.spi.java.queries.SourceLevelQueryImplementation;
46
import org.netbeans.spi.project.support.ant.PropertyEvaluator;
47
import org.netbeans.spi.project.support.ant.PropertyUtils;
48
import org.netbeans.spi.project.support.ant.EditableProperties;
49
import org.openide.filesystems.FileObject;
50
51
/**
52
 * Returns source level of project sources.
53
 * @author David Konecny
54
 */
55
public class SourceLevelQueryImpl implements SourceLevelQueryImplementation {
56
57
    private final PropertyEvaluator evaluator;
58
59
    public SourceLevelQueryImpl(PropertyEvaluator evaluator) {
60
        this.evaluator = evaluator;
61
    }
62
63
    public String getSourceLevel(FileObject javaFile) {
64
        final String activePlatform = evaluator.getProperty (AppClientProjectProperties.JAVA_PLATFORM);  //NOI18N
65
        if (AppClientProjectUtil.getActivePlatform(activePlatform) != null) {
66
            String sl = evaluator.getProperty("javac.source");  //NOI18N
67
            if (sl != null && sl.length() > 0) {
68
                return sl;
69
            } else {
70
                return null;
71
            }
72
        }
73
        else {
74
            EditableProperties props = PropertyUtils.getGlobalProperties();
75
            String sl = props.get("default.javac.source"); //NOI18N
76
            if (sl != null && sl.length() > 0) {
77
                return sl;
78
            } else {
79
                return null;
80
            }
81
        }
82
    }
83
84
}
(-)a/j2ee.clientproject/src/org/netbeans/modules/j2ee/clientproject/queries/UnitTestForSourceQueryImpl.java (-83 lines)
Lines 1-83 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 1997-2007 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
 * Contributor(s):
25
 *
26
 * The Original Software is NetBeans. The Initial Developer of the Original
27
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
28
 * Microsystems, Inc. All Rights Reserved.
29
 *
30
 * If you wish your version of this file to be governed by only the CDDL
31
 * or only the GPL Version 2, indicate your decision by adding
32
 * "[Contributor] elects to include this software in this distribution
33
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
34
 * single choice of license, a recipient has the option to distribute
35
 * your version of this file under either the CDDL, the GPL Version 2 or
36
 * to extend the choice of license to its licensees as provided above.
37
 * However, if you add GPL Version 2 code and therefore, elected the GPL
38
 * Version 2 license, then the option applies only if the new code is
39
 * made subject to such option by the copyright holder.
40
 */
41
42
package org.netbeans.modules.j2ee.clientproject.queries;
43
44
import java.net.URL;
45
import org.netbeans.api.project.FileOwnerQuery;
46
import org.netbeans.api.project.Project;
47
import org.netbeans.spi.java.queries.MultipleRootsUnitTestForSourceQueryImplementation;
48
import org.netbeans.modules.j2ee.clientproject.SourceRoots;
49
import org.openide.filesystems.FileObject;
50
51
public class UnitTestForSourceQueryImpl implements MultipleRootsUnitTestForSourceQueryImplementation {
52
53
    private final SourceRoots sourceRoots;
54
    private final SourceRoots testRoots;
55
56
    public UnitTestForSourceQueryImpl(SourceRoots sourceRoots, SourceRoots testRoots) {
57
        this.sourceRoots = sourceRoots;
58
        this.testRoots = testRoots;
59
    }
60
61
    public URL[] findUnitTests(FileObject source) {
62
        return find(source, sourceRoots, testRoots); // NOI18N
63
    }
64
65
    public URL[] findSources(FileObject unitTest) {
66
        return find(unitTest, testRoots, sourceRoots); // NOI18N
67
    }
68
69
    private URL[] find(FileObject file, SourceRoots from, SourceRoots to) {
70
        Project p = FileOwnerQuery.getOwner(file);
71
        if (p == null) {
72
            return null;
73
        }
74
        FileObject[] fromRoots = from.getRoots();
75
        for (int i = 0; i < fromRoots.length; i++) {
76
            if (fromRoots[i].equals(file)) {
77
                return to.getRootURLs();
78
            }
79
        }
80
        return null;
81
    }
82
83
}
(-)a/j2ee.clientproject/src/org/netbeans/modules/j2ee/clientproject/ui/ActionFilterNode.java (-1 / +1 lines)
Lines 65-72 import org.netbeans.api.java.queries.Jav Link Here
65
import org.netbeans.api.java.queries.JavadocForBinaryQuery;
65
import org.netbeans.api.java.queries.JavadocForBinaryQuery;
66
import org.netbeans.spi.project.support.ant.AntProjectHelper;
66
import org.netbeans.spi.project.support.ant.AntProjectHelper;
67
import org.netbeans.spi.project.support.ant.EditableProperties;
67
import org.netbeans.spi.project.support.ant.EditableProperties;
68
import org.netbeans.modules.j2ee.clientproject.UpdateHelper;
69
import org.netbeans.modules.j2ee.clientproject.ui.customizer.AppClientProjectProperties;
68
import org.netbeans.modules.j2ee.clientproject.ui.customizer.AppClientProjectProperties;
69
import org.netbeans.modules.java.api.common.ant.UpdateHelper;
70
import org.netbeans.spi.project.support.ant.PropertyEvaluator;
70
import org.netbeans.spi.project.support.ant.PropertyEvaluator;
71
import org.netbeans.spi.project.support.ant.ReferenceHelper;
71
import org.netbeans.spi.project.support.ant.ReferenceHelper;
72
import org.openide.nodes.FilterNode.Children;
72
import org.openide.nodes.FilterNode.Children;
(-)a/j2ee.clientproject/src/org/netbeans/modules/j2ee/clientproject/ui/AppClientLogicalViewProvider.java (-3 / +3 lines)
Lines 81-88 import org.netbeans.modules.j2ee.api.ejb Link Here
81
import org.netbeans.modules.j2ee.api.ejbjar.EjbProjectConstants;
81
import org.netbeans.modules.j2ee.api.ejbjar.EjbProjectConstants;
82
import org.netbeans.modules.j2ee.clientproject.AppClientProject;
82
import org.netbeans.modules.j2ee.clientproject.AppClientProject;
83
import org.netbeans.modules.j2ee.clientproject.AppClientProjectUtil;
83
import org.netbeans.modules.j2ee.clientproject.AppClientProjectUtil;
84
import org.netbeans.modules.j2ee.clientproject.SourceRoots;
85
import org.netbeans.modules.j2ee.clientproject.UpdateHelper;
86
import org.netbeans.modules.j2ee.clientproject.classpath.ClassPathSupport;
84
import org.netbeans.modules.j2ee.clientproject.classpath.ClassPathSupport;
87
import org.netbeans.modules.j2ee.clientproject.ui.customizer.AppClientProjectProperties;
85
import org.netbeans.modules.j2ee.clientproject.ui.customizer.AppClientProjectProperties;
88
import org.netbeans.modules.j2ee.clientproject.ui.customizer.CustomizerLibraries;
86
import org.netbeans.modules.j2ee.clientproject.ui.customizer.CustomizerLibraries;
Lines 95-100 import org.netbeans.modules.j2ee.deploym Link Here
95
import org.netbeans.modules.j2ee.deployment.devmodules.spi.InstanceListener;
93
import org.netbeans.modules.j2ee.deployment.devmodules.spi.InstanceListener;
96
import org.netbeans.modules.j2ee.deployment.devmodules.spi.J2eeModuleProvider;
94
import org.netbeans.modules.j2ee.deployment.devmodules.spi.J2eeModuleProvider;
97
import org.netbeans.modules.j2ee.spi.ejbjar.support.J2eeProjectView;
95
import org.netbeans.modules.j2ee.spi.ejbjar.support.J2eeProjectView;
96
import org.netbeans.modules.java.api.common.SourceRoots;
97
import org.netbeans.modules.java.api.common.ant.UpdateHelper;
98
import org.netbeans.modules.websvc.api.client.WebServicesClientSupport;
98
import org.netbeans.modules.websvc.api.client.WebServicesClientSupport;
99
import org.netbeans.modules.websvc.api.client.WebServicesClientView;
99
import org.netbeans.modules.websvc.api.client.WebServicesClientView;
100
import org.netbeans.modules.websvc.api.jaxws.client.JAXWSClientSupport;
100
import org.netbeans.modules.websvc.api.jaxws.client.JAXWSClientSupport;
Lines 632-638 public class AppClientLogicalViewProvide Link Here
632
            public void actionPerformed(ActionEvent e) {
632
            public void actionPerformed(ActionEvent e) {
633
                try {
633
                try {
634
                    helper.requestSave();
634
                    helper.requestUpdate();
635
                    BrokenReferencesSupport.showCustomizer(helper.getAntProjectHelper(), resolver, getBreakableProperties(), new String[] {AppClientProjectProperties.JAVA_PLATFORM});
635
                    BrokenReferencesSupport.showCustomizer(helper.getAntProjectHelper(), resolver, getBreakableProperties(), new String[] {AppClientProjectProperties.JAVA_PLATFORM});
636
                    run();
636
                    run();
637
                } catch (IOException ioe) {
637
                } catch (IOException ioe) {
(-)a/j2ee.clientproject/src/org/netbeans/modules/j2ee/clientproject/ui/LibrariesNode.java (-1 / +1 lines)
Lines 102-112 import org.netbeans.spi.project.support. Link Here
102
import org.netbeans.spi.project.support.ant.ReferenceHelper;
102
import org.netbeans.spi.project.support.ant.ReferenceHelper;
103
import org.netbeans.spi.java.project.support.ui.PackageView;
103
import org.netbeans.spi.java.project.support.ui.PackageView;
104
import org.netbeans.spi.java.classpath.support.ClassPathSupport;
104
import org.netbeans.spi.java.classpath.support.ClassPathSupport;
105
import org.netbeans.modules.j2ee.clientproject.UpdateHelper;
106
import org.netbeans.modules.j2ee.clientproject.classpath.AppClientProjectClassPathExtender;
105
import org.netbeans.modules.j2ee.clientproject.classpath.AppClientProjectClassPathExtender;
107
import org.netbeans.modules.j2ee.clientproject.ui.customizer.AntArtifactChooser;
106
import org.netbeans.modules.j2ee.clientproject.ui.customizer.AntArtifactChooser;
108
import org.netbeans.modules.j2ee.clientproject.ui.customizer.AppClientClassPathUi;
107
import org.netbeans.modules.j2ee.clientproject.ui.customizer.AppClientClassPathUi;
109
import org.netbeans.modules.j2ee.clientproject.ui.customizer.LibrariesChooser;
108
import org.netbeans.modules.j2ee.clientproject.ui.customizer.LibrariesChooser;
109
import org.netbeans.modules.java.api.common.ant.UpdateHelper;
110
import org.openide.util.Exceptions;
110
import org.openide.util.Exceptions;
(-)a/j2ee.clientproject/src/org/netbeans/modules/j2ee/clientproject/ui/ProjectNode.java (-1 / +1 lines)
Lines 81-88 import org.netbeans.spi.project.support. Link Here
81
import org.netbeans.spi.project.support.ant.EditableProperties;
81
import org.netbeans.spi.project.support.ant.EditableProperties;
82
import org.netbeans.spi.project.support.ant.AntProjectHelper;
82
import org.netbeans.spi.project.support.ant.AntProjectHelper;
83
import org.netbeans.spi.project.support.ant.ReferenceHelper;
83
import org.netbeans.spi.project.support.ant.ReferenceHelper;
84
import org.netbeans.modules.j2ee.clientproject.UpdateHelper;
85
import org.netbeans.modules.j2ee.clientproject.ui.customizer.AppClientProjectProperties;
84
import org.netbeans.modules.j2ee.clientproject.ui.customizer.AppClientProjectProperties;
85
import org.netbeans.modules.java.api.common.ant.UpdateHelper;
86
import org.netbeans.spi.project.support.ant.PropertyEvaluator;
86
import org.netbeans.spi.project.support.ant.PropertyEvaluator;
87
import org.openide.filesystems.FileObject;
87
import org.openide.filesystems.FileObject;
88
import org.openide.util.Exceptions;
88
import org.openide.util.Exceptions;
(-)a/j2ee.clientproject/src/org/netbeans/modules/j2ee/clientproject/ui/customizer/AppClientProjectProperties.java (-5 / +10 lines)
Lines 71-79 import org.netbeans.api.queries.Collocat Link Here
71
import org.netbeans.api.queries.CollocationQuery;
71
import org.netbeans.api.queries.CollocationQuery;
72
import org.netbeans.api.queries.FileEncodingQuery;
72
import org.netbeans.api.queries.FileEncodingQuery;
73
import org.netbeans.modules.j2ee.clientproject.AppClientProject;
73
import org.netbeans.modules.j2ee.clientproject.AppClientProject;
74
import org.netbeans.modules.j2ee.clientproject.AppClientProjectType;
74
import org.netbeans.modules.j2ee.clientproject.AppClientProjectUtil;
75
import org.netbeans.modules.j2ee.clientproject.AppClientProjectUtil;
75
import org.netbeans.modules.j2ee.clientproject.SourceRoots;
76
import org.netbeans.modules.j2ee.clientproject.UpdateHelper;
77
import org.netbeans.modules.j2ee.clientproject.Utils;
76
import org.netbeans.modules.j2ee.clientproject.Utils;
78
import org.netbeans.modules.j2ee.clientproject.classpath.ClassPathSupport;
77
import org.netbeans.modules.j2ee.clientproject.classpath.ClassPathSupport;
79
import org.netbeans.modules.j2ee.deployment.devmodules.api.AntDeploymentHelper;
78
import org.netbeans.modules.j2ee.deployment.devmodules.api.AntDeploymentHelper;
Lines 81-86 import org.netbeans.modules.j2ee.deploym Link Here
81
import org.netbeans.modules.j2ee.deployment.devmodules.api.J2eeModule;
80
import org.netbeans.modules.j2ee.deployment.devmodules.api.J2eeModule;
82
import org.netbeans.modules.j2ee.deployment.devmodules.api.J2eePlatform;
81
import org.netbeans.modules.j2ee.deployment.devmodules.api.J2eePlatform;
83
import org.netbeans.modules.j2ee.deployment.plugins.api.InstanceProperties;
82
import org.netbeans.modules.j2ee.deployment.plugins.api.InstanceProperties;
83
import org.netbeans.modules.java.api.common.SourceRoots;
84
import org.netbeans.modules.java.api.common.ant.UpdateHelper;
85
import org.netbeans.modules.java.api.common.ui.PlatformUiSupport;
84
import org.netbeans.modules.websvc.api.client.WebServicesClientConstants;
86
import org.netbeans.modules.websvc.api.client.WebServicesClientConstants;
85
import org.netbeans.spi.project.support.ant.AntProjectHelper;
87
import org.netbeans.spi.project.support.ant.AntProjectHelper;
86
import org.netbeans.spi.project.support.ant.EditableProperties;
88
import org.netbeans.spi.project.support.ant.EditableProperties;
Lines 94-100 import org.openide.filesystems.FileObjec Link Here
94
import org.openide.filesystems.FileObject;
96
import org.openide.filesystems.FileObject;
95
import org.openide.filesystems.FileUtil;
97
import org.openide.filesystems.FileUtil;
96
import org.openide.filesystems.URLMapper;
98
import org.openide.filesystems.URLMapper;
97
import org.openide.modules.SpecificationVersion;
98
import org.openide.util.Exceptions;
99
import org.openide.util.Exceptions;
99
import org.openide.util.Mutex;
100
import org.openide.util.Mutex;
100
import org.openide.util.MutexException;
101
import org.openide.util.MutexException;
Lines 339-345 public class AppClientProjectProperties Link Here
339
        RUN_TEST_CLASSPATH_MODEL = ClassPathUiSupport.createListModel( cs.itemsIterator(projectProperties.get( RUN_TEST_CLASSPATH ), null ) );
340
        RUN_TEST_CLASSPATH_MODEL = ClassPathUiSupport.createListModel( cs.itemsIterator(projectProperties.get( RUN_TEST_CLASSPATH ), null ) );
340
        PLATFORM_MODEL = PlatformUiSupport.createPlatformComboBoxModel (evaluator.getProperty(JAVA_PLATFORM));
341
        PLATFORM_MODEL = PlatformUiSupport.createPlatformComboBoxModel (evaluator.getProperty(JAVA_PLATFORM));
341
        PLATFORM_LIST_RENDERER = PlatformUiSupport.createPlatformListCellRenderer();
342
        PLATFORM_LIST_RENDERER = PlatformUiSupport.createPlatformListCellRenderer();
342
        JAVAC_SOURCE_MODEL = PlatformUiSupport.createSourceLevelComboBoxModel (PLATFORM_MODEL, evaluator.getProperty(JAVAC_SOURCE), evaluator.getProperty(JAVAC_TARGET), evaluator.getProperty(J2EE_PLATFORM));
343
        PlatformUiSupport.JDK minimalSourceLevel = null;
344
        if (evaluator.getProperty(J2EE_PLATFORM).equals(JAVA_EE_5)) {
345
            minimalSourceLevel = PlatformUiSupport.JDK.VERSION_5;
346
        }
347
        JAVAC_SOURCE_MODEL = PlatformUiSupport.createSourceLevelComboBoxModel(PLATFORM_MODEL, evaluator.getProperty(JAVAC_SOURCE), evaluator.getProperty(JAVAC_TARGET), minimalSourceLevel);
343
        JAVAC_SOURCE_RENDERER = PlatformUiSupport.createSourceLevelListCellRenderer ();
348
        JAVAC_SOURCE_RENDERER = PlatformUiSupport.createSourceLevelListCellRenderer ();
344
        // CustomizerCompile
349
        // CustomizerCompile
Lines 472-478 public class AppClientProjectProperties Link Here
472
        projectProperties.setProperty( RUN_TEST_CLASSPATH, run_test_cp );
477
        projectProperties.setProperty( RUN_TEST_CLASSPATH, run_test_cp );
473
        //Handle platform selection and javac.source javac.target properties
478
        //Handle platform selection and javac.source javac.target properties
474
        PlatformUiSupport.storePlatform (projectProperties, updateHelper,PLATFORM_MODEL.getSelectedItem(), JAVAC_SOURCE_MODEL.getSelectedItem());
479
        PlatformUiSupport.storePlatform (projectProperties, updateHelper, AppClientProjectType.PROJECT_CONFIGURATION_NAMESPACE, PLATFORM_MODEL.getSelectedItem(), JAVAC_SOURCE_MODEL.getSelectedItem());
475
        // Handle other special cases
480
        // Handle other special cases
476
        if ( NO_DEPENDENCIES_MODEL.isSelected() ) { // NOI18N
481
        if ( NO_DEPENDENCIES_MODEL.isSelected() ) { // NOI18N
(-)a/j2ee.clientproject/src/org/netbeans/modules/j2ee/clientproject/ui/customizer/AppClientSourceRootsUi.java (-1 / +1 lines)
Lines 83-89 import org.netbeans.api.project.FileOwne Link Here
83
import org.netbeans.api.project.FileOwnerQuery;
83
import org.netbeans.api.project.FileOwnerQuery;
84
import org.netbeans.api.project.Project;
84
import org.netbeans.api.project.Project;
85
import org.netbeans.api.project.ProjectInformation;
85
import org.netbeans.api.project.ProjectInformation;
86
import org.netbeans.modules.j2ee.clientproject.SourceRoots;
86
import org.netbeans.modules.java.api.common.SourceRoots;
87
import org.openide.DialogDisplayer;
87
import org.openide.DialogDisplayer;
88
import org.openide.DialogDescriptor;
88
import org.openide.DialogDescriptor;
89
import org.openide.filesystems.FileObject;
89
import org.openide.filesystems.FileObject;
(-)a/j2ee.clientproject/src/org/netbeans/modules/j2ee/clientproject/ui/customizer/CustomizerLibraries.java (+1 lines)
Lines 55-60 import org.netbeans.api.java.platform.Pl Link Here
55
import org.netbeans.api.java.platform.PlatformsCustomizer;
55
import org.netbeans.api.java.platform.PlatformsCustomizer;
56
import org.netbeans.modules.j2ee.clientproject.classpath.ClassPathSupport;
56
import org.netbeans.modules.j2ee.clientproject.classpath.ClassPathSupport;
57
import org.netbeans.modules.j2ee.clientproject.ui.AppClientLogicalViewProvider;
57
import org.netbeans.modules.j2ee.clientproject.ui.AppClientLogicalViewProvider;
58
import org.netbeans.modules.java.api.common.ui.PlatformUiSupport;
58
import org.openide.util.HelpCtx;
59
import org.openide.util.HelpCtx;
59
import org.openide.util.NbBundle;
60
import org.openide.util.NbBundle;
(-)a/j2ee.clientproject/src/org/netbeans/modules/j2ee/clientproject/ui/customizer/CustomizerProviderImpl.java (-2 / +1 lines)
Lines 50-59 import java.util.HashMap; Link Here
50
import java.util.HashMap;
50
import java.util.HashMap;
51
import java.util.Map;
51
import java.util.Map;
52
import org.netbeans.api.project.Project;
52
import org.netbeans.api.project.Project;
53
import org.netbeans.api.project.ProjectManager;
54
import org.netbeans.api.project.ProjectUtils;
53
import org.netbeans.api.project.ProjectUtils;
55
import org.netbeans.modules.j2ee.clientproject.AppClientProject;
54
import org.netbeans.modules.j2ee.clientproject.AppClientProject;
56
import org.netbeans.modules.j2ee.clientproject.UpdateHelper;
55
import org.netbeans.modules.java.api.common.ant.UpdateHelper;
57
import org.netbeans.spi.project.support.ant.GeneratedFilesHelper;
56
import org.netbeans.spi.project.support.ant.GeneratedFilesHelper;
58
import org.netbeans.spi.project.support.ant.PropertyEvaluator;
57
import org.netbeans.spi.project.support.ant.PropertyEvaluator;
59
import org.netbeans.spi.project.support.ant.ReferenceHelper;
58
import org.netbeans.spi.project.support.ant.ReferenceHelper;
(-)a/j2ee.clientproject/src/org/netbeans/modules/j2ee/clientproject/ui/customizer/CustomizerRun.form (-1 / +2 lines)
Lines 1-8 Link Here
1
<?xml version="1.0" encoding="UTF-8" ?>
1
<?xml version="1.0" encoding="UTF-8" ?>
2
<Form version="1.2" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
2
<Form version="1.2" maxVersion="1.2" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
3
  <AuxValues>
3
  <AuxValues>
4
    <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/>
4
    <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/>
5
    <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
5
    <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
6
    <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
6
    <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/>
7
    <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/>
7
    <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
8
    <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
(-)a/j2ee.clientproject/src/org/netbeans/modules/j2ee/clientproject/ui/customizer/CustomizerRun.java (-1 / +1 lines)
Lines 53-59 import javax.swing.event.ChangeEvent; Link Here
53
import javax.swing.event.ChangeEvent;
53
import javax.swing.event.ChangeEvent;
54
import javax.swing.event.ChangeListener;
54
import javax.swing.event.ChangeListener;
55
import org.netbeans.modules.j2ee.clientproject.AppClientProject;
55
import org.netbeans.modules.j2ee.clientproject.AppClientProject;
56
import org.netbeans.modules.j2ee.clientproject.SourceRoots;
56
import org.netbeans.modules.java.api.common.SourceRoots;
57
import org.openide.DialogDescriptor;
57
import org.openide.DialogDescriptor;
58
import org.openide.DialogDisplayer;
58
import org.openide.DialogDisplayer;
59
import org.openide.awt.MouseUtils;
59
import org.openide.awt.MouseUtils;
(-)a/j2ee.clientproject/src/org/netbeans/modules/j2ee/clientproject/ui/customizer/PlatformUiSupport.java (-705 lines)
Lines 1-705 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 1997-2007 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
 * Contributor(s):
25
 *
26
 * The Original Software is NetBeans. The Initial Developer of the Original
27
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
28
 * Microsystems, Inc. All Rights Reserved.
29
 *
30
 * If you wish your version of this file to be governed by only the CDDL
31
 * or only the GPL Version 2, indicate your decision by adding
32
 * "[Contributor] elects to include this software in this distribution
33
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
34
 * single choice of license, a recipient has the option to distribute
35
 * your version of this file under either the CDDL, the GPL Version 2 or
36
 * to extend the choice of license to its licensees as provided above.
37
 * However, if you add GPL Version 2 code and therefore, elected the GPL
38
 * Version 2 license, then the option applies only if the new code is
39
 * made subject to such option by the copyright holder.
40
 */
41
42
package org.netbeans.modules.j2ee.clientproject.ui.customizer;
43
44
import java.awt.Component;
45
import java.beans.PropertyChangeEvent;
46
import java.beans.PropertyChangeListener;
47
import java.text.MessageFormat;
48
import java.util.ArrayList;
49
import java.util.List;
50
import java.util.Set;
51
import java.util.TreeSet;
52
import java.util.logging.Level;
53
import java.util.logging.Logger;
54
import javax.swing.AbstractListModel;
55
import javax.swing.ComboBoxModel;
56
import javax.swing.JButton;
57
import javax.swing.JList;
58
import javax.swing.ListCellRenderer;
59
import javax.swing.event.ListDataEvent;
60
import javax.swing.event.ListDataListener;
61
import org.netbeans.api.java.platform.JavaPlatform;
62
import org.netbeans.api.java.platform.JavaPlatformManager;
63
import org.netbeans.api.java.platform.Specification;
64
import org.netbeans.modules.j2ee.clientproject.AppClientProjectType;
65
import org.netbeans.modules.j2ee.clientproject.UpdateHelper;
66
import org.netbeans.spi.project.support.ant.EditableProperties;
67
import org.openide.DialogDisplayer;
68
import org.openide.NotifyDescriptor;
69
import org.openide.awt.HtmlRenderer;
70
import org.openide.modules.SpecificationVersion;
71
import org.openide.util.NbBundle;
72
import org.openide.util.WeakListeners;
73
import org.w3c.dom.Element;
74
import org.w3c.dom.NodeList;
75
76
/**
77
 * Support class for {@link JavaPlatform} manipulation in j2seproject customizer.
78
 * @author tzezula
79
 */
80
public class PlatformUiSupport {
81
82
    private static final SpecificationVersion JDK_5 = new SpecificationVersion ("1.5");  //NOI18N
83
    private static final SpecificationVersion JDK_6 = new SpecificationVersion ("1.6");  //NOI18N
84
    private static final Logger LOGGER = Logger.getLogger(PlatformUiSupport.class.getName());
85
86
    private PlatformUiSupport() {
87
    }
88
89
    /**
90
     * Creates {@link ComboBoxModel} of J2SE platforms.
91
     * The model listens on the {@link JavaPlatformManager} and update its
92
     * state according to changes
93
     * @param activePlatform the active project's platform
94
     * @return {@link ComboBoxModel}
95
     */
96
    public static ComboBoxModel createPlatformComboBoxModel(String activePlatform) {
97
        return new PlatformComboBoxModel(activePlatform);
98
    }
99
100
101
    /**
102
     * Creates a {@link ListCellRenderer} for rendering items of the {@link ComboBoxModel}
103
     * created by the {@link PlatformUiSupport#createPlatformComboBoxModel} method.
104
     * @return {@link ListCellRenderer}
105
     */
106
    public static ListCellRenderer createPlatformListCellRenderer() {
107
        return new PlatformListCellRenderer();
108
    }
109
110
    /**
111
     * Like {@link #storePlatform}, but platformName may be null (in which case the default platform is used)
112
     */
113
    public static void storePlatform(EditableProperties props, UpdateHelper helper, String platformName, SpecificationVersion sourceLevel) {
114
        PlatformKey platformKey;
115
        if (platformName != null) {
116
            platformKey = new PlatformKey(PlatformUiSupport.findPlatform(platformName));
117
        } else {
118
            platformKey = new PlatformKey(JavaPlatformManager.getDefault().getDefaultPlatform());
119
        }
120
        storePlatform(props, helper, platformKey, new SourceLevelKey(sourceLevel));
121
    }
122
123
    public static JavaPlatform findPlatform(String displayName) {
124
        JavaPlatform[] platforms = JavaPlatformManager.getDefault().getPlatforms(displayName, new Specification("j2se", null)); //NOI18N
125
        return platforms.length == 0 ? null : platforms[0];
126
    }
127
128
    /**
129
     * Stores active platform, javac.source and javac.target into the project's metadata
130
     * @param props project's shared properties
131
     * @param helper to read/update project.xml
132
     * @param platformKey the PatformKey got from the platform model
133
     * @param sourceLevel source level
134
     */
135
    public static void storePlatform(EditableProperties props, UpdateHelper helper, Object platformKey, Object sourceLevelKey) {
136
        assert platformKey instanceof PlatformKey;
137
        PlatformKey pk = (PlatformKey) platformKey;
138
        JavaPlatform platform = getPlatform(pk);
139
        //null means active broken (unresolved) platform, no need to do anything
140
        if (platform != null) {
141
            SpecificationVersion jdk13 = new SpecificationVersion("1.3");  //NOI18N
142
            String platformAntName = platform.getProperties().get("platform.ant.name");    //NOI18N
143
            assert platformAntName != null;
144
            props.put(AppClientProjectProperties.JAVA_PLATFORM, platformAntName);
145
            Element root = helper.getPrimaryConfigurationData(true);
146
            boolean defaultPlatform = pk.isDefaultPlatform();
147
            boolean changed = false;
148
            NodeList explicitPlatformNodes = root.getElementsByTagNameNS(AppClientProjectType.PROJECT_CONFIGURATION_NAMESPACE,"explicit-platform");   //NOI18N
149
            if (defaultPlatform) {
150
                if (explicitPlatformNodes.getLength()==1) {
151
                    root.removeChild(explicitPlatformNodes.item(0));
152
                    changed = true;
153
                }
154
            } else {
155
                Element explicitPlatform;
156
                switch (explicitPlatformNodes.getLength()) {
157
                    case 0:
158
                        explicitPlatform = root.getOwnerDocument().createElementNS(AppClientProjectType.PROJECT_CONFIGURATION_NAMESPACE, "explicit-platform"); //NOI18N
159
                        NodeList sourceRootNodes = root.getElementsByTagNameNS(AppClientProjectType.PROJECT_CONFIGURATION_NAMESPACE,"source-roots");   //NOI18N
160
                        assert sourceRootNodes.getLength() == 1 : "Broken project.xml file"; //NOI18N
161
                        root.insertBefore(explicitPlatform, sourceRootNodes.item(0));
162
                        changed = true;
163
                        break;
164
                    case 1:
165
                        explicitPlatform = (Element)explicitPlatformNodes.item(0);
166
                        break;
167
                    default:
168
                        throw new AssertionError("Broken project.xml file");   //NOI18N
169
                }
170
                String explicitSourceAttrValue = explicitPlatform.getAttribute("explicit-source-supported");    //NOI18N
171
                if (jdk13.compareTo(platform.getSpecification().getVersion())>=0 &&
172
                        !"false".equals(explicitSourceAttrValue)) {   //NOI18N
173
                    explicitPlatform.setAttribute("explicit-source-supported","false"); //NOI18N
174
                    changed = true;
175
                } else if (jdk13.compareTo(platform.getSpecification().getVersion())<0 &&
176
                        !"true".equals(explicitSourceAttrValue)) {  //NOI18N
177
                    explicitPlatform.setAttribute("explicit-source-supported","true"); //NOI18N
178
                    changed = true;
179
                }
180
            }
181
182
            SpecificationVersion sourceLevel;
183
            if (sourceLevelKey == null) {
184
                sourceLevel = platform.getSpecification().getVersion();
185
            }
186
            else {
187
                assert sourceLevelKey instanceof SourceLevelKey;
188
                sourceLevel = ((SourceLevelKey)sourceLevelKey).getSourceLevel();
189
            }
190
            String javacSource = sourceLevel.toString();
191
            String javacTarget = javacSource;
192
193
            //Issue #116490
194
            // Customizer value | -source | -target
195
            // JDK 1.2            1.2        1.1
196
            // JDK 1.3            1.3        1.1
197
            // JDK 1.4            1.4        1.4
198
            // JDK 5              1.5        1.5
199
            // JDK 6              1.5        1.6
200
            // JDK 7              1.7        1.7  - should bring a new language features
201
            if (jdk13.compareTo(sourceLevel)>=0) {
202
                javacTarget = "1.1";        //NOI18N
203
            }
204
            else if (JDK_6.equals(sourceLevel)) {
205
                javacSource = JDK_5.toString();        //NOI18N
206
            }
207
208
            // #89131: these levels are not actually distinct from 1.5.
209
            if (javacSource.equals("1.6") || javacSource.equals("1.7")) {
210
                javacSource = "1.5";
211
            }
212
            if (!javacSource.equals(props.getProperty(AppClientProjectProperties.JAVAC_SOURCE))) {
213
                props.setProperty(AppClientProjectProperties.JAVAC_SOURCE, javacSource);
214
            }
215
            if (!javacTarget.equals(props.getProperty(AppClientProjectProperties.JAVAC_TARGET))) {
216
                props.setProperty(AppClientProjectProperties.JAVAC_TARGET, javacTarget);
217
            }
218
219
            if (changed) {
220
                helper.putPrimaryConfigurationData(root, true);
221
            }
222
        }
223
    }
224
225
226
    /**
227
     * Returns a {@link JavaPlatform} for an item obtained from the ComboBoxModel created by
228
     * the {@link PlatformUiSupport#createComboBoxModel} method
229
     * @param platformKey an item obtained from ComboBoxModel created by {@link PlatformUiSupport#createComboBoxModel}
230
     * @return JavaPlatform or null in case when platform is broken
231
     * @exception {@link IllegalArgumentException} is thrown in case when parameter in not an object created by
232
     * platform combobox model.
233
     */
234
    public static JavaPlatform getPlatform(Object platformKey) {
235
        if (platformKey instanceof PlatformKey) {
236
            return getPlatform((PlatformKey)platformKey);
237
        } else {
238
            throw new IllegalArgumentException();
239
        }
240
    }
241
242
    /**
243
     * Creates {@link ComboBoxModel} of source levels for active platform.
244
     * The model listens on the platform's {@link ComboBoxModel} and update its
245
     * state according to changes
246
     * @param platformComboBoxModel the platform's model used for listenning
247
     * @param initialSourceLevel initial source level value
248
     * @param initialTargetLevel initial target level value
249
     * @return {@link ComboBoxModel} of {@link SpecificationVersion}
250
     */
251
    public static ComboBoxModel createSourceLevelComboBoxModel(ComboBoxModel platformComboBoxModel, String initialSourceLevel, String initialTargetLevel, String j2eePlatform) {
252
        return new SourceLevelComboBoxModel(platformComboBoxModel, initialSourceLevel, initialTargetLevel, j2eePlatform);
253
    }
254
255
    public static ListCellRenderer createSourceLevelListCellRenderer() {
256
        return new SourceLevelListCellRenderer();
257
    }
258
259
260
    private static JavaPlatform getPlatform(PlatformKey platformKey) {
261
        return platformKey.platform;
262
    }
263
264
265
    /**
266
     * This class represents a  JavaPlatform in the {@link ListModel}
267
     * created by the {@link PlatformUiSupport#createPlatformComboBoxModel}
268
     * method.
269
     */
270
    private static class PlatformKey implements Comparable {
271
272
        private String name;
273
        private JavaPlatform platform;
274
275
        /**
276
         * Creates a PlatformKey for a broken platform
277
         * @param name the ant name of the broken platform
278
         */
279
        public PlatformKey(String name) {
280
            assert name != null;
281
            this.name = name;
282
        }
283
284
        /**
285
         * Creates a PlatformKey for a platform
286
         * @param platform the {@link JavaPlatform}
287
         */
288
        public PlatformKey(JavaPlatform platform) {
289
            assert platform != null;
290
            this.platform = platform;
291
        }
292
293
        public int compareTo(Object o) {
294
            return this.getDisplayName().compareTo(((PlatformKey)o).getDisplayName());
295
        }
296
297
        @Override
298
        public boolean equals(Object other) {
299
            if (other instanceof PlatformKey) {
300
                PlatformKey otherKey = (PlatformKey)other;
301
                return (this.platform == null ? otherKey.platform == null : this.platform.equals(otherKey.platform)) &&
302
                        otherKey.getDisplayName().equals(this.getDisplayName());
303
            } else {
304
                return false;
305
            }
306
        }
307
308
        @Override
309
        public int hashCode() {
310
            return getDisplayName().hashCode();
311
        }
312
313
        @Override
314
        public String toString() {
315
            return getDisplayName();
316
        }
317
318
        public synchronized String getDisplayName() {
319
            if (this.name == null) {
320
                this.name = this.platform.getDisplayName();
321
            }
322
            return this.name;
323
        }
324
325
        public boolean isDefaultPlatform() {
326
            if (this.platform == null) {
327
                return false;
328
            }
329
            return this.platform.equals(JavaPlatformManager.getDefault().getDefaultPlatform());
330
        }
331
332
        public boolean isBroken() {
333
            return this.platform == null;
334
        }
335
336
    }
337
338
    private static final class SourceLevelKey implements Comparable {
339
340
        final SpecificationVersion sourceLevel;
341
        final boolean broken;
342
343
        public SourceLevelKey(final SpecificationVersion sourceLevel) {
344
            this(sourceLevel, false);
345
        }
346
347
        public SourceLevelKey(final SpecificationVersion sourceLevel, final boolean broken) {
348
            assert sourceLevel != null : "Source level cannot be null";     //NOI18N
349
            this.sourceLevel = sourceLevel;
350
            this.broken = broken;
351
        }
352
353
        public SpecificationVersion getSourceLevel() {
354
            return this.sourceLevel;
355
        }
356
357
        public boolean isBroken() {
358
            return this.broken;
359
        }
360
361
        public int compareTo(final Object other) {
362
            assert other instanceof SourceLevelKey : "Illegal argument of SourceLevelKey.compareTo()";  //NOI18N
363
            SourceLevelKey otherKey = (SourceLevelKey) other;
364
            return this.sourceLevel.compareTo(otherKey.sourceLevel);
365
        }
366
367
        @Override
368
        public boolean equals(final Object other) {
369
            return (other instanceof SourceLevelKey) &&
370
                    ((SourceLevelKey)other).sourceLevel.equals(this.sourceLevel);
371
        }
372
373
        @Override
374
        public int hashCode() {
375
            return this.sourceLevel.hashCode();
376
        }
377
378
        @Override
379
        public String toString() {
380
            StringBuffer buffer = new StringBuffer();
381
            if (this.broken) {
382
                buffer.append("Broken: ");      //NOI18N
383
            }
384
            buffer.append(this.sourceLevel.toString());
385
            return buffer.toString();
386
        }
387
388
        public String getDisplayName () {
389
            String _tmp = sourceLevel.toString();
390
            if (JDK_5.compareTo(sourceLevel)<=0) {
391
                _tmp = _tmp.replaceFirst("^1\\.([5-9]|\\d\\d+)$", "$1");        //NOI18N
392
            }
393
            return NbBundle.getMessage(PlatformUiSupport.class, "LBL_JDK",_tmp);
394
        }
395
396
    }
397
398
    private static class PlatformComboBoxModel extends AbstractListModel implements ComboBoxModel, PropertyChangeListener {
399
        private static final long serialVersionUID = 1L;
400
401
        private final JavaPlatformManager pm;
402
        private PlatformKey[] platformNamesCache;
403
        private String initialPlatform;
404
        private PlatformKey selectedPlatform;
405
406
        public PlatformComboBoxModel(String initialPlatform) {
407
            this.pm = JavaPlatformManager.getDefault();
408
            this.pm.addPropertyChangeListener(WeakListeners.propertyChange(this, this.pm));
409
            this.initialPlatform = initialPlatform;
410
        }
411
412
        public int getSize() {
413
            PlatformKey[] platformNames = getPlatformNames();
414
            return platformNames.length;
415
        }
416
417
        public Object getElementAt(int index) {
418
            PlatformKey[] platformNames = getPlatformNames();
419
            assert index >=0 && index< platformNames.length;
420
            return platformNames[index];
421
        }
422
423
        public Object getSelectedItem() {
424
            this.getPlatformNames(); //Force setting of selectedPlatform if it is not alredy done
425
            return this.selectedPlatform;
426
        }
427
428
        public void setSelectedItem(Object obj) {
429
            this.selectedPlatform = (PlatformKey) obj;
430
            this.fireContentsChanged(this, -1, -1);
431
        }
432
433
        public void propertyChange(PropertyChangeEvent event) {
434
            if (JavaPlatformManager.PROP_INSTALLED_PLATFORMS.equals(event.getPropertyName())) {
435
                synchronized (this) {
436
                    this.platformNamesCache = null;
437
                }
438
                this.fireContentsChanged(this, -1, -1);
439
            }
440
        }
441
442
        private synchronized PlatformKey[] getPlatformNames() {
443
            if (this.platformNamesCache == null) {
444
                JavaPlatform[] platforms = pm.getPlatforms(null, new Specification("j2se",null));    //NOI18N
445
                Set<PlatformKey> orderedNames = new TreeSet<PlatformKey>();
446
                boolean activeFound = false;
447
                for (int i=0; i< platforms.length; i++) {
448
                    if (platforms[i].getInstallFolders().size()>0) {
449
                        PlatformKey pk = new PlatformKey(platforms[i]);
450
                        orderedNames.add(pk);
451
                        if (!activeFound && initialPlatform != null) {
452
                            String antName = platforms[i].getProperties().get("platform.ant.name");    //NOI18N
453
                            if (initialPlatform.equals(antName)) {
454
                                if (this.selectedPlatform == null) {
455
                                    this.selectedPlatform = pk;
456
                                    initialPlatform = null;
457
                                }
458
                                activeFound = true;
459
                            }
460
                        }
461
                    }
462
                }
463
                if (!activeFound) {
464
                    if (initialPlatform == null) {
465
                        if (this.selectedPlatform == null || !orderedNames.contains(this.selectedPlatform)) {
466
                            this.selectedPlatform = new PlatformKey(JavaPlatformManager.getDefault().getDefaultPlatform());
467
                        }
468
                    } else {
469
                        PlatformKey pk = new PlatformKey(this.initialPlatform);
470
                        orderedNames.add(pk);
471
                        if (this.selectedPlatform == null) {
472
                            this.selectedPlatform = pk;
473
                        }
474
                    }
475
                }
476
                this.platformNamesCache = orderedNames.toArray(new PlatformKey[orderedNames.size()]);
477
            }
478
            return this.platformNamesCache;
479
        }
480
481
    }
482
483
    private static class PlatformListCellRenderer implements ListCellRenderer {
484
485
        private final ListCellRenderer delegate;
486
487
        public PlatformListCellRenderer() {
488
            this.delegate = HtmlRenderer.createRenderer();
489
        }
490
491
        public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
492
            String name;
493
            if (value == null) {
494
                name = "";  //NOI18N
495
            } else {
496
                assert value instanceof PlatformKey : "Wrong model";  //NOI18N
497
                PlatformKey key = (PlatformKey) value;
498
                if (key.isBroken()) {
499
                    name = "<html><font color=\"#A40000\">" +    //NOI18N
500
                            NbBundle.getMessage(PlatformUiSupport.class,"TXT_BrokenPlatformFmt", key.getDisplayName());
501
                } else {
502
                    name = key.getDisplayName();
503
                }
504
            }
505
            return this.delegate.getListCellRendererComponent(list, name, index, isSelected, cellHasFocus);
506
        }
507
    }
508
509
    private static class SourceLevelComboBoxModel extends AbstractListModel implements ComboBoxModel, ListDataListener {
510
        private static final long serialVersionUID = 1L;
511
512
        private static final String VERSION_PREFIX = "1.";      //The version prefix // NOI18N
513
        private static final int INITIAL_VERSION_MINOR = 2;     //1.2
514
        // if project is JAVA EE 5 show only 1.5 and higher
515
        private static final int INITIAL_VERSION_MINOR_JAVA_EE_5 = 5;     // 1.5
516
517
        private SpecificationVersion selectedSourceLevel;
518
        private SpecificationVersion originalSourceLevel;
519
        private SourceLevelKey[] sourceLevelCache;
520
        private final ComboBoxModel platformComboBoxModel;
521
        private PlatformKey activePlatform;
522
        private String j2eePlatform = null;
523
524
        public SourceLevelComboBoxModel(ComboBoxModel platformComboBoxModel, String initialSourceLevel, String initialTargetLevel) {
525
            this.platformComboBoxModel = platformComboBoxModel;
526
            this.activePlatform = (PlatformKey) this.platformComboBoxModel.getSelectedItem();
527
            this.platformComboBoxModel.addListDataListener(this);
528
            if (initialSourceLevel != null && initialSourceLevel.length()>0) {
529
                try {
530
                    originalSourceLevel = new SpecificationVersion (initialSourceLevel);
531
                } catch (NumberFormatException nfe) {
532
                    // If the javac.source has invalid value, do not preselect and log it.
533
                    LOGGER.log(Level.INFO, "Invalid javac.source: " + initialSourceLevel);
534
                }
535
            }
536
            if (initialTargetLevel != null && initialTargetLevel.length() > 0) {
537
                try {
538
                    SpecificationVersion originalTargetLevel = new SpecificationVersion (initialTargetLevel);
539
                    if (this.originalSourceLevel == null || this.originalSourceLevel.compareTo(originalTargetLevel)<0) {
540
                        this.originalSourceLevel = originalTargetLevel;
541
                    }
542
                } catch (NumberFormatException nfe) {
543
                    //If the javac.target has invalid value, do not preselect and log it
544
                    LOGGER.warning("Invalid javac.target: "+initialTargetLevel);       //NOI18N
545
                }
546
            }
547
            this.selectedSourceLevel = this.originalSourceLevel;
548
        }
549
550
        public SourceLevelComboBoxModel(ComboBoxModel platformComboBoxModel, String initialSourceLevel, String initialTargetLevel, String j2eePlatform) {
551
            this(platformComboBoxModel, initialSourceLevel, initialTargetLevel);
552
            this.j2eePlatform = j2eePlatform;
553
        }
554
555
        public int getSize() {
556
            SourceLevelKey[] sLevels = getSourceLevels();
557
            return sLevels.length;
558
        }
559
560
        public Object getElementAt(int index) {
561
            SourceLevelKey[] sLevels = getSourceLevels();
562
            assert index >=0 && index< sLevels.length;
563
            return sLevels[index];
564
        }
565
566
        public Object getSelectedItem () {
567
            SourceLevelKey[] keys = getSourceLevels();
568
            for (int i=0; i<keys.length; i++) {
569
                if (keys[i].getSourceLevel().equals(this.selectedSourceLevel)) {
570
                    return keys[i];
571
                }
572
            }
573
            return null;
574
        }
575
576
        public void setSelectedItem (Object obj) {
577
            this.selectedSourceLevel = (obj == null ? null : ((SourceLevelKey) obj).getSourceLevel());
578
            this.fireContentsChanged(this, -1, -1);
579
        }
580
581
        public void intervalAdded(ListDataEvent e) {
582
        }
583
584
        public void intervalRemoved(ListDataEvent e) {
585
        }
586
587
        public void contentsChanged(ListDataEvent e) {
588
            PlatformKey selectedPlatform = (PlatformKey) this.platformComboBoxModel.getSelectedItem();
589
            JavaPlatform platform = getPlatform(selectedPlatform);
590
            if (platform != null) {
591
                SpecificationVersion version = platform.getSpecification().getVersion();
592
                if (this.selectedSourceLevel != null && this.selectedSourceLevel.compareTo(version)>0 &&
593
                        !shouldChangePlatform(selectedSourceLevel, version)) {
594
                    //Restore original
595
                    this.platformComboBoxModel.setSelectedItem(this.activePlatform);
596
                    return;
597
                }
598
                else {
599
                    this.originalSourceLevel = null;
600
                }
601
            }
602
            this.activePlatform = selectedPlatform;
603
            resetCache();
604
        }
605
606
        private void resetCache() {
607
            synchronized (this) {
608
                this.sourceLevelCache = null;
609
            }
610
            this.fireContentsChanged(this, -1, -1);
611
        }
612
613
        private SourceLevelKey[] getSourceLevels() {
614
            if (this.sourceLevelCache == null) {
615
                PlatformKey selectedPlatform = (PlatformKey) this.platformComboBoxModel.getSelectedItem();
616
                JavaPlatform platform = getPlatform(selectedPlatform);
617
                List<SourceLevelKey> sLevels = new ArrayList<SourceLevelKey>();
618
                //If platform == null broken platform, the source level range is unknown
619
                //The source level combo box should be empty and disabled
620
                boolean selSourceLevelValid = false;
621
                if (platform != null) {
622
                    SpecificationVersion version = platform.getSpecification().getVersion();
623
                    int index = INITIAL_VERSION_MINOR;
624
                    // #71619 - source level lower than 1.5 won't be shown for Java EE 5 project
625
                    if (j2eePlatform != null && j2eePlatform.equals(AppClientProjectProperties.JAVA_EE_5)) {
626
                        index = INITIAL_VERSION_MINOR_JAVA_EE_5;
627
                    }
628
                    SpecificationVersion template = new SpecificationVersion (VERSION_PREFIX + Integer.toString (index++));
629
                    boolean origSourceLevelValid = false;
630
631
                    while (template.compareTo(version)<=0) {
632
                        if (template.equals(this.originalSourceLevel)) {
633
                            origSourceLevelValid = true;
634
                        }
635
                        if (template.equals(this.selectedSourceLevel)) {
636
                            selSourceLevelValid = true;
637
                        }
638
                        sLevels.add (new SourceLevelKey (template));
639
                        template = new SpecificationVersion (VERSION_PREFIX + Integer.toString (index++));
640
                    }
641
                    if (this.originalSourceLevel != null && !origSourceLevelValid) {
642
                        if (originalSourceLevel.equals(this.selectedSourceLevel)) {
643
                            selSourceLevelValid = true;
644
                        }
645
                        sLevels.add (new SourceLevelKey(this.originalSourceLevel,true));
646
                    }
647
                }
648
                this.sourceLevelCache = sLevels.toArray(new SourceLevelKey[sLevels.size()]);
649
                if (!selSourceLevelValid) {
650
                    this.selectedSourceLevel = this.sourceLevelCache.length == 0 ?
651
                        null : this.sourceLevelCache[this.sourceLevelCache.length-1].getSourceLevel();
652
                }
653
            }
654
            return this.sourceLevelCache;
655
        }
656
657
        private static boolean shouldChangePlatform(SpecificationVersion selectedSourceLevel, SpecificationVersion platformSourceLevel) {
658
            JButton changeOption = new JButton(NbBundle.getMessage(PlatformUiSupport.class, "CTL_ChangePlatform"));
659
            changeOption.getAccessibleContext().setAccessibleDescription(NbBundle.getMessage(PlatformUiSupport.class, "AD_ChangePlatform"));
660
            String message = MessageFormat.format(NbBundle.getMessage(PlatformUiSupport.class,"TXT_ChangePlatform"),new Object[] {
661
                selectedSourceLevel.toString(),
662
                platformSourceLevel.toString(),
663
            });
664
            return DialogDisplayer.getDefault().notify(
665
                    new NotifyDescriptor(message,
666
                    NbBundle.getMessage(PlatformUiSupport.class,"TXT_ChangePlatformTitle"),
667
                    NotifyDescriptor.DEFAULT_OPTION,
668
                    NotifyDescriptor.WARNING_MESSAGE,
669
                    new Object[] {
670
                changeOption,
671
                NotifyDescriptor.CANCEL_OPTION
672
            },
673
                    changeOption)) == changeOption;
674
        }
675
    }
676
677
    private static class SourceLevelListCellRenderer implements ListCellRenderer {
678
679
        ListCellRenderer delegate;
680
681
        public SourceLevelListCellRenderer() {
682
            this.delegate = HtmlRenderer.createRenderer();
683
        }
684
685
        public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
686
            String message;
687
            if (value == null) {
688
                message = "";   //NOI18N
689
            }
690
            else {
691
                assert value instanceof SourceLevelKey;
692
                SourceLevelKey key = (SourceLevelKey) value;
693
                if (key.isBroken()) {
694
                    message = "<html><font color=\"#A40000\">" +    //NOI18N
695
                        NbBundle.getMessage(PlatformUiSupport.class,"TXT_InvalidSourceLevel",key.getDisplayName());
696
                }
697
                else {
698
                    message = key.getDisplayName();
699
                }
700
            }
701
            return this.delegate.getListCellRendererComponent(list, message, index, isSelected, cellHasFocus);
702
        }
703
    }
704
705
}
(-)a/j2ee.ejbjarproject/nbproject/project.xml (+9 lines)
Lines 195-200 made subject to such option by the copyr Link Here
195
                    <run-dependency>
195
                    <run-dependency>
196
                        <release-version>4</release-version>
196
                        <release-version>4</release-version>
197
                        <specification-version>1.29</specification-version>
197
                        <specification-version>1.29</specification-version>
198
                    </run-dependency>
199
                </dependency>
200
                <dependency>
201
                    <code-name-base>org.netbeans.modules.java.api.common</code-name-base>
202
                    <build-prerequisite/>
203
                    <compile-dependency/>
204
                    <run-dependency>
205
                        <release-version>0-1</release-version>
206
                        <specification-version>1.0</specification-version>
198
                    </run-dependency>
207
                    </run-dependency>
199
                </dependency>
208
                </dependency>
200
                <dependency>
209
                <dependency>
(-)a/j2ee.ejbjarproject/src/org/netbeans/modules/j2ee/ejbjarproject/EjbJarFileBuiltQuery.java (-100 lines)
Lines 1-100 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 1997-2007 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
 * Contributor(s):
25
 *
26
 * The Original Software is NetBeans. The Initial Developer of the Original
27
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
28
 * Microsystems, Inc. All Rights Reserved.
29
 *
30
 * If you wish your version of this file to be governed by only the CDDL
31
 * or only the GPL Version 2, indicate your decision by adding
32
 * "[Contributor] elects to include this software in this distribution
33
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
34
 * single choice of license, a recipient has the option to distribute
35
 * your version of this file under either the CDDL, the GPL Version 2 or
36
 * to extend the choice of license to its licensees as provided above.
37
 * However, if you add GPL Version 2 code and therefore, elected the GPL
38
 * Version 2 license, then the option applies only if the new code is
39
 * made subject to such option by the copyright holder.
40
 */
41
package org.netbeans.modules.j2ee.ejbjarproject;
42
43
import java.beans.PropertyChangeEvent;
44
import java.beans.PropertyChangeListener;
45
import org.netbeans.modules.j2ee.ejbjarproject.ui.customizer.EjbJarProjectProperties;
46
import org.openide.filesystems.FileObject;
47
import org.netbeans.api.queries.FileBuiltQuery;
48
import org.netbeans.spi.queries.FileBuiltQueryImplementation;
49
import org.netbeans.spi.project.support.ant.AntProjectHelper;
50
import org.netbeans.spi.project.support.ant.PropertyEvaluator;
51
52
53
public class EjbJarFileBuiltQuery implements FileBuiltQueryImplementation, PropertyChangeListener {
54
55
    private FileBuiltQueryImplementation delegate;
56
    private final AntProjectHelper helper;
57
    private final PropertyEvaluator evaluator;
58
    private final SourceRoots sourceRoots;
59
    private final SourceRoots testRoots;
60
61
    EjbJarFileBuiltQuery (AntProjectHelper helper, PropertyEvaluator evaluator,
62
                        SourceRoots sourceRoots, SourceRoots testRoots) {
63
        this.helper = helper;
64
        this.evaluator = evaluator;
65
        this.sourceRoots = sourceRoots;
66
        this.testRoots = testRoots;
67
    }
68
69
    public synchronized FileBuiltQuery.Status getStatus(FileObject file) {
70
        if (this.delegate == null) {
71
            this.delegate = createDelegate ();
72
        }
73
        return this.delegate.getStatus (file);
74
    }
75
76
    private FileBuiltQueryImplementation createDelegate () {
77
        String[] srcRoots = this.sourceRoots.getRootProperties();
78
        String[] tstRoots = this.testRoots.getRootProperties();
79
        String[] from = new String [srcRoots.length + tstRoots.length];
80
        String[] to = new String [srcRoots.length + tstRoots.length];
81
        for (int i=0; i< srcRoots.length; i++) {
82
            from[i] = "${" + srcRoots[i] + "}/*.java"; // NOI18N
83
            to[i] = "${" + EjbJarProjectProperties.BUILD_CLASSES_DIR + "}/*.class"; // NOI18N
84
        }
85
        for (int i=0; i<tstRoots.length; i++) {
86
            from[srcRoots.length+i] = "${" + tstRoots[i] + "}/*.java"; // NOI18N
87
            to[srcRoots.length+i] = "${" + EjbJarProjectProperties.BUILD_TEST_CLASSES_DIR + "}/*.class"; // NOI18N
88
        }
89
        return helper.createGlobFileBuiltQuery(evaluator, from, to);    //Safe to pass APH
90
    }
91
92
    public void propertyChange(PropertyChangeEvent evt) {
93
        if (SourceRoots.PROP_ROOT_PROPERTIES.equals (evt.getPropertyName())) {
94
            synchronized(this) {
95
                this.delegate = null;
96
                ///XXX: What to do with already returned Statuses
97
            }
98
        }
99
    }
100
}
(-)a/j2ee.ejbjarproject/src/org/netbeans/modules/j2ee/ejbjarproject/EjbJarProject.java (-15 / +17 lines)
Lines 75-83 import org.netbeans.modules.j2ee.ejbjarp Link Here
75
import org.netbeans.modules.j2ee.ejbjarproject.classpath.EjbJarProjectClassPathExtender;
75
import org.netbeans.modules.j2ee.ejbjarproject.classpath.EjbJarProjectClassPathExtender;
76
import org.netbeans.modules.j2ee.ejbjarproject.jaxws.EjbProjectJAXWSClientSupport;
76
import org.netbeans.modules.j2ee.ejbjarproject.jaxws.EjbProjectJAXWSClientSupport;
77
import org.netbeans.modules.j2ee.ejbjarproject.jaxws.EjbProjectJAXWSSupport;
77
import org.netbeans.modules.j2ee.ejbjarproject.jaxws.EjbProjectJAXWSSupport;
78
import org.netbeans.modules.j2ee.ejbjarproject.queries.CompiledSourceForBinaryQuery;
79
import org.netbeans.modules.j2ee.ejbjarproject.queries.JavadocForBinaryQueryImpl;
80
import org.netbeans.modules.j2ee.ejbjarproject.queries.UnitTestForSourceQueryImpl;
81
import org.netbeans.modules.j2ee.ejbjarproject.ui.EjbJarLogicalViewProvider;
78
import org.netbeans.modules.j2ee.ejbjarproject.ui.EjbJarLogicalViewProvider;
82
import org.netbeans.modules.j2ee.ejbjarproject.ui.customizer.EjbJarProjectProperties;
79
import org.netbeans.modules.j2ee.ejbjarproject.ui.customizer.EjbJarProjectProperties;
83
import org.netbeans.api.project.ProjectInformation;
80
import org.netbeans.api.project.ProjectInformation;
Lines 118-128 import org.netbeans.modules.j2ee.deploym Link Here
118
import org.netbeans.modules.j2ee.deployment.devmodules.api.Deployment;
115
import org.netbeans.modules.j2ee.deployment.devmodules.api.Deployment;
119
import org.netbeans.modules.j2ee.deployment.devmodules.api.J2eePlatform;
116
import org.netbeans.modules.j2ee.deployment.devmodules.api.J2eePlatform;
120
import org.netbeans.modules.j2ee.ejbjarproject.jaxws.EjbProjectJAXWSVersionProvider;
117
import org.netbeans.modules.j2ee.ejbjarproject.jaxws.EjbProjectJAXWSVersionProvider;
121
import org.netbeans.modules.j2ee.ejbjarproject.queries.EjbJarProjectEncodingQueryImpl;
122
import org.netbeans.modules.j2ee.ejbjarproject.ui.BrokenReferencesAlertPanel;
118
import org.netbeans.modules.j2ee.ejbjarproject.ui.BrokenReferencesAlertPanel;
123
import org.netbeans.modules.j2ee.ejbjarproject.ui.FoldersListSettings;
119
import org.netbeans.modules.j2ee.ejbjarproject.ui.FoldersListSettings;
124
import org.netbeans.modules.j2ee.ejbjarproject.ui.customizer.CustomizerProviderImpl;
120
import org.netbeans.modules.j2ee.ejbjarproject.ui.customizer.CustomizerProviderImpl;
125
import org.netbeans.modules.j2ee.ejbjarproject.queries.SourceLevelQueryImpl;
121
import org.netbeans.modules.java.api.common.SourceRoots;
122
import org.netbeans.modules.java.api.common.SourceRootsSupport;
123
import org.netbeans.modules.java.api.common.ant.UpdateHelper;
124
import org.netbeans.modules.java.api.common.ant.UpdateImplementation;
125
import org.netbeans.modules.java.api.common.queries.QuerySupport;
126
import org.netbeans.spi.java.project.support.ui.BrokenReferencesSupport;
126
import org.netbeans.spi.java.project.support.ui.BrokenReferencesSupport;
127
import org.netbeans.spi.project.AuxiliaryConfiguration;
127
import org.netbeans.spi.project.AuxiliaryConfiguration;
128
import org.netbeans.spi.project.support.ant.EditableProperties;
128
import org.netbeans.spi.project.support.ant.EditableProperties;
Lines 249-255 public class EjbJarProject implements Pr Link Here
249
        refHelper = new ReferenceHelper(helper, aux, helper.getStandardPropertyEvaluator());
249
        refHelper = new ReferenceHelper(helper, aux, helper.getStandardPropertyEvaluator());
250
        buildExtender = AntBuildExtenderFactory.createAntExtender(new EjbExtenderImplementation());
250
        buildExtender = AntBuildExtenderFactory.createAntExtender(new EjbExtenderImplementation());
251
        genFilesHelper = new GeneratedFilesHelper(helper, buildExtender);
251
        genFilesHelper = new GeneratedFilesHelper(helper, buildExtender);
252
        this.updateHelper = new UpdateHelper (this, this.helper, this.aux, this.genFilesHelper, UpdateHelper.createDefaultNotifier());
252
        UpdateImplementation updateProject = new UpdateProjectImpl(this, helper, aux, genFilesHelper);
253
        this.updateHelper = new UpdateHelper(updateProject, helper);
253
        this.cpProvider = new ClassPathProviderImpl(helper, evaluator(), getSourceRoots(), getTestSourceRoots());
254
        this.cpProvider = new ClassPathProviderImpl(helper, evaluator(), getSourceRoots(), getTestSourceRoots());
254
        ejbModule = new EjbJarProvider(this, helper, cpProvider);
255
        ejbModule = new EjbJarProvider(this, helper, cpProvider);
255
        apiEjbJar = EjbJarFactory.createEjbJar(ejbModule);
256
        apiEjbJar = EjbJarFactory.createEjbJar(ejbModule);
Lines 347-363 public class EjbJarProject implements Pr Link Here
347
                new EjbJarLogicalViewProvider(this, updateHelper, evaluator(), spp, refHelper),
348
                new EjbJarLogicalViewProvider(this, updateHelper, evaluator(), spp, refHelper),
348
                new CustomizerProviderImpl( this, updateHelper, evaluator(), refHelper ),
349
                new CustomizerProviderImpl( this, updateHelper, evaluator(), refHelper ),
349
                new ClassPathProviderMerger(cpProvider),
350
                new ClassPathProviderMerger(cpProvider),
350
                new CompiledSourceForBinaryQuery(helper,evaluator(),getSourceRoots(),getTestSourceRoots()),
351
                QuerySupport.createCompiledSourceForBinaryQuery(helper, evaluator(), getSourceRoots(), getTestSourceRoots()),
351
                new JavadocForBinaryQueryImpl(helper, evaluator()),
352
                QuerySupport.createJavadocForBinaryQuery(helper, evaluator()),
352
                new AntArtifactProviderImpl(),
353
                new AntArtifactProviderImpl(),
353
                new ProjectXmlSavedHookImpl(),
354
                new ProjectXmlSavedHookImpl(),
354
                UILookupMergerSupport.createProjectOpenHookMerger(new ProjectOpenedHookImpl()),
355
                UILookupMergerSupport.createProjectOpenHookMerger(new ProjectOpenedHookImpl()),
355
                new UnitTestForSourceQueryImpl(getSourceRoots(),getTestSourceRoots()),
356
                QuerySupport.createUnitTestForSourceQuery(getSourceRoots(), getTestSourceRoots()),
356
                new SourceLevelQueryImpl(helper, evaluator()),
357
                QuerySupport.createSourceLevelQuery(evaluator()),
357
                new EjbJarSources (helper, evaluator(), getSourceRoots(), getTestSourceRoots()),
358
                new EjbJarSources (helper, evaluator(), getSourceRoots(), getTestSourceRoots()),
358
                new EjbJarSharabilityQuery(helper, evaluator(), getSourceRoots(), getTestSourceRoots()),
359
                QuerySupport.createSharabilityQuery(helper, evaluator(), getSourceRoots(), getTestSourceRoots(),
359
                new EjbJarFileBuiltQuery (helper, evaluator(),getSourceRoots(),getTestSourceRoots()),
360
                        EjbJarProjectProperties.META_INF),
360
                new EjbJarProjectEncodingQueryImpl(evaluator()),
361
                QuerySupport.createFileBuiltQuery(helper, evaluator(), getSourceRoots(), getTestSourceRoots()),
362
                QuerySupport.createFileEncodingQuery(evaluator(), EjbJarProjectProperties.SOURCE_ENCODING),
361
                new RecommendedTemplatesImpl(updateHelper),
363
                new RecommendedTemplatesImpl(updateHelper),
362
                refHelper,
364
                refHelper,
363
                classpathExtender,
365
                classpathExtender,
Lines 408-421 public class EjbJarProject implements Pr Link Here
408
     */
410
     */
409
    public synchronized SourceRoots getSourceRoots() {
411
    public synchronized SourceRoots getSourceRoots() {
410
        if (this.sourceRoots == null) { //Local caching, no project metadata access
412
        if (this.sourceRoots == null) { //Local caching, no project metadata access
411
            this.sourceRoots = new SourceRoots(this.updateHelper, evaluator(), getReferenceHelper(), "source-roots", false, "src.{0}{1}.dir"); //NOI18N
413
            this.sourceRoots = SourceRootsSupport.create(this.updateHelper, evaluator(), getReferenceHelper(), EjbJarProjectType.PROJECT_CONFIGURATION_NAMESPACE, "source-roots", false, "src.{0}{1}.dir"); //NOI18N
412
        }
414
        }
413
        return this.sourceRoots;
415
        return this.sourceRoots;
414
    }
416
    }
415
    public synchronized SourceRoots getTestSourceRoots() {
417
    public synchronized SourceRoots getTestSourceRoots() {
416
        if (this.testRoots == null) { //Local caching, no project metadata access
418
        if (this.testRoots == null) { //Local caching, no project metadata access
417
            this.testRoots = new SourceRoots(this.updateHelper, evaluator(), getReferenceHelper(), "test-roots", true, "test.{0}{1}.dir"); //NOI18N
419
            this.testRoots = SourceRootsSupport.create(this.updateHelper, evaluator(), getReferenceHelper(), EjbJarProjectType.PROJECT_CONFIGURATION_NAMESPACE, "test-roots", true, "test.{0}{1}.dir"); //NOI18N
418
        }
420
        }
419
        return this.testRoots;
421
        return this.testRoots;
420
    }
422
    }
(-)a/j2ee.ejbjarproject/src/org/netbeans/modules/j2ee/ejbjarproject/EjbJarProjectOperations.java (+1 lines)
Lines 51-56 import org.netbeans.api.project.ProjectM Link Here
51
import org.netbeans.api.project.ProjectManager;
51
import org.netbeans.api.project.ProjectManager;
52
import org.netbeans.modules.j2ee.ejbjarproject.classpath.EjbJarProjectClassPathExtender;
52
import org.netbeans.modules.j2ee.ejbjarproject.classpath.EjbJarProjectClassPathExtender;
53
import org.netbeans.modules.j2ee.ejbjarproject.ui.customizer.EjbJarProjectProperties;
53
import org.netbeans.modules.j2ee.ejbjarproject.ui.customizer.EjbJarProjectProperties;
54
import org.netbeans.modules.java.api.common.SourceRoots;
54
import org.netbeans.spi.project.ActionProvider;
55
import org.netbeans.spi.project.ActionProvider;
55
import org.netbeans.spi.project.CopyOperationImplementation;
56
import org.netbeans.spi.project.CopyOperationImplementation;
56
import org.netbeans.spi.project.DeleteOperationImplementation;
57
import org.netbeans.spi.project.DeleteOperationImplementation;
(-)a/j2ee.ejbjarproject/src/org/netbeans/modules/j2ee/ejbjarproject/EjbJarSharabilityQuery.java (-128 lines)
Lines 1-128 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 1997-2007 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
 * Contributor(s):
25
 *
26
 * The Original Software is NetBeans. The Initial Developer of the Original
27
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
28
 * Microsystems, Inc. All Rights Reserved.
29
 *
30
 * If you wish your version of this file to be governed by only the CDDL
31
 * or only the GPL Version 2, indicate your decision by adding
32
 * "[Contributor] elects to include this software in this distribution
33
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
34
 * single choice of license, a recipient has the option to distribute
35
 * your version of this file under either the CDDL, the GPL Version 2 or
36
 * to extend the choice of license to its licensees as provided above.
37
 * However, if you add GPL Version 2 code and therefore, elected the GPL
38
 * Version 2 license, then the option applies only if the new code is
39
 * made subject to such option by the copyright holder.
40
 */
41
42
package org.netbeans.modules.j2ee.ejbjarproject;
43
44
import java.io.File;
45
import java.beans.PropertyChangeEvent;
46
import java.beans.PropertyChangeListener;
47
import org.openide.util.Mutex;
48
import org.netbeans.api.project.ProjectManager;
49
import org.netbeans.spi.queries.SharabilityQueryImplementation;
50
import org.netbeans.spi.project.support.ant.AntProjectHelper;
51
import org.netbeans.spi.project.support.ant.PropertyEvaluator;
52
import org.netbeans.modules.j2ee.ejbjarproject.ui.customizer.EjbJarProjectProperties;
53
54
/**
55
 * SharabilityQueryImplementation for j2seproject with multiple sources
56
 */
57
public class EjbJarSharabilityQuery implements SharabilityQueryImplementation, PropertyChangeListener {
58
59
    private final AntProjectHelper helper;
60
    private final PropertyEvaluator evaluator;
61
    private final SourceRoots srcRoots;
62
    private final SourceRoots testRoots;
63
    private SharabilityQueryImplementation delegate;
64
65
    /**
66
     * Creates new J2SESharabilityQuery
67
     * @param helper AntProjectHelper
68
     * @param evaluator PropertyEvaluator
69
     * @param srcRoots sources
70
     * @param testRoots tests
71
     */
72
    EjbJarSharabilityQuery (AntProjectHelper helper, PropertyEvaluator evaluator, SourceRoots srcRoots, SourceRoots testRoots) {
73
        this.helper = helper;
74
        this.evaluator = evaluator;
75
        this.srcRoots = srcRoots;
76
        this.testRoots = testRoots;
77
        this.srcRoots.addPropertyChangeListener(this);
78
        this.testRoots.addPropertyChangeListener(this);
79
    }
80
81
    /**
82
     * Check whether a file or directory should be shared.
83
     * If it is, it ought to be committed to a VCS if the user is using one.
84
     * If it is not, it is either a disposable build product, or a per-user
85
     * private file which is important but should not be shared.
86
     * @param file a file to check for sharability (may or may not yet exist)
87
     * @return one of {@link org.netbeans.api.queries.SharabilityQuery}'s constants
88
     */
89
    public int getSharability(final File file) {
90
        Integer ret = ProjectManager.mutex().readAccess(new Mutex.Action<Integer>() {
91
            public Integer run() {
92
                synchronized (EjbJarSharabilityQuery.this) {
93
                    if (delegate == null) {
94
                        delegate = createDelegate ();
95
                    }
96
                    return new Integer(delegate.getSharability (file));
97
                }
98
            }
99
        });
100
        return ret.intValue();
101
    }
102
103
    public void propertyChange(PropertyChangeEvent evt) {
104
        if (SourceRoots.PROP_ROOT_PROPERTIES.equals(evt.getPropertyName())) {
105
            synchronized (this) {
106
                this.delegate = null;
107
            }
108
        }
109
    }
110
111
    private SharabilityQueryImplementation createDelegate () {
112
        String[] srcProps = srcRoots.getRootProperties();
113
        String[] testProps = testRoots.getRootProperties();
114
        String[] props = new String [srcProps.length + testProps.length + 1];
115
        for (int i=0; i<srcProps.length; i++) {
116
            props[i] = "${"+srcProps[i]+"}"; // NOI18N
117
        }
118
        for (int i=0; i<testProps.length; i++) {
119
            props[srcProps.length+i] = "${"+testProps[i]+"}"; // NOI18N
120
        }
121
        props[props.length - 1] = "${" + EjbJarProjectProperties.META_INF + "}"; // NOI18N
122
        return helper.createSharabilityQuery(this.evaluator, props,
123
            new String[] {
124
                "${" + EjbJarProjectProperties.DIST_DIR + "}", // NOI18N
125
                "${" + EjbJarProjectProperties.BUILD_DIR + "}", // NOI18N
126
            });
127
    }
128
}
(-)a/j2ee.ejbjarproject/src/org/netbeans/modules/j2ee/ejbjarproject/EjbJarSources.java (+1 lines)
Lines 55-60 import org.netbeans.api.project.ProjectM Link Here
55
import org.netbeans.api.project.ProjectManager;
55
import org.netbeans.api.project.ProjectManager;
56
import org.netbeans.api.project.FileOwnerQuery;
56
import org.netbeans.api.project.FileOwnerQuery;
57
import org.netbeans.api.java.project.JavaProjectConstants;
57
import org.netbeans.api.java.project.JavaProjectConstants;
58
import org.netbeans.modules.java.api.common.SourceRoots;
58
import org.netbeans.spi.project.support.ant.SourcesHelper;
59
import org.netbeans.spi.project.support.ant.SourcesHelper;
59
import org.netbeans.spi.project.support.ant.AntProjectHelper;
60
import org.netbeans.spi.project.support.ant.AntProjectHelper;
60
import org.netbeans.spi.project.support.ant.PropertyEvaluator;
61
import org.netbeans.spi.project.support.ant.PropertyEvaluator;
(-)a/j2ee.ejbjarproject/src/org/netbeans/modules/j2ee/ejbjarproject/PropertyHelper.java (+1 lines)
Lines 44-49 import java.io.IOException; Link Here
44
import java.io.IOException;
44
import java.io.IOException;
45
import org.netbeans.api.project.Project;
45
import org.netbeans.api.project.Project;
46
import org.netbeans.api.project.ProjectManager;
46
import org.netbeans.api.project.ProjectManager;
47
import org.netbeans.modules.java.api.common.ant.UpdateHelper;
47
import org.netbeans.spi.project.support.ant.EditableProperties;
48
import org.netbeans.spi.project.support.ant.EditableProperties;
48
import org.openide.util.Exceptions;
49
import org.openide.util.Exceptions;
(-)a/j2ee.ejbjarproject/src/org/netbeans/modules/j2ee/ejbjarproject/SourceRoots.java (-473 lines)
Lines 1-473 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 1997-2007 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
 * Contributor(s):
25
 *
26
 * The Original Software is NetBeans. The Initial Developer of the Original
27
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
28
 * Microsystems, Inc. All Rights Reserved.
29
 *
30
 * If you wish your version of this file to be governed by only the CDDL
31
 * or only the GPL Version 2, indicate your decision by adding
32
 * "[Contributor] elects to include this software in this distribution
33
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
34
 * single choice of license, a recipient has the option to distribute
35
 * your version of this file under either the CDDL, the GPL Version 2 or
36
 * to extend the choice of license to its licensees as provided above.
37
 * However, if you add GPL Version 2 code and therefore, elected the GPL
38
 * Version 2 license, then the option applies only if the new code is
39
 * made subject to such option by the copyright holder.
40
 */
41
package org.netbeans.modules.j2ee.ejbjarproject;
42
43
import java.beans.PropertyChangeEvent;
44
import java.beans.PropertyChangeListener;
45
import java.beans.PropertyChangeSupport;
46
import java.io.File;
47
import java.net.MalformedURLException;
48
import java.net.URL;
49
import java.net.URI;
50
import java.util.Arrays;
51
import java.util.ArrayList;
52
import java.util.Collections;
53
import java.util.Iterator;
54
import java.util.List;
55
import java.util.Map;
56
import java.util.HashMap;
57
import java.text.MessageFormat;
58
import java.util.logging.Level;
59
import java.util.logging.Logger;
60
import org.openide.filesystems.FileObject;
61
import org.openide.filesystems.FileUtil;
62
import org.openide.filesystems.URLMapper;
63
import org.openide.util.NbBundle;
64
import org.openide.util.WeakListeners;
65
import org.openide.util.Mutex;
66
import org.w3c.dom.Element;
67
import org.w3c.dom.NodeList;
68
import org.w3c.dom.Document;
69
import org.netbeans.spi.project.support.ant.AntProjectHelper;
70
import org.netbeans.spi.project.support.ant.AntProjectEvent;
71
import org.netbeans.spi.project.support.ant.AntProjectListener;
72
import org.netbeans.spi.project.support.ant.EditableProperties;
73
import org.netbeans.spi.project.support.ant.PropertyEvaluator;
74
import org.netbeans.spi.project.support.ant.ReferenceHelper;
75
import org.netbeans.api.project.ProjectManager;
76
import org.netbeans.api.java.project.JavaProjectConstants;
77
import org.openide.util.Exceptions;
78
79
/**
80
 * This class represents a project source roots. It is used to obtain roots as Ant properties, FileObject's
81
 * or URLs.
82
 * @author Tomas Zezula
83
 */
84
public final class SourceRoots {
85
86
    public static final String PROP_ROOT_PROPERTIES = "rootProperties";    //NOI18N
87
    public static final String PROP_ROOTS = "roots";   //NOI18N
88
    private static final String PROP_BUILD_DIR = "build.dir";   //NOI18N
89
90
    public static final String DEFAULT_SOURCE_LABEL = NbBundle.getMessage(SourceRoots.class, "NAME_src.dir"); //NOI18N
91
    public static final String DEFAULT_TEST_LABEL = NbBundle.getMessage(SourceRoots.class, "NAME_test.src.dir"); //NOI18N
92
93
    private final UpdateHelper helper;
94
    private final PropertyEvaluator evaluator;
95
    private final ReferenceHelper refHelper;
96
    private final String elementName;
97
    private final String newRootNameTemplate;
98
    private List<String> sourceRootProperties;
99
    private List<String> sourceRootNames;
100
    private List<FileObject> sourceRoots;
101
    private List<URL> sourceRootURLs;
102
    private final PropertyChangeSupport support;
103
    private final ProjectMetadataListener listener;
104
    private final boolean isTest;
105
    private final File projectDir;
106
107
    /**
108
     * Creates new SourceRoots
109
     * @param helper
110
     * @param evaluator
111
     * @param elementName the name of XML element under which are declared the roots
112
     * @param newRootNameTemplate template for new property name of source root
113
     */
114
    SourceRoots (UpdateHelper helper, PropertyEvaluator evaluator, ReferenceHelper refHelper, String elementName, boolean isTest, String newRootNameTemplate) {
115
        assert helper != null && evaluator != null && refHelper != null && elementName != null && newRootNameTemplate != null;
116
        this.helper = helper;
117
        this.evaluator = evaluator;
118
        this.refHelper = refHelper;
119
        this.elementName = elementName;
120
        this.isTest = isTest;
121
        this.newRootNameTemplate = newRootNameTemplate;
122
        this.projectDir = FileUtil.toFile(this.helper.getAntProjectHelper().getProjectDirectory());
123
        this.support = new PropertyChangeSupport(this);
124
        this.listener = new ProjectMetadataListener();
125
        this.evaluator.addPropertyChangeListener (WeakListeners.propertyChange(this.listener,this.evaluator));
126
        this.helper.getAntProjectHelper().addAntProjectListener(WeakListeners.create(AntProjectListener.class, this.listener, this.helper));
127
    }
128
129
130
    /**
131
     * Returns the display names of soruce roots
132
     * The returned array has the same length as an array returned by the getRootProperties.
133
     * It may contain empty strings but not null.
134
     * @return an array of String
135
     */
136
    public   String[] getRootNames () {
137
        return ProjectManager.mutex().readAccess(new Mutex.Action<String[]>() {
138
            public String[] run() {
139
                synchronized (SourceRoots.this) {
140
                    if (sourceRootNames == null) {
141
                        readProjectMetadata();
142
                    }
143
                }
144
                return sourceRootNames.toArray(new String[sourceRootNames.size()]);
145
            }
146
        });
147
    }
148
149
    /**
150
     * Returns names of Ant properties in the project.properties file holding the source roots.
151
     * @return an array of String
152
     */
153
    public String[] getRootProperties () {
154
        return ProjectManager.mutex().readAccess(new Mutex.Action<String[]>() {
155
            public String[] run() {
156
                synchronized (SourceRoots.this) {
157
                    if (sourceRootProperties == null) {
158
                        readProjectMetadata();
159
                    }
160
                }
161
                return sourceRootProperties.toArray (new String[sourceRootProperties.size()]);
162
            }
163
        });
164
    }
165
166
    /**
167
     * Returns the source roots
168
     * @return an array of FileObject
169
     */
170
    public FileObject[] getRoots () {
171
        return ProjectManager.mutex().readAccess(new Mutex.Action<FileObject[]>() {
172
                public FileObject[] run () {
173
                    synchronized (this) {
174
                        //Local caching
175
                        if (sourceRoots == null) {
176
                            String[] srcProps = getRootProperties();
177
                            List<FileObject> result = new ArrayList<FileObject>();
178
                            for (int i = 0; i<srcProps.length; i++) {
179
                                String prop = evaluator.getProperty(srcProps[i]);
180
                                if (prop != null) {
181
                                    FileObject f = helper.getAntProjectHelper().resolveFileObject(prop);
182
                                    if (f == null) {
183
                                        continue;
184
                                    }
185
                                    if (FileUtil.isArchiveFile(f)) {
186
                                        f = FileUtil.getArchiveRoot(f);
187
                                    }
188
                                    result.add(f);
189
                                }
190
                            }
191
192
                            String buildDir = evaluator.getProperty(PROP_BUILD_DIR);
193
                            if (buildDir != null) {
194
                                try {
195
                                    // generated/wsimport/client
196
                                    File f =  new File (helper.getAntProjectHelper().resolveFile (buildDir),"generated/wsimport/client"); //NOI18N
197
                                    URL url = f.toURI().toURL();
198
                                    if (!f.exists()) {  //NOI18N
199
                                        assert !url.toExternalForm().endsWith("/");  //NOI18N
200
                                        url = new URL (url.toExternalForm()+'/');   //NOI18N
201
                                    }
202
                                    FileObject root = URLMapper.findFileObject(url);
203
                                    if (root != null) {
204
                                        result.add(root);
205
                                    }
206
                                    // generated/wsimport/service
207
                                    f = new File (helper.getAntProjectHelper().resolveFile(buildDir),"generated/wsimport/service"); //NOI18N
208
                                    url = f.toURI().toURL();
209
                                    if (!f.exists()) {  //NOI18N
210
                                        assert !url.toExternalForm().endsWith("/");  //NOI18N
211
                                        url = new URL (url.toExternalForm()+'/');   //NOI18N
212
                                    }
213
                                    root = URLMapper.findFileObject(url);
214
                                    if (root != null) {
215
                                        result.add(root);
216
                                    }
217
                                } catch (MalformedURLException ex) {
218
                                     Logger.getLogger("global").log(Level.INFO, null, ex);
219
                                }
220
                            }
221
                            sourceRoots = Collections.unmodifiableList(result);
222
                        }
223
                    }
224
                    return sourceRoots.toArray(new FileObject[sourceRoots.size()]);
225
                }
226
        });
227
    }
228
229
    /**
230
     * Returns the source roots as URLs.
231
     * @return an array of URL
232
     */
233
    public URL[] getRootURLs() {
234
        return ProjectManager.mutex().readAccess(new Mutex.Action<URL[]>() {
235
            public URL[] run () {
236
                synchronized (this) {
237
                    //Local caching
238
                    if (sourceRootURLs == null) {
239
                        String[] srcProps = getRootProperties();
240
                        List<URL> result = new ArrayList<URL>();
241
                        for (int i = 0; i<srcProps.length; i++) {
242
                            String prop = evaluator.getProperty(srcProps[i]);
243
                            if (prop != null) {
244
                                File f = helper.getAntProjectHelper().resolveFile(prop);
245
                                try {
246
                                    result.add(EjbJarProjectUtil.getRootURL(f,null));
247
                                } catch (MalformedURLException e) {
248
                                    Exceptions.printStackTrace(e);
249
                                }
250
                            }
251
                        }
252
                        sourceRootURLs = Collections.<URL>unmodifiableList(result);
253
                    }
254
                }
255
                return sourceRootURLs.toArray(new URL[sourceRootURLs.size()]);
256
            }
257
        });
258
    }
259
260
    /**
261
     * Adds PropertyChangeListener
262
     * @param listener
263
     */
264
    public void addPropertyChangeListener (PropertyChangeListener listener) {
265
        this.support.addPropertyChangeListener (listener);
266
    }
267
268
    /**
269
     * Removes PropertyChangeListener
270
     * @param listener
271
     */
272
    public void removePropertyChangeListener (PropertyChangeListener listener) {
273
        this.support.removePropertyChangeListener (listener);
274
    }
275
276
277
    /**
278
     * Replaces the current roots by the new ones
279
     * @param roots the URLs of new roots
280
     * @param labels the names of roots
281
     */
282
    public void putRoots (final URL[] roots, final String[] labels) {
283
        ProjectManager.mutex().writeAccess(
284
                new Runnable() {
285
                    public void run() {
286
                        String[] originalProps = getRootProperties();
287
                        URL[] originalRoots = getRootURLs();
288
                        Map<URL, String> oldRoots2props = new HashMap<URL, String>();
289
                        for (int i=0; i<originalProps.length;i++) {
290
                            oldRoots2props.put (originalRoots[i],originalProps[i]);
291
                        }
292
                        Map<URL, String> newRoots2lab = new HashMap<URL, String>();
293
                        for (int i=0; i<roots.length;i++) {
294
                            newRoots2lab.put (roots[i],labels[i]);
295
                        }
296
                        Element cfgEl = helper.getPrimaryConfigurationData(true);
297
                        NodeList nl = cfgEl.getElementsByTagNameNS(EjbJarProjectType.PROJECT_CONFIGURATION_NAMESPACE, elementName);
298
                        assert nl.getLength() == 1 : "Illegal project.xml"; //NOI18N
299
                        Element ownerElement = (Element) nl.item(0);
300
                        //Remove all old roots
301
                        NodeList rootsNodes = ownerElement.getElementsByTagNameNS(EjbJarProjectType.PROJECT_CONFIGURATION_NAMESPACE, "root");    //NOI18N
302
                        while (rootsNodes.getLength()>0) {
303
                            Element root = (Element) rootsNodes.item(0);
304
                            ownerElement.removeChild(root);
305
                        }
306
                        //Remove all unused root properties
307
                        List newRoots = Arrays.asList(roots);
308
                        Map<URL, String> propsToRemove = new HashMap<URL, String>(oldRoots2props);
309
                        propsToRemove.keySet().removeAll(newRoots);
310
                        EditableProperties props = helper.getProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH);
311
                        for (Iterator it = propsToRemove.values().iterator(); it.hasNext();) {
312
                            String propName = (String) it.next ();
313
                            props.remove(propName);
314
                        }
315
                        helper.putProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH,props);
316
                        //Add the new roots
317
                        Document doc = ownerElement.getOwnerDocument();
318
                        oldRoots2props.keySet().retainAll(newRoots);
319
                        for (Iterator it = newRoots.iterator(); it.hasNext();) {
320
                            URL newRoot = (URL) it.next ();
321
                            String rootName = oldRoots2props.get(newRoot);
322
                            if (rootName == null) {
323
                                //Root is new generate property for it
324
                                props = helper.getProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH);
325
                                String[] names = newRoot.getPath().split("/");  //NOI18N
326
                                rootName = MessageFormat.format(newRootNameTemplate,new Object[]{names[names.length-1],""});    //NOI18N
327
                                int rootIndex = 1;
328
                                while (props.containsKey(rootName)) {
329
                                    rootIndex++;
330
                                    rootName = MessageFormat.format(newRootNameTemplate,new Object[]{names[names.length-1],new Integer(rootIndex)});
331
                                }
332
                                File f = FileUtil.normalizeFile(new File(URI.create(newRoot.toExternalForm())));
333
                                File projDir = FileUtil.toFile(helper.getAntProjectHelper().getProjectDirectory());
334
                                String path = f.getAbsolutePath();
335
                                String prjPath = projDir.getAbsolutePath()+File.separatorChar;
336
                                if (path.startsWith(prjPath)) {
337
                                    path = path.substring(prjPath.length());
338
                                }
339
                                else {
340
                                    path = refHelper.createForeignFileReference(f, JavaProjectConstants.SOURCES_TYPE_JAVA);
341
                                    props = helper.getProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH);
342
                                }
343
                                props.put(rootName,path);
344
                                helper.putProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH,props);
345
                            }
346
                            Element newRootNode = doc.createElementNS(EjbJarProjectType.PROJECT_CONFIGURATION_NAMESPACE, "root"); //NOI18N
347
                            newRootNode.setAttribute("id",rootName);    //NOI18N
348
                            String label = newRoots2lab.get(newRoot);
349
                            if (label != null && label.length()>0 && !label.equals (getRootDisplayName(null,rootName))) { //NOI18N
350
                                newRootNode.setAttribute("name",label); //NOI18N
351
                            }
352
                            ownerElement.appendChild (newRootNode);
353
                        }
354
                        helper.putPrimaryConfigurationData(cfgEl,true);
355
                    }
356
                }
357
        );
358
    }
359
360
    /**
361
     * Translates root name into display name of source/test root
362
     * @param rootName the name of root got from {@link SourceRoots#getRootNames}
363
     * @param propName the name of property the root is stored in
364
     * @return the label to be displayed
365
     */
366
    public String getRootDisplayName (String rootName, String propName) {
367
        if (rootName == null || rootName.length() ==0) {
368
            //If the prop is src.dir use the default name
369
            if (isTest && "test.src.dir".equals(propName)) {    //NOI18N
370
                rootName = DEFAULT_TEST_LABEL;
371
            }
372
            else if (!isTest && "src.dir".equals(propName)) {   //NOI18N
373
                rootName = DEFAULT_SOURCE_LABEL;
374
            }
375
            else {
376
                //If the name is not given, it should be either a relative path in the project dir
377
                //or absolute path when the root is not under the project dir
378
                String propValue = evaluator.getProperty(propName);
379
                File sourceRoot = propValue == null ? null : helper.getAntProjectHelper().resolveFile(propValue);
380
                rootName = createInitialDisplayName(sourceRoot);
381
            }
382
        }
383
        return rootName;
384
    }
385
386
    /**
387
     * Creates initial display name of source/test root
388
     * @param sourceRoot the source root
389
     * @return the label to be displayed
390
     */
391
    public String createInitialDisplayName (File sourceRoot) {
392
        String rootName;
393
        if (sourceRoot != null) {
394
            String srPath = sourceRoot.getAbsolutePath();
395
            String pdPath = projectDir.getAbsolutePath() + File.separatorChar;
396
            if (srPath.startsWith(pdPath)) {
397
                rootName = srPath.substring(pdPath.length());
398
            }
399
            else {
400
                rootName = sourceRoot.getAbsolutePath();
401
            }
402
        }
403
        else {
404
            rootName = isTest ? DEFAULT_TEST_LABEL : DEFAULT_SOURCE_LABEL;
405
        }
406
        return rootName;
407
    }
408
409
    private void resetCache (boolean isXMLChange, String propName) {
410
        boolean fire = false;
411
        synchronized (this) {
412
            //In case of change reset local cache
413
            if (isXMLChange) {
414
                this.sourceRootProperties = null;
415
                this.sourceRootNames = null;
416
                this.sourceRoots = null;
417
                this.sourceRootURLs = null;
418
                fire = true;
419
            } else if (propName == null || (sourceRootProperties != null && sourceRootProperties.contains(propName))) {
420
                this.sourceRoots = null;
421
                this.sourceRootURLs = null;
422
                fire = true;
423
            }
424
        }
425
        if (fire) {
426
            if (isXMLChange) {
427
                this.support.firePropertyChange (PROP_ROOT_PROPERTIES,null,null);
428
            }
429
            this.support.firePropertyChange (PROP_ROOTS,null,null);
430
        }
431
    }
432
433
    private void readProjectMetadata () {
434
        Element cfgEl = helper.getPrimaryConfigurationData(true);
435
        NodeList nl = cfgEl.getElementsByTagNameNS(EjbJarProjectType.PROJECT_CONFIGURATION_NAMESPACE, elementName);
436
        assert nl.getLength() == 0 || nl.getLength() == 1 : "Illegal project.xml"; //NOI18N
437
        List<String> rootProps = new ArrayList<String>();
438
        List<String> rootNames = new ArrayList<String>();
439
        // It can be 0 in the case when the project is created by EjbJarProjectGenerator and not yet customized
440
        if (nl.getLength()==1) {
441
            NodeList roots = ((Element)nl.item(0)).getElementsByTagNameNS(EjbJarProjectType.PROJECT_CONFIGURATION_NAMESPACE, "root");    //NOI18N
442
            for (int i=0; i<roots.getLength(); i++) {
443
                Element root = (Element) roots.item(i);
444
                String value = root.getAttribute("id");  //NOI18N
445
                assert value.length() > 0 : "Illegal project.xml";
446
                rootProps.add(value);
447
                value = root.getAttribute("name");  //NOI18N
448
                rootNames.add (value);
449
            }
450
        }
451
        this.sourceRootProperties = Collections.<String>unmodifiableList(rootProps);
452
        this.sourceRootNames = Collections.<String>unmodifiableList(rootNames);
453
    }
454
455
    private class ProjectMetadataListener implements PropertyChangeListener,AntProjectListener {
456
457
        public void propertyChange(PropertyChangeEvent evt) {
458
            resetCache (false,evt.getPropertyName());
459
        }
460
461
        public void configurationXmlChanged(AntProjectEvent ev) {
462
            resetCache (true,null);
463
        }
464
465
        public void propertiesChanged(AntProjectEvent ev) {
466
            //Handled by propertyChange
467
        }
468
    }
469
470
    public boolean isTest() {
471
        return isTest;
472
    }
473
}
(-)a/j2ee.ejbjarproject/src/org/netbeans/modules/j2ee/ejbjarproject/UpdateHelper.java (-448 lines)
Lines 1-448 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 1997-2007 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
 * Contributor(s):
25
 *
26
 * The Original Software is NetBeans. The Initial Developer of the Original
27
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
28
 * Microsystems, Inc. All Rights Reserved.
29
 *
30
 * If you wish your version of this file to be governed by only the CDDL
31
 * or only the GPL Version 2, indicate your decision by adding
32
 * "[Contributor] elects to include this software in this distribution
33
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
34
 * single choice of license, a recipient has the option to distribute
35
 * your version of this file under either the CDDL, the GPL Version 2 or
36
 * to extend the choice of license to its licensees as provided above.
37
 * However, if you add GPL Version 2 code and therefore, elected the GPL
38
 * Version 2 license, then the option applies only if the new code is
39
 * made subject to such option by the copyright holder.
40
 */
41
42
package org.netbeans.modules.j2ee.ejbjarproject;
43
44
import java.io.IOException;
45
import java.net.URL;
46
import java.util.ArrayList;
47
import java.util.Iterator;
48
import java.util.List;
49
import org.netbeans.modules.j2ee.ejbjarproject.api.EjbJarProjectGenerator;
50
import org.netbeans.spi.project.support.ant.GeneratedFilesHelper;
51
import org.w3c.dom.Comment;
52
import org.w3c.dom.Document;
53
import org.w3c.dom.Element;
54
import org.w3c.dom.NamedNodeMap;
55
import org.w3c.dom.Node;
56
import org.w3c.dom.NodeList;
57
import org.w3c.dom.Text;
58
import org.openide.DialogDisplayer;
59
import org.openide.NotifyDescriptor;
60
import org.openide.util.NbBundle;
61
import org.openide.util.Mutex;
62
import org.netbeans.api.project.Project;
63
import org.netbeans.api.project.ProjectManager;
64
import org.netbeans.api.project.libraries.LibraryManager;
65
import org.netbeans.spi.project.AuxiliaryConfiguration;
66
import org.netbeans.spi.project.support.ant.AntProjectHelper;
67
import org.netbeans.spi.project.support.ant.EditableProperties;
68
import org.openide.filesystems.FileObject;
69
import org.openide.filesystems.FileUtil;
70
import org.openide.util.Exceptions;
71
72
73
/**
74
 * Proxy for the AntProjectHelper which defers the update of the project metadata
75
 * to explicit user action. Currently it is hard coded for update from
76
 * "http://www.netbeans.org/ns/j2se-project/1" to "http://www.netbeans.org/ns/j2se-project/2".
77
 * In future it should define plugable SPI.
78
 */
79
public class UpdateHelper {
80
81
    private final Project project;
82
    private final AntProjectHelper helper;
83
    private final AuxiliaryConfiguration cfg;
84
    private final GeneratedFilesHelper genFileHelper;
85
    private final Notifier notifier;
86
    private boolean alreadyAskedInWriteAccess;
87
    private Boolean isCurrent;
88
    private Element cachedElement;
89
90
    private static final String BUILD_NUMBER = System.getProperty("netbeans.buildnumber"); // NOI18N
91
    private static final String INCLUDED_LIBRARY_ELEMENT = "included-library"; //NOI18N
92
    private static final String MINIMUM_ANT_VERSION_ELEMENT = "minimum-ant-version"; // NOI18N
93
    private static final String ATTR_FILES = "files"; //NOI18N
94
    private static final String ATTR_DIRS = "dirs"; //NOI18N
95
96
    /**
97
     * Creates new UpdateHelper
98
     * @param project
99
     * @param helper AntProjectHelper
100
     * @param cfg AuxiliaryConfiguration
101
     * @param genFileHelper GeneratedFilesHelper
102
     * @param notifier used to ask user about project update
103
     */
104
    UpdateHelper (Project project, AntProjectHelper helper, AuxiliaryConfiguration cfg, GeneratedFilesHelper genFileHelper, Notifier notifier) {
105
        assert project != null && helper != null && cfg != null && genFileHelper != null && notifier != null;
106
        this.project = project;
107
        this.helper = helper;
108
        this.cfg = cfg;
109
        this.genFileHelper = genFileHelper;
110
        this.notifier = notifier;
111
    }
112
113
    /**
114
     * Returns the AntProjectHelper.getProperties(), {@link AntProjectHelper#getProperties(String)}
115
     * @param path a relative URI in the project directory.
116
     * @return a set of properties
117
     */
118
    public EditableProperties getProperties (String path) {
119
        //Properties are the same in both j2seproject/1 and j2seproject/2
120
        return this.helper.getProperties(path);
121
    }
122
123
    /**
124
     * In the case that the project is of current version or the properties are not {@link AntProjectHelper#PROJECT_PROPERTIES_PATH}
125
     * it calls AntProjectHelper.putProperties(), {@link AntProjectHelper#putProperties(String, EditableProperties)}
126
     * otherwise it asks user to updata project. If the user agrees with the project update, it does the update and calls
127
     * AntProjectHelper.putProperties().
128
     * @param path a relative URI in the project directory.
129
     * @param props a set of properties
130
     */
131
    public void putProperties(final String path, final EditableProperties props) {
132
        ProjectManager.mutex().writeAccess(new Runnable() {
133
            public void run() {
134
                if (isCurrent() || !AntProjectHelper.PROJECT_PROPERTIES_PATH.equals(path)) {  //Only project props should cause update
135
                    helper.putProperties(path,props);
136
                } else if (canUpdate()) {
137
                    try {
138
                        saveUpdate(props);
139
                        helper.putProperties(path,props);
140
                    } catch (IOException ioe) {
141
                        Exceptions.printStackTrace(ioe);
142
                    }
143
                }
144
            }
145
        });
146
    }
147
148
    /**
149
     * In the case that the project is of current version or shared is false it delegates to
150
     * AntProjectHelper.getPrimaryConfigurationData(), {@link AntProjectHelper#getPrimaryConfigurationData(boolean)}.
151
     * Otherwise it creates an in memory update of shared configuration data and returns it.
152
     * @param shared if true, refers to <code>project.xml</code>, else refers to
153
     *               <code>private.xml</code>
154
     * @return the configuration data that is available
155
     */
156
    public Element getPrimaryConfigurationData (final boolean shared) {
157
        return ProjectManager.mutex().readAccess(new Mutex.Action<Element>(){
158
            public Element run() {
159
                if (!shared || isCurrent()) { //Only shared props should cause update
160
                    return helper.getPrimaryConfigurationData(shared);
161
                }
162
                return getUpdatedSharedConfigurationData();
163
            }
164
        });
165
    }
166
167
    /**
168
     * In the case that the project is of current version or shared is false it calls AntProjectHelper.putPrimaryConfigurationData(),
169
     * {@link AntProjectHelper#putPrimaryConfigurationData(Element, boolean)}.
170
     * Otherwise it asks user to update the project. If the user agrees with the project update, it does the update and calls
171
     * AntProjectHelper.PrimaryConfigurationData().
172
     * @param element the configuration data
173
     * @param shared if true, refers to <code>project.xml</code>, else refers to
174
     * <code>private.xml</code>
175
     */
176
    public void putPrimaryConfigurationData(final Element element, final boolean shared) {
177
        ProjectManager.mutex().writeAccess(new Runnable() {
178
            public void run() {
179
                if (!shared || isCurrent()) {
180
                    helper.putPrimaryConfigurationData(element, shared);
181
                } else if (canUpdate()) {
182
                    try {
183
                        saveUpdate(null);
184
                        helper.putPrimaryConfigurationData(element, shared);
185
                    } catch (IOException ioe) {
186
                        Exceptions.printStackTrace(ioe);
187
                    }
188
                }
189
            }
190
        });
191
    }
192
193
    /**
194
     * Returns an AntProjectHelper. The helper may not be used for accessing/storing project metadata.
195
     * For project metadata manipulation the UpdateHelper must be used.
196
     * @return AntProjectHelper
197
     */
198
    public AntProjectHelper getAntProjectHelper () {
199
        return this.helper;
200
    }
201
202
    /**
203
     * Request an saving of update. If the project is not of current version the user will be asked to update the project.
204
     * If the user agrees with an update the project is updated.
205
     */
206
    public boolean requestSave () throws IOException{
207
        if (isCurrent()) {
208
            return true;
209
        }
210
        if (!canUpdate()) {
211
            return false;
212
        }
213
        saveUpdate (null);
214
        return true;
215
    }
216
217
    /**
218
     * Returns true if the project is of current version.
219
     * @return true if the project is of current version, otherwise false.
220
     */
221
    public synchronized boolean isCurrent () {
222
        if (this.isCurrent == null) {
223
            this.isCurrent = this.cfg.getConfigurationFragment("data","http://www.netbeans.org/ns/j2ee-ejbjarproject/1",true) == null
224
                    && this.cfg.getConfigurationFragment("data","http://www.netbeans.org/ns/j2ee-ejbjarproject/2",true) == null? //NOI18N
225
                Boolean.TRUE : Boolean.FALSE;
226
        }
227
        return isCurrent.booleanValue();
228
    }
229
230
    private boolean canUpdate () {
231
        //Ask just once under a single write access
232
        if (alreadyAskedInWriteAccess) {
233
            return false;
234
        }
235
        else {
236
            boolean canUpdate = this.notifier.canUpdate();
237
            if (!canUpdate) {
238
                alreadyAskedInWriteAccess = true;
239
                ProjectManager.mutex().postReadRequest(new Runnable() {
240
                    public void run() {
241
                        alreadyAskedInWriteAccess = false;
242
                    }
243
                });
244
            }
245
            return canUpdate;
246
        }
247
    }
248
249
    private void saveUpdate (EditableProperties props) throws IOException {
250
        this.helper.putPrimaryConfigurationData(getUpdatedSharedConfigurationData(),true);
251
        if (this.cfg.getConfigurationFragment("data","http://www.netbeans.org/ns/j2ee-ejbjarproject/1",true) != null) { //NOI18N
252
            //version 1
253
            this.cfg.removeConfigurationFragment("data","http://www.netbeans.org/ns/j2ee-ejbjarproject/1",true); //NOI18N
254
        } else {
255
            //version 2
256
            this.cfg.removeConfigurationFragment("data","http://www.netbeans.org/ns/j2ee-ejbjarproject/2",true); //NOI18N
257
        }
258
259
        boolean putProps = false;
260
261
        // AB: fix for #55597: should not update the project without adding the properties
262
        // update is only done once, so if we don't add the properties now, we don't get another chance to do so
263
        if (props == null) {
264
            props = getProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH);
265
            putProps = true;
266
        }
267
268
        //add properties needed by 4.1 project
269
        if(props != null) {
270
            props.put("test.src.dir", "test"); //NOI18N
271
        }
272
273
        if (putProps) {
274
            helper.putProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH, props);
275
        }
276
277
        ProjectManager.getDefault().saveProject (this.project);
278
        this.genFileHelper.refreshBuildScript(GeneratedFilesHelper.BUILD_IMPL_XML_PATH, UpdateHelper.class.getResource("resources/build-impl.xsl"),
279
            true);
280
        synchronized(this) {
281
            this.isCurrent = Boolean.TRUE;
282
        }
283
    }
284
285
    private synchronized Element getUpdatedSharedConfigurationData () {
286
        if (cachedElement == null) {
287
            Element  oldRoot = this.cfg.getConfigurationFragment("data","http://www.netbeans.org/ns/j2ee-ejbjarproject/1",true);    //NOI18N
288
289
            int version = 1;
290
            if (oldRoot == null) {
291
                version = 2;
292
                oldRoot = this.cfg.getConfigurationFragment("data","http://www.netbeans.org/ns/j2ee-ejbjarproject/2",true);    //NOI18N
293
            }
294
            final String ns = version == 1 ? "http://www.netbeans.org/ns/j2ee-ejbjarproject/1" : "http://www.netbeans.org/ns/j2ee-ejbjarproject/2"; //NOI18N
295
296
            if (oldRoot != null) {
297
                Document doc = oldRoot.getOwnerDocument();
298
                Element newRoot = doc.createElementNS (EjbJarProjectType.PROJECT_CONFIGURATION_NAMESPACE,"data"); //NOI18N
299
                copyDocument (doc, oldRoot, newRoot);
300
                if(version == 1) {
301
                    //1=>2 upgrade
302
                    Element sourceRoots = doc.createElementNS(EjbJarProjectType.PROJECT_CONFIGURATION_NAMESPACE,"source-roots");  //NOI18N
303
                    Element root = doc.createElementNS (EjbJarProjectType.PROJECT_CONFIGURATION_NAMESPACE,"root");   //NOI18N
304
                    root.setAttribute ("id","src.dir");   //NOI18N
305
                    sourceRoots.appendChild(root);
306
                    newRoot.appendChild (sourceRoots);
307
                    Element testRoots = doc.createElementNS(EjbJarProjectType.PROJECT_CONFIGURATION_NAMESPACE,"test-roots");  //NOI18N
308
                    root = doc.createElementNS (EjbJarProjectType.PROJECT_CONFIGURATION_NAMESPACE,"root");   //NOI18N
309
                    root.setAttribute ("id","test.src.dir");   //NOI18N
310
                    testRoots.appendChild (root);
311
                    newRoot.appendChild (testRoots);
312
                }
313
                if(version == 1 || version == 2) {
314
                    //2=>3 upgrade
315
                    NodeList libList = newRoot.getElementsByTagNameNS(ns, INCLUDED_LIBRARY_ELEMENT);
316
                    for (int i = 0; i < libList.getLength(); i++) {
317
                        if (libList.item(i).getNodeType() == Node.ELEMENT_NODE) {
318
                            Element library = (Element) libList.item(i);
319
                            String fileText = findText(library);
320
                            if (fileText.startsWith ("libs.")) {
321
                                String libName = fileText.substring(6, fileText.indexOf(".classpath")); //NOI18N
322
                                List/*<URL>*/ roots = LibraryManager.getDefault().getLibrary(libName).getContent("classpath"); //NOI18N
323
                                ArrayList<FileObject> files = new ArrayList<FileObject>();
324
                                ArrayList<FileObject> dirs = new ArrayList<FileObject>();
325
                                for (Iterator it = roots.iterator(); it.hasNext();) {
326
                                    URL rootUrl = (URL) it.next();
327
                                    FileObject root = org.openide.filesystems.URLMapper.findFileObject (rootUrl);
328
                                    if ("jar".equals(rootUrl.getProtocol())) {  //NOI18N
329
                                        root = FileUtil.getArchiveFile (root);
330
                                    }
331
                                    if (root != null) {
332
                                        if (root.isData()) {
333
                                            files.add(root);
334
                                        } else {
335
                                            dirs.add(root);
336
                                        }
337
                                    }
338
                                }
339
                                if (files.size() > 0) {
340
                                    library.setAttribute(ATTR_FILES, "" + files.size()); //NOI18N
341
                                }
342
                                if (dirs.size() > 0) {
343
                                    library.setAttribute(ATTR_DIRS, "" + dirs.size()); //NOI18N
344
                                }
345
                            }
346
                        }
347
                    }
348
                }
349
350
                cachedElement = updateMinAntVersion(newRoot, doc);
351
            }
352
        }
353
        return cachedElement;
354
    }
355
356
    private static void copyDocument (Document doc, Element from, Element to) {
357
        NodeList nl = from.getChildNodes();
358
        int length = nl.getLength();
359
        for (int i=0; i< length; i++) {
360
            Node node = nl.item (i);
361
            Node newNode = null;
362
            switch (node.getNodeType()) {
363
                case Node.ELEMENT_NODE:
364
                    Element oldElement = (Element) node;
365
                    newNode = doc.createElementNS(EjbJarProjectType.PROJECT_CONFIGURATION_NAMESPACE,oldElement.getTagName());
366
                    //copy attributes
367
                    NamedNodeMap m = oldElement.getAttributes();
368
                    Element newElement = (Element) newNode;
369
                    for (int index = 0; index < m.getLength(); index++) {
370
                        Node attr = m.item(index);
371
                        newElement.setAttribute(attr.getNodeName(), attr.getNodeValue());
372
                    }
373
                    copyDocument(doc,oldElement,(Element)newNode);
374
                    break;
375
                case Node.TEXT_NODE:
376
                    Text oldText = (Text) node;
377
                    newNode = doc.createTextNode(oldText.getData());
378
                    break;
379
                case Node.COMMENT_NODE:
380
                    Comment oldComment = (Comment) node;
381
                    newNode = doc.createComment(oldComment.getData());
382
                    break;
383
            }
384
            if (newNode != null) {
385
                to.appendChild (newNode);
386
            }
387
        }
388
    }
389
390
    private static Element updateMinAntVersion (final Element root, final Document doc) {
391
        NodeList list = root.getElementsByTagNameNS (EjbJarProjectType.PROJECT_CONFIGURATION_NAMESPACE,MINIMUM_ANT_VERSION_ELEMENT);
392
        if (list.getLength() == 1) {
393
            Element me = (Element) list.item(0);
394
            list = me.getChildNodes();
395
            if (list.getLength() == 1) {
396
                me.replaceChild (doc.createTextNode(EjbJarProjectGenerator.MINIMUM_ANT_VERSION), list.item(0));
397
                return root;
398
            }
399
        }
400
        assert false : "Invalid project file"; //NOI18N
401
        return root;
402
    }
403
404
    /**
405
     * Creates an default Notifier. The default notifier displays a dialog warning user about project update.
406
     * @return notifier
407
     */
408
    public static Notifier createDefaultNotifier () {
409
        return new Notifier() {
410
            public boolean canUpdate() {
411
                return DialogDisplayer.getDefault().notify(
412
                    new NotifyDescriptor.Confirmation (NbBundle.getMessage(UpdateHelper.class,"TXT_ProjectUpdate",BUILD_NUMBER),
413
                        NbBundle.getMessage(UpdateHelper.class,"TXT_ProjectUpdateTitle"),
414
                        NotifyDescriptor.YES_NO_OPTION)) == NotifyDescriptor.YES_OPTION;
415
            }
416
        };
417
    }
418
419
    /**
420
     * Extract nested text from a node.
421
     * Currently does not handle coalescing text nodes, CDATA sections, etc.
422
     * @param parent a parent node
423
     * @return the nested text, or null if none was found
424
     */
425
    private static String findText(Node parent) {
426
        NodeList l = parent.getChildNodes();
427
        for (int i = 0; i < l.getLength(); i++) {
428
            if (l.item(i).getNodeType() == Node.TEXT_NODE) {
429
                Text text = (Text)l.item(i);
430
                return text.getNodeValue();
431
            }
432
        }
433
        return null;
434
    }
435
436
437
    /**
438
     * Interface used by the UpdateHelper to ask user about
439
     * the project update.
440
     */
441
    public static interface Notifier {
442
        /**
443
         * Asks user to update the project
444
         * @return true if the project should be updated
445
         */
446
        public boolean canUpdate ();
447
    }
448
}
(-)a/j2ee.ejbjarproject/src/org/netbeans/modules/j2ee/ejbjarproject/UpdateProjectImpl.java (+327 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 1997-2007 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 2008 Sun Microsystems, Inc.
38
 */
39
40
package org.netbeans.modules.j2ee.ejbjarproject;
41
42
import java.io.IOException;
43
import java.net.URL;
44
import java.util.ArrayList;
45
import java.util.Iterator;
46
import java.util.List;
47
import org.netbeans.api.project.Project;
48
import org.netbeans.api.project.ProjectManager;
49
import org.netbeans.api.project.libraries.LibraryManager;
50
import org.netbeans.modules.j2ee.ejbjarproject.api.EjbJarProjectGenerator;
51
import org.netbeans.modules.java.api.common.ant.UpdateImplementation;
52
import org.netbeans.spi.project.AuxiliaryConfiguration;
53
import org.netbeans.spi.project.support.ant.AntProjectHelper;
54
import org.netbeans.spi.project.support.ant.EditableProperties;
55
import org.netbeans.spi.project.support.ant.GeneratedFilesHelper;
56
import org.openide.DialogDisplayer;
57
import org.openide.NotifyDescriptor;
58
import org.openide.filesystems.FileObject;
59
import org.openide.filesystems.FileUtil;
60
import org.openide.util.Mutex;
61
import org.openide.util.NbBundle;
62
import org.w3c.dom.Comment;
63
import org.w3c.dom.Document;
64
import org.w3c.dom.Element;
65
import org.w3c.dom.NamedNodeMap;
66
import org.w3c.dom.Node;
67
import org.w3c.dom.NodeList;
68
import org.w3c.dom.Text;
69
70
/**
71
 *
72
 * @author Tomas Mysik
73
 */
74
public class UpdateProjectImpl implements UpdateImplementation {
75
76
    private static final String BUILD_NUMBER = System.getProperty("netbeans.buildnumber"); // NOI18N
77
    private static final String INCLUDED_LIBRARY_ELEMENT = "included-library"; //NOI18N
78
    private static final String MINIMUM_ANT_VERSION_ELEMENT = "minimum-ant-version"; // NOI18N
79
    private static final String ATTR_FILES = "files"; //NOI18N
80
    private static final String ATTR_DIRS = "dirs"; //NOI18N
81
82
    private final Project project;
83
    private final AntProjectHelper helper;
84
    private final AuxiliaryConfiguration cfg;
85
    private final GeneratedFilesHelper genFileHelper;
86
    private boolean alreadyAskedInWriteAccess;
87
    private Boolean isCurrent;
88
    private Element cachedElement;
89
90
    /**
91
     * Creates new UpdateHelper
92
     * @param project
93
     * @param helper AntProjectHelper
94
     * @param cfg AuxiliaryConfiguration
95
     * @param genFileHelper GeneratedFilesHelper
96
     * @param notifier used to ask user about project update
97
     */
98
    UpdateProjectImpl(Project project, AntProjectHelper helper, AuxiliaryConfiguration cfg,
99
            GeneratedFilesHelper genFileHelper) {
100
        assert project != null && helper != null && cfg != null && genFileHelper != null;
101
        this.project = project;
102
        this.helper = helper;
103
        this.cfg = cfg;
104
        this.genFileHelper = genFileHelper;
105
    }
106
107
    public boolean isCurrent() {
108
        return ProjectManager.mutex().readAccess(new Mutex.Action<Boolean>() {
109
            public Boolean run() {
110
                synchronized (this) {
111
                    if (isCurrent == null) {
112
                        if ((cfg.getConfigurationFragment("data","http://www.netbeans.org/ns/j2ee-ejbjarproject/1",true) != null) ||
113
                        (cfg.getConfigurationFragment("data","http://www.netbeans.org/ns/j2ee-ejbjarproject/2",true) != null)) {
114
                            isCurrent = Boolean.FALSE;
115
                        } else {
116
                            isCurrent = Boolean.TRUE;
117
                        }
118
                    }
119
                    return isCurrent;
120
                }
121
            }
122
        }).booleanValue();
123
    }
124
125
    public boolean canUpdate() {
126
        //Ask just once under a single write access
127
        if (alreadyAskedInWriteAccess) {
128
            return false;
129
        }
130
        else {
131
            boolean canUpdate = showUpdateDialog();
132
            if (!canUpdate) {
133
                alreadyAskedInWriteAccess = true;
134
                ProjectManager.mutex().postReadRequest(new Runnable() {
135
                    public void run() {
136
                        alreadyAskedInWriteAccess = false;
137
                    }
138
                });
139
            }
140
            return canUpdate;
141
        }
142
    }
143
144
    public void saveUpdate(EditableProperties props) throws IOException {
145
        this.helper.putPrimaryConfigurationData(getUpdatedSharedConfigurationData(),true);
146
        if (this.cfg.getConfigurationFragment("data","http://www.netbeans.org/ns/j2ee-ejbjarproject/1",true) != null) { //NOI18N
147
            //version 1
148
            this.cfg.removeConfigurationFragment("data","http://www.netbeans.org/ns/j2ee-ejbjarproject/1",true); //NOI18N
149
        } else {
150
            //version 2
151
            this.cfg.removeConfigurationFragment("data","http://www.netbeans.org/ns/j2ee-ejbjarproject/2",true); //NOI18N
152
        }
153
154
        boolean putProps = false;
155
156
        // AB: fix for #55597: should not update the project without adding the properties
157
        // update is only done once, so if we don't add the properties now, we don't get another chance to do so
158
        if (props == null) {
159
            props = helper.getProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH);
160
            putProps = true;
161
        }
162
163
        //add properties needed by 4.1 project
164
        if(props != null) {
165
            props.put("test.src.dir", "test"); //NOI18N
166
        }
167
168
        if (putProps) {
169
            helper.putProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH, props);
170
        }
171
172
        ProjectManager.getDefault().saveProject (this.project);
173
        this.genFileHelper.refreshBuildScript(GeneratedFilesHelper.BUILD_IMPL_XML_PATH, UpdateProjectImpl.class.getResource("resources/build-impl.xsl"),
174
            true);
175
        synchronized(this) {
176
            this.isCurrent = Boolean.TRUE;
177
        }
178
    }
179
180
    public Element getUpdatedSharedConfigurationData() {
181
        if (cachedElement == null) {
182
            Element  oldRoot = this.cfg.getConfigurationFragment("data","http://www.netbeans.org/ns/j2ee-ejbjarproject/1",true);    //NOI18N
183
184
            int version = 1;
185
            if (oldRoot == null) {
186
                version = 2;
187
                oldRoot = this.cfg.getConfigurationFragment("data","http://www.netbeans.org/ns/j2ee-ejbjarproject/2",true);    //NOI18N
188
            }
189
            final String ns = version == 1 ? "http://www.netbeans.org/ns/j2ee-ejbjarproject/1" : "http://www.netbeans.org/ns/j2ee-ejbjarproject/2"; //NOI18N
190
191
            if (oldRoot != null) {
192
                Document doc = oldRoot.getOwnerDocument();
193
                Element newRoot = doc.createElementNS (EjbJarProjectType.PROJECT_CONFIGURATION_NAMESPACE,"data"); //NOI18N
194
                copyDocument (doc, oldRoot, newRoot);
195
                if(version == 1) {
196
                    //1=>2 upgrade
197
                    Element sourceRoots = doc.createElementNS(EjbJarProjectType.PROJECT_CONFIGURATION_NAMESPACE,"source-roots");  //NOI18N
198
                    Element root = doc.createElementNS (EjbJarProjectType.PROJECT_CONFIGURATION_NAMESPACE,"root");   //NOI18N
199
                    root.setAttribute ("id","src.dir");   //NOI18N
200
                    sourceRoots.appendChild(root);
201
                    newRoot.appendChild (sourceRoots);
202
                    Element testRoots = doc.createElementNS(EjbJarProjectType.PROJECT_CONFIGURATION_NAMESPACE,"test-roots");  //NOI18N
203
                    root = doc.createElementNS (EjbJarProjectType.PROJECT_CONFIGURATION_NAMESPACE,"root");   //NOI18N
204
                    root.setAttribute ("id","test.src.dir");   //NOI18N
205
                    testRoots.appendChild (root);
206
                    newRoot.appendChild (testRoots);
207
                }
208
                if(version == 1 || version == 2) {
209
                    //2=>3 upgrade
210
                    NodeList libList = newRoot.getElementsByTagNameNS(ns, INCLUDED_LIBRARY_ELEMENT);
211
                    for (int i = 0; i < libList.getLength(); i++) {
212
                        if (libList.item(i).getNodeType() == Node.ELEMENT_NODE) {
213
                            Element library = (Element) libList.item(i);
214
                            String fileText = findText(library);
215
                            if (fileText.startsWith ("libs.")) {
216
                                String libName = fileText.substring(6, fileText.indexOf(".classpath")); //NOI18N
217
                                List/*<URL>*/ roots = LibraryManager.getDefault().getLibrary(libName).getContent("classpath"); //NOI18N
218
                                ArrayList<FileObject> files = new ArrayList<FileObject>();
219
                                ArrayList<FileObject> dirs = new ArrayList<FileObject>();
220
                                for (Iterator it = roots.iterator(); it.hasNext();) {
221
                                    URL rootUrl = (URL) it.next();
222
                                    FileObject root = org.openide.filesystems.URLMapper.findFileObject (rootUrl);
223
                                    if ("jar".equals(rootUrl.getProtocol())) {  //NOI18N
224
                                        root = FileUtil.getArchiveFile (root);
225
                                    }
226
                                    if (root != null) {
227
                                        if (root.isData()) {
228
                                            files.add(root);
229
                                        } else {
230
                                            dirs.add(root);
231
                                        }
232
                                    }
233
                                }
234
                                if (files.size() > 0) {
235
                                    library.setAttribute(ATTR_FILES, "" + files.size()); //NOI18N
236
                                }
237
                                if (dirs.size() > 0) {
238
                                    library.setAttribute(ATTR_DIRS, "" + dirs.size()); //NOI18N
239
                                }
240
                            }
241
                        }
242
                    }
243
                }
244
245
                cachedElement = updateMinAntVersion(newRoot, doc);
246
            }
247
        }
248
        return cachedElement;
249
    }
250
251
    public EditableProperties getUpdatedProjectProperties() {
252
        // XXX no need to update? original comment was: Properties are the same in both j2seproject/1 and j2seproject/2
253
        return helper.getProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH);
254
    }
255
256
    private static void copyDocument (Document doc, Element from, Element to) {
257
        NodeList nl = from.getChildNodes();
258
        int length = nl.getLength();
259
        for (int i=0; i< length; i++) {
260
            Node node = nl.item (i);
261
            Node newNode = null;
262
            switch (node.getNodeType()) {
263
                case Node.ELEMENT_NODE:
264
                    Element oldElement = (Element) node;
265
                    newNode = doc.createElementNS(EjbJarProjectType.PROJECT_CONFIGURATION_NAMESPACE,oldElement.getTagName());
266
                    //copy attributes
267
                    NamedNodeMap m = oldElement.getAttributes();
268
                    Element newElement = (Element) newNode;
269
                    for (int index = 0; index < m.getLength(); index++) {
270
                        Node attr = m.item(index);
271
                        newElement.setAttribute(attr.getNodeName(), attr.getNodeValue());
272
                    }
273
                    copyDocument(doc,oldElement,(Element)newNode);
274
                    break;
275
                case Node.TEXT_NODE:
276
                    Text oldText = (Text) node;
277
                    newNode = doc.createTextNode(oldText.getData());
278
                    break;
279
                case Node.COMMENT_NODE:
280
                    Comment oldComment = (Comment) node;
281
                    newNode = doc.createComment(oldComment.getData());
282
                    break;
283
            }
284
            if (newNode != null) {
285
                to.appendChild (newNode);
286
            }
287
        }
288
    }
289
290
    private static Element updateMinAntVersion (final Element root, final Document doc) {
291
        NodeList list = root.getElementsByTagNameNS (EjbJarProjectType.PROJECT_CONFIGURATION_NAMESPACE,MINIMUM_ANT_VERSION_ELEMENT);
292
        if (list.getLength() == 1) {
293
            Element me = (Element) list.item(0);
294
            list = me.getChildNodes();
295
            if (list.getLength() == 1) {
296
                me.replaceChild (doc.createTextNode(EjbJarProjectGenerator.MINIMUM_ANT_VERSION), list.item(0));
297
                return root;
298
            }
299
        }
300
        assert false : "Invalid project file"; //NOI18N
301
        return root;
302
    }
303
304
    /**
305
     * Extract nested text from a node.
306
     * Currently does not handle coalescing text nodes, CDATA sections, etc.
307
     * @param parent a parent node
308
     * @return the nested text, or null if none was found
309
     */
310
    private static String findText(Node parent) {
311
        NodeList l = parent.getChildNodes();
312
        for (int i = 0; i < l.getLength(); i++) {
313
            if (l.item(i).getNodeType() == Node.TEXT_NODE) {
314
                Text text = (Text)l.item(i);
315
                return text.getNodeValue();
316
            }
317
        }
318
        return null;
319
    }
320
321
    private boolean showUpdateDialog() {
322
        return DialogDisplayer.getDefault().notify(
323
            new NotifyDescriptor.Confirmation (NbBundle.getMessage(UpdateProjectImpl.class,"TXT_ProjectUpdate",BUILD_NUMBER),
324
                NbBundle.getMessage(UpdateProjectImpl.class,"TXT_ProjectUpdateTitle"),
325
                NotifyDescriptor.YES_NO_OPTION)) == NotifyDescriptor.YES_OPTION;
326
    }
327
}
(-)a/j2ee.ejbjarproject/src/org/netbeans/modules/j2ee/ejbjarproject/api/EjbJarProjectGenerator.java (-3 / +3 lines)
Lines 71-80 import org.netbeans.modules.j2ee.deploym Link Here
71
import org.netbeans.modules.j2ee.deployment.devmodules.api.J2eePlatform;
71
import org.netbeans.modules.j2ee.deployment.devmodules.api.J2eePlatform;
72
import org.netbeans.modules.j2ee.ejbjarproject.EjbJarProject;
72
import org.netbeans.modules.j2ee.ejbjarproject.EjbJarProject;
73
import org.netbeans.modules.j2ee.ejbjarproject.EjbJarProjectType;
73
import org.netbeans.modules.j2ee.ejbjarproject.EjbJarProjectType;
74
import org.netbeans.modules.j2ee.ejbjarproject.UpdateHelper;
75
import org.netbeans.modules.j2ee.ejbjarproject.Utils;
74
import org.netbeans.modules.j2ee.ejbjarproject.Utils;
76
import org.netbeans.modules.j2ee.ejbjarproject.ui.customizer.EjbJarProjectProperties;
75
import org.netbeans.modules.j2ee.ejbjarproject.ui.customizer.EjbJarProjectProperties;
77
import org.netbeans.modules.j2ee.ejbjarproject.ui.customizer.PlatformUiSupport;
76
import org.netbeans.modules.java.api.common.ant.UpdateHelper;
77
import org.netbeans.modules.java.api.common.ui.PlatformUiSupport;
78
import org.netbeans.modules.websvc.spi.webservices.WebServicesConstants;
78
import org.netbeans.modules.websvc.spi.webservices.WebServicesConstants;
79
import org.openide.filesystems.FileSystem;
79
import org.openide.filesystems.FileSystem;
80
import org.openide.filesystems.FileSystem.AtomicAction;
80
import org.openide.filesystems.FileSystem.AtomicAction;
Lines 510-516 public class EjbJarProjectGenerator { Link Here
510
                                    finalPlatformName = JavaPlatformManager.getDefault().getDefaultPlatform().getDisplayName();
510
                                    finalPlatformName = JavaPlatformManager.getDefault().getDefaultPlatform().getDisplayName();
511
                                }
511
                                }
512
                                PlatformUiSupport.storePlatform(ep, updateHelper, finalPlatformName, sourceLevel != null ? new SpecificationVersion(sourceLevel) : null);
512
                                PlatformUiSupport.storePlatform(ep, updateHelper, EjbJarProjectType.PROJECT_CONFIGURATION_NAMESPACE, finalPlatformName, sourceLevel != null ? new SpecificationVersion(sourceLevel) : null);
513
                                helper.putProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH, ep);
513
                                helper.putProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH, ep);
514
                                ProjectManager.getDefault().saveProject(ProjectManager.getDefault().findProject(helper.getProjectDirectory()));
514
                                ProjectManager.getDefault().saveProject(ProjectManager.getDefault().findProject(helper.getProjectDirectory()));
515
                            } catch (IOException e) {
515
                            } catch (IOException e) {
(-)a/j2ee.ejbjarproject/src/org/netbeans/modules/j2ee/ejbjarproject/classpath/ClassPathProviderImpl.java (-1 / +1 lines)
Lines 47-53 import java.util.HashMap; Link Here
47
import org.netbeans.api.java.classpath.ClassPath;
47
import org.netbeans.api.java.classpath.ClassPath;
48
import org.netbeans.modules.j2ee.ejbjarproject.ui.customizer.EjbJarProjectProperties;
48
import org.netbeans.modules.j2ee.ejbjarproject.ui.customizer.EjbJarProjectProperties;
49
import org.netbeans.modules.j2ee.ejbjarproject.SourceRoots;
49
import org.netbeans.modules.java.api.common.SourceRoots;
50
import org.netbeans.spi.java.classpath.ClassPathFactory;
50
import org.netbeans.spi.java.classpath.ClassPathFactory;
51
import org.netbeans.spi.java.classpath.ClassPathProvider;
51
import org.netbeans.spi.java.classpath.ClassPathProvider;
52
import org.netbeans.spi.java.project.classpath.support.ProjectClassPathSupport;
52
import org.netbeans.spi.java.project.classpath.support.ProjectClassPathSupport;
(-)a/j2ee.ejbjarproject/src/org/netbeans/modules/j2ee/ejbjarproject/classpath/EjbJarProjectClassPathExtender.java (-1 / +1 lines)
Lines 58-69 import org.netbeans.api.project.ant.AntA Link Here
58
import org.netbeans.api.project.ant.AntArtifact;
58
import org.netbeans.api.project.ant.AntArtifact;
59
import org.netbeans.api.project.ProjectManager;
59
import org.netbeans.api.project.ProjectManager;
60
import org.netbeans.api.project.Project;
60
import org.netbeans.api.project.Project;
61
import org.netbeans.modules.java.api.common.ant.UpdateHelper;
61
import org.netbeans.spi.java.project.classpath.ProjectClassPathExtender;
62
import org.netbeans.spi.java.project.classpath.ProjectClassPathExtender;
62
import org.netbeans.spi.project.support.ant.AntProjectHelper;
63
import org.netbeans.spi.project.support.ant.AntProjectHelper;
63
import org.netbeans.spi.project.support.ant.ReferenceHelper;
64
import org.netbeans.spi.project.support.ant.ReferenceHelper;
64
import org.netbeans.spi.project.support.ant.PropertyEvaluator;
65
import org.netbeans.spi.project.support.ant.PropertyEvaluator;
65
import org.netbeans.spi.project.support.ant.EditableProperties;
66
import org.netbeans.spi.project.support.ant.EditableProperties;
66
import org.netbeans.modules.j2ee.ejbjarproject.UpdateHelper;
67
import org.openide.util.Exceptions;
67
import org.openide.util.Exceptions;
68
import org.openide.util.RequestProcessor;
68
import org.openide.util.RequestProcessor;
(-)a/j2ee.ejbjarproject/src/org/netbeans/modules/j2ee/ejbjarproject/classpath/SourcePathImplementation.java (-1 / +1 lines)
Lines 51-58 import java.net.URL; Link Here
51
import java.net.URL;
51
import java.net.URL;
52
import java.util.Iterator;
52
import java.util.Iterator;
53
import java.util.StringTokenizer;
53
import java.util.StringTokenizer;
54
import org.netbeans.modules.j2ee.ejbjarproject.SourceRoots;
55
import org.netbeans.modules.j2ee.ejbjarproject.ui.customizer.EjbJarProjectProperties;
54
import org.netbeans.modules.j2ee.ejbjarproject.ui.customizer.EjbJarProjectProperties;
55
import org.netbeans.modules.java.api.common.SourceRoots;
56
import org.netbeans.spi.java.classpath.ClassPathImplementation;
56
import org.netbeans.spi.java.classpath.ClassPathImplementation;
57
import org.netbeans.spi.java.classpath.PathResourceImplementation;
57
import org.netbeans.spi.java.classpath.PathResourceImplementation;
58
import org.netbeans.spi.java.classpath.support.ClassPathSupport;
58
import org.netbeans.spi.java.classpath.support.ClassPathSupport;
(-)a/j2ee.ejbjarproject/src/org/netbeans/modules/j2ee/ejbjarproject/queries/CompiledSourceForBinaryQuery.java (-195 lines)
Lines 1-195 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 1997-2007 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
 * Contributor(s):
25
 *
26
 * The Original Software is NetBeans. The Initial Developer of the Original
27
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
28
 * Microsystems, Inc. All Rights Reserved.
29
 *
30
 * If you wish your version of this file to be governed by only the CDDL
31
 * or only the GPL Version 2, indicate your decision by adding
32
 * "[Contributor] elects to include this software in this distribution
33
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
34
 * single choice of license, a recipient has the option to distribute
35
 * your version of this file under either the CDDL, the GPL Version 2 or
36
 * to extend the choice of license to its licensees as provided above.
37
 * However, if you add GPL Version 2 code and therefore, elected the GPL
38
 * Version 2 license, then the option applies only if the new code is
39
 * made subject to such option by the copyright holder.
40
 */
41
package org.netbeans.modules.j2ee.ejbjarproject.queries;
42
43
import java.beans.PropertyChangeEvent;
44
import java.beans.PropertyChangeListener;
45
import java.io.File;
46
import java.util.ArrayList;
47
import java.util.Iterator;
48
import javax.swing.event.ChangeEvent;
49
import org.netbeans.modules.j2ee.ejbjarproject.SourceRoots;
50
import org.netbeans.modules.j2ee.ejbjarproject.ui.customizer.EjbJarProjectProperties;
51
import org.netbeans.spi.java.queries.SourceForBinaryQueryImplementation;
52
import org.netbeans.spi.project.support.ant.AntProjectHelper;
53
import org.netbeans.spi.project.support.ant.PropertyEvaluator;
54
import org.openide.filesystems.FileObject;
55
import java.net.URL;
56
import java.net.MalformedURLException;
57
import javax.swing.event.ChangeListener;
58
import org.netbeans.api.java.queries.SourceForBinaryQuery;
59
import java.util.Map;
60
import java.util.HashMap;
61
import org.openide.filesystems.FileUtil;
62
import org.openide.util.Exceptions;
63
64
/**
65
 * Finds sources corresponding to binaries in a J2SE project.
66
 * @author Jesse Glick, Tomas Zezula
67
 */
68
public class CompiledSourceForBinaryQuery implements SourceForBinaryQueryImplementation {
69
70
    private AntProjectHelper helper;
71
    private final PropertyEvaluator evaluator;
72
    private final SourceRoots sourceRoots;
73
    private final SourceRoots testRoots;
74
    private Map<URL,SourceForBinaryQuery.Result>  cache = new HashMap<URL,SourceForBinaryQuery.Result>();
75
76
    public CompiledSourceForBinaryQuery (AntProjectHelper helper,PropertyEvaluator evaluator,
77
            SourceRoots srcRoots, SourceRoots testRoots) {
78
        this.helper = helper;
79
        this.evaluator = evaluator;
80
        this.sourceRoots = srcRoots;
81
        this.testRoots = testRoots;
82
    }
83
84
    public SourceForBinaryQuery.Result findSourceRoots(URL binaryRoot) {
85
        if (FileUtil.getArchiveFile(binaryRoot) != null) {
86
            binaryRoot = FileUtil.getArchiveFile(binaryRoot);
87
            // XXX check whether this is really the root
88
        }
89
        SourceForBinaryQuery.Result res = cache.get(binaryRoot);
90
        if (res != null) {
91
            return res;
92
        }
93
        SourceRoots src = null;
94
        if (hasSources(binaryRoot, EjbJarProjectProperties.BUILD_CLASSES_DIR)) {   //NOI18N
95
            src = this.sourceRoots;
96
        }
97
        else if (hasSources (binaryRoot, EjbJarProjectProperties.DIST_JAR)) {      //NOI18N
98
            src = this.sourceRoots;
99
        }
100
        else if (hasSources (binaryRoot, EjbJarProjectProperties.BUILD_TEST_CLASSES_DIR)) {    //NOI18N
101
            src = this.testRoots;
102
        }
103
        if (src == null) {
104
            return null;
105
        }
106
        else {
107
            res = new Result (src);
108
            cache.put (binaryRoot, res);
109
            return res;
110
        }
111
    }
112
113
114
    private boolean hasSources (URL binaryRoot, String binaryProperty) {
115
        try {
116
            //TODO: Fix this. Use FileUtil.getArchiveFile.
117
            if (binaryRoot.getProtocol().equals("jar")) {  // NOI18N
118
                // We are interested in the JAR file itself.
119
                // Note that this impl therefore accepts *both* file:/tmp/foo.jar
120
                // and jar:file:/tmp/foo.jar!/ as equivalent (like URLClassLoader).
121
                String surl = binaryRoot.toExternalForm();
122
                if (surl.endsWith("!/")) { // NOI18N
123
                    binaryRoot = new URL(surl.substring(4, surl.length() - 2));
124
                } else if (surl.lastIndexOf("!/") == -1) { // NOI18N
125
                    // Legal??
126
                    binaryRoot = new URL(surl.substring(4));
127
                } else {
128
                    // Some specific path, e.g. jar:file:/tmp/foo.jar!/foo/,
129
                    // which we do not support.
130
                }
131
            }
132
            String outDir = helper.getStandardPropertyEvaluator ().getProperty (binaryProperty);
133
            if (outDir != null) {
134
                File f = helper.resolveFile (outDir);
135
                URL url = f.toURI().toURL();
136
                if (!f.exists() && !f.getPath().toLowerCase().endsWith(".jar")) { // NOI18N
137
                    // non-existing
138
                    assert !url.toExternalForm().endsWith("/") : f; // NOI18N
139
                    url = new URL(url.toExternalForm() + "/"); // NOI18N
140
                }
141
                if (url.equals (binaryRoot)) {
142
                    return true;
143
                }
144
            }
145
        } catch (MalformedURLException malformedURL) {
146
            Exceptions.printStackTrace(malformedURL);
147
        }
148
        return false;
149
    }
150
151
    private static class Result implements SourceForBinaryQuery.Result, PropertyChangeListener {
152
153
        private ArrayList listeners;
154
        private SourceRoots sourceRoots;
155
156
        public Result (SourceRoots sourceRoots) {
157
            this.sourceRoots = sourceRoots;
158
            this.sourceRoots.addPropertyChangeListener(this);
159
        }
160
161
        public FileObject[] getRoots () {
162
             return this.sourceRoots.getRoots(); //No need to cache it, SourceRoots does
163
        }
164
165
        public void addChangeListener (ChangeListener l) {
166
            //TODO: Implement this if needed (source folder can be changed)
167
        }
168
169
        public void removeChangeListener (ChangeListener l) {
170
            //TODO: Implement this if needed (source folder can be changed)
171
        }
172
173
        public void propertyChange(PropertyChangeEvent evt) {
174
            if (SourceRoots.PROP_ROOTS.equals(evt.getPropertyName())) {
175
                this.fireChange ();
176
            }
177
        }
178
179
        private void fireChange() {
180
            Iterator it;
181
            synchronized (this) {
182
                if (this.listeners == null) {
183
                    return;
184
                }
185
                it = ((ArrayList)this.listeners.clone()).iterator();
186
            }
187
            ChangeEvent event = new ChangeEvent(this);
188
            while (it.hasNext()) {
189
                ((ChangeListener)it.next()).stateChanged(event);
190
            }
191
        }
192
193
    }
194
195
}
(-)a/j2ee.ejbjarproject/src/org/netbeans/modules/j2ee/ejbjarproject/queries/EjbJarProjectEncodingQueryImpl.java (-99 lines)
Lines 1-99 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 1997-2007 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
 * Contributor(s):
25
 *
26
 * The Original Software is NetBeans. The Initial Developer of the Original
27
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
28
 * Microsystems, Inc. All Rights Reserved.
29
 *
30
 * If you wish your version of this file to be governed by only the CDDL
31
 * or only the GPL Version 2, indicate your decision by adding
32
 * "[Contributor] elects to include this software in this distribution
33
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
34
 * single choice of license, a recipient has the option to distribute
35
 * your version of this file under either the CDDL, the GPL Version 2 or
36
 * to extend the choice of license to its licensees as provided above.
37
 * However, if you add GPL Version 2 code and therefore, elected the GPL
38
 * Version 2 license, then the option applies only if the new code is
39
 * made subject to such option by the copyright holder.
40
 */
41
42
package org.netbeans.modules.j2ee.ejbjarproject.queries;
43
44
import java.beans.PropertyChangeEvent;
45
import java.beans.PropertyChangeListener;
46
import java.nio.charset.Charset;
47
import java.nio.charset.IllegalCharsetNameException;
48
import org.netbeans.modules.j2ee.ejbjarproject.ui.customizer.EjbJarProjectProperties;
49
import org.netbeans.spi.queries.FileEncodingQueryImplementation;
50
import org.netbeans.spi.project.support.ant.PropertyEvaluator;
51
import org.openide.filesystems.FileObject;
52
53
/**
54
 *
55
 * @author Tomas Zezula
56
 */
57
public class EjbJarProjectEncodingQueryImpl extends FileEncodingQueryImplementation implements PropertyChangeListener {
58
59
60
    private final PropertyEvaluator eval;
61
    private Charset cache;
62
63
    /** Creates a new instance of J2SEProjectEncodingQueryImpl */
64
    public EjbJarProjectEncodingQueryImpl(final PropertyEvaluator eval) {
65
        assert eval != null;
66
        this.eval = eval;
67
        this.eval.addPropertyChangeListener(this);
68
    }
69
70
    public Charset getEncoding(FileObject file) {
71
        assert file != null;
72
        synchronized (this) {
73
            if (cache != null) {
74
                return cache;
75
            }
76
        }
77
        String enc = eval.getProperty(EjbJarProjectProperties.SOURCE_ENCODING);
78
        synchronized (this) {
79
            if (cache == null) {
80
                try {
81
                    cache = enc == null ? Charset.defaultCharset() : Charset.forName(enc);
82
                } catch (IllegalCharsetNameException exception) {
83
                    return null;
84
                }
85
            }
86
            return cache;
87
        }
88
    }
89
90
    public void propertyChange(PropertyChangeEvent event) {
91
        String propName = event.getPropertyName();
92
        if (propName == null || propName.equals(EjbJarProjectProperties.SOURCE_ENCODING)) {
93
            synchronized (this) {
94
                cache = null;
95
            }
96
        }
97
    }
98
99
}
(-)a/j2ee.ejbjarproject/src/org/netbeans/modules/j2ee/ejbjarproject/queries/JavadocForBinaryQueryImpl.java (-183 lines)
Lines 1-183 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 1997-2007 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
 * Contributor(s):
25
 *
26
 * The Original Software is NetBeans. The Initial Developer of the Original
27
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
28
 * Microsystems, Inc. All Rights Reserved.
29
 *
30
 * If you wish your version of this file to be governed by only the CDDL
31
 * or only the GPL Version 2, indicate your decision by adding
32
 * "[Contributor] elects to include this software in this distribution
33
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
34
 * single choice of license, a recipient has the option to distribute
35
 * your version of this file under either the CDDL, the GPL Version 2 or
36
 * to extend the choice of license to its licensees as provided above.
37
 * However, if you add GPL Version 2 code and therefore, elected the GPL
38
 * Version 2 license, then the option applies only if the new code is
39
 * made subject to such option by the copyright holder.
40
 */
41
package org.netbeans.modules.j2ee.ejbjarproject.queries;
42
43
import java.beans.PropertyChangeEvent;
44
import java.beans.PropertyChangeListener;
45
import java.io.File;
46
import java.net.MalformedURLException;
47
import java.net.URL;
48
import javax.swing.event.ChangeListener;
49
import org.netbeans.api.java.queries.JavadocForBinaryQuery;
50
import org.netbeans.modules.j2ee.ejbjarproject.ui.customizer.EjbJarProjectProperties;
51
import org.netbeans.spi.java.queries.JavadocForBinaryQueryImplementation;
52
import org.netbeans.spi.project.support.ant.AntProjectHelper;
53
import org.netbeans.spi.project.support.ant.PropertyEvaluator;
54
import org.openide.filesystems.FileUtil;
55
import org.openide.util.ChangeSupport;
56
import org.openide.util.Exceptions;
57
import org.openide.util.WeakListeners;
58
59
60
/**
61
 * Finds Javadoc (if it is built) corresponding to binaries in web project.
62
 * @author David Konecny, Jesse Glick
63
 */
64
public class JavadocForBinaryQueryImpl implements JavadocForBinaryQueryImplementation {
65
66
    private final AntProjectHelper helper;
67
    private final PropertyEvaluator evaluator;
68
69
    public JavadocForBinaryQueryImpl(AntProjectHelper helper, PropertyEvaluator evaluator) {
70
        this.helper = helper;
71
        this.evaluator = evaluator;
72
    }
73
74
    public JavadocForBinaryQuery.Result findJavadoc(final URL binaryRoot) {
75
76
        class R implements JavadocForBinaryQuery.Result, PropertyChangeListener  {
77
78
            private final ChangeSupport changeSupport = new ChangeSupport(this);
79
            private URL[] result;
80
81
            public R () {
82
                JavadocForBinaryQueryImpl.this.evaluator.addPropertyChangeListener (WeakListeners.propertyChange(this,JavadocForBinaryQueryImpl.this.evaluator));
83
            }
84
85
            public synchronized URL[] getRoots() {
86
                if (this.result == null) {
87
                    String javadocDir = evaluator.getProperty(EjbJarProjectProperties.DIST_JAVADOC_DIR);
88
                    if (javadocDir != null) {
89
                        File f = helper.resolveFile(javadocDir);
90
                        try {
91
                            URL url = f.toURI().toURL();
92
                            if (!f.exists()) {
93
                                assert !url.toExternalForm().endsWith("/") : f; // NOI18N
94
                                url = new URL(url.toExternalForm() + "/"); // NOI18N
95
                            }
96
                            this.result = new URL[] {url};
97
                        } catch (MalformedURLException e) {
98
                            this.result = new URL[0];
99
                            Exceptions.printStackTrace(e);
100
                        }
101
                    }
102
                    else {
103
                        this.result = new URL[0];
104
                    }
105
                }
106
                return this.result;
107
            }
108
            public void addChangeListener(final ChangeListener l) {
109
                assert l != null;
110
                changeSupport.addChangeListener(l);
111
            }
112
            public void removeChangeListener(final ChangeListener l) {
113
                assert l != null;
114
                changeSupport.removeChangeListener(l);
115
            }
116
117
            public void propertyChange (final PropertyChangeEvent event) {
118
                if (EjbJarProjectProperties.DIST_JAVADOC_DIR.equals(event.getPropertyName())) {
119
                    synchronized (this) {
120
                        result = null;
121
                    }
122
                    this.changeSupport.fireChange ();
123
                }
124
            }
125
        }
126
        if (isRootOwner(binaryRoot, EjbJarProjectProperties.BUILD_CLASSES_DIR) || isRootOwner (binaryRoot, EjbJarProjectProperties.DIST_JAR)) {
127
            return new R();
128
        }
129
        return null;
130
    }
131
132
    private boolean isRootOwner (URL binaryRoot, String binaryProperty) {
133
        try {
134
            if (FileUtil.getArchiveFile(binaryRoot) != null) {
135
                binaryRoot = FileUtil.getArchiveFile(binaryRoot);
136
                // XXX check whether this is really the root
137
            }
138
            String outDir = evaluator.getProperty(binaryProperty);
139
            if (outDir != null) {
140
                File f = helper.resolveFile (outDir);
141
                URL url = f.toURI().toURL();
142
                if (!f.exists() && !f.getPath().toLowerCase().endsWith(".jar")) { // NOI18N
143
                    assert !url.toExternalForm().endsWith("/") : f; // NOI18N
144
                    url = new URL(url.toExternalForm() + "/"); // NOI18N
145
                }
146
                return url.equals(binaryRoot) ||
147
                        binaryRoot.toExternalForm().startsWith(url.toExternalForm());
148
            }
149
        } catch (MalformedURLException malformedURL) {
150
            Exceptions.printStackTrace(malformedURL);
151
        }
152
        return false;
153
    }
154
155
//    private URL getJavadoc(URL binaryRoot, String binaryProperty, String javadocProperty) {
156
//        try {
157
//            if (FileUtil.getArchiveFile(binaryRoot) != null) {
158
//                binaryRoot = FileUtil.getArchiveFile(binaryRoot);
159
//            }
160
//            String outDir = evaluator.getProperty(binaryProperty);
161
//            if (outDir != null) {
162
//                File f = helper.resolveFile (outDir);
163
//                URL url = f.toURI().toURL();
164
//                if (!f.exists() && !f.getPath().toLowerCase().endsWith(".jar")) {
165
//                    assert !url.toExternalForm().endsWith("/") : f;
166
//                    url = new URL(url.toExternalForm() + "/");
167
//                }
168
//                if (url.equals(binaryRoot) ||
169
//                        binaryRoot.toExternalForm().startsWith(url.toExternalForm())) {
170
//                    String javadocDir = evaluator.getProperty(javadocProperty);
171
//                    if (javadocDir != null) {
172
//                        f = helper.resolveFile(javadocDir);
173
//                        return f.toURI().toURL();
174
//                    }
175
//                }
176
//            }
177
//        } catch (MalformedURLException malformedURL) {
178
//            ErrorManager.getDefault().notify(malformedURL);
179
//        }
180
//        return null;
181
//    }
182
183
}
(-)a/j2ee.ejbjarproject/src/org/netbeans/modules/j2ee/ejbjarproject/queries/SourceLevelQueryImpl.java (-71 lines)
Lines 1-71 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 1997-2007 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
 * Contributor(s):
25
 *
26
 * The Original Software is NetBeans. The Initial Developer of the Original
27
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
28
 * Microsystems, Inc. All Rights Reserved.
29
 *
30
 * If you wish your version of this file to be governed by only the CDDL
31
 * or only the GPL Version 2, indicate your decision by adding
32
 * "[Contributor] elects to include this software in this distribution
33
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
34
 * single choice of license, a recipient has the option to distribute
35
 * your version of this file under either the CDDL, the GPL Version 2 or
36
 * to extend the choice of license to its licensees as provided above.
37
 * However, if you add GPL Version 2 code and therefore, elected the GPL
38
 * Version 2 license, then the option applies only if the new code is
39
 * made subject to such option by the copyright holder.
40
 */
41
package org.netbeans.modules.j2ee.ejbjarproject.queries;
42
43
import org.netbeans.spi.java.queries.SourceLevelQueryImplementation;
44
import org.netbeans.spi.project.support.ant.AntProjectHelper;
45
import org.netbeans.spi.project.support.ant.PropertyEvaluator;
46
import org.openide.filesystems.FileObject;
47
48
/**
49
 * Returns source level of project sources.
50
 * @author David Konecny
51
 */
52
public class SourceLevelQueryImpl implements SourceLevelQueryImplementation {
53
54
    private final AntProjectHelper helper;
55
    private final PropertyEvaluator evaluator;
56
57
    public SourceLevelQueryImpl(AntProjectHelper helper, PropertyEvaluator evaluator) {
58
        this.helper = helper;
59
        this.evaluator = evaluator;
60
    }
61
62
    public String getSourceLevel(FileObject javaFile) {
63
        String sl = evaluator.getProperty("javac.source"); //NOI18N
64
        if (sl != null && sl.length() > 0) {
65
            return sl;
66
        } else {
67
            return null;
68
        }
69
    }
70
71
}
(-)a/j2ee.ejbjarproject/src/org/netbeans/modules/j2ee/ejbjarproject/queries/UnitTestForSourceQueryImpl.java (-81 lines)
Lines 1-81 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 1997-2007 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
 * Contributor(s):
25
 *
26
 * The Original Software is NetBeans. The Initial Developer of the Original
27
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
28
 * Microsystems, Inc. All Rights Reserved.
29
 *
30
 * If you wish your version of this file to be governed by only the CDDL
31
 * or only the GPL Version 2, indicate your decision by adding
32
 * "[Contributor] elects to include this software in this distribution
33
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
34
 * single choice of license, a recipient has the option to distribute
35
 * your version of this file under either the CDDL, the GPL Version 2 or
36
 * to extend the choice of license to its licensees as provided above.
37
 * However, if you add GPL Version 2 code and therefore, elected the GPL
38
 * Version 2 license, then the option applies only if the new code is
39
 * made subject to such option by the copyright holder.
40
 */
41
package org.netbeans.modules.j2ee.ejbjarproject.queries;
42
import java.net.URL;
43
import org.netbeans.api.project.FileOwnerQuery;
44
import org.netbeans.api.project.Project;
45
import org.netbeans.spi.java.queries.MultipleRootsUnitTestForSourceQueryImplementation;
46
import org.netbeans.modules.j2ee.ejbjarproject.SourceRoots;
47
import org.openide.filesystems.FileObject;
48
49
public class UnitTestForSourceQueryImpl implements MultipleRootsUnitTestForSourceQueryImplementation {
50
51
    private final SourceRoots sourceRoots;
52
    private final SourceRoots testRoots;
53
54
    public UnitTestForSourceQueryImpl(SourceRoots sourceRoots, SourceRoots testRoots) {
55
        this.sourceRoots = sourceRoots;
56
        this.testRoots = testRoots;
57
    }
58
59
    public URL[] findUnitTests(FileObject source) {
60
        return find(source, sourceRoots, testRoots); // NOI18N
61
    }
62
63
    public URL[] findSources(FileObject unitTest) {
64
        return find(unitTest, testRoots, sourceRoots); // NOI18N
65
    }
66
67
    private URL[] find(FileObject file, SourceRoots from, SourceRoots to) {
68
        Project p = FileOwnerQuery.getOwner(file);
69
        if (p == null) {
70
            return null;
71
        }
72
        FileObject[] fromRoots = from.getRoots();
73
        for (int i = 0; i < fromRoots.length; i++) {
74
            if (fromRoots[i].equals(file)) {
75
                return to.getRootURLs();
76
            }
77
        }
78
        return null;
79
    }
80
81
}
(-)a/j2ee.ejbjarproject/src/org/netbeans/modules/j2ee/ejbjarproject/ui/EjbJarLogicalViewProvider.java (-2 / +2 lines)
Lines 67-73 import javax.swing.event.ChangeListener; Link Here
67
import javax.swing.event.ChangeListener;
67
import javax.swing.event.ChangeListener;
68
import org.netbeans.api.java.platform.JavaPlatformManager;
68
import org.netbeans.api.java.platform.JavaPlatformManager;
69
import org.netbeans.modules.j2ee.deployment.devmodules.spi.J2eeModuleProvider;
69
import org.netbeans.modules.j2ee.deployment.devmodules.spi.J2eeModuleProvider;
70
import org.netbeans.modules.j2ee.ejbjarproject.SourceRoots;
71
import org.openide.nodes.*;
70
import org.openide.nodes.*;
72
import org.openide.util.*;
71
import org.openide.util.*;
Lines 91-97 import org.netbeans.api.project.SourceGr Link Here
91
import org.netbeans.api.project.SourceGroup;
90
import org.netbeans.api.project.SourceGroup;
92
import org.netbeans.api.project.Sources;
91
import org.netbeans.api.project.Sources;
93
import org.netbeans.modules.j2ee.ejbjarproject.ui.customizer.EjbJarProjectProperties;
92
import org.netbeans.modules.j2ee.ejbjarproject.ui.customizer.EjbJarProjectProperties;
94
import org.netbeans.modules.j2ee.ejbjarproject.UpdateHelper;
95
import org.openide.filesystems.FileObject;
93
import org.openide.filesystems.FileObject;
96
import org.openide.loaders.DataFolder;
94
import org.openide.loaders.DataFolder;
97
import org.openide.util.lookup.Lookups;
95
import org.openide.util.lookup.Lookups;
Lines 103-108 import org.netbeans.modules.j2ee.deploym Link Here
103
import org.netbeans.modules.j2ee.deployment.devmodules.spi.InstanceListener;
101
import org.netbeans.modules.j2ee.deployment.devmodules.spi.InstanceListener;
104
import org.netbeans.modules.j2ee.ejbjarproject.EjbJarProject;
102
import org.netbeans.modules.j2ee.ejbjarproject.EjbJarProject;
105
import org.netbeans.modules.j2ee.spi.ejbjar.support.J2eeProjectView;
103
import org.netbeans.modules.j2ee.spi.ejbjar.support.J2eeProjectView;
104
import org.netbeans.modules.java.api.common.SourceRoots;
105
import org.netbeans.modules.java.api.common.ant.UpdateHelper;
106
import org.netbeans.spi.project.ui.support.DefaultProjectOperations;
106
import org.netbeans.spi.project.ui.support.DefaultProjectOperations;
107
import org.netbeans.spi.project.ui.support.NodeFactorySupport;
107
import org.netbeans.spi.project.ui.support.NodeFactorySupport;
108
import org.openide.filesystems.FileStateInvalidException;
108
import org.openide.filesystems.FileStateInvalidException;
(-)a/j2ee.ejbjarproject/src/org/netbeans/modules/j2ee/ejbjarproject/ui/LibrariesNodeFactory.java (-2 / +2 lines)
Lines 53-65 import javax.swing.event.ChangeListener; Link Here
53
import javax.swing.event.ChangeListener;
53
import javax.swing.event.ChangeListener;
54
import org.netbeans.api.project.Project;
54
import org.netbeans.api.project.Project;
55
import org.netbeans.modules.j2ee.ejbjarproject.EjbJarProject;
55
import org.netbeans.modules.j2ee.ejbjarproject.EjbJarProject;
56
import org.netbeans.modules.j2ee.ejbjarproject.SourceRoots;
57
import org.netbeans.modules.j2ee.ejbjarproject.UpdateHelper;
58
import org.netbeans.modules.j2ee.ejbjarproject.classpath.ClassPathSupport;
56
import org.netbeans.modules.j2ee.ejbjarproject.classpath.ClassPathSupport;
59
import org.netbeans.modules.j2ee.ejbjarproject.ui.SourceNodeFactory.PreselectPropertiesAction;
57
import org.netbeans.modules.j2ee.ejbjarproject.ui.SourceNodeFactory.PreselectPropertiesAction;
60
import org.netbeans.modules.j2ee.ejbjarproject.ui.customizer.CustomizerLibraries;
58
import org.netbeans.modules.j2ee.ejbjarproject.ui.customizer.CustomizerLibraries;
61
import org.netbeans.modules.j2ee.ejbjarproject.ui.customizer.EjbJarProjectProperties;
59
import org.netbeans.modules.j2ee.ejbjarproject.ui.customizer.EjbJarProjectProperties;
62
import org.netbeans.modules.j2ee.ejbjarproject.ui.logicalview.libraries.LibrariesNode;
60
import org.netbeans.modules.j2ee.ejbjarproject.ui.logicalview.libraries.LibrariesNode;
61
import org.netbeans.modules.java.api.common.SourceRoots;
62
import org.netbeans.modules.java.api.common.ant.UpdateHelper;
63
import org.netbeans.spi.project.support.ant.PropertyEvaluator;
63
import org.netbeans.spi.project.support.ant.PropertyEvaluator;
64
import org.netbeans.spi.project.support.ant.ReferenceHelper;
64
import org.netbeans.spi.project.support.ant.ReferenceHelper;
65
import org.netbeans.spi.project.ui.support.NodeFactory;
65
import org.netbeans.spi.project.ui.support.NodeFactory;
(-)a/j2ee.ejbjarproject/src/org/netbeans/modules/j2ee/ejbjarproject/ui/customizer/CustomizerLibraries.java (+1 lines)
Lines 55-60 import org.netbeans.api.java.platform.Pl Link Here
55
import org.netbeans.api.java.platform.PlatformsCustomizer;
55
import org.netbeans.api.java.platform.PlatformsCustomizer;
56
import org.netbeans.modules.j2ee.ejbjarproject.classpath.ClassPathSupport;
56
import org.netbeans.modules.j2ee.ejbjarproject.classpath.ClassPathSupport;
57
import org.netbeans.modules.j2ee.ejbjarproject.ui.EjbJarLogicalViewProvider;
57
import org.netbeans.modules.j2ee.ejbjarproject.ui.EjbJarLogicalViewProvider;
58
import org.netbeans.modules.java.api.common.ui.PlatformUiSupport;
58
import org.openide.util.HelpCtx;
59
import org.openide.util.HelpCtx;
59
import org.openide.util.NbBundle;
60
import org.openide.util.NbBundle;
(-)a/j2ee.ejbjarproject/src/org/netbeans/modules/j2ee/ejbjarproject/ui/customizer/CustomizerProviderImpl.java (-1 / +1 lines)
Lines 52-58 import org.netbeans.api.project.Project; Link Here
52
import org.netbeans.api.project.Project;
52
import org.netbeans.api.project.Project;
53
import org.netbeans.api.project.ProjectUtils;
53
import org.netbeans.api.project.ProjectUtils;
54
import org.netbeans.modules.j2ee.ejbjarproject.EjbJarProject;
54
import org.netbeans.modules.j2ee.ejbjarproject.EjbJarProject;
55
import org.netbeans.modules.j2ee.ejbjarproject.UpdateHelper;
55
import org.netbeans.modules.java.api.common.ant.UpdateHelper;
56
import org.netbeans.spi.project.support.ant.PropertyEvaluator;
56
import org.netbeans.spi.project.support.ant.PropertyEvaluator;
57
import org.netbeans.spi.project.support.ant.ReferenceHelper;
57
import org.netbeans.spi.project.support.ant.ReferenceHelper;
58
import org.netbeans.spi.project.ui.CustomizerProvider;
58
import org.netbeans.spi.project.ui.CustomizerProvider;
(-)a/j2ee.ejbjarproject/src/org/netbeans/modules/j2ee/ejbjarproject/ui/customizer/EjbJarProjectProperties.java (-4 / +10 lines)
Lines 67-74 import org.netbeans.api.queries.Collocat Link Here
67
import org.netbeans.api.queries.CollocationQuery;
67
import org.netbeans.api.queries.CollocationQuery;
68
import org.netbeans.api.queries.FileEncodingQuery;
68
import org.netbeans.api.queries.FileEncodingQuery;
69
import org.netbeans.modules.j2ee.deployment.devmodules.api.AntDeploymentHelper;
69
import org.netbeans.modules.j2ee.deployment.devmodules.api.AntDeploymentHelper;
70
import org.netbeans.modules.j2ee.ejbjarproject.SourceRoots;
71
import org.netbeans.modules.j2ee.ejbjarproject.UpdateHelper;
72
import org.netbeans.spi.project.support.ant.PropertyEvaluator;
70
import org.netbeans.spi.project.support.ant.PropertyEvaluator;
73
import org.openide.filesystems.FileUtil;
71
import org.openide.filesystems.FileUtil;
74
import org.openide.util.MutexException;
72
import org.openide.util.MutexException;
Lines 86-94 import org.netbeans.modules.j2ee.deploym Link Here
86
import org.netbeans.modules.j2ee.deployment.devmodules.api.J2eePlatform;
84
import org.netbeans.modules.j2ee.deployment.devmodules.api.J2eePlatform;
87
import org.netbeans.modules.j2ee.ejbjarproject.classpath.ClassPathSupport;
85
import org.netbeans.modules.j2ee.ejbjarproject.classpath.ClassPathSupport;
88
import org.netbeans.modules.j2ee.ejbjarproject.EjbJarProject;
86
import org.netbeans.modules.j2ee.ejbjarproject.EjbJarProject;
87
import org.netbeans.modules.j2ee.ejbjarproject.EjbJarProjectType;
89
import org.netbeans.modules.j2ee.ejbjarproject.EjbJarProjectUtil;
88
import org.netbeans.modules.j2ee.ejbjarproject.EjbJarProjectUtil;
90
import org.netbeans.modules.j2ee.ejbjarproject.Utils;
89
import org.netbeans.modules.j2ee.ejbjarproject.Utils;
91
import org.netbeans.modules.j2ee.ejbjarproject.classpath.ClassPathSupport.Item;
90
import org.netbeans.modules.j2ee.ejbjarproject.classpath.ClassPathSupport.Item;
91
import org.netbeans.modules.java.api.common.SourceRoots;
92
import org.netbeans.modules.java.api.common.ant.UpdateHelper;
93
import org.netbeans.modules.java.api.common.ui.PlatformUiSupport;
92
import org.netbeans.modules.websvc.spi.webservices.WebServicesConstants;
94
import org.netbeans.modules.websvc.spi.webservices.WebServicesConstants;
93
import org.netbeans.spi.project.support.ant.PropertyUtils;
95
import org.netbeans.spi.project.support.ant.PropertyUtils;
94
import org.openide.filesystems.FileObject;
96
import org.openide.filesystems.FileObject;
Lines 304-310 public class EjbJarProjectProperties { Link Here
304
        RUN_TEST_CLASSPATH_MODEL = ClassPathUiSupport.createListModel( cs.itemsIterator( projectProperties.get(RUN_TEST_CLASSPATH), null  ) );
306
        RUN_TEST_CLASSPATH_MODEL = ClassPathUiSupport.createListModel( cs.itemsIterator( projectProperties.get(RUN_TEST_CLASSPATH), null  ) );
305
        PLATFORM_MODEL = PlatformUiSupport.createPlatformComboBoxModel (evaluator.getProperty(JAVA_PLATFORM));
307
        PLATFORM_MODEL = PlatformUiSupport.createPlatformComboBoxModel (evaluator.getProperty(JAVA_PLATFORM));
306
        PLATFORM_LIST_RENDERER = PlatformUiSupport.createPlatformListCellRenderer();
308
        PLATFORM_LIST_RENDERER = PlatformUiSupport.createPlatformListCellRenderer();
307
        JAVAC_SOURCE_MODEL = PlatformUiSupport.createSourceLevelComboBoxModel (PLATFORM_MODEL, evaluator.getProperty(JAVAC_SOURCE), evaluator.getProperty(JAVAC_TARGET), evaluator.getProperty(J2EE_PLATFORM));
309
        PlatformUiSupport.JDK minimalSourceLevel = null;
310
        if (evaluator.getProperty(J2EE_PLATFORM).equals(JAVA_EE_5)) {
311
            minimalSourceLevel = PlatformUiSupport.JDK.VERSION_5;
312
        }
313
        JAVAC_SOURCE_MODEL = PlatformUiSupport.createSourceLevelComboBoxModel (PLATFORM_MODEL, evaluator.getProperty(JAVAC_SOURCE), evaluator.getProperty(JAVAC_TARGET), minimalSourceLevel);
308
        JAVAC_SOURCE_RENDERER = PlatformUiSupport.createSourceLevelListCellRenderer ();
314
        JAVAC_SOURCE_RENDERER = PlatformUiSupport.createSourceLevelListCellRenderer ();
309
        // CustomizerCompile
315
        // CustomizerCompile
Lines 392-398 public class EjbJarProjectProperties { Link Here
392
        projectProperties.setProperty( RUN_TEST_CLASSPATH, run_test_cp );
398
        projectProperties.setProperty( RUN_TEST_CLASSPATH, run_test_cp );
393
        //Handle platform selection and javac.source javac.target properties
399
        //Handle platform selection and javac.source javac.target properties
394
        PlatformUiSupport.storePlatform (projectProperties, updateHelper, PLATFORM_MODEL.getSelectedItem(), JAVAC_SOURCE_MODEL.getSelectedItem());
400
        PlatformUiSupport.storePlatform (projectProperties, updateHelper, EjbJarProjectType.PROJECT_CONFIGURATION_NAMESPACE, PLATFORM_MODEL.getSelectedItem(), JAVAC_SOURCE_MODEL.getSelectedItem());
395
        // Handle other special cases
401
        // Handle other special cases
396
        if ( NO_DEPENDENCIES_MODEL.isSelected() ) { // NOI18N
402
        if ( NO_DEPENDENCIES_MODEL.isSelected() ) { // NOI18N
(-)a/j2ee.ejbjarproject/src/org/netbeans/modules/j2ee/ejbjarproject/ui/customizer/EjbJarSourceRootsUi.java (-1 / +1 lines)
Lines 80-86 import org.netbeans.api.project.FileOwne Link Here
80
import org.netbeans.api.project.FileOwnerQuery;
80
import org.netbeans.api.project.FileOwnerQuery;
81
import org.netbeans.api.project.Project;
81
import org.netbeans.api.project.Project;
82
import org.netbeans.api.project.ProjectInformation;
82
import org.netbeans.api.project.ProjectInformation;
83
import org.netbeans.modules.j2ee.ejbjarproject.SourceRoots;
83
import org.netbeans.modules.java.api.common.SourceRoots;
84
import org.openide.DialogDisplayer;
84
import org.openide.DialogDisplayer;
85
import org.openide.DialogDescriptor;
85
import org.openide.DialogDescriptor;
86
import org.openide.filesystems.FileUtil;
86
import org.openide.filesystems.FileUtil;
(-)a/j2ee.ejbjarproject/src/org/netbeans/modules/j2ee/ejbjarproject/ui/customizer/PlatformUiSupport.java (-694 lines)
Lines 1-694 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 1997-2007 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
 * Contributor(s):
25
 *
26
 * The Original Software is NetBeans. The Initial Developer of the Original
27
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
28
 * Microsystems, Inc. All Rights Reserved.
29
 *
30
 * If you wish your version of this file to be governed by only the CDDL
31
 * or only the GPL Version 2, indicate your decision by adding
32
 * "[Contributor] elects to include this software in this distribution
33
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
34
 * single choice of license, a recipient has the option to distribute
35
 * your version of this file under either the CDDL, the GPL Version 2 or
36
 * to extend the choice of license to its licensees as provided above.
37
 * However, if you add GPL Version 2 code and therefore, elected the GPL
38
 * Version 2 license, then the option applies only if the new code is
39
 * made subject to such option by the copyright holder.
40
 */
41
42
package org.netbeans.modules.j2ee.ejbjarproject.ui.customizer;
43
44
import java.awt.Component;
45
import java.beans.PropertyChangeEvent;
46
import java.beans.PropertyChangeListener;
47
import java.text.MessageFormat;
48
import java.util.ArrayList;
49
import java.util.List;
50
import java.util.Set;
51
import java.util.TreeSet;
52
import java.util.logging.Level;
53
import java.util.logging.Logger;
54
import javax.swing.AbstractListModel;
55
import javax.swing.ComboBoxModel;
56
import javax.swing.DefaultListCellRenderer;
57
import javax.swing.JButton;
58
import javax.swing.JList;
59
import javax.swing.ListCellRenderer;
60
import javax.swing.event.ListDataEvent;
61
import javax.swing.event.ListDataListener;
62
import org.netbeans.api.java.platform.JavaPlatform;
63
import org.netbeans.api.java.platform.JavaPlatformManager;
64
import org.netbeans.api.java.platform.Specification;
65
import org.netbeans.modules.j2ee.ejbjarproject.EjbJarProjectType;
66
import org.netbeans.modules.j2ee.ejbjarproject.UpdateHelper;
67
import org.netbeans.spi.project.support.ant.EditableProperties;
68
import org.openide.DialogDisplayer;
69
import org.openide.NotifyDescriptor;
70
import org.openide.awt.HtmlRenderer;
71
import org.openide.modules.SpecificationVersion;
72
import org.openide.util.NbBundle;
73
import org.openide.util.WeakListeners;
74
import org.w3c.dom.Element;
75
import org.w3c.dom.NodeList;
76
77
/**
78
 * Support class for {@link JavaPlatform} manipulation in ejbjarproject customizer.
79
 * @author tzezula
80
 */
81
public class PlatformUiSupport {
82
83
    private static final SpecificationVersion JDK_5 = new SpecificationVersion ("1.5");  //NOI18N
84
    private static final SpecificationVersion JDK_6 = new SpecificationVersion ("1.6");  //NOI18N
85
    private static final Logger LOGGER = Logger.getLogger(PlatformUiSupport.class.getName());
86
87
    private PlatformUiSupport() {
88
    }
89
90
    /**
91
     * Creates {@link ComboBoxModel} of J2SE platforms.
92
     * The model listens on the {@link JavaPlatformManager} and update its
93
     * state according to changes
94
     * @param activePlatform the active project's platform
95
     * @return {@link ComboBoxModel}
96
     */
97
    public static ComboBoxModel createPlatformComboBoxModel (String activePlatform) {
98
        return new PlatformComboBoxModel (activePlatform);
99
    }
100
101
    /**
102
     * Creates a {@link ListCellRenderer} for rendering items of the {@link ComboBoxModel}
103
     * created by the {@link PlatformUiSupport#createPlatformComboBoxModel} method.
104
     * @return {@link ListCellRenderer}
105
     */
106
    public static ListCellRenderer createPlatformListCellRenderer () {
107
        return new PlatformListCellRenderer ();
108
    }
109
110
    /**
111
     * Like {@link #storePlatform}, but platformName may be null (in which case the default platform is used)
112
     */
113
    public static void storePlatform (EditableProperties props, UpdateHelper helper, String platformName, SpecificationVersion sourceLevel) {
114
        PlatformKey platformKey;
115
        if (platformName != null) {
116
            platformKey = new PlatformKey(PlatformUiSupport.findPlatform(platformName));
117
        } else {
118
            platformKey = new PlatformKey(JavaPlatformManager.getDefault().getDefaultPlatform());
119
        }
120
        storePlatform(props, helper, platformKey, sourceLevel == null ? null : new SourceLevelKey(sourceLevel));
121
    }
122
123
    /**
124
     * Stores active platform, javac.source and javac.target into the project's metadata
125
     * @param props project's shared properties
126
     * @param helper to read/update project.xml
127
     * @param platformKey the PatformKey got from the platform model
128
     * @param sourceLevel source level
129
     */
130
    public static void storePlatform (EditableProperties props, UpdateHelper helper, Object platformKey, Object sourceLevelKey) {
131
        assert platformKey instanceof PlatformKey;
132
        PlatformKey pk = (PlatformKey) platformKey;
133
        JavaPlatform platform = getPlatform(pk);
134
        //null means active broken (unresolved) platform, no need to do anything
135
        if (platform != null) {
136
            SpecificationVersion jdk13 = new SpecificationVersion ("1.3");  //NOI18N
137
            String platformAntName = platform.getProperties().get("platform.ant.name");    //NOI18N
138
            assert platformAntName != null;
139
            props.put(EjbJarProjectProperties.JAVA_PLATFORM, platformAntName);
140
            Element root = helper.getPrimaryConfigurationData(true);
141
            boolean defaultPlatform = pk.isDefaultPlatform();
142
            boolean changed = false;
143
            NodeList explicitPlatformNodes = root.getElementsByTagNameNS (EjbJarProjectType.PROJECT_CONFIGURATION_NAMESPACE,"explicit-platform");   //NOI18N
144
            if (defaultPlatform) {
145
                if (explicitPlatformNodes.getLength()==1) {
146
                    root.removeChild(explicitPlatformNodes.item(0));
147
                    changed = true;
148
                }
149
            }
150
            else {
151
                Element explicitPlatform;
152
                switch (explicitPlatformNodes.getLength()) {
153
                    case 0:
154
                        explicitPlatform = root.getOwnerDocument().createElementNS(EjbJarProjectType.PROJECT_CONFIGURATION_NAMESPACE, "explicit-platform"); //NOI18N
155
                        NodeList sourceRootNodes = root.getElementsByTagNameNS (EjbJarProjectType.PROJECT_CONFIGURATION_NAMESPACE,"source-roots");   //NOI18N
156
                        assert sourceRootNodes.getLength() == 1 : "Broken project.xml file"; //NOI18N
157
                        root.insertBefore(explicitPlatform, sourceRootNodes.item(0));
158
                        changed = true;
159
                        break;
160
                    case 1:
161
                        explicitPlatform = (Element)explicitPlatformNodes.item(0);
162
                        break;
163
                    default:
164
                        throw new AssertionError("Broken project.xml file");   //NOI18N
165
                }
166
                String explicitSourceAttrValue = explicitPlatform.getAttribute("explicit-source-supported");    //NOI18N
167
                if (jdk13.compareTo(platform.getSpecification().getVersion())>=0 &&
168
                    !"false".equals(explicitSourceAttrValue)) {   //NOI18N
169
                    explicitPlatform.setAttribute("explicit-source-supported","false"); //NOI18N
170
                    changed = true;
171
                }
172
                else if (jdk13.compareTo(platform.getSpecification().getVersion())<0 &&
173
                    !"true".equals(explicitSourceAttrValue)) {  //NOI18N
174
                    explicitPlatform.setAttribute("explicit-source-supported","true"); //NOI18N
175
                    changed = true;
176
                }
177
            }
178
179
            SpecificationVersion sourceLevel;
180
            if (sourceLevelKey == null) {
181
                sourceLevel = platform.getSpecification().getVersion();
182
            }
183
            else {
184
                assert sourceLevelKey instanceof SourceLevelKey;
185
                sourceLevel = ((SourceLevelKey)sourceLevelKey).getSourceLevel();
186
            }
187
            String javacSource = sourceLevel.toString();
188
            String javacTarget = javacSource;
189
190
            //Issue #116490
191
            // Customizer value | -source | -targer
192
            // JDK 1.2            1.2        1.1
193
            // JDK 1.3            1.3        1.1
194
            // JDK 1.4            1.4        1.4
195
            // JDK 5              1.5        1.5
196
            // JDK 6              1.5        1.6
197
            // JDK 7              1.7        1.7  - should bring a new language features
198
            if (jdk13.compareTo(sourceLevel)>=0) {
199
                javacTarget = "1.1";        //NOI18N
200
            }
201
            else if (JDK_6.equals(sourceLevel)) {
202
                javacSource = JDK_5.toString();        //NOI18N
203
            }
204
205
            // #89131: these levels are not actually distinct from 1.5.
206
            if (javacSource.equals("1.6") || javacSource.equals("1.7")) {
207
                javacSource = "1.5";
208
            }
209
            if (!javacSource.equals(props.getProperty(EjbJarProjectProperties.JAVAC_SOURCE))) {
210
                props.setProperty (EjbJarProjectProperties.JAVAC_SOURCE, javacSource);
211
            }
212
            if (!javacTarget.equals(props.getProperty(EjbJarProjectProperties.JAVAC_TARGET))) {
213
                props.setProperty (EjbJarProjectProperties.JAVAC_TARGET, javacTarget);
214
            }
215
216
            if (changed) {
217
                helper.putPrimaryConfigurationData(root, true);
218
            }
219
        }
220
    }
221
222
    public static JavaPlatform findPlatform(String displayName) {
223
        JavaPlatform[] platforms = JavaPlatformManager.getDefault().getPlatforms(displayName, new Specification("j2se", null)); //NOI18N
224
        return platforms.length == 0 ? null : platforms[0];
225
    }
226
227
228
    /**
229
     * Returns a {@link JavaPlatform} for an item obtained from the ComboBoxModel created by
230
     * the {@link PlatformUiSupport#createComboBoxModel} method
231
     * @param platformKey an item obtained from ComboBoxModel created by {@link PlatformUiSupport#createComboBoxModel}
232
     * @return JavaPlatform or null in case when platform is broken
233
     * @exception {@link IllegalArgumentException} is thrown in case when parameter in not an object created by
234
     * platform combobox model.
235
     */
236
    public static JavaPlatform getPlatform (Object platformKey) {
237
       if (platformKey instanceof PlatformKey) {
238
           return getPlatform ((PlatformKey)platformKey);
239
       }
240
       else {
241
           throw new IllegalArgumentException ();
242
       }
243
    }
244
245
    /**
246
     * Creates {@link ComboBoxModel} of source levels for active platform.
247
     * The model listens on the platform's {@link ComboBoxModel} and update its
248
     * state according to changes
249
     * @param platformComboBoxModel the platform's model used for listenning
250
     * @param initialSourceLevel initial source level value
251
     * @param initialTargetLevel initial target level value
252
     * @return {@link ComboBoxModel} of {@link SpecificationVersion}
253
     */
254
    public static ComboBoxModel createSourceLevelComboBoxModel(ComboBoxModel platformComboBoxModel, String initialSourceLevel, String initialTargetLevel, String j2eePlatform) {
255
        return new SourceLevelComboBoxModel(platformComboBoxModel, initialSourceLevel, initialTargetLevel, j2eePlatform);
256
    }
257
258
    public static ListCellRenderer createSourceLevelListCellRenderer() {
259
        return new SourceLevelListCellRenderer();
260
    }
261
262
    private static JavaPlatform getPlatform (PlatformKey platformKey) {
263
        return platformKey.platform;
264
    }
265
266
    /**
267
     * This class represents a  JavaPlatform in the {@link ListModel}
268
     * created by the {@link PlatformUiSupport#createPlatformComboBoxModel}
269
     * method.
270
     */
271
    private static class PlatformKey implements Comparable {
272
273
        private String name;
274
        private JavaPlatform platform;
275
276
        /**
277
         * Creates a PlatformKey for a broken platform
278
         * @param name the ant name of the broken platform
279
         */
280
        public PlatformKey (String name) {
281
            assert name != null;
282
            this.name = name;
283
        }
284
285
        /**
286
         * Creates a PlatformKey for a platform
287
         * @param platform the {@link JavaPlatform}
288
         */
289
        public PlatformKey (JavaPlatform platform) {
290
            assert platform != null;
291
            this.platform = platform;
292
        }
293
294
        public int compareTo(Object o) {
295
            return this.getDisplayName().compareTo(((PlatformKey)o).getDisplayName());
296
        }
297
298
        @Override
299
        public boolean equals (Object other) {
300
            if (other instanceof PlatformKey) {
301
                PlatformKey otherKey = (PlatformKey)other;
302
                return (this.platform == null ? otherKey.platform == null : this.platform.equals(otherKey.platform)) &&
303
                       otherKey.getDisplayName().equals (this.getDisplayName());
304
            }
305
            else {
306
                return false;
307
            }
308
        }
309
310
        @Override
311
        public int hashCode () {
312
            return getDisplayName ().hashCode ();
313
        }
314
315
        @Override
316
        public String toString () {
317
            return getDisplayName ();
318
        }
319
320
        public synchronized String getDisplayName () {
321
            if (this.name == null) {
322
                this.name = this.platform.getDisplayName();
323
            }
324
            return this.name;
325
        }
326
327
        public boolean isDefaultPlatform () {
328
            if (this.platform == null) {
329
                return false;
330
            }
331
            return this.platform.equals(JavaPlatformManager.getDefault().getDefaultPlatform());
332
        }
333
334
        public boolean isBroken () {
335
            return this.platform == null;
336
        }
337
    }
338
339
    private static final class SourceLevelKey implements Comparable {
340
341
        final SpecificationVersion sourceLevel;
342
        final boolean broken;
343
344
        public SourceLevelKey (final SpecificationVersion sourceLevel) {
345
            this (sourceLevel, false);
346
        }
347
348
        public SourceLevelKey (final SpecificationVersion sourceLevel, final boolean broken) {
349
            assert sourceLevel != null : "Source level cannot be null";     //NOI18N
350
            this.sourceLevel = sourceLevel;
351
            this.broken = broken;
352
        }
353
354
        public SpecificationVersion getSourceLevel () {
355
            return this.sourceLevel;
356
        }
357
358
        public boolean isBroken () {
359
            return this.broken;
360
        }
361
362
        public int compareTo (final Object other) {
363
            assert other instanceof SourceLevelKey : "Illegal argument of SourceLevelKey.compareTo()";  //NOI18N
364
            SourceLevelKey otherKey = (SourceLevelKey) other;
365
            return this.sourceLevel.compareTo(otherKey.sourceLevel);
366
        }
367
368
        public @Override boolean equals (final Object other) {
369
            return (other instanceof SourceLevelKey) &&
370
                   ((SourceLevelKey)other).sourceLevel.equals(this.sourceLevel);
371
        }
372
373
        public @Override int hashCode () {
374
            return this.sourceLevel.hashCode();
375
        }
376
377
        public @Override String toString () {
378
            StringBuffer buffer = new StringBuffer ();
379
            if (this.broken) {
380
                buffer.append("Broken: ");      //NOI18N
381
            }
382
            buffer.append(this.sourceLevel.toString());
383
            return buffer.toString();
384
        }
385
386
        public String getDisplayName () {
387
            String _tmp = sourceLevel.toString();
388
            if (JDK_5.compareTo(sourceLevel)<=0) {
389
                _tmp = _tmp.replaceFirst("^1\\.([5-9]|\\d\\d+)$", "$1");        //NOI18N
390
            }
391
            return NbBundle.getMessage(PlatformUiSupport.class, "LBL_JDK",_tmp);
392
        }
393
394
    }
395
396
    private static class PlatformComboBoxModel extends AbstractListModel implements ComboBoxModel, PropertyChangeListener {
397
        private static final long serialVersionUID = 41647580130743122L;
398
399
        private final JavaPlatformManager pm;
400
        private PlatformKey[] platformNamesCache;
401
        private String initialPlatform;
402
        private PlatformKey selectedPlatform;
403
404
        public PlatformComboBoxModel (String initialPlatform) {
405
            this.pm = JavaPlatformManager.getDefault();
406
            this.pm.addPropertyChangeListener(WeakListeners.propertyChange(this, this.pm));
407
            this.initialPlatform = initialPlatform;
408
        }
409
410
        public int getSize () {
411
            PlatformKey[] platformNames = getPlatformNames ();
412
            return platformNames.length;
413
        }
414
415
        public Object getElementAt (int index) {
416
            PlatformKey[] platformNames = getPlatformNames ();
417
            assert index >=0 && index< platformNames.length;
418
            return platformNames[index];
419
        }
420
421
        public Object getSelectedItem () {
422
            this.getPlatformNames(); //Force setting of selectedPlatform if it is not alredy done
423
            return this.selectedPlatform;
424
        }
425
426
        public void setSelectedItem (Object obj) {
427
            this.selectedPlatform = (PlatformKey) obj;
428
            this.fireContentsChanged(this, -1, -1);
429
        }
430
431
        public void propertyChange (PropertyChangeEvent event) {
432
            if (JavaPlatformManager.PROP_INSTALLED_PLATFORMS.equals(event.getPropertyName())) {
433
                synchronized (this) {
434
                    this.platformNamesCache = null;
435
                }
436
                this.fireContentsChanged(this, -1, -1);
437
            }
438
        }
439
440
        private synchronized PlatformKey[] getPlatformNames () {
441
            if (this.platformNamesCache == null) {
442
                JavaPlatform[] platforms = pm.getPlatforms (null, new Specification("j2se",null));    //NOI18N
443
                Set<PlatformKey> orderedNames = new TreeSet<PlatformKey>();
444
                boolean activeFound = false;
445
                for (int i=0; i< platforms.length; i++) {
446
                    if (platforms[i].getInstallFolders().size()>0) {
447
                        PlatformKey pk = new PlatformKey(platforms[i]);
448
                        orderedNames.add (pk);
449
                        if (!activeFound && initialPlatform != null) {
450
                            String antName = platforms[i].getProperties().get("platform.ant.name");    //NOI18N
451
                            if (initialPlatform.equals(antName)) {
452
                                if (this.selectedPlatform == null) {
453
                                    this.selectedPlatform = pk;
454
                                    initialPlatform = null;
455
                                }
456
                                activeFound = true;
457
                            }
458
                        }
459
                    }
460
                }
461
                if (!activeFound) {
462
                    if (initialPlatform == null) {
463
                        if (this.selectedPlatform == null || !orderedNames.contains(this.selectedPlatform)) {
464
                            this.selectedPlatform = new PlatformKey (JavaPlatformManager.getDefault().getDefaultPlatform());
465
                        }
466
                    }
467
                    else {
468
                        PlatformKey pk = new PlatformKey (this.initialPlatform);
469
                        orderedNames.add (pk);
470
                        if (this.selectedPlatform == null) {
471
                            this.selectedPlatform = pk;
472
                        }
473
                    }
474
                }
475
                this.platformNamesCache = orderedNames.toArray(new PlatformKey[orderedNames.size()]);
476
            }
477
            return this.platformNamesCache;
478
        }
479
480
    }
481
482
    private static class PlatformListCellRenderer extends DefaultListCellRenderer {
483
        private static final long serialVersionUID = 51419604163086358L;
484
485
        @Override
486
        public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
487
            assert value instanceof PlatformKey : "Wrong model";  //NOI18N
488
            PlatformKey key = (PlatformKey) value;
489
            String name;
490
            if (key.isBroken()) {
491
                name = NbBundle.getMessage (PlatformUiSupport.class,"TXT_BrokenPlatformFmt", key.getDisplayName());
492
            }
493
            else {
494
                name = key.getDisplayName();
495
            }
496
            return super.getListCellRendererComponent(list, name, index, isSelected, cellHasFocus);
497
        }
498
    }
499
500
    private static class SourceLevelComboBoxModel extends AbstractListModel implements ComboBoxModel, ListDataListener {
501
        private static final long serialVersionUID = 108135581162238931L;
502
        private static final String VERSION_PREFIX = "1.";      //The version prefix
503
        private static final int INITIAL_VERSION_MINOR = 2;     //1.2
504
        // if project is JAVA EE 5 show only 1.5 and higher
505
        private static final int INITIAL_VERSION_MINOR_JAVA_EE_5 = 5;     // 1.5
506
507
        private SpecificationVersion selectedSourceLevel;
508
        private SpecificationVersion originalSourceLevel;
509
        private SourceLevelKey[] sourceLevelCache;
510
        private final ComboBoxModel platformComboBoxModel;
511
        private PlatformKey activePlatform;
512
        private String j2eePlatform = null;
513
514
        public SourceLevelComboBoxModel(ComboBoxModel platformComboBoxModel, String initialSourceLevel, String initialTargetLevel) {
515
            this.platformComboBoxModel = platformComboBoxModel;
516
            this.activePlatform = (PlatformKey) this.platformComboBoxModel.getSelectedItem();
517
            this.platformComboBoxModel.addListDataListener(this);
518
            if (initialSourceLevel != null && initialSourceLevel.length()>0) {
519
                try {
520
                    originalSourceLevel = new SpecificationVersion (initialSourceLevel);
521
                } catch (NumberFormatException nfe) {
522
                    // If the javac.source has invalid value, do not preselect and log it.
523
                    LOGGER.log(Level.INFO, "Invalid javac.source: " + initialSourceLevel);
524
                }
525
            }
526
            if (initialTargetLevel != null && initialTargetLevel.length() > 0) {
527
                try {
528
                    SpecificationVersion originalTargetLevel = new SpecificationVersion (initialTargetLevel);
529
                    if (this.originalSourceLevel == null || this.originalSourceLevel.compareTo(originalTargetLevel)<0) {
530
                        this.originalSourceLevel = originalTargetLevel;
531
                    }
532
                } catch (NumberFormatException nfe) {
533
                    //If the javac.target has invalid value, do not preselect and log it
534
                    LOGGER.warning("Invalid javac.target: "+initialTargetLevel);       //NOI18N
535
                }
536
            }
537
            this.selectedSourceLevel = this.originalSourceLevel;
538
        }
539
540
        public SourceLevelComboBoxModel(ComboBoxModel platformComboBoxModel, String initialSourceLevel, String initialTargetLevel, String j2eePlatform) {
541
            this(platformComboBoxModel, initialSourceLevel, initialTargetLevel);
542
            this.j2eePlatform = j2eePlatform;
543
        }
544
545
        public int getSize() {
546
            SourceLevelKey[] sLevels = getSourceLevels();
547
            return sLevels.length;
548
        }
549
550
        public Object getElementAt(int index) {
551
            SourceLevelKey[] sLevels = getSourceLevels();
552
            assert index >=0 && index< sLevels.length;
553
            return sLevels[index];
554
        }
555
556
        public Object getSelectedItem () {
557
            SourceLevelKey[] keys = getSourceLevels();
558
            for (int i=0; i<keys.length; i++) {
559
                if (keys[i].getSourceLevel().equals(this.selectedSourceLevel)) {
560
                    return keys[i];
561
                }
562
            }
563
            return null;
564
        }
565
566
        public void setSelectedItem (Object obj) {
567
            this.selectedSourceLevel = (obj == null ? null : ((SourceLevelKey) obj).getSourceLevel());
568
            this.fireContentsChanged(this, -1, -1);
569
        }
570
571
        public void intervalAdded(ListDataEvent e) {
572
        }
573
574
        public void intervalRemoved(ListDataEvent e) {
575
        }
576
577
        public void contentsChanged(ListDataEvent e) {
578
            PlatformKey selectedPlatform = (PlatformKey) this.platformComboBoxModel.getSelectedItem();
579
            JavaPlatform platform = getPlatform(selectedPlatform);
580
            if (platform != null) {
581
                SpecificationVersion version = platform.getSpecification().getVersion();
582
                if (this.selectedSourceLevel != null && this.selectedSourceLevel.compareTo(version)>0 &&
583
                        !shouldChangePlatform(selectedSourceLevel, version)) {
584
                    //Restore original
585
                    this.platformComboBoxModel.setSelectedItem(this.activePlatform);
586
                    return;
587
                }
588
                else {
589
                    this.originalSourceLevel = null;
590
                }
591
            }
592
            this.activePlatform = selectedPlatform;
593
            resetCache();
594
        }
595
596
        private void resetCache() {
597
            synchronized (this) {
598
                this.sourceLevelCache = null;
599
            }
600
            this.fireContentsChanged(this, -1, -1);
601
        }
602
603
        private SourceLevelKey[] getSourceLevels() {
604
            if (this.sourceLevelCache == null) {
605
                PlatformKey selectedPlatform = (PlatformKey) this.platformComboBoxModel.getSelectedItem();
606
                JavaPlatform platform = getPlatform(selectedPlatform);
607
                List<SourceLevelKey> sLevels = new ArrayList<SourceLevelKey>();
608
                //If platform == null broken platform, the source level range is unknown
609
                //The source level combo box should be empty and disabled
610
                boolean selSourceLevelValid = false;
611
                if (platform != null) {
612
                    SpecificationVersion version = platform.getSpecification().getVersion();
613
                    int index = INITIAL_VERSION_MINOR;
614
                    // #71619 - source level lower than 1.5 won't be shown for Java EE 5 project
615
                    if (j2eePlatform != null && j2eePlatform.equals(EjbJarProjectProperties.JAVA_EE_5)) {
616
                        index = INITIAL_VERSION_MINOR_JAVA_EE_5;
617
                    }
618
                    SpecificationVersion template = new SpecificationVersion (VERSION_PREFIX + Integer.toString (index++));
619
                    boolean origSourceLevelValid = false;
620
621
                    while (template.compareTo(version)<=0) {
622
                        if (template.equals(this.originalSourceLevel)) {
623
                            origSourceLevelValid = true;
624
                        }
625
                        if (template.equals(this.selectedSourceLevel)) {
626
                            selSourceLevelValid = true;
627
                        }
628
                        sLevels.add (new SourceLevelKey (template));
629
                        template = new SpecificationVersion (VERSION_PREFIX + Integer.toString (index++));
630
                    }
631
                    if (this.originalSourceLevel != null && !origSourceLevelValid) {
632
                        if (originalSourceLevel.equals(this.selectedSourceLevel)) {
633
                            selSourceLevelValid = true;
634
                        }
635
                        sLevels.add (new SourceLevelKey(this.originalSourceLevel,true));
636
                    }
637
                }
638
                this.sourceLevelCache = sLevels.toArray(new SourceLevelKey[sLevels.size()]);
639
                if (!selSourceLevelValid) {
640
                    this.selectedSourceLevel = this.sourceLevelCache.length == 0 ?
641
                        null : this.sourceLevelCache[this.sourceLevelCache.length-1].getSourceLevel();
642
                }
643
            }
644
            return this.sourceLevelCache;
645
        }
646
647
        private static boolean shouldChangePlatform (SpecificationVersion selectedSourceLevel, SpecificationVersion platformSourceLevel) {
648
            JButton changeOption = new JButton (NbBundle.getMessage(PlatformUiSupport.class, "CTL_ChangePlatform"));
649
            changeOption.getAccessibleContext().setAccessibleDescription(NbBundle.getMessage(PlatformUiSupport.class, "AD_ChangePlatform"));
650
            String message = MessageFormat.format (NbBundle.getMessage(PlatformUiSupport.class,"TXT_ChangePlatform"),new Object[] {
651
                selectedSourceLevel.toString(),
652
                platformSourceLevel.toString(),
653
            });
654
            return DialogDisplayer.getDefault().notify(
655
                new NotifyDescriptor (message,
656
                        NbBundle.getMessage(PlatformUiSupport.class,"TXT_ChangePlatformTitle"),
657
                        NotifyDescriptor.DEFAULT_OPTION,
658
                        NotifyDescriptor.WARNING_MESSAGE,
659
                        new Object[] {
660
                            changeOption,
661
                            NotifyDescriptor.CANCEL_OPTION
662
                        },
663
                        changeOption)) == changeOption;
664
        }
665
    }
666
667
    private static class SourceLevelListCellRenderer implements ListCellRenderer {
668
669
        ListCellRenderer delegate;
670
671
        public SourceLevelListCellRenderer() {
672
            this.delegate = HtmlRenderer.createRenderer();
673
        }
674
675
        public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
676
            String message;
677
            if (value == null) {
678
                message = "";   //NOI18N
679
            }
680
            else {
681
                assert value instanceof SourceLevelKey;
682
                SourceLevelKey key = (SourceLevelKey) value;
683
                if (key.isBroken()) {
684
                    message = "<html><font color=\"#A40000\">" +    //NOI18N
685
                        NbBundle.getMessage(PlatformUiSupport.class,"TXT_InvalidSourceLevel",key.getDisplayName());
686
                }
687
                else {
688
                    message = key.getDisplayName();
689
                }
690
            }
691
            return this.delegate.getListCellRendererComponent(list, message, index, isSelected, cellHasFocus);
692
        }
693
    }
694
}
(-)a/j2ee.ejbjarproject/src/org/netbeans/modules/j2ee/ejbjarproject/ui/logicalview/libraries/ActionFilterNode.java (-1 / +1 lines)
Lines 66-74 import org.netbeans.spi.project.support. Link Here
66
import org.netbeans.spi.project.support.ant.EditableProperties;
66
import org.netbeans.spi.project.support.ant.EditableProperties;
67
import org.netbeans.spi.project.support.ant.PropertyEvaluator;
67
import org.netbeans.spi.project.support.ant.PropertyEvaluator;
68
import org.netbeans.spi.project.support.ant.ReferenceHelper;
68
import org.netbeans.spi.project.support.ant.ReferenceHelper;
69
import org.netbeans.modules.j2ee.ejbjarproject.UpdateHelper;
70
import org.netbeans.modules.j2ee.ejbjarproject.classpath.ClassPathSupport;
69
import org.netbeans.modules.j2ee.ejbjarproject.classpath.ClassPathSupport;
71
import org.netbeans.modules.j2ee.ejbjarproject.ui.customizer.EjbJarProjectProperties;
70
import org.netbeans.modules.j2ee.ejbjarproject.ui.customizer.EjbJarProjectProperties;
71
import org.netbeans.modules.java.api.common.ant.UpdateHelper;
72
import org.openide.nodes.FilterNode.Children;
72
import org.openide.nodes.FilterNode.Children;
73
import org.openide.util.Exceptions;
73
import org.openide.util.Exceptions;
(-)a/j2ee.ejbjarproject/src/org/netbeans/modules/j2ee/ejbjarproject/ui/logicalview/libraries/LibrariesNode.java (-1 / +1 lines)
Lines 99-110 import org.netbeans.spi.project.support. Link Here
99
import org.netbeans.spi.project.support.ant.ReferenceHelper;
99
import org.netbeans.spi.project.support.ant.ReferenceHelper;
100
import org.netbeans.spi.java.project.support.ui.PackageView;
100
import org.netbeans.spi.java.project.support.ui.PackageView;
101
import org.netbeans.modules.j2ee.ejbjarproject.ui.FoldersListSettings;
101
import org.netbeans.modules.j2ee.ejbjarproject.ui.FoldersListSettings;
102
import org.netbeans.modules.j2ee.ejbjarproject.UpdateHelper;
103
import org.netbeans.modules.j2ee.ejbjarproject.classpath.EjbJarProjectClassPathExtender;
102
import org.netbeans.modules.j2ee.ejbjarproject.classpath.EjbJarProjectClassPathExtender;
104
import org.netbeans.modules.j2ee.ejbjarproject.ui.customizer.AntArtifactChooser;
103
import org.netbeans.modules.j2ee.ejbjarproject.ui.customizer.AntArtifactChooser;
105
import org.netbeans.modules.j2ee.ejbjarproject.ui.customizer.EjbJarClassPathUi;
104
import org.netbeans.modules.j2ee.ejbjarproject.ui.customizer.EjbJarClassPathUi;
106
import org.netbeans.modules.j2ee.ejbjarproject.ui.customizer.EjbJarProjectProperties;
105
import org.netbeans.modules.j2ee.ejbjarproject.ui.customizer.EjbJarProjectProperties;
107
import org.netbeans.modules.j2ee.ejbjarproject.ui.customizer.LibrariesChooser;
106
import org.netbeans.modules.j2ee.ejbjarproject.ui.customizer.LibrariesChooser;
107
import org.netbeans.modules.java.api.common.ant.UpdateHelper;
108
import org.netbeans.spi.java.classpath.support.ClassPathSupport;
108
import org.netbeans.spi.java.classpath.support.ClassPathSupport;
109
import org.openide.util.Exceptions;
109
import org.openide.util.Exceptions;
110
import org.openide.util.lookup.Lookups;
110
import org.openide.util.lookup.Lookups;
(-)a/j2ee.ejbjarproject/src/org/netbeans/modules/j2ee/ejbjarproject/ui/logicalview/libraries/ProjectNode.java (-1 / +1 lines)
Lines 78-84 import org.netbeans.spi.project.support. Link Here
78
import org.netbeans.spi.project.support.ant.ReferenceHelper;
78
import org.netbeans.spi.project.support.ant.ReferenceHelper;
79
import org.netbeans.modules.j2ee.ejbjarproject.classpath.ClassPathSupport;
79
import org.netbeans.modules.j2ee.ejbjarproject.classpath.ClassPathSupport;
80
import org.netbeans.modules.j2ee.ejbjarproject.ui.customizer.EjbJarProjectProperties;
80
import org.netbeans.modules.j2ee.ejbjarproject.ui.customizer.EjbJarProjectProperties;
81
import org.netbeans.modules.j2ee.ejbjarproject.UpdateHelper;
81
import org.netbeans.modules.java.api.common.ant.UpdateHelper;
82
import org.openide.filesystems.FileObject;
82
import org.openide.filesystems.FileObject;
83
import org.openide.util.Exceptions;
83
import org.openide.util.Exceptions;
84
import org.openide.util.Lookup;
84
import org.openide.util.Lookup;
(-)a/java.commonapi/build.xml (+46 lines)
Line 0 Link Here
1
<?xml version="1.0" encoding="UTF-8"?>
2
<!--
3
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
4
5
Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
6
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.  Sun designates this
19
particular file as subject to the "Classpath" exception as provided
20
by Sun 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
Contributor(s):
27
28
The Original Software is NetBeans. The Initial Developer of the Original
29
Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
30
Microsystems, Inc. All Rights Reserved.
31
32
If you wish your version of this file to be governed by only the CDDL
33
or only the GPL Version 2, indicate your decision by adding
34
"[Contributor] elects to include this software in this distribution
35
under the [CDDL or GPL Version 2] license." If you do not indicate a
36
single choice of license, a recipient has the option to distribute
37
your version of this file under either the CDDL, the GPL Version 2 or
38
to extend the choice of license to its licensees as provided above.
39
However, if you add GPL Version 2 code and therefore, elected the GPL
40
Version 2 license, then the option applies only if the new code is
41
made subject to such option by the copyright holder.
42
-->
43
<project basedir="." default="netbeans" name="java.commonapi">
44
    <import file="../nbbuild/templates/projectized.xml"/>
45
</project>
46
(-)a/java.commonapi/manifest.mf (+6 lines)
Line 0 Link Here
1
Manifest-Version: 1.0
2
OpenIDE-Module: org.netbeans.modules.java.api.common/0
3
OpenIDE-Module-Layer: org/netbeans/modules/java/api/common/resources/layer.xml
4
OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/java/api/common/resources/Bundle.properties
5
OpenIDE-Module-Specification-Version: 1.0
6
(-)a/java.commonapi/nbproject/project.properties (+3 lines)
Line 0 Link Here
1
is.autoload=true
2
javac.compilerargs=-Xlint -Xlint:-serial
3
javac.source=1.5
(-)a/java.commonapi/nbproject/project.xml (+152 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.java.api.common</code-name-base>
7
            <module-dependencies>
8
                <dependency>
9
                    <code-name-base>org.netbeans.api.java</code-name-base>
10
                    <build-prerequisite/>
11
                    <compile-dependency/>
12
                    <run-dependency>
13
                        <release-version>1</release-version>
14
                        <specification-version>1.14</specification-version>
15
                    </run-dependency>
16
                </dependency>
17
                <dependency>
18
                    <code-name-base>org.netbeans.modules.java.platform</code-name-base>
19
                    <build-prerequisite/>
20
                    <compile-dependency/>
21
                    <run-dependency>
22
                        <release-version>1</release-version>
23
                        <specification-version>1.10</specification-version>
24
                    </run-dependency>
25
                </dependency>
26
                <dependency>
27
                    <code-name-base>org.netbeans.modules.java.project</code-name-base>
28
                    <build-prerequisite/>
29
                    <compile-dependency/>
30
                    <run-dependency>
31
                        <release-version>1</release-version>
32
                        <specification-version>1.13</specification-version>
33
                    </run-dependency>
34
                </dependency>
35
                <dependency>
36
                    <code-name-base>org.netbeans.modules.project.ant</code-name-base>
37
                    <build-prerequisite/>
38
                    <compile-dependency/>
39
                    <run-dependency>
40
                        <release-version>1</release-version>
41
                        <specification-version>1.18</specification-version>
42
                    </run-dependency>
43
                </dependency>
44
                <dependency>
45
                    <code-name-base>org.netbeans.modules.project.libraries</code-name-base>
46
                    <build-prerequisite/>
47
                    <compile-dependency/>
48
                    <run-dependency>
49
                        <release-version>1</release-version>
50
                        <specification-version>1.16</specification-version>
51
                    </run-dependency>
52
                </dependency>
53
                <dependency>
54
                    <code-name-base>org.netbeans.modules.projectapi</code-name-base>
55
                    <build-prerequisite/>
56
                    <compile-dependency/>
57
                    <run-dependency>
58
                        <release-version>1</release-version>
59
                        <specification-version>1.14</specification-version>
60
                    </run-dependency>
61
                </dependency>
62
                <dependency>
63
                    <code-name-base>org.netbeans.modules.queries</code-name-base>
64
                    <build-prerequisite/>
65
                    <compile-dependency/>
66
                    <run-dependency>
67
                        <release-version>1</release-version>
68
                        <specification-version>1.11</specification-version>
69
                    </run-dependency>
70
                </dependency>
71
                <dependency>
72
                    <code-name-base>org.openide.awt</code-name-base>
73
                    <build-prerequisite/>
74
                    <compile-dependency/>
75
                    <run-dependency>
76
                        <specification-version>6.12</specification-version>
77
                    </run-dependency>
78
                </dependency>
79
                <dependency>
80
                    <code-name-base>org.openide.dialogs</code-name-base>
81
                    <build-prerequisite/>
82
                    <compile-dependency/>
83
                    <run-dependency>
84
                        <specification-version>7.6</specification-version>
85
                    </run-dependency>
86
                </dependency>
87
                <dependency>
88
                    <code-name-base>org.openide.filesystems</code-name-base>
89
                    <build-prerequisite/>
90
                    <compile-dependency/>
91
                    <run-dependency>
92
                        <specification-version>7.4</specification-version>
93
                    </run-dependency>
94
                </dependency>
95
                <dependency>
96
                    <code-name-base>org.openide.modules</code-name-base>
97
                    <build-prerequisite/>
98
                    <compile-dependency/>
99
                    <run-dependency>
100
                        <specification-version>7.4</specification-version>
101
                    </run-dependency>
102
                </dependency>
103
                <dependency>
104
                    <code-name-base>org.openide.util</code-name-base>
105
                    <build-prerequisite/>
106
                    <compile-dependency/>
107
                    <run-dependency>
108
                        <specification-version>7.11</specification-version>
109
                    </run-dependency>
110
                </dependency>
111
            </module-dependencies>
112
            <test-dependencies>
113
                <test-type>
114
                    <name>unit</name>
115
                    <test-dependency>
116
                        <code-name-base>org.netbeans.modules.diff</code-name-base>
117
                    </test-dependency>
118
                    <test-dependency>
119
                        <code-name-base>org.netbeans.modules.masterfs</code-name-base>
120
                    </test-dependency>
121
                    <test-dependency>
122
                        <code-name-base>org.netbeans.modules.project.ant</code-name-base>
123
                        <compile-dependency/>
124
                        <test/>
125
                    </test-dependency>
126
                    <test-dependency>
127
                        <code-name-base>org.netbeans.modules.projectapi</code-name-base>
128
                        <compile-dependency/>
129
                        <test/>
130
                    </test-dependency>
131
                    <test-dependency>
132
                        <code-name-base>org.openide.util</code-name-base>
133
                        <compile-dependency/>
134
                        <test/>
135
                    </test-dependency>
136
                </test-type>
137
            </test-dependencies>
138
            <friend-packages>
139
                <friend>org.netbeans.modules.j2ee.clientproject</friend>
140
                <friend>org.netbeans.modules.j2ee.common</friend>
141
                <friend>org.netbeans.modules.j2ee.earproject</friend>
142
                <friend>org.netbeans.modules.j2ee.ejbjarproject</friend>
143
                <friend>org.netbeans.modules.java.j2seproject</friend>
144
                <friend>org.netbeans.modules.web.project</friend>
145
                <package>org.netbeans.modules.java.api.common</package>
146
                <package>org.netbeans.modules.java.api.common.ant</package>
147
                <package>org.netbeans.modules.java.api.common.queries</package>
148
                <package>org.netbeans.modules.java.api.common.ui</package>
149
            </friend-packages>
150
        </data>
151
    </configuration>
152
</project>
(-)a/java.commonapi/src/org/netbeans/modules/java/api/common/Bundle.properties (+39 lines)
Line 0 Link Here
1
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
2
#
3
# Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
4
#
5
# The contents of this file are subject to the terms of either the GNU
6
# General Public License Version 2 only ("GPL") or the Common
7
# Development and Distribution License("CDDL") (collectively, the
8
# "License"). You may not use this file except in compliance with the
9
# License. You can obtain a copy of the License at
10
# http://www.netbeans.org/cddl-gplv2.html
11
# or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
12
# specific language governing permissions and limitations under the
13
# License.  When distributing the software, include this License Header
14
# Notice in each file and include the License file at
15
# nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
16
# particular file as subject to the "Classpath" exception as provided
17
# by Sun in the GPL Version 2 section of the License file that
18
# accompanied this code. If applicable, add the following below the
19
# License Header, with the fields enclosed by brackets [] replaced by
20
# your own identifying information:
21
# "Portions Copyrighted [year] [name of copyright owner]"
22
#
23
# If you wish your version of this file to be governed by only the CDDL
24
# or only the GPL Version 2, indicate your decision by adding
25
# "[Contributor] elects to include this software in this distribution
26
# under the [CDDL or GPL Version 2] license." If you do not indicate a
27
# single choice of license, a recipient has the option to distribute
28
# your version of this file under either the CDDL, the GPL Version 2 or
29
# to extend the choice of license to its licensees as provided above.
30
# However, if you add GPL Version 2 code and therefore, elected the GPL
31
# Version 2 license, then the option applies only if the new code is
32
# made subject to such option by the copyright holder.
33
#
34
# Contributor(s):
35
#
36
# Portions Copyrighted 2008 Sun Microsystems, Inc.
37
38
NAME_src.dir=Source Packages
39
NAME_test.src.dir=Test Packages
(-)a/java.commonapi/src/org/netbeans/modules/java/api/common/SourceRoots.java (+144 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 1997-2007 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 2007 Sun Microsystems, Inc.
38
 */
39
40
package org.netbeans.modules.java.api.common;
41
42
import java.beans.PropertyChangeListener;
43
import java.io.File;
44
import java.net.URL;
45
import org.openide.filesystems.FileObject;
46
import org.openide.util.NbBundle;
47
48
/**
49
 * Represents a project source roots. It can be used to obtain source roots as Ant properties, {@link FileObject}'s
50
 * or {@link URL}s.
51
 * All implementations have to be thread safe and have to listen to the changes
52
 * in Ant project metadata (see {@link #PROP_ROOT_PROPERTIES}) as well as
53
 * in project properties (see {@link #PROP_ROOTS}).
54
 * @author Tomas Zezula, Tomas Mysik
55
 */
56
public interface SourceRoots {
57
58
    /**
59
     * Property name of a event that has to be fired when Ant project metadata change.
60
     */
61
    String PROP_ROOT_PROPERTIES = SourceRoots.class.getName() + ".rootProperties"; //NOI18N
62
    /**
63
     * Property name of a event that has to be fired when project properties change.
64
     */
65
    String PROP_ROOTS = SourceRoots.class.getName() + ".roots"; //NOI18N
66
67
    /**
68
     * Default label for sources node used in {@link org.netbeans.spi.project.ui.LogicalViewProvider}.
69
     */
70
    String DEFAULT_SOURCE_LABEL = NbBundle.getMessage(SourceRoots.class, "NAME_src.dir");
71
    /**
72
     * Default label for tests node used in {@link org.netbeans.spi.project.ui.LogicalViewProvider}.
73
     */
74
    String DEFAULT_TEST_LABEL = NbBundle.getMessage(SourceRoots.class, "NAME_test.src.dir");
75
76
    /**
77
     * Returns the display names of source roots.
78
     * The returned array has the same length as an array returned by the {@link #getRootProperties()}.
79
     * It may contain empty {@link String}s but not <code>null</code>.
80
     * @return an array of source roots names.
81
     */
82
    String[] getRootNames();
83
84
    /**
85
     * Returns names of Ant properties in the <i>project.properties</i> file holding the source roots.
86
     * @return an array of String.
87
     */
88
    String[] getRootProperties();
89
90
    /**
91
     * Returns the source roots in the form of absolute paths.
92
     * @return an array of {@link FileObject}s.
93
     */
94
    FileObject[] getRoots();
95
96
    /**
97
     * Returns the source roots as {@link URL}s.
98
     * @return an array of {@link URL}.
99
     */
100
    URL[] getRootURLs();
101
102
    /**
103
     * Adds {@link PropertyChangeListener}, see class description for more information
104
     * about listening to the source roots changes.
105
     * @param listener a listener to add.
106
     */
107
    void addPropertyChangeListener(PropertyChangeListener listener);
108
109
    /**
110
     * Removes {@link PropertyChangeListener}, see class description for more information
111
     * about listening to the source roots changes.
112
     * @param listener a listener to remove.
113
     */
114
    void removePropertyChangeListener(PropertyChangeListener listener);
115
116
    /**
117
     * Replaces the current roots by the given ones.
118
     * @param roots the {@link URL}s of the new roots.
119
     * @param labels the names of the new roots.
120
     */
121
    void putRoots(final URL[] roots, final String[] labels);
122
123
    /**
124
     * Translates root name into display name of source/test root.
125
     * @param rootName the name of root got from {@link SourceRoots#getRootNames()}.
126
     * @param propName the name of a property the root is stored in.
127
     * @return the label to be displayed.
128
     */
129
    String getRootDisplayName(String rootName, String propName);
130
131
    /**
132
     * Creates initial display name of source/test root.
133
     * @param sourceRoot the source root.
134
     * @return the label to be displayed.
135
     */
136
    String createInitialDisplayName(File sourceRoot);
137
138
    /**
139
     * Returns <code>true</code> if the current {@link SourceRoots} instance represents source roots belonging to
140
     * the test compilation unit.
141
     * @return boolean <code>true</code> if the instance belongs to the test compilation unit, false otherwise.
142
     */
143
    boolean isTest();
144
}
(-)a/java.commonapi/src/org/netbeans/modules/java/api/common/SourceRootsImpl.java (+427 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 1997-2007 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
 * Contributor(s):
25
 *
26
 * The Original Software is NetBeans. The Initial Developer of the Original
27
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
28
 * Microsystems, Inc. All Rights Reserved.
29
 *
30
 * If you wish your version of this file to be governed by only the CDDL
31
 * or only the GPL Version 2, indicate your decision by adding
32
 * "[Contributor] elects to include this software in this distribution
33
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
34
 * single choice of license, a recipient has the option to distribute
35
 * your version of this file under either the CDDL, the GPL Version 2 or
36
 * to extend the choice of license to its licensees as provided above.
37
 * However, if you add GPL Version 2 code and therefore, elected the GPL
38
 * Version 2 license, then the option applies only if the new code is
39
 * made subject to such option by the copyright holder.
40
 */
41
42
package org.netbeans.modules.java.api.common;
43
44
import java.beans.PropertyChangeEvent;
45
import java.beans.PropertyChangeListener;
46
import java.beans.PropertyChangeSupport;
47
import java.io.File;
48
import java.net.MalformedURLException;
49
import java.net.URL;
50
import java.net.URI;
51
import java.util.Arrays;
52
import java.util.ArrayList;
53
import java.util.Collections;
54
import java.util.List;
55
import java.util.Map;
56
import java.util.HashMap;
57
import java.text.MessageFormat;
58
import org.openide.filesystems.FileObject;
59
import org.openide.filesystems.FileUtil;
60
import org.openide.util.Exceptions;
61
import org.openide.util.WeakListeners;
62
import org.openide.util.Mutex;
63
import org.w3c.dom.Element;
64
import org.w3c.dom.NodeList;
65
import org.w3c.dom.Document;
66
import org.netbeans.spi.project.support.ant.AntProjectHelper;
67
import org.netbeans.spi.project.support.ant.AntProjectEvent;
68
import org.netbeans.spi.project.support.ant.AntProjectListener;
69
import org.netbeans.spi.project.support.ant.EditableProperties;
70
import org.netbeans.spi.project.support.ant.PropertyEvaluator;
71
import org.netbeans.spi.project.support.ant.ReferenceHelper;
72
import org.netbeans.api.project.ProjectManager;
73
import org.netbeans.api.java.project.JavaProjectConstants;
74
import org.netbeans.modules.java.api.common.ant.UpdateHelper;
75
76
/**
77
 * This class represents a project source roots. It is used to obtain roots as Ant properties, FileObject's
78
 * or URLs.
79
 * @author Tomas Zezula
80
 */
81
final class SourceRootsImpl implements SourceRoots {
82
83
    private final UpdateHelper helper;
84
    private final PropertyEvaluator evaluator;
85
    private final ReferenceHelper refHelper;
86
    private final String projectConfigurationNamespace;
87
    private final String elementName;
88
    private final String newRootNameTemplate;
89
    private List<String> sourceRootProperties;
90
    private List<String> sourceRootNames;
91
    private List<FileObject> sourceRoots;
92
    private List<URL> sourceRootURLs;
93
    private final PropertyChangeSupport support;
94
    private final ProjectMetadataListener listener;
95
    private final boolean isTest;
96
    private final File projectDir;
97
98
    public SourceRootsImpl(UpdateHelper helper, PropertyEvaluator evaluator, ReferenceHelper refHelper,
99
            String projectConfigurationNamespace, String elementName, boolean isTest, String newRootNameTemplate) {
100
        assert helper != null;
101
        assert evaluator != null;
102
        assert refHelper != null;
103
        assert projectConfigurationNamespace != null;
104
        assert elementName != null;
105
        assert newRootNameTemplate != null;
106
107
        this.helper = helper;
108
        this.evaluator = evaluator;
109
        this.refHelper = refHelper;
110
        this.projectConfigurationNamespace = projectConfigurationNamespace;
111
        this.elementName = elementName;
112
        this.isTest = isTest;
113
        this.newRootNameTemplate = newRootNameTemplate;
114
        this.projectDir = FileUtil.toFile(this.helper.getAntProjectHelper().getProjectDirectory());
115
        this.support = new PropertyChangeSupport(this);
116
        this.listener = new ProjectMetadataListener();
117
        this.evaluator.addPropertyChangeListener(WeakListeners.propertyChange(this.listener, this.evaluator));
118
        this.helper.getAntProjectHelper().addAntProjectListener(
119
                WeakListeners.create(AntProjectListener.class, this.listener, this.helper));
120
    }
121
122
123
    public String[] getRootNames() {
124
        return ProjectManager.mutex().readAccess(new Mutex.Action<String[]>() {
125
            public String[] run() {
126
                synchronized (SourceRootsImpl.this) {
127
                    if (sourceRootNames == null) {
128
                        readProjectMetadata();
129
                    }
130
                }
131
                return sourceRootNames.toArray(new String[sourceRootNames.size()]);
132
            }
133
        });
134
    }
135
136
    public String[] getRootProperties() {
137
        return ProjectManager.mutex().readAccess(new Mutex.Action<String[]>() {
138
            public String[] run() {
139
                synchronized (SourceRootsImpl.this) {
140
                    if (sourceRootProperties == null) {
141
                        readProjectMetadata();
142
                    }
143
                    return sourceRootProperties.toArray(new String[sourceRootProperties.size()]);
144
                }
145
            }
146
        });
147
    }
148
149
    public FileObject[] getRoots() {
150
        return ProjectManager.mutex().readAccess(new Mutex.Action<FileObject[]>() {
151
                public FileObject[] run() {
152
                    synchronized (this) {
153
                        // local caching
154
                        if (sourceRoots == null) {
155
                            String[] srcProps = getRootProperties();
156
                            List<FileObject> result = new ArrayList<FileObject>();
157
                            for (String p : srcProps) {
158
                                String prop = evaluator.getProperty(p);
159
                                if (prop != null) {
160
                                    FileObject f = helper.getAntProjectHelper().resolveFileObject(prop);
161
                                    if (f == null) {
162
                                        continue;
163
                                    }
164
                                    if (FileUtil.isArchiveFile(f)) {
165
                                        f = FileUtil.getArchiveRoot(f);
166
                                    }
167
                                    result.add(f);
168
                                }
169
                            }
170
                            sourceRoots = Collections.unmodifiableList(result);
171
                        }
172
                    }
173
                    return sourceRoots.toArray(new FileObject[sourceRoots.size()]);
174
                }
175
        });
176
    }
177
178
    public URL[] getRootURLs() {
179
        return ProjectManager.mutex().readAccess(new Mutex.Action<URL[]>() {
180
            public URL[] run() {
181
                synchronized (this) {
182
                    // local caching
183
                    if (sourceRootURLs == null) {
184
                        List<URL> result = new ArrayList<URL>();
185
                        for (String srcProp : getRootProperties()) {
186
                            String prop = evaluator.getProperty(srcProp);
187
                            if (prop != null) {
188
                                File f = helper.getAntProjectHelper().resolveFile(prop);
189
                                try {
190
                                    URL url = f.toURI().toURL();
191
                                    if (!f.exists()) {
192
                                        url = new URL(url.toExternalForm() + "/"); // NOI18N
193
                                    } else if (f.isFile()) {
194
                                        // file cannot be a source root (archives are not supported as source roots).
195
                                        continue;
196
                                    }
197
                                    assert url.toExternalForm().endsWith("/") : "#90639 violation for " + url + "; "
198
                                            + f + " exists? " + f.exists() + " dir? " + f.isDirectory()
199
                                            + " file? " + f.isFile();
200
                                    result.add(url);
201
                                } catch (MalformedURLException e) {
202
                                    Exceptions.printStackTrace(e);
203
                                }
204
                            }
205
                        }
206
                        sourceRootURLs = Collections.unmodifiableList(result);
207
                    }
208
                }
209
                return sourceRootURLs.toArray(new URL[sourceRootURLs.size()]);
210
            }
211
        });
212
    }
213
214
    private Map<URL, String> getRootsToProps() {
215
        return ProjectManager.mutex().readAccess(new Mutex.Action<Map<URL, String>>() {
216
            public Map<URL, String> run() {
217
                Map<URL, String> result = new HashMap<URL, String>();
218
                for (String srcProp : getRootProperties()) {
219
                    String prop = evaluator.getProperty(srcProp);
220
                    if (prop != null) {
221
                        File f = helper.getAntProjectHelper().resolveFile(prop);
222
                        try {
223
                            URL url = f.toURI().toURL();
224
                            if (!f.exists()) {
225
                                url = new URL(url.toExternalForm() + "/"); // NOI18N
226
                            } else if (f.isFile()) {
227
                                // file cannot be a source root (archives are not supported as source roots).
228
                                continue;
229
                            }
230
                            assert url.toExternalForm().endsWith("/") : "#90639 violation for " + url + "; "
231
                                    + f + " exists? " + f.exists() + " dir? " + f.isDirectory()
232
                                    + " file? " + f.isFile();
233
                            result.put(url, srcProp);
234
                        } catch (MalformedURLException e) {
235
                            Exceptions.printStackTrace(e);
236
                        }
237
                    }
238
                }
239
                return result;
240
            }
241
        });
242
    }
243
244
    public void addPropertyChangeListener(PropertyChangeListener listener) {
245
        support.addPropertyChangeListener(listener);
246
    }
247
248
    public void removePropertyChangeListener(PropertyChangeListener listener) {
249
        support.removePropertyChangeListener(listener);
250
    }
251
252
253
    public void putRoots(final URL[] roots, final String[] labels) {
254
        ProjectManager.mutex().writeAccess(
255
                new Runnable() {
256
                    public void run() {
257
                        Map<URL, String> oldRoots2props = getRootsToProps();
258
                        Map<URL, String> newRoots2lab = new HashMap<URL, String>();
259
                        for (int i = 0; i < roots.length; i++) {
260
                            newRoots2lab.put(roots[i], labels[i]);
261
                        }
262
                        Element cfgEl = helper.getPrimaryConfigurationData(true);
263
                        NodeList nl = cfgEl.getElementsByTagNameNS(projectConfigurationNamespace, elementName);
264
                        assert nl.getLength() == 1 : "Illegal project.xml"; //NOI18N
265
                        Element ownerElement = (Element) nl.item(0);
266
                        // remove all old roots
267
                        NodeList rootsNodes =
268
                                ownerElement.getElementsByTagNameNS(projectConfigurationNamespace, "root");    //NOI18N
269
                        while (rootsNodes.getLength() > 0) {
270
                            Element root = (Element) rootsNodes.item(0);
271
                            ownerElement.removeChild(root);
272
                        }
273
                        // remove all unused root properties
274
                        List<URL> newRoots = Arrays.asList(roots);
275
                        Map<URL, String> propsToRemove = new HashMap<URL, String>(oldRoots2props);
276
                        propsToRemove.keySet().removeAll(newRoots);
277
                        EditableProperties props = helper.getProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH);
278
                        props.keySet().removeAll(propsToRemove.values());
279
                        helper.putProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH, props);
280
                        // add the new roots
281
                        Document doc = ownerElement.getOwnerDocument();
282
                        oldRoots2props.keySet().retainAll(newRoots);
283
                        for (URL newRoot : newRoots) {
284
                            String rootName = oldRoots2props.get(newRoot);
285
                            if (rootName == null) {
286
                                // root is new generate property for it
287
                                props = helper.getProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH);
288
                                String[] names = newRoot.getPath().split("/");  //NOI18N
289
                                rootName = MessageFormat.format(
290
                                        newRootNameTemplate, new Object[] {names[names.length - 1], ""}); // NOI18N
291
                                int rootIndex = 1;
292
                                while (props.containsKey(rootName)) {
293
                                    rootIndex++;
294
                                    rootName = MessageFormat.format(
295
                                            newRootNameTemplate, new Object[] {names[names.length - 1], rootIndex});
296
                                }
297
                                File f = FileUtil.normalizeFile(new File(URI.create(newRoot.toExternalForm())));
298
                                File projDir = FileUtil.toFile(helper.getAntProjectHelper().getProjectDirectory());
299
                                String path = f.getAbsolutePath();
300
                                String prjPath = projDir.getAbsolutePath() + File.separatorChar;
301
                                if (path.startsWith(prjPath)) {
302
                                    path = path.substring(prjPath.length());
303
                                } else {
304
                                    path = refHelper.createForeignFileReference(
305
                                            f, JavaProjectConstants.SOURCES_TYPE_JAVA);
306
                                    props = helper.getProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH);
307
                                }
308
                                props.put(rootName, path);
309
                                helper.putProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH, props);
310
                            }
311
                            Element newRootNode = doc.createElementNS(projectConfigurationNamespace, "root"); //NOI18N
312
                            newRootNode.setAttribute("id", rootName);    //NOI18N
313
                            String label = newRoots2lab.get(newRoot);
314
                            if (label != null
315
                                    && label.length() > 0
316
                                    && !label.equals(getRootDisplayName(null, rootName))) { //NOI18N
317
                                newRootNode.setAttribute("name", label); //NOI18N
318
                            }
319
                            ownerElement.appendChild(newRootNode);
320
                        }
321
                        helper.putPrimaryConfigurationData(cfgEl, true);
322
                    }
323
                }
324
        );
325
    }
326
327
    public String getRootDisplayName(String rootName, String propName) {
328
        if (rootName == null || rootName.length() == 0) {
329
            // if the prop is src.dir use the default name
330
            if (isTest && "test.src.dir".equals(propName)) { //NOI18N
331
                rootName = DEFAULT_TEST_LABEL;
332
            } else if (!isTest && "src.dir".equals(propName)) { //NOI18N
333
                rootName = DEFAULT_SOURCE_LABEL;
334
            } else {
335
                // if the name is not given, it should be either a relative path in the project dir
336
                // or absolute path when the root is not under the project dir
337
                String propValue = evaluator.getProperty(propName);
338
                File sourceRoot = propValue == null ? null : helper.getAntProjectHelper().resolveFile(propValue);
339
                rootName = createInitialDisplayName(sourceRoot);
340
            }
341
        }
342
        return rootName;
343
    }
344
345
    public String createInitialDisplayName(File sourceRoot) {
346
        String rootName;
347
        if (sourceRoot != null) {
348
            String srPath = sourceRoot.getAbsolutePath();
349
            String pdPath = projectDir.getAbsolutePath() + File.separatorChar;
350
            if (srPath.startsWith(pdPath)) {
351
                rootName = srPath.substring(pdPath.length());
352
            } else {
353
                rootName = sourceRoot.getAbsolutePath();
354
            }
355
        } else {
356
            rootName = isTest ? DEFAULT_TEST_LABEL : DEFAULT_SOURCE_LABEL;
357
        }
358
        return rootName;
359
    }
360
361
    public boolean isTest() {
362
        return isTest;
363
    }
364
365
    private void resetCache(boolean isXMLChange, String propName) {
366
        boolean fire = false;
367
        synchronized (this) {
368
            // in case of change reset local cache
369
            if (isXMLChange) {
370
                sourceRootProperties = null;
371
                sourceRootNames = null;
372
                sourceRoots = null;
373
                sourceRootURLs = null;
374
                fire = true;
375
            } else if (propName == null || (sourceRootProperties != null && sourceRootProperties.contains(propName))) {
376
                sourceRoots = null;
377
                sourceRootURLs = null;
378
                fire = true;
379
            }
380
        }
381
        if (fire) {
382
            if (isXMLChange) {
383
                support.firePropertyChange(PROP_ROOT_PROPERTIES, null, null);
384
            }
385
            support.firePropertyChange(PROP_ROOTS, null, null);
386
        }
387
    }
388
389
    private void readProjectMetadata() {
390
        Element cfgEl = helper.getPrimaryConfigurationData(true);
391
        NodeList nl = cfgEl.getElementsByTagNameNS(projectConfigurationNamespace, elementName);
392
        assert nl.getLength() == 0 || nl.getLength() == 1 : "Illegal project.xml"; //NOI18N
393
        List<String> rootProps = new ArrayList<String>();
394
        List<String> rootNames = new ArrayList<String>();
395
        // it can be 0 in the case when the project is created by J2SEProjectGenerator and not yet customized
396
        if (nl.getLength() == 1) {
397
            NodeList roots =
398
                    ((Element) nl.item(0)).getElementsByTagNameNS(projectConfigurationNamespace, "root"); //NOI18N
399
            for (int i = 0; i < roots.getLength(); i++) {
400
                Element root = (Element) roots.item(i);
401
                String value = root.getAttribute("id"); //NOI18N
402
                assert value.length() > 0 : "Illegal project.xml";
403
                rootProps.add(value);
404
                value = root.getAttribute("name"); //NOI18N
405
                rootNames.add(value);
406
            }
407
        }
408
        sourceRootProperties = Collections.unmodifiableList(rootProps);
409
        sourceRootNames = Collections.unmodifiableList(rootNames);
410
    }
411
412
    private class ProjectMetadataListener implements PropertyChangeListener, AntProjectListener {
413
414
        public void propertyChange(PropertyChangeEvent evt) {
415
            resetCache(false, evt.getPropertyName());
416
        }
417
418
        public void configurationXmlChanged(AntProjectEvent ev) {
419
            resetCache(true, null);
420
        }
421
422
        public void propertiesChanged(AntProjectEvent ev) {
423
            // handled by propertyChange
424
        }
425
    }
426
427
}
(-)a/java.commonapi/src/org/netbeans/modules/java/api/common/SourceRootsSupport.java (+68 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 1997-2007 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 2007 Sun Microsystems, Inc.
38
 */
39
40
package org.netbeans.modules.java.api.common;
41
42
import org.netbeans.modules.java.api.common.ant.UpdateHelper;
43
import org.netbeans.spi.project.support.ant.PropertyEvaluator;
44
import org.netbeans.spi.project.support.ant.ReferenceHelper;
45
import org.openide.util.Parameters;
46
47
/**
48
 * Support class for creating {@link SourceRoots} implementation.
49
 * @author Tomas Mysik
50
 */
51
public final class SourceRootsSupport {
52
53
    private SourceRootsSupport() {
54
    }
55
56
    public static SourceRoots create(UpdateHelper helper, PropertyEvaluator evaluator, ReferenceHelper refHelper,
57
            String projectConfigurationNamespace, String elementName, boolean isTest, String newRootNameTemplate) {
58
        Parameters.notNull("helper", helper); // NOI18N
59
        Parameters.notNull("evaluator", evaluator); // NOI18N
60
        Parameters.notNull("refHelper", refHelper); // NOI18N
61
        Parameters.notNull("projectConfigurationNamespace", projectConfigurationNamespace); // NOI18N
62
        Parameters.notNull("elementName", elementName); // NOI18N
63
        Parameters.notNull("newRootNameTemplate", newRootNameTemplate); // NOI18N
64
65
        return new SourceRootsImpl(helper, evaluator, refHelper, projectConfigurationNamespace, elementName, isTest,
66
                newRootNameTemplate);
67
    }
68
}
(-)a/java.commonapi/src/org/netbeans/modules/java/api/common/ant/UpdateHelper.java (+217 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 1997-2007 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
 * Contributor(s):
25
 *
26
 * The Original Software is NetBeans. The Initial Developer of the Original
27
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
28
 * Microsystems, Inc. All Rights Reserved.
29
 *
30
 * If you wish your version of this file to be governed by only the CDDL
31
 * or only the GPL Version 2, indicate your decision by adding
32
 * "[Contributor] elects to include this software in this distribution
33
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
34
 * single choice of license, a recipient has the option to distribute
35
 * your version of this file under either the CDDL, the GPL Version 2 or
36
 * to extend the choice of license to its licensees as provided above.
37
 * However, if you add GPL Version 2 code and therefore, elected the GPL
38
 * Version 2 license, then the option applies only if the new code is
39
 * made subject to such option by the copyright holder.
40
 */
41
42
package org.netbeans.modules.java.api.common.ant;
43
44
import java.io.IOException;
45
import org.openide.util.Exceptions;
46
import org.w3c.dom.Element;
47
import org.openide.util.Mutex;
48
import org.netbeans.api.project.ProjectManager;
49
import org.netbeans.spi.project.support.ant.AntProjectHelper;
50
import org.netbeans.spi.project.support.ant.EditableProperties;
51
import org.openide.util.MutexException;
52
import org.openide.util.Parameters;
53
54
55
/**
56
 * Proxy for the {@link AntProjectHelper} which defers the update of the project metadata
57
 * to explicit user action. Caller has to provide implementation of {@link UpdateProject}
58
 * which takes care of updating project itself.
59
 * @author Tomas Zezula, Tomas Mysik
60
 * @see UpdateImplementation
61
 */
62
public final class UpdateHelper {
63
64
    private final UpdateImplementation updateProject;
65
    private final AntProjectHelper helper;
66
67
    /**
68
     * Create new {@link UpdateHelper}.
69
     * @param updateProject {@link UpdateImplementation} which takes care of updating project itself.
70
     * @param helper {@link AntProjectHelper} to be proxied.
71
     */
72
    public UpdateHelper(UpdateImplementation updateProject, AntProjectHelper helper) {
73
        Parameters.notNull("updateProject", updateProject); // NOI18N
74
        Parameters.notNull("helper", helper); // NOI18N
75
76
        this.updateProject = updateProject;
77
        this.helper = helper;
78
    }
79
80
    /**
81
     * In the case that the project is of current version or the properties
82
     * are not {@link AntProjectHelper#PROJECT_PROPERTIES_PATH} it calls
83
     * {@link AntProjectHelper#getProperties(String)} otherwise it asks for updated project properties.
84
     * @param path a relative URI in the project directory.
85
     * @return a set of properties.
86
     */
87
    public EditableProperties getProperties(final String path) {
88
        return ProjectManager.mutex().readAccess(new Mutex.Action<EditableProperties>() {
89
            public EditableProperties run() {
90
                if (!isCurrent() && AntProjectHelper.PROJECT_PROPERTIES_PATH.equals(path)) {
91
                    // only project properties were changed
92
                    return updateProject.getUpdatedProjectProperties();
93
                }
94
                return helper.getProperties(path);
95
            }
96
        });
97
    }
98
99
    /**
100
     * In the case that the project is of current version or the properties
101
     * are not {@link AntProjectHelper#PROJECT_PROPERTIES_PATH} it calls
102
     * {@link AntProjectHelper#putProperties(String, EditableProperties)} otherwise it asks to update project.
103
     * If the project can be updated, it does the update and calls
104
     * {@link AntProjectHelper#putProperties(String, EditableProperties)}.
105
     * @param path a relative URI in the project directory.
106
     * @param props a set of properties.
107
     */
108
    public void putProperties(final String path, final EditableProperties props) {
109
        ProjectManager.mutex().writeAccess(
110
            new Runnable() {
111
                public void run() {
112
                    if (isCurrent() || !AntProjectHelper.PROJECT_PROPERTIES_PATH.equals(path)) {
113
                        // only project props should cause update
114
                        helper.putProperties(path, props);
115
                    } else if (updateProject.canUpdate()) {
116
                        try {
117
                            updateProject.saveUpdate(props);
118
                            helper.putProperties(path, props);
119
                        } catch (IOException ioe) {
120
                            Exceptions.printStackTrace(ioe);
121
                        }
122
                    }
123
                }
124
            });
125
    }
126
127
    /**
128
     * In the case that the project is of current version or shared is <code>false</code> it delegates to
129
     * {@link AntProjectHelper#getPrimaryConfigurationData(boolean)}.
130
     * Otherwise it creates an in memory update of shared configuration data and returns it.
131
     * @param shared if <code>true</code>, refers to <e>project.xml</e>, else refers to
132
     *               <e>private.xml</e>.
133
     * @return the configuration data that is available.
134
     */
135
    public Element getPrimaryConfigurationData(final boolean shared) {
136
        return ProjectManager.mutex().readAccess(new Mutex.Action<Element>() {
137
            public Element run() {
138
                if (!shared || isCurrent()) { // only shared props should cause update
139
                    return helper.getPrimaryConfigurationData(shared);
140
                }
141
                return updateProject.getUpdatedSharedConfigurationData();
142
            }
143
        });
144
    }
145
146
    /**
147
     * In the case that the project is of current version or shared is <code>false</code> it calls
148
     * {@link AntProjectHelper#putPrimaryConfigurationData(Element, boolean)}.
149
     * Otherwise the project can be updated, it does the update and calls
150
     * {@link AntProjectHelper#putPrimaryConfigurationData(Element, boolean)}.
151
     * @param element the configuration data
152
     * @param shared if true, refers to <code>project.xml</code>, else refers to
153
     * <code>private.xml</code>
154
     */
155
    public void putPrimaryConfigurationData(final Element element, final boolean shared) {
156
        ProjectManager.mutex().writeAccess(new Runnable() {
157
            public void run () {
158
                if (!shared || isCurrent()) {
159
                    helper.putPrimaryConfigurationData(element, shared);
160
                } else if (updateProject.canUpdate()) {
161
                    try {
162
                        updateProject.saveUpdate(null);
163
                        helper.putPrimaryConfigurationData(element, shared);
164
                    } catch (IOException ioe) {
165
                        Exceptions.printStackTrace(ioe);
166
                    }
167
                }
168
            }
169
        });
170
    }
171
172
    /**
173
     * Request saving of update. If the project is not of current version and the project can be updated, then
174
     * the update is done.
175
     * @return <code>true</code> if the metadata are of current version or updated.
176
     * @throws IOException if error occurs during saving.
177
     */
178
    public boolean requestUpdate() throws IOException {
179
        try {
180
            return ProjectManager.mutex().writeAccess(new Mutex.ExceptionAction<Boolean>() {
181
                public Boolean run() throws IOException {
182
                    if (isCurrent()) {
183
                        return true;
184
                    }
185
                    if (!updateProject.canUpdate()) {
186
                        return false;
187
                    }
188
                    updateProject.saveUpdate(null);
189
                    return true;
190
                }
191
            });
192
193
        } catch (MutexException ex) {
194
            Exception inner = ex.getException();
195
            if (inner instanceof IOException) {
196
                throw (IOException) inner;
197
            }
198
            throw (RuntimeException) inner;
199
        }
200
    }
201
202
    /**
203
     * Return <code>true</code> if the project is of current version.
204
     * @return <code>true</code> if the project is of current version.
205
     */
206
    public boolean isCurrent() {
207
        return updateProject.isCurrent();
208
    }
209
210
    /**
211
     * Get the {@link AntProjectHelper} that is proxied.
212
     * @return the {@link AntProjectHelper} that is proxied.
213
     */
214
    public AntProjectHelper getAntProjectHelper() {
215
        return helper;
216
    }
217
}
(-)a/java.commonapi/src/org/netbeans/modules/java/api/common/ant/UpdateImplementation.java (+87 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 1997-2007 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 2007 Sun Microsystems, Inc.
38
 */
39
40
package org.netbeans.modules.java.api.common.ant;
41
42
import java.io.IOException;
43
import org.netbeans.spi.project.support.ant.EditableProperties;
44
import org.w3c.dom.Element;
45
46
/**
47
 * Interface that has to be implemented in order to use {@link UpdateHelper}. It represents and does the project update
48
 * process itself.
49
 * @author Tomas Mysik
50
 * @see UpdateHelper
51
 */
52
public interface UpdateImplementation {
53
54
    /**
55
     * Return <code>true</code> if the project is of current version.
56
     * @return <code>true</code> if the project is of current version.
57
     */
58
    boolean isCurrent();
59
60
    /**
61
     * Return <code>true</code> if the project can be updated.
62
     * @return <code>true</code> if the project can be updated.
63
     */
64
    boolean canUpdate();
65
66
    /**
67
     * Saving of update. If the project is of current version it should probably do nothing.
68
     * @param props project properties to be saved, can be <code>null</code>. There's no need to save them because
69
     *          {@link UpdateHelper} does it.
70
     * @throws IOException if error occurs during saving.
71
     */
72
    void saveUpdate(final EditableProperties props) throws IOException;
73
74
    /**
75
     * Creates probably an in memory update of shared configuration data and return it.
76
     * @return the configuration data that is available.
77
     * @see {@link UpdateHelper#getPrimaryConfigurationData(boolean)}
78
     */
79
    Element getUpdatedSharedConfigurationData();
80
81
    /**
82
     * Creates probably an in memory update of project properties.
83
     * @return a set of properties.
84
     * @see {@link UpdateHelper#getProperties(String)}
85
     */
86
    EditableProperties getUpdatedProjectProperties();
87
}
(-)a/java.commonapi/src/org/netbeans/modules/java/api/common/queries/CompiledSourceForBinaryQueryImpl.java (+160 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 1997-2007 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
 * Contributor(s):
25
 *
26
 * The Original Software is NetBeans. The Initial Developer of the Original
27
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
28
 * Microsystems, Inc. All Rights Reserved.
29
 *
30
 * If you wish your version of this file to be governed by only the CDDL
31
 * or only the GPL Version 2, indicate your decision by adding
32
 * "[Contributor] elects to include this software in this distribution
33
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
34
 * single choice of license, a recipient has the option to distribute
35
 * your version of this file under either the CDDL, the GPL Version 2 or
36
 * to extend the choice of license to its licensees as provided above.
37
 * However, if you add GPL Version 2 code and therefore, elected the GPL
38
 * Version 2 license, then the option applies only if the new code is
39
 * made subject to such option by the copyright holder.
40
 */
41
package org.netbeans.modules.java.api.common.queries;
42
43
import org.netbeans.modules.java.api.common.SourceRoots;
44
import java.io.File;
45
import org.netbeans.spi.java.queries.SourceForBinaryQueryImplementation;
46
import org.netbeans.spi.project.support.ant.AntProjectHelper;
47
import org.openide.filesystems.FileObject;
48
import org.openide.filesystems.FileUtil;
49
import java.net.URL;
50
import java.net.MalformedURLException;
51
import java.beans.PropertyChangeListener;
52
import java.beans.PropertyChangeEvent;
53
import java.util.Map;
54
import java.util.HashMap;
55
import javax.swing.event.ChangeListener;
56
import org.netbeans.api.java.queries.SourceForBinaryQuery;
57
import org.netbeans.spi.project.support.ant.PropertyEvaluator;
58
import org.openide.util.ChangeSupport;
59
import org.openide.util.Exceptions;
60
61
/**
62
 * Default implementation of {@link SourceForBinaryQueryImplementation}.
63
 * @author Jesse Glick, Tomas Zezula
64
 */
65
class CompiledSourceForBinaryQueryImpl implements SourceForBinaryQueryImplementation {
66
67
    private final AntProjectHelper helper;
68
    private final PropertyEvaluator evaluator;
69
    private final SourceRoots sourceRoots;
70
    private final SourceRoots testRoots;
71
    private final Map<URL, SourceForBinaryQuery.Result> cache = new HashMap<URL, SourceForBinaryQuery.Result>();
72
73
    public CompiledSourceForBinaryQueryImpl(AntProjectHelper helper, PropertyEvaluator evaluator, SourceRoots srcRoots,
74
            SourceRoots testRoots) {
75
        assert helper != null;
76
        assert evaluator != null;
77
        assert srcRoots != null;
78
        assert testRoots != null;
79
80
        this.helper = helper;
81
        this.evaluator = evaluator;
82
        this.sourceRoots = srcRoots;
83
        this.testRoots = testRoots;
84
    }
85
86
    public SourceForBinaryQuery.Result findSourceRoots(URL binaryRoot) {
87
        if (FileUtil.getArchiveFile(binaryRoot) != null) {
88
            binaryRoot = FileUtil.getArchiveFile(binaryRoot);
89
            // XXX check whether this is really the root
90
        }
91
        SourceForBinaryQuery.Result res = cache.get(binaryRoot);
92
        if (res != null) {
93
            return res;
94
        }
95
        SourceRoots src = null;
96
        if (hasSources(binaryRoot, "build.classes.dir")) { //NOI18N
97
            src = sourceRoots;
98
        } else if (hasSources(binaryRoot, "dist.jar")) { //NOI18N
99
            src = sourceRoots;
100
        } else if (hasSources(binaryRoot, "build.test.classes.dir")) { //NOI18N
101
            src = testRoots;
102
        }
103
        if (src == null) {
104
            return null;
105
        }
106
        res = new Result(src);
107
        cache.put(binaryRoot, res);
108
        return res;
109
    }
110
111
    private boolean hasSources(URL binaryRoot, String binaryProperty) {
112
        try {
113
            String outDir = evaluator.getProperty(binaryProperty);
114
            if (outDir != null) {
115
                File f = helper.resolveFile(outDir);
116
                URL url = f.toURI().toURL();
117
                if (!f.exists() && !f.getPath().toLowerCase().endsWith(".jar")) { // NOI18N
118
                    // non-existing
119
                    assert !url.toExternalForm().endsWith("/") : f; // NOI18N
120
                    url = new URL(url.toExternalForm() + "/"); // NOI18N
121
                }
122
                if (url.equals(binaryRoot)) {
123
                    return true;
124
                }
125
            }
126
        } catch (MalformedURLException malformedURL) {
127
            Exceptions.printStackTrace(malformedURL);
128
        }
129
        return false;
130
    }
131
132
    private class Result implements SourceForBinaryQuery.Result, PropertyChangeListener {
133
134
        private final ChangeSupport changeSupport = new ChangeSupport(this);
135
        private SourceRoots sourceRoots;
136
137
        public Result(SourceRoots sourceRoots) {
138
            this.sourceRoots = sourceRoots;
139
            this.sourceRoots.addPropertyChangeListener(this);
140
        }
141
142
        public FileObject[] getRoots() {
143
            return this.sourceRoots.getRoots(); // no need to cache it, SourceRoots does
144
        }
145
146
        public void addChangeListener (ChangeListener l) {
147
            changeSupport.addChangeListener(l);
148
        }
149
150
        public void removeChangeListener (ChangeListener l) {
151
            changeSupport.removeChangeListener(l);
152
        }
153
154
        public void propertyChange(PropertyChangeEvent evt) {
155
            if (SourceRoots.PROP_ROOTS.equals(evt.getPropertyName())) {
156
                changeSupport.fireChange();
157
            }
158
        }
159
    }
160
}
(-)a/java.commonapi/src/org/netbeans/modules/java/api/common/queries/FileBuiltQueryImpl.java (+122 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 1997-2007 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
 * Contributor(s):
25
 *
26
 * The Original Software is NetBeans. The Initial Developer of the Original
27
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
28
 * Microsystems, Inc. All Rights Reserved.
29
 *
30
 * If you wish your version of this file to be governed by only the CDDL
31
 * or only the GPL Version 2, indicate your decision by adding
32
 * "[Contributor] elects to include this software in this distribution
33
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
34
 * single choice of license, a recipient has the option to distribute
35
 * your version of this file under either the CDDL, the GPL Version 2 or
36
 * to extend the choice of license to its licensees as provided above.
37
 * However, if you add GPL Version 2 code and therefore, elected the GPL
38
 * Version 2 license, then the option applies only if the new code is
39
 * made subject to such option by the copyright holder.
40
 */
41
package org.netbeans.modules.java.api.common.queries;
42
43
import java.beans.PropertyChangeEvent;
44
import java.beans.PropertyChangeListener;
45
import org.netbeans.api.project.ProjectManager;
46
import org.openide.filesystems.FileObject;
47
import org.netbeans.api.queries.FileBuiltQuery;
48
import org.netbeans.modules.java.api.common.SourceRoots;
49
import org.netbeans.spi.queries.FileBuiltQueryImplementation;
50
import org.netbeans.spi.project.support.ant.AntProjectHelper;
51
import org.netbeans.spi.project.support.ant.PropertyEvaluator;
52
import org.openide.util.Mutex.Action;
53
54
55
/**
56
 * Default implementation of {@link FileBuiltQueryImplementation}.
57
 * @author Jesse Glick, Tomas Zezula
58
 */
59
final class FileBuiltQueryImpl implements FileBuiltQueryImplementation, PropertyChangeListener {
60
61
    private FileBuiltQueryImplementation delegate;
62
    private final AntProjectHelper helper;
63
    private final PropertyEvaluator evaluator;
64
    private final SourceRoots sourceRoots;
65
    private final SourceRoots testRoots;
66
67
    FileBuiltQueryImpl(AntProjectHelper helper, PropertyEvaluator evaluator, SourceRoots sourceRoots,
68
            SourceRoots testRoots) {
69
        assert helper != null;
70
        assert evaluator != null;
71
        assert sourceRoots != null;
72
        assert testRoots != null;
73
74
        this.helper = helper;
75
        this.evaluator = evaluator;
76
        this.sourceRoots = sourceRoots;
77
        this.testRoots = testRoots;
78
        this.sourceRoots.addPropertyChangeListener(this);
79
        this.testRoots.addPropertyChangeListener(this);
80
    }
81
82
    public FileBuiltQuery.Status getStatus(final FileObject file) {
83
        return ProjectManager.mutex().readAccess(new Action<FileBuiltQuery.Status>() {
84
            public FileBuiltQuery.Status run() {
85
                return getStatusImpl(file);
86
            }
87
        });
88
    }
89
90
    private synchronized FileBuiltQuery.Status getStatusImpl(FileObject file) {
91
        if (delegate == null) {
92
            delegate = createDelegate();
93
        }
94
        return delegate.getStatus(file);
95
    }
96
97
98
    private FileBuiltQueryImplementation createDelegate() {
99
        String[] srcRoots = sourceRoots.getRootProperties();
100
        String[] tstRoots = testRoots.getRootProperties();
101
        String[] from = new String [srcRoots.length + tstRoots.length];
102
        String[] to = new String [srcRoots.length + tstRoots.length];
103
        for (int i = 0; i < srcRoots.length; i++) {
104
            from[i] = "${" + srcRoots[i] + "}/*.java"; // NOI18N
105
            to[i] = "${build.classes.dir}/*.class"; // NOI18N
106
        }
107
        for (int i = 0; i < tstRoots.length; i++) {
108
            from[srcRoots.length + i] = "${" + tstRoots[i] + "}/*.java"; // NOI18N
109
            to[srcRoots.length + i] = "${build.test.classes.dir}/*.class"; // NOI18N
110
        }
111
        return helper.createGlobFileBuiltQuery(evaluator, from, to); // save to pass APH
112
    }
113
114
    public void propertyChange(PropertyChangeEvent evt) {
115
        if (SourceRoots.PROP_ROOT_PROPERTIES.equals(evt.getPropertyName())) {
116
            synchronized (this) {
117
                delegate = null;
118
                // XXX: what to do with already returned Statuses
119
            }
120
        }
121
    }
122
}
(-)a/java.commonapi/src/org/netbeans/modules/java/api/common/queries/FileEncodingQueryImpl.java (+109 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 1997-2007 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
 * Contributor(s):
25
 *
26
 * The Original Software is NetBeans. The Initial Developer of the Original
27
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
28
 * Microsystems, Inc. All Rights Reserved.
29
 *
30
 * If you wish your version of this file to be governed by only the CDDL
31
 * or only the GPL Version 2, indicate your decision by adding
32
 * "[Contributor] elects to include this software in this distribution
33
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
34
 * single choice of license, a recipient has the option to distribute
35
 * your version of this file under either the CDDL, the GPL Version 2 or
36
 * to extend the choice of license to its licensees as provided above.
37
 * However, if you add GPL Version 2 code and therefore, elected the GPL
38
 * Version 2 license, then the option applies only if the new code is
39
 * made subject to such option by the copyright holder.
40
 */
41
42
package org.netbeans.modules.java.api.common.queries;
43
44
import java.beans.PropertyChangeEvent;
45
import java.beans.PropertyChangeListener;
46
import java.nio.charset.Charset;
47
import java.nio.charset.IllegalCharsetNameException;
48
import java.nio.charset.UnsupportedCharsetException;
49
import org.netbeans.spi.queries.FileEncodingQueryImplementation;
50
import org.netbeans.spi.project.support.ant.PropertyEvaluator;
51
import org.openide.filesystems.FileObject;
52
import org.openide.util.Parameters;
53
54
/**
55
 * Default implementation of {@link FileEncodingQueryImplementation}. It listens to the changes
56
 * in particular property values.
57
 * @author Tomas Zezula
58
 */
59
class FileEncodingQueryImpl extends FileEncodingQueryImplementation implements PropertyChangeListener {
60
61
    private final PropertyEvaluator eval;
62
    private final String sourceEncodingPropertyName;
63
    private Charset cache;
64
65
    public FileEncodingQueryImpl(final PropertyEvaluator eval, final String sourceEncodingPropertyName) {
66
        assert eval != null;
67
        assert sourceEncodingPropertyName != null;
68
69
        this.eval = eval;
70
        this.sourceEncodingPropertyName = sourceEncodingPropertyName;
71
        this.eval.addPropertyChangeListener(this);
72
    }
73
74
    public Charset getEncoding(FileObject file) {
75
        Parameters.notNull("file", file); // NOI18N
76
77
        synchronized (this) {
78
            if (cache != null) {
79
                return cache;
80
            }
81
        }
82
        String enc = eval.getProperty(sourceEncodingPropertyName);
83
        synchronized (this) {
84
            if (cache == null) {
85
                try {
86
                    //From discussion with K. Frank the project returns Charset.defaultCharset ()
87
                    //for old j2se projects. The old project used system encoding => Charset.defaultCharset ()
88
                    //should work for most users.
89
                    cache = enc == null ? Charset.defaultCharset() : Charset.forName(enc);
90
                } catch (IllegalCharsetNameException exception) {
91
                    return null;
92
                } catch (UnsupportedCharsetException exception) {
93
                    return null;
94
                }
95
            }
96
            return cache;
97
        }
98
    }
99
100
    public void propertyChange(PropertyChangeEvent event) {
101
        String propName = event.getPropertyName();
102
        if (propName == null || propName.equals(sourceEncodingPropertyName)) {
103
            synchronized (this) {
104
                cache = null;
105
            }
106
        }
107
    }
108
109
}
(-)a/java.commonapi/src/org/netbeans/modules/java/api/common/queries/JavadocForBinaryQueryImpl.java (+173 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 1997-2007 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
 * Contributor(s):
25
 *
26
 * The Original Software is NetBeans. The Initial Developer of the Original
27
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
28
 * Microsystems, Inc. All Rights Reserved.
29
 *
30
 * If you wish your version of this file to be governed by only the CDDL
31
 * or only the GPL Version 2, indicate your decision by adding
32
 * "[Contributor] elects to include this software in this distribution
33
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
34
 * single choice of license, a recipient has the option to distribute
35
 * your version of this file under either the CDDL, the GPL Version 2 or
36
 * to extend the choice of license to its licensees as provided above.
37
 * However, if you add GPL Version 2 code and therefore, elected the GPL
38
 * Version 2 license, then the option applies only if the new code is
39
 * made subject to such option by the copyright holder.
40
 */
41
package org.netbeans.modules.java.api.common.queries;
42
43
import java.beans.PropertyChangeEvent;
44
import java.beans.PropertyChangeListener;
45
import java.io.File;
46
import org.netbeans.spi.project.support.ant.AntProjectHelper;
47
import org.openide.filesystems.FileUtil;
48
import java.net.URL;
49
import java.net.MalformedURLException;
50
import javax.swing.event.ChangeListener;
51
import org.netbeans.api.java.queries.JavadocForBinaryQuery;
52
import org.netbeans.spi.java.queries.JavadocForBinaryQueryImplementation;
53
import org.netbeans.spi.project.support.ant.PropertyEvaluator;
54
import org.openide.util.ChangeSupport;
55
import org.openide.util.Exceptions;
56
import org.openide.util.WeakListeners;
57
58
/**
59
 * Finds Javadoc (if it is built) corresponding to binaries in a project.
60
 * @author David Konecny, Jesse Glick
61
 */
62
class JavadocForBinaryQueryImpl implements JavadocForBinaryQueryImplementation {
63
64
    private static final String PROP_JAVADOC_DIR = "dist.javadoc.dir";  //NOI18N
65
66
    private final AntProjectHelper helper;
67
    private final PropertyEvaluator evaluator;
68
69
    public JavadocForBinaryQueryImpl(AntProjectHelper helper, PropertyEvaluator evaluator) {
70
        assert helper != null;
71
        assert evaluator != null;
72
73
        this.helper = helper;
74
        this.evaluator = evaluator;
75
    }
76
77
    public JavadocForBinaryQuery.Result findJavadoc(final URL binaryRoot) {
78
79
        class Result implements JavadocForBinaryQuery.Result, PropertyChangeListener  {
80
81
            private final ChangeSupport changeSupport = new ChangeSupport(this);
82
            private URL[] result;
83
            private long eventId;
84
85
            public Result() {
86
                JavadocForBinaryQueryImpl.this.evaluator.addPropertyChangeListener(
87
                        WeakListeners.propertyChange(this, JavadocForBinaryQueryImpl.this.evaluator));
88
            }
89
90
            public URL[] getRoots() {
91
                long lEventId;
92
                synchronized (this) {
93
                    if (this.result != null) {
94
                        return this.result;
95
                    }
96
                    lEventId = eventId;
97
                }
98
                URL[] lResult;
99
                String javadocDir = evaluator.getProperty(PROP_JAVADOC_DIR);
100
                if (javadocDir != null) {
101
                    File f = helper.resolveFile(javadocDir);
102
                    try {
103
                        URL url = f.toURI().toURL();
104
                        if (!f.exists()) {
105
                            assert !url.toExternalForm().endsWith("/") : f; // NOI18N
106
                            url = new URL(url.toExternalForm() + "/"); // NOI18N
107
                        }
108
                        lResult = new URL[] {url};
109
                    } catch (MalformedURLException e) {
110
                        lResult = new URL[0];
111
                        Exceptions.printStackTrace(e);
112
                    }
113
                } else {
114
                    lResult = new URL[0];
115
                }
116
                synchronized (this) {
117
                    if (lEventId == eventId) {
118
                        if (this.result == null) {
119
                            this.result = lResult;
120
                        }
121
                        return this.result;
122
                    }
123
                    return lResult;
124
                }
125
            }
126
127
            public void addChangeListener(final ChangeListener l) {
128
                changeSupport.addChangeListener(l);
129
            }
130
131
            public void removeChangeListener(final ChangeListener l) {
132
                changeSupport.removeChangeListener(l);
133
            }
134
135
            public void propertyChange(final PropertyChangeEvent event) {
136
                if (PROP_JAVADOC_DIR.equals(event.getPropertyName())) {
137
                    synchronized (this) {
138
                        result = null;
139
                        eventId++;
140
                    }
141
                    this.changeSupport.fireChange();
142
                }
143
            }
144
        }
145
        if (isRootOwner(binaryRoot, "build.classes.dir") || isRootOwner(binaryRoot, "dist.jar")) { //NOI18N
146
            return new Result();
147
        }
148
        return null;
149
    }
150
151
    private boolean isRootOwner(URL binaryRoot, String binaryProperty) {
152
        try {
153
            if (FileUtil.getArchiveFile(binaryRoot) != null) {
154
                binaryRoot = FileUtil.getArchiveFile(binaryRoot);
155
                // XXX check whether this is really the root
156
            }
157
            String outDir = evaluator.getProperty(binaryProperty);
158
            if (outDir != null) {
159
                File f = helper.resolveFile(outDir);
160
                URL url = f.toURI().toURL();
161
                if (!f.exists() && !f.getPath().toLowerCase().endsWith(".jar")) { // NOI18N
162
                    assert !url.toExternalForm().endsWith("/") : f; // NOI18N
163
                    url = new URL(url.toExternalForm() + "/"); // NOI18N
164
                }
165
                return url.equals(binaryRoot)
166
                        || binaryRoot.toExternalForm().startsWith(url.toExternalForm());
167
            }
168
        } catch (MalformedURLException malformedURL) {
169
            Exceptions.printStackTrace(malformedURL);
170
        }
171
        return false;
172
    }
173
}
(-)a/java.commonapi/src/org/netbeans/modules/java/api/common/queries/QuerySupport.java (+190 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 1997-2007 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 2007 Sun Microsystems, Inc.
38
 */
39
40
package org.netbeans.modules.java.api.common.queries;
41
42
import org.netbeans.modules.java.api.common.SourceRoots;
43
import org.netbeans.spi.java.queries.JavadocForBinaryQueryImplementation;
44
import org.netbeans.spi.java.queries.MultipleRootsUnitTestForSourceQueryImplementation;
45
import org.netbeans.spi.java.queries.SourceForBinaryQueryImplementation;
46
import org.netbeans.spi.java.queries.SourceLevelQueryImplementation;
47
import org.netbeans.spi.project.support.ant.AntProjectHelper;
48
import org.netbeans.spi.project.support.ant.PropertyEvaluator;
49
import org.netbeans.spi.queries.FileBuiltQueryImplementation;
50
import org.netbeans.spi.queries.FileEncodingQueryImplementation;
51
import org.netbeans.spi.queries.SharabilityQueryImplementation;
52
import org.openide.util.Parameters;
53
54
/**
55
 * Support class for creating different types of queries implementations.
56
 * @author Tomas Mysik
57
 */
58
public final class QuerySupport {
59
60
    private QuerySupport() {
61
    }
62
63
    /**
64
     * Create a new query to provide information about where Java sources
65
     * corresponding to binaries (classfiles) can be found.
66
     * @param helper {@link AntProjectHelper} used for resolving files, e.g. output directory.
67
     * @param evaluator {@link PropertyEvaluator} used for obtaining project properties.
68
     * @param srcRoots a list of source roots.
69
     * @param testRoots a list of test roots.
70
     * @return {@link SourceForBinaryQueryImplementation} to provide information about where Java sources can be found.
71
     * @see SourceForBinaryQueryImplementation
72
     */
73
    public static SourceForBinaryQueryImplementation createCompiledSourceForBinaryQuery(AntProjectHelper helper,
74
            PropertyEvaluator evaluator, SourceRoots srcRoots, SourceRoots testRoots) {
75
        Parameters.notNull("helper", helper); // NOI18N
76
        Parameters.notNull("evaluator", evaluator); // NOI18N
77
        Parameters.notNull("srcRoots", srcRoots); // NOI18N
78
        Parameters.notNull("testRoots", testRoots); // NOI18N
79
80
        return new CompiledSourceForBinaryQueryImpl(helper, evaluator, srcRoots, testRoots);
81
    }
82
83
    /**
84
     * Create a new query to provide information about encoding of a file. The returned query listens to the changes
85
     * in particular property values.
86
     * @param eval {@link PropertyEvaluator} used for obtaining the value of source encoding.
87
     * @param sourceEncodingPropertyName the source encoding property name.
88
     * @return a {@link FileEncodingQueryImplementation} to provide information about encoding of a file.
89
     */
90
    public static FileEncodingQueryImplementation createFileEncodingQuery(PropertyEvaluator eval,
91
            String sourceEncodingPropertyName) {
92
        Parameters.notNull("eval", eval); // NOI18N
93
        Parameters.notNull("sourceEncodingPropertyName", sourceEncodingPropertyName); // NOI18N
94
95
        return new FileEncodingQueryImpl(eval, sourceEncodingPropertyName);
96
    }
97
98
    /**
99
     * Create a new query to find Javadoc. The returned query listens on changes of the Javadoc directory.
100
     * @param helper {@link AntProjectHelper} used for resolving files, e.g. output directory.
101
     * @param evaluator {@link PropertyEvaluator} used for obtaining the Javadoc root.
102
     * @return a {@link JavadocForBinaryQueryImplementation} to find Javadoc.
103
     */
104
    public static JavadocForBinaryQueryImplementation createJavadocForBinaryQuery(AntProjectHelper helper,
105
            PropertyEvaluator evaluator) {
106
        Parameters.notNull("helper", helper); // NOI18N
107
        Parameters.notNull("evaluator", evaluator); // NOI18N
108
109
        return new JavadocForBinaryQueryImpl(helper, evaluator);
110
    }
111
112
    /**
113
     * Create a new query to provide information about files sharability. The returned query listens to the changes
114
     * in particular source roots.
115
     * @param helper {@link AntProjectHelper} used for creating a query itself.
116
     * @param evaluator a {@link PropertyEvaluator property evaluator} to interpret paths with.
117
     * @param srcRoots a list of source roots to treat as sharable.
118
     * @param testRoots a list of test roots to treat as sharable.
119
     * @param additionalSourceRoots additional paths to treat as sharable (just pure property names, do not
120
     *          use <i>${</i> and <i>}</i> characters). Can be <code>null</code>.
121
     * @return a {@link SharabilityQueryImplementation} to provide information about files sharability.
122
     */
123
    public static SharabilityQueryImplementation createSharabilityQuery(AntProjectHelper helper,
124
            PropertyEvaluator evaluator, SourceRoots srcRoots, SourceRoots testRoots,
125
            String... additionalSourceRoots) {
126
        Parameters.notNull("helper", helper); // NOI18N
127
        Parameters.notNull("evaluator", evaluator); // NOI18N
128
        Parameters.notNull("srcRoots", srcRoots); // NOI18N
129
        Parameters.notNull("testRoots", testRoots); // NOI18N
130
131
        return new SharabilityQueryImpl(helper, evaluator, srcRoots, testRoots, additionalSourceRoots);
132
    }
133
134
    /**
135
     * Create a new query to provide information about files sharability without any additional source roots. See
136
     * {@link #createSharabilityQuery(AntProjectHelper, PropertyEvaluator, SourceRoots, SourceRoots, String...)
137
     * createSharabilityQuery()}
138
     * for more information.
139
     */
140
    public static SharabilityQueryImplementation createSharabilityQuery(AntProjectHelper helper,
141
            PropertyEvaluator evaluator, SourceRoots srcRoots, SourceRoots testRoots) {
142
143
        return createSharabilityQuery(helper, evaluator, srcRoots, testRoots, (String[]) null);
144
    }
145
146
    /**
147
     * Create a new query to find out specification source level of Java source files.
148
     * @param evaluator {@link PropertyEvaluator} used for obtaining needed properties.
149
     * @return a {@link SourceLevelQueryImplementation} to find out specification source level of Java source files.
150
     */
151
    public static SourceLevelQueryImplementation createSourceLevelQuery(PropertyEvaluator evaluator) {
152
        Parameters.notNull("evaluator", evaluator); // NOI18N
153
154
        return new SourceLevelQueryImpl(evaluator);
155
    }
156
157
    /**
158
     * Create a new query to find Java package roots of unit tests for Java package root of sources and vice versa.
159
     * @param sourceRoots a list of source roots.
160
     * @param testRoots a list of test roots.
161
     * @return a {@link MultipleRootsUnitTestForSourceQueryImplementation} to find Java package roots of unit tests
162
     *         for Java package root of sources and vice versa.
163
     */
164
    public static MultipleRootsUnitTestForSourceQueryImplementation createUnitTestForSourceQuery(
165
            SourceRoots sourceRoots, SourceRoots testRoots) {
166
        Parameters.notNull("sourceRoots", sourceRoots); // NOI18N
167
        Parameters.notNull("testRoots", testRoots); // NOI18N
168
169
        return new UnitTestForSourceQueryImpl(sourceRoots, testRoots);
170
    }
171
172
    /**
173
     * Create a new query to test whether a file can be considered to be built (up to date). The returned query
174
     * listens to the changes in particular source roots.
175
     * @param helper {@link AntProjectHelper} used for creating a query itself.
176
     * @param evaluator {@link PropertyEvaluator} used for obtaining needed properties.
177
     * @param sourceRoots a list of source roots.
178
     * @param testRoots a list of test roots.
179
     * @return a {@link FileBuiltQueryImplementation} to test whether a file can be considered to be built (up to date).
180
     */
181
    public static FileBuiltQueryImplementation createFileBuiltQuery(AntProjectHelper helper,
182
            PropertyEvaluator evaluator, SourceRoots sourceRoots, SourceRoots testRoots) {
183
        Parameters.notNull("helper", helper); // NOI18N
184
        Parameters.notNull("evaluator", evaluator); // NOI18N
185
        Parameters.notNull("sourceRoots", sourceRoots); // NOI18N
186
        Parameters.notNull("testRoots", testRoots); // NOI18N
187
188
        return new FileBuiltQueryImpl(helper, evaluator, sourceRoots, testRoots);
189
    }
190
}
(-)a/java.commonapi/src/org/netbeans/modules/java/api/common/queries/SharabilityQueryImpl.java (+133 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 1997-2007 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
 * Contributor(s):
25
 *
26
 * The Original Software is NetBeans. The Initial Developer of the Original
27
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
28
 * Microsystems, Inc. All Rights Reserved.
29
 *
30
 * If you wish your version of this file to be governed by only the CDDL
31
 * or only the GPL Version 2, indicate your decision by adding
32
 * "[Contributor] elects to include this software in this distribution
33
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
34
 * single choice of license, a recipient has the option to distribute
35
 * your version of this file under either the CDDL, the GPL Version 2 or
36
 * to extend the choice of license to its licensees as provided above.
37
 * However, if you add GPL Version 2 code and therefore, elected the GPL
38
 * Version 2 license, then the option applies only if the new code is
39
 * made subject to such option by the copyright holder.
40
 */
41
42
package org.netbeans.modules.java.api.common.queries;
43
44
import org.netbeans.modules.java.api.common.SourceRoots;
45
import java.io.File;
46
import java.beans.PropertyChangeEvent;
47
import java.beans.PropertyChangeListener;
48
import java.util.ArrayList;
49
import java.util.Arrays;
50
import java.util.Collections;
51
import java.util.List;
52
import org.openide.util.Mutex;
53
import org.netbeans.api.project.ProjectManager;
54
import org.netbeans.spi.queries.SharabilityQueryImplementation;
55
import org.netbeans.spi.project.support.ant.AntProjectHelper;
56
import org.netbeans.spi.project.support.ant.PropertyEvaluator;
57
58
/**
59
 * Default implementation of {@link SharabilityQueryImplementation} which is capable to take more sources.
60
 * It listens to the changes in particular property values.
61
 * @author Tomas Zezula, Tomas Mysik
62
 */
63
class SharabilityQueryImpl implements SharabilityQueryImplementation, PropertyChangeListener {
64
65
    private final AntProjectHelper helper;
66
    private final PropertyEvaluator evaluator;
67
    private final SourceRoots srcRoots;
68
    private final SourceRoots testRoots;
69
    private final List<String> additionalSourceRoots;
70
    private SharabilityQueryImplementation delegate;
71
72
    public SharabilityQueryImpl(AntProjectHelper helper, PropertyEvaluator evaluator, SourceRoots srcRoots,
73
            SourceRoots testRoots, String... additionalSourceRoots) {
74
        assert helper != null;
75
        assert evaluator != null;
76
        assert srcRoots != null;
77
        assert testRoots != null;
78
79
        this.helper = helper;
80
        this.evaluator = evaluator;
81
        this.srcRoots = srcRoots;
82
        this.testRoots = testRoots;
83
        if (additionalSourceRoots != null) {
84
            this.additionalSourceRoots = Collections.unmodifiableList(Arrays.asList(additionalSourceRoots));
85
        } else {
86
            this.additionalSourceRoots = Collections.<String>emptyList();
87
        }
88
        this.srcRoots.addPropertyChangeListener(this);
89
        this.testRoots.addPropertyChangeListener(this);
90
    }
91
92
    public int getSharability(final File file) {
93
        return ProjectManager.mutex().readAccess(new Mutex.Action<Integer>() {
94
            public Integer run() {
95
                synchronized (SharabilityQueryImpl.this) {
96
                    if (delegate == null) {
97
                        delegate = createDelegate();
98
                    }
99
                    return delegate.getSharability(file);
100
                }
101
            }
102
        });
103
    }
104
105
    public void propertyChange(PropertyChangeEvent evt) {
106
        if (SourceRoots.PROP_ROOT_PROPERTIES.equals(evt.getPropertyName())) {
107
            synchronized (this) {
108
                delegate = null;
109
            }
110
        }
111
    }
112
113
    private SharabilityQueryImplementation createDelegate() {
114
        String[] srcProps = srcRoots.getRootProperties();
115
        String[] testProps = testRoots.getRootProperties();
116
        String[] buildDirectories = new String[] {"${dist.dir}", "${build.dir}"}; // NOI18N
117
118
        int size = srcProps.length;
119
        size += testProps.length;
120
        size += additionalSourceRoots.size();
121
        List<String> props = new ArrayList<String>(size);
122
123
        for (String src : srcProps) {
124
            props.add("${" + src + "}"); // NOI18N
125
        }
126
        for (String test : testProps) {
127
            props.add("${" + test + "}"); // NOI18N
128
        }
129
        props.addAll(additionalSourceRoots);
130
131
        return helper.createSharabilityQuery(evaluator, props.toArray(new String[props.size()]), buildDirectories);
132
    }
133
}
(-)a/java.commonapi/src/org/netbeans/modules/java/api/common/queries/SourceLevelQueryImpl.java (+85 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 1997-2007 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
 * Contributor(s):
25
 *
26
 * The Original Software is NetBeans. The Initial Developer of the Original
27
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
28
 * Microsystems, Inc. All Rights Reserved.
29
 *
30
 * If you wish your version of this file to be governed by only the CDDL
31
 * or only the GPL Version 2, indicate your decision by adding
32
 * "[Contributor] elects to include this software in this distribution
33
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
34
 * single choice of license, a recipient has the option to distribute
35
 * your version of this file under either the CDDL, the GPL Version 2 or
36
 * to extend the choice of license to its licensees as provided above.
37
 * However, if you add GPL Version 2 code and therefore, elected the GPL
38
 * Version 2 license, then the option applies only if the new code is
39
 * made subject to such option by the copyright holder.
40
 */
41
package org.netbeans.modules.java.api.common.queries;
42
43
import org.netbeans.api.java.platform.JavaPlatform;
44
import org.netbeans.api.java.platform.JavaPlatformManager;
45
import org.netbeans.api.java.platform.Specification;
46
import org.netbeans.modules.java.api.common.util.CommonProjectUtils;
47
import org.netbeans.spi.java.queries.SourceLevelQueryImplementation;
48
import org.netbeans.spi.project.support.ant.PropertyEvaluator;
49
import org.netbeans.spi.project.support.ant.PropertyUtils;
50
import org.netbeans.spi.project.support.ant.EditableProperties;
51
import org.openide.filesystems.FileObject;
52
53
/**
54
 * Returns source level of project Java source files.
55
 * @author David Konecny
56
 */
57
class SourceLevelQueryImpl implements SourceLevelQueryImplementation {
58
59
    private final PropertyEvaluator evaluator;
60
61
    public SourceLevelQueryImpl(PropertyEvaluator evaluator) {
62
        assert evaluator != null;
63
64
        this.evaluator = evaluator;
65
    }
66
67
    public String getSourceLevel(FileObject javaFile) {
68
        final String activePlatform = evaluator.getProperty("platform.active"); //NOI18N
69
        if (CommonProjectUtils.getActivePlatform(activePlatform) != null) {
70
            String sl = evaluator.getProperty("javac.source"); //NOI18N
71
            if (sl != null && sl.length() > 0) {
72
                return sl;
73
            }
74
            return null;
75
        }
76
77
        EditableProperties props = PropertyUtils.getGlobalProperties();
78
        String sl = props.get("default.javac.source"); //NOI18N
79
        if (sl != null && sl.length() > 0) {
80
            return sl;
81
        }
82
        return null;
83
    }
84
85
}
(-)a/java.commonapi/src/org/netbeans/modules/java/api/common/queries/UnitTestForSourceQueryImpl.java (+89 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 1997-2007 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
 * Contributor(s):
25
 *
26
 * The Original Software is NetBeans. The Initial Developer of the Original
27
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
28
 * Microsystems, Inc. All Rights Reserved.
29
 *
30
 * If you wish your version of this file to be governed by only the CDDL
31
 * or only the GPL Version 2, indicate your decision by adding
32
 * "[Contributor] elects to include this software in this distribution
33
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
34
 * single choice of license, a recipient has the option to distribute
35
 * your version of this file under either the CDDL, the GPL Version 2 or
36
 * to extend the choice of license to its licensees as provided above.
37
 * However, if you add GPL Version 2 code and therefore, elected the GPL
38
 * Version 2 license, then the option applies only if the new code is
39
 * made subject to such option by the copyright holder.
40
 */
41
42
package org.netbeans.modules.java.api.common.queries;
43
44
import org.netbeans.modules.java.api.common.SourceRoots;
45
import java.net.URL;
46
import org.netbeans.api.project.FileOwnerQuery;
47
import org.netbeans.api.project.Project;
48
import org.netbeans.spi.java.queries.MultipleRootsUnitTestForSourceQueryImplementation;
49
import org.openide.filesystems.FileObject;
50
51
/**
52
 * Default implementation of {@link MultipleRootsUnitTestForSourceQueryImplementation}.
53
 * @author Tomas Zezula
54
 */
55
class UnitTestForSourceQueryImpl implements MultipleRootsUnitTestForSourceQueryImplementation {
56
57
    private final SourceRoots sourceRoots;
58
    private final SourceRoots testRoots;
59
60
    public UnitTestForSourceQueryImpl(SourceRoots sourceRoots, SourceRoots testRoots) {
61
        assert sourceRoots != null;
62
        assert testRoots != null;
63
64
        this.sourceRoots = sourceRoots;
65
        this.testRoots = testRoots;
66
    }
67
68
    public URL[] findUnitTests(FileObject source) {
69
        return find(source, sourceRoots, testRoots);
70
    }
71
72
    public URL[] findSources(FileObject unitTest) {
73
        return find(unitTest, testRoots, sourceRoots);
74
    }
75
76
    private URL[] find(FileObject file, SourceRoots from, SourceRoots to) {
77
        Project p = FileOwnerQuery.getOwner(file);
78
        if (p == null) {
79
            return null;
80
        }
81
        for (FileObject fromRoot : from.getRoots()) {
82
            if (fromRoot.equals(file)) {
83
                return to.getRootURLs();
84
            }
85
        }
86
        return null;
87
    }
88
89
}
(-)a/java.commonapi/src/org/netbeans/modules/java/api/common/resources/Bundle.properties (+6 lines)
Line 0 Link Here
1
OpenIDE-Module-Display-Category=Java
2
OpenIDE-Module-Long-Description=\
3
    Miscellaneous API implementations that are common for all the project types, it means J2SEProject, Java EE projects such as WebProject, EjbJarProject, AppClientProject. \
4
    Supplies default implementation of FileEncodingQuery, SourceLevelQuery etc.
5
OpenIDE-Module-Name=Java Common Project API
6
OpenIDE-Module-Short-Description=API implementations common to all the project types.
(-)a/java.commonapi/src/org/netbeans/modules/java/api/common/resources/layer.xml (+4 lines)
Line 0 Link Here
1
<?xml version="1.0" encoding="UTF-8"?>
2
<!DOCTYPE filesystem PUBLIC "-//NetBeans//DTD Filesystem 1.1//EN" "http://www.netbeans.org/dtds/filesystem-1_1.dtd">
3
<filesystem>
4
</filesystem>
(-)a/java.commonapi/src/org/netbeans/modules/java/api/common/ui/Bundle.properties (+53 lines)
Line 0 Link Here
1
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
2
#
3
# Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
4
#
5
# The contents of this file are subject to the terms of either the GNU
6
# General Public License Version 2 only ("GPL") or the Common
7
# Development and Distribution License("CDDL") (collectively, the
8
# "License"). You may not use this file except in compliance with the
9
# License. You can obtain a copy of the License at
10
# http://www.netbeans.org/cddl-gplv2.html
11
# or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
12
# specific language governing permissions and limitations under the
13
# License.  When distributing the software, include this License Header
14
# Notice in each file and include the License file at
15
# nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
16
# particular file as subject to the "Classpath" exception as provided
17
# by Sun in the GPL Version 2 section of the License file that
18
# accompanied this code. If applicable, add the following below the
19
# License Header, with the fields enclosed by brackets [] replaced by
20
# your own identifying information:
21
# "Portions Copyrighted [year] [name of copyright owner]"
22
#
23
# If you wish your version of this file to be governed by only the CDDL
24
# or only the GPL Version 2, indicate your decision by adding
25
# "[Contributor] elects to include this software in this distribution
26
# under the [CDDL or GPL Version 2] license." If you do not indicate a
27
# single choice of license, a recipient has the option to distribute
28
# your version of this file under either the CDDL, the GPL Version 2 or
29
# to extend the choice of license to its licensees as provided above.
30
# However, if you add GPL Version 2 code and therefore, elected the GPL
31
# Version 2 license, then the option applies only if the new code is
32
# made subject to such option by the copyright holder.
33
#
34
# Contributor(s):
35
#
36
# Portions Copyrighted 2007 Sun Microsystems, Inc.
37
38
# PlatformUiSupport
39
# {0} - JDK version
40
LBL_JDK=JDK {0}
41
# {0} - Platform Name
42
TXT_BrokenPlatformFmt=Missing platform: {0}
43
# {0} - Source Level
44
TXT_InvalidSourceLevel=Illegal Source Level: {0}
45
CTL_ChangePlatform=Change Platform
46
AD_ChangePlatform=N/A
47
TXT_ChangePlatform=<html><b>Incompatible Source Level Value {0}</b></html>\n\
48
    The source level version for this project ({0}) is higher than the\n\
49
    Java Platform version you just selected ({1}). Changing the Java\n\
50
    Platform will update the project''s source level to version {1}.\n\n\
51
    Do you want to change the Java Platform and update the source level\n\
52
    version?
53
TXT_ChangePlatformTitle=Change Java Platform
(-)a/java.commonapi/src/org/netbeans/modules/java/api/common/ui/PlatformUiSupport.java (+778 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 1997-2007 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
 * Contributor(s):
25
 *
26
 * The Original Software is NetBeans. The Initial Developer of the Original
27
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
28
 * Microsystems, Inc. All Rights Reserved.
29
 *
30
 * If you wish your version of this file to be governed by only the CDDL
31
 * or only the GPL Version 2, indicate your decision by adding
32
 * "[Contributor] elects to include this software in this distribution
33
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
34
 * single choice of license, a recipient has the option to distribute
35
 * your version of this file under either the CDDL, the GPL Version 2 or
36
 * to extend the choice of license to its licensees as provided above.
37
 * However, if you add GPL Version 2 code and therefore, elected the GPL
38
 * Version 2 license, then the option applies only if the new code is
39
 * made subject to such option by the copyright holder.
40
 */
41
42
package org.netbeans.modules.java.api.common.ui;
43
44
import java.awt.Component;
45
import java.beans.PropertyChangeEvent;
46
import java.beans.PropertyChangeListener;
47
import java.text.MessageFormat;
48
import java.util.ArrayList;
49
import java.util.List;
50
import java.util.Set;
51
import java.util.TreeSet;
52
import java.util.logging.Logger;
53
import javax.swing.AbstractListModel;
54
import javax.swing.ComboBoxModel;
55
import javax.swing.JButton;
56
import javax.swing.JList;
57
import javax.swing.ListCellRenderer;
58
import javax.swing.event.ListDataEvent;
59
import javax.swing.event.ListDataListener;
60
import org.netbeans.api.java.platform.JavaPlatform;
61
import org.netbeans.api.java.platform.JavaPlatformManager;
62
import org.netbeans.api.java.platform.Specification;
63
import org.netbeans.modules.java.api.common.ant.UpdateHelper;
64
import org.netbeans.spi.project.support.ant.EditableProperties;
65
import org.openide.DialogDisplayer;
66
import org.openide.NotifyDescriptor;
67
import org.openide.awt.HtmlRenderer;
68
import org.openide.modules.SpecificationVersion;
69
import org.openide.util.NbBundle;
70
import org.openide.util.Parameters;
71
import org.openide.util.WeakListeners;
72
import org.w3c.dom.Element;
73
import org.w3c.dom.NodeList;
74
75
/**
76
 * Support class for {@link JavaPlatform} manipulation in project customizer.
77
 * @author Tomas Zezula, Tomas Mysik
78
 */
79
public final class PlatformUiSupport {
80
81
    /**
82
     * Enum used for specifying minimal version of the source level. Currently, only JDK 5 is supported.
83
     * @see PlatformUiSupport#createSourceLevelComboBoxModel(ComboBoxModel, String, String, String)
84
     */
85
    public enum JDK { VERSION_5 }
86
87
    private static final SpecificationVersion JDK_1_5 = new SpecificationVersion("1.5"); //NOI18N
88
    private static final SpecificationVersion JDK_1_6 = new SpecificationVersion("1.6"); //NOI18N
89
    private static final Logger LOGGER = Logger.getLogger(PlatformUiSupport.class.getName());
90
91
    private PlatformUiSupport() {
92
    }
93
94
    /**
95
     * Create a {@link ComboBoxModel} of Java platforms.
96
     * The model listens on the {@link JavaPlatformManager} and update its
97
     * state according to the changes.
98
     * @param activePlatform the active project's platform, can be <code>null</code>.
99
     * @return {@link ComboBoxModel}.
100
     */
101
    public static ComboBoxModel createPlatformComboBoxModel(String activePlatform) {
102
        return new PlatformComboBoxModel(activePlatform);
103
    }
104
105
106
    /**
107
     * Create a {@link ListCellRenderer} for rendering items of the {@link ComboBoxModel}
108
     * created by the {@link PlatformUiSupport#createPlatformComboBoxModel(String)} method.
109
     * @return {@link ListCellRenderer}.
110
     */
111
    public static ListCellRenderer createPlatformListCellRenderer() {
112
        return new PlatformListCellRenderer();
113
    }
114
115
    /**
116
     * Like {@link #storePlatform(EditableProperties, UpdateHelper, Object, Object)}, but platform name may be
117
     * <code>null</code> (in such case the default platform is used).
118
     * @param props project's shared properties.
119
     * @param helper {@link UpdateHelper} that is capable to upgrade project metadata if needed.
120
     * @param projectConfigurationNamespace project configuration namespace.
121
     * @param platformName platform name to store, can be <code>null</code>.
122
     * @param sourceLevel specification version to store.
123
     */
124
    public static void storePlatform(EditableProperties props, UpdateHelper helper,
125
            String projectConfigurationNamespace, String platformName, SpecificationVersion sourceLevel) {
126
        Parameters.notNull("props", props); //NOI18N
127
        Parameters.notNull("helper", helper); //NOI18N
128
        Parameters.notNull("projectConfigurationNamespace", projectConfigurationNamespace); //NOI18N
129
        Parameters.notNull("sourceLevel", sourceLevel); //NOI18N
130
131
        PlatformKey platformKey;
132
        if (platformName != null) {
133
            platformKey = new PlatformKey(PlatformUiSupport.findPlatform(platformName));
134
        } else {
135
            platformKey = new PlatformKey(JavaPlatformManager.getDefault().getDefaultPlatform());
136
        }
137
        storePlatform(props, helper, projectConfigurationNamespace, platformKey, new SourceLevelKey(sourceLevel));
138
    }
139
140
    /**
141
     * Stores active platform, <i>javac.source</i> and <i>javac.target</i> into the project's metadata.
142
     * @param props project's shared properties
143
     * @param helper {@link UpdateHelper} that is capable to upgrade project metadata if needed.
144
     * @param projectConfigurationNamespace project configuration namespace.
145
     * @param platformKey the {@link PlatformKey} got from the platform model.
146
     * @param sourceLevelKey {@link SourceLevelKey} representing source level; can be <code>null</code>.
147
     */
148
    public static void storePlatform(EditableProperties props, UpdateHelper helper,
149
            String projectConfigurationNamespace, Object platformKey, Object sourceLevelKey) {
150
        Parameters.notNull("props", props); //NOI18N
151
        Parameters.notNull("helper", helper); //NOI18N
152
        Parameters.notNull("projectConfigurationNamespace", projectConfigurationNamespace); //NOI18N
153
        Parameters.notNull("platformKey", platformKey); //NOI18N
154
155
        assert platformKey instanceof PlatformKey;
156
157
        final String javaPlatformKey = "platform.active"; //NOI18N
158
        final String javacSourceKey = "javac.source"; //NOI18N
159
        final String javacTargetKey = "javac.target"; //NOI18N
160
161
        PlatformKey pk = (PlatformKey) platformKey;
162
        JavaPlatform platform = getPlatform(pk);
163
        // null means active broken (unresolved) platform, no need to do anything
164
        if (platform == null) {
165
            return;
166
        }
167
168
        SpecificationVersion jdk13 = new SpecificationVersion("1.3"); //NOI18N
169
        String platformAntName = platform.getProperties().get("platform.ant.name"); //NOI18N
170
        assert platformAntName != null;
171
        props.put(javaPlatformKey, platformAntName);
172
        Element root = helper.getPrimaryConfigurationData(true);
173
        boolean changed = false;
174
        NodeList explicitPlatformNodes =
175
                root.getElementsByTagNameNS(projectConfigurationNamespace, "explicit-platform"); //NOI18N
176
177
        if (pk.isDefaultPlatform()) {
178
            if (explicitPlatformNodes.getLength() == 1) {
179
                root.removeChild(explicitPlatformNodes.item(0));
180
                changed = true;
181
            }
182
        } else {
183
            Element explicitPlatform;
184
            switch (explicitPlatformNodes.getLength()) {
185
                case 0:
186
                    explicitPlatform = root.getOwnerDocument().createElementNS(
187
                            projectConfigurationNamespace, "explicit-platform"); //NOI18N
188
                    NodeList sourceRootNodes = root.getElementsByTagNameNS(
189
                            projectConfigurationNamespace, "source-roots"); //NOI18N
190
                    assert sourceRootNodes.getLength() == 1 : "Broken project.xml file";
191
192
                    root.insertBefore(explicitPlatform, sourceRootNodes.item(0));
193
                    changed = true;
194
                    break;
195
                case 1:
196
                    explicitPlatform = (Element) explicitPlatformNodes.item(0);
197
                    break;
198
                default:
199
                    throw new AssertionError("Broken project.xml file");
200
            }
201
            String explicitSourceAttrValue = explicitPlatform.getAttribute("explicit-source-supported"); //NOI18N
202
            if (jdk13.compareTo(platform.getSpecification().getVersion()) >= 0
203
                    && !"false".equals(explicitSourceAttrValue)) { //NOI18N
204
                explicitPlatform.setAttribute("explicit-source-supported", "false"); //NOI18N
205
                changed = true;
206
            } else if (jdk13.compareTo(platform.getSpecification().getVersion()) < 0
207
                    && !"true".equals(explicitSourceAttrValue)) { //NOI18N
208
                explicitPlatform.setAttribute("explicit-source-supported", "true"); //NOI18N
209
                changed = true;
210
            }
211
        }
212
213
        SpecificationVersion sourceLevel;
214
        if (sourceLevelKey == null) {
215
            sourceLevel = platform.getSpecification().getVersion();
216
        } else {
217
            assert sourceLevelKey instanceof SourceLevelKey;
218
            sourceLevel = ((SourceLevelKey) sourceLevelKey).getSourceLevel();
219
        }
220
        String javacSource = sourceLevel.toString();
221
        String javacTarget = javacSource;
222
223
        //Issue #116490
224
        // Customizer value | -source | -target
225
        // JDK 1.2            1.2        1.1
226
        // JDK 1.3            1.3        1.1
227
        // JDK 1.4            1.4        1.4
228
        // JDK 5              1.5        1.5
229
        // JDK 6              1.5        1.6
230
        // JDK 7              1.7        1.7  - should bring a new language features
231
        if (jdk13.compareTo(sourceLevel) >= 0) {
232
            javacTarget = "1.1"; //NOI18N
233
        } else if (JDK_1_6.equals(sourceLevel)) {
234
            javacSource = JDK_1_5.toString();
235
        }
236
237
        if (!javacSource.equals(props.getProperty(javacSourceKey))) {
238
            props.setProperty(javacSourceKey, javacSource);
239
        }
240
        if (!javacTarget.equals(props.getProperty(javacTargetKey))) {
241
            props.setProperty(javacTargetKey, javacTarget);
242
        }
243
244
        if (changed) {
245
            helper.putPrimaryConfigurationData(root, true);
246
        }
247
    }
248
249
250
    /**
251
     * Return a {@link JavaPlatform} for an item obtained from the ComboBoxModel created by
252
     * the {@link PlatformUiSupport#createPlatformComboBoxModel(String)} method. This method
253
     * can return <code>null</code> if the platform is broken.
254
     * @param platformKey an item obtained from {@link ComboBoxModel} created by
255
     *                    {@link PlatformUiSupport#createPlatformComboBoxModel(String)}.
256
     * @return {@link JavaPlatform} or <code>null</code> in case when platform is broken.
257
     * @throws IllegalArgumentException if the input parameter is not an object created by platform combobox model.
258
     */
259
    public static JavaPlatform getPlatform(Object platformKey) {
260
        Parameters.notNull("platformKey", platformKey); //NOI18N
261
262
        if (platformKey instanceof PlatformKey) {
263
            return getPlatform((PlatformKey) platformKey);
264
        }
265
        throw new IllegalArgumentException();
266
    }
267
268
    /**
269
     * Create {@link ComboBoxModel} of source levels for active platform.
270
     * The model listens on the platform's {@link ComboBoxModel} and update its
271
     * state according to the changes. It is possible to define minimal JDK version.
272
     * @param platformComboBoxModel the platform's model used for listenning.
273
     * @param initialSourceLevel initial source level value.
274
     * @param initialTargetLevel initial target level value.
275
     * @param minimalJDKVersion minimal JDK version to be displayed. It can be <code>null</code> if all the JDK versions
276
     *                          should be displayed (typically for Java SE project).
277
     * @return {@link ComboBoxModel} of {@link SourceLevelKey}.
278
     * @see #createSourceLevelComboBoxModel(ComboBoxModel, String, String)
279
     */
280
    public static ComboBoxModel createSourceLevelComboBoxModel(ComboBoxModel platformComboBoxModel,
281
            String initialSourceLevel, String initialTargetLevel, JDK minimalJDKVersion) {
282
        Parameters.notNull("platformComboBoxModel", platformComboBoxModel); // NOI18N
283
        Parameters.notNull("initialSourceLevel", initialSourceLevel); // NOI18N
284
        Parameters.notNull("initialTargetLevel", initialTargetLevel); // NOI18N
285
286
        return new SourceLevelComboBoxModel(platformComboBoxModel, initialSourceLevel, initialTargetLevel,
287
                minimalJDKVersion);
288
    }
289
290
    /**
291
     * Exactly like {@link #createSourceLevelComboBoxModel(ComboBoxModel, String, String, JDK)}
292
     * but without any minimal JDK version.
293
     * @param platformComboBoxModel the platform's model used for listenning.
294
     * @param initialSourceLevel initial source level value.
295
     * @param initialTargetLevel initial target level value.
296
     * @return {@link ComboBoxModel} of {@link SourceLevelKey}.
297
     * @see #createSourceLevelComboBoxModel(ComboBoxModel, String, String, JDK)
298
     */
299
    public static ComboBoxModel createSourceLevelComboBoxModel(ComboBoxModel platformComboBoxModel,
300
            String initialSourceLevel, String initialTargetLevel) {
301
        Parameters.notNull("platformComboBoxModel", platformComboBoxModel); // NOI18N
302
        Parameters.notNull("initialSourceLevel", initialSourceLevel); // NOI18N
303
        Parameters.notNull("initialTargetLevel", initialTargetLevel); // NOI18N
304
305
        return new SourceLevelComboBoxModel(platformComboBoxModel, initialSourceLevel, initialTargetLevel, null);
306
    }
307
308
    /**
309
     * Create {@link ListCellRenderer} for source levels. This method could be used when highlighting
310
     * of illegal source levels is needed.
311
     * @return {@link ListCellRenderer} for source levels.
312
     */
313
    public static ListCellRenderer createSourceLevelListCellRenderer() {
314
        return new SourceLevelListCellRenderer();
315
    }
316
317
    /**
318
     * This class represents a JavaPlatform in the {@link ListModel}
319
     * created by the {@link PlatformUiSupport#createPlatformComboBoxModel(String)} method.
320
     */
321
    private static final class PlatformKey implements Comparable {
322
323
        private String name;
324
        private JavaPlatform platform;
325
326
        /**
327
         * Create a PlatformKey for a broken platform.
328
         * @param name the ant name of the broken platform.
329
         */
330
        public PlatformKey(String name) {
331
            assert name != null;
332
            this.name = name;
333
        }
334
335
        /**
336
         * Create a PlatformKey for a platform.
337
         * @param platform the {@link JavaPlatform}.
338
         */
339
        public PlatformKey(JavaPlatform platform) {
340
            assert platform != null;
341
            this.platform = platform;
342
        }
343
344
        public int compareTo(Object o) {
345
            return this.getDisplayName().compareTo(((PlatformKey) o).getDisplayName());
346
        }
347
348
        @Override
349
        public boolean equals(Object other) {
350
            if (other instanceof PlatformKey) {
351
                PlatformKey otherKey = (PlatformKey) other;
352
                boolean equals;
353
                if (this.platform == null) {
354
                    equals = otherKey.platform == null;
355
                } else {
356
                    equals = this.platform.equals(otherKey.platform);
357
                }
358
                return equals && otherKey.getDisplayName().equals(this.getDisplayName());
359
            }
360
            return false;
361
        }
362
363
        @Override
364
        public int hashCode() {
365
            return getDisplayName().hashCode();
366
        }
367
368
        @Override
369
        public String toString() {
370
            return getDisplayName();
371
        }
372
373
        public synchronized String getDisplayName() {
374
            if (this.name == null) {
375
                this.name = this.platform.getDisplayName();
376
            }
377
            return this.name;
378
        }
379
380
        public boolean isDefaultPlatform() {
381
            if (this.platform == null) {
382
                return false;
383
            }
384
            return this.platform.equals(JavaPlatformManager.getDefault().getDefaultPlatform());
385
        }
386
387
        public boolean isBroken() {
388
            return this.platform == null;
389
        }
390
    }
391
392
    private static final class SourceLevelKey implements Comparable {
393
394
        private final SpecificationVersion sourceLevel;
395
        private final boolean broken;
396
397
        public SourceLevelKey(final SpecificationVersion sourceLevel) {
398
            this(sourceLevel, false);
399
        }
400
401
        public SourceLevelKey(final SpecificationVersion sourceLevel, final boolean broken) {
402
            assert sourceLevel != null : "Source level cannot be null";
403
            this.sourceLevel = sourceLevel;
404
            this.broken = broken;
405
        }
406
407
        public SpecificationVersion getSourceLevel() {
408
            return this.sourceLevel;
409
        }
410
411
        public boolean isBroken() {
412
            return this.broken;
413
        }
414
415
        public int compareTo(final Object other) {
416
            assert other instanceof SourceLevelKey : "Illegal argument of SourceLevelKey.compareTo()";
417
            SourceLevelKey otherKey = (SourceLevelKey) other;
418
            return this.sourceLevel.compareTo(otherKey.sourceLevel);
419
        }
420
421
        @Override
422
        public boolean equals(final Object other) {
423
            return (other instanceof SourceLevelKey)
424
                    && ((SourceLevelKey) other).sourceLevel.equals(this.sourceLevel);
425
        }
426
427
        @Override
428
        public int hashCode() {
429
            return this.sourceLevel.hashCode();
430
        }
431
432
        @Override
433
        public String toString() {
434
            StringBuilder buffer = new StringBuilder();
435
            if (this.broken) {
436
                buffer.append("Broken: "); //NOI18N
437
            }
438
            buffer.append(this.sourceLevel.toString());
439
            return buffer.toString();
440
        }
441
442
        public String getDisplayName() {
443
            String tmp = sourceLevel.toString();
444
            if (JDK_1_5.compareTo(sourceLevel) <= 0) {
445
                tmp = tmp.replaceFirst("^1\\.([5-9]|\\d\\d+)$", "$1"); //NOI18N
446
            }
447
            return NbBundle.getMessage(PlatformUiSupport.class, "LBL_JDK", tmp);
448
        }
449
    }
450
451
    private static final class PlatformComboBoxModel extends AbstractListModel
452
            implements ComboBoxModel, PropertyChangeListener {
453
        private static final long serialVersionUID = 1L;
454
455
        private final JavaPlatformManager pm;
456
        private PlatformKey[] platformNamesCache;
457
        private String initialPlatform;
458
        private PlatformKey selectedPlatform;
459
460
        public PlatformComboBoxModel(String initialPlatform) {
461
            this.pm = JavaPlatformManager.getDefault();
462
            this.pm.addPropertyChangeListener(WeakListeners.propertyChange(this, this.pm));
463
            this.initialPlatform = initialPlatform;
464
        }
465
466
        public int getSize() {
467
            PlatformKey[] platformNames = getPlatformNames();
468
            return platformNames.length;
469
        }
470
471
        public Object getElementAt(int index) {
472
            PlatformKey[] platformNames = getPlatformNames();
473
            assert index >= 0 && index < platformNames.length;
474
            return platformNames[index];
475
        }
476
477
        public Object getSelectedItem() {
478
            getPlatformNames(); // force setting of selectedPlatform if it is not already done
479
            return selectedPlatform;
480
        }
481
482
        public void setSelectedItem(Object obj) {
483
            selectedPlatform = (PlatformKey) obj;
484
            fireContentsChanged(this, -1, -1);
485
        }
486
487
        public void propertyChange(PropertyChangeEvent event) {
488
            if (JavaPlatformManager.PROP_INSTALLED_PLATFORMS.equals(event.getPropertyName())) {
489
                synchronized (this) {
490
                    platformNamesCache = null;
491
                }
492
                fireContentsChanged(this, -1, -1);
493
            }
494
        }
495
496
        private synchronized PlatformKey[] getPlatformNames() {
497
            if (platformNamesCache == null) {
498
                JavaPlatform[] platforms = pm.getPlatforms(null, new Specification("j2se", null)); //NOI18N
499
                Set<PlatformKey> orderedNames = new TreeSet<PlatformKey>();
500
                boolean activeFound = false;
501
                for (JavaPlatform platform : platforms) {
502
                    if (platform.getInstallFolders().size() > 0) {
503
                        PlatformKey pk = new PlatformKey(platform);
504
                        orderedNames.add(pk);
505
                        if (!activeFound && initialPlatform != null) {
506
                            String antName = platform.getProperties().get("platform.ant.name"); //NOI18N
507
                            if (initialPlatform.equals(antName)) {
508
                                if (selectedPlatform == null) {
509
                                    selectedPlatform = pk;
510
                                    initialPlatform = null;
511
                                }
512
                                activeFound = true;
513
                            }
514
                        }
515
                    }
516
                }
517
                if (!activeFound) {
518
                    if (initialPlatform == null) {
519
                        if (selectedPlatform == null || !orderedNames.contains(selectedPlatform)) {
520
                            selectedPlatform = new PlatformKey(JavaPlatformManager.getDefault().getDefaultPlatform());
521
                        }
522
                    } else {
523
                        PlatformKey pk = new PlatformKey(initialPlatform);
524
                        orderedNames.add(pk);
525
                        if (selectedPlatform == null) {
526
                            selectedPlatform = pk;
527
                        }
528
                    }
529
                }
530
                platformNamesCache = orderedNames.toArray(new PlatformKey[0]);
531
            }
532
            return platformNamesCache;
533
        }
534
535
    }
536
537
    private static final class PlatformListCellRenderer implements ListCellRenderer {
538
539
        private final ListCellRenderer delegate;
540
541
        public PlatformListCellRenderer() {
542
            delegate = HtmlRenderer.createRenderer();
543
        }
544
545
        public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected,
546
                boolean cellHasFocus) {
547
            String name;
548
            if (value == null) {
549
                name = ""; //NOI18N
550
            } else {
551
                assert value instanceof PlatformKey : "Wrong model";
552
                PlatformKey key = (PlatformKey) value;
553
                if (key.isBroken()) {
554
                    name = "<html><font color=\"#A40000\">" //NOI18N
555
                            + NbBundle.getMessage(
556
                                    PlatformUiSupport.class, "TXT_BrokenPlatformFmt", key.getDisplayName());
557
                } else {
558
                    name = key.getDisplayName();
559
                }
560
            }
561
            return delegate.getListCellRendererComponent(list, name, index, isSelected, cellHasFocus);
562
        }
563
    }
564
565
    private static final class SourceLevelComboBoxModel extends AbstractListModel
566
            implements ComboBoxModel, ListDataListener {
567
        private static final long serialVersionUID = 1L;
568
569
        private static final String VERSION_PREFIX = "1."; // the version prefix // NOI18N
570
        private static final int INITIAL_VERSION_MINOR = 2; // 1.2
571
        // if project is JAVA EE 5 show only 1.5 and higher
572
        private static final int INITIAL_VERSION_MINOR_JAVA_EE_5 = 5; // 1.5
573
574
        private final ComboBoxModel platformComboBoxModel;
575
        private final JDK minimalJDKVersion;
576
        private SpecificationVersion selectedSourceLevel;
577
        private SpecificationVersion originalSourceLevel;
578
        private SourceLevelKey[] sourceLevelCache;
579
        private PlatformKey activePlatform;
580
581
        public SourceLevelComboBoxModel(ComboBoxModel platformComboBoxModel, String initialSourceLevel,
582
                String initialTargetLevel, JDK minimalJDKVersion) {
583
            this.platformComboBoxModel = platformComboBoxModel;
584
            activePlatform = (PlatformKey) this.platformComboBoxModel.getSelectedItem();
585
            this.platformComboBoxModel.addListDataListener(this);
586
            if (initialSourceLevel != null && initialSourceLevel.length() > 0) {
587
                try {
588
                    originalSourceLevel = new SpecificationVersion(initialSourceLevel);
589
                } catch (NumberFormatException nfe) {
590
                    // if the javac.source has invalid value, do not preselect and log it.
591
                    LOGGER.warning("Invalid javac.source: " + initialSourceLevel);
592
                }
593
            }
594
            if (initialTargetLevel != null && initialTargetLevel.length() > 0) {
595
                try {
596
                    SpecificationVersion originalTargetLevel = new SpecificationVersion(initialTargetLevel);
597
                    if (originalSourceLevel == null || originalSourceLevel.compareTo(originalTargetLevel)<0) {
598
                        originalSourceLevel = originalTargetLevel;
599
                    }
600
                } catch (NumberFormatException nfe) {
601
                    // if the javac.target has invalid value, do not preselect and log it
602
                    LOGGER.warning("Invalid javac.target: "+initialTargetLevel);
603
                }
604
            }
605
            selectedSourceLevel = originalSourceLevel;
606
            this.minimalJDKVersion = minimalJDKVersion;
607
        }
608
609
        public int getSize() {
610
            SourceLevelKey[] sLevels = getSourceLevels();
611
            return sLevels.length;
612
        }
613
614
        public Object getElementAt(int index) {
615
            SourceLevelKey[] sLevels = getSourceLevels();
616
            assert index >= 0 && index < sLevels.length;
617
            return sLevels[index];
618
        }
619
620
        public Object getSelectedItem() {
621
            for (SourceLevelKey key : getSourceLevels()) {
622
                if (key.getSourceLevel().equals(selectedSourceLevel)) {
623
                    return key;
624
                }
625
            }
626
            return null;
627
        }
628
629
        public void setSelectedItem(Object obj) {
630
            selectedSourceLevel = (obj == null ? null : ((SourceLevelKey) obj).getSourceLevel());
631
            fireContentsChanged(this, -1, -1);
632
        }
633
634
        public void intervalAdded(ListDataEvent e) {
635
        }
636
637
        public void intervalRemoved(ListDataEvent e) {
638
        }
639
640
        public void contentsChanged(ListDataEvent e) {
641
            PlatformKey selectedPlatform = (PlatformKey) platformComboBoxModel.getSelectedItem();
642
            JavaPlatform platform = getPlatform(selectedPlatform);
643
            if (platform != null) {
644
                SpecificationVersion version = platform.getSpecification().getVersion();
645
                if (selectedSourceLevel != null
646
                        && selectedSourceLevel.compareTo(version) > 0
647
                        && !shouldChangePlatform(selectedSourceLevel, version)) {
648
                    // restore original
649
                    platformComboBoxModel.setSelectedItem(activePlatform);
650
                    return;
651
                } else {
652
                    originalSourceLevel = null;
653
                }
654
            }
655
            activePlatform = selectedPlatform;
656
            resetCache();
657
        }
658
659
        private void resetCache() {
660
            synchronized (this) {
661
                sourceLevelCache = null;
662
            }
663
            fireContentsChanged(this, -1, -1);
664
        }
665
666
        private SourceLevelKey[] getSourceLevels() {
667
            if (sourceLevelCache == null) {
668
                PlatformKey selectedPlatform = (PlatformKey) platformComboBoxModel.getSelectedItem();
669
                JavaPlatform platform = getPlatform(selectedPlatform);
670
                List<SourceLevelKey> sLevels = new ArrayList<SourceLevelKey>();
671
                // if platform == null => broken platform, the source level range is unknown
672
                // the source level combo box should be empty and disabled
673
                boolean selSourceLevelValid = false;
674
                if (platform != null) {
675
                    SpecificationVersion version = platform.getSpecification().getVersion();
676
                    int index = INITIAL_VERSION_MINOR;
677
                    // #71619 - source level lower than 1.5 won't be shown for Java EE 5 project
678
                    if (minimalJDKVersion != null) {
679
                        switch (minimalJDKVersion) {
680
                            case VERSION_5:
681
                                index = INITIAL_VERSION_MINOR_JAVA_EE_5;
682
                                break;
683
                            default:
684
                                break;
685
                        }
686
                    }
687
                    SpecificationVersion template =
688
                            new SpecificationVersion(VERSION_PREFIX + Integer.toString(index++));
689
                    boolean origSourceLevelValid = false;
690
691
                    while (template.compareTo(version) <= 0) {
692
                        if (template.equals(originalSourceLevel)) {
693
                            origSourceLevelValid = true;
694
                        }
695
                        if (template.equals(selectedSourceLevel)) {
696
                            selSourceLevelValid = true;
697
                        }
698
                        sLevels.add(new SourceLevelKey(template));
699
                        template = new SpecificationVersion(VERSION_PREFIX + Integer.toString(index++));
700
                    }
701
                    if (originalSourceLevel != null && !origSourceLevelValid) {
702
                        if (originalSourceLevel.equals(selectedSourceLevel)) {
703
                            selSourceLevelValid = true;
704
                        }
705
                        sLevels.add(new SourceLevelKey(originalSourceLevel, true));
706
                    }
707
                }
708
                sourceLevelCache = sLevels.toArray(new SourceLevelKey[sLevels.size()]);
709
                if (!selSourceLevelValid) {
710
                    selectedSourceLevel = sourceLevelCache.length == 0
711
                            ? null : sourceLevelCache[sourceLevelCache.length - 1].getSourceLevel();
712
                }
713
            }
714
            return sourceLevelCache;
715
        }
716
717
        private boolean shouldChangePlatform(SpecificationVersion selectedSourceLevel,
718
                SpecificationVersion platformSourceLevel) {
719
            JButton changeOption = new JButton(NbBundle.getMessage(PlatformUiSupport.class, "CTL_ChangePlatform"));
720
            changeOption.getAccessibleContext().setAccessibleDescription(
721
                    NbBundle.getMessage(PlatformUiSupport.class, "AD_ChangePlatform"));
722
            String message = MessageFormat.format(
723
                    NbBundle.getMessage(PlatformUiSupport.class, "TXT_ChangePlatform"),
724
                    new Object[] {selectedSourceLevel.toString(), platformSourceLevel.toString()});
725
            return DialogDisplayer.getDefault().notify(new NotifyDescriptor(
726
                    message,
727
                    NbBundle.getMessage(PlatformUiSupport.class, "TXT_ChangePlatformTitle"),
728
                    NotifyDescriptor.DEFAULT_OPTION,
729
                    NotifyDescriptor.WARNING_MESSAGE,
730
                    new Object[] {
731
                        changeOption,
732
                        NotifyDescriptor.CANCEL_OPTION
733
                    },
734
                    changeOption)) == changeOption;
735
        }
736
    }
737
738
    private static final class SourceLevelListCellRenderer implements ListCellRenderer {
739
740
        private ListCellRenderer delegate;
741
742
        public SourceLevelListCellRenderer() {
743
            delegate = HtmlRenderer.createRenderer();
744
        }
745
746
        public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected,
747
                boolean cellHasFocus) {
748
            String message;
749
            if (value == null) {
750
                message = "";   //NOI18N
751
            } else {
752
                assert value instanceof SourceLevelKey;
753
                SourceLevelKey key = (SourceLevelKey) value;
754
                if (key.isBroken()) {
755
                    message = "<html><font color=\"#A40000\">" //NOI18N
756
                            + NbBundle.getMessage(
757
                                    PlatformUiSupport.class, "TXT_InvalidSourceLevel", key.getDisplayName());
758
                } else {
759
                    message = key.getDisplayName();
760
                }
761
            }
762
            return delegate.getListCellRendererComponent(list, message, index, isSelected, cellHasFocus);
763
        }
764
    }
765
766
    private static JavaPlatform getPlatform(PlatformKey platformKey) {
767
        return platformKey.platform;
768
    }
769
770
    private static JavaPlatform findPlatform(String displayName) {
771
        JavaPlatform[] platforms = JavaPlatformManager.getDefault().getPlatforms(
772
                displayName, new Specification("j2se", null)); //NOI18N
773
        if (platforms.length == 0) {
774
            return null;
775
        }
776
        return platforms[0];
777
    }
778
}
(-)a/java.commonapi/src/org/netbeans/modules/java/api/common/util/CommonProjectUtils.java (+93 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 1997-2007 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 2008 Sun Microsystems, Inc.
38
 */
39
40
package org.netbeans.modules.java.api.common.util;
41
42
import org.netbeans.api.java.platform.JavaPlatform;
43
import org.netbeans.api.java.platform.JavaPlatformManager;
44
import org.netbeans.api.java.platform.Specification;
45
46
/**
47
 * Common project utilities. This is a helper class; all methods are static.
48
 * @author Tomas Mysik
49
 */
50
public final class CommonProjectUtils {
51
52
    private CommonProjectUtils() {
53
    }
54
55
    // XXX copied from J2SEProjectUtilities, should be part of some API probably (JavaPlatformManager?)
56
    /**
57
     * Returns the active platform used by the project or null if the active
58
     * project platform is broken.
59
     * @param activePlatformId the name of platform used by Ant script or null
60
     * for default platform.
61
     * @return active {@link JavaPlatform} or null if the project's platform
62
     * is broken
63
     */
64
    public static JavaPlatform getActivePlatform(final String activePlatformId) {
65
        final JavaPlatformManager pm = JavaPlatformManager.getDefault();
66
        if (activePlatformId == null) {
67
            return pm.getDefaultPlatform();
68
        }
69
70
        JavaPlatform[] installedPlatforms = pm.getPlatforms(null, new Specification("j2se", null)); //NOI18N
71
        for (JavaPlatform javaPlatform : installedPlatforms) {
72
            String antName = javaPlatform.getProperties().get("platform.ant.name"); //NOI18N
73
            if (antName != null && antName.equals(activePlatformId)) {
74
                return javaPlatform;
75
            }
76
        }
77
        return null;
78
    }
79
80
    /**
81
     * Converts the ant reference to the name of the referenced property.
82
     * @param property the name of the referenced property.
83
     * @return the referenced property.
84
     */
85
    public static String getAntPropertyName(String property) {
86
        if (property != null
87
                && property.startsWith("${") // NOI18N
88
                && property.endsWith("}")) { // NOI18N
89
            return property.substring(2, property.length() - 1);
90
        }
91
        return property;
92
    }
93
}
(-)a/java.commonapi/test/build-unit.xml (+44 lines)
Line 0 Link Here
1
<?xml version="1.0" encoding="UTF-8"?>
2
<!--
3
4
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
5
6
Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
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.  Sun designates this
19
particular file as subject to the "Classpath" exception as provided
20
by Sun 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 2007 Sun Microsystems, Inc.
40
-->
41
42
<project name="java/commonapi/test-unit" basedir="." default="all">
43
    <import file="../../../nbbuild/templates/xtest-unit.xml"/>
44
</project>
(-)a/java.commonapi/test/build.xml (+53 lines)
Line 0 Link Here
1
<?xml version="1.0" encoding="UTF-8"?>
2
<!--
3
4
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
5
6
Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
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.  Sun designates this
19
particular file as subject to the "Classpath" exception as provided
20
by Sun 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 2007 Sun Microsystems, Inc.
40
-->
41
42
<project name="java/commonapi/test" basedir="." default="all" >
43
44
    <!-- Name of tested module -->
45
    <property name="xtest.module" value="java/commonapi"/>
46
47
    <import file="../../../nbbuild/templates/xtest.xml"/>
48
49
    <!-- default testtypes, attributes used when no value is supplied from command line -->
50
    <property name="xtest.testtype" value="unit"/>
51
    <property name="xtest.attribs" value="stable"/>
52
53
</project>
(-)a/java.commonapi/test/cfg-unit.xml (+55 lines)
Line 0 Link Here
1
<?xml version="1.0" encoding="UTF-8"?>
2
<!--
3
4
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
5
6
Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
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.  Sun designates this
19
particular file as subject to the "Classpath" exception as provided
20
by Sun 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 2007 Sun Microsystems, Inc.
40
-->
41
42
<mconfig name="java/commonapi">
43
44
    <testbag testattribs="unstable" executor="unit-executor" name="java/commonapi">
45
        <testset dir="unit/src">
46
            <patternset>
47
                <include name="**/*Test.class"/>
48
            </patternset>
49
        </testset>
50
    </testbag>
51
52
    <compiler name="default-compiler" antfile="build-unit.xml" target="default-compiler" default="true"/>
53
    <executor name="unit-executor" antfile="build-unit.xml" target="run-unit-test"/>
54
55
</mconfig>
(-)a/java.commonapi/test/unit/src/org/netbeans/modules/java/api/common/queries/FileEncodingQueryImplTest.java (+120 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 1997-2007 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 2007 Sun Microsystems, Inc.
38
 */
39
40
package org.netbeans.modules.java.api.common.queries;
41
42
import java.io.File;
43
import java.nio.charset.Charset;
44
import org.netbeans.api.project.Project;
45
import org.netbeans.api.project.ProjectManager;
46
import org.netbeans.junit.NbTestCase;
47
import org.netbeans.spi.project.support.ant.AntBasedTestUtil;
48
import org.netbeans.spi.project.support.ant.PropertyEvaluator;
49
import org.openide.filesystems.FileObject;
50
import org.netbeans.spi.queries.FileEncodingQueryImplementation;
51
import org.netbeans.spi.project.support.ant.AntProjectHelper;
52
import org.netbeans.spi.project.support.ant.EditableProperties;
53
import org.netbeans.spi.project.support.ant.ProjectGenerator;
54
import org.openide.filesystems.FileUtil;
55
import org.openide.util.Mutex;
56
import org.openide.util.test.MockLookup;
57
58
/**
59
 * Tests for {@link FileEncodingQueryImpl}.
60
 *
61
 * @author Tomas Mysik
62
 */
63
public class FileEncodingQueryImplTest extends NbTestCase {
64
65
    private FileObject projdir;
66
    private AntProjectHelper helper;
67
    private PropertyEvaluator eval;
68
    private Project prj;
69
    private static final String SOURCE_ENCODING = "source.encoding";
70
71
    public FileEncodingQueryImplTest(String testName) {
72
        super(testName);
73
    }
74
75
    @Override
76
    protected void setUp() throws Exception {
77
        MockLookup.setInstances(AntBasedTestUtil.testAntBasedProjectType());
78
        super.setUp();
79
        this.clearWorkDir();
80
        File wd = getWorkDir();
81
        FileObject scratch = FileUtil.toFileObject(wd);
82
        assertNotNull(wd);
83
        projdir = scratch.createFolder("proj");
84
        helper = ProjectGenerator.createProject(projdir, "test");
85
        assertNotNull(helper);
86
        eval = helper.getStandardPropertyEvaluator();
87
        assertNotNull(eval);
88
        prj = ProjectManager.getDefault().findProject(projdir);
89
        assertNotNull(prj);
90
    }
91
92
    public void testFileEncodingQuery() throws Exception {
93
        final Charset UTF_8 = Charset.forName("UTF-8");
94
        final Charset ISO_8859_2 = Charset.forName("ISO-8859-2");
95
96
        FileObject dummy = projdir.createData("Dummy.java");
97
98
        setProjectCharset(UTF_8);
99
        FileEncodingQueryImplementation fileEncodingQuery = QuerySupport.createFileEncodingQuery(eval, SOURCE_ENCODING);
100
101
        Charset enc = fileEncodingQuery.getEncoding(dummy);
102
        assertEquals(UTF_8, enc);
103
104
        setProjectCharset(ISO_8859_2);
105
        enc = fileEncodingQuery.getEncoding(dummy);
106
        assertEquals(ISO_8859_2, enc);
107
    }
108
109
    private void setProjectCharset(final Charset charset) throws Exception {
110
        ProjectManager.mutex().writeAccess(new Mutex.ExceptionAction<Void>() {
111
            public Void run() throws Exception {
112
                EditableProperties ep = helper.getProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH);
113
                ep.setProperty(SOURCE_ENCODING, charset.name());
114
                helper.putProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH, ep);
115
                ProjectManager.getDefault().saveProject(prj);
116
                return null;
117
            }
118
        });
119
    }
120
}
(-)a/java.commonapi/test/unit/src/org/netbeans/modules/java/api/common/queries/JavadocForBinaryQueryImplTest.java (+137 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 1997-2007 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 2007 Sun Microsystems, Inc.
38
 */
39
40
package org.netbeans.modules.java.api.common.queries;
41
42
import java.io.File;
43
import java.net.URL;
44
import org.netbeans.api.java.queries.JavadocForBinaryQuery.Result;
45
import org.netbeans.api.project.Project;
46
import org.netbeans.api.project.ProjectManager;
47
import org.netbeans.junit.NbTestCase;
48
import org.netbeans.spi.java.queries.JavadocForBinaryQueryImplementation;
49
import org.netbeans.spi.project.support.ant.AntBasedTestUtil;
50
import org.netbeans.spi.project.support.ant.PropertyEvaluator;
51
import org.openide.filesystems.FileObject;
52
import org.netbeans.spi.project.support.ant.AntProjectHelper;
53
import org.netbeans.spi.project.support.ant.EditableProperties;
54
import org.netbeans.spi.project.support.ant.ProjectGenerator;
55
import org.openide.filesystems.FileStateInvalidException;
56
import org.openide.filesystems.FileUtil;
57
import org.openide.util.Mutex;
58
import org.openide.util.test.MockLookup;
59
60
/**
61
 * Tests for {@link JavadocForBinaryQueryImpl}.
62
 *
63
 * @author Tomas Mysik
64
 */
65
public class JavadocForBinaryQueryImplTest extends NbTestCase {
66
67
    private FileObject projdir;
68
    private AntProjectHelper helper;
69
    private PropertyEvaluator eval;
70
    private Project prj;
71
    private FileObject builddir;
72
    private static final String BUILD_CLASSES_DIR  = "build.classes.dir";
73
    private static final String JAVADOC_DIR = "dist.javadoc.dir";
74
75
    private static final String JAVADOC_1 = "javadoc1";
76
    private static final String JAVADOC_2 = "javadoc2";
77
78
    public JavadocForBinaryQueryImplTest(String testName) {
79
        super(testName);
80
    }
81
82
    @Override
83
    protected void setUp() throws Exception {
84
        MockLookup.setInstances(AntBasedTestUtil.testAntBasedProjectType());
85
        super.setUp();
86
        this.clearWorkDir();
87
        File wd = getWorkDir();
88
        FileObject scratch = FileUtil.toFileObject(wd);
89
        assertNotNull(wd);
90
        projdir = scratch.createFolder("proj");
91
        helper = ProjectGenerator.createProject(projdir, "test");
92
        assertNotNull(helper);
93
        eval = helper.getStandardPropertyEvaluator();
94
        assertNotNull(eval);
95
        prj = ProjectManager.getDefault().findProject(projdir);
96
        assertNotNull(prj);
97
        builddir = projdir.createFolder("build");
98
        assertNotNull(builddir);
99
    }
100
101
    public void testJavadocForBinaryQuery() throws Exception {
102
        setProjectDirectory(BUILD_CLASSES_DIR, builddir);
103
        JavadocForBinaryQueryImplementation javadocForBinaryQuery =
104
                QuerySupport.createJavadocForBinaryQuery(helper, eval);
105
106
        setProjectDirectory(JAVADOC_DIR, projdir.createFolder(JAVADOC_1));
107
        Result javadoc = javadocForBinaryQuery.findJavadoc(builddir.getURL());
108
        assertNotNull(javadoc);
109
110
        URL[] roots = javadoc.getRoots();
111
        assertEquals(1, roots.length);
112
        assertEquals(getJavadocUrl(JAVADOC_1), roots[0]);
113
114
        // change javadoc directory
115
        setProjectDirectory(JAVADOC_DIR, projdir.createFolder(JAVADOC_2));
116
        roots = javadoc.getRoots();
117
        assertEquals(1, roots.length);
118
        assertEquals(getJavadocUrl(JAVADOC_2), roots[0]);
119
    }
120
121
    private URL getJavadocUrl(String javadoc) throws FileStateInvalidException {
122
        return projdir.getFileObject(javadoc).getURL();
123
    }
124
125
    private void setProjectDirectory(final String property, final FileObject directory) throws Exception {
126
        assertTrue(directory.isFolder());
127
        ProjectManager.mutex().writeAccess(new Mutex.ExceptionAction<Void>() {
128
            public Void run() throws Exception {
129
                EditableProperties ep = helper.getProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH);
130
                ep.setProperty(property, directory.getName());
131
                helper.putProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH, ep);
132
                ProjectManager.getDefault().saveProject(prj);
133
                return null;
134
            }
135
        });
136
    }
137
}
(-)a/java.commonapi/test/unit/src/org/netbeans/modules/java/api/common/queries/SourceLevelQueryImplTest.java (+220 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 1997-2007 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 2007 Sun Microsystems, Inc.
38
 */
39
40
package org.netbeans.modules.java.api.common.queries;
41
42
import java.beans.PropertyChangeListener;
43
import java.io.IOException;
44
import java.net.URL;
45
import java.util.Collection;
46
import java.util.Collections;
47
import java.util.List;
48
import java.util.Map;
49
import java.util.Properties;
50
import org.netbeans.api.java.classpath.ClassPath;
51
import org.netbeans.api.java.platform.JavaPlatform;
52
import org.netbeans.api.java.platform.Specification;
53
import org.netbeans.api.project.Project;
54
import org.netbeans.api.project.ProjectManager;
55
import org.netbeans.junit.NbTestCase;
56
import org.netbeans.modules.java.platform.JavaPlatformProvider;
57
import org.netbeans.spi.project.support.ant.PropertyUtils;
58
import org.openide.filesystems.FileObject;
59
import org.netbeans.api.project.TestUtil;
60
import org.netbeans.spi.java.classpath.support.ClassPathSupport;
61
import org.netbeans.spi.java.queries.SourceLevelQueryImplementation;
62
import org.netbeans.spi.project.support.ant.AntBasedTestUtil;
63
import org.netbeans.spi.project.support.ant.AntProjectHelper;
64
import org.netbeans.spi.project.support.ant.EditableProperties;
65
import org.netbeans.spi.project.support.ant.ProjectGenerator;
66
import org.netbeans.spi.project.support.ant.PropertyEvaluator;
67
import org.openide.filesystems.FileUtil;
68
import org.openide.modules.SpecificationVersion;
69
import org.openide.util.test.MockLookup;
70
71
/**
72
 * Tests for {@link SourceLevelQueryImpl}.
73
 *
74
 * @author Tomas Mysik
75
 */
76
public class SourceLevelQueryImplTest extends NbTestCase {
77
78
    private static final String JAVAC_SOURCE = "1.2";
79
    private static final String DEFAULT_JAVAC_SOURCE = "17.2";
80
81
    private static final String TEST_PLATFORM = "TestPlatform";
82
    private static final String BROKEN_PLATFORM = "BrokenPlatform";
83
84
    private FileObject scratch;
85
    private FileObject projdir;
86
    private AntProjectHelper helper;
87
    private PropertyEvaluator eval;
88
    private Project prj;
89
90
    public SourceLevelQueryImplTest(String testName) {
91
        super(testName);
92
    }
93
94
    @Override
95
    protected void setUp() throws Exception {
96
        MockLookup.setInstances(
97
                AntBasedTestUtil.testAntBasedProjectType(),
98
                new TestPlatformProvider());
99
        super.setUp();
100
        this.clearWorkDir();
101
        Properties p = System.getProperties();
102
        if (p.getProperty("netbeans.user") == null) {
103
            p.put("netbeans.user", FileUtil.toFile(TestUtil.makeScratchDir(this)).getAbsolutePath());
104
        }
105
    }
106
107
    @Override
108
    protected void tearDown() throws Exception {
109
        scratch = null;
110
        projdir = null;
111
        super.tearDown();
112
    }
113
114
115
    private void prepareProject(String platformName) throws IOException {
116
        scratch = TestUtil.makeScratchDir(this);
117
        projdir = scratch.createFolder("proj");
118
        helper = ProjectGenerator.createProject(projdir, "test");
119
        assertNotNull(helper);
120
        prj = ProjectManager.getDefault().findProject(projdir);
121
        assertNotNull(prj);
122
        EditableProperties props = helper.getProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH);
123
        props.setProperty("javac.source", "${def}");
124
        props.setProperty("platform.active", platformName);
125
        props.setProperty("def", JAVAC_SOURCE);
126
        helper.putProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH, props);
127
        props = PropertyUtils.getGlobalProperties();
128
        props.put("default.javac.source", DEFAULT_JAVAC_SOURCE);
129
        PropertyUtils.putGlobalProperties(props);
130
        eval = helper.getStandardPropertyEvaluator();
131
        assertNotNull(eval);
132
    }
133
134
    public void testGetSourceLevelWithValidPlatform() throws Exception {
135
        this.prepareProject(TEST_PLATFORM);
136
137
        FileObject dummy = projdir.createData("Dummy.java");
138
        SourceLevelQueryImplementation sourceLevelQuery = QuerySupport.createSourceLevelQuery(eval);
139
140
        String sl = sourceLevelQuery.getSourceLevel(dummy);
141
        assertEquals(JAVAC_SOURCE, sl);
142
    }
143
144
    public void testGetSourceLevelWithBrokenPlatform() throws Exception {
145
        this.prepareProject(BROKEN_PLATFORM);
146
147
        FileObject dummy = projdir.createData("Dummy.java");
148
        SourceLevelQueryImplementation sourceLevelQuery = QuerySupport.createSourceLevelQuery(eval);
149
150
        String sl = sourceLevelQuery.getSourceLevel(dummy);
151
        assertEquals(DEFAULT_JAVAC_SOURCE, sl);
152
    }
153
154
    private static class TestPlatformProvider implements JavaPlatformProvider {
155
156
        private JavaPlatform platform;
157
158
        public void removePropertyChangeListener(PropertyChangeListener listener) {
159
        }
160
161
        public void addPropertyChangeListener(PropertyChangeListener listener) {
162
        }
163
164
        public JavaPlatform[] getInstalledPlatforms()  {
165
            return new JavaPlatform[] {
166
                getDefaultPlatform()
167
            };
168
        }
169
170
        public JavaPlatform getDefaultPlatform()  {
171
            if (this.platform == null) {
172
                this.platform = new TestPlatform();
173
            }
174
            return this.platform;
175
        }
176
    }
177
178
    private static class TestPlatform extends JavaPlatform {
179
180
        public FileObject findTool(String toolName) {
181
            return null;
182
        }
183
184
        public String getVendor() {
185
            return "me";
186
        }
187
188
        public ClassPath getStandardLibraries() {
189
            return ClassPathSupport.createClassPath(new URL[0]);
190
        }
191
192
        public Specification getSpecification() {
193
            return new Specification("j2se", new SpecificationVersion("1.5"));
194
        }
195
196
        public ClassPath getSourceFolders() {
197
            return null;
198
        }
199
200
        public Map<String, String> getProperties() {
201
            return Collections.singletonMap("platform.ant.name", TEST_PLATFORM);
202
        }
203
204
        public List<URL> getJavadocFolders() {
205
            return null;
206
        }
207
208
        public Collection<FileObject> getInstallFolders() {
209
            return null;
210
        }
211
212
        public String getDisplayName() {
213
            return "TestPlatform";
214
        }
215
216
        public ClassPath getBootstrapLibraries() {
217
            return ClassPathSupport.createClassPath(new URL[0]);
218
        }
219
    }
220
}
(-)a/java.j2seproject/nbproject/project.xml (-56 / +69 lines)
Lines 114-119 made subject to such option by the copyr Link Here
114
                    <run-dependency>
114
                    <run-dependency>
115
                        <release-version>1</release-version>
115
                        <release-version>1</release-version>
116
                        <specification-version>1.3</specification-version>
116
                        <specification-version>1.3</specification-version>
117
                    </run-dependency>
118
                </dependency>
119
                <dependency>
120
                    <code-name-base>org.netbeans.modules.java.api.common</code-name-base>
121
                    <build-prerequisite/>
122
                    <compile-dependency/>
123
                    <run-dependency>
124
                        <release-version>0-1</release-version>
125
                        <specification-version>1.0</specification-version>
117
                    </run-dependency>
126
                    </run-dependency>
118
                </dependency>
127
                </dependency>
119
                <dependency>
128
                <dependency>
Lines 284-296 made subject to such option by the copyr Link Here
284
                <test-type>
293
                <test-type>
285
                    <name>unit</name>
294
                    <name>unit</name>
286
                    <test-dependency>
295
                    <test-dependency>
296
                        <code-name-base>org.netbeans.api.progress</code-name-base>
297
                    </test-dependency>
298
                    <test-dependency>
299
                        <code-name-base>org.netbeans.bootstrap</code-name-base>
300
                    </test-dependency>
301
                    <test-dependency>
302
                        <code-name-base>org.netbeans.core</code-name-base>
303
                    </test-dependency>
304
                    <test-dependency>
305
                        <code-name-base>org.netbeans.core.startup</code-name-base>
306
                    </test-dependency>
307
                    <test-dependency>
308
                        <code-name-base>org.netbeans.libs.xerces</code-name-base>
309
                    </test-dependency>
310
                    <test-dependency>
311
                        <code-name-base>org.netbeans.modules.java.api.common</code-name-base>
312
                        <compile-dependency/>
313
                    </test-dependency>
314
                    <test-dependency>
287
                        <code-name-base>org.netbeans.modules.java.j2seproject</code-name-base>
315
                        <code-name-base>org.netbeans.modules.java.j2seproject</code-name-base>
288
                        <recursive/>
316
                        <recursive/>
289
                        <compile-dependency/>
317
                        <compile-dependency/>
290
                    </test-dependency>
318
                    </test-dependency>
291
                    <test-dependency>
319
                    <test-dependency>
292
                        <code-name-base>org.openide.io</code-name-base>
320
                        <code-name-base>org.netbeans.modules.masterfs</code-name-base>
293
                        <compile-dependency/>
294
                    </test-dependency>
321
                    </test-dependency>
295
                    <test-dependency>
322
                    <test-dependency>
296
                        <code-name-base>org.netbeans.modules.projectapi</code-name-base>
323
                        <code-name-base>org.netbeans.modules.projectapi</code-name-base>
Lines 298-356 made subject to such option by the copyr Link Here
298
                        <test/>
325
                        <test/>
299
                    </test-dependency>
326
                    </test-dependency>
300
                    <test-dependency>
327
                    <test-dependency>
301
                        <code-name-base>org.netbeans.core</code-name-base>
328
                        <code-name-base>org.netbeans.modules.projectui</code-name-base>
302
                    </test-dependency>
303
                    <test-dependency>
304
                        <code-name-base>org.openide.loaders</code-name-base>
305
                    </test-dependency>
306
                    <test-dependency>
307
                        <code-name-base>org.netbeans.modules.masterfs</code-name-base>
308
                    </test-dependency>
309
                    <test-dependency>
310
                        <code-name-base>org.netbeans.api.progress</code-name-base>
311
                    </test-dependency>
312
                    <test-dependency>
313
                        <code-name-base>org.openide.options</code-name-base>
314
                    </test-dependency>
315
                    <test-dependency>
316
                        <code-name-base>org.openide.explorer</code-name-base>
317
                    </test-dependency>
318
                    <test-dependency>
319
                        <code-name-base>org.openide.dialogs</code-name-base>
320
                    </test-dependency>
321
                    <test-dependency>
322
                        <code-name-base>org.openide.nodes</code-name-base>
323
                    </test-dependency>
324
                    <test-dependency>
325
                        <code-name-base>org.openide.text</code-name-base>
326
                    </test-dependency>
327
                    <test-dependency>
328
                        <code-name-base>org.openide.awt</code-name-base>
329
                    </test-dependency>
330
                    <test-dependency>
331
                        <code-name-base>org.openide.util</code-name-base>
332
                        <compile-dependency/>
333
                        <test/>
334
                    </test-dependency>
335
                    <test-dependency>
336
                        <code-name-base>org.openide.actions</code-name-base>
337
                    </test-dependency>
338
                    <test-dependency>
339
                        <code-name-base>org.openide.modules</code-name-base>
340
                    </test-dependency>
341
                    <test-dependency>
342
                        <code-name-base>org.openide.filesystems</code-name-base>
343
                        <compile-dependency/>
344
                        <test/>
345
                    </test-dependency>
346
                    <test-dependency>
347
                        <code-name-base>org.netbeans.core.startup</code-name-base>
348
                    </test-dependency>
349
                    <test-dependency>
350
                        <code-name-base>org.netbeans.bootstrap</code-name-base>
351
                    </test-dependency>
352
                    <test-dependency>
353
                        <code-name-base>org.netbeans.libs.xerces</code-name-base>
354
                    </test-dependency>
329
                    </test-dependency>
355
                    <test-dependency>
330
                    <test-dependency>
356
                        <code-name-base>org.netbeans.modules.schema2beans</code-name-base>
331
                        <code-name-base>org.netbeans.modules.schema2beans</code-name-base>
Lines 359-365 made subject to such option by the copyr Link Here
359
                        <code-name-base>org.netbeans.modules.xml.retriever</code-name-base>
334
                        <code-name-base>org.netbeans.modules.xml.retriever</code-name-base>
360
                    </test-dependency>
335
                    </test-dependency>
361
                    <test-dependency>
336
                    <test-dependency>
362
                        <code-name-base>org.netbeans.modules.projectui</code-name-base>
337
                        <code-name-base>org.openide.actions</code-name-base>
338
                    </test-dependency>
339
                    <test-dependency>
340
                        <code-name-base>org.openide.awt</code-name-base>
341
                    </test-dependency>
342
                    <test-dependency>
343
                        <code-name-base>org.openide.dialogs</code-name-base>
344
                    </test-dependency>
345
                    <test-dependency>
346
                        <code-name-base>org.openide.explorer</code-name-base>
347
                    </test-dependency>
348
                    <test-dependency>
349
                        <code-name-base>org.openide.filesystems</code-name-base>
350
                        <compile-dependency/>
351
                        <test/>
352
                    </test-dependency>
353
                    <test-dependency>
354
                        <code-name-base>org.openide.io</code-name-base>
355
                        <compile-dependency/>
356
                    </test-dependency>
357
                    <test-dependency>
358
                        <code-name-base>org.openide.loaders</code-name-base>
359
                    </test-dependency>
360
                    <test-dependency>
361
                        <code-name-base>org.openide.modules</code-name-base>
362
                    </test-dependency>
363
                    <test-dependency>
364
                        <code-name-base>org.openide.nodes</code-name-base>
365
                    </test-dependency>
366
                    <test-dependency>
367
                        <code-name-base>org.openide.options</code-name-base>
368
                    </test-dependency>
369
                    <test-dependency>
370
                        <code-name-base>org.openide.text</code-name-base>
371
                    </test-dependency>
372
                    <test-dependency>
373
                        <code-name-base>org.openide.util</code-name-base>
374
                        <compile-dependency/>
375
                        <test/>
363
                    </test-dependency>
376
                    </test-dependency>
364
                </test-type>
377
                </test-type>
365
                <test-type>
378
                <test-type>
(-)a/java.j2seproject/src/org/netbeans/modules/java/j2seproject/J2SEActionProvider.java (-1 / +2 lines)
Lines 73-78 import org.netbeans.api.project.ProjectU Link Here
73
import org.netbeans.api.project.ProjectUtils;
73
import org.netbeans.api.project.ProjectUtils;
74
import org.netbeans.api.project.SourceGroup;
74
import org.netbeans.api.project.SourceGroup;
75
import org.netbeans.api.project.Sources;
75
import org.netbeans.api.project.Sources;
76
import org.netbeans.modules.java.api.common.ant.UpdateHelper;
76
import org.netbeans.modules.java.j2seproject.applet.AppletSupport;
77
import org.netbeans.modules.java.j2seproject.applet.AppletSupport;
77
import org.netbeans.modules.java.j2seproject.classpath.ClassPathProviderImpl;
78
import org.netbeans.modules.java.j2seproject.classpath.ClassPathProviderImpl;
78
import org.netbeans.modules.java.j2seproject.ui.customizer.J2SEProjectProperties;
79
import org.netbeans.modules.java.j2seproject.ui.customizer.J2SEProjectProperties;
Lines 433-439 class J2SEActionProvider implements Acti Link Here
433
                    result=isSetMainClass (project.getSourceRoots().getRoots(), mainClass);
434
                    result=isSetMainClass (project.getSourceRoots().getRoots(), mainClass);
434
                } while (result != MainClassStatus.SET_AND_VALID);
435
                } while (result != MainClassStatus.SET_AND_VALID);
435
                try {
436
                try {
436
                    if (updateHelper.requestSave()) {
437
                    if (updateHelper.requestUpdate()) {
437
                        updateHelper.putProperties(path, ep);
438
                        updateHelper.putProperties(path, ep);
438
                        ProjectManager.getDefault().saveProject(project);
439
                        ProjectManager.getDefault().saveProject(project);
439
                    }
440
                    }
(-)a/java.j2seproject/src/org/netbeans/modules/java/j2seproject/J2SEFileBuiltQuery.java (-117 lines)
Lines 1-117 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 1997-2007 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
 * Contributor(s):
25
 *
26
 * The Original Software is NetBeans. The Initial Developer of the Original
27
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
28
 * Microsystems, Inc. All Rights Reserved.
29
 *
30
 * If you wish your version of this file to be governed by only the CDDL
31
 * or only the GPL Version 2, indicate your decision by adding
32
 * "[Contributor] elects to include this software in this distribution
33
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
34
 * single choice of license, a recipient has the option to distribute
35
 * your version of this file under either the CDDL, the GPL Version 2 or
36
 * to extend the choice of license to its licensees as provided above.
37
 * However, if you add GPL Version 2 code and therefore, elected the GPL
38
 * Version 2 license, then the option applies only if the new code is
39
 * made subject to such option by the copyright holder.
40
 */
41
package org.netbeans.modules.java.j2seproject;
42
43
import java.beans.PropertyChangeEvent;
44
import java.beans.PropertyChangeListener;
45
import org.netbeans.api.project.ProjectManager;
46
import org.openide.filesystems.FileObject;
47
import org.netbeans.api.queries.FileBuiltQuery;
48
import org.netbeans.spi.queries.FileBuiltQueryImplementation;
49
import org.netbeans.spi.project.support.ant.AntProjectHelper;
50
import org.netbeans.spi.project.support.ant.PropertyEvaluator;
51
import org.netbeans.modules.java.j2seproject.ui.customizer.J2SEProjectProperties;
52
import org.openide.util.Mutex.Action;
53
54
55
56
57
58
public class J2SEFileBuiltQuery implements FileBuiltQueryImplementation, PropertyChangeListener {
59
60
    private FileBuiltQueryImplementation delegate;
61
    private final AntProjectHelper helper;
62
    private final PropertyEvaluator evaluator;
63
    private final SourceRoots sourceRoots;
64
    private final SourceRoots testRoots;
65
66
    J2SEFileBuiltQuery (AntProjectHelper helper, PropertyEvaluator evaluator,
67
                        SourceRoots sourceRoots, SourceRoots testRoots) {
68
        assert helper != null && evaluator != null && sourceRoots != null && testRoots != null;
69
        this.helper = helper;
70
        this.evaluator = evaluator;
71
        this.sourceRoots = sourceRoots;
72
        this.testRoots = testRoots;
73
        this.sourceRoots.addPropertyChangeListener (this);
74
        this.testRoots.addPropertyChangeListener (this);
75
    }
76
77
    public FileBuiltQuery.Status getStatus(final FileObject file) {
78
        return ProjectManager.mutex().readAccess(new Action<FileBuiltQuery.Status>() {
79
            public FileBuiltQuery.Status run() {
80
                return getStatusImpl(file);
81
            }
82
        });
83
    }
84
85
    private synchronized FileBuiltQuery.Status getStatusImpl(FileObject file) {
86
        if (this.delegate == null) {
87
            this.delegate = createDelegate ();
88
        }
89
        return this.delegate.getStatus (file);
90
    }
91
92
93
    private FileBuiltQueryImplementation createDelegate () {
94
        String[] srcRoots = this.sourceRoots.getRootProperties();
95
        String[] tstRoots = this.testRoots.getRootProperties();
96
        String[] from = new String [srcRoots.length + tstRoots.length];
97
        String[] to = new String [srcRoots.length + tstRoots.length];
98
        for (int i=0; i< srcRoots.length; i++) {
99
            from[i] = "${" + srcRoots[i] + "}/*.java"; // NOI18N
100
            to[i] = "${" + J2SEProjectProperties.BUILD_CLASSES_DIR + "}/*.class"; // NOI18N
101
        }
102
        for (int i=0; i<tstRoots.length; i++) {
103
            from[srcRoots.length+i] = "${" + tstRoots[i] + "}/*.java"; // NOI18N
104
            to[srcRoots.length+i] = "${" + J2SEProjectProperties.BUILD_TEST_CLASSES_DIR + "}/*.class"; // NOI18N
105
        }
106
        return helper.createGlobFileBuiltQuery(evaluator, from, to);    //Safe to pass APH
107
    }
108
109
    public void propertyChange(PropertyChangeEvent evt) {
110
        if (SourceRoots.PROP_ROOT_PROPERTIES.equals (evt.getPropertyName())) {
111
            synchronized(this) {
112
                this.delegate = null;
113
                ///XXX: What to do with already returned Statuses
114
            }
115
        }
116
    }
117
}
(-)a/java.j2seproject/src/org/netbeans/modules/java/j2seproject/J2SEPersistenceProvider.java (-1 lines)
Lines 45-51 import java.beans.PropertyChangeListener Link Here
45
import java.beans.PropertyChangeListener;
45
import java.beans.PropertyChangeListener;
46
import java.io.File;
46
import java.io.File;
47
import java.io.IOException;
47
import java.io.IOException;
48
import java.net.URI;
49
import java.net.URL;
48
import java.net.URL;
50
import org.netbeans.api.java.classpath.ClassPath;
49
import org.netbeans.api.java.classpath.ClassPath;
51
import org.netbeans.api.project.FileOwnerQuery;
50
import org.netbeans.api.project.FileOwnerQuery;
(-)a/java.j2seproject/src/org/netbeans/modules/java/j2seproject/J2SEProject.java (-17 / +19 lines)
Lines 67-84 import org.netbeans.api.project.ProjectM Link Here
67
import org.netbeans.api.project.ProjectManager;
67
import org.netbeans.api.project.ProjectManager;
68
import org.netbeans.api.project.ant.AntArtifact;
68
import org.netbeans.api.project.ant.AntArtifact;
69
import org.netbeans.api.project.ant.AntBuildExtender;
69
import org.netbeans.api.project.ant.AntBuildExtender;
70
import org.netbeans.modules.java.api.common.SourceRoots;
71
import org.netbeans.modules.java.api.common.SourceRootsSupport;
72
import org.netbeans.modules.java.api.common.ant.UpdateHelper;
73
import org.netbeans.modules.java.api.common.ant.UpdateImplementation;
74
import org.netbeans.modules.java.api.common.queries.QuerySupport;
70
import org.netbeans.modules.java.j2seproject.api.J2SEPropertyEvaluator;
75
import org.netbeans.modules.java.j2seproject.api.J2SEPropertyEvaluator;
71
import org.netbeans.modules.java.j2seproject.classpath.ClassPathProviderImpl;
76
import org.netbeans.modules.java.j2seproject.classpath.ClassPathProviderImpl;
72
import org.netbeans.modules.java.j2seproject.classpath.J2SEProjectClassPathExtender;
77
import org.netbeans.modules.java.j2seproject.classpath.J2SEProjectClassPathExtender;
73
import org.netbeans.modules.java.j2seproject.classpath.J2SEProjectClassPathModifier;
78
import org.netbeans.modules.java.j2seproject.classpath.J2SEProjectClassPathModifier;
74
import org.netbeans.modules.java.j2seproject.queries.CompiledSourceForBinaryQuery;
75
import org.netbeans.modules.java.j2seproject.queries.JavadocForBinaryQueryImpl;
76
import org.netbeans.modules.java.j2seproject.queries.SourceLevelQueryImpl;
77
import org.netbeans.modules.java.j2seproject.queries.UnitTestForSourceQueryImpl;
78
import org.netbeans.modules.java.j2seproject.ui.J2SELogicalViewProvider;
79
import org.netbeans.modules.java.j2seproject.ui.J2SELogicalViewProvider;
79
import org.netbeans.modules.java.j2seproject.ui.customizer.CustomizerProviderImpl;
80
import org.netbeans.modules.java.j2seproject.ui.customizer.CustomizerProviderImpl;
80
import org.netbeans.modules.java.j2seproject.ui.customizer.J2SEProjectProperties;
81
import org.netbeans.modules.java.j2seproject.ui.customizer.J2SEProjectProperties;
81
import org.netbeans.modules.java.j2seproject.queries.J2SEProjectEncodingQueryImpl;
82
import org.netbeans.modules.java.j2seproject.queries.BinaryForSourceQueryImpl;
82
import org.netbeans.modules.java.j2seproject.queries.BinaryForSourceQueryImpl;
83
import org.netbeans.spi.java.project.support.ExtraSourceJavadocSupport;
83
import org.netbeans.spi.java.project.support.ExtraSourceJavadocSupport;
84
import org.netbeans.spi.java.project.support.LookupMergerSupport;
84
import org.netbeans.spi.java.project.support.LookupMergerSupport;
Lines 160-167 public final class J2SEProject implement Link Here
160
        buildExtender = AntBuildExtenderFactory.createAntExtender(new J2SEExtenderImplementation());
160
        buildExtender = AntBuildExtenderFactory.createAntExtender(new J2SEExtenderImplementation());
161
    /// TODO replace this GeneratedFilesHelper with the default one when fixing #101710
161
    /// TODO replace this GeneratedFilesHelper with the default one when fixing #101710
162
        genFilesHelper = new GeneratedFilesHelper(helper, buildExtender);
162
        genFilesHelper = new GeneratedFilesHelper(helper, buildExtender);
163
        this.updateHelper = new UpdateHelper (this, this.helper, this.aux, this.genFilesHelper,
163
        UpdateImplementation updateProject = new UpdateProjectImpl(this, helper, aux);
164
            UpdateHelper.createDefaultNotifier());
164
        this.updateHelper = new UpdateHelper(updateProject, helper);
165
        this.cpProvider = new ClassPathProviderImpl(this.helper, evaluator(), getSourceRoots(),getTestSourceRoots()); //Does not use APH to get/put properties/cfgdata
165
        this.cpProvider = new ClassPathProviderImpl(this.helper, evaluator(), getSourceRoots(),getTestSourceRoots()); //Does not use APH to get/put properties/cfgdata
166
        lookup = createLookup(aux);
166
        lookup = createLookup(aux);
Lines 260-275 public final class J2SEProject implement Link Here
260
            // new J2SECustomizerProvider(this, this.updateHelper, evaluator(), refHelper),
260
            // new J2SECustomizerProvider(this, this.updateHelper, evaluator(), refHelper),
261
            new CustomizerProviderImpl(this, this.updateHelper, evaluator(), refHelper, this.genFilesHelper),
261
            new CustomizerProviderImpl(this, this.updateHelper, evaluator(), refHelper, this.genFilesHelper),
262
            new ClassPathProviderMerger(cpProvider),
262
            new ClassPathProviderMerger(cpProvider),
263
            new CompiledSourceForBinaryQuery(this.helper, evaluator(),getSourceRoots(),getTestSourceRoots()), //Does not use APH to get/put properties/cfgdata
263
            QuerySupport.createCompiledSourceForBinaryQuery(helper, evaluator(), getSourceRoots(), getTestSourceRoots()),
264
            new JavadocForBinaryQueryImpl(this.helper, evaluator()), //Does not use APH to get/put properties/cfgdata
264
            QuerySupport.createJavadocForBinaryQuery(helper, evaluator()),
265
            new AntArtifactProviderImpl(),
265
            new AntArtifactProviderImpl(),
266
            new ProjectXmlSavedHookImpl(),
266
            new ProjectXmlSavedHookImpl(),
267
            UILookupMergerSupport.createProjectOpenHookMerger(new ProjectOpenedHookImpl()),
267
            UILookupMergerSupport.createProjectOpenHookMerger(new ProjectOpenedHookImpl()),
268
            new UnitTestForSourceQueryImpl(getSourceRoots(),getTestSourceRoots()),
268
            QuerySupport.createUnitTestForSourceQuery(getSourceRoots(), getTestSourceRoots()),
269
            new SourceLevelQueryImpl(evaluator()),
269
            QuerySupport.createSourceLevelQuery(evaluator()),
270
            new J2SESources (this.helper, evaluator(), getSourceRoots(), getTestSourceRoots()),
270
            new J2SESources (this.helper, evaluator(), getSourceRoots(), getTestSourceRoots()),
271
            new J2SESharabilityQuery (this.helper, evaluator(), getSourceRoots(), getTestSourceRoots()), //Does not use APH to get/put properties/cfgdata
271
            QuerySupport.createSharabilityQuery(helper, evaluator(), getSourceRoots(), getTestSourceRoots()),
272
            new J2SEFileBuiltQuery (this.helper, evaluator(),getSourceRoots(),getTestSourceRoots()), //Does not use APH to get/put properties/cfgdata
272
            QuerySupport.createFileBuiltQuery(helper, evaluator(), getSourceRoots(), getTestSourceRoots()),
273
            new RecommendedTemplatesImpl (this.updateHelper),
273
            new RecommendedTemplatesImpl (this.updateHelper),
274
            new J2SEProjectClassPathExtender(cpMod),
274
            new J2SEProjectClassPathExtender(cpMod),
275
            buildExtender,
275
            buildExtender,
Lines 281-287 public final class J2SEProject implement Link Here
281
            UILookupMergerSupport.createPrivilegedTemplatesMerger(),
281
            UILookupMergerSupport.createPrivilegedTemplatesMerger(),
282
            UILookupMergerSupport.createRecommendedTemplatesMerger(),
282
            UILookupMergerSupport.createRecommendedTemplatesMerger(),
283
            LookupProviderSupport.createSourcesMerger(),
283
            LookupProviderSupport.createSourcesMerger(),
284
            new J2SEProjectEncodingQueryImpl (evaluator()),
284
            QuerySupport.createFileEncodingQuery(evaluator(), J2SEProjectProperties.SOURCE_ENCODING),
285
            new J2SEPropertyEvaluatorImpl(evaluator()),
285
            new J2SEPropertyEvaluatorImpl(evaluator()),
286
            new J2SETemplateAttributesProvider(this.helper),
286
            new J2SETemplateAttributesProvider(this.helper),
287
            ExtraSourceJavadocSupport.createExtraSourceQueryImplementation(this, helper, eval),
287
            ExtraSourceJavadocSupport.createExtraSourceQueryImplementation(this, helper, eval),
Lines 318-331 public final class J2SEProject implement Link Here
318
     */
318
     */
319
    public synchronized SourceRoots getSourceRoots() {
319
    public synchronized SourceRoots getSourceRoots() {
320
        if (this.sourceRoots == null) { //Local caching, no project metadata access
320
        if (this.sourceRoots == null) { //Local caching, no project metadata access
321
            this.sourceRoots = new SourceRoots(this.updateHelper, evaluator(), getReferenceHelper(), "source-roots", false, "src.{0}{1}.dir"); //NOI18N
321
            this.sourceRoots = SourceRootsSupport.create(updateHelper, evaluator(), getReferenceHelper(),
322
        }
322
                    J2SEProjectType.PROJECT_CONFIGURATION_NAMESPACE, "source-roots", false, "src.{0}{1}.dir"); //NOI18N
323
       }
323
        return this.sourceRoots;
324
        return this.sourceRoots;
324
    }
325
    }
325
    public synchronized SourceRoots getTestSourceRoots() {
326
    public synchronized SourceRoots getTestSourceRoots() {
326
        if (this.testRoots == null) { //Local caching, no project metadata access
327
        if (this.testRoots == null) { //Local caching, no project metadata access
327
            this.testRoots = new SourceRoots(this.updateHelper, evaluator(), getReferenceHelper(), "test-roots", true, "test.{0}{1}.dir"); //NOI18N
328
            this.testRoots = SourceRootsSupport.create(updateHelper, evaluator(), getReferenceHelper(),
329
                    J2SEProjectType.PROJECT_CONFIGURATION_NAMESPACE, "test-roots", true, "test.{0}{1}.dir"); //NOI18N
328
        }
330
        }
329
        return this.testRoots;
331
        return this.testRoots;
330
    }
332
    }
(-)a/java.j2seproject/src/org/netbeans/modules/java/j2seproject/J2SEProjectOperations.java (-1 / +1 lines)
Lines 146-152 public class J2SEProjectOperations imple Link Here
146
    }
146
    }
147
    public void notifyMoving() throws IOException {
147
    public void notifyMoving() throws IOException {
148
        if (!this.project.getUpdateHelper().requestSave()) {
148
        if (!this.project.getUpdateHelper().requestUpdate()) {
149
            throw new IOException (NbBundle.getMessage(J2SEProjectOperations.class,
149
            throw new IOException (NbBundle.getMessage(J2SEProjectOperations.class,
150
                "MSG_OldProjectMetadata"));
150
                "MSG_OldProjectMetadata"));
151
        }
151
        }
(-)a/java.j2seproject/src/org/netbeans/modules/java/j2seproject/J2SESharabilityQuery.java (-127 lines)
Lines 1-127 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 1997-2007 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
 * Contributor(s):
25
 *
26
 * The Original Software is NetBeans. The Initial Developer of the Original
27
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
28
 * Microsystems, Inc. All Rights Reserved.
29
 *
30
 * If you wish your version of this file to be governed by only the CDDL
31
 * or only the GPL Version 2, indicate your decision by adding
32
 * "[Contributor] elects to include this software in this distribution
33
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
34
 * single choice of license, a recipient has the option to distribute
35
 * your version of this file under either the CDDL, the GPL Version 2 or
36
 * to extend the choice of license to its licensees as provided above.
37
 * However, if you add GPL Version 2 code and therefore, elected the GPL
38
 * Version 2 license, then the option applies only if the new code is
39
 * made subject to such option by the copyright holder.
40
 */
41
42
package org.netbeans.modules.java.j2seproject;
43
44
import java.io.File;
45
import java.beans.PropertyChangeEvent;
46
import java.beans.PropertyChangeListener;
47
import org.openide.util.Mutex;
48
import org.netbeans.api.project.ProjectManager;
49
import org.netbeans.spi.queries.SharabilityQueryImplementation;
50
import org.netbeans.spi.project.support.ant.AntProjectHelper;
51
import org.netbeans.spi.project.support.ant.PropertyEvaluator;
52
import org.netbeans.modules.java.j2seproject.ui.customizer.J2SEProjectProperties;
53
54
/**
55
 * SharabilityQueryImplementation for j2seproject with multiple sources
56
 */
57
public class J2SESharabilityQuery implements SharabilityQueryImplementation, PropertyChangeListener {
58
59
    private final AntProjectHelper helper;
60
    private final PropertyEvaluator evaluator;
61
    private final SourceRoots srcRoots;
62
    private final SourceRoots testRoots;
63
    private SharabilityQueryImplementation delegate;
64
65
    /**
66
     * Creates new J2SESharabilityQuery
67
     * @param helper AntProjectHelper
68
     * @param evaluator PropertyEvaluator
69
     * @param srcRoots sources
70
     * @param testRoots tests
71
     */
72
    J2SESharabilityQuery (AntProjectHelper helper, PropertyEvaluator evaluator, SourceRoots srcRoots, SourceRoots testRoots) {
73
        this.helper = helper;
74
        this.evaluator = evaluator;
75
        this.srcRoots = srcRoots;
76
        this.testRoots = testRoots;
77
        this.srcRoots.addPropertyChangeListener(this);
78
        this.testRoots.addPropertyChangeListener(this);
79
    }
80
81
    /**
82
     * Check whether a file or directory should be shared.
83
     * If it is, it ought to be committed to a VCS if the user is using one.
84
     * If it is not, it is either a disposable build product, or a per-user
85
     * private file which is important but should not be shared.
86
     * @param file a file to check for sharability (may or may not yet exist)
87
     * @return one of {@link org.netbeans.api.queries.SharabilityQuery}'s constants
88
     */
89
    public int getSharability(final File file) {
90
        return ProjectManager.mutex().readAccess(new Mutex.Action<Integer>() {
91
            public Integer run() {
92
                synchronized (J2SESharabilityQuery.this) {
93
                    if (delegate == null) {
94
                        delegate = createDelegate ();
95
                    }
96
                    return delegate.getSharability(file);
97
                }
98
            }
99
        });
100
    }
101
102
    public void propertyChange(PropertyChangeEvent evt) {
103
        if (SourceRoots.PROP_ROOT_PROPERTIES.equals(evt.getPropertyName())) {
104
            synchronized (this) {
105
                this.delegate = null;
106
            }
107
        }
108
    }
109
110
    private SharabilityQueryImplementation createDelegate () {
111
        String[] srcProps = srcRoots.getRootProperties();
112
        String[] testProps = testRoots.getRootProperties();
113
        String[] props = new String [srcProps.length + testProps.length];
114
        for (int i=0; i<srcProps.length; i++) {
115
            props[i] = "${"+srcProps[i]+"}";
116
        }
117
        for (int i=0; i<testProps.length; i++) {
118
            props[srcProps.length+i] = "${"+testProps[i]+"}";
119
        }
120
        return helper.createSharabilityQuery(this.evaluator, props,
121
            new String[] {
122
                "${" + J2SEProjectProperties.DIST_DIR + "}", // NOI18N
123
                "${" + J2SEProjectProperties.BUILD_DIR + "}", // NOI18N
124
            });
125
    }
126
127
}
(-)a/java.j2seproject/src/org/netbeans/modules/java/j2seproject/J2SESources.java (+1 lines)
Lines 53-58 import org.netbeans.api.project.ProjectM Link Here
53
import org.netbeans.api.project.ProjectManager;
53
import org.netbeans.api.project.ProjectManager;
54
import org.netbeans.api.project.FileOwnerQuery;
54
import org.netbeans.api.project.FileOwnerQuery;
55
import org.netbeans.api.java.project.JavaProjectConstants;
55
import org.netbeans.api.java.project.JavaProjectConstants;
56
import org.netbeans.modules.java.api.common.SourceRoots;
56
import org.netbeans.spi.project.support.GenericSources;
57
import org.netbeans.spi.project.support.GenericSources;
57
import org.netbeans.spi.project.support.ant.SourcesHelper;
58
import org.netbeans.spi.project.support.ant.SourcesHelper;
58
import org.netbeans.spi.project.support.ant.AntProjectHelper;
59
import org.netbeans.spi.project.support.ant.AntProjectHelper;
(-)a/java.j2seproject/src/org/netbeans/modules/java/j2seproject/MainClassUpdater.java (-1 / +2 lines)
Lines 57-62 import org.netbeans.api.java.source.Sour Link Here
57
import org.netbeans.api.java.source.SourceUtils;
57
import org.netbeans.api.java.source.SourceUtils;
58
import org.netbeans.api.project.Project;
58
import org.netbeans.api.project.Project;
59
import org.netbeans.api.project.ProjectManager;
59
import org.netbeans.api.project.ProjectManager;
60
import org.netbeans.modules.java.api.common.ant.UpdateHelper;
60
import org.netbeans.spi.project.support.ant.AntProjectHelper;
61
import org.netbeans.spi.project.support.ant.AntProjectHelper;
61
import org.netbeans.spi.project.support.ant.EditableProperties;
62
import org.netbeans.spi.project.support.ant.EditableProperties;
62
import org.netbeans.spi.project.support.ant.PropertyEvaluator;
63
import org.netbeans.spi.project.support.ant.PropertyEvaluator;
Lines 145-151 public class MainClassUpdater extends Fi Link Here
145
                            ElementHandle<TypeElement> mainHandle = main.iterator().next();
146
                            ElementHandle<TypeElement> mainHandle = main.iterator().next();
146
                            newMainClass = mainHandle.getQualifiedName();
147
                            newMainClass = mainHandle.getQualifiedName();
147
                        }
148
                        }
148
                        if (newMainClass != null && !newMainClass.equals(oldMainClass) && helper.requestSave() &&
149
                        if (newMainClass != null && !newMainClass.equals(oldMainClass) && helper.requestUpdate() &&
149
                                // XXX ##84806: ideally should update nbproject/configs/*.properties in this case:
150
                                // XXX ##84806: ideally should update nbproject/configs/*.properties in this case:
150
                            eval.getProperty(J2SEConfigurationProvider.PROP_CONFIG) == null) {
151
                            eval.getProperty(J2SEConfigurationProvider.PROP_CONFIG) == null) {
151
                            final String newMainClassFinal = newMainClass;
152
                            final String newMainClassFinal = newMainClass;
(-)a/java.j2seproject/src/org/netbeans/modules/java/j2seproject/SourceRoots.java (-477 lines)
Lines 1-477 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 1997-2007 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
 * Contributor(s):
25
 *
26
 * The Original Software is NetBeans. The Initial Developer of the Original
27
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
28
 * Microsystems, Inc. All Rights Reserved.
29
 *
30
 * If you wish your version of this file to be governed by only the CDDL
31
 * or only the GPL Version 2, indicate your decision by adding
32
 * "[Contributor] elects to include this software in this distribution
33
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
34
 * single choice of license, a recipient has the option to distribute
35
 * your version of this file under either the CDDL, the GPL Version 2 or
36
 * to extend the choice of license to its licensees as provided above.
37
 * However, if you add GPL Version 2 code and therefore, elected the GPL
38
 * Version 2 license, then the option applies only if the new code is
39
 * made subject to such option by the copyright holder.
40
 */
41
42
package org.netbeans.modules.java.j2seproject;
43
44
import java.beans.PropertyChangeEvent;
45
import java.beans.PropertyChangeListener;
46
import java.beans.PropertyChangeSupport;
47
import java.io.File;
48
import java.net.MalformedURLException;
49
import java.net.URL;
50
import java.net.URI;
51
import java.util.Arrays;
52
import java.util.ArrayList;
53
import java.util.Collections;
54
import java.util.List;
55
import java.util.Map;
56
import java.util.HashMap;
57
import java.text.MessageFormat;
58
import org.openide.ErrorManager;
59
import org.openide.filesystems.FileObject;
60
import org.openide.filesystems.FileUtil;
61
import org.openide.util.Exceptions;
62
import org.openide.util.WeakListeners;
63
import org.openide.util.Mutex;
64
import org.openide.util.NbBundle;
65
import org.w3c.dom.Element;
66
import org.w3c.dom.NodeList;
67
import org.w3c.dom.Document;
68
import org.netbeans.spi.project.support.ant.AntProjectHelper;
69
import org.netbeans.spi.project.support.ant.AntProjectEvent;
70
import org.netbeans.spi.project.support.ant.AntProjectListener;
71
import org.netbeans.spi.project.support.ant.EditableProperties;
72
import org.netbeans.spi.project.support.ant.PropertyEvaluator;
73
import org.netbeans.spi.project.support.ant.ReferenceHelper;
74
import org.netbeans.api.project.ProjectManager;
75
import org.netbeans.api.java.project.JavaProjectConstants;
76
77
/**
78
 * This class represents a project source roots. It is used to obtain roots as Ant properties, FileObject's
79
 * or URLs.
80
 * @author Tomas Zezula
81
 */
82
public final class SourceRoots {
83
84
    public static final String PROP_ROOT_PROPERTIES = "rootProperties";    //NOI18N
85
    public static final String PROP_ROOTS = "roots";   //NOI18N
86
87
    public static final String DEFAULT_SOURCE_LABEL = NbBundle.getMessage(SourceRoots.class, "NAME_src.dir");
88
    public static final String DEFAULT_TEST_LABEL = NbBundle.getMessage(SourceRoots.class, "NAME_test.src.dir");
89
90
    private final UpdateHelper helper;
91
    private final PropertyEvaluator evaluator;
92
    private final ReferenceHelper refHelper;
93
    private final String elementName;
94
    private final String newRootNameTemplate;
95
    private List<String> sourceRootProperties;
96
    private List<String> sourceRootNames;
97
    private List<FileObject> sourceRoots;
98
    private List<URL> sourceRootURLs;
99
    private final PropertyChangeSupport support;
100
    private final ProjectMetadataListener listener;
101
    private final boolean isTest;
102
    private final File projectDir;
103
104
    /**
105
     * Creates new SourceRoots
106
     * @param helper
107
     * @param evaluator
108
     * @param elementName the name of XML element under which are declared the roots
109
     * @param newRootNameTemplate template for new property name of source root
110
     */
111
    SourceRoots (UpdateHelper helper, PropertyEvaluator evaluator, ReferenceHelper refHelper, String elementName, boolean isTest, String newRootNameTemplate) {
112
        assert helper != null && evaluator != null && refHelper != null && elementName != null && newRootNameTemplate != null;
113
        this.helper = helper;
114
        this.evaluator = evaluator;
115
        this.refHelper = refHelper;
116
        this.elementName = elementName;
117
        this.isTest = isTest;
118
        this.newRootNameTemplate = newRootNameTemplate;
119
        this.projectDir = FileUtil.toFile(this.helper.getAntProjectHelper().getProjectDirectory());
120
        this.support = new PropertyChangeSupport(this);
121
        this.listener = new ProjectMetadataListener();
122
        this.evaluator.addPropertyChangeListener (WeakListeners.propertyChange(this.listener,this.evaluator));
123
        this.helper.getAntProjectHelper().addAntProjectListener(WeakListeners.create(AntProjectListener.class, this.listener, this.helper));
124
    }
125
126
127
    /**
128
     * Returns the display names of soruce roots
129
     * The returned array has the same length as an array returned by the getRootProperties.
130
     * It may contain empty strings but not null.
131
     * @return an array of String
132
     */
133
    public   String[] getRootNames () {
134
        return ProjectManager.mutex().readAccess(new Mutex.Action<String[]>() {
135
            public String[] run() {
136
                synchronized (SourceRoots.this) {
137
                    if (sourceRootNames == null) {
138
                        readProjectMetadata();
139
                    }
140
                }
141
                return sourceRootNames.toArray (new String[sourceRootNames.size()]);
142
            }
143
        });
144
    }
145
146
    /**
147
     * Returns names of Ant properties in the project.properties file holding the source roots.
148
     * @return an array of String
149
     */
150
    public String[] getRootProperties () {
151
        return ProjectManager.mutex().readAccess(new Mutex.Action<String[]>() {
152
            public String[] run() {
153
                synchronized (SourceRoots.this) {
154
                    if (sourceRootProperties == null) {
155
                        readProjectMetadata();
156
                    }
157
                    return sourceRootProperties.toArray(new String[sourceRootProperties.size()]);
158
                }
159
            }
160
        });
161
    }
162
163
    /**
164
     * Returns the source roots
165
     * @return an array of FileObject
166
     */
167
    public FileObject[] getRoots () {
168
        return ProjectManager.mutex().readAccess(new Mutex.Action<FileObject[]>() {
169
                public FileObject[] run () {
170
                    synchronized (this) {
171
                        //Local caching
172
                        if (sourceRoots == null) {
173
                            String[] srcProps = getRootProperties();
174
                            List<FileObject> result = new ArrayList<FileObject>();
175
                            for (String p : srcProps) {
176
                                String prop = evaluator.getProperty(p);
177
                                if (prop != null) {
178
                                    FileObject f = helper.getAntProjectHelper().resolveFileObject(prop);
179
                                    if (f == null) {
180
                                        continue;
181
                                    }
182
                                    if (FileUtil.isArchiveFile(f)) {
183
                                        f = FileUtil.getArchiveRoot(f);
184
                                    }
185
                                    result.add(f);
186
                                }
187
                            }
188
                            sourceRoots = Collections.unmodifiableList(result);
189
                        }
190
                    }
191
                    return sourceRoots.toArray(new FileObject[sourceRoots.size()]);
192
                }
193
        });
194
    }
195
196
    /**
197
     * Returns the source roots as URLs.
198
     * @return an array of URL
199
     */
200
    public URL[] getRootURLs() {
201
        return ProjectManager.mutex().readAccess(new Mutex.Action<URL[]>() {
202
            public URL[] run () {
203
                synchronized (this) {
204
                    //Local caching
205
                    if (sourceRootURLs == null) {
206
                        String[] srcProps = getRootProperties();
207
                        List<URL> result = new ArrayList<URL>();
208
                        for (int i = 0; i<srcProps.length; i++) {
209
                            String prop = evaluator.getProperty(srcProps[i]);
210
                            if (prop != null) {
211
                                File f = helper.getAntProjectHelper().resolveFile(prop);
212
                                try {
213
                                    URL url = f.toURI().toURL();
214
                                    if (!f.exists()) {
215
                                        url = new URL(url.toExternalForm() + "/"); // NOI18N
216
                                    }
217
                                    else if (f.isFile()) {
218
                                        //File cannot be a source root (archives are not supported as source roots).
219
                                        continue;
220
                                    }
221
                                    assert url.toExternalForm().endsWith("/") : "#90639 violation for " + url + "; " + f + " exists? " + f.exists() + " dir? " + f.isDirectory() + " file? " + f.isFile();
222
                                    result.add(url);
223
                                } catch (MalformedURLException e) {
224
                                    ErrorManager.getDefault().notify(e);
225
                                }
226
                            }
227
                        }
228
                        sourceRootURLs = Collections.unmodifiableList(result);
229
                    }
230
                }
231
                return sourceRootURLs.toArray(new URL[sourceRootURLs.size()]);
232
            }
233
        });
234
    }
235
236
    private Map<URL,String> getRootsToProps () {
237
        return ProjectManager.mutex().readAccess(new Mutex.Action<Map<URL,String>>() {
238
            public Map<URL,String> run () {
239
                String[] srcProps = getRootProperties();
240
                Map<URL,String> result = new HashMap<URL,String>();
241
                for (int i = 0; i<srcProps.length; i++) {
242
                    String prop = evaluator.getProperty(srcProps[i]);
243
                    if (prop != null) {
244
                        File f = helper.getAntProjectHelper().resolveFile(prop);
245
                        try {
246
                            URL url = f.toURI().toURL();
247
                            if (!f.exists()) {
248
                                url = new URL(url.toExternalForm() + "/"); // NOI18N
249
                            }
250
                            else if (f.isFile()) {
251
                                //File cannot be a source root (archives are not supported as source roots).
252
                                continue;
253
                            }
254
                            assert url.toExternalForm().endsWith("/") : "#90639 violation for " + url + "; " + f + " exists? " + f.exists() + " dir? " + f.isDirectory() + " file? " + f.isFile();
255
                            result.put(url,srcProps[i]);
256
                        } catch (MalformedURLException e) {
257
                            Exceptions.printStackTrace(e);
258
                        }
259
                    }
260
                }
261
                return result;
262
            }
263
        });
264
    }
265
266
    /**
267
     * Adds PropertyChangeListener
268
     * @param listener
269
     */
270
    public void addPropertyChangeListener (PropertyChangeListener listener) {
271
        this.support.addPropertyChangeListener (listener);
272
    }
273
274
    /**
275
     * Removes PropertyChangeListener
276
     * @param listener
277
     */
278
    public void removePropertyChangeListener (PropertyChangeListener listener) {
279
        this.support.removePropertyChangeListener (listener);
280
    }
281
282
283
    /**
284
     * Replaces the current roots by the new ones
285
     * @param roots the URLs of new roots
286
     * @param labels the names of roots
287
     */
288
    public void putRoots (final URL[] roots, final String[] labels) {
289
        ProjectManager.mutex().writeAccess(
290
                new Mutex.Action<Void>() {
291
                    public Void run() {
292
                        Map<URL,String> oldRoots2props = getRootsToProps();
293
                        Map<URL,String> newRoots2lab = new HashMap<URL,String>();
294
                        for (int i=0; i<roots.length;i++) {
295
                            newRoots2lab.put (roots[i],labels[i]);
296
                        }
297
                        Element cfgEl = helper.getPrimaryConfigurationData(true);
298
                        NodeList nl = cfgEl.getElementsByTagNameNS(J2SEProjectType.PROJECT_CONFIGURATION_NAMESPACE, elementName);
299
                        assert nl.getLength() == 1 : "Illegal project.xml"; //NOI18N
300
                        Element ownerElement = (Element) nl.item(0);
301
                        //Remove all old roots
302
                        NodeList rootsNodes = ownerElement.getElementsByTagNameNS(J2SEProjectType.PROJECT_CONFIGURATION_NAMESPACE, "root");    //NOI18N
303
                        while (rootsNodes.getLength()>0) {
304
                            Element root = (Element) rootsNodes.item(0);
305
                            ownerElement.removeChild(root);
306
                        }
307
                        //Remove all unused root properties
308
                        List<URL> newRoots = Arrays.asList(roots);
309
                        Map<URL,String> propsToRemove = new HashMap<URL,String>(oldRoots2props);
310
                        propsToRemove.keySet().removeAll(newRoots);
311
                        EditableProperties props = helper.getProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH);
312
                        props.keySet().removeAll(propsToRemove.values());
313
                        helper.putProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH,props);
314
                        //Add the new roots
315
                        Document doc = ownerElement.getOwnerDocument();
316
                        oldRoots2props.keySet().retainAll(newRoots);
317
                        for (URL newRoot : newRoots) {
318
                            String rootName = oldRoots2props.get(newRoot);
319
                            if (rootName == null) {
320
                                //Root is new generate property for it
321
                                props = helper.getProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH);
322
                                String[] names = newRoot.getPath().split("/");  //NOI18N
323
                                rootName = MessageFormat.format(newRootNameTemplate, new Object[] {names[names.length - 1], ""}); // NOI18N
324
                                int rootIndex = 1;
325
                                while (props.containsKey(rootName)) {
326
                                    rootIndex++;
327
                                    rootName = MessageFormat.format(newRootNameTemplate, new Object[] {names[names.length - 1], rootIndex});
328
                                }
329
                                File f = FileUtil.normalizeFile(new File(URI.create(newRoot.toExternalForm())));
330
                                File projDir = FileUtil.toFile(helper.getAntProjectHelper().getProjectDirectory());
331
                                String path = f.getAbsolutePath();
332
                                String prjPath = projDir.getAbsolutePath()+File.separatorChar;
333
                                if (path.startsWith(prjPath)) {
334
                                    path = path.substring(prjPath.length());
335
                                }
336
                                else {
337
                                    path = refHelper.createForeignFileReference(f, JavaProjectConstants.SOURCES_TYPE_JAVA);
338
                                    props = helper.getProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH);
339
                                }
340
                                props.put(rootName,path);
341
                                helper.putProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH,props);
342
                            }
343
                            Element newRootNode = doc.createElementNS(J2SEProjectType.PROJECT_CONFIGURATION_NAMESPACE, "root"); //NOI18N
344
                            newRootNode.setAttribute("id",rootName);    //NOI18N
345
                            String label = newRoots2lab.get(newRoot);
346
                            if (label != null && label.length()>0 && !label.equals (getRootDisplayName(null,rootName))) { //NOI18N
347
                                newRootNode.setAttribute("name",label); //NOI18N
348
                            }
349
                            ownerElement.appendChild (newRootNode);
350
                        }
351
                        helper.putPrimaryConfigurationData(cfgEl,true);
352
                        return null;
353
                    }
354
                }
355
        );
356
    }
357
358
    /**
359
     * Translates root name into display name of source/test root
360
     * @param rootName the name of root got from {@link SourceRoots#getRootNames}
361
     * @param propName the name of property the root is stored in
362
     * @return the label to be displayed
363
     */
364
    public String getRootDisplayName (String rootName, String propName) {
365
        if (rootName == null || rootName.length() ==0) {
366
            //If the prop is src.dir use the default name
367
            if (isTest && "test.src.dir".equals(propName)) {    //NOI18N
368
                rootName = DEFAULT_TEST_LABEL;
369
            }
370
            else if (!isTest && "src.dir".equals(propName)) {   //NOI18N
371
                rootName = DEFAULT_SOURCE_LABEL;
372
            }
373
            else {
374
                //If the name is not given, it should be either a relative path in the project dir
375
                //or absolute path when the root is not under the project dir
376
                String propValue = evaluator.getProperty(propName);
377
                File sourceRoot = propValue == null ? null : helper.getAntProjectHelper().resolveFile(propValue);
378
                rootName = createInitialDisplayName(sourceRoot);
379
            }
380
        }
381
        return rootName;
382
    }
383
384
    /**
385
     * Creates initial display name of source/test root
386
     * @param sourceRoot the source root
387
     * @return the label to be displayed
388
     */
389
    public String createInitialDisplayName (File sourceRoot) {
390
        String rootName;
391
        if (sourceRoot != null) {
392
        String srPath = sourceRoot.getAbsolutePath();
393
        String pdPath = projectDir.getAbsolutePath() + File.separatorChar;
394
        if (srPath.startsWith(pdPath)) {
395
            rootName = srPath.substring(pdPath.length());
396
        }
397
        else {
398
            rootName = sourceRoot.getAbsolutePath();
399
        }
400
        }
401
        else {
402
            rootName = isTest ? DEFAULT_TEST_LABEL : DEFAULT_SOURCE_LABEL;
403
        }
404
        return rootName;
405
    }
406
407
    /**
408
     * Returns true if this SourceRoots instance represents source roots belonging to
409
     * the tests compilation unit.
410
     * @return boolean
411
     */
412
    public boolean isTest () {
413
        return this.isTest;
414
    }
415
416
    private void resetCache (boolean isXMLChange, String propName) {
417
        boolean fire = false;
418
        synchronized (this) {
419
            //In case of change reset local cache
420
            if (isXMLChange) {
421
                this.sourceRootProperties = null;
422
                this.sourceRootNames = null;
423
                this.sourceRoots = null;
424
                this.sourceRootURLs = null;
425
                fire = true;
426
            } else if (propName == null || (sourceRootProperties != null && sourceRootProperties.contains(propName))) {
427
                this.sourceRoots = null;
428
                this.sourceRootURLs = null;
429
                fire = true;
430
            }
431
        }
432
        if (fire) {
433
            if (isXMLChange) {
434
                this.support.firePropertyChange (PROP_ROOT_PROPERTIES,null,null);
435
            }
436
            this.support.firePropertyChange (PROP_ROOTS,null,null);
437
        }
438
    }
439
440
    private void readProjectMetadata () {
441
        Element cfgEl = helper.getPrimaryConfigurationData(true);
442
        NodeList nl = cfgEl.getElementsByTagNameNS(J2SEProjectType.PROJECT_CONFIGURATION_NAMESPACE, elementName);
443
        assert nl.getLength() == 0 || nl.getLength() == 1 : "Illegal project.xml"; //NOI18N
444
        List<String> rootProps = new ArrayList<String>();
445
        List<String> rootNames = new ArrayList<String>();
446
        // It can be 0 in the case when the project is created by J2SEProjectGenerator and not yet customized
447
        if (nl.getLength()==1) {
448
            NodeList roots = ((Element)nl.item(0)).getElementsByTagNameNS(J2SEProjectType.PROJECT_CONFIGURATION_NAMESPACE, "root");    //NOI18N
449
            for (int i=0; i<roots.getLength(); i++) {
450
                Element root = (Element) roots.item(i);
451
                String value = root.getAttribute("id");  //NOI18N
452
                assert value.length() > 0 : "Illegal project.xml";
453
                rootProps.add(value);
454
                value = root.getAttribute("name");  //NOI18N
455
                rootNames.add (value);
456
            }
457
        }
458
        this.sourceRootProperties = Collections.unmodifiableList(rootProps);
459
        this.sourceRootNames = Collections.unmodifiableList(rootNames);
460
    }
461
462
    private class ProjectMetadataListener implements PropertyChangeListener,AntProjectListener {
463
464
        public void propertyChange(PropertyChangeEvent evt) {
465
            resetCache (false,evt.getPropertyName());
466
        }
467
468
        public void configurationXmlChanged(AntProjectEvent ev) {
469
            resetCache (true,null);
470
        }
471
472
        public void propertiesChanged(AntProjectEvent ev) {
473
            //Handled by propertyChange
474
        }
475
    }
476
477
}
(-)a/java.j2seproject/src/org/netbeans/modules/java/j2seproject/UpdateHelper.java (-420 lines)
Lines 1-420 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 1997-2007 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
 * Contributor(s):
25
 *
26
 * The Original Software is NetBeans. The Initial Developer of the Original
27
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
28
 * Microsystems, Inc. All Rights Reserved.
29
 *
30
 * If you wish your version of this file to be governed by only the CDDL
31
 * or only the GPL Version 2, indicate your decision by adding
32
 * "[Contributor] elects to include this software in this distribution
33
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
34
 * single choice of license, a recipient has the option to distribute
35
 * your version of this file under either the CDDL, the GPL Version 2 or
36
 * to extend the choice of license to its licensees as provided above.
37
 * However, if you add GPL Version 2 code and therefore, elected the GPL
38
 * Version 2 license, then the option applies only if the new code is
39
 * made subject to such option by the copyright holder.
40
 */
41
42
package org.netbeans.modules.java.j2seproject;
43
44
import java.io.IOException;
45
import javax.swing.JButton;
46
import org.netbeans.modules.java.j2seproject.ui.customizer.J2SEProjectProperties;
47
import org.netbeans.spi.project.support.ant.GeneratedFilesHelper;
48
import org.openide.util.Exceptions;
49
import org.openide.util.MutexException;
50
import org.w3c.dom.Comment;
51
import org.w3c.dom.Document;
52
import org.w3c.dom.Element;
53
import org.w3c.dom.NamedNodeMap;
54
import org.w3c.dom.Node;
55
import org.w3c.dom.NodeList;
56
import org.w3c.dom.Text;
57
import org.openide.DialogDisplayer;
58
import org.openide.NotifyDescriptor;
59
import org.openide.util.NbBundle;
60
import org.openide.util.Mutex;
61
import org.netbeans.api.project.Project;
62
import org.netbeans.api.project.ProjectManager;
63
import org.netbeans.spi.project.AuxiliaryConfiguration;
64
import org.netbeans.spi.project.support.ant.AntProjectHelper;
65
import org.netbeans.spi.project.support.ant.EditableProperties;
66
67
68
/**
69
 * Proxy for the AntProjectHelper which defers the update of the project metadata
70
 * to explicit user action. Currently it is hard coded for update from
71
 * "http://www.netbeans.org/ns/j2se-project/1" to "http://www.netbeans.org/ns/j2se-project/2".
72
 * In future it should define plugable SPI.
73
 */
74
public class UpdateHelper {
75
76
    private static final boolean TRANSPARENT_UPDATE = Boolean.getBoolean("j2seproject.transparentUpdate");
77
    private static final String BUILD_NUMBER = System.getProperty("netbeans.buildnumber"); // NOI18N
78
    private static final String MINIMUM_ANT_VERSION_ELEMENT = "minimum-ant-version";
79
80
    private final Project project;
81
    private final AntProjectHelper helper;
82
    private final AuxiliaryConfiguration cfg;
83
    private final GeneratedFilesHelper genFileHelper;
84
    private final Notifier notifier;
85
    private boolean alreadyAskedInWriteAccess;
86
    private Boolean isCurrent;
87
    private Element cachedElement;
88
89
    /**
90
     * Creates new UpdateHelper
91
     * @param project
92
     * @param helper AntProjectHelper
93
     * @param cfg AuxiliaryConfiguration
94
     * @param genFileHelper GeneratedFilesHelper
95
     * @param notifier used to ask user about project update
96
     */
97
    UpdateHelper (Project project, AntProjectHelper helper, AuxiliaryConfiguration cfg, GeneratedFilesHelper genFileHelper, Notifier notifier) {
98
        assert project != null && helper != null && cfg != null && genFileHelper != null && notifier != null;
99
        this.project = project;
100
        this.helper = helper;
101
        this.cfg = cfg;
102
        this.genFileHelper = genFileHelper;
103
        this.notifier = notifier;
104
    }
105
106
    /**
107
     * Returns the AntProjectHelper.getProperties(), {@link AntProjectHelper#getProperties(String)}
108
     * @param path a relative URI in the project directory.
109
     * @return a set of properties
110
     */
111
    public EditableProperties getProperties (final String path) {
112
        //Properties are the same in both j2seproject/1 and j2seproject/2
113
        return ProjectManager.mutex().readAccess(new Mutex.Action<EditableProperties>(){
114
            public EditableProperties run() {
115
                if (!isCurrent() && AntProjectHelper.PROJECT_PROPERTIES_PATH.equals(path)) { //Only project properties were changed
116
                    return getUpdatedProjectProperties ();
117
                }
118
                else {
119
                    return helper.getProperties(path);
120
                }
121
            }
122
        });
123
    }
124
125
    /**
126
     * In the case that the project is of current version or the properties are not {@link AntProjectHelper#PROJECT_PROPERTIES_PATH}
127
     * it calls AntProjectHelper.putProperties(), {@link AntProjectHelper#putProperties(String, EditableProperties)}
128
     * otherwise it asks user to updata project. If the user agrees with the project update, it does the update and calls
129
     * AntProjectHelper.putProperties().
130
     * @param path a relative URI in the project directory.
131
     * @param props a set of properties
132
     */
133
    public void putProperties (final String path, final EditableProperties props) {
134
        ProjectManager.mutex().writeAccess(
135
            new Runnable () {
136
                public void run() {
137
                    if (isCurrent() || !AntProjectHelper.PROJECT_PROPERTIES_PATH.equals(path)) {  //Only project props should cause update
138
                        helper.putProperties(path,props);
139
                    }
140
                    else if (canUpdate()) {
141
                        try {
142
                            saveUpdate ();
143
                            helper.putProperties(path,props);
144
                        } catch (IOException ioe) {
145
                            Exceptions.printStackTrace(ioe);
146
                        }
147
                    }
148
                }
149
            });
150
    }
151
152
    /**
153
     * In the case that the project is of current version or shared is false it delegates to
154
     * AntProjectHelper.getPrimaryConfigurationData(), {@link AntProjectHelper#getPrimaryConfigurationData(boolean)}.
155
     * Otherwise it creates an in memory update of shared configuration data and returns it.
156
     * @param shared if true, refers to <code>project.xml</code>, else refers to
157
     *               <code>private.xml</code>
158
     * @return the configuration data that is available
159
     */
160
    public Element getPrimaryConfigurationData (final boolean shared) {
161
        return ProjectManager.mutex().readAccess(new Mutex.Action<Element>(){
162
            public Element run() {
163
                if (!shared || isCurrent()) { //Only shared props should cause update
164
                    return helper.getPrimaryConfigurationData(shared);
165
                }
166
                else {
167
                    return getUpdatedSharedConfigurationData ();
168
                }
169
            }
170
        });
171
    }
172
173
    /**
174
     * In the case that the project is of current version or shared is false it calls AntProjectHelper.putPrimaryConfigurationData(),
175
     * {@link AntProjectHelper#putPrimaryConfigurationData(Element, boolean)}.
176
     * Otherwise it asks user to update the project. If the user agrees with the project update, it does the update and calls
177
     * AntProjectHelper.PrimaryConfigurationData().
178
     * @param element the configuration data
179
     * @param shared if true, refers to <code>project.xml</code>, else refers to
180
     * <code>private.xml</code>
181
     */
182
    public void putPrimaryConfigurationData (final Element element, final boolean shared) {
183
        ProjectManager.mutex().writeAccess(new Runnable () {
184
            public void run () {
185
                if (!shared || isCurrent()) {
186
                    helper.putPrimaryConfigurationData(element, shared);
187
                } else if (canUpdate()) {
188
                    try {
189
                        saveUpdate ();
190
                        helper.putPrimaryConfigurationData(element, shared);
191
                    } catch (IOException ioe) {
192
                        Exceptions.printStackTrace(ioe);
193
                    }
194
                }
195
            }
196
        });
197
    }
198
199
    /**
200
     * Returns an AntProjectHelper. The helper may not be used for accessing/storing project metadata.
201
     * For project metadata manipulation the UpdateHelper must be used.
202
     * @return AntProjectHelper
203
     */
204
    public AntProjectHelper getAntProjectHelper () {
205
        return this.helper;
206
    }
207
208
    /**
209
     * Request an saving of update. If the project is not of current version the user will be asked to update the project.
210
     * If the user agrees with an update the project is updated.
211
     * @return true if the metadata are of current version or updated
212
     */
213
    public boolean requestSave () throws IOException {
214
        try {
215
            return ProjectManager.mutex().writeAccess(new Mutex.ExceptionAction<Boolean>() {
216
                public Boolean run() throws IOException {
217
                    if (isCurrent()) {
218
                        return Boolean.TRUE;
219
                    }
220
                    if (!canUpdate()) {
221
                        return Boolean.FALSE;
222
                    }
223
                    saveUpdate();
224
                    return Boolean.TRUE;
225
                }
226
            }).booleanValue();
227
228
        } catch (MutexException ex) {
229
            Exception inner = ex.getException();
230
            if (inner instanceof IOException) {
231
                throw (IOException) inner;
232
            }
233
            else {
234
                throw (RuntimeException) inner;
235
            }
236
        }
237
    }
238
239
    /**
240
     * Returns true if the project is of current version.
241
     * @return true if the project is of current version, otherwise false.
242
     */
243
    public boolean isCurrent () {
244
        return ProjectManager.mutex().readAccess(new Mutex.Action<Boolean>() {
245
            public Boolean run() {
246
                synchronized (this) {
247
                    if (isCurrent == null) {
248
                        if ((cfg.getConfigurationFragment("data","http://www.netbeans.org/ns/j2se-project/1",true) != null) ||
249
                        (cfg.getConfigurationFragment("data","http://www.netbeans.org/ns/j2se-project/2",true) != null)) {
250
                            isCurrent = Boolean.FALSE;
251
                        } else {
252
                            isCurrent = Boolean.TRUE;
253
                        }
254
                    }
255
                    return isCurrent;
256
                }
257
            }
258
        }).booleanValue();
259
    }
260
261
    private boolean canUpdate () {
262
        if (TRANSPARENT_UPDATE) {
263
            return true;
264
        }
265
        //Ask just once under a single write access
266
        if (alreadyAskedInWriteAccess) {
267
            return false;
268
        }
269
        else {
270
            boolean canUpdate = this.notifier.canUpdate();
271
            if (!canUpdate) {
272
                alreadyAskedInWriteAccess = true;
273
                ProjectManager.mutex().postReadRequest(new Runnable() {
274
                    public void run() {
275
                        alreadyAskedInWriteAccess = false;
276
                    }
277
                });
278
            }
279
            return canUpdate;
280
        }
281
    }
282
283
    private void saveUpdate () throws IOException {
284
        this.helper.putPrimaryConfigurationData(getUpdatedSharedConfigurationData(),true);
285
        this.cfg.removeConfigurationFragment("data","http://www.netbeans.org/ns/j2se-project/1",true); //NOI18N
286
        this.cfg.removeConfigurationFragment("data","http://www.netbeans.org/ns/j2se-project/2",true); //NOI18N
287
        ProjectManager.getDefault().saveProject (this.project);
288
        synchronized(this) {
289
            this.isCurrent = Boolean.TRUE;
290
        }
291
    }
292
293
    private synchronized Element getUpdatedSharedConfigurationData () {
294
        if (cachedElement == null) {
295
            Element  oldRoot = this.cfg.getConfigurationFragment("data","http://www.netbeans.org/ns/j2se-project/1",true);    //NOI18N
296
            if (oldRoot != null) {
297
                Document doc = oldRoot.getOwnerDocument();
298
                Element newRoot = doc.createElementNS (J2SEProjectType.PROJECT_CONFIGURATION_NAMESPACE,"data"); //NOI18N
299
                copyDocument (doc, oldRoot, newRoot);
300
                Element sourceRoots = doc.createElementNS(J2SEProjectType.PROJECT_CONFIGURATION_NAMESPACE,"source-roots");  //NOI18N
301
                Element root = doc.createElementNS (J2SEProjectType.PROJECT_CONFIGURATION_NAMESPACE,"root");   //NOI18N
302
                root.setAttribute ("id","src.dir");   //NOI18N
303
                sourceRoots.appendChild(root);
304
                newRoot.appendChild (sourceRoots);
305
                Element testRoots = doc.createElementNS(J2SEProjectType.PROJECT_CONFIGURATION_NAMESPACE,"test-roots");  //NOI18N
306
                root = doc.createElementNS (J2SEProjectType.PROJECT_CONFIGURATION_NAMESPACE,"root");   //NOI18N
307
                root.setAttribute ("id","test.src.dir");   //NOI18N
308
                testRoots.appendChild (root);
309
                newRoot.appendChild (testRoots);
310
                cachedElement = updateMinAntVersion (newRoot, doc);
311
            } else {
312
                oldRoot = this.cfg.getConfigurationFragment("data","http://www.netbeans.org/ns/j2se-project/2",true);    //NOI18N
313
                if (oldRoot != null) {
314
                    Document doc = oldRoot.getOwnerDocument();
315
                    Element newRoot = doc.createElementNS (J2SEProjectType.PROJECT_CONFIGURATION_NAMESPACE,"data"); //NOI18N
316
                    copyDocument (doc, oldRoot, newRoot);
317
                    cachedElement = updateMinAntVersion (newRoot, doc);
318
                    }
319
                }
320
            }
321
        return cachedElement;
322
    }
323
324
    private synchronized EditableProperties getUpdatedProjectProperties () {
325
        EditableProperties cachedProperties = this.helper.getProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH);
326
        //The javadoc.additionalparam was not in NB 4.0
327
        if (cachedProperties.get (J2SEProjectProperties.JAVADOC_ADDITIONALPARAM)==null) {
328
            cachedProperties.put (J2SEProjectProperties.JAVADOC_ADDITIONALPARAM,"");    //NOI18N
329
        }
330
        if (cachedProperties.get ("build.generated.dir")==null) { //NOI18N
331
            cachedProperties.put ("build.generated.dir","${build.dir}/generated"); //NOI18N
332
        }
333
         if (cachedProperties.get ("meta.inf.dir")==null) { //NOI18N
334
            cachedProperties.put ("meta.inf.dir","${src.dir}/META-INF"); //NOI18N
335
        }
336
        return cachedProperties;
337
    }
338
339
    private static void copyDocument (Document doc, Element from, Element to) {
340
        NodeList nl = from.getChildNodes();
341
        int length = nl.getLength();
342
        for (int i=0; i< length; i++) {
343
            Node node = nl.item (i);
344
            Node newNode = null;
345
            switch (node.getNodeType()) {
346
                case Node.ELEMENT_NODE:
347
                    Element oldElement = (Element) node;
348
                    newNode = doc.createElementNS(J2SEProjectType.PROJECT_CONFIGURATION_NAMESPACE,oldElement.getTagName());
349
                    NamedNodeMap m = oldElement.getAttributes();
350
                    Element newElement = (Element) newNode;
351
                    for (int index = 0; index < m.getLength(); index++) {
352
                        Node attr = m.item(index);
353
                          newElement.setAttribute(attr.getNodeName(), attr.getNodeValue());
354
                    }
355
                    copyDocument(doc,oldElement,newElement);
356
                    break;
357
                case Node.TEXT_NODE:
358
                    Text oldText = (Text) node;
359
                    newNode = doc.createTextNode(oldText.getData());
360
                    break;
361
                case Node.COMMENT_NODE:
362
                    Comment oldComment = (Comment) node;
363
                    newNode = doc.createComment(oldComment.getData());
364
                    break;
365
            }
366
            if (newNode != null) {
367
                to.appendChild (newNode);
368
            }
369
        }
370
    }
371
372
    private static Element updateMinAntVersion (final Element root, final Document doc) {
373
        NodeList list = root.getElementsByTagNameNS (J2SEProjectType.PROJECT_CONFIGURATION_NAMESPACE,MINIMUM_ANT_VERSION_ELEMENT);
374
        if (list.getLength() == 1) {
375
            Element me = (Element) list.item(0);
376
            list = me.getChildNodes();
377
            if (list.getLength() == 1) {
378
                me.replaceChild (doc.createTextNode(J2SEProjectGenerator.MINIMUM_ANT_VERSION), list.item(0));
379
                return root;
380
            }
381
        }
382
        assert false : "Invalid project file"; //NOI18N
383
        return root;
384
    }
385
386
    /**
387
     * Creates an default Notifier. The default notifier displays a dialog warning user about project update.
388
     * @return notifier
389
     */
390
    public static Notifier createDefaultNotifier () {
391
        return new Notifier() {
392
            public boolean canUpdate() {
393
                JButton updateOption = new JButton (NbBundle.getMessage(UpdateHelper.class, "CTL_UpdateOption"));
394
                updateOption.getAccessibleContext().setAccessibleDescription(NbBundle.getMessage(UpdateHelper.class, "AD_UpdateOption"));
395
                return DialogDisplayer.getDefault().notify(
396
                    new NotifyDescriptor (NbBundle.getMessage(UpdateHelper.class,"TXT_ProjectUpdate", BUILD_NUMBER),
397
                        NbBundle.getMessage(UpdateHelper.class,"TXT_ProjectUpdateTitle"),
398
                        NotifyDescriptor.DEFAULT_OPTION,
399
                        NotifyDescriptor.WARNING_MESSAGE,
400
                        new Object[] {
401
                            updateOption,
402
                            NotifyDescriptor.CANCEL_OPTION
403
                        },
404
                        updateOption)) == updateOption;
405
            }
406
        };
407
    }
408
409
    /**
410
     * Interface used by the UpdateHelper to ask user about
411
     * the project update.
412
     */
413
    public static interface Notifier {
414
        /**
415
         * Asks user to update the project
416
         * @return true if the project should be updated
417
         */
418
        public boolean canUpdate ();
419
    }
420
}
(-)a/java.j2seproject/src/org/netbeans/modules/java/j2seproject/UpdateProjectImpl.java (+256 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 1997-2007 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 2008 Sun Microsystems, Inc.
38
 */
39
40
package org.netbeans.modules.java.j2seproject;
41
42
import java.io.IOException;
43
import javax.swing.JButton;
44
import org.netbeans.api.project.Project;
45
import org.netbeans.api.project.ProjectManager;
46
import org.netbeans.modules.java.api.common.ant.UpdateImplementation;
47
import org.netbeans.modules.java.j2seproject.ui.customizer.J2SEProjectProperties;
48
import org.netbeans.spi.project.AuxiliaryConfiguration;
49
import org.netbeans.spi.project.support.ant.AntProjectHelper;
50
import org.netbeans.spi.project.support.ant.EditableProperties;
51
import org.openide.DialogDisplayer;
52
import org.openide.NotifyDescriptor;
53
import org.openide.util.Mutex;
54
import org.openide.util.NbBundle;
55
import org.w3c.dom.Comment;
56
import org.w3c.dom.Document;
57
import org.w3c.dom.Element;
58
import org.w3c.dom.NamedNodeMap;
59
import org.w3c.dom.Node;
60
import org.w3c.dom.NodeList;
61
import org.w3c.dom.Text;
62
63
/**
64
 *
65
 * @author Tomas Mysik
66
 */
67
public class UpdateProjectImpl implements UpdateImplementation {
68
69
    private static final boolean TRANSPARENT_UPDATE = Boolean.getBoolean("j2seproject.transparentUpdate");
70
    private static final String BUILD_NUMBER = System.getProperty("netbeans.buildnumber"); // NOI18N
71
    private static final String MINIMUM_ANT_VERSION_ELEMENT = "minimum-ant-version";
72
73
    private final Project project;
74
    private final AntProjectHelper helper;
75
    private final AuxiliaryConfiguration cfg;
76
    private boolean alreadyAskedInWriteAccess;
77
    private Boolean isCurrent;
78
    private Element cachedElement;
79
80
    /**
81
     * Creates new UpdateHelper
82
     * @param project
83
     * @param helper AntProjectHelper
84
     * @param cfg AuxiliaryConfiguration
85
     * @param genFileHelper GeneratedFilesHelper
86
     * @param notifier used to ask user about project update
87
     */
88
    UpdateProjectImpl(Project project, AntProjectHelper helper, AuxiliaryConfiguration cfg) {
89
        assert project != null && helper != null && cfg != null;
90
        this.project = project;
91
        this.helper = helper;
92
        this.cfg = cfg;
93
    }
94
95
    /**
96
     * Returns true if the project is of current version.
97
     * @return true if the project is of current version, otherwise false.
98
     */
99
    public boolean isCurrent () {
100
        return ProjectManager.mutex().readAccess(new Mutex.Action<Boolean>() {
101
            public Boolean run() {
102
                synchronized (this) {
103
                    if (isCurrent == null) {
104
                        if ((cfg.getConfigurationFragment("data","http://www.netbeans.org/ns/j2se-project/1",true) != null) ||
105
                        (cfg.getConfigurationFragment("data","http://www.netbeans.org/ns/j2se-project/2",true) != null)) {
106
                            isCurrent = Boolean.FALSE;
107
                        } else {
108
                            isCurrent = Boolean.TRUE;
109
                        }
110
                    }
111
                    return isCurrent;
112
                }
113
            }
114
        }).booleanValue();
115
    }
116
117
    public boolean canUpdate () {
118
        if (TRANSPARENT_UPDATE) {
119
            return true;
120
        }
121
        //Ask just once under a single write access
122
        if (alreadyAskedInWriteAccess) {
123
            return false;
124
        }
125
        else {
126
            boolean canUpdate = showUpdateDialog();
127
            if (!canUpdate) {
128
                alreadyAskedInWriteAccess = true;
129
                ProjectManager.mutex().postReadRequest(new Runnable() {
130
                    public void run() {
131
                        alreadyAskedInWriteAccess = false;
132
                    }
133
                });
134
            }
135
            return canUpdate;
136
        }
137
    }
138
139
    public void saveUpdate(final EditableProperties props) throws IOException {
140
        this.helper.putPrimaryConfigurationData(getUpdatedSharedConfigurationData(),true);
141
        this.cfg.removeConfigurationFragment("data","http://www.netbeans.org/ns/j2se-project/1",true); //NOI18N
142
        this.cfg.removeConfigurationFragment("data","http://www.netbeans.org/ns/j2se-project/2",true); //NOI18N
143
        ProjectManager.getDefault().saveProject (this.project);
144
        synchronized(this) {
145
            this.isCurrent = Boolean.TRUE;
146
        }
147
    }
148
149
    public synchronized Element getUpdatedSharedConfigurationData () {
150
        if (cachedElement == null) {
151
            Element  oldRoot = this.cfg.getConfigurationFragment("data","http://www.netbeans.org/ns/j2se-project/1",true);    //NOI18N
152
            if (oldRoot != null) {
153
                Document doc = oldRoot.getOwnerDocument();
154
                Element newRoot = doc.createElementNS (J2SEProjectType.PROJECT_CONFIGURATION_NAMESPACE,"data"); //NOI18N
155
                copyDocument (doc, oldRoot, newRoot);
156
                Element sourceRoots = doc.createElementNS(J2SEProjectType.PROJECT_CONFIGURATION_NAMESPACE,"source-roots");  //NOI18N
157
                Element root = doc.createElementNS (J2SEProjectType.PROJECT_CONFIGURATION_NAMESPACE,"root");   //NOI18N
158
                root.setAttribute ("id","src.dir");   //NOI18N
159
                sourceRoots.appendChild(root);
160
                newRoot.appendChild (sourceRoots);
161
                Element testRoots = doc.createElementNS(J2SEProjectType.PROJECT_CONFIGURATION_NAMESPACE,"test-roots");  //NOI18N
162
                root = doc.createElementNS (J2SEProjectType.PROJECT_CONFIGURATION_NAMESPACE,"root");   //NOI18N
163
                root.setAttribute ("id","test.src.dir");   //NOI18N
164
                testRoots.appendChild (root);
165
                newRoot.appendChild (testRoots);
166
                cachedElement = updateMinAntVersion (newRoot, doc);
167
            } else {
168
                oldRoot = this.cfg.getConfigurationFragment("data","http://www.netbeans.org/ns/j2se-project/2",true);    //NOI18N
169
                if (oldRoot != null) {
170
                    Document doc = oldRoot.getOwnerDocument();
171
                    Element newRoot = doc.createElementNS (J2SEProjectType.PROJECT_CONFIGURATION_NAMESPACE,"data"); //NOI18N
172
                    copyDocument (doc, oldRoot, newRoot);
173
                    cachedElement = updateMinAntVersion (newRoot, doc);
174
                    }
175
                }
176
            }
177
        return cachedElement;
178
    }
179
180
    public synchronized EditableProperties getUpdatedProjectProperties () {
181
        EditableProperties cachedProperties = this.helper.getProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH);
182
        //The javadoc.additionalparam was not in NB 4.0
183
        if (cachedProperties.get (J2SEProjectProperties.JAVADOC_ADDITIONALPARAM)==null) {
184
            cachedProperties.put (J2SEProjectProperties.JAVADOC_ADDITIONALPARAM,"");    //NOI18N
185
        }
186
        if (cachedProperties.get ("build.generated.dir")==null) { //NOI18N
187
            cachedProperties.put ("build.generated.dir","${build.dir}/generated"); //NOI18N
188
        }
189
         if (cachedProperties.get ("meta.inf.dir")==null) { //NOI18N
190
            cachedProperties.put ("meta.inf.dir","${src.dir}/META-INF"); //NOI18N
191
        }
192
        return cachedProperties;
193
    }
194
195
    private static void copyDocument (Document doc, Element from, Element to) {
196
        NodeList nl = from.getChildNodes();
197
        int length = nl.getLength();
198
        for (int i=0; i< length; i++) {
199
            Node node = nl.item (i);
200
            Node newNode = null;
201
            switch (node.getNodeType()) {
202
                case Node.ELEMENT_NODE:
203
                    Element oldElement = (Element) node;
204
                    newNode = doc.createElementNS(J2SEProjectType.PROJECT_CONFIGURATION_NAMESPACE,oldElement.getTagName());
205
                    NamedNodeMap m = oldElement.getAttributes();
206
                    Element newElement = (Element) newNode;
207
                    for (int index = 0; index < m.getLength(); index++) {
208
                        Node attr = m.item(index);
209
                          newElement.setAttribute(attr.getNodeName(), attr.getNodeValue());
210
                    }
211
                    copyDocument(doc,oldElement,newElement);
212
                    break;
213
                case Node.TEXT_NODE:
214
                    Text oldText = (Text) node;
215
                    newNode = doc.createTextNode(oldText.getData());
216
                    break;
217
                case Node.COMMENT_NODE:
218
                    Comment oldComment = (Comment) node;
219
                    newNode = doc.createComment(oldComment.getData());
220
                    break;
221
            }
222
            if (newNode != null) {
223
                to.appendChild (newNode);
224
            }
225
        }
226
    }
227
228
    private static Element updateMinAntVersion (final Element root, final Document doc) {
229
        NodeList list = root.getElementsByTagNameNS (J2SEProjectType.PROJECT_CONFIGURATION_NAMESPACE,MINIMUM_ANT_VERSION_ELEMENT);
230
        if (list.getLength() == 1) {
231
            Element me = (Element) list.item(0);
232
            list = me.getChildNodes();
233
            if (list.getLength() == 1) {
234
                me.replaceChild (doc.createTextNode(J2SEProjectGenerator.MINIMUM_ANT_VERSION), list.item(0));
235
                return root;
236
            }
237
        }
238
        assert false : "Invalid project file"; //NOI18N
239
        return root;
240
    }
241
242
    private boolean showUpdateDialog() {
243
        JButton updateOption = new JButton (NbBundle.getMessage(UpdateProjectImpl.class, "CTL_UpdateOption"));
244
        updateOption.getAccessibleContext().setAccessibleDescription(NbBundle.getMessage(UpdateProjectImpl.class, "AD_UpdateOption"));
245
        return DialogDisplayer.getDefault().notify(
246
            new NotifyDescriptor (NbBundle.getMessage(UpdateProjectImpl.class,"TXT_ProjectUpdate", BUILD_NUMBER),
247
                NbBundle.getMessage(UpdateProjectImpl.class,"TXT_ProjectUpdateTitle"),
248
                NotifyDescriptor.DEFAULT_OPTION,
249
                NotifyDescriptor.WARNING_MESSAGE,
250
                new Object[] {
251
                    updateOption,
252
                    NotifyDescriptor.CANCEL_OPTION
253
                },
254
                updateOption)) == updateOption;
255
    }
256
}
(-)a/java.j2seproject/src/org/netbeans/modules/java/j2seproject/classpath/ClassPathProviderImpl.java (-1 / +1 lines)
Lines 47-58 import java.util.HashMap; Link Here
47
import java.util.HashMap;
47
import java.util.HashMap;
48
import org.netbeans.api.java.classpath.ClassPath;
48
import org.netbeans.api.java.classpath.ClassPath;
49
import org.netbeans.api.project.SourceGroup;
49
import org.netbeans.api.project.SourceGroup;
50
import org.netbeans.modules.java.api.common.SourceRoots;
50
import org.netbeans.spi.java.classpath.ClassPathFactory;
51
import org.netbeans.spi.java.classpath.ClassPathFactory;
51
import org.netbeans.spi.java.classpath.ClassPathProvider;
52
import org.netbeans.spi.java.classpath.ClassPathProvider;
52
import org.netbeans.spi.java.project.classpath.support.ProjectClassPathSupport;
53
import org.netbeans.spi.java.project.classpath.support.ProjectClassPathSupport;
53
import org.netbeans.spi.project.support.ant.AntProjectHelper;
54
import org.netbeans.spi.project.support.ant.AntProjectHelper;
54
import org.netbeans.spi.project.support.ant.PropertyEvaluator;
55
import org.netbeans.spi.project.support.ant.PropertyEvaluator;
55
import org.netbeans.modules.java.j2seproject.SourceRoots;
56
import org.openide.filesystems.FileObject;
56
import org.openide.filesystems.FileObject;
57
import org.openide.filesystems.FileUtil;
57
import org.openide.filesystems.FileUtil;
58
import org.openide.util.WeakListeners;
58
import org.openide.util.WeakListeners;
(-)a/java.j2seproject/src/org/netbeans/modules/java/j2seproject/classpath/ClassPathSupport.java (-3 / +1 lines)
Lines 54-67 import org.netbeans.api.project.ant.AntA Link Here
54
import org.netbeans.api.project.ant.AntArtifact;
54
import org.netbeans.api.project.ant.AntArtifact;
55
import org.netbeans.api.project.libraries.Library;
55
import org.netbeans.api.project.libraries.Library;
56
import org.netbeans.api.project.libraries.LibraryManager;
56
import org.netbeans.api.project.libraries.LibraryManager;
57
import org.netbeans.api.queries.CollocationQuery;
57
import org.netbeans.modules.java.api.common.ant.UpdateHelper;
58
import org.netbeans.modules.java.j2seproject.UpdateHelper;
59
import org.netbeans.spi.project.support.ant.AntProjectHelper;
58
import org.netbeans.spi.project.support.ant.AntProjectHelper;
60
import org.netbeans.spi.project.support.ant.EditableProperties;
59
import org.netbeans.spi.project.support.ant.EditableProperties;
61
import org.netbeans.spi.project.support.ant.PropertyEvaluator;
60
import org.netbeans.spi.project.support.ant.PropertyEvaluator;
62
import org.netbeans.spi.project.support.ant.PropertyUtils;
61
import org.netbeans.spi.project.support.ant.PropertyUtils;
63
import org.netbeans.spi.project.support.ant.ReferenceHelper;
62
import org.netbeans.spi.project.support.ant.ReferenceHelper;
64
import org.openide.filesystems.FileUtil;
65
/**
63
/**
66
 *
64
 *
(-)a/java.j2seproject/src/org/netbeans/modules/java/j2seproject/classpath/J2SEProjectClassPathModifier.java (-3 / +1 lines)
Lines 52-66 import java.util.logging.Logger; Link Here
52
import java.util.logging.Logger;
52
import java.util.logging.Logger;
53
import org.netbeans.api.java.classpath.ClassPath;
53
import org.netbeans.api.java.classpath.ClassPath;
54
import org.netbeans.api.java.project.JavaProjectConstants;
54
import org.netbeans.api.java.project.JavaProjectConstants;
55
import org.netbeans.api.project.Project;
56
import org.netbeans.api.project.ProjectManager;
55
import org.netbeans.api.project.ProjectManager;
57
import org.netbeans.api.project.SourceGroup;
56
import org.netbeans.api.project.SourceGroup;
58
import org.netbeans.api.project.Sources;
57
import org.netbeans.api.project.Sources;
59
import org.netbeans.api.project.ant.AntArtifact;
58
import org.netbeans.api.project.ant.AntArtifact;
60
import org.netbeans.api.project.libraries.Library;
59
import org.netbeans.api.project.libraries.Library;
61
import org.netbeans.api.project.libraries.LibraryManager;
60
import org.netbeans.modules.java.api.common.ant.UpdateHelper;
62
import org.netbeans.modules.java.j2seproject.J2SEProject;
61
import org.netbeans.modules.java.j2seproject.J2SEProject;
63
import org.netbeans.modules.java.j2seproject.UpdateHelper;
64
import org.netbeans.modules.java.j2seproject.ui.customizer.J2SEProjectProperties;
62
import org.netbeans.modules.java.j2seproject.ui.customizer.J2SEProjectProperties;
65
import org.netbeans.spi.java.project.classpath.ProjectClassPathModifierImplementation;
63
import org.netbeans.spi.java.project.classpath.ProjectClassPathModifierImplementation;
66
import org.netbeans.spi.project.libraries.support.LibrariesSupport;
64
import org.netbeans.spi.project.libraries.support.LibrariesSupport;
(-)a/java.j2seproject/src/org/netbeans/modules/java/j2seproject/classpath/SourcePathImplementation.java (-1 / +1 lines)
Lines 52-61 import java.net.URL; Link Here
52
import java.net.URL;
52
import java.net.URL;
53
import java.util.Iterator;
53
import java.util.Iterator;
54
import java.util.StringTokenizer;
54
import java.util.StringTokenizer;
55
import org.netbeans.modules.java.api.common.SourceRoots;
55
import org.netbeans.spi.java.classpath.ClassPathImplementation;
56
import org.netbeans.spi.java.classpath.ClassPathImplementation;
56
import org.netbeans.spi.java.classpath.PathResourceImplementation;
57
import org.netbeans.spi.java.classpath.PathResourceImplementation;
57
import org.netbeans.spi.java.classpath.support.ClassPathSupport;
58
import org.netbeans.spi.java.classpath.support.ClassPathSupport;
58
import org.netbeans.modules.java.j2seproject.SourceRoots;
59
import org.netbeans.modules.java.j2seproject.ui.customizer.J2SEProjectProperties;
59
import org.netbeans.modules.java.j2seproject.ui.customizer.J2SEProjectProperties;
60
import org.netbeans.spi.java.classpath.FilteringPathResourceImplementation;
60
import org.netbeans.spi.java.classpath.FilteringPathResourceImplementation;
61
import org.netbeans.spi.project.support.ant.AntProjectHelper;
61
import org.netbeans.spi.project.support.ant.AntProjectHelper;
(-)a/java.j2seproject/src/org/netbeans/modules/java/j2seproject/queries/BinaryForSourceQueryImpl.java (-2 / +1 lines)
Lines 48-58 import java.net.URL; Link Here
48
import java.net.URL;
48
import java.net.URL;
49
import java.util.HashMap;
49
import java.util.HashMap;
50
import java.util.Map;
50
import java.util.Map;
51
import javax.swing.event.ChangeEvent;
52
import javax.swing.event.ChangeListener;
51
import javax.swing.event.ChangeListener;
53
import org.netbeans.api.java.queries.BinaryForSourceQuery;
52
import org.netbeans.api.java.queries.BinaryForSourceQuery;
54
import org.netbeans.api.java.queries.BinaryForSourceQuery.Result;
53
import org.netbeans.api.java.queries.BinaryForSourceQuery.Result;
55
import org.netbeans.modules.java.j2seproject.SourceRoots;
54
import org.netbeans.modules.java.api.common.SourceRoots;
56
import org.netbeans.modules.java.j2seproject.ui.customizer.J2SEProjectProperties;
55
import org.netbeans.modules.java.j2seproject.ui.customizer.J2SEProjectProperties;
57
import org.netbeans.spi.java.queries.BinaryForSourceQueryImplementation;
56
import org.netbeans.spi.java.queries.BinaryForSourceQueryImplementation;
58
import org.netbeans.spi.project.support.ant.AntProjectHelper;
57
import org.netbeans.spi.project.support.ant.AntProjectHelper;
(-)a/java.j2seproject/src/org/netbeans/modules/java/j2seproject/queries/CompiledSourceForBinaryQuery.java (-214 lines)
Lines 1-214 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 1997-2007 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
 * Contributor(s):
25
 *
26
 * The Original Software is NetBeans. The Initial Developer of the Original
27
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
28
 * Microsystems, Inc. All Rights Reserved.
29
 *
30
 * If you wish your version of this file to be governed by only the CDDL
31
 * or only the GPL Version 2, indicate your decision by adding
32
 * "[Contributor] elects to include this software in this distribution
33
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
34
 * single choice of license, a recipient has the option to distribute
35
 * your version of this file under either the CDDL, the GPL Version 2 or
36
 * to extend the choice of license to its licensees as provided above.
37
 * However, if you add GPL Version 2 code and therefore, elected the GPL
38
 * Version 2 license, then the option applies only if the new code is
39
 * made subject to such option by the copyright holder.
40
 */
41
package org.netbeans.modules.java.j2seproject.queries;
42
43
import java.io.File;
44
import java.util.Arrays;
45
import java.util.List;
46
import org.netbeans.spi.java.queries.SourceForBinaryQueryImplementation;
47
import org.netbeans.spi.project.support.ant.AntProjectHelper;
48
import org.openide.ErrorManager;
49
import org.openide.filesystems.FileObject;
50
import org.openide.filesystems.FileUtil;
51
import java.net.URL;
52
import java.net.MalformedURLException;
53
import java.beans.PropertyChangeListener;
54
import java.beans.PropertyChangeEvent;
55
import java.util.ArrayList;
56
import java.util.Map;
57
import java.util.HashMap;
58
import javax.swing.event.ChangeListener;
59
import javax.swing.event.ChangeEvent;
60
import org.netbeans.api.java.queries.SourceForBinaryQuery;
61
import org.netbeans.spi.project.support.ant.PropertyEvaluator;
62
import org.netbeans.modules.java.j2seproject.SourceRoots;
63
import org.openide.filesystems.URLMapper;
64
import org.openide.util.ChangeSupport;
65
66
/**
67
 * Finds sources corresponding to binaries in a J2SE project.
68
 * @author Jesse Glick, Tomas Zezula
69
 */
70
public class CompiledSourceForBinaryQuery implements SourceForBinaryQueryImplementation {
71
72
    private static final String PROP_BUILD_DIR = "build.dir";   //NOI18N
73
74
    private final AntProjectHelper helper;
75
    private final PropertyEvaluator evaluator;
76
    private final SourceRoots sourceRoots;
77
    private final SourceRoots testRoots;
78
    private Map<URL,SourceForBinaryQuery.Result>  cache = new HashMap<URL,SourceForBinaryQuery.Result>();
79
80
    public CompiledSourceForBinaryQuery(AntProjectHelper helper, PropertyEvaluator evaluator, SourceRoots srcRoots, SourceRoots testRoots) {
81
        this.helper = helper;
82
        this.evaluator = evaluator;
83
        this.sourceRoots = srcRoots;
84
        this.testRoots = testRoots;
85
    }
86
87
    public SourceForBinaryQuery.Result findSourceRoots(URL binaryRoot) {
88
        if (FileUtil.getArchiveFile(binaryRoot) != null) {
89
            binaryRoot = FileUtil.getArchiveFile(binaryRoot);
90
            // XXX check whether this is really the root
91
        }
92
        SourceForBinaryQuery.Result res = cache.get(binaryRoot);
93
        if (res != null) {
94
            return res;
95
        }
96
        SourceRoots src = null;
97
        if (hasSources(binaryRoot,"build.classes.dir")) {   //NOI18N
98
            src = this.sourceRoots;
99
        }
100
        else if (hasSources (binaryRoot,"dist.jar")) {      //NOI18N
101
            src = this.sourceRoots;
102
        }
103
        else if (hasSources (binaryRoot,"build.test.classes.dir")) {    //NOI18N
104
            src = this.testRoots;
105
        }
106
        if (src == null) {
107
            return null;
108
        }
109
        else {
110
            res = new Result (src);
111
            cache.put (binaryRoot, res);
112
            return res;
113
        }
114
    }
115
116
117
    private boolean hasSources (URL binaryRoot, String binaryProperty) {
118
        try {
119
            String outDir = evaluator.getProperty(binaryProperty);
120
            if (outDir != null) {
121
                File f = helper.resolveFile (outDir);
122
                URL url = f.toURI().toURL();
123
                if (!f.exists() && !f.getPath().toLowerCase().endsWith(".jar")) { // NOI18N
124
                    // non-existing
125
                    assert !url.toExternalForm().endsWith("/") : f; // NOI18N
126
                    url = new URL(url.toExternalForm() + "/"); // NOI18N
127
                }
128
                if (url.equals (binaryRoot)) {
129
                    return true;
130
                }
131
            }
132
        } catch (MalformedURLException malformedURL) {
133
            ErrorManager.getDefault().notify(malformedURL);
134
        }
135
        return false;
136
    }
137
138
    private class Result implements SourceForBinaryQuery.Result, PropertyChangeListener {
139
140
        private final ChangeSupport changeSupport = new ChangeSupport(this);
141
        private SourceRoots sourceRoots;
142
143
        public Result (SourceRoots sourceRoots) {
144
            this.sourceRoots = sourceRoots;
145
            this.sourceRoots.addPropertyChangeListener(this);
146
        }
147
148
        public FileObject[] getRoots () {
149
            //todo: May need to cache the result
150
            List<FileObject> result = new ArrayList<FileObject>();
151
            result.addAll(Arrays.asList(this.sourceRoots.getRoots()));
152
            try {
153
                String buildDir = evaluator.getProperty(PROP_BUILD_DIR);
154
                if (buildDir != null) {
155
                    // generated/wsclient
156
                    File f =  new File (helper.resolveFile (buildDir),"generated/wsclient"); //NOI18N
157
                    URL url = f.toURI().toURL();
158
                    if (!f.exists()) {  //NOI18N
159
                        assert !url.toExternalForm().endsWith("/");  //NOI18N
160
                        url = new URL (url.toExternalForm()+'/');   //NOI18N
161
                    }
162
                    FileObject root = URLMapper.findFileObject(url);
163
                    if (root != null) {
164
                        result.add(root);
165
                    }
166
167
                    // generated/wsimport/client
168
                    f = new File (helper.resolveFile(buildDir),"generated/wsimport/client"); //NOI18N
169
                    url = f.toURI().toURL();
170
                    if (!f.exists()) {  //NOI18N
171
                        assert !url.toExternalForm().endsWith("/");  //NOI18N
172
                        url = new URL (url.toExternalForm()+'/');   //NOI18N
173
                    }
174
                    root = URLMapper.findFileObject(url);
175
                    if (root != null) {
176
                        result.add(root);
177
                    }
178
179
                    // generated/addons/jaxb
180
                    f =  new File (helper.resolveFile (buildDir),"generated/addons/jaxb"); //NOI18N
181
                    url = f.toURI().toURL();
182
                    if (!f.exists()) {
183
                        assert !url.toExternalForm().endsWith("/");  //NOI18N
184
                        url = new URL (url.toExternalForm()+'/');   //NOI18N
185
                    }
186
                    root = URLMapper.findFileObject(url);
187
                    if (root != null) {
188
                        result.add(root);
189
                    }
190
191
                }
192
            } catch (MalformedURLException ex) {
193
                ErrorManager.getDefault ().notify (ex);
194
            }
195
            return result.toArray(new FileObject[result.size()]);
196
        }
197
198
        public void addChangeListener (ChangeListener l) {
199
            changeSupport.addChangeListener(l);
200
        }
201
202
        public void removeChangeListener (ChangeListener l) {
203
            changeSupport.removeChangeListener(l);
204
        }
205
206
        public void propertyChange(PropertyChangeEvent evt) {
207
            if (SourceRoots.PROP_ROOTS.equals(evt.getPropertyName())) {
208
                this.changeSupport.fireChange ();
209
            }
210
        }
211
212
    }
213
214
}
(-)a/java.j2seproject/src/org/netbeans/modules/java/j2seproject/queries/J2SEProjectEncodingQueryImpl.java (-106 lines)
Lines 1-106 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 1997-2007 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
 * Contributor(s):
25
 *
26
 * The Original Software is NetBeans. The Initial Developer of the Original
27
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
28
 * Microsystems, Inc. All Rights Reserved.
29
 *
30
 * If you wish your version of this file to be governed by only the CDDL
31
 * or only the GPL Version 2, indicate your decision by adding
32
 * "[Contributor] elects to include this software in this distribution
33
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
34
 * single choice of license, a recipient has the option to distribute
35
 * your version of this file under either the CDDL, the GPL Version 2 or
36
 * to extend the choice of license to its licensees as provided above.
37
 * However, if you add GPL Version 2 code and therefore, elected the GPL
38
 * Version 2 license, then the option applies only if the new code is
39
 * made subject to such option by the copyright holder.
40
 */
41
42
package org.netbeans.modules.java.j2seproject.queries;
43
44
import java.beans.PropertyChangeEvent;
45
import java.beans.PropertyChangeListener;
46
import java.nio.charset.Charset;
47
import java.nio.charset.IllegalCharsetNameException;
48
import java.nio.charset.UnsupportedCharsetException;
49
import org.netbeans.modules.java.j2seproject.ui.customizer.J2SEProjectProperties;
50
import org.netbeans.spi.queries.FileEncodingQueryImplementation;
51
import org.netbeans.spi.project.support.ant.PropertyEvaluator;
52
import org.openide.filesystems.FileObject;
53
54
/**
55
 *
56
 * @author Tomas Zezula
57
 */
58
public class J2SEProjectEncodingQueryImpl extends FileEncodingQueryImplementation implements PropertyChangeListener {
59
60
61
    private final PropertyEvaluator eval;
62
    private Charset cache;
63
64
    /** Creates a new instance of J2SEProjectEncodingQueryImpl */
65
    public J2SEProjectEncodingQueryImpl(final PropertyEvaluator eval) {
66
        assert eval != null;
67
        this.eval = eval;
68
        this.eval.addPropertyChangeListener(this);
69
    }
70
71
    public Charset getEncoding(FileObject file) {
72
        assert file != null;
73
        synchronized (this) {
74
            if (cache != null) {
75
                return cache;
76
            }
77
        }
78
        String enc = eval.getProperty(J2SEProjectProperties.SOURCE_ENCODING);
79
        synchronized (this) {
80
            if (cache == null) {
81
                try {
82
                    //From discussion with K. Frank the project returns Charset.defaultCharset ()
83
                    //for old j2se projects. The old project used system encoding => Charset.defaultCharset ()
84
                    //should work for most users.
85
                    cache = enc == null ? Charset.defaultCharset() : Charset.forName(enc);
86
                } catch (IllegalCharsetNameException exception) {
87
                    return null;
88
                }
89
                catch (UnsupportedCharsetException exception) {
90
                    return null;
91
                }
92
            }
93
            return cache;
94
        }
95
    }
96
97
    public void propertyChange(PropertyChangeEvent event) {
98
        String propName = event.getPropertyName();
99
        if (propName == null || propName.equals(J2SEProjectProperties.SOURCE_ENCODING)) {
100
            synchronized (this) {
101
                cache = null;
102
            }
103
        }
104
    }
105
106
}
(-)a/java.j2seproject/src/org/netbeans/modules/java/j2seproject/queries/JavadocForBinaryQueryImpl.java (-203 lines)
Lines 1-203 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 1997-2007 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
 * Contributor(s):
25
 *
26
 * The Original Software is NetBeans. The Initial Developer of the Original
27
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
28
 * Microsystems, Inc. All Rights Reserved.
29
 *
30
 * If you wish your version of this file to be governed by only the CDDL
31
 * or only the GPL Version 2, indicate your decision by adding
32
 * "[Contributor] elects to include this software in this distribution
33
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
34
 * single choice of license, a recipient has the option to distribute
35
 * your version of this file under either the CDDL, the GPL Version 2 or
36
 * to extend the choice of license to its licensees as provided above.
37
 * However, if you add GPL Version 2 code and therefore, elected the GPL
38
 * Version 2 license, then the option applies only if the new code is
39
 * made subject to such option by the copyright holder.
40
 */
41
package org.netbeans.modules.java.j2seproject.queries;
42
43
import java.beans.PropertyChangeEvent;
44
import java.beans.PropertyChangeListener;
45
import java.io.File;
46
import org.netbeans.spi.project.support.ant.AntProjectHelper;
47
import org.openide.filesystems.FileUtil;
48
import java.net.URL;
49
import java.net.MalformedURLException;
50
import javax.swing.event.ChangeListener;
51
import org.netbeans.api.java.queries.JavadocForBinaryQuery;
52
import org.netbeans.spi.java.queries.JavadocForBinaryQueryImplementation;
53
import org.netbeans.spi.project.support.ant.PropertyEvaluator;
54
import org.openide.util.ChangeSupport;
55
import org.openide.util.Exceptions;
56
import org.openide.util.WeakListeners;
57
58
/**
59
 * Finds Javadoc (if it is built) corresponding to binaries in J2SE project.
60
 * @author David Konecny, Jesse Glick
61
 */
62
public class JavadocForBinaryQueryImpl implements JavadocForBinaryQueryImplementation {
63
64
    private static final String PROP_JAVADOC_DIR = "dist.javadoc.dir";  //NOI18N
65
66
    private final AntProjectHelper helper;
67
    private final PropertyEvaluator evaluator;
68
69
    public JavadocForBinaryQueryImpl(AntProjectHelper helper, PropertyEvaluator evaluator) {
70
        this.helper = helper;
71
        this.evaluator = evaluator;
72
    }
73
74
    public JavadocForBinaryQuery.Result findJavadoc(final URL binaryRoot) {
75
76
        class R implements JavadocForBinaryQuery.Result, PropertyChangeListener  {
77
78
            private final ChangeSupport changeSupport = new ChangeSupport(this);
79
            private URL[] result;
80
            private long eventId;
81
82
            public R () {
83
                JavadocForBinaryQueryImpl.this.evaluator.addPropertyChangeListener (WeakListeners.propertyChange(this,JavadocForBinaryQueryImpl.this.evaluator));
84
            }
85
86
            public  URL[] getRoots() {
87
                long _eventId;
88
                synchronized (this) {
89
                    if (this.result != null) {
90
                        return this.result;
91
                    }
92
                    _eventId = eventId;
93
                }
94
                URL[] _result;
95
                String javadocDir = evaluator.getProperty(PROP_JAVADOC_DIR);
96
                if (javadocDir != null) {
97
                    File f = helper.resolveFile(javadocDir);
98
                    try {
99
                        URL url = f.toURI().toURL();
100
                        if (!f.exists()) {
101
                            assert !url.toExternalForm().endsWith("/") : f; // NOI18N
102
                            url = new URL(url.toExternalForm() + "/"); // NOI18N
103
                        }
104
                        _result = new URL[] {url};
105
                    } catch (MalformedURLException e) {
106
                        _result = new URL[0];
107
                        Exceptions.printStackTrace(e);
108
                    }
109
                }
110
                else {
111
                    _result = new URL[0];
112
                }
113
                synchronized (this) {
114
                    if (_eventId == eventId) {
115
                        if (this.result == null) {
116
                            this.result = _result;
117
                        }
118
                        return this.result;
119
                    }
120
                    else {
121
                        return _result;
122
                    }
123
124
                }
125
126
            }
127
            public void addChangeListener(final ChangeListener l) {
128
                assert l != null;
129
                changeSupport.addChangeListener(l);
130
            }
131
            public void removeChangeListener(final ChangeListener l) {
132
                assert l != null;
133
                changeSupport.removeChangeListener(l);
134
            }
135
136
            public void propertyChange (final PropertyChangeEvent event) {
137
                if (PROP_JAVADOC_DIR.equals(event.getPropertyName())) {
138
                    synchronized (this) {
139
                        result = null;
140
                        eventId++;
141
                    }
142
                    this.changeSupport.fireChange ();
143
                }
144
            }
145
        }
146
        if (isRootOwner(binaryRoot, "build.classes.dir") || isRootOwner (binaryRoot, "dist.jar")) { //NOI18N
147
            return new R();
148
        }
149
        return null;
150
    }
151
152
    private boolean isRootOwner (URL binaryRoot, String binaryProperty) {
153
        try {
154
            if (FileUtil.getArchiveFile(binaryRoot) != null) {
155
                binaryRoot = FileUtil.getArchiveFile(binaryRoot);
156
                // XXX check whether this is really the root
157
            }
158
            String outDir = evaluator.getProperty(binaryProperty);
159
            if (outDir != null) {
160
                File f = helper.resolveFile (outDir);
161
                URL url = f.toURI().toURL();
162
                if (!f.exists() && !f.getPath().toLowerCase().endsWith(".jar")) { // NOI18N
163
                    assert !url.toExternalForm().endsWith("/") : f; // NOI18N
164
                    url = new URL(url.toExternalForm() + "/"); // NOI18N
165
                }
166
                return url.equals(binaryRoot) ||
167
                        binaryRoot.toExternalForm().startsWith(url.toExternalForm());
168
            }
169
        } catch (MalformedURLException malformedURL) {
170
            Exceptions.printStackTrace(malformedURL);
171
        }
172
        return false;
173
    }
174
175
//    private URL getJavadoc(URL binaryRoot, String binaryProperty, String javadocProperty) {
176
//        try {
177
//            if (FileUtil.getArchiveFile(binaryRoot) != null) {
178
//                binaryRoot = FileUtil.getArchiveFile(binaryRoot);
179
//            }
180
//            String outDir = evaluator.getProperty(binaryProperty);
181
//            if (outDir != null) {
182
//                File f = helper.resolveFile (outDir);
183
//                URL url = f.toURI().toURL();
184
//                if (!f.exists() && !f.getPath().toLowerCase().endsWith(".jar")) {
185
//                    assert !url.toExternalForm().endsWith("/") : f;
186
//                    url = new URL(url.toExternalForm() + "/");
187
//                }
188
//                if (url.equals(binaryRoot) ||
189
//                        binaryRoot.toExternalForm().startsWith(url.toExternalForm())) {
190
//                    String javadocDir = evaluator.getProperty(javadocProperty);
191
//                    if (javadocDir != null) {
192
//                        f = helper.resolveFile(javadocDir);
193
//                        return f.toURI().toURL();
194
//                    }
195
//                }
196
//            }
197
//        } catch (MalformedURLException malformedURL) {
198
//            ErrorManager.getDefault().notify(malformedURL);
199
//        }
200
//        return null;
201
//    }
202
203
}
(-)a/java.j2seproject/src/org/netbeans/modules/java/j2seproject/queries/SourceLevelQueryImpl.java (-85 lines)
Lines 1-85 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 1997-2007 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
 * Contributor(s):
25
 *
26
 * The Original Software is NetBeans. The Initial Developer of the Original
27
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
28
 * Microsystems, Inc. All Rights Reserved.
29
 *
30
 * If you wish your version of this file to be governed by only the CDDL
31
 * or only the GPL Version 2, indicate your decision by adding
32
 * "[Contributor] elects to include this software in this distribution
33
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
34
 * single choice of license, a recipient has the option to distribute
35
 * your version of this file under either the CDDL, the GPL Version 2 or
36
 * to extend the choice of license to its licensees as provided above.
37
 * However, if you add GPL Version 2 code and therefore, elected the GPL
38
 * Version 2 license, then the option applies only if the new code is
39
 * made subject to such option by the copyright holder.
40
 */
41
package org.netbeans.modules.java.j2seproject.queries;
42
43
import org.netbeans.modules.java.j2seproject.J2SEProjectUtil;
44
import org.netbeans.spi.java.queries.SourceLevelQueryImplementation;
45
import org.netbeans.spi.project.support.ant.AntProjectHelper;
46
import org.netbeans.spi.project.support.ant.PropertyEvaluator;
47
import org.netbeans.spi.project.support.ant.PropertyUtils;
48
import org.netbeans.spi.project.support.ant.EditableProperties;
49
import org.netbeans.api.java.platform.Specification;
50
import org.openide.filesystems.FileObject;
51
52
/**
53
 * Returns source level of project sources.
54
 * @author David Konecny
55
 */
56
public class SourceLevelQueryImpl implements SourceLevelQueryImplementation {
57
58
    private final PropertyEvaluator evaluator;
59
60
    public SourceLevelQueryImpl(PropertyEvaluator evaluator) {
61
        this.evaluator = evaluator;
62
    }
63
64
    public String getSourceLevel(FileObject javaFile) {
65
        final String activePlatform = evaluator.getProperty ("platform.active");  //NOI18N
66
        if (J2SEProjectUtil.getActivePlatform(activePlatform) != null) {
67
            String sl = evaluator.getProperty("javac.source");  //NOI18N
68
            if (sl != null && sl.length() > 0) {
69
                return sl;
70
            } else {
71
                return null;
72
            }
73
        }
74
        else {
75
            EditableProperties props = PropertyUtils.getGlobalProperties();
76
            String sl = (String) props.get("default.javac.source"); //NOI18N
77
            if (sl != null && sl.length() > 0) {
78
                return sl;
79
            } else {
80
                return null;
81
            }
82
        }
83
    }
84
85
}
(-)a/java.j2seproject/src/org/netbeans/modules/java/j2seproject/queries/UnitTestForSourceQueryImpl.java (-83 lines)
Lines 1-83 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 1997-2007 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
 * Contributor(s):
25
 *
26
 * The Original Software is NetBeans. The Initial Developer of the Original
27
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
28
 * Microsystems, Inc. All Rights Reserved.
29
 *
30
 * If you wish your version of this file to be governed by only the CDDL
31
 * or only the GPL Version 2, indicate your decision by adding
32
 * "[Contributor] elects to include this software in this distribution
33
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
34
 * single choice of license, a recipient has the option to distribute
35
 * your version of this file under either the CDDL, the GPL Version 2 or
36
 * to extend the choice of license to its licensees as provided above.
37
 * However, if you add GPL Version 2 code and therefore, elected the GPL
38
 * Version 2 license, then the option applies only if the new code is
39
 * made subject to such option by the copyright holder.
40
 */
41
42
package org.netbeans.modules.java.j2seproject.queries;
43
44
import java.net.URL;
45
import org.netbeans.api.project.FileOwnerQuery;
46
import org.netbeans.api.project.Project;
47
import org.netbeans.spi.java.queries.MultipleRootsUnitTestForSourceQueryImplementation;
48
import org.netbeans.modules.java.j2seproject.SourceRoots;
49
import org.openide.filesystems.FileObject;
50
51
public class UnitTestForSourceQueryImpl implements MultipleRootsUnitTestForSourceQueryImplementation {
52
53
    private final SourceRoots sourceRoots;
54
    private final SourceRoots testRoots;
55
56
    public UnitTestForSourceQueryImpl(SourceRoots sourceRoots, SourceRoots testRoots) {
57
        this.sourceRoots = sourceRoots;
58
        this.testRoots = testRoots;
59
    }
60
61
    public URL[] findUnitTests(FileObject source) {
62
        return find(source, sourceRoots, testRoots); // NOI18N
63
    }
64
65
    public URL[] findSources(FileObject unitTest) {
66
        return find(unitTest, testRoots, sourceRoots); // NOI18N
67
    }
68
69
    private URL[] find(FileObject file, SourceRoots from, SourceRoots to) {
70
        Project p = FileOwnerQuery.getOwner(file);
71
        if (p == null) {
72
            return null;
73
        }
74
        FileObject[] fromRoots = from.getRoots();
75
        for (int i = 0; i < fromRoots.length; i++) {
76
            if (fromRoots[i].equals(file)) {
77
                return to.getRootURLs();
78
            }
79
        }
80
        return null;
81
    }
82
83
}
(-)a/java.j2seproject/src/org/netbeans/modules/java/j2seproject/ui/ActionFilterNode.java (-1 / +1 lines)
Lines 65-74 import org.openide.util.lookup.ProxyLook Link Here
65
import org.openide.util.lookup.ProxyLookup;
65
import org.openide.util.lookup.ProxyLookup;
66
import org.netbeans.api.java.queries.JavadocForBinaryQuery;
66
import org.netbeans.api.java.queries.JavadocForBinaryQuery;
67
import org.netbeans.api.project.ProjectManager;
67
import org.netbeans.api.project.ProjectManager;
68
import org.netbeans.modules.java.api.common.ant.UpdateHelper;
68
import org.netbeans.spi.project.support.ant.AntProjectHelper;
69
import org.netbeans.spi.project.support.ant.AntProjectHelper;
69
import org.netbeans.spi.project.support.ant.EditableProperties;
70
import org.netbeans.spi.project.support.ant.EditableProperties;
70
import org.netbeans.spi.project.support.ant.PropertyUtils;
71
import org.netbeans.spi.project.support.ant.PropertyUtils;
71
import org.netbeans.modules.java.j2seproject.UpdateHelper;
72
import org.netbeans.spi.project.support.ant.ReferenceHelper;
72
import org.netbeans.spi.project.support.ant.ReferenceHelper;
73
/**
73
/**
(-)a/java.j2seproject/src/org/netbeans/modules/java/j2seproject/ui/J2SELogicalViewProvider.java (-3 / +3 lines)
Lines 69-79 import org.netbeans.api.project.ProjectU Link Here
69
import org.netbeans.api.project.ProjectUtils;
69
import org.netbeans.api.project.ProjectUtils;
70
import org.netbeans.api.project.SourceGroup;
70
import org.netbeans.api.project.SourceGroup;
71
import org.netbeans.api.project.Sources;
71
import org.netbeans.api.project.Sources;
72
import org.netbeans.modules.java.api.common.SourceRoots;
73
import org.netbeans.modules.java.api.common.ant.UpdateHelper;
72
import org.netbeans.modules.java.j2seproject.J2SEProjectUtil;
74
import org.netbeans.modules.java.j2seproject.J2SEProjectUtil;
73
import org.netbeans.modules.java.j2seproject.ui.customizer.J2SEProjectProperties;
75
import org.netbeans.modules.java.j2seproject.ui.customizer.J2SEProjectProperties;
74
import org.netbeans.modules.java.j2seproject.J2SEProject;
76
import org.netbeans.modules.java.j2seproject.J2SEProject;
75
import org.netbeans.modules.java.j2seproject.SourceRoots;
76
import org.netbeans.modules.java.j2seproject.UpdateHelper;
77
import org.netbeans.spi.java.project.support.ui.BrokenReferencesSupport;
77
import org.netbeans.spi.java.project.support.ui.BrokenReferencesSupport;
78
import org.netbeans.spi.java.project.support.ui.PackageView;
78
import org.netbeans.spi.java.project.support.ui.PackageView;
79
import org.netbeans.spi.project.ActionProvider;
79
import org.netbeans.spi.project.ActionProvider;
Lines 587-593 public class J2SELogicalViewProvider imp Link Here
587
            public void actionPerformed(ActionEvent e) {
587
            public void actionPerformed(ActionEvent e) {
588
                try {
588
                try {
589
                    helper.requestSave();
589
                    helper.requestUpdate();
590
                    BrokenReferencesSupport.showCustomizer(helper.getAntProjectHelper(), resolver, getBreakableProperties(), new String[] {J2SEProjectProperties.JAVA_PLATFORM});
590
                    BrokenReferencesSupport.showCustomizer(helper.getAntProjectHelper(), resolver, getBreakableProperties(), new String[] {J2SEProjectProperties.JAVA_PLATFORM});
591
                    run();
591
                    run();
592
                } catch (IOException ioe) {
592
                } catch (IOException ioe) {
(-)a/java.j2seproject/src/org/netbeans/modules/java/j2seproject/ui/LibrariesNode.java (-1 / +1 lines)
Lines 91-96 import org.netbeans.api.project.ant.File Link Here
91
import org.netbeans.api.project.ant.FileChooser;
91
import org.netbeans.api.project.ant.FileChooser;
92
import org.netbeans.api.project.libraries.LibraryChooser;
92
import org.netbeans.api.project.libraries.LibraryChooser;
93
import org.netbeans.api.project.libraries.LibraryManager;
93
import org.netbeans.api.project.libraries.LibraryManager;
94
import org.netbeans.modules.java.api.common.ant.UpdateHelper;
94
import org.netbeans.modules.java.j2seproject.J2SEProject;
95
import org.netbeans.modules.java.j2seproject.J2SEProject;
95
import org.netbeans.spi.project.support.ant.AntProjectHelper;
96
import org.netbeans.spi.project.support.ant.AntProjectHelper;
96
import org.netbeans.spi.project.support.ant.EditableProperties;
97
import org.netbeans.spi.project.support.ant.EditableProperties;
Lines 99-105 import org.netbeans.spi.project.support. Link Here
99
import org.netbeans.spi.project.support.ant.ReferenceHelper;
100
import org.netbeans.spi.project.support.ant.ReferenceHelper;
100
import org.netbeans.spi.java.project.support.ui.PackageView;
101
import org.netbeans.spi.java.project.support.ui.PackageView;
101
import org.netbeans.spi.java.classpath.support.ClassPathSupport;
102
import org.netbeans.spi.java.classpath.support.ClassPathSupport;
102
import org.netbeans.modules.java.j2seproject.UpdateHelper;
103
import org.netbeans.modules.java.j2seproject.ui.customizer.AntArtifactChooser;
103
import org.netbeans.modules.java.j2seproject.ui.customizer.AntArtifactChooser;
104
import org.netbeans.spi.project.libraries.support.LibrariesSupport;
104
import org.netbeans.spi.project.libraries.support.LibrariesSupport;
105
import org.openide.util.Exceptions;
105
import org.openide.util.Exceptions;
(-)a/java.j2seproject/src/org/netbeans/modules/java/j2seproject/ui/LibrariesNodeFactory.java (-4 / +2 lines)
Lines 47-62 import java.net.URI; Link Here
47
import java.net.URI;
47
import java.net.URI;
48
import java.net.URL;
48
import java.net.URL;
49
import java.util.ArrayList;
49
import java.util.ArrayList;
50
import java.util.Iterator;
51
import java.util.List;
50
import java.util.List;
52
import javax.swing.Action;
51
import javax.swing.Action;
53
import javax.swing.SwingUtilities;
52
import javax.swing.SwingUtilities;
54
import javax.swing.event.ChangeEvent;
55
import javax.swing.event.ChangeListener;
53
import javax.swing.event.ChangeListener;
56
import org.netbeans.api.project.Project;
54
import org.netbeans.api.project.Project;
55
import org.netbeans.modules.java.api.common.SourceRoots;
56
import org.netbeans.modules.java.api.common.ant.UpdateHelper;
57
import org.netbeans.modules.java.j2seproject.J2SEProject;
57
import org.netbeans.modules.java.j2seproject.J2SEProject;
58
import org.netbeans.modules.java.j2seproject.SourceRoots;
59
import org.netbeans.modules.java.j2seproject.UpdateHelper;
60
import org.netbeans.modules.java.j2seproject.ui.customizer.CustomizerLibraries;
58
import org.netbeans.modules.java.j2seproject.ui.customizer.CustomizerLibraries;
61
import org.netbeans.modules.java.j2seproject.ui.customizer.J2SEProjectProperties;
59
import org.netbeans.modules.java.j2seproject.ui.customizer.J2SEProjectProperties;
62
import org.netbeans.spi.project.support.ant.PropertyEvaluator;
60
import org.netbeans.spi.project.support.ant.PropertyEvaluator;
(-)a/java.j2seproject/src/org/netbeans/modules/java/j2seproject/ui/ProjectNode.java (-3 / +1 lines)
Lines 41-49 Link Here
41
package org.netbeans.modules.java.j2seproject.ui;
41
package org.netbeans.modules.java.j2seproject.ui;
42
import java.awt.Component;
43
import java.awt.Image;
42
import java.awt.Image;
44
import java.awt.Panel;
45
import java.io.IOException;
43
import java.io.IOException;
46
import java.net.URI;
44
import java.net.URI;
47
import java.net.URL;
45
import java.net.URL;
Lines 80-90 import org.netbeans.api.project.ant.AntA Link Here
80
import org.netbeans.api.project.ant.AntArtifact;
78
import org.netbeans.api.project.ant.AntArtifact;
81
import org.netbeans.api.project.ui.OpenProjects;
79
import org.netbeans.api.project.ui.OpenProjects;
82
import org.netbeans.api.java.queries.JavadocForBinaryQuery;
80
import org.netbeans.api.java.queries.JavadocForBinaryQuery;
81
import org.netbeans.modules.java.api.common.ant.UpdateHelper;
83
import org.netbeans.spi.project.support.ant.EditableProperties;
82
import org.netbeans.spi.project.support.ant.EditableProperties;
84
import org.netbeans.spi.project.support.ant.AntProjectHelper;
83
import org.netbeans.spi.project.support.ant.AntProjectHelper;
85
import org.netbeans.spi.project.support.ant.PropertyUtils;
84
import org.netbeans.spi.project.support.ant.PropertyUtils;
86
import org.netbeans.spi.project.support.ant.ReferenceHelper;
85
import org.netbeans.spi.project.support.ant.ReferenceHelper;
87
import org.netbeans.modules.java.j2seproject.UpdateHelper;
(-)a/java.j2seproject/src/org/netbeans/modules/java/j2seproject/ui/customizer/CustomizerLibraries.java (+1 lines)
Lines 54-59 import org.netbeans.api.java.platform.Ja Link Here
54
import org.netbeans.api.java.platform.JavaPlatform;
54
import org.netbeans.api.java.platform.JavaPlatform;
55
import org.netbeans.api.java.platform.PlatformsCustomizer;
55
import org.netbeans.api.java.platform.PlatformsCustomizer;
56
import org.netbeans.api.project.libraries.LibraryManager;
56
import org.netbeans.api.project.libraries.LibraryManager;
57
import org.netbeans.modules.java.api.common.ui.PlatformUiSupport;
57
import org.netbeans.modules.java.j2seproject.classpath.ClassPathSupport;
58
import org.netbeans.modules.java.j2seproject.classpath.ClassPathSupport;
58
import org.netbeans.modules.java.j2seproject.ui.J2SELogicalViewProvider;
59
import org.netbeans.modules.java.j2seproject.ui.J2SELogicalViewProvider;
59
import org.netbeans.modules.java.j2seproject.ui.wizards.PanelOptionsVisual;
60
import org.netbeans.modules.java.j2seproject.ui.wizards.PanelOptionsVisual;
(-)a/java.j2seproject/src/org/netbeans/modules/java/j2seproject/ui/customizer/CustomizerProviderImpl.java (-1 / +1 lines)
Lines 51-58 import java.util.Map; Link Here
51
import java.util.Map;
51
import java.util.Map;
52
import org.netbeans.api.project.Project;
52
import org.netbeans.api.project.Project;
53
import org.netbeans.api.project.ProjectUtils;
53
import org.netbeans.api.project.ProjectUtils;
54
import org.netbeans.modules.java.api.common.ant.UpdateHelper;
54
import org.netbeans.modules.java.j2seproject.J2SEProject;
55
import org.netbeans.modules.java.j2seproject.J2SEProject;
55
import org.netbeans.modules.java.j2seproject.UpdateHelper;
56
import org.netbeans.spi.project.support.ant.GeneratedFilesHelper;
56
import org.netbeans.spi.project.support.ant.GeneratedFilesHelper;
57
import org.netbeans.spi.project.support.ant.PropertyEvaluator;
57
import org.netbeans.spi.project.support.ant.PropertyEvaluator;
58
import org.netbeans.spi.project.support.ant.ReferenceHelper;
58
import org.netbeans.spi.project.support.ant.ReferenceHelper;
(-)a/java.j2seproject/src/org/netbeans/modules/java/j2seproject/ui/customizer/CustomizerRun.java (-1 / +1 lines)
Lines 69-76 import javax.swing.event.DocumentListene Link Here
69
import javax.swing.event.DocumentListener;
69
import javax.swing.event.DocumentListener;
70
import javax.swing.plaf.UIResource;
70
import javax.swing.plaf.UIResource;
71
import org.netbeans.api.project.Project;
71
import org.netbeans.api.project.Project;
72
import org.netbeans.modules.java.api.common.SourceRoots;
72
import org.netbeans.modules.java.j2seproject.J2SEProject;
73
import org.netbeans.modules.java.j2seproject.J2SEProject;
73
import org.netbeans.modules.java.j2seproject.SourceRoots;
74
import org.netbeans.modules.java.j2seproject.api.J2SERunConfigProvider;
74
import org.netbeans.modules.java.j2seproject.api.J2SERunConfigProvider;
75
import org.openide.DialogDescriptor;
75
import org.openide.DialogDescriptor;
76
import org.openide.DialogDisplayer;
76
import org.openide.DialogDisplayer;
(-)a/java.j2seproject/src/org/netbeans/modules/java/j2seproject/ui/customizer/J2SEProjectProperties.java (-3 / +5 lines)
Lines 67-76 import org.netbeans.api.queries.FileEnco Link Here
67
import org.netbeans.api.queries.FileEncodingQuery;
67
import org.netbeans.api.queries.FileEncodingQuery;
68
import org.netbeans.api.project.ProjectManager;
68
import org.netbeans.api.project.ProjectManager;
69
import org.netbeans.api.project.ProjectUtils;
69
import org.netbeans.api.project.ProjectUtils;
70
import org.netbeans.modules.java.api.common.SourceRoots;
71
import org.netbeans.modules.java.api.common.ant.UpdateHelper;
72
import org.netbeans.modules.java.api.common.ui.PlatformUiSupport;
70
import org.netbeans.modules.java.j2seproject.J2SEProject;
73
import org.netbeans.modules.java.j2seproject.J2SEProject;
74
import org.netbeans.modules.java.j2seproject.J2SEProjectType;
71
import org.netbeans.modules.java.j2seproject.J2SEProjectUtil;
75
import org.netbeans.modules.java.j2seproject.J2SEProjectUtil;
72
import org.netbeans.modules.java.j2seproject.SourceRoots;
73
import org.netbeans.modules.java.j2seproject.UpdateHelper;
74
import org.netbeans.modules.java.j2seproject.classpath.ClassPathSupport;
76
import org.netbeans.modules.java.j2seproject.classpath.ClassPathSupport;
75
import org.netbeans.spi.java.project.support.ui.IncludeExcludeVisualizer;
77
import org.netbeans.spi.java.project.support.ui.IncludeExcludeVisualizer;
76
import org.netbeans.spi.project.support.ant.AntProjectHelper;
78
import org.netbeans.spi.project.support.ant.AntProjectHelper;
Lines 496-502 public class J2SEProjectProperties { Link Here
496
        projectProperties.setProperty( RUN_TEST_CLASSPATH, run_test_cp );
498
        projectProperties.setProperty( RUN_TEST_CLASSPATH, run_test_cp );
497
        //Handle platform selection and javac.source javac.target properties
499
        //Handle platform selection and javac.source javac.target properties
498
        PlatformUiSupport.storePlatform (projectProperties, updateHelper,PLATFORM_MODEL.getSelectedItem(), JAVAC_SOURCE_MODEL.getSelectedItem());
500
        PlatformUiSupport.storePlatform (projectProperties, updateHelper, J2SEProjectType.PROJECT_CONFIGURATION_NAMESPACE, PLATFORM_MODEL.getSelectedItem(), JAVAC_SOURCE_MODEL.getSelectedItem());
499
        // Handle other special cases
501
        // Handle other special cases
500
        if ( NO_DEPENDENCIES_MODEL.isSelected() ) { // NOI18N
502
        if ( NO_DEPENDENCIES_MODEL.isSelected() ) { // NOI18N
(-)a/java.j2seproject/src/org/netbeans/modules/java/j2seproject/ui/customizer/J2SESourceRootsUi.java (-5 / +1 lines)
Lines 47-53 import java.io.File; Link Here
47
import java.io.File;
47
import java.io.File;
48
import java.net.URI;
48
import java.net.URI;
49
import java.net.URL;
49
import java.net.URL;
50
import java.util.ArrayList;
51
import java.util.Iterator;
50
import java.util.Iterator;
52
import java.util.HashSet;
51
import java.util.HashSet;
53
import java.util.Set;
52
import java.util.Set;
Lines 66-83 import org.netbeans.api.project.SourceGr Link Here
66
import org.netbeans.api.project.SourceGroup;
65
import org.netbeans.api.project.SourceGroup;
67
import org.netbeans.api.project.Sources;
66
import org.netbeans.api.project.Sources;
68
import org.netbeans.modules.java.j2seproject.J2SEProject;
67
import org.netbeans.modules.java.j2seproject.J2SEProject;
69
import org.netbeans.modules.java.j2seproject.ui.FoldersListSettings;
70
import org.netbeans.api.project.FileOwnerQuery;
68
import org.netbeans.api.project.FileOwnerQuery;
71
import org.netbeans.api.project.Project;
69
import org.netbeans.api.project.Project;
72
import org.netbeans.api.project.ProjectInformation;
70
import org.netbeans.api.project.ProjectInformation;
73
import org.netbeans.modules.java.j2seproject.SourceRoots;
71
import org.netbeans.modules.java.api.common.SourceRoots;
74
import org.openide.DialogDisplayer;
72
import org.openide.DialogDisplayer;
75
import org.openide.DialogDescriptor;
73
import org.openide.DialogDescriptor;
76
import org.openide.NotifyDescriptor;
77
import org.openide.filesystems.FileObject;
74
import org.openide.filesystems.FileObject;
78
import org.openide.filesystems.FileUtil;
75
import org.openide.filesystems.FileUtil;
79
import org.openide.util.NbBundle;
76
import org.openide.util.NbBundle;
80
import org.openide.util.HelpCtx;
81
/** Handles adding, removing, reordering of source roots.
77
/** Handles adding, removing, reordering of source roots.
82
 *
78
 *
(-)a/java.j2seproject/src/org/netbeans/modules/java/j2seproject/ui/customizer/PlatformUiSupport.java (-670 lines)
Lines 1-670 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 1997-2007 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
 * Contributor(s):
25
 *
26
 * The Original Software is NetBeans. The Initial Developer of the Original
27
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
28
 * Microsystems, Inc. All Rights Reserved.
29
 *
30
 * If you wish your version of this file to be governed by only the CDDL
31
 * or only the GPL Version 2, indicate your decision by adding
32
 * "[Contributor] elects to include this software in this distribution
33
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
34
 * single choice of license, a recipient has the option to distribute
35
 * your version of this file under either the CDDL, the GPL Version 2 or
36
 * to extend the choice of license to its licensees as provided above.
37
 * However, if you add GPL Version 2 code and therefore, elected the GPL
38
 * Version 2 license, then the option applies only if the new code is
39
 * made subject to such option by the copyright holder.
40
 */
41
42
package org.netbeans.modules.java.j2seproject.ui.customizer;
43
44
import java.awt.Component;
45
import java.beans.PropertyChangeEvent;
46
import java.beans.PropertyChangeListener;
47
import java.text.MessageFormat;
48
import java.util.ArrayList;
49
import java.util.List;
50
import java.util.Set;
51
import java.util.TreeSet;
52
import java.util.logging.Logger;
53
import javax.swing.AbstractListModel;
54
import javax.swing.ComboBoxModel;
55
import javax.swing.JButton;
56
import javax.swing.JList;
57
import javax.swing.ListCellRenderer;
58
import javax.swing.event.ListDataEvent;
59
import javax.swing.event.ListDataListener;
60
import org.netbeans.api.java.platform.JavaPlatform;
61
import org.netbeans.api.java.platform.JavaPlatformManager;
62
import org.netbeans.api.java.platform.Specification;
63
import org.netbeans.modules.java.j2seproject.J2SEProjectType;
64
import org.netbeans.modules.java.j2seproject.UpdateHelper;
65
import org.netbeans.spi.project.support.ant.EditableProperties;
66
import org.openide.DialogDisplayer;
67
import org.openide.NotifyDescriptor;
68
import org.openide.awt.HtmlRenderer;
69
import org.openide.modules.SpecificationVersion;
70
import org.openide.util.NbBundle;
71
import org.openide.util.WeakListeners;
72
import org.w3c.dom.Element;
73
import org.w3c.dom.NodeList;
74
75
/**
76
 * Support class for {@link JavaPlatform} manipulation in j2seproject customizer.
77
 * @author tzezula
78
 */
79
public class PlatformUiSupport {
80
81
    private static final SpecificationVersion JDK_5 = new SpecificationVersion ("1.5");  //NOI18N
82
    private static final SpecificationVersion JDK_6 = new SpecificationVersion ("1.6");  //NOI18N
83
    private static final Logger LOGGER = Logger.getLogger(PlatformUiSupport.class.getName());
84
85
    private PlatformUiSupport() {
86
    }
87
88
    /**
89
     * Creates {@link ComboBoxModel} of J2SE platforms.
90
     * The model listens on the {@link JavaPlatformManager} and update its
91
     * state according to changes
92
     * @param activePlatform the active project's platform
93
     * @return {@link ComboBoxModel}
94
     */
95
    public static ComboBoxModel createPlatformComboBoxModel (String activePlatform) {
96
        return new PlatformComboBoxModel (activePlatform);
97
    }
98
99
100
    /**
101
     * Creates a {@link ListCellRenderer} for rendering items of the {@link ComboBoxModel}
102
     * created by the {@link PlatformUiSupport#createPlatformComboBoxModel} method.
103
     * @return {@link ListCellRenderer}
104
     */
105
    public static ListCellRenderer createPlatformListCellRenderer () {
106
        return new PlatformListCellRenderer ();
107
    }
108
109
    /**
110
     * Stores active platform, javac.source and javac.target into the project's metadata
111
     * @param props project's shared properties
112
     * @param helper to read/update project.xml
113
     * @param platformKey the PatformKey got from the platform model
114
     * @param sourceLevel source level
115
     */
116
    public static void storePlatform (EditableProperties props, UpdateHelper helper, Object platformKey, Object sourceLevelKey) {
117
        assert platformKey instanceof PlatformKey;
118
        PlatformKey pk = (PlatformKey) platformKey;
119
        JavaPlatform platform = getPlatform(pk);
120
        //null means active broken (unresolved) platform, no need to do anything
121
        if (platform != null) {
122
            SpecificationVersion jdk13 = new SpecificationVersion ("1.3");  //NOI18N
123
            String platformAntName = (String) platform.getProperties().get("platform.ant.name");    //NOI18N
124
            assert platformAntName != null;
125
            props.put(J2SEProjectProperties.JAVA_PLATFORM, platformAntName);
126
            Element root = helper.getPrimaryConfigurationData(true);
127
            boolean defaultPlatform = pk.isDefaultPlatform();
128
            boolean changed = false;
129
            NodeList explicitPlatformNodes = root.getElementsByTagNameNS (J2SEProjectType.PROJECT_CONFIGURATION_NAMESPACE,"explicit-platform");   //NOI18N
130
            if (defaultPlatform) {
131
                if (explicitPlatformNodes.getLength()==1) {
132
                    root.removeChild(explicitPlatformNodes.item(0));
133
                    changed = true;
134
                }
135
            }
136
            else {
137
                Element explicitPlatform;
138
                switch (explicitPlatformNodes.getLength()) {
139
                    case 0:
140
                        explicitPlatform = root.getOwnerDocument().createElementNS(J2SEProjectType.PROJECT_CONFIGURATION_NAMESPACE, "explicit-platform"); //NOI18N
141
                        NodeList sourceRootNodes = root.getElementsByTagNameNS (J2SEProjectType.PROJECT_CONFIGURATION_NAMESPACE,"source-roots");   //NOI18N
142
                        assert sourceRootNodes.getLength() == 1 : "Broken project.xml file"; //NOI18N
143
                        root.insertBefore(explicitPlatform, sourceRootNodes.item(0));
144
                        changed = true;
145
                        break;
146
                    case 1:
147
                        explicitPlatform = (Element)explicitPlatformNodes.item(0);
148
                        break;
149
                    default:
150
                        throw new AssertionError("Broken project.xml file");   //NOI18N
151
                }
152
                String explicitSourceAttrValue = explicitPlatform.getAttribute("explicit-source-supported");    //NOI18N
153
                if (jdk13.compareTo(platform.getSpecification().getVersion())>=0 &&
154
                    !"false".equals(explicitSourceAttrValue)) {   //NOI18N
155
                    explicitPlatform.setAttribute("explicit-source-supported","false"); //NOI18N
156
                    changed = true;
157
                }
158
                else if (jdk13.compareTo(platform.getSpecification().getVersion())<0 &&
159
                    !"true".equals(explicitSourceAttrValue)) {  //NOI18N
160
                    explicitPlatform.setAttribute("explicit-source-supported","true"); //NOI18N
161
                    changed = true;
162
                }
163
            }
164
165
            SpecificationVersion sourceLevel;
166
            if (sourceLevelKey == null) {
167
                sourceLevel = platform.getSpecification().getVersion();
168
            }
169
            else {
170
                assert sourceLevelKey instanceof SourceLevelKey;
171
                sourceLevel = ((SourceLevelKey)sourceLevelKey).getSourceLevel();
172
            }
173
            String javacSource = sourceLevel.toString();
174
            String javacTarget = javacSource;
175
176
            //Issue #116490
177
            // Customizer value | -source | -targer
178
            // JDK 1.2            1.2        1.1
179
            // JDK 1.3            1.3        1.1
180
            // JDK 1.4            1.4        1.4
181
            // JDK 5              1.5        1.5
182
            // JDK 6              1.5        1.6
183
            // JDK 7              1.7        1.7  - should bring a new language features
184
            if (jdk13.compareTo(sourceLevel)>=0) {
185
                javacTarget = "1.1";        //NOI18N
186
            }
187
            else if (JDK_6.equals(sourceLevel)) {
188
                javacSource = JDK_5.toString();
189
            }
190
191
            if (!javacSource.equals(props.getProperty(J2SEProjectProperties.JAVAC_SOURCE))) {
192
                props.setProperty (J2SEProjectProperties.JAVAC_SOURCE, javacSource);
193
            }
194
            if (!javacTarget.equals(props.getProperty(J2SEProjectProperties.JAVAC_TARGET))) {
195
                props.setProperty (J2SEProjectProperties.JAVAC_TARGET, javacTarget);
196
            }
197
198
            if (changed) {
199
                helper.putPrimaryConfigurationData(root, true);
200
            }
201
        }
202
    }
203
204
205
    /**
206
     * Returns a {@link JavaPlatform} for an item obtained from the ComboBoxModel created by
207
     * the {@link PlatformUiSupport#createComboBoxModel} method
208
     * @param platformKey an item obtained from ComboBoxModel created by {@link PlatformUiSupport#createComboBoxModel}
209
     * @return JavaPlatform or null in case when platform is broken
210
     * @exception {@link IllegalArgumentException} is thrown in case when parameter in not an object created by
211
     * platform combobox model.
212
     */
213
    public static JavaPlatform getPlatform (Object platformKey) {
214
       if (platformKey instanceof PlatformKey) {
215
           return getPlatform ((PlatformKey)platformKey);
216
       }
217
       else {
218
           throw new IllegalArgumentException ();
219
       }
220
    }
221
222
    /**
223
     * Creates {@link ComboBoxModel} of source levels for active platform.
224
     * The model listens on the platform's {@link ComboBoxModel} and update its
225
     * state according to changes
226
     * @param platformComboBoxModel the platform's model used for listenning
227
     * @param initialValue initial source level value
228
     * @return {@link ComboBoxModel} of {@link SpecificationVersion}
229
     */
230
    public static ComboBoxModel createSourceLevelComboBoxModel (ComboBoxModel platformComboBoxModel, String initialSourceLevel, String initinalTargetLevel) {
231
        return new SourceLevelComboBoxModel (platformComboBoxModel, initialSourceLevel, initinalTargetLevel);
232
    }
233
234
235
    public static ListCellRenderer createSourceLevelListCellRenderer () {
236
        return new SourceLevelListCellRenderer ();
237
    }
238
239
240
    private static JavaPlatform getPlatform (PlatformKey platformKey) {
241
        return platformKey.platform;
242
    }
243
244
245
    /**
246
     * This class represents a  JavaPlatform in the {@link ListModel}
247
     * created by the {@link PlatformUiSupport#createPlatformComboBoxModel}
248
     * method.
249
     */
250
    private static class PlatformKey implements Comparable {
251
252
        private String name;
253
        private JavaPlatform platform;
254
255
        /**
256
         * Creates a PlatformKey for a broken platform
257
         * @param name the ant name of the broken platform
258
         */
259
        public PlatformKey (String name) {
260
            assert name != null;
261
            this.name = name;
262
        }
263
264
        /**
265
         * Creates a PlatformKey for a platform
266
         * @param platform the {@link JavaPlatform}
267
         */
268
        public PlatformKey (JavaPlatform platform) {
269
            assert platform != null;
270
            this.platform = platform;
271
        }
272
273
        public int compareTo(Object o) {
274
            return this.getDisplayName().compareTo(((PlatformKey)o).getDisplayName());
275
        }
276
277
        public boolean equals (Object other) {
278
            if (other instanceof PlatformKey) {
279
                PlatformKey otherKey = (PlatformKey)other;
280
                return (this.platform == null ? otherKey.platform == null : this.platform.equals(otherKey.platform)) &&
281
                       otherKey.getDisplayName().equals (this.getDisplayName());
282
            }
283
            else {
284
                return false;
285
            }
286
        }
287
288
        public int hashCode () {
289
            return getDisplayName ().hashCode ();
290
        }
291
292
        public String toString () {
293
            return getDisplayName ();
294
        }
295
296
        public synchronized String getDisplayName () {
297
            if (this.name == null) {
298
                this.name = this.platform.getDisplayName();
299
            }
300
            return this.name;
301
        }
302
303
        public boolean isDefaultPlatform () {
304
            if (this.platform == null) {
305
                return false;
306
            }
307
            return this.platform.equals(JavaPlatformManager.getDefault().getDefaultPlatform());
308
        }
309
310
        public boolean isBroken () {
311
            return this.platform == null;
312
        }
313
314
    }
315
316
    private static final class SourceLevelKey implements Comparable {
317
318
        final SpecificationVersion sourceLevel;
319
        final boolean broken;
320
321
        public SourceLevelKey (final SpecificationVersion sourceLevel) {
322
            this (sourceLevel, false);
323
        }
324
325
        public SourceLevelKey (final SpecificationVersion sourceLevel, final boolean broken) {
326
            assert sourceLevel != null : "Source level cannot be null";     //NOI18N
327
            this.sourceLevel = sourceLevel;
328
            this.broken = broken;
329
        }
330
331
        public SpecificationVersion getSourceLevel () {
332
            return this.sourceLevel;
333
        }
334
335
        public boolean isBroken () {
336
            return this.broken;
337
        }
338
339
        public int compareTo (final Object other) {
340
            assert other instanceof SourceLevelKey : "Illegal argument of SourceLevelKey.compareTo()";  //NOI18N
341
            SourceLevelKey otherKey = (SourceLevelKey) other;
342
            return this.sourceLevel.compareTo(otherKey.sourceLevel);
343
        }
344
345
        public @Override boolean equals (final Object other) {
346
            return (other instanceof SourceLevelKey) &&
347
                   ((SourceLevelKey)other).sourceLevel.equals(this.sourceLevel);
348
        }
349
350
        public @Override int hashCode () {
351
            return this.sourceLevel.hashCode();
352
        }
353
354
        public @Override String toString () {
355
            StringBuffer buffer = new StringBuffer ();
356
            if (this.broken) {
357
                buffer.append("Broken: ");      //NOI18N
358
            }
359
            buffer.append(this.sourceLevel.toString());
360
            return buffer.toString();
361
        }
362
363
        public String getDisplayName () {
364
            String _tmp = sourceLevel.toString();
365
            if (JDK_5.compareTo(sourceLevel)<=0) {
366
                _tmp = _tmp.replaceFirst("^1\\.([5-9]|\\d\\d+)$", "$1");        //NOI18N
367
            }
368
            return NbBundle.getMessage(PlatformUiSupport.class, "LBL_JDK",_tmp);
369
        }
370
371
    }
372
373
    private static class PlatformComboBoxModel extends AbstractListModel implements ComboBoxModel, PropertyChangeListener {
374
375
        private JavaPlatformManager pm;
376
        private PlatformKey[] platformNamesCache;
377
        private String initialPlatform;
378
        private PlatformKey selectedPlatform;
379
380
        public PlatformComboBoxModel (String initialPlatform) {
381
            this.pm = JavaPlatformManager.getDefault();
382
            this.pm.addPropertyChangeListener(WeakListeners.propertyChange(this, this.pm));
383
            this.initialPlatform = initialPlatform;
384
        }
385
386
        public int getSize () {
387
            PlatformKey[] platformNames = getPlatformNames ();
388
            return platformNames.length;
389
        }
390
391
        public Object getElementAt (int index) {
392
            PlatformKey[] platformNames = getPlatformNames ();
393
            assert index >=0 && index< platformNames.length;
394
            return platformNames[index];
395
        }
396
397
        public Object getSelectedItem () {
398
            this.getPlatformNames(); //Force setting of selectedPlatform if it is not alredy done
399
            return this.selectedPlatform;
400
        }
401
402
        public void setSelectedItem (Object obj) {
403
            this.selectedPlatform = (PlatformKey) obj;
404
            this.fireContentsChanged(this, -1, -1);
405
        }
406
407
        public void propertyChange (PropertyChangeEvent event) {
408
            if (JavaPlatformManager.PROP_INSTALLED_PLATFORMS.equals(event.getPropertyName())) {
409
                synchronized (this) {
410
                    this.platformNamesCache = null;
411
                }
412
                this.fireContentsChanged(this, -1, -1);
413
            }
414
        }
415
416
        private synchronized PlatformKey[] getPlatformNames () {
417
            if (this.platformNamesCache == null) {
418
                JavaPlatform[] platforms = pm.getPlatforms (null, new Specification("j2se",null));    //NOI18N
419
                JavaPlatform defaultPlatform = pm.getDefaultPlatform ();
420
                Set/*<PlatformKey>*/ orderedNames = new TreeSet ();
421
                boolean activeFound = false;
422
                for (int i=0; i< platforms.length; i++) {
423
                    if (platforms[i].getInstallFolders().size()>0) {
424
                        PlatformKey pk = new PlatformKey(platforms[i]);
425
                        orderedNames.add (pk);
426
                        if (!activeFound && initialPlatform != null) {
427
                            String antName = (String) platforms[i].getProperties().get("platform.ant.name");    //NOI18N
428
                            if (initialPlatform.equals(antName)) {
429
                                if (this.selectedPlatform == null) {
430
                                    this.selectedPlatform = pk;
431
                                    initialPlatform = null;
432
                                }
433
                                activeFound = true;
434
                            }
435
                        }
436
                    }
437
                }
438
                if (!activeFound) {
439
                    if (initialPlatform == null) {
440
                        if (this.selectedPlatform == null || !orderedNames.contains(this.selectedPlatform)) {
441
                            this.selectedPlatform = new PlatformKey (JavaPlatformManager.getDefault().getDefaultPlatform());
442
                        }
443
                    }
444
                    else {
445
                        PlatformKey pk = new PlatformKey (this.initialPlatform);
446
                        orderedNames.add (pk);
447
                        if (this.selectedPlatform == null) {
448
                            this.selectedPlatform = pk;
449
                        }
450
                    }
451
                }
452
                this.platformNamesCache = (PlatformKey[]) orderedNames.toArray(new PlatformKey[orderedNames.size()]);
453
            }
454
            return this.platformNamesCache;
455
        }
456
457
    }
458
459
    private static class PlatformListCellRenderer implements ListCellRenderer {
460
461
        private ListCellRenderer delegate;
462
463
        public PlatformListCellRenderer () {
464
            this.delegate = HtmlRenderer.createRenderer ();
465
        }
466
467
        public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
468
            String name;
469
            if (value == null) {
470
                name = "";  //NOI18N
471
            }
472
            else {
473
                assert value instanceof PlatformKey : "Wrong model";  //NOI18N
474
                PlatformKey key = (PlatformKey) value;
475
                if (key.isBroken()) {
476
                    name = "<html><font color=\"#A40000\">" +    //NOI18N
477
                        NbBundle.getMessage (PlatformUiSupport.class,"TXT_BrokenPlatformFmt", key.getDisplayName());
478
                }
479
                else {
480
                    name = key.getDisplayName();
481
                }
482
            }
483
            return this.delegate.getListCellRendererComponent(list, name, index, isSelected, cellHasFocus);
484
        }
485
    }
486
487
    private static class SourceLevelComboBoxModel extends AbstractListModel implements ComboBoxModel, ListDataListener {
488
489
        private static final String VERSION_PREFIX = "1.";      //The version prefix
490
        private static final int INITIAL_VERSION_MINOR = 2;     //1.2
491
492
        private SpecificationVersion selectedSourceLevel;
493
        private SpecificationVersion originalSourceLevel;
494
        private SourceLevelKey[] sourceLevelCache;
495
        private final ComboBoxModel platformComboBoxModel;
496
        private PlatformKey activePlatform;
497
498
        public SourceLevelComboBoxModel (ComboBoxModel platformComboBoxModel, String initialSourceLevel, String initialTargetLevel) {
499
            this.platformComboBoxModel = platformComboBoxModel;
500
            this.activePlatform = (PlatformKey) this.platformComboBoxModel.getSelectedItem();
501
            this.platformComboBoxModel.addListDataListener (this);
502
            if (initialSourceLevel != null && initialSourceLevel.length() > 0) {
503
                try {
504
                    this.originalSourceLevel = new SpecificationVersion (initialSourceLevel);
505
                } catch (NumberFormatException nfe) {
506
                    //If the javac.source has invalid value, do not preselect and log it
507
                    LOGGER.warning("Invalid javac.source: "+initialSourceLevel);        //NO18N
508
                }
509
            }
510
            if (initialTargetLevel != null && initialTargetLevel.length() > 0) {
511
                try {
512
                    SpecificationVersion originalTargetLevel = new SpecificationVersion (initialTargetLevel);
513
                    if (this.originalSourceLevel == null || this.originalSourceLevel.compareTo(originalTargetLevel)<0) {
514
                        this.originalSourceLevel = originalTargetLevel;
515
                    }
516
                } catch (NumberFormatException nfe) {
517
                    //If the javac.target has invalid value, do not preselect and log it
518
                    LOGGER.warning("Invalid javac.target: "+initialTargetLevel);        //NOI18N
519
                }
520
            }
521
            this.selectedSourceLevel = this.originalSourceLevel;
522
        }
523
524
        public int getSize () {
525
            SourceLevelKey[] sLevels = getSourceLevels ();
526
            return sLevels.length;
527
        }
528
529
        public Object getElementAt (int index) {
530
            SourceLevelKey[] sLevels = getSourceLevels ();
531
            assert index >=0 && index< sLevels.length;
532
            return sLevels[index];
533
        }
534
535
        public Object getSelectedItem () {
536
            SourceLevelKey[] keys = getSourceLevels ();
537
            for (int i=0; i<keys.length; i++) {
538
                if (keys[i].getSourceLevel().equals(this.selectedSourceLevel)) {
539
                    return keys[i];
540
                }
541
            }
542
            return null;
543
        }
544
545
        public void setSelectedItem (Object obj) {
546
            this.selectedSourceLevel = (obj == null ? null : ((SourceLevelKey)obj).getSourceLevel());
547
            this.fireContentsChanged(this, -1, -1);
548
        }
549
550
        public void intervalAdded(ListDataEvent e) {
551
        }
552
553
        public void intervalRemoved(ListDataEvent e) {
554
        }
555
556
        public void contentsChanged(ListDataEvent e) {
557
            PlatformKey selectedPlatform = (PlatformKey) this.platformComboBoxModel.getSelectedItem();
558
            JavaPlatform platform = getPlatform(selectedPlatform);
559
            if (platform != null) {
560
                SpecificationVersion version = platform.getSpecification().getVersion();
561
                if (this.selectedSourceLevel != null && this.selectedSourceLevel.compareTo(version)>0 &&
562
                    !shouldChangePlatform (selectedSourceLevel, version)) {
563
                    //Restore original
564
                   this.platformComboBoxModel.setSelectedItem(this.activePlatform);
565
                   return;
566
                }
567
                else {
568
                    this.originalSourceLevel = null;
569
                }
570
            }
571
            this.activePlatform = selectedPlatform;
572
            resetCache ();
573
        }
574
575
        private void resetCache () {
576
            synchronized (this) {
577
                this.sourceLevelCache = null;
578
            }
579
            this.fireContentsChanged(this, -1, -1);
580
        }
581
582
        private SourceLevelKey[] getSourceLevels () {
583
            if (this.sourceLevelCache == null) {
584
                PlatformKey selectedPlatform = (PlatformKey) this.platformComboBoxModel.getSelectedItem();
585
                JavaPlatform platform = getPlatform(selectedPlatform);
586
                List/*<SpecificationVersion>*/ sLevels = new ArrayList ();
587
                //If platform == null broken platform, the source level range is unknown
588
                //The source level combo box should be empty and disabled
589
                boolean selSourceLevelValid = false;
590
                if (platform != null) {
591
                    SpecificationVersion version = platform.getSpecification().getVersion();
592
                    int index = INITIAL_VERSION_MINOR;
593
                    SpecificationVersion template = new SpecificationVersion (VERSION_PREFIX + Integer.toString (index++));
594
                    boolean origSourceLevelValid = false;
595
596
                    while (template.compareTo(version)<=0) {
597
                        if (template.equals(this.originalSourceLevel)) {
598
                            origSourceLevelValid = true;
599
                        }
600
                        if (template.equals(this.selectedSourceLevel)) {
601
                            selSourceLevelValid = true;
602
                        }
603
                        sLevels.add (new SourceLevelKey (template));
604
                        template = new SpecificationVersion (VERSION_PREFIX + Integer.toString (index++));
605
                    }
606
                    if (this.originalSourceLevel != null && !origSourceLevelValid) {
607
                        if (originalSourceLevel.equals(this.selectedSourceLevel)) {
608
                            selSourceLevelValid = true;
609
                        }
610
                        sLevels.add (new SourceLevelKey(this.originalSourceLevel,true));
611
                    }
612
                }
613
                this.sourceLevelCache = (SourceLevelKey[]) sLevels.toArray(new SourceLevelKey[sLevels.size()]);
614
                if (!selSourceLevelValid) {
615
                    this.selectedSourceLevel = this.sourceLevelCache.length == 0 ?
616
                        null : this.sourceLevelCache[this.sourceLevelCache.length-1].getSourceLevel();
617
                }
618
            }
619
            return this.sourceLevelCache;
620
        }
621
622
        private static boolean shouldChangePlatform (SpecificationVersion selectedSourceLevel, SpecificationVersion platformSourceLevel) {
623
            JButton changeOption = new JButton (NbBundle.getMessage(PlatformUiSupport.class, "CTL_ChangePlatform"));
624
            changeOption.getAccessibleContext().setAccessibleDescription(NbBundle.getMessage(PlatformUiSupport.class, "AD_ChangePlatform"));
625
            String message = MessageFormat.format (NbBundle.getMessage(PlatformUiSupport.class,"TXT_ChangePlatform"),new Object[] {
626
                selectedSourceLevel.toString(),
627
                platformSourceLevel.toString(),
628
            });
629
            return DialogDisplayer.getDefault().notify(
630
                new NotifyDescriptor (message,
631
                        NbBundle.getMessage(PlatformUiSupport.class,"TXT_ChangePlatformTitle"),
632
                        NotifyDescriptor.DEFAULT_OPTION,
633
                        NotifyDescriptor.WARNING_MESSAGE,
634
                        new Object[] {
635
                            changeOption,
636
                            NotifyDescriptor.CANCEL_OPTION
637
                        },
638
                        changeOption)) == changeOption;
639
        }
640
    }
641
642
    private static class SourceLevelListCellRenderer implements ListCellRenderer {
643
644
        ListCellRenderer delegate;
645
646
        public SourceLevelListCellRenderer () {
647
            this.delegate = HtmlRenderer.createRenderer();
648
        }
649
650
        public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
651
            String message;
652
            if (value == null) {
653
                message = "";   //NOI18N
654
            }
655
            else {
656
                assert value instanceof SourceLevelKey;
657
                SourceLevelKey key = (SourceLevelKey) value;
658
                if (key.isBroken()) {
659
                    message = "<html><font color=\"#A40000\">" +    //NOI18N
660
                        NbBundle.getMessage(PlatformUiSupport.class,"TXT_InvalidSourceLevel",key.getDisplayName());
661
                }
662
                else {
663
                    message = key.getDisplayName();
664
                }
665
            }
666
            return this.delegate.getListCellRendererComponent(list, message, index, isSelected, cellHasFocus);
667
        }
668
    }
669
670
}
(-)a/java.j2seproject/test/unit/src/org/netbeans/modules/java/j2seproject/SourceRootsTest.java (+1 lines)
Lines 55-60 import org.netbeans.api.project.ProjectM Link Here
55
import org.netbeans.api.project.ProjectManager;
55
import org.netbeans.api.project.ProjectManager;
56
import org.netbeans.api.project.Project;
56
import org.netbeans.api.project.Project;
57
import org.netbeans.api.project.TestUtil;
57
import org.netbeans.api.project.TestUtil;
58
import org.netbeans.modules.java.api.common.SourceRoots;
58
import org.netbeans.spi.project.support.ant.AntProjectHelper;
59
import org.netbeans.spi.project.support.ant.AntProjectHelper;
59
import org.netbeans.spi.project.support.ant.EditableProperties;
60
import org.netbeans.spi.project.support.ant.EditableProperties;
60
import org.w3c.dom.Element;
61
import org.w3c.dom.Element;
(-)a/nbbuild/cluster.properties (+1 lines)
Lines 387-392 nb.cluster.java=\ Link Here
387
        java.platform,\
387
        java.platform,\
388
        java.preprocessorbridge,\
388
        java.preprocessorbridge,\
389
        java.project,\
389
        java.project,\
390
        java.commonapi,\
390
        java.source,\
391
        java.source,\
391
        java.sourceui,\
392
        java.sourceui,\
392
        javadoc,\
393
        javadoc,\
(-)a/nbbuild/javadoctools/links.xml (+1 lines)
Lines 163-165 made subject to such option by the copyr Link Here
163
<link href="${javadoc.docs.org-netbeans-modules-xml-retriever}" offline="true" packagelistloc="${netbeans.javadoc.dir}/org-netbeans-modules-xml-retriever"/>
163
<link href="${javadoc.docs.org-netbeans-modules-xml-retriever}" offline="true" packagelistloc="${netbeans.javadoc.dir}/org-netbeans-modules-xml-retriever"/>
164
<link href="${javadoc.docs.org-netbeans-modules-server}" offline="true" packagelistloc="${netbeans.javadoc.dir}/org-netbeans-modules-server"/>
164
<link href="${javadoc.docs.org-netbeans-modules-server}" offline="true" packagelistloc="${netbeans.javadoc.dir}/org-netbeans-modules-server"/>
165
<link href="${javadoc.docs.org-netbeans-modules-websvc-serviceapi}" offline="true" packagelistloc="${netbeans.javadoc.dir}/org-netbeans-modules-websvc-serviceapi"/>
165
<link href="${javadoc.docs.org-netbeans-modules-websvc-serviceapi}" offline="true" packagelistloc="${netbeans.javadoc.dir}/org-netbeans-modules-websvc-serviceapi"/>
166
<link href="${javadoc.docs.org-netbeans-modules-java-api-common}" offline="true" packagelistloc="${netbeans.javadoc.dir}/org-netbeans-modules-java-api-common"/>
(-)a/nbbuild/javadoctools/properties.xml (+1 lines)
Lines 161-163 made subject to such option by the copyr Link Here
161
<property name="javadoc.docs.org-netbeans-modules-xml-retriever" value="${javadoc.web.root}/org-netbeans-modules-xml-retriever"/>
161
<property name="javadoc.docs.org-netbeans-modules-xml-retriever" value="${javadoc.web.root}/org-netbeans-modules-xml-retriever"/>
162
<property name="javadoc.docs.org-netbeans-modules-server" value="${javadoc.web.root}/org-netbeans-modules-server"/>
162
<property name="javadoc.docs.org-netbeans-modules-server" value="${javadoc.web.root}/org-netbeans-modules-server"/>
163
<property name="javadoc.docs.org-netbeans-modules-websvc-serviceapi" value="${javadoc.web.root}/org-netbeans-modules-websvc-serviceapi"/>
163
<property name="javadoc.docs.org-netbeans-modules-websvc-serviceapi" value="${javadoc.web.root}/org-netbeans-modules-websvc-serviceapi"/>
164
<property name="javadoc.docs.org-netbeans-modules-java-api-common" value="${javadoc.web.root}/org-netbeans-modules-java-api-common"/>
(-)a/nbbuild/javadoctools/replaces.xml (+1 lines)
Lines 161-163 made subject to such option by the copyr Link Here
161
<replacefilter token="@org-netbeans-modules-xml-retriever@" value="${javadoc.docs.org-netbeans-modules-xml-retriever}"/>
161
<replacefilter token="@org-netbeans-modules-xml-retriever@" value="${javadoc.docs.org-netbeans-modules-xml-retriever}"/>
162
<replacefilter token="@org-netbeans-modules-server@" value="${javadoc.docs.org-netbeans-modules-server}"/>
162
<replacefilter token="@org-netbeans-modules-server@" value="${javadoc.docs.org-netbeans-modules-server}"/>
163
<replacefilter token="@org-netbeans-modules-websvc-serviceapi@" value="${javadoc.docs.org-netbeans-modules-websvc-serviceapi}"/>
163
<replacefilter token="@org-netbeans-modules-websvc-serviceapi@" value="${javadoc.docs.org-netbeans-modules-websvc-serviceapi}"/>
164
<replacefilter token="@org-netbeans-modules-java-api-common@" value="${javadoc.docs.org-netbeans-modules-java-api-common}"/>
(-)a/web.project/nbproject/project.xml (+9 lines)
Lines 200-205 made subject to such option by the copyr Link Here
200
                    <run-dependency>
200
                    <run-dependency>
201
                        <release-version>4</release-version>
201
                        <release-version>4</release-version>
202
                        <specification-version>1.29</specification-version>
202
                        <specification-version>1.29</specification-version>
203
                    </run-dependency>
204
                </dependency>
205
                <dependency>
206
                    <code-name-base>org.netbeans.modules.java.api.common</code-name-base>
207
                    <build-prerequisite/>
208
                    <compile-dependency/>
209
                    <run-dependency>
210
                        <release-version>0-1</release-version>
211
                        <specification-version>1.0</specification-version>
203
                    </run-dependency>
212
                    </run-dependency>
204
                </dependency>
213
                </dependency>
205
                <dependency>
214
                <dependency>
(-)a/web.project/src/org/netbeans/modules/web/project/ProjectWebModule.java (+1 lines)
Lines 82-87 import org.netbeans.modules.j2ee.dd.spi. Link Here
82
import org.netbeans.modules.j2ee.dd.spi.web.WebAppMetadataModelFactory;
82
import org.netbeans.modules.j2ee.dd.spi.web.WebAppMetadataModelFactory;
83
import org.netbeans.modules.j2ee.dd.spi.webservices.WebservicesMetadataModelFactory;
83
import org.netbeans.modules.j2ee.dd.spi.webservices.WebservicesMetadataModelFactory;
84
import org.netbeans.modules.j2ee.metadata.model.api.MetadataModel;
84
import org.netbeans.modules.j2ee.metadata.model.api.MetadataModel;
85
import org.netbeans.modules.java.api.common.ant.UpdateHelper;
85
import org.netbeans.modules.websvc.spi.webservices.WebServicesConstants;
86
import org.netbeans.modules.websvc.spi.webservices.WebServicesConstants;
86
/** A web module implementation on top of project.
87
/** A web module implementation on top of project.
(-)a/web.project/src/org/netbeans/modules/web/project/SourceRoots.java (-438 lines)
Lines 1-438 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 1997-2007 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
 * Contributor(s):
25
 *
26
 * The Original Software is NetBeans. The Initial Developer of the Original
27
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
28
 * Microsystems, Inc. All Rights Reserved.
29
 *
30
 * If you wish your version of this file to be governed by only the CDDL
31
 * or only the GPL Version 2, indicate your decision by adding
32
 * "[Contributor] elects to include this software in this distribution
33
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
34
 * single choice of license, a recipient has the option to distribute
35
 * your version of this file under either the CDDL, the GPL Version 2 or
36
 * to extend the choice of license to its licensees as provided above.
37
 * However, if you add GPL Version 2 code and therefore, elected the GPL
38
 * Version 2 license, then the option applies only if the new code is
39
 * made subject to such option by the copyright holder.
40
 */
41
package org.netbeans.modules.web.project;
42
43
import java.beans.PropertyChangeEvent;
44
import java.beans.PropertyChangeListener;
45
import java.beans.PropertyChangeSupport;
46
import java.io.File;
47
import java.net.MalformedURLException;
48
import java.net.URL;
49
import java.net.URI;
50
import java.util.Arrays;
51
import java.util.ArrayList;
52
import java.util.Collections;
53
import java.util.Iterator;
54
import java.util.List;
55
import java.util.Map;
56
import java.util.HashMap;
57
import java.text.MessageFormat;
58
59
import org.openide.filesystems.FileObject;
60
import org.openide.filesystems.FileUtil;
61
import org.openide.util.NbBundle;
62
import org.openide.util.WeakListeners;
63
import org.openide.util.Mutex;
64
65
import org.w3c.dom.Element;
66
import org.w3c.dom.NodeList;
67
import org.w3c.dom.Document;
68
69
import org.netbeans.spi.project.support.ant.AntProjectHelper;
70
import org.netbeans.spi.project.support.ant.AntProjectEvent;
71
import org.netbeans.spi.project.support.ant.AntProjectListener;
72
import org.netbeans.spi.project.support.ant.EditableProperties;
73
import org.netbeans.spi.project.support.ant.PropertyEvaluator;
74
import org.netbeans.spi.project.support.ant.ReferenceHelper;
75
import org.netbeans.api.project.ProjectManager;
76
import org.netbeans.api.java.project.JavaProjectConstants;
77
import org.openide.util.Exceptions;
78
79
/**
80
 * This class represents a project source roots. It is used to obtain roots as Ant properties, FileObject's
81
 * or URLs.
82
 * @author Tomas Zezula
83
 */
84
public final class SourceRoots {
85
86
    public static final String PROP_ROOT_PROPERTIES = "rootProperties";    //NOI18N
87
    public static final String PROP_ROOTS = "roots";   //NOI18N
88
89
    public static final String DEFAULT_SOURCE_LABEL = NbBundle.getMessage(SourceRoots.class, "NAME_src.dir");
90
    public static final String DEFAULT_TEST_LABEL = NbBundle.getMessage(SourceRoots.class, "NAME_test.src.dir");
91
92
    private final UpdateHelper helper;
93
    private final PropertyEvaluator evaluator;
94
    private final ReferenceHelper refHelper;
95
    private final String elementName;
96
    private final String newRootNameTemplate;
97
    private List/*<String>*/ sourceRootProperties;
98
    private List/*<String>*/ sourceRootNames;
99
    private List/*<FileObject>*/ sourceRoots;
100
    private List/*<URL>*/ sourceRootURLs;
101
    private final PropertyChangeSupport support;
102
    private final ProjectMetadataListener listener;
103
    private final boolean isTest;
104
    private final File projectDir;
105
106
    /**
107
     * Creates new SourceRoots
108
     * @param helper
109
     * @param evaluator
110
     * @param elementName the name of XML element under which are declared the roots
111
     * @param newRootNameTemplate template for new property name of source root
112
     */
113
    SourceRoots (UpdateHelper helper, PropertyEvaluator evaluator, ReferenceHelper refHelper, String elementName, boolean isTest, String newRootNameTemplate) {
114
        assert helper != null && evaluator != null && refHelper != null && elementName != null && newRootNameTemplate != null;
115
        this.helper = helper;
116
        this.evaluator = evaluator;
117
        this.refHelper = refHelper;
118
        this.elementName = elementName;
119
        this.isTest = isTest;
120
        this.newRootNameTemplate = newRootNameTemplate;
121
        this.projectDir = FileUtil.toFile(this.helper.getAntProjectHelper().getProjectDirectory());
122
        this.support = new PropertyChangeSupport(this);
123
        this.listener = new ProjectMetadataListener();
124
        this.evaluator.addPropertyChangeListener (WeakListeners.propertyChange(this.listener,this.evaluator));
125
        this.helper.getAntProjectHelper().addAntProjectListener ((AntProjectListener)WeakListeners.create(AntProjectListener.class, this.listener,this.helper));
126
    }
127
128
129
    /**
130
     * Returns the display names of soruce roots
131
     * The returned array has the same length as an array returned by the getRootProperties.
132
     * It may contain empty strings but not null.
133
     * @return an array of String
134
     */
135
    public   String[] getRootNames () {
136
        return (String[]) ProjectManager.mutex().readAccess(new Mutex.Action() {
137
            public Object run() {
138
                synchronized (SourceRoots.this) {
139
                    if (sourceRootNames == null) {
140
                        readProjectMetadata();
141
                    }
142
                }
143
                return sourceRootNames.toArray (new String[sourceRootNames.size()]);
144
            }
145
        });
146
    }
147
148
    /**
149
     * Returns names of Ant properties in the project.properties file holding the source roots.
150
     * @return an array of String
151
     */
152
    public String[] getRootProperties () {
153
        return (String[]) ProjectManager.mutex().readAccess(new Mutex.Action() {
154
            public Object run() {
155
                synchronized (SourceRoots.this) {
156
                    if (sourceRootProperties == null) {
157
                        readProjectMetadata();
158
                    }
159
                }
160
                return sourceRootProperties.toArray (new String[sourceRootProperties.size()]);
161
            }
162
        });
163
    }
164
165
    /**
166
     * Returns the source roots
167
     * @return an array of FileObject
168
     */
169
    public FileObject[] getRoots () {
170
        return (FileObject[]) ProjectManager.mutex().readAccess(new Mutex.Action () {
171
                public Object run () {
172
                    synchronized (this) {
173
                        //Local caching
174
                        if (sourceRoots == null) {
175
                            String[] srcProps = getRootProperties();
176
                            List result = new ArrayList();
177
                            for (int i = 0; i<srcProps.length; i++) {
178
                                String prop = evaluator.getProperty(srcProps[i]);
179
                                if (prop != null) {
180
                                    FileObject f = helper.getAntProjectHelper().resolveFileObject(prop);
181
                                    if (f == null) {
182
                                        continue;
183
                                    }
184
                                    if (FileUtil.isArchiveFile(f)) {
185
                                        f = FileUtil.getArchiveRoot(f);
186
                                    }
187
                                    result.add(f);
188
                                }
189
                            }
190
                            sourceRoots = Collections.unmodifiableList(result);
191
                        }
192
                    }
193
                    return sourceRoots.toArray(new FileObject[sourceRoots.size()]);
194
                }
195
        });
196
    }
197
198
    /**
199
     * Returns the source roots as URLs.
200
     * @return an array of URL
201
     */
202
    public URL[] getRootURLs() {
203
        return (URL[]) ProjectManager.mutex().readAccess(new Mutex.Action () {
204
            public Object run() {
205
                synchronized (this) {
206
                    //Local caching
207
                    if (sourceRootURLs == null) {
208
                        String[] srcProps = getRootProperties();
209
                        List result = new ArrayList();
210
                        for (int i = 0; i<srcProps.length; i++) {
211
                            String prop = evaluator.getProperty(srcProps[i]);
212
                            if (prop != null) {
213
                                File f = helper.getAntProjectHelper().resolveFile(prop);
214
                                try {
215
                                    result.add(WebProjectUtil.getRootURL(f,null));
216
                                } catch (MalformedURLException e) {
217
                                    Exceptions.printStackTrace(e);
218
                                }
219
                            }
220
                        }
221
                        sourceRootURLs = Collections.unmodifiableList(result);
222
                    }
223
                }
224
                return sourceRootURLs.toArray(new URL[sourceRootURLs.size()]);
225
            }
226
        });
227
    }
228
229
    /**
230
     * Adds PropertyChangeListener
231
     * @param listener
232
     */
233
    public void addPropertyChangeListener (PropertyChangeListener listener) {
234
        this.support.addPropertyChangeListener (listener);
235
    }
236
237
    /**
238
     * Removes PropertyChangeListener
239
     * @param listener
240
     */
241
    public void removePropertyChangeListener (PropertyChangeListener listener) {
242
        this.support.removePropertyChangeListener (listener);
243
    }
244
245
246
    /**
247
     * Replaces the current roots by the new ones
248
     * @param roots the URLs of new roots
249
     * @param labels the names of roots
250
     */
251
    public void putRoots (final URL[] roots, final String[] labels) {
252
        ProjectManager.mutex().writeAccess(
253
                new Mutex.Action () {
254
                    public Object run() {
255
                        String[] originalProps = getRootProperties();
256
                        URL[] originalRoots = getRootURLs();
257
                        Map oldRoots2props = new HashMap ();
258
                        for (int i=0; i<originalProps.length;i++) {
259
                            oldRoots2props.put (originalRoots[i],originalProps[i]);
260
                        }
261
                        Map newRoots2lab = new HashMap();
262
                        for (int i=0; i<roots.length;i++) {
263
                            newRoots2lab.put (roots[i],labels[i]);
264
                        }
265
                        Element cfgEl = helper.getPrimaryConfigurationData(true);
266
                        NodeList nl = cfgEl.getElementsByTagNameNS(WebProjectType.PROJECT_CONFIGURATION_NAMESPACE, elementName);
267
                        assert nl.getLength() == 1 : "Illegal project.xml"; //NOI18N
268
                        Element ownerElement = (Element) nl.item(0);
269
                        //Remove all old roots
270
                        NodeList rootsNodes = ownerElement.getElementsByTagNameNS(WebProjectType.PROJECT_CONFIGURATION_NAMESPACE, "root");    //NOI18N
271
                        while (rootsNodes.getLength()>0) {
272
                            Element root = (Element) rootsNodes.item(0);
273
                            ownerElement.removeChild(root);
274
                        }
275
                        //Remove all unused root properties
276
                        List newRoots = Arrays.asList(roots);
277
                        Map propsToRemove = new HashMap (oldRoots2props);
278
                        propsToRemove.keySet().removeAll(newRoots);
279
                        EditableProperties props = helper.getProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH);
280
                        for (Iterator it = propsToRemove.values().iterator(); it.hasNext();) {
281
                            String propName = (String) it.next ();
282
                            props.remove(propName);
283
                        }
284
                        helper.putProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH,props);
285
                        //Add the new roots
286
                        Document doc = ownerElement.getOwnerDocument();
287
                        oldRoots2props.keySet().retainAll(newRoots);
288
                        for (Iterator it = newRoots.iterator(); it.hasNext();) {
289
                            URL newRoot = (URL) it.next ();
290
                            String rootName = (String) oldRoots2props.get (newRoot);
291
                            if (rootName == null) {
292
                                //Root is new generate property for it
293
                                props = helper.getProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH);
294
                                String[] names = newRoot.getPath().split("/");  //NOI18N
295
                                rootName = MessageFormat.format(newRootNameTemplate, new Object[]{names[names.length-1],""});    //NOI18N
296
                                int rootIndex = 1;
297
                                while (props.containsKey(rootName)) {
298
                                    rootIndex++;
299
                                    rootName = MessageFormat.format(newRootNameTemplate,new Object[]{names[names.length-1], Integer.valueOf(rootIndex)});
300
                                }
301
                                File f = FileUtil.normalizeFile(new File(URI.create(newRoot.toExternalForm())));
302
                                File projDir = FileUtil.toFile(helper.getAntProjectHelper().getProjectDirectory());
303
                                String path = f.getAbsolutePath();
304
                                String prjPath = projDir.getAbsolutePath()+File.separatorChar;
305
                                if (path.startsWith(prjPath)) {
306
                                    path = path.substring(prjPath.length());
307
                                }
308
                                else {
309
                                    path = refHelper.createForeignFileReference(f, JavaProjectConstants.SOURCES_TYPE_JAVA);
310
                                    props = helper.getProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH);
311
                                }
312
                                props.put(rootName,path);
313
                                helper.putProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH,props);
314
                            }
315
                            Element newRootNode = doc.createElementNS(WebProjectType.PROJECT_CONFIGURATION_NAMESPACE, "root"); //NOI18N
316
                            newRootNode.setAttribute("id",rootName);    //NOI18N
317
                            String label = (String) newRoots2lab.get (newRoot);
318
                            if (label != null && label.length()>0 && !label.equals (getRootDisplayName(null,rootName))) { //NOI18N
319
                                newRootNode.setAttribute("name",label); //NOI18N
320
                            }
321
                            ownerElement.appendChild (newRootNode);
322
                        }
323
                        helper.putPrimaryConfigurationData(cfgEl,true);
324
                        return null;
325
                    }
326
                }
327
        );
328
    }
329
330
    /**
331
     * Translates root name into display name of source/test root
332
     * @param rootName the name of root got from {@link SourceRoots#getRootNames}
333
     * @param propName the name of property the root is stored in
334
     * @return the label to be displayed
335
     */
336
    public String getRootDisplayName (String rootName, String propName) {
337
        if (rootName == null || rootName.length() ==0) {
338
            //If the prop is src.dir use the default name
339
            if (isTest && "test.src.dir".equals(propName)) {    //NOI18N
340
                rootName = DEFAULT_TEST_LABEL;
341
            }
342
            else if (!isTest && "src.dir".equals(propName)) {   //NOI18N
343
                rootName = DEFAULT_SOURCE_LABEL;
344
            }
345
            else {
346
                //If the name is not given, it should be either a relative path in the project dir
347
                //or absolute path when the root is not under the project dir
348
                String propValue = evaluator.getProperty(propName);
349
                File sourceRoot = propValue == null ? null : helper.getAntProjectHelper().resolveFile(propValue);
350
                rootName = createInitialDisplayName(sourceRoot);
351
            }
352
        }
353
        return rootName;
354
    }
355
356
    public String createInitialDisplayName (File sourceRoot) {
357
        String rootName;
358
        if (sourceRoot != null) {
359
        String srPath = sourceRoot.getAbsolutePath();
360
        String pdPath = projectDir.getAbsolutePath() + File.separatorChar;
361
        if (srPath.startsWith(pdPath)) {
362
            rootName = srPath.substring(pdPath.length());
363
        }
364
        else {
365
            rootName = sourceRoot.getAbsolutePath();
366
        }
367
        }
368
        else {
369
            rootName = isTest ? DEFAULT_TEST_LABEL : DEFAULT_SOURCE_LABEL;
370
        }
371
        return rootName;
372
    }
373
374
    private void resetCache (boolean isXMLChange, String propName) {
375
        boolean fire = false;
376
        synchronized (this) {
377
            //In case of change reset local cache
378
            if (isXMLChange) {
379
                this.sourceRootProperties = null;
380
                this.sourceRootNames = null;
381
                this.sourceRoots = null;
382
                this.sourceRootURLs = null;
383
                fire = true;
384
            } else if (propName == null || (sourceRootProperties != null && sourceRootProperties.contains(propName))) {
385
                this.sourceRoots = null;
386
                this.sourceRootURLs = null;
387
                fire = true;
388
            }
389
        }
390
        if (fire) {
391
            if (isXMLChange) {
392
                this.support.firePropertyChange (PROP_ROOT_PROPERTIES,null,null);
393
            }
394
            this.support.firePropertyChange (PROP_ROOTS,null,null);
395
        }
396
    }
397
398
    private void readProjectMetadata () {
399
        Element cfgEl = helper.getPrimaryConfigurationData(true);
400
        NodeList nl = cfgEl.getElementsByTagNameNS(WebProjectType.PROJECT_CONFIGURATION_NAMESPACE, elementName);
401
        assert nl.getLength() == 0 || nl.getLength() == 1 : "Illegal project.xml"; //NOI18N
402
        List rootProps = new ArrayList ();
403
        List rootNames = new ArrayList ();
404
        // It can be 0 in the case when the project is created by WebProjectGenerator and not yet customized
405
        if (nl.getLength()==1) {
406
            NodeList roots = ((Element)nl.item(0)).getElementsByTagNameNS(WebProjectType.PROJECT_CONFIGURATION_NAMESPACE, "root");    //NOI18N
407
            for (int i=0; i<roots.getLength(); i++) {
408
                Element root = (Element) roots.item(i);
409
                String value = root.getAttribute("id");  //NOI18N
410
                assert value.length() > 0 : "Illegal project.xml";
411
                rootProps.add(value);
412
                value = root.getAttribute("name");  //NOI18N
413
                rootNames.add (value);
414
            }
415
        }
416
        this.sourceRootProperties = Collections.unmodifiableList(rootProps);
417
        this.sourceRootNames = Collections.unmodifiableList(rootNames);
418
    }
419
420
    private class ProjectMetadataListener implements PropertyChangeListener,AntProjectListener {
421
422
        public void propertyChange(PropertyChangeEvent evt) {
423
            resetCache (false,evt.getPropertyName());
424
        }
425
426
        public void configurationXmlChanged(AntProjectEvent ev) {
427
            resetCache (true,null);
428
        }
429
430
        public void propertiesChanged(AntProjectEvent ev) {
431
            //Handled by propertyChange
432
        }
433
    }
434
435
    public boolean isTest() {
436
        return isTest;
437
    }
438
}
(-)a/web.project/src/org/netbeans/modules/web/project/UpdateHelper.java (-563 lines)
Lines 1-563 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 1997-2007 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
 * Contributor(s):
25
 *
26
 * The Original Software is NetBeans. The Initial Developer of the Original
27
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
28
 * Microsystems, Inc. All Rights Reserved.
29
 *
30
 * If you wish your version of this file to be governed by only the CDDL
31
 * or only the GPL Version 2, indicate your decision by adding
32
 * "[Contributor] elects to include this software in this distribution
33
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
34
 * single choice of license, a recipient has the option to distribute
35
 * your version of this file under either the CDDL, the GPL Version 2 or
36
 * to extend the choice of license to its licensees as provided above.
37
 * However, if you add GPL Version 2 code and therefore, elected the GPL
38
 * Version 2 license, then the option applies only if the new code is
39
 * made subject to such option by the copyright holder.
40
 */
41
42
package org.netbeans.modules.web.project;
43
44
import java.io.IOException;
45
import java.net.URL;
46
import java.util.ArrayList;
47
import java.util.Iterator;
48
import java.util.List;
49
import javax.swing.JButton;
50
import org.netbeans.api.project.libraries.LibraryManager;
51
import org.netbeans.modules.web.project.api.WebProjectUtilities;
52
import org.netbeans.modules.web.project.classpath.ClassPathSupport;
53
import org.netbeans.modules.web.project.ui.customizer.WebProjectProperties;
54
import org.netbeans.spi.project.support.ant.ReferenceHelper;
55
import org.openide.filesystems.FileObject;
56
import org.openide.filesystems.FileUtil;
57
import org.openide.filesystems.Repository;
58
import org.w3c.dom.Comment;
59
import org.w3c.dom.Document;
60
import org.w3c.dom.Element;
61
import org.w3c.dom.NamedNodeMap;
62
import org.w3c.dom.Node;
63
import org.w3c.dom.NodeList;
64
import org.w3c.dom.Text;
65
import org.openide.DialogDisplayer;
66
import org.openide.NotifyDescriptor;
67
import org.openide.util.NbBundle;
68
import org.openide.util.Mutex;
69
import org.netbeans.api.project.Project;
70
import org.netbeans.api.project.ProjectManager;
71
import org.netbeans.spi.project.AuxiliaryConfiguration;
72
import org.netbeans.spi.project.support.ant.AntProjectHelper;
73
import org.netbeans.spi.project.support.ant.EditableProperties;
74
import org.openide.filesystems.URLMapper;
75
import org.openide.util.Exceptions;
76
77
78
/**
79
 * Proxy for the AntProjectHelper which defers the update of the project metadata
80
 * to explicit user action. Currently it is hard coded for update from
81
 * "http://www.netbeans.org/ns/web-project/1" to "http://www.netbeans.org/ns/web-project/2".
82
 * In future it should define plugable SPI.
83
 */
84
public class UpdateHelper {
85
86
    private static final boolean TRANSPARENT_UPDATE = Boolean.getBoolean("webproject.transparentUpdate"); //NOI18N
87
    private static final String BUILD_NUMBER = System.getProperty("netbeans.buildnumber"); // NOI18N
88
89
    private final Project project;
90
    private final AntProjectHelper helper;
91
    private final AuxiliaryConfiguration cfg;
92
    private final Notifier notifier;
93
    private boolean alreadyAskedInWriteAccess;
94
    private Boolean isCurrent;
95
    private EditableProperties cachedProperties;
96
    private Element cachedElement;
97
    private static final String TAG_MINIMUM_ANT_VERSION = "minimum-ant-version"; // NOI18N
98
    private static final String TAG_FILE = "file"; //NOI18N
99
    private static final String TAG_LIBRARY = "library"; //NOI18N
100
    private static final String ATTR_FILES = "files"; //NOI18N
101
    private static final String ATTR_DIRS = "dirs"; //NOI18N
102
103
    /**
104
     * Creates new UpdateHelper
105
     * @param project
106
     * @param helper AntProjectHelper
107
     * @param cfg AuxiliaryConfiguration
108
     * @param notifier used to ask user about project update
109
     */
110
    UpdateHelper (Project project, AntProjectHelper helper, AuxiliaryConfiguration cfg, Notifier notifier) {
111
        assert project != null && helper != null && cfg != null && notifier != null;
112
        this.project = project;
113
        this.helper = helper;
114
        this.cfg = cfg;
115
        this.notifier = notifier;
116
    }
117
118
    /**
119
     * Returns the AntProjectHelper.getProperties(), {@link AntProjectHelper#getProperties(String)}
120
     * @param path a relative URI in the project directory.
121
     * @return a set of properties
122
     */
123
    public EditableProperties getProperties (final String path) {
124
        //Properties are the same in both webproject/1 and webproject/2
125
        return (EditableProperties) ProjectManager.mutex().readAccess(new Mutex.Action (){
126
            public Object run() {
127
                if (!isCurrent() && AntProjectHelper.PROJECT_PROPERTIES_PATH.equals(path)) { //Only project properties were changed
128
                    return getUpdatedProjectProperties ();
129
                }
130
                else {
131
                    return helper.getProperties(path);
132
                }
133
            }
134
        });
135
    }
136
137
    /**
138
     * In the case that the project is of current version or the properties are not {@link AntProjectHelper#PROJECT_PROPERTIES_PATH}
139
     * it calls AntProjectHelper.putProperties(), {@link AntProjectHelper#putProperties(String, EditableProperties)}
140
     * otherwise it asks user to updata project. If the user agrees with the project update, it does the update and calls
141
     * AntProjectHelper.putProperties().
142
     * @param path a relative URI in the project directory.
143
     * @param props a set of properties
144
     */
145
    public void putProperties (final String path, final EditableProperties props) {
146
        ProjectManager.mutex().writeAccess(new Runnable() {
147
            public void run() {
148
                if (isCurrent() || !AntProjectHelper.PROJECT_PROPERTIES_PATH.equals(path)) {  //Only project props should cause update
149
                    helper.putProperties(path,props);
150
                } else if (canUpdate()) {
151
                    try {
152
                        saveUpdate(props);
153
                        helper.putProperties(path,props);
154
                    } catch (IOException ioe) {
155
                        Exceptions.printStackTrace(ioe);
156
                    }
157
                }
158
            }
159
        });
160
    }
161
162
    /**
163
     * In the case that the project is of current version or shared is false it delegates to
164
     * AntProjectHelper.getPrimaryConfigurationData(), {@link AntProjectHelper#getPrimaryConfigurationData(boolean)}.
165
     * Otherwise it creates an in memory update of shared configuration data and returns it.
166
     * @param shared if true, refers to <code>project.xml</code>, else refers to
167
     *               <code>private.xml</code>
168
     * @return the configuration data that is available
169
     */
170
    public Element getPrimaryConfigurationData (final boolean shared) {
171
        return (Element) ProjectManager.mutex().readAccess(new Mutex.Action (){
172
            public Object run() {
173
                if (!shared || isCurrent()) { //Only shared props should cause update
174
                    return helper.getPrimaryConfigurationData(shared);
175
                }
176
                else {
177
                    return getUpdatedSharedConfigurationData ();
178
                }
179
            }
180
        });
181
    }
182
183
    /**
184
     * In the case that the project is of current version or shared is false it calls AntProjectHelper.putPrimaryConfigurationData(),
185
     * {@link AntProjectHelper#putPrimaryConfigurationData(Element, boolean)}.
186
     * Otherwise it asks user to update the project. If the user agrees with the project update, it does the update and calls
187
     * AntProjectHelper.PrimaryConfigurationData().
188
     * @param element the configuration data
189
     * @param shared if true, refers to <code>project.xml</code>, else refers to
190
     * <code>private.xml</code>
191
     */
192
    public void putPrimaryConfigurationData (final Element element, final boolean shared) {
193
        ProjectManager.mutex().writeAccess(new Runnable() {
194
            public void run() {
195
                if (!shared || isCurrent()) {
196
                    helper.putPrimaryConfigurationData(element, shared);
197
                } else if (canUpdate()) {
198
                    try {
199
                        saveUpdate(null);
200
                        helper.putPrimaryConfigurationData(element, shared);
201
                    } catch (IOException ioe) {
202
                        Exceptions.printStackTrace(ioe);
203
                    }
204
                }
205
            }
206
        });
207
    }
208
209
    /**
210
     * Returns an AntProjectHelper. The helper may not be used for accessing/storing project metadata.
211
     * For project metadata manipulation the UpdateHelper must be used.
212
     * @return AntProjectHelper
213
     */
214
    public AntProjectHelper getAntProjectHelper () {
215
        return this.helper;
216
    }
217
218
    /**
219
     * Request an saving of update. If the project is not of current version the user will be asked to update the project.
220
     * If the user agrees with an update the project is updated.
221
     * @return true if the metadata are of current version or updated
222
     */
223
    public boolean requestSave () throws IOException{
224
        if (isCurrent()) {
225
            return true;
226
        }
227
        if (!canUpdate()) {
228
            return false;
229
        }
230
        saveUpdate (null);
231
        return true;
232
    }
233
234
    /**
235
     * Returns true if the project is of current version.
236
     * @return true if the project is of current version, otherwise false.
237
     */
238
    public synchronized boolean isCurrent () {
239
        if (this.isCurrent == null) {
240
            this.isCurrent = this.cfg.getConfigurationFragment("data","http://www.netbeans.org/ns/web-project/1",true) == null //NOI18N
241
                    && this.cfg.getConfigurationFragment("data","http://www.netbeans.org/ns/web-project/2",true) == null? //NOI18N
242
                Boolean.TRUE : Boolean.FALSE;
243
        }
244
        return isCurrent.booleanValue();
245
    }
246
247
    private boolean canUpdate () {
248
        if (TRANSPARENT_UPDATE) {
249
            return true;
250
        }
251
        //Ask just once under a single write access
252
        if (alreadyAskedInWriteAccess) {
253
            return false;
254
        }
255
        else {
256
            boolean canUpdate = this.notifier.canUpdate();
257
            if (!canUpdate) {
258
                alreadyAskedInWriteAccess = true;
259
                ProjectManager.mutex().postReadRequest(new Runnable() {
260
                    public void run() {
261
                        alreadyAskedInWriteAccess = false;
262
                    }
263
                });
264
            }
265
            return canUpdate;
266
        }
267
    }
268
269
    private void saveUpdate (EditableProperties props) throws IOException {
270
        this.helper.putPrimaryConfigurationData(getUpdatedSharedConfigurationData(),true);
271
        if (this.cfg.getConfigurationFragment("data","http://www.netbeans.org/ns/web-project/1",true) != null) { //NOI18N
272
            this.cfg.removeConfigurationFragment("data","http://www.netbeans.org/ns/web-project/1",true); //NOI18N
273
        } else {
274
            this.cfg.removeConfigurationFragment("data","http://www.netbeans.org/ns/web-project/2",true); //NOI18N
275
        }
276
277
        boolean putProps = false;
278
279
        // AB: fix for #55597: should not update the project without adding the properties
280
        // update is only done once, so if we don't add the properties now, we don't get another chance to do so
281
        if (props == null) {
282
            props = getProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH);
283
            putProps = true;
284
        }
285
286
        //add properties needed by 4.1 project
287
        if(props != null) {
288
            props.put("test.src.dir", "test"); //NOI18N
289
            props.put("build.test.classes.dir", "${build.dir}/test/classes"); //NOI18N
290
            props.put("build.test.results.dir", "${build.dir}/test/results"); //NOI18N
291
            props.put("conf.dir","${source.root}/conf"); //NOI18N
292
            props.put("jspcompilation.classpath", "${jspc.classpath}:${javac.classpath}");
293
294
            props.setProperty(WebProjectProperties.JAVAC_TEST_CLASSPATH, new String[] {
295
                "${javac.classpath}:", // NOI18N
296
                "${build.classes.dir}:", // NOI18N
297
                "${libs.junit.classpath}:", // NOI18N
298
                "${libs.junit_4.classpath}", // NOI18N
299
            });
300
            props.setProperty(WebProjectProperties.RUN_TEST_CLASSPATH, new String[] {
301
                "${javac.test.classpath}:", // NOI18N
302
                "${build.test.classes.dir}", // NOI18N
303
            });
304
            props.setProperty(WebProjectProperties.DEBUG_TEST_CLASSPATH, new String[] {
305
                "${run.test.classpath}", // NOI18N
306
            });
307
308
            props.put(WebProjectProperties.WAR_EAR_NAME, props.getProperty(WebProjectProperties.WAR_NAME));
309
            props.put(WebProjectProperties.DIST_WAR_EAR, "${dist.dir}/${war.ear.name}");
310
311
            if (props.getProperty(WebProjectProperties.LIBRARIES_DIR) == null) {
312
                props.setProperty(WebProjectProperties.LIBRARIES_DIR, "${" + WebProjectProperties.WEB_DOCBASE_DIR + "}/WEB-INF/lib"); //NOI18N
313
            }
314
        }
315
316
        if(props != null) {
317
            //remove jsp20 and servlet24 libraries
318
            ReferenceHelper refHelper = new ReferenceHelper(helper, cfg, helper.getStandardPropertyEvaluator());
319
            ClassPathSupport cs = new ClassPathSupport( helper.getStandardPropertyEvaluator(), refHelper, helper,
320
                                        WebProjectProperties.WELL_KNOWN_PATHS,
321
                                        WebProjectProperties.LIBRARY_PREFIX,
322
                                        WebProjectProperties.LIBRARY_SUFFIX,
323
                                        WebProjectProperties.ANT_ARTIFACT_PREFIX );
324
            Iterator items = cs.itemsIterator((String)props.get( WebProjectProperties.JAVAC_CLASSPATH ), ClassPathSupport.TAG_WEB_MODULE_LIBRARIES);
325
            ArrayList cpItems = new ArrayList();
326
            while(items.hasNext()) {
327
                ClassPathSupport.Item cpti = (ClassPathSupport.Item)items.next();
328
                String propertyName = cpti.getReference();
329
                if(propertyName != null) {
330
                    String libname = propertyName.substring("${libs.".length());
331
                    if(libname.indexOf(".classpath}") != -1) libname = libname.substring(0, libname.indexOf(".classpath}"));
332
333
                    if(!("servlet24".equals(libname) || "jsp20".equals(libname))) { //NOI18N
334
                        cpItems.add(cpti);
335
                    }
336
                }
337
            }
338
            String[] javac_cp = cs.encodeToStrings(cpItems.iterator(), ClassPathSupport.TAG_WEB_MODULE_LIBRARIES );
339
            props.setProperty( WebProjectProperties.JAVAC_CLASSPATH, javac_cp );
340
        }
341
342
        if (putProps) {
343
            helper.putProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH, props);
344
        }
345
346
        ProjectManager.getDefault().saveProject (this.project);
347
        synchronized(this) {
348
            this.isCurrent = Boolean.TRUE;
349
        }
350
351
        //fire project updated
352
        if(projectUpdateListener != null) projectUpdateListener.projectUpdated();
353
354
        //create conf dir if doesn't exist and copy default manifest inside
355
        try {
356
            //I cannot use ${conf.dir} since the PE doesn't know about it
357
            //String confDir = helper.getStandardPropertyEvaluator().evaluate("${source.root}/conf"); //NOI18N
358
            FileObject prjFO = project.getProjectDirectory();
359
            // folder creation will throw IOE if already exists
360
            // use the hard coded string due to issue #54882 - since the 4.0 supports creation of only jakarta structure projects the conf dir is always in project root
361
            FileObject confDirFO = prjFO.createFolder("conf");//NOI18N
362
            // copyfile will throw IOE if the file already exists
363
            FileUtil.copyFile(Repository.getDefault().getDefaultFileSystem().findResource("org-netbeans-modules-web-project/MANIFEST.MF"), confDirFO, "MANIFEST"); //NOI18N
364
        }catch(IOException e) {
365
            //just ignore
366
        }
367
368
    }
369
370
    private synchronized Element getUpdatedSharedConfigurationData () {
371
        if (cachedElement == null) {
372
            int version = 1;
373
            Element  oldRoot = this.cfg.getConfigurationFragment("data","http://www.netbeans.org/ns/web-project/1",true);    //NOI18N
374
            if (oldRoot == null) {
375
                version = 2;
376
                oldRoot = this.cfg.getConfigurationFragment("data","http://www.netbeans.org/ns/web-project/2",true);    //NOI18N
377
            }
378
            final String ns = version == 1 ? "http://www.netbeans.org/ns/web-project/1" : "http://www.netbeans.org/ns/web-project/2"; //NOI18N
379
            if (oldRoot != null) {
380
                Document doc = oldRoot.getOwnerDocument();
381
                Element newRoot = doc.createElementNS (WebProjectType.PROJECT_CONFIGURATION_NAMESPACE,"data"); //NOI18N
382
                copyDocument (doc, oldRoot, newRoot);
383
                if (version == 1) {
384
                    //1->2 upgrade
385
                    Element sourceRoots = doc.createElementNS(WebProjectType.PROJECT_CONFIGURATION_NAMESPACE,"source-roots");  //NOI18N
386
                    Element root = doc.createElementNS (WebProjectType.PROJECT_CONFIGURATION_NAMESPACE,"root");   //NOI18N
387
                    root.setAttribute ("id","src.dir");   //NOI18N
388
                    sourceRoots.appendChild(root);
389
                    newRoot.appendChild (sourceRoots);
390
                    Element testRoots = doc.createElementNS(WebProjectType.PROJECT_CONFIGURATION_NAMESPACE,"test-roots");  //NOI18N
391
                    root = doc.createElementNS (WebProjectType.PROJECT_CONFIGURATION_NAMESPACE,"root");   //NOI18N
392
                    root.setAttribute ("id","test.src.dir");   //NOI18N
393
                    testRoots.appendChild (root);
394
                    newRoot.appendChild (testRoots);
395
                }
396
                if (version == 1 || version == 2) {
397
                    //2->3 upgrade
398
                    NodeList libList = newRoot.getElementsByTagNameNS(ns, TAG_LIBRARY);
399
                    for (int i = 0; i < libList.getLength(); i++) {
400
                        if (libList.item(i).getNodeType() == Node.ELEMENT_NODE) {
401
                            Element library = (Element) libList.item(i);
402
                            Node webFile = library.getElementsByTagNameNS(ns, TAG_FILE).item(0);
403
                            //remove ${ and } from the beginning and end
404
                            String webFileText = findText(webFile);
405
                            webFileText = webFileText.substring(2, webFileText.length() - 1);
406
//                            warIncludesMap.put(webFileText, pathInWarElements.getLength() > 0 ? findText((Element) pathInWarElements.item(0)) : Item.PATH_IN_WAR_NONE);
407
                            if (webFileText.startsWith ("lib.")) {
408
                                String libName = webFileText.substring(6, webFileText.indexOf(".classpath")); //NOI18N
409
                                List/*<URL>*/ roots = LibraryManager.getDefault().getLibrary(libName).getContent("classpath"); //NOI18N
410
                                ArrayList files = new ArrayList ();
411
                                ArrayList dirs = new ArrayList ();
412
                                for (Iterator it = roots.iterator(); it.hasNext();) {
413
                                    URL rootUrl = (URL) it.next();
414
                                    FileObject root = URLMapper.findFileObject (rootUrl);
415
                                    if ("jar".equals(rootUrl.getProtocol())) {  //NOI18N
416
                                        root = FileUtil.getArchiveFile (root);
417
                                    }
418
                                    if (root != null) {
419
                                        if (root.isData()) {
420
                                            files.add(root);
421
                                        } else {
422
                                            dirs.add(root);
423
                                        }
424
                                    }
425
                                }
426
                                if (files.size() > 0) {
427
                                    library.setAttribute(ATTR_FILES, "" + files.size());
428
                                }
429
                                if (dirs.size() > 0) {
430
                                    library.setAttribute(ATTR_DIRS, "" + dirs.size());
431
                                }
432
                            }
433
                        }
434
                    }
435
                }
436
                cachedElement = updateMinAntVersion(newRoot, doc);
437
            }
438
        }
439
        return cachedElement;
440
    }
441
442
    private synchronized EditableProperties getUpdatedProjectProperties () {
443
        if (cachedProperties == null) {
444
            cachedProperties = this.helper.getProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH);
445
            //The javadoc.additionalparam was not in NB 4.0
446
            if (cachedProperties.get (WebProjectProperties.JAVADOC_ADDITIONALPARAM)==null) {
447
                cachedProperties.put (WebProjectProperties.JAVADOC_ADDITIONALPARAM,"");    //NOI18N
448
            }
449
        }
450
        return this.cachedProperties;
451
    }
452
453
    private static void copyDocument (Document doc, Element from, Element to) {
454
        NodeList nl = from.getChildNodes();
455
        int length = nl.getLength();
456
        for (int i=0; i< length; i++) {
457
            Node node = nl.item (i);
458
            Node newNode = null;
459
            switch (node.getNodeType()) {
460
                case Node.ELEMENT_NODE:
461
                    Element oldElement = (Element) node;
462
                    newNode = doc.createElementNS(WebProjectType.PROJECT_CONFIGURATION_NAMESPACE,oldElement.getTagName());
463
                    NamedNodeMap m = oldElement.getAttributes();
464
                    Element newElement = (Element) newNode;
465
                    for (int index = 0; index < m.getLength(); index++) {
466
                        Node attr = m.item(index);
467
                        newElement.setAttribute(attr.getNodeName(), attr.getNodeValue());
468
                    }
469
                    copyDocument(doc,oldElement,(Element)newNode);
470
                    break;
471
                case Node.TEXT_NODE:
472
                    Text oldText = (Text) node;
473
                    newNode = doc.createTextNode(oldText.getData());
474
                    break;
475
                case Node.COMMENT_NODE:
476
                    Comment oldComment = (Comment) node;
477
                    newNode = doc.createComment(oldComment.getData());
478
                    break;
479
            }
480
            if (newNode != null) {
481
                to.appendChild (newNode);
482
            }
483
        }
484
    }
485
486
    private static Element updateMinAntVersion (final Element root, final Document doc) {
487
        NodeList list = root.getElementsByTagNameNS (WebProjectType.PROJECT_CONFIGURATION_NAMESPACE,TAG_MINIMUM_ANT_VERSION);
488
        if (list.getLength() == 1) {
489
            Element me = (Element) list.item(0);
490
            list = me.getChildNodes();
491
            if (list.getLength() == 1) {
492
                me.replaceChild (doc.createTextNode(WebProjectUtilities.MINIMUM_ANT_VERSION), list.item(0));
493
                return root;
494
            }
495
        }
496
        assert false : "Invalid project file"; //NOI18N
497
        return root;
498
    }
499
500
    /**
501
     * Creates an default Notifier. The default notifier displays a dialog warning user about project update.
502
     * @return notifier
503
     */
504
    public static Notifier createDefaultNotifier () {
505
        return new Notifier() {
506
            public boolean canUpdate() {
507
                JButton updateOption = new JButton (NbBundle.getMessage(UpdateHelper.class, "CTL_UpdateOption"));
508
                return DialogDisplayer.getDefault().notify(
509
                    new NotifyDescriptor (NbBundle.getMessage(UpdateHelper.class,"TXT_ProjectUpdate", BUILD_NUMBER),
510
                        NbBundle.getMessage(UpdateHelper.class,"TXT_ProjectUpdateTitle"),
511
                        NotifyDescriptor.DEFAULT_OPTION,
512
                        NotifyDescriptor.WARNING_MESSAGE,
513
                        new Object[] {
514
                            updateOption,
515
                            NotifyDescriptor.CANCEL_OPTION
516
                        },
517
                        updateOption)) == updateOption;
518
            }
519
        };
520
    }
521
522
    /**
523
     * Extract nested text from a node.
524
     * Currently does not handle coalescing text nodes, CDATA sections, etc.
525
     * @param parent a parent node
526
     * @return the nested text, or null if none was found
527
     */
528
    private static String findText(Node parent) {
529
        NodeList l = parent.getChildNodes();
530
        for (int i = 0; i < l.getLength(); i++) {
531
            if (l.item(i).getNodeType() == Node.TEXT_NODE) {
532
                Text text = (Text)l.item(i);
533
                return text.getNodeValue();
534
            }
535
        }
536
        return null;
537
    }
538
539
    /**
540
     * Interface used by the UpdateHelper to ask user about
541
     * the project update.
542
     */
543
    public static interface Notifier {
544
        /**
545
         * Asks user to update the project
546
         * @return true if the project should be updated
547
         */
548
        public boolean canUpdate ();
549
    }
550
551
    private ProjectUpdateListener projectUpdateListener = null;
552
553
    public void setProjectUpdateListener(ProjectUpdateListener l) {
554
        this.projectUpdateListener = l;
555
    }
556
557
    /** Used to notify someone that the project needs to be updated.
558
     * A workaround for #54077 - Import 4.0 project - remove Servlet/JSP APIs */
559
    public static interface ProjectUpdateListener {
560
        public void projectUpdated();
561
    }
562
563
}
(-)a/web.project/src/org/netbeans/modules/web/project/UpdateProjectImpl.java (+431 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 1997-2007 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 2008 Sun Microsystems, Inc.
38
 */
39
40
package org.netbeans.modules.web.project;
41
42
import java.io.IOException;
43
import java.net.URL;
44
import java.util.ArrayList;
45
import java.util.Iterator;
46
import java.util.List;
47
import javax.swing.JButton;
48
import org.netbeans.api.project.Project;
49
import org.netbeans.api.project.ProjectManager;
50
import org.netbeans.api.project.libraries.LibraryManager;
51
import org.netbeans.modules.java.api.common.ant.UpdateHelper;
52
import org.netbeans.modules.java.api.common.ant.UpdateImplementation;
53
import org.netbeans.modules.web.project.api.WebProjectUtilities;
54
import org.netbeans.modules.web.project.classpath.ClassPathSupport;
55
import org.netbeans.modules.web.project.ui.customizer.WebProjectProperties;
56
import org.netbeans.spi.project.AuxiliaryConfiguration;
57
import org.netbeans.spi.project.support.ant.AntProjectHelper;
58
import org.netbeans.spi.project.support.ant.EditableProperties;
59
import org.netbeans.spi.project.support.ant.ReferenceHelper;
60
import org.openide.DialogDisplayer;
61
import org.openide.NotifyDescriptor;
62
import org.openide.filesystems.FileObject;
63
import org.openide.filesystems.FileUtil;
64
import org.openide.filesystems.Repository;
65
import org.openide.filesystems.URLMapper;
66
import org.openide.util.Mutex;
67
import org.openide.util.NbBundle;
68
import org.w3c.dom.Comment;
69
import org.w3c.dom.Document;
70
import org.w3c.dom.Element;
71
import org.w3c.dom.NamedNodeMap;
72
import org.w3c.dom.Node;
73
import org.w3c.dom.NodeList;
74
import org.w3c.dom.Text;
75
76
/**
77
 *
78
 * @author Tomas Mysik
79
 */
80
public class UpdateProjectImpl implements UpdateImplementation {
81
82
    private static final boolean TRANSPARENT_UPDATE = Boolean.getBoolean("webproject.transparentUpdate");
83
    private static final String BUILD_NUMBER = System.getProperty("netbeans.buildnumber"); // NOI18N
84
    private static final String TAG_MINIMUM_ANT_VERSION = "minimum-ant-version"; // NOI18N
85
    private static final String TAG_FILE = "file"; //NOI18N
86
    private static final String TAG_LIBRARY = "library"; //NOI18N
87
    private static final String ATTR_FILES = "files"; //NOI18N
88
    private static final String ATTR_DIRS = "dirs"; //NOI18N
89
90
    private final Project project;
91
    private final AntProjectHelper helper;
92
    private final AuxiliaryConfiguration cfg;
93
    private boolean alreadyAskedInWriteAccess;
94
    private Boolean isCurrent;
95
    private Element cachedElement;
96
    private ProjectUpdateListener projectUpdateListener = null;
97
    private UpdateHelper updateHelper;
98
    private EditableProperties cachedProperties;
99
100
    /**
101
     * Creates new UpdateHelper
102
     * @param project
103
     * @param helper AntProjectHelper
104
     * @param cfg AuxiliaryConfiguration
105
     * @param genFileHelper GeneratedFilesHelper
106
     * @param notifier used to ask user about project update
107
     */
108
    UpdateProjectImpl(Project project, AntProjectHelper helper, AuxiliaryConfiguration cfg) {
109
        assert project != null && helper != null && cfg != null;
110
        this.project = project;
111
        this.helper = helper;
112
        this.cfg = cfg;
113
    }
114
115
    public void setUpdateHelper(UpdateHelper updateHelper) {
116
        this.updateHelper = updateHelper;
117
    }
118
119
    public boolean isCurrent() {
120
        return ProjectManager.mutex().readAccess(new Mutex.Action<Boolean>() {
121
            public Boolean run() {
122
                synchronized (this) {
123
                    if (isCurrent == null) {
124
                        if ((cfg.getConfigurationFragment("data","http://www.netbeans.org/ns/web-project/1",true) != null) || // NOI18N
125
                        (cfg.getConfigurationFragment("data","http://www.netbeans.org/ns/web-project/2",true) != null)) { // NOI18N
126
                            isCurrent = Boolean.FALSE;
127
                        } else {
128
                            isCurrent = Boolean.TRUE;
129
                        }
130
                    }
131
                    return isCurrent;
132
                }
133
            }
134
        }).booleanValue();
135
    }
136
137
    public boolean canUpdate () {
138
        if (TRANSPARENT_UPDATE) {
139
            return true;
140
        }
141
        //Ask just once under a single write access
142
        if (alreadyAskedInWriteAccess) {
143
            return false;
144
        }
145
        else {
146
            boolean canUpdate = showUpdateDialog();
147
            if (!canUpdate) {
148
                alreadyAskedInWriteAccess = true;
149
                ProjectManager.mutex().postReadRequest(new Runnable() {
150
                    public void run() {
151
                        alreadyAskedInWriteAccess = false;
152
                    }
153
                });
154
            }
155
            return canUpdate;
156
        }
157
    }
158
159
    public void saveUpdate(EditableProperties props) throws IOException {
160
        this.helper.putPrimaryConfigurationData(getUpdatedSharedConfigurationData(),true);
161
        if (this.cfg.getConfigurationFragment("data","http://www.netbeans.org/ns/web-project/1",true) != null) { //NOI18N
162
            this.cfg.removeConfigurationFragment("data","http://www.netbeans.org/ns/web-project/1",true); //NOI18N
163
        } else {
164
            this.cfg.removeConfigurationFragment("data","http://www.netbeans.org/ns/web-project/2",true); //NOI18N
165
        }
166
167
        boolean putProps = false;
168
169
        // AB: fix for #55597: should not update the project without adding the properties
170
        // update is only done once, so if we don't add the properties now, we don't get another chance to do so
171
        if (props == null) {
172
            assert updateHelper != null;
173
            props = updateHelper.getProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH);
174
            putProps = true;
175
        }
176
177
        //add properties needed by 4.1 project
178
        if(props != null) {
179
            props.put("test.src.dir", "test"); //NOI18N
180
            props.put("build.test.classes.dir", "${build.dir}/test/classes"); //NOI18N
181
            props.put("build.test.results.dir", "${build.dir}/test/results"); //NOI18N
182
            props.put("conf.dir","${source.root}/conf"); //NOI18N
183
            props.put("jspcompilation.classpath", "${jspc.classpath}:${javac.classpath}");
184
185
            props.setProperty(WebProjectProperties.JAVAC_TEST_CLASSPATH, new String[] {
186
                "${javac.classpath}:", // NOI18N
187
                "${build.classes.dir}:", // NOI18N
188
                "${libs.junit.classpath}:", // NOI18N
189
                "${libs.junit_4.classpath}", // NOI18N
190
            });
191
            props.setProperty(WebProjectProperties.RUN_TEST_CLASSPATH, new String[] {
192
                "${javac.test.classpath}:", // NOI18N
193
                "${build.test.classes.dir}", // NOI18N
194
            });
195
            props.setProperty(WebProjectProperties.DEBUG_TEST_CLASSPATH, new String[] {
196
                "${run.test.classpath}", // NOI18N
197
            });
198
199
            props.put(WebProjectProperties.WAR_EAR_NAME, props.getProperty(WebProjectProperties.WAR_NAME));
200
            props.put(WebProjectProperties.DIST_WAR_EAR, "${dist.dir}/${war.ear.name}");
201
202
            if (props.getProperty(WebProjectProperties.LIBRARIES_DIR) == null) {
203
                props.setProperty(WebProjectProperties.LIBRARIES_DIR, "${" + WebProjectProperties.WEB_DOCBASE_DIR + "}/WEB-INF/lib"); //NOI18N
204
            }
205
        }
206
207
        if(props != null) {
208
            //remove jsp20 and servlet24 libraries
209
            ReferenceHelper refHelper = new ReferenceHelper(helper, cfg, helper.getStandardPropertyEvaluator());
210
            ClassPathSupport cs = new ClassPathSupport( helper.getStandardPropertyEvaluator(), refHelper, helper,
211
                                        WebProjectProperties.WELL_KNOWN_PATHS,
212
                                        WebProjectProperties.LIBRARY_PREFIX,
213
                                        WebProjectProperties.LIBRARY_SUFFIX,
214
                                        WebProjectProperties.ANT_ARTIFACT_PREFIX );
215
            Iterator items = cs.itemsIterator((String)props.get( WebProjectProperties.JAVAC_CLASSPATH ), ClassPathSupport.TAG_WEB_MODULE_LIBRARIES);
216
            ArrayList cpItems = new ArrayList();
217
            while(items.hasNext()) {
218
                ClassPathSupport.Item cpti = (ClassPathSupport.Item)items.next();
219
                String propertyName = cpti.getReference();
220
                if(propertyName != null) {
221
                    String libname = propertyName.substring("${libs.".length());
222
                    if(libname.indexOf(".classpath}") != -1) libname = libname.substring(0, libname.indexOf(".classpath}"));
223
224
                    if(!("servlet24".equals(libname) || "jsp20".equals(libname))) { //NOI18N
225
                        cpItems.add(cpti);
226
                    }
227
                }
228
            }
229
            String[] javac_cp = cs.encodeToStrings(cpItems.iterator(), ClassPathSupport.TAG_WEB_MODULE_LIBRARIES );
230
            props.setProperty( WebProjectProperties.JAVAC_CLASSPATH, javac_cp );
231
        }
232
233
        if (putProps) {
234
            helper.putProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH, props);
235
        }
236
237
        ProjectManager.getDefault().saveProject (this.project);
238
        synchronized(this) {
239
            this.isCurrent = Boolean.TRUE;
240
        }
241
242
        //fire project updated
243
        if(projectUpdateListener != null) projectUpdateListener.projectUpdated();
244
245
        //create conf dir if doesn't exist and copy default manifest inside
246
        try {
247
            //I cannot use ${conf.dir} since the PE doesn't know about it
248
            //String confDir = helper.getStandardPropertyEvaluator().evaluate("${source.root}/conf"); //NOI18N
249
            FileObject prjFO = project.getProjectDirectory();
250
            // folder creation will throw IOE if already exists
251
            // use the hard coded string due to issue #54882 - since the 4.0 supports creation of only jakarta structure projects the conf dir is always in project root
252
            FileObject confDirFO = prjFO.createFolder("conf");//NOI18N
253
            // copyfile will throw IOE if the file already exists
254
            FileUtil.copyFile(Repository.getDefault().getDefaultFileSystem().findResource("org-netbeans-modules-web-project/MANIFEST.MF"), confDirFO, "MANIFEST"); //NOI18N
255
        }catch(IOException e) {
256
            //just ignore
257
        }
258
    }
259
260
    public synchronized Element getUpdatedSharedConfigurationData () {
261
        if (cachedElement == null) {
262
            int version = 1;
263
            Element  oldRoot = this.cfg.getConfigurationFragment("data","http://www.netbeans.org/ns/web-project/1",true);    //NOI18N
264
            if (oldRoot == null) {
265
                version = 2;
266
                oldRoot = this.cfg.getConfigurationFragment("data","http://www.netbeans.org/ns/web-project/2",true);    //NOI18N
267
            }
268
            final String ns = version == 1 ? "http://www.netbeans.org/ns/web-project/1" : "http://www.netbeans.org/ns/web-project/2"; //NOI18N
269
            if (oldRoot != null) {
270
                Document doc = oldRoot.getOwnerDocument();
271
                Element newRoot = doc.createElementNS (WebProjectType.PROJECT_CONFIGURATION_NAMESPACE,"data"); //NOI18N
272
                copyDocument (doc, oldRoot, newRoot);
273
                if (version == 1) {
274
                    //1->2 upgrade
275
                    Element sourceRoots = doc.createElementNS(WebProjectType.PROJECT_CONFIGURATION_NAMESPACE,"source-roots");  //NOI18N
276
                    Element root = doc.createElementNS (WebProjectType.PROJECT_CONFIGURATION_NAMESPACE,"root");   //NOI18N
277
                    root.setAttribute ("id","src.dir");   //NOI18N
278
                    sourceRoots.appendChild(root);
279
                    newRoot.appendChild (sourceRoots);
280
                    Element testRoots = doc.createElementNS(WebProjectType.PROJECT_CONFIGURATION_NAMESPACE,"test-roots");  //NOI18N
281
                    root = doc.createElementNS (WebProjectType.PROJECT_CONFIGURATION_NAMESPACE,"root");   //NOI18N
282
                    root.setAttribute ("id","test.src.dir");   //NOI18N
283
                    testRoots.appendChild (root);
284
                    newRoot.appendChild (testRoots);
285
                }
286
                if (version == 1 || version == 2) {
287
                    //2->3 upgrade
288
                    NodeList libList = newRoot.getElementsByTagNameNS(ns, TAG_LIBRARY);
289
                    for (int i = 0; i < libList.getLength(); i++) {
290
                        if (libList.item(i).getNodeType() == Node.ELEMENT_NODE) {
291
                            Element library = (Element) libList.item(i);
292
                            Node webFile = library.getElementsByTagNameNS(ns, TAG_FILE).item(0);
293
                            //remove ${ and } from the beginning and end
294
                            String webFileText = findText(webFile);
295
                            webFileText = webFileText.substring(2, webFileText.length() - 1);
296
//                            warIncludesMap.put(webFileText, pathInWarElements.getLength() > 0 ? findText((Element) pathInWarElements.item(0)) : Item.PATH_IN_WAR_NONE);
297
                            if (webFileText.startsWith ("lib.")) {
298
                                String libName = webFileText.substring(6, webFileText.indexOf(".classpath")); //NOI18N
299
                                List/*<URL>*/ roots = LibraryManager.getDefault().getLibrary(libName).getContent("classpath"); //NOI18N
300
                                ArrayList files = new ArrayList ();
301
                                ArrayList dirs = new ArrayList ();
302
                                for (Iterator it = roots.iterator(); it.hasNext();) {
303
                                    URL rootUrl = (URL) it.next();
304
                                    FileObject root = URLMapper.findFileObject (rootUrl);
305
                                    if ("jar".equals(rootUrl.getProtocol())) {  //NOI18N
306
                                        root = FileUtil.getArchiveFile (root);
307
                                    }
308
                                    if (root != null) {
309
                                        if (root.isData()) {
310
                                            files.add(root);
311
                                        } else {
312
                                            dirs.add(root);
313
                                        }
314
                                    }
315
                                }
316
                                if (files.size() > 0) {
317
                                    library.setAttribute(ATTR_FILES, "" + files.size());
318
                                }
319
                                if (dirs.size() > 0) {
320
                                    library.setAttribute(ATTR_DIRS, "" + dirs.size());
321
                                }
322
                            }
323
                        }
324
                    }
325
                }
326
                cachedElement = updateMinAntVersion(newRoot, doc);
327
            }
328
        }
329
        return cachedElement;
330
    }
331
332
    public synchronized EditableProperties getUpdatedProjectProperties () {
333
        if (cachedProperties == null) {
334
            cachedProperties = this.helper.getProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH);
335
            //The javadoc.additionalparam was not in NB 4.0
336
            if (cachedProperties.get (WebProjectProperties.JAVADOC_ADDITIONALPARAM)==null) {
337
                cachedProperties.put (WebProjectProperties.JAVADOC_ADDITIONALPARAM,"");    //NOI18N
338
            }
339
        }
340
        return this.cachedProperties;
341
    }
342
343
    /**
344
     * Extract nested text from a node.
345
     * Currently does not handle coalescing text nodes, CDATA sections, etc.
346
     * @param parent a parent node
347
     * @return the nested text, or null if none was found
348
     */
349
    private static String findText(Node parent) {
350
        NodeList l = parent.getChildNodes();
351
        for (int i = 0; i < l.getLength(); i++) {
352
            if (l.item(i).getNodeType() == Node.TEXT_NODE) {
353
                Text text = (Text)l.item(i);
354
                return text.getNodeValue();
355
            }
356
        }
357
        return null;
358
    }
359
360
    private static void copyDocument (Document doc, Element from, Element to) {
361
        NodeList nl = from.getChildNodes();
362
        int length = nl.getLength();
363
        for (int i=0; i< length; i++) {
364
            Node node = nl.item (i);
365
            Node newNode = null;
366
            switch (node.getNodeType()) {
367
                case Node.ELEMENT_NODE:
368
                    Element oldElement = (Element) node;
369
                    newNode = doc.createElementNS(WebProjectType.PROJECT_CONFIGURATION_NAMESPACE,oldElement.getTagName());
370
                    NamedNodeMap m = oldElement.getAttributes();
371
                    Element newElement = (Element) newNode;
372
                    for (int index = 0; index < m.getLength(); index++) {
373
                        Node attr = m.item(index);
374
                        newElement.setAttribute(attr.getNodeName(), attr.getNodeValue());
375
                    }
376
                    copyDocument(doc,oldElement,(Element)newNode);
377
                    break;
378
                case Node.TEXT_NODE:
379
                    Text oldText = (Text) node;
380
                    newNode = doc.createTextNode(oldText.getData());
381
                    break;
382
                case Node.COMMENT_NODE:
383
                    Comment oldComment = (Comment) node;
384
                    newNode = doc.createComment(oldComment.getData());
385
                    break;
386
            }
387
            if (newNode != null) {
388
                to.appendChild (newNode);
389
            }
390
        }
391
    }
392
393
    private static Element updateMinAntVersion (final Element root, final Document doc) {
394
        NodeList list = root.getElementsByTagNameNS (WebProjectType.PROJECT_CONFIGURATION_NAMESPACE,TAG_MINIMUM_ANT_VERSION);
395
        if (list.getLength() == 1) {
396
            Element me = (Element) list.item(0);
397
            list = me.getChildNodes();
398
            if (list.getLength() == 1) {
399
                me.replaceChild (doc.createTextNode(WebProjectUtilities.MINIMUM_ANT_VERSION), list.item(0));
400
                return root;
401
            }
402
        }
403
        assert false : "Invalid project file"; //NOI18N
404
        return root;
405
    }
406
407
    private boolean showUpdateDialog() {
408
        JButton updateOption = new JButton (NbBundle.getMessage(UpdateProjectImpl.class, "CTL_UpdateOption"));
409
        updateOption.getAccessibleContext().setAccessibleDescription(NbBundle.getMessage(UpdateProjectImpl.class, "AD_UpdateOption"));
410
        return DialogDisplayer.getDefault().notify(
411
            new NotifyDescriptor (NbBundle.getMessage(UpdateProjectImpl.class,"TXT_ProjectUpdate", BUILD_NUMBER),
412
                NbBundle.getMessage(UpdateProjectImpl.class,"TXT_ProjectUpdateTitle"),
413
                NotifyDescriptor.DEFAULT_OPTION,
414
                NotifyDescriptor.WARNING_MESSAGE,
415
                new Object[] {
416
                    updateOption,
417
                    NotifyDescriptor.CANCEL_OPTION
418
                },
419
                updateOption)) == updateOption;
420
    }
421
422
    public void setProjectUpdateListener(ProjectUpdateListener l) {
423
        this.projectUpdateListener = l;
424
    }
425
426
    /** Used to notify someone that the project needs to be updated.
427
     * A workaround for #54077 - Import 4.0 project - remove Servlet/JSP APIs */
428
    public static interface ProjectUpdateListener {
429
        public void projectUpdated();
430
    }
431
}
(-)a/web.project/src/org/netbeans/modules/web/project/WebActionProvider.java (-3 / +1 lines)
Lines 86-94 import org.netbeans.modules.web.api.webm Link Here
86
import org.netbeans.modules.web.api.webmodule.WebModule;
86
import org.netbeans.modules.web.api.webmodule.WebModule;
87
import org.netbeans.modules.web.api.webmodule.WebProjectConstants;
87
import org.netbeans.modules.web.api.webmodule.WebProjectConstants;
88
import java.util.HashSet;
88
import java.util.HashSet;
89
import java.util.logging.Level;
90
import java.util.logging.Logger;
91
import org.netbeans.api.fileinfo.NonRecursiveFolder;
89
import org.netbeans.api.fileinfo.NonRecursiveFolder;
90
import org.netbeans.modules.java.api.common.ant.UpdateHelper;
92
import org.netbeans.modules.web.api.webmodule.RequestParametersQuery;
91
import org.netbeans.modules.web.api.webmodule.RequestParametersQuery;
93
import org.netbeans.modules.web.jsps.parserapi.JspParserAPI;
92
import org.netbeans.modules.web.jsps.parserapi.JspParserAPI;
94
import org.netbeans.modules.web.jsps.parserapi.JspParserFactory;
93
import org.netbeans.modules.web.jsps.parserapi.JspParserFactory;
Lines 98-104 import org.netbeans.modules.websvc.api.w Link Here
98
import org.netbeans.modules.websvc.api.webservices.WebServicesSupport;
97
import org.netbeans.modules.websvc.api.webservices.WebServicesSupport;
99
import org.netbeans.modules.websvc.api.webservices.WsCompileEditorSupport;
98
import org.netbeans.modules.websvc.api.webservices.WsCompileEditorSupport;
100
import org.netbeans.spi.project.support.ant.AntProjectHelper;
99
import org.netbeans.spi.project.support.ant.AntProjectHelper;
101
import org.netbeans.spi.project.support.ant.EditableProperties;
102
import org.netbeans.spi.project.support.ant.PropertyUtils;
100
import org.netbeans.spi.project.support.ant.PropertyUtils;
103
import org.openide.DialogDescriptor;
101
import org.openide.DialogDescriptor;
104
import org.openide.util.Exceptions;
102
import org.openide.util.Exceptions;
(-)a/web.project/src/org/netbeans/modules/web/project/WebFileBuiltQuery.java (-99 lines)
Lines 1-99 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 1997-2007 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
 * Contributor(s):
25
 *
26
 * The Original Software is NetBeans. The Initial Developer of the Original
27
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
28
 * Microsystems, Inc. All Rights Reserved.
29
 *
30
 * If you wish your version of this file to be governed by only the CDDL
31
 * or only the GPL Version 2, indicate your decision by adding
32
 * "[Contributor] elects to include this software in this distribution
33
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
34
 * single choice of license, a recipient has the option to distribute
35
 * your version of this file under either the CDDL, the GPL Version 2 or
36
 * to extend the choice of license to its licensees as provided above.
37
 * However, if you add GPL Version 2 code and therefore, elected the GPL
38
 * Version 2 license, then the option applies only if the new code is
39
 * made subject to such option by the copyright holder.
40
 */
41
package org.netbeans.modules.web.project;
42
43
import java.beans.PropertyChangeEvent;
44
import java.beans.PropertyChangeListener;
45
import org.openide.filesystems.FileObject;
46
import org.netbeans.api.queries.FileBuiltQuery;
47
import org.netbeans.spi.queries.FileBuiltQueryImplementation;
48
import org.netbeans.spi.project.support.ant.AntProjectHelper;
49
import org.netbeans.spi.project.support.ant.PropertyEvaluator;
50
import org.netbeans.modules.web.project.ui.customizer.WebProjectProperties;
51
52
public class WebFileBuiltQuery implements FileBuiltQueryImplementation, PropertyChangeListener {
53
54
    private FileBuiltQueryImplementation delegate;
55
    private final AntProjectHelper helper;
56
    private final PropertyEvaluator evaluator;
57
    private final SourceRoots sourceRoots;
58
    private final SourceRoots testRoots;
59
60
    WebFileBuiltQuery (AntProjectHelper helper, PropertyEvaluator evaluator,
61
                        SourceRoots sourceRoots, SourceRoots testRoots) {
62
        this.helper = helper;
63
        this.evaluator = evaluator;
64
        this.sourceRoots = sourceRoots;
65
        this.testRoots = testRoots;
66
    }
67
68
    public synchronized FileBuiltQuery.Status getStatus(FileObject file) {
69
        if (this.delegate == null) {
70
            this.delegate = createDelegate ();
71
        }
72
        return this.delegate.getStatus (file);
73
    }
74
75
    private FileBuiltQueryImplementation createDelegate () {
76
        String[] srcRoots = this.sourceRoots.getRootProperties();
77
        String[] tstRoots = this.testRoots.getRootProperties();
78
        String[] from = new String [srcRoots.length + tstRoots.length];
79
        String[] to = new String [srcRoots.length + tstRoots.length];
80
        for (int i=0; i< srcRoots.length; i++) {
81
            from[i] = "${" + srcRoots[i] + "}/*.java"; // NOI18N
82
            to[i] = "${" + WebProjectProperties.BUILD_CLASSES_DIR + "}/*.class"; // NOI18N
83
        }
84
        for (int i=0; i<tstRoots.length; i++) {
85
            from[srcRoots.length+i] = "${" + tstRoots[i] + "}/*.java"; // NOI18N
86
            to[srcRoots.length+i] = "${" + WebProjectProperties.BUILD_TEST_CLASSES_DIR + "}/*.class"; // NOI18N
87
        }
88
        return helper.createGlobFileBuiltQuery(evaluator, from, to);
89
    }
90
91
    public void propertyChange(PropertyChangeEvent evt) {
92
        if (SourceRoots.PROP_ROOT_PROPERTIES.equals (evt.getPropertyName())) {
93
            synchronized(this) {
94
                this.delegate = null;
95
                ///XXX: What to do with already returned Statuses
96
            }
97
        }
98
    }
99
}
(-)a/web.project/src/org/netbeans/modules/web/project/WebProject.java (-11 / +22 lines)
Lines 98-110 import org.netbeans.api.project.ant.AntA Link Here
98
import org.netbeans.api.project.ant.AntArtifact;
98
import org.netbeans.api.project.ant.AntArtifact;
99
import org.netbeans.modules.web.project.classpath.ClassPathProviderImpl;
99
import org.netbeans.modules.web.project.classpath.ClassPathProviderImpl;
100
import org.netbeans.modules.web.project.classpath.WebProjectClassPathExtender;
100
import org.netbeans.modules.web.project.classpath.WebProjectClassPathExtender;
101
import org.netbeans.modules.web.project.queries.*;
102
import org.netbeans.modules.web.project.ui.WebLogicalViewProvider;
101
import org.netbeans.modules.web.project.ui.WebLogicalViewProvider;
103
import org.netbeans.modules.web.project.ui.customizer.WebProjectProperties;
102
import org.netbeans.modules.web.project.ui.customizer.WebProjectProperties;
104
import org.netbeans.spi.project.AuxiliaryConfiguration;
103
import org.netbeans.spi.project.AuxiliaryConfiguration;
105
import org.netbeans.api.project.ProjectInformation;
104
import org.netbeans.api.project.ProjectInformation;
106
import org.netbeans.modules.j2ee.common.ui.BrokenServerSupport;
105
import org.netbeans.modules.j2ee.common.ui.BrokenServerSupport;
107
import org.netbeans.modules.j2ee.deployment.devmodules.api.J2eePlatform;
106
import org.netbeans.modules.j2ee.deployment.devmodules.api.J2eePlatform;
107
import org.netbeans.modules.java.api.common.SourceRoots;
108
import org.netbeans.modules.java.api.common.SourceRootsSupport;
109
import org.netbeans.modules.java.api.common.ant.UpdateHelper;
110
import org.netbeans.modules.java.api.common.queries.QuerySupport;
108
import org.netbeans.spi.project.SubprojectProvider;
111
import org.netbeans.spi.project.SubprojectProvider;
109
import org.netbeans.spi.project.ant.AntArtifactProvider;
112
import org.netbeans.spi.project.ant.AntArtifactProvider;
110
import org.netbeans.spi.project.ant.AntBuildExtenderFactory;
113
import org.netbeans.spi.project.ant.AntBuildExtenderFactory;
Lines 170-175 public final class WebProject implements Link Here
170
    private SourceRoots sourceRoots;
173
    private SourceRoots sourceRoots;
171
    private SourceRoots testRoots;
174
    private SourceRoots testRoots;
172
    private final UpdateHelper updateHelper;
175
    private final UpdateHelper updateHelper;
176
    private final UpdateProjectImpl updateProject;
173
    private final AuxiliaryConfiguration aux;
177
    private final AuxiliaryConfiguration aux;
174
    private final WebProjectClassPathExtender classPathExtender;
178
    private final WebProjectClassPathExtender classPathExtender;
175
    private final WebProjectClassPathModifier cpMod;
179
    private final WebProjectClassPathModifier cpMod;
Lines 297-303 public final class WebProject implements Link Here
297
        refHelper = new ReferenceHelper(helper, aux, eval);
301
        refHelper = new ReferenceHelper(helper, aux, eval);
298
        buildExtender = AntBuildExtenderFactory.createAntExtender(new WebExtenderImplementation());
302
        buildExtender = AntBuildExtenderFactory.createAntExtender(new WebExtenderImplementation());
299
        genFilesHelper = new GeneratedFilesHelper(helper, buildExtender);
303
        genFilesHelper = new GeneratedFilesHelper(helper, buildExtender);
300
        this.updateHelper = new UpdateHelper (this, this.helper, this.aux, UpdateHelper.createDefaultNotifier());
304
        updateProject = new UpdateProjectImpl(this, this.helper, aux);
305
        this.updateHelper = new UpdateHelper(updateProject, helper);
306
        updateProject.setUpdateHelper(updateHelper);
301
        this.cpProvider = new ClassPathProviderImpl(this.helper, evaluator(), getSourceRoots(),getTestSourceRoots());
307
        this.cpProvider = new ClassPathProviderImpl(this.helper, evaluator(), getSourceRoots(),getTestSourceRoots());
302
        webModule = new ProjectWebModule (this, updateHelper, cpProvider);
308
        webModule = new ProjectWebModule (this, updateHelper, cpProvider);
303
        apiWebModule = WebModuleFactory.createWebModule (webModule);
309
        apiWebModule = WebModuleFactory.createWebModule (webModule);
Lines 318-323 public final class WebProject implements Link Here
318
        css = new CopyOnSaveSupport();
324
        css = new CopyOnSaveSupport();
319
        webPagesFileWatch = new FileWatch(WebProjectProperties.WEB_DOCBASE_DIR);
325
        webPagesFileWatch = new FileWatch(WebProjectProperties.WEB_DOCBASE_DIR);
320
        webInfFileWatch = new FileWatch(WebProjectProperties.WEBINF_DIR);
326
        webInfFileWatch = new FileWatch(WebProjectProperties.WEBINF_DIR);
327
    }
328
329
    public UpdateProjectImpl getUpdateImplementation() {
330
        return updateProject;
321
    }
331
    }
322
    public FileObject getProjectDirectory() {
332
    public FileObject getProjectDirectory() {
Lines 372-388 public final class WebProject implements Link Here
372
            new WebLogicalViewProvider(this, this.updateHelper, evaluator (), refHelper),
382
            new WebLogicalViewProvider(this, this.updateHelper, evaluator (), refHelper),
373
            new CustomizerProviderImpl(this, this.updateHelper, evaluator(), refHelper),
383
            new CustomizerProviderImpl(this, this.updateHelper, evaluator(), refHelper),
374
            new ClassPathProviderMerger(cpProvider),
384
            new ClassPathProviderMerger(cpProvider),
375
            new CompiledSourceForBinaryQuery(this.helper, evaluator(),getSourceRoots(),getTestSourceRoots()),
385
            QuerySupport.createCompiledSourceForBinaryQuery(helper, evaluator(), getSourceRoots(), getTestSourceRoots()),
376
            new JavadocForBinaryQueryImpl(this.helper, evaluator()),
386
            QuerySupport.createJavadocForBinaryQuery(helper, evaluator()),
377
            new AntArtifactProviderImpl(),
387
            new AntArtifactProviderImpl(),
378
            new ProjectXmlSavedHookImpl(),
388
            new ProjectXmlSavedHookImpl(),
379
            UILookupMergerSupport.createProjectOpenHookMerger(new ProjectOpenedHookImpl()),
389
            UILookupMergerSupport.createProjectOpenHookMerger(new ProjectOpenedHookImpl()),
380
            new UnitTestForSourceQueryImpl(getSourceRoots(),getTestSourceRoots()),
390
            QuerySupport.createUnitTestForSourceQuery(getSourceRoots(), getTestSourceRoots()),
381
            new SourceLevelQueryImpl(evaluator()),
391
            QuerySupport.createSourceLevelQuery(evaluator()),
382
            new WebSources (this.helper, evaluator(), getSourceRoots(), getTestSourceRoots()),
392
            new WebSources (this.helper, evaluator(), getSourceRoots(), getTestSourceRoots()),
383
            new WebSharabilityQuery (this.helper, evaluator(), getSourceRoots(), getTestSourceRoots()), //Does not use APH to get/put properties/cfgdata
393
            QuerySupport.createSharabilityQuery(helper, evaluator(), getSourceRoots(), getTestSourceRoots(),
394
                    WebProjectProperties.WEB_DOCBASE_DIR),
384
            new RecommendedTemplatesImpl(),
395
            new RecommendedTemplatesImpl(),
385
            new WebFileBuiltQuery (this.helper, evaluator(),getSourceRoots(),getTestSourceRoots()),
396
            QuerySupport.createFileBuiltQuery(helper, evaluator(), getSourceRoots(), getTestSourceRoots()),
386
            classPathExtender,
397
            classPathExtender,
387
            buildExtender,
398
            buildExtender,
388
            cpMod,
399
            cpMod,
Lines 400-406 public final class WebProject implements Link Here
400
            new WebPropertyEvaluatorImpl(evaluator()),
411
            new WebPropertyEvaluatorImpl(evaluator()),
401
            WebProject.this, // never cast an externally obtained Project to WebProject - use lookup instead
412
            WebProject.this, // never cast an externally obtained Project to WebProject - use lookup instead
402
            libMod,
413
            libMod,
403
            new WebProjectEncodingQueryImpl(evaluator()),
414
            QuerySupport.createFileEncodingQuery(evaluator(), WebProjectProperties.SOURCE_ENCODING),
404
            new WebTemplateAttributesProvider(this.helper),
415
            new WebTemplateAttributesProvider(this.helper),
405
        });
416
        });
406
        return LookupProviderSupport.createCompositeLookup(base, "Projects/org-netbeans-modules-web-project/Lookup"); //NOI18N
417
        return LookupProviderSupport.createCompositeLookup(base, "Projects/org-netbeans-modules-web-project/Lookup"); //NOI18N
Lines 436-449 public final class WebProject implements Link Here
436
     */
447
     */
437
    public synchronized SourceRoots getSourceRoots() {
448
    public synchronized SourceRoots getSourceRoots() {
438
        if (this.sourceRoots == null) { //Local caching, no project metadata access
449
        if (this.sourceRoots == null) { //Local caching, no project metadata access
439
            this.sourceRoots = new SourceRoots(this.updateHelper, evaluator(), getReferenceHelper(), "source-roots", false, "src.{0}{1}.dir"); //NOI18N
450
            this.sourceRoots = SourceRootsSupport.create(updateHelper, evaluator(), getReferenceHelper(), WebProjectType.PROJECT_CONFIGURATION_NAMESPACE, "source-roots", false, "src.{0}{1}.dir"); //NOI18N
440
        }
451
        }
441
        return this.sourceRoots;
452
        return this.sourceRoots;
442
    }
453
    }
443
    public synchronized SourceRoots getTestSourceRoots() {
454
    public synchronized SourceRoots getTestSourceRoots() {
444
        if (this.testRoots == null) { //Local caching, no project metadata access
455
        if (this.testRoots == null) { //Local caching, no project metadata access
445
            this.testRoots = new SourceRoots(this.updateHelper, evaluator(), getReferenceHelper(), "test-roots", true, "test.{0}{1}.dir"); //NOI18N
456
            this.testRoots = SourceRootsSupport.create(this.updateHelper, evaluator(), getReferenceHelper(), WebProjectType.PROJECT_CONFIGURATION_NAMESPACE, "test-roots", true, "test.{0}{1}.dir"); //NOI18N
446
        }
457
        }
447
        return this.testRoots;
458
        return this.testRoots;
448
    }
459
    }
(-)a/web.project/src/org/netbeans/modules/web/project/WebProjectOperations.java (+1 lines)
Lines 49-54 import org.apache.tools.ant.module.api.s Link Here
49
import org.apache.tools.ant.module.api.support.ActionUtils;
49
import org.apache.tools.ant.module.api.support.ActionUtils;
50
import org.netbeans.api.project.Project;
50
import org.netbeans.api.project.Project;
51
import org.netbeans.api.project.ProjectManager;
51
import org.netbeans.api.project.ProjectManager;
52
import org.netbeans.modules.java.api.common.SourceRoots;
52
import org.netbeans.modules.web.project.classpath.WebProjectClassPathModifier;
53
import org.netbeans.modules.web.project.classpath.WebProjectClassPathModifier;
53
import org.netbeans.modules.web.project.ui.customizer.WebProjectProperties;
54
import org.netbeans.modules.web.project.ui.customizer.WebProjectProperties;
54
import org.netbeans.spi.project.ActionProvider;
55
import org.netbeans.spi.project.ActionProvider;
(-)a/web.project/src/org/netbeans/modules/web/project/WebSharabilityQuery.java (-131 lines)
Lines 1-131 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 1997-2007 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
 * Contributor(s):
25
 *
26
 * The Original Software is NetBeans. The Initial Developer of the Original
27
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
28
 * Microsystems, Inc. All Rights Reserved.
29
 *
30
 * If you wish your version of this file to be governed by only the CDDL
31
 * or only the GPL Version 2, indicate your decision by adding
32
 * "[Contributor] elects to include this software in this distribution
33
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
34
 * single choice of license, a recipient has the option to distribute
35
 * your version of this file under either the CDDL, the GPL Version 2 or
36
 * to extend the choice of license to its licensees as provided above.
37
 * However, if you add GPL Version 2 code and therefore, elected the GPL
38
 * Version 2 license, then the option applies only if the new code is
39
 * made subject to such option by the copyright holder.
40
 */
41
42
package org.netbeans.modules.web.project;
43
44
import java.io.File;
45
import java.beans.PropertyChangeEvent;
46
import java.beans.PropertyChangeListener;
47
import org.openide.util.Mutex;
48
import org.netbeans.api.project.ProjectManager;
49
import org.netbeans.spi.queries.SharabilityQueryImplementation;
50
import org.netbeans.spi.project.support.ant.AntProjectHelper;
51
import org.netbeans.spi.project.support.ant.PropertyEvaluator;
52
import org.netbeans.modules.web.project.ui.customizer.WebProjectProperties;
53
54
/**
55
 * SharabilityQueryImplementation for webproject with multiple sources
56
 */
57
public class WebSharabilityQuery implements SharabilityQueryImplementation, PropertyChangeListener {
58
59
    private final AntProjectHelper helper;
60
    private final PropertyEvaluator evaluator;
61
    private final SourceRoots srcRoots;
62
    private final SourceRoots testRoots;
63
    private SharabilityQueryImplementation delegate;
64
65
    /**
66
     * Creates new WebSharabilityQuery
67
     * @param helper AntProjectHelper
68
     * @param evaluator PropertyEvaluator
69
     * @param srcRoots sources
70
     * @param testRoots tests
71
     */
72
    WebSharabilityQuery (AntProjectHelper helper, PropertyEvaluator evaluator, SourceRoots srcRoots, SourceRoots testRoots) {
73
        this.helper = helper;
74
        this.evaluator = evaluator;
75
        this.srcRoots = srcRoots;
76
        this.testRoots = testRoots;
77
        this.srcRoots.addPropertyChangeListener(this);
78
        this.testRoots.addPropertyChangeListener(this);
79
    }
80
81
82
    /**
83
     * Check whether a file or directory should be shared.
84
     * If it is, it ought to be committed to a VCS if the user is using one.
85
     * If it is not, it is either a disposable build product, or a per-user
86
     * private file which is important but should not be shared.
87
     * @param file a file to check for sharability (may or may not yet exist)
88
     * @return one of {@link org.netbeans.api.queries.SharabilityQuery}'s constants
89
     */
90
    public int getSharability(final File file) {
91
        Integer ret = (Integer) ProjectManager.mutex().readAccess( new Mutex.Action() {
92
            public Object run() {
93
                synchronized (WebSharabilityQuery.this) {
94
                    if (delegate == null) {
95
                        delegate = createDelegate ();
96
                    }
97
                    return Integer.valueOf(delegate.getSharability (file));
98
                }
99
            }
100
        });
101
        return ret.intValue();
102
    }
103
104
    public void propertyChange(PropertyChangeEvent evt) {
105
        if (SourceRoots.PROP_ROOT_PROPERTIES.equals(evt.getPropertyName())) {
106
            synchronized (this) {
107
                this.delegate = null;
108
            }
109
        }
110
    }
111
112
    private SharabilityQueryImplementation createDelegate () {
113
        String[] srcProps = srcRoots.getRootProperties();
114
        String[] testProps = testRoots.getRootProperties();
115
        String[] props = new String [srcProps.length + testProps.length + 1];
116
        for (int i=0; i<srcProps.length; i++) {
117
            props[i] = "${"+srcProps[i]+"}";
118
        }
119
        for (int i=0; i<testProps.length; i++) {
120
            props[srcProps.length+i] = "${"+testProps[i]+"}";
121
        }
122
        props[props.length - 1] = "${" + WebProjectProperties.WEB_DOCBASE_DIR + "}";
123
        return helper.createSharabilityQuery(this.evaluator, props,
124
            new String[] {
125
                "${" + WebProjectProperties.DIST_DIR + "}", // NOI18N
126
                "${" + WebProjectProperties.BUILD_DIR + "}", // NOI18N
127
            });
128
    }
129
130
131
}
(-)a/web.project/src/org/netbeans/modules/web/project/WebSources.java (+1 lines)
Lines 56-61 import org.netbeans.api.project.ProjectM Link Here
56
import org.netbeans.api.project.ProjectManager;
56
import org.netbeans.api.project.ProjectManager;
57
import org.netbeans.api.project.FileOwnerQuery;
57
import org.netbeans.api.project.FileOwnerQuery;
58
import org.netbeans.api.java.project.JavaProjectConstants;
58
import org.netbeans.api.java.project.JavaProjectConstants;
59
import org.netbeans.modules.java.api.common.SourceRoots;
59
import org.netbeans.modules.web.api.webmodule.WebProjectConstants;
60
import org.netbeans.modules.web.api.webmodule.WebProjectConstants;
60
import org.netbeans.modules.web.project.ui.customizer.WebProjectProperties;
61
import org.netbeans.modules.web.project.ui.customizer.WebProjectProperties;
61
import org.netbeans.spi.project.support.ant.SourcesHelper;
62
import org.netbeans.spi.project.support.ant.SourcesHelper;
(-)a/web.project/src/org/netbeans/modules/web/project/api/WebProjectUtilities.java (-7 / +4 lines)
Lines 58-64 import org.netbeans.spi.project.support. Link Here
58
import org.netbeans.spi.project.support.ant.ReferenceHelper;
58
import org.netbeans.spi.project.support.ant.ReferenceHelper;
59
import org.openide.filesystems.FileObject;
59
import org.openide.filesystems.FileObject;
60
import org.openide.filesystems.FileSystem;
60
import org.openide.filesystems.FileSystem;
61
import org.openide.filesystems.FileSystem.AtomicAction;
62
import org.openide.filesystems.FileUtil;
61
import org.openide.filesystems.FileUtil;
63
import org.openide.filesystems.FileLock;
62
import org.openide.filesystems.FileLock;
64
import org.openide.filesystems.Repository;
63
import org.openide.filesystems.Repository;
Lines 83-101 import org.netbeans.api.queries.FileEnco Link Here
83
import org.netbeans.api.queries.FileEncodingQuery;
82
import org.netbeans.api.queries.FileEncodingQuery;
84
import org.netbeans.modules.j2ee.deployment.devmodules.api.J2eePlatform;
83
import org.netbeans.modules.j2ee.deployment.devmodules.api.J2eePlatform;
85
import org.netbeans.modules.web.project.classpath.ClassPathSupport;
86
import org.netbeans.modules.web.project.classpath.WebProjectClassPathExtender;
87
import org.netbeans.modules.web.project.ui.customizer.PlatformUiSupport;
88
import org.netbeans.modules.j2ee.common.FileSearchUtility;
84
import org.netbeans.modules.j2ee.common.FileSearchUtility;
89
import org.netbeans.modules.j2ee.dd.api.web.DDProvider;
85
import org.netbeans.modules.j2ee.dd.api.web.DDProvider;
90
import org.netbeans.modules.j2ee.dd.api.web.WebApp;
86
import org.netbeans.modules.j2ee.dd.api.web.WebApp;
91
import org.netbeans.modules.j2ee.dd.api.web.WelcomeFileList;
87
import org.netbeans.modules.j2ee.dd.api.web.WelcomeFileList;
88
import org.netbeans.modules.java.api.common.ant.UpdateHelper;
89
import org.netbeans.modules.java.api.common.ui.PlatformUiSupport;
92
import org.netbeans.modules.websvc.spi.webservices.WebServicesConstants;
90
import org.netbeans.modules.websvc.spi.webservices.WebServicesConstants;
93
import org.openide.filesystems.URLMapper;
91
import org.openide.filesystems.URLMapper;
94
import org.openide.loaders.DataFolder;
92
import org.openide.loaders.DataFolder;
95
import org.openide.loaders.DataObject;
93
import org.openide.loaders.DataObject;
96
import org.openide.modules.SpecificationVersion;
94
import org.openide.modules.SpecificationVersion;
97
import org.openide.util.Exceptions;
98
import org.w3c.dom.NodeList;
95
import org.w3c.dom.NodeList;
Lines 293-299 public class WebProjectUtilities { Link Here
293
        if (sourceLevel == null) {
290
        if (sourceLevel == null) {
294
            sourceLevel = "1.5"; // NOI18N
291
            sourceLevel = "1.5"; // NOI18N
295
        }
292
        }
296
        PlatformUiSupport.storePlatform(ep, updateHelper, javaPlatformName, new SpecificationVersion(sourceLevel));
293
        PlatformUiSupport.storePlatform(ep, updateHelper, WebProjectType.PROJECT_CONFIGURATION_NAMESPACE, javaPlatformName, new SpecificationVersion(sourceLevel));
297
        h.putProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH, ep);
294
        h.putProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH, ep);
Lines 571-577 public class WebProjectUtilities { Link Here
571
        // #89131: these levels are not actually distinct from 1.5.
568
        // #89131: these levels are not actually distinct from 1.5.
572
        if (sourceLevel != null && (sourceLevel.equals("1.6") || sourceLevel.equals("1.7")))
569
        if (sourceLevel != null && (sourceLevel.equals("1.6") || sourceLevel.equals("1.7")))
573
            sourceLevel = "1.5";
570
            sourceLevel = "1.5";
574
        PlatformUiSupport.storePlatform(ep, updateHelper, javaPlatformName, sourceLevel != null ? new SpecificationVersion(sourceLevel) : null);
571
        PlatformUiSupport.storePlatform(ep, updateHelper, WebProjectType.PROJECT_CONFIGURATION_NAMESPACE, javaPlatformName, sourceLevel != null ? new SpecificationVersion(sourceLevel) : null);
575
        // Utils.updateProperties() prevents problems caused by modification of properties in AntProjectHelper
572
        // Utils.updateProperties() prevents problems caused by modification of properties in AntProjectHelper
576
        // (e.g. during createForeignFileReference()) when local copy of properties is concurrently modified
573
        // (e.g. during createForeignFileReference()) when local copy of properties is concurrently modified
(-)a/web.project/src/org/netbeans/modules/web/project/classpath/ClassPathProviderImpl.java (-1 / +1 lines)
Lines 48-60 import java.util.HashMap; Link Here
48
import org.netbeans.api.java.classpath.ClassPath;
48
import org.netbeans.api.java.classpath.ClassPath;
49
import org.netbeans.api.project.SourceGroup;
49
import org.netbeans.api.project.SourceGroup;
50
import org.netbeans.modules.java.api.common.SourceRoots;
50
import org.netbeans.modules.web.project.ui.customizer.WebProjectProperties;
51
import org.netbeans.modules.web.project.ui.customizer.WebProjectProperties;
51
import org.netbeans.spi.java.classpath.ClassPathFactory;
52
import org.netbeans.spi.java.classpath.ClassPathFactory;
52
import org.netbeans.spi.java.classpath.ClassPathProvider;
53
import org.netbeans.spi.java.classpath.ClassPathProvider;
53
import org.netbeans.spi.java.classpath.support.ClassPathSupport;
54
import org.netbeans.spi.java.classpath.support.ClassPathSupport;
54
import org.netbeans.spi.project.support.ant.AntProjectHelper;
55
import org.netbeans.spi.project.support.ant.AntProjectHelper;
55
import org.netbeans.spi.project.support.ant.PropertyEvaluator;
56
import org.netbeans.spi.project.support.ant.PropertyEvaluator;
56
import org.netbeans.modules.web.project.SourceRoots;
57
import org.openide.filesystems.FileObject;
57
import org.openide.filesystems.FileObject;
58
import org.openide.filesystems.FileUtil;
58
import org.openide.filesystems.FileUtil;
59
import org.openide.util.WeakListeners;
59
import org.openide.util.WeakListeners;
(-)a/web.project/src/org/netbeans/modules/web/project/classpath/SourcePathImplementation.java (-1 / +1 lines)
Lines 52-62 import java.net.URL; Link Here
52
import java.net.URL;
52
import java.net.URL;
53
import java.util.Iterator;
53
import java.util.Iterator;
54
import java.util.StringTokenizer;
54
import java.util.StringTokenizer;
55
import org.netbeans.modules.java.api.common.SourceRoots;
55
import org.netbeans.modules.web.project.ui.customizer.WebProjectProperties;
56
import org.netbeans.modules.web.project.ui.customizer.WebProjectProperties;
56
import org.netbeans.spi.java.classpath.ClassPathImplementation;
57
import org.netbeans.spi.java.classpath.ClassPathImplementation;
57
import org.netbeans.spi.java.classpath.PathResourceImplementation;
58
import org.netbeans.spi.java.classpath.PathResourceImplementation;
58
import org.netbeans.spi.java.classpath.support.ClassPathSupport;
59
import org.netbeans.spi.java.classpath.support.ClassPathSupport;
59
import org.netbeans.modules.web.project.SourceRoots;
60
import org.netbeans.spi.project.support.ant.AntProjectHelper;
60
import org.netbeans.spi.project.support.ant.AntProjectHelper;
61
import org.openide.filesystems.FileChangeAdapter;
61
import org.openide.filesystems.FileChangeAdapter;
62
import org.openide.filesystems.FileChangeListener;
62
import org.openide.filesystems.FileChangeListener;
(-)a/web.project/src/org/netbeans/modules/web/project/classpath/WebProjectClassPathModifier.java (-1 / +1 lines)
Lines 59-65 import org.netbeans.api.project.ant.AntA Link Here
59
import org.netbeans.api.project.ant.AntArtifact;
59
import org.netbeans.api.project.ant.AntArtifact;
60
import org.netbeans.api.project.libraries.Library;
60
import org.netbeans.api.project.libraries.Library;
61
import org.netbeans.api.project.libraries.LibraryManager;
61
import org.netbeans.api.project.libraries.LibraryManager;
62
import org.netbeans.modules.web.project.UpdateHelper;
62
import org.netbeans.modules.java.api.common.ant.UpdateHelper;
63
import org.netbeans.modules.web.project.WebProject;
63
import org.netbeans.modules.web.project.WebProject;
64
import org.netbeans.modules.web.project.ui.customizer.WebProjectProperties;
64
import org.netbeans.modules.web.project.ui.customizer.WebProjectProperties;
65
import org.netbeans.spi.java.project.classpath.ProjectClassPathModifierImplementation;
65
import org.netbeans.spi.java.project.classpath.ProjectClassPathModifierImplementation;
(-)a/web.project/src/org/netbeans/modules/web/project/classpath/WebProjectLibrariesModifierImpl.java (-1 / +1 lines)
Lines 53-59 import org.netbeans.api.project.Project; Link Here
53
import org.netbeans.api.project.Project;
53
import org.netbeans.api.project.Project;
54
import org.netbeans.api.project.ProjectManager;
54
import org.netbeans.api.project.ProjectManager;
55
import org.netbeans.api.project.libraries.Library;
55
import org.netbeans.api.project.libraries.Library;
56
import org.netbeans.modules.web.project.UpdateHelper;
56
import org.netbeans.modules.java.api.common.ant.UpdateHelper;
57
import org.netbeans.modules.web.project.ui.customizer.WarIncludesUiSupport;
57
import org.netbeans.modules.web.project.ui.customizer.WarIncludesUiSupport;
58
import org.netbeans.modules.web.project.ui.customizer.WebProjectProperties;
58
import org.netbeans.modules.web.project.ui.customizer.WebProjectProperties;
59
import org.netbeans.spi.project.support.ant.AntProjectHelper;
59
import org.netbeans.spi.project.support.ant.AntProjectHelper;
(-)a/web.project/src/org/netbeans/modules/web/project/queries/CompiledSourceForBinaryQuery.java (-164 lines)
Lines 1-164 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 1997-2007 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
 * Contributor(s):
25
 *
26
 * The Original Software is NetBeans. The Initial Developer of the Original
27
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
28
 * Microsystems, Inc. All Rights Reserved.
29
 *
30
 * If you wish your version of this file to be governed by only the CDDL
31
 * or only the GPL Version 2, indicate your decision by adding
32
 * "[Contributor] elects to include this software in this distribution
33
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
34
 * single choice of license, a recipient has the option to distribute
35
 * your version of this file under either the CDDL, the GPL Version 2 or
36
 * to extend the choice of license to its licensees as provided above.
37
 * However, if you add GPL Version 2 code and therefore, elected the GPL
38
 * Version 2 license, then the option applies only if the new code is
39
 * made subject to such option by the copyright holder.
40
 */
41
package org.netbeans.modules.web.project.queries;
42
43
import java.io.File;
44
import org.netbeans.modules.web.project.ui.customizer.WebProjectProperties;
45
import org.netbeans.spi.java.queries.SourceForBinaryQueryImplementation;
46
import org.netbeans.spi.project.support.ant.AntProjectHelper;
47
import org.openide.filesystems.FileObject;
48
import org.openide.filesystems.FileUtil;
49
50
import java.net.URL;
51
import java.net.MalformedURLException;
52
import java.beans.PropertyChangeListener;
53
import java.beans.PropertyChangeEvent;
54
import java.util.Map;
55
import java.util.HashMap;
56
import javax.swing.event.ChangeListener;
57
58
import org.netbeans.api.java.queries.SourceForBinaryQuery;
59
import org.netbeans.spi.project.support.ant.PropertyEvaluator;
60
import org.netbeans.modules.web.project.SourceRoots;
61
import org.openide.util.ChangeSupport;
62
import org.openide.util.Exceptions;
63
64
/**
65
 * Finds sources corresponding to binaries in a J2SE project.
66
 * @author Jesse Glick, Tomas Zezula
67
 */
68
public class CompiledSourceForBinaryQuery implements SourceForBinaryQueryImplementation {
69
70
    private AntProjectHelper helper;
71
    private final PropertyEvaluator evaluator;
72
    private final SourceRoots sourceRoots;
73
    private final SourceRoots testRoots;
74
    private Map/*<URL,SourceForBinaryQuery.Result>*/  cache = new HashMap ();
75
76
    public CompiledSourceForBinaryQuery (AntProjectHelper helper, PropertyEvaluator evaluator, SourceRoots srcRoots, SourceRoots testRoots) {
77
        this.helper = helper;
78
        this.evaluator = evaluator;
79
        this.sourceRoots = srcRoots;
80
        this.testRoots = testRoots;
81
    }
82
83
    public SourceForBinaryQuery.Result findSourceRoots(URL binaryRoot) {
84
        if (FileUtil.getArchiveFile(binaryRoot) != null) {
85
            binaryRoot = FileUtil.getArchiveFile(binaryRoot);
86
            // XXX check whether this is really the root
87
        }
88
        SourceForBinaryQuery.Result res = (SourceForBinaryQuery.Result) cache.get (binaryRoot);
89
        if (res != null) {
90
            return res;
91
        }
92
        SourceRoots src = null;
93
        if (hasSources(binaryRoot, WebProjectProperties.BUILD_CLASSES_DIR)) {   //NOI18N
94
            src = this.sourceRoots;
95
        }
96
        else if (hasSources (binaryRoot, WebProjectProperties.DIST_WAR)) {      //NOI18N
97
            src = this.sourceRoots;
98
        }
99
        else if (hasSources (binaryRoot, WebProjectProperties.BUILD_TEST_CLASSES_DIR)) {    //NOI18N
100
            src = this.testRoots;
101
        }
102
        if (src == null) {
103
            return null;
104
        }
105
        else {
106
            res = new Result (src);
107
            cache.put (binaryRoot, res);
108
            return res;
109
        }
110
    }
111
112
113
    private boolean hasSources (URL binaryRoot, String binaryProperty) {
114
        try {
115
            String outDir = evaluator.getProperty(binaryProperty);
116
            if (outDir != null) {
117
                File f = helper.resolveFile (outDir);
118
                URL url = f.toURI().toURL();
119
                if (!f.exists() && !f.getPath().toLowerCase().endsWith(".jar")) { // NOI18N
120
                    // non-existing
121
                    assert !url.toExternalForm().endsWith("/") : f; // NOI18N
122
                    url = new URL(url.toExternalForm() + "/"); // NOI18N
123
                }
124
                if (url.equals (binaryRoot)) {
125
                    return true;
126
                }
127
            }
128
        } catch (MalformedURLException malformedURL) {
129
            Exceptions.printStackTrace(malformedURL);
130
        }
131
        return false;
132
    }
133
134
    private static class Result implements SourceForBinaryQuery.Result, PropertyChangeListener {
135
136
        private final ChangeSupport changeSupport = new ChangeSupport(this);
137
        private SourceRoots sourceRoots;
138
139
        public Result (SourceRoots sourceRoots) {
140
            this.sourceRoots = sourceRoots;
141
            this.sourceRoots.addPropertyChangeListener(this);
142
        }
143
144
        public FileObject[] getRoots () {
145
            return this.sourceRoots.getRoots(); //No need to cache it, SourceRoots does
146
        }
147
148
        public void addChangeListener (ChangeListener l) {
149
            changeSupport.addChangeListener(l);
150
        }
151
152
        public void removeChangeListener (ChangeListener l) {
153
            changeSupport.removeChangeListener(l);
154
        }
155
156
        public void propertyChange(PropertyChangeEvent evt) {
157
            if (SourceRoots.PROP_ROOTS.equals(evt.getPropertyName())) {
158
                this.changeSupport.fireChange ();
159
            }
160
        }
161
162
    }
163
164
}
(-)a/web.project/src/org/netbeans/modules/web/project/queries/JavadocForBinaryQueryImpl.java (-182 lines)
Lines 1-182 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 1997-2007 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
 * Contributor(s):
25
 *
26
 * The Original Software is NetBeans. The Initial Developer of the Original
27
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
28
 * Microsystems, Inc. All Rights Reserved.
29
 *
30
 * If you wish your version of this file to be governed by only the CDDL
31
 * or only the GPL Version 2, indicate your decision by adding
32
 * "[Contributor] elects to include this software in this distribution
33
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
34
 * single choice of license, a recipient has the option to distribute
35
 * your version of this file under either the CDDL, the GPL Version 2 or
36
 * to extend the choice of license to its licensees as provided above.
37
 * However, if you add GPL Version 2 code and therefore, elected the GPL
38
 * Version 2 license, then the option applies only if the new code is
39
 * made subject to such option by the copyright holder.
40
 */
41
package org.netbeans.modules.web.project.queries;
42
43
import java.beans.PropertyChangeEvent;
44
import java.beans.PropertyChangeListener;
45
import java.io.File;
46
import org.netbeans.spi.project.support.ant.AntProjectHelper;
47
import org.openide.filesystems.FileUtil;
48
import java.net.URL;
49
import java.net.MalformedURLException;
50
import javax.swing.event.ChangeListener;
51
import org.netbeans.api.java.queries.JavadocForBinaryQuery;
52
import org.netbeans.modules.web.project.ui.customizer.WebProjectProperties;
53
import org.netbeans.spi.java.queries.JavadocForBinaryQueryImplementation;
54
import org.netbeans.spi.project.support.ant.PropertyEvaluator;
55
import org.openide.util.ChangeSupport;
56
import org.openide.util.Exceptions;
57
import org.openide.util.WeakListeners;
58
59
/**
60
 * Finds Javadoc (if it is built) corresponding to binaries in web project.
61
 * @author David Konecny, Jesse Glick
62
 */
63
public class JavadocForBinaryQueryImpl implements JavadocForBinaryQueryImplementation {
64
65
    private final AntProjectHelper helper;
66
    private final PropertyEvaluator evaluator;
67
68
    public JavadocForBinaryQueryImpl(AntProjectHelper helper, PropertyEvaluator evaluator) {
69
        this.helper = helper;
70
        this.evaluator = evaluator;
71
    }
72
73
    public JavadocForBinaryQuery.Result findJavadoc(final URL binaryRoot) {
74
75
        class R implements JavadocForBinaryQuery.Result, PropertyChangeListener  {
76
77
            private final ChangeSupport changeSupport = new ChangeSupport(this);
78
            private URL[] result;
79
80
            public R () {
81
                JavadocForBinaryQueryImpl.this.evaluator.addPropertyChangeListener (WeakListeners.propertyChange(this,JavadocForBinaryQueryImpl.this.evaluator));
82
            }
83
84
            public synchronized URL[] getRoots() {
85
                if (this.result == null) {
86
                    String javadocDir = evaluator.getProperty(WebProjectProperties.DIST_JAVADOC_DIR);
87
                    if (javadocDir != null) {
88
                        File f = helper.resolveFile(javadocDir);
89
                        try {
90
                            URL url = f.toURI().toURL();
91
                            if (!f.exists()) {
92
                                assert !url.toExternalForm().endsWith("/") : f; // NOI18N
93
                                url = new URL(url.toExternalForm() + "/"); // NOI18N
94
                            }
95
                            this.result = new URL[] {url};
96
                        } catch (MalformedURLException e) {
97
                            this.result = new URL[0];
98
                            Exceptions.printStackTrace(e);
99
                        }
100
                    }
101
                    else {
102
                        this.result = new URL[0];
103
                    }
104
                }
105
                return this.result;
106
            }
107
            public void addChangeListener(final ChangeListener l) {
108
                assert l != null;
109
                changeSupport.addChangeListener(l);
110
            }
111
            public void removeChangeListener(final ChangeListener l) {
112
                assert l != null;
113
                changeSupport.removeChangeListener(l);
114
            }
115
116
            public void propertyChange (final PropertyChangeEvent event) {
117
                if (WebProjectProperties.DIST_JAVADOC_DIR.equals(event.getPropertyName())) {
118
                    synchronized (this) {
119
                        result = null;
120
                    }
121
                    this.changeSupport.fireChange ();
122
                }
123
            }
124
        }
125
        if (isRootOwner(binaryRoot, WebProjectProperties.BUILD_CLASSES_DIR) || isRootOwner (binaryRoot, WebProjectProperties.DIST_WAR)) {
126
            return new R();
127
        }
128
        return null;
129
    }
130
131
    private boolean isRootOwner (URL binaryRoot, String binaryProperty) {
132
        try {
133
            if (FileUtil.getArchiveFile(binaryRoot) != null) {
134
                binaryRoot = FileUtil.getArchiveFile(binaryRoot);
135
                // XXX check whether this is really the root
136
            }
137
            String outDir = evaluator.getProperty(binaryProperty);
138
            if (outDir != null) {
139
                File f = helper.resolveFile (outDir);
140
                URL url = f.toURI().toURL();
141
                if (!f.exists() && !f.getPath().toLowerCase().endsWith(".jar")) { // NOI18N
142
                    assert !url.toExternalForm().endsWith("/") : f; // NOI18N
143
                    url = new URL(url.toExternalForm() + "/"); // NOI18N
144
                }
145
                return url.equals(binaryRoot) ||
146
                        binaryRoot.toExternalForm().startsWith(url.toExternalForm());
147
            }
148
        } catch (MalformedURLException malformedURL) {
149
            Exceptions.printStackTrace(malformedURL);
150
        }
151
        return false;
152
    }
153
154
//    private URL getJavadoc(URL binaryRoot, String binaryProperty, String javadocProperty) {
155
//        try {
156
//            if (FileUtil.getArchiveFile(binaryRoot) != null) {
157
//                binaryRoot = FileUtil.getArchiveFile(binaryRoot);
158
//            }
159
//            String outDir = evaluator.getProperty(binaryProperty);
160
//            if (outDir != null) {
161
//                File f = helper.resolveFile (outDir);
162
//                URL url = f.toURI().toURL();
163
//                if (!f.exists() && !f.getPath().toLowerCase().endsWith(".jar")) {
164
//                    assert !url.toExternalForm().endsWith("/") : f;
165
//                    url = new URL(url.toExternalForm() + "/");
166
//                }
167
//                if (url.equals(binaryRoot) ||
168
//                        binaryRoot.toExternalForm().startsWith(url.toExternalForm())) {
169
//                    String javadocDir = evaluator.getProperty(javadocProperty);
170
//                    if (javadocDir != null) {
171
//                        f = helper.resolveFile(javadocDir);
172
//                        return f.toURI().toURL();
173
//                    }
174
//                }
175
//            }
176
//        } catch (MalformedURLException malformedURL) {
177
//            ErrorManager.getDefault().notify(malformedURL);
178
//        }
179
//        return null;
180
//    }
181
182
}
(-)a/web.project/src/org/netbeans/modules/web/project/queries/SourceLevelQueryImpl.java (-97 lines)
Lines 1-97 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 1997-2007 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
 * Contributor(s):
25
 *
26
 * The Original Software is NetBeans. The Initial Developer of the Original
27
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
28
 * Microsystems, Inc. All Rights Reserved.
29
 *
30
 * If you wish your version of this file to be governed by only the CDDL
31
 * or only the GPL Version 2, indicate your decision by adding
32
 * "[Contributor] elects to include this software in this distribution
33
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
34
 * single choice of license, a recipient has the option to distribute
35
 * your version of this file under either the CDDL, the GPL Version 2 or
36
 * to extend the choice of license to its licensees as provided above.
37
 * However, if you add GPL Version 2 code and therefore, elected the GPL
38
 * Version 2 license, then the option applies only if the new code is
39
 * made subject to such option by the copyright holder.
40
 */
41
package org.netbeans.modules.web.project.queries;
42
43
import org.openide.filesystems.FileObject;
44
45
import org.netbeans.api.java.platform.JavaPlatform;
46
import org.netbeans.api.java.platform.JavaPlatformManager;
47
import org.netbeans.api.java.platform.Specification;
48
import org.netbeans.spi.java.queries.SourceLevelQueryImplementation;
49
import org.netbeans.spi.project.support.ant.PropertyEvaluator;
50
import org.netbeans.spi.project.support.ant.PropertyUtils;
51
import org.netbeans.spi.project.support.ant.EditableProperties;
52
53
/**
54
 * Returns source level of project sources.
55
 * @author David Konecny
56
 */
57
public class SourceLevelQueryImpl implements SourceLevelQueryImplementation {
58
59
    private final PropertyEvaluator evaluator;
60
61
    public SourceLevelQueryImpl(PropertyEvaluator evaluator) {
62
        this.evaluator = evaluator;
63
    }
64
65
    public String getSourceLevel(FileObject javaFile) {
66
        boolean platformExists = false;
67
        String activePlatform = evaluator.getProperty ("platform.active");  //NOI18N
68
        if (activePlatform != null && activePlatform.length()>0) {
69
            JavaPlatform[] j2sePlatforms = JavaPlatformManager.getDefault().getPlatforms(null, new Specification("j2se",null)); //NOI18N
70
            for (int i=0; i< j2sePlatforms.length; i++) {
71
                String antName = (String) j2sePlatforms[i].getProperties().get("platform.ant.name");        //NOI18N
72
                if (antName != null && antName.equals(activePlatform)) {
73
                    platformExists = true;
74
                    break;
75
                }
76
            }
77
        }
78
        if (platformExists) {
79
            String sl = evaluator.getProperty("javac.source");  //NOI18N
80
            if (sl != null && sl.length() > 0) {
81
                return sl;
82
            } else {
83
                return null;
84
            }
85
        }
86
        else {
87
            EditableProperties props = PropertyUtils.getGlobalProperties();
88
            String sl = (String) props.get("default.javac.source"); //NOI18N
89
            if (sl != null && sl.length() > 0) {
90
                return sl;
91
            } else {
92
                return null;
93
            }
94
        }
95
    }
96
97
}
(-)a/web.project/src/org/netbeans/modules/web/project/queries/UnitTestForSourceQueryImpl.java (-82 lines)
Lines 1-82 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 1997-2007 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
 * Contributor(s):
25
 *
26
 * The Original Software is NetBeans. The Initial Developer of the Original
27
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
28
 * Microsystems, Inc. All Rights Reserved.
29
 *
30
 * If you wish your version of this file to be governed by only the CDDL
31
 * or only the GPL Version 2, indicate your decision by adding
32
 * "[Contributor] elects to include this software in this distribution
33
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
34
 * single choice of license, a recipient has the option to distribute
35
 * your version of this file under either the CDDL, the GPL Version 2 or
36
 * to extend the choice of license to its licensees as provided above.
37
 * However, if you add GPL Version 2 code and therefore, elected the GPL
38
 * Version 2 license, then the option applies only if the new code is
39
 * made subject to such option by the copyright holder.
40
 */
41
package org.netbeans.modules.web.project.queries;
42
43
import java.net.URL;
44
import org.netbeans.api.project.FileOwnerQuery;
45
import org.netbeans.api.project.Project;
46
import org.netbeans.spi.java.queries.MultipleRootsUnitTestForSourceQueryImplementation;
47
import org.netbeans.modules.web.project.SourceRoots;
48
import org.openide.filesystems.FileObject;
49
50
public class UnitTestForSourceQueryImpl implements MultipleRootsUnitTestForSourceQueryImplementation {
51
52
    private final SourceRoots sourceRoots;
53
    private final SourceRoots testRoots;
54
55
    public UnitTestForSourceQueryImpl(SourceRoots sourceRoots, SourceRoots testRoots) {
56
        this.sourceRoots = sourceRoots;
57
        this.testRoots = testRoots;
58
    }
59
60
    public URL[] findUnitTests(FileObject source) {
61
        return find(source, sourceRoots, testRoots); // NOI18N
62
    }
63
64
    public URL[] findSources(FileObject unitTest) {
65
        return find(unitTest, testRoots, sourceRoots); // NOI18N
66
    }
67
68
    private URL[] find(FileObject file, SourceRoots from, SourceRoots to) {
69
        Project p = FileOwnerQuery.getOwner(file);
70
        if (p == null) {
71
            return null;
72
        }
73
        FileObject[] fromRoots = from.getRoots();
74
        for (int i = 0; i < fromRoots.length; i++) {
75
            if (fromRoots[i].equals(file)) {
76
                return to.getRootURLs();
77
            }
78
        }
79
        return null;
80
    }
81
82
}
(-)a/web.project/src/org/netbeans/modules/web/project/queries/WebProjectEncodingQueryImpl.java (-100 lines)
Lines 1-100 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 1997-2007 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
 * Contributor(s):
25
 *
26
 * The Original Software is NetBeans. The Initial Developer of the Original
27
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
28
 * Microsystems, Inc. All Rights Reserved.
29
 *
30
 * If you wish your version of this file to be governed by only the CDDL
31
 * or only the GPL Version 2, indicate your decision by adding
32
 * "[Contributor] elects to include this software in this distribution
33
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
34
 * single choice of license, a recipient has the option to distribute
35
 * your version of this file under either the CDDL, the GPL Version 2 or
36
 * to extend the choice of license to its licensees as provided above.
37
 * However, if you add GPL Version 2 code and therefore, elected the GPL
38
 * Version 2 license, then the option applies only if the new code is
39
 * made subject to such option by the copyright holder.
40
 */
41
42
package org.netbeans.modules.web.project.queries;
43
44
import java.beans.PropertyChangeEvent;
45
import java.beans.PropertyChangeListener;
46
import java.nio.charset.Charset;
47
import java.nio.charset.IllegalCharsetNameException;
48
import org.netbeans.api.queries.FileEncodingQuery;
49
import org.netbeans.modules.web.project.ui.customizer.WebProjectProperties;
50
import org.netbeans.spi.queries.FileEncodingQueryImplementation;
51
import org.netbeans.spi.project.support.ant.PropertyEvaluator;
52
import org.openide.filesystems.FileObject;
53
54
/**
55
 *
56
 * @author Tomas Zezula
57
 */
58
public class WebProjectEncodingQueryImpl extends FileEncodingQueryImplementation implements PropertyChangeListener {
59
60
61
    private final PropertyEvaluator eval;
62
    private Charset cache;
63
64
    /** Creates a new instance of J2SEProjectEncodingQueryImpl */
65
    public WebProjectEncodingQueryImpl(final PropertyEvaluator eval) {
66
        assert eval != null;
67
        this.eval = eval;
68
        this.eval.addPropertyChangeListener(this);
69
    }
70
71
    public Charset getEncoding(FileObject file) {
72
        assert file != null;
73
        synchronized (this) {
74
            if (cache != null) {
75
                return cache;
76
            }
77
        }
78
        String enc = eval.getProperty(WebProjectProperties.SOURCE_ENCODING);
79
        synchronized (this) {
80
            if (cache == null) {
81
                try {
82
                    cache = enc == null ? Charset.defaultCharset() : Charset.forName(enc);
83
                } catch (IllegalCharsetNameException exception) {
84
                    return null;
85
                }
86
            }
87
            return cache;
88
        }
89
    }
90
91
    public void propertyChange(PropertyChangeEvent event) {
92
        String propName = event.getPropertyName();
93
        if (propName == null || propName.equals(WebProjectProperties.SOURCE_ENCODING)) {
94
            synchronized (this) {
95
                cache = null;
96
            }
97
        }
98
    }
99
100
}
(-)a/web.project/src/org/netbeans/modules/web/project/ui/ActionFilterNode.java (-1 / +1 lines)
Lines 65-76 import org.netbeans.api.project.FileOwne Link Here
65
import org.netbeans.api.project.FileOwnerQuery;
65
import org.netbeans.api.project.FileOwnerQuery;
66
import org.netbeans.api.project.Project;
66
import org.netbeans.api.project.Project;
67
import org.netbeans.api.java.queries.JavadocForBinaryQuery;
67
import org.netbeans.api.java.queries.JavadocForBinaryQuery;
68
import org.netbeans.modules.java.api.common.ant.UpdateHelper;
68
import org.netbeans.spi.project.support.ant.AntProjectHelper;
69
import org.netbeans.spi.project.support.ant.AntProjectHelper;
69
import org.netbeans.spi.project.support.ant.EditableProperties;
70
import org.netbeans.spi.project.support.ant.EditableProperties;
70
import org.netbeans.spi.project.support.ant.PropertyEvaluator;
71
import org.netbeans.spi.project.support.ant.PropertyEvaluator;
71
import org.netbeans.spi.project.support.ant.ReferenceHelper;
72
import org.netbeans.spi.project.support.ant.ReferenceHelper;
72
import org.netbeans.modules.web.project.UpdateHelper;
73
import org.netbeans.modules.web.project.classpath.ClassPathSupport;
73
import org.netbeans.modules.web.project.classpath.ClassPathSupport;
74
import org.netbeans.modules.web.project.ui.customizer.WebProjectProperties;
74
import org.netbeans.modules.web.project.ui.customizer.WebProjectProperties;
75
import org.openide.nodes.FilterNode.Children;
75
import org.openide.nodes.FilterNode.Children;
(-)a/web.project/src/org/netbeans/modules/web/project/ui/DocBaseNodeFactory.java (-1 / +1 lines)
Lines 58-64 import org.netbeans.api.project.Project; Link Here
58
import org.netbeans.api.project.Project;
58
import org.netbeans.api.project.Project;
59
import org.netbeans.api.project.ProjectManager;
59
import org.netbeans.api.project.ProjectManager;
60
import org.netbeans.api.queries.VisibilityQuery;
60
import org.netbeans.api.queries.VisibilityQuery;
61
import org.netbeans.modules.web.project.UpdateHelper;
61
import org.netbeans.modules.java.api.common.ant.UpdateHelper;
62
import org.netbeans.modules.web.project.WebProject;
62
import org.netbeans.modules.web.project.WebProject;
63
import org.netbeans.modules.web.project.ui.SourceNodeFactory.PreselectPropertiesAction;
63
import org.netbeans.modules.web.project.ui.SourceNodeFactory.PreselectPropertiesAction;
64
import org.netbeans.modules.web.project.ui.customizer.WebProjectProperties;
64
import org.netbeans.modules.web.project.ui.customizer.WebProjectProperties;
(-)a/web.project/src/org/netbeans/modules/web/project/ui/LibrariesNode.java (-2 / +1 lines)
Lines 92-97 import org.netbeans.api.java.classpath.C Link Here
92
import org.netbeans.api.java.classpath.ClassPath;
92
import org.netbeans.api.java.classpath.ClassPath;
93
import org.netbeans.api.java.project.JavaProjectConstants;
93
import org.netbeans.api.java.project.JavaProjectConstants;
94
import org.netbeans.api.java.project.classpath.ProjectClassPathModifier;
94
import org.netbeans.api.java.project.classpath.ProjectClassPathModifier;
95
import org.netbeans.modules.java.api.common.ant.UpdateHelper;
95
import org.netbeans.spi.project.support.ant.AntProjectHelper;
96
import org.netbeans.spi.project.support.ant.AntProjectHelper;
96
import org.netbeans.spi.project.support.ant.EditableProperties;
97
import org.netbeans.spi.project.support.ant.EditableProperties;
97
import org.netbeans.spi.project.support.ant.PropertyEvaluator;
98
import org.netbeans.spi.project.support.ant.PropertyEvaluator;
Lines 99-112 import org.netbeans.spi.project.support. Link Here
99
import org.netbeans.spi.project.support.ant.ReferenceHelper;
100
import org.netbeans.spi.project.support.ant.ReferenceHelper;
100
import org.netbeans.spi.java.project.support.ui.PackageView;
101
import org.netbeans.spi.java.project.support.ui.PackageView;
101
import org.netbeans.spi.java.classpath.support.ClassPathSupport;
102
import org.netbeans.spi.java.classpath.support.ClassPathSupport;
102
import org.netbeans.modules.web.project.UpdateHelper;
103
import org.netbeans.modules.web.api.webmodule.WebModule;
103
import org.netbeans.modules.web.api.webmodule.WebModule;
104
import org.netbeans.modules.web.project.WebProject;
104
import org.netbeans.modules.web.project.WebProject;
105
import org.netbeans.modules.web.project.ui.customizer.AntArtifactChooser;
105
import org.netbeans.modules.web.project.ui.customizer.AntArtifactChooser;
106
import org.netbeans.modules.web.project.ui.customizer.WebProjectProperties;
106
import org.netbeans.modules.web.project.ui.customizer.WebProjectProperties;
107
import org.netbeans.modules.web.project.ui.customizer.LibrariesChooser;
107
import org.netbeans.modules.web.project.ui.customizer.LibrariesChooser;
108
import org.netbeans.spi.project.libraries.support.LibrariesSupport;
108
import org.netbeans.spi.project.libraries.support.LibrariesSupport;
109
import org.openide.ErrorManager;
110
import org.openide.util.Exceptions;
109
import org.openide.util.Exceptions;
111
import org.openide.util.lookup.Lookups;
110
import org.openide.util.lookup.Lookups;
(-)a/web.project/src/org/netbeans/modules/web/project/ui/LibrariesNodeFactory.java (-2 / +2 lines)
Lines 52-59 import javax.swing.SwingUtilities; Link Here
52
import javax.swing.SwingUtilities;
52
import javax.swing.SwingUtilities;
53
import javax.swing.event.ChangeListener;
53
import javax.swing.event.ChangeListener;
54
import org.netbeans.api.project.Project;
54
import org.netbeans.api.project.Project;
55
import org.netbeans.modules.web.project.SourceRoots;
55
import org.netbeans.modules.java.api.common.SourceRoots;
56
import org.netbeans.modules.web.project.UpdateHelper;
56
import org.netbeans.modules.java.api.common.ant.UpdateHelper;
57
import org.netbeans.modules.web.project.WebProject;
57
import org.netbeans.modules.web.project.WebProject;
58
import org.netbeans.modules.web.project.ui.customizer.CustomizerLibraries;
58
import org.netbeans.modules.web.project.ui.customizer.CustomizerLibraries;
59
import org.netbeans.modules.web.project.ui.customizer.WebProjectProperties;
59
import org.netbeans.modules.web.project.ui.customizer.WebProjectProperties;
(-)a/web.project/src/org/netbeans/modules/web/project/ui/ProjectNode.java (-1 / +1 lines)
Lines 72-83 import org.netbeans.api.project.ant.AntA Link Here
72
import org.netbeans.api.project.ant.AntArtifact;
72
import org.netbeans.api.project.ant.AntArtifact;
73
import org.netbeans.api.project.ui.OpenProjects;
73
import org.netbeans.api.project.ui.OpenProjects;
74
import org.netbeans.api.java.queries.JavadocForBinaryQuery;
74
import org.netbeans.api.java.queries.JavadocForBinaryQuery;
75
import org.netbeans.modules.java.api.common.ant.UpdateHelper;
75
import org.netbeans.spi.project.support.ant.EditableProperties;
76
import org.netbeans.spi.project.support.ant.EditableProperties;
76
import org.netbeans.spi.project.support.ant.AntProjectHelper;
77
import org.netbeans.spi.project.support.ant.AntProjectHelper;
77
import org.netbeans.spi.project.support.ant.PropertyEvaluator;
78
import org.netbeans.spi.project.support.ant.PropertyEvaluator;
78
import org.netbeans.spi.project.support.ant.ReferenceHelper;
79
import org.netbeans.spi.project.support.ant.ReferenceHelper;
79
import org.netbeans.modules.web.project.ui.customizer.WebProjectProperties;
80
import org.netbeans.modules.web.project.ui.customizer.WebProjectProperties;
80
import org.netbeans.modules.web.project.UpdateHelper;
81
import org.openide.filesystems.FileObject;
81
import org.openide.filesystems.FileObject;
82
import org.openide.util.Exceptions;
82
import org.openide.util.Exceptions;
83
import org.openide.util.Lookup;
83
import org.openide.util.Lookup;
(-)a/web.project/src/org/netbeans/modules/web/project/ui/WebLogicalViewProvider.java (-3 / +3 lines)
Lines 108-116 import org.netbeans.modules.j2ee.deploym Link Here
108
import org.netbeans.modules.j2ee.deployment.devmodules.api.J2eeModule;
108
import org.netbeans.modules.j2ee.deployment.devmodules.api.J2eeModule;
109
import org.netbeans.modules.j2ee.deployment.devmodules.spi.InstanceListener;
109
import org.netbeans.modules.j2ee.deployment.devmodules.spi.InstanceListener;
110
import org.netbeans.modules.j2ee.deployment.devmodules.spi.J2eeModuleProvider;
110
import org.netbeans.modules.j2ee.deployment.devmodules.spi.J2eeModuleProvider;
111
import org.netbeans.modules.java.api.common.SourceRoots;
112
import org.netbeans.modules.java.api.common.ant.UpdateHelper;
111
import org.netbeans.modules.web.api.webmodule.WebProjectConstants;
113
import org.netbeans.modules.web.api.webmodule.WebProjectConstants;
112
import org.netbeans.modules.web.project.SourceRoots;
113
import org.netbeans.modules.web.project.UpdateHelper;
114
import org.netbeans.modules.web.project.WebProject;
114
import org.netbeans.modules.web.project.WebProject;
115
import org.netbeans.modules.web.project.ui.customizer.WebProjectProperties;
115
import org.netbeans.modules.web.project.ui.customizer.WebProjectProperties;
116
import org.netbeans.spi.project.AuxiliaryConfiguration;
116
import org.netbeans.spi.project.AuxiliaryConfiguration;
Lines 581-587 public class WebLogicalViewProvider impl Link Here
581
            public void actionPerformed(ActionEvent e) {
581
            public void actionPerformed(ActionEvent e) {
582
                try {
582
                try {
583
                    helper.requestSave();
583
                    helper.requestUpdate();
584
                    BrokenReferencesSupport.showCustomizer(helper.getAntProjectHelper(), resolver, getBreakableProperties(), new String[]{WebProjectProperties.JAVA_PLATFORM});
584
                    BrokenReferencesSupport.showCustomizer(helper.getAntProjectHelper(), resolver, getBreakableProperties(), new String[]{WebProjectProperties.JAVA_PLATFORM});
585
                    run();
585
                    run();
586
                } catch (IOException ioe) {
586
                } catch (IOException ioe) {
(-)a/web.project/src/org/netbeans/modules/web/project/ui/customizer/CustomizerLibraries.java (+1 lines)
Lines 53-58 import javax.swing.table.TableColumn; Link Here
53
import javax.swing.table.TableColumn;
53
import javax.swing.table.TableColumn;
54
import org.netbeans.api.java.platform.JavaPlatform;
54
import org.netbeans.api.java.platform.JavaPlatform;
55
import org.netbeans.api.java.platform.PlatformsCustomizer;
55
import org.netbeans.api.java.platform.PlatformsCustomizer;
56
import org.netbeans.modules.java.api.common.ui.PlatformUiSupport;
56
import org.netbeans.modules.web.project.classpath.ClassPathSupport;
57
import org.netbeans.modules.web.project.classpath.ClassPathSupport;
57
import org.netbeans.modules.web.project.ui.WebLogicalViewProvider;
58
import org.netbeans.modules.web.project.ui.WebLogicalViewProvider;
58
import org.openide.util.HelpCtx;
59
import org.openide.util.HelpCtx;
(-)a/web.project/src/org/netbeans/modules/web/project/ui/customizer/CustomizerProviderImpl.java (-1 / +1 lines)
Lines 51-58 import java.util.Map; Link Here
51
import java.util.Map;
51
import java.util.Map;
52
import org.netbeans.api.project.Project;
52
import org.netbeans.api.project.Project;
53
import org.netbeans.api.project.ProjectUtils;
53
import org.netbeans.api.project.ProjectUtils;
54
import org.netbeans.modules.java.api.common.ant.UpdateHelper;
54
import org.netbeans.modules.web.project.WebProject;
55
import org.netbeans.modules.web.project.WebProject;
55
import org.netbeans.modules.web.project.UpdateHelper;
56
import org.netbeans.spi.project.support.ant.PropertyEvaluator;
56
import org.netbeans.spi.project.support.ant.PropertyEvaluator;
57
import org.netbeans.spi.project.support.ant.ReferenceHelper;
57
import org.netbeans.spi.project.support.ant.ReferenceHelper;
58
import org.netbeans.spi.project.ui.CustomizerProvider;
58
import org.netbeans.spi.project.ui.CustomizerProvider;
(-)a/web.project/src/org/netbeans/modules/web/project/ui/customizer/PlatformUiSupport.java (-690 lines)
Lines 1-690 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 1997-2007 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
 * Contributor(s):
25
 *
26
 * The Original Software is NetBeans. The Initial Developer of the Original
27
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
28
 * Microsystems, Inc. All Rights Reserved.
29
 *
30
 * If you wish your version of this file to be governed by only the CDDL
31
 * or only the GPL Version 2, indicate your decision by adding
32
 * "[Contributor] elects to include this software in this distribution
33
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
34
 * single choice of license, a recipient has the option to distribute
35
 * your version of this file under either the CDDL, the GPL Version 2 or
36
 * to extend the choice of license to its licensees as provided above.
37
 * However, if you add GPL Version 2 code and therefore, elected the GPL
38
 * Version 2 license, then the option applies only if the new code is
39
 * made subject to such option by the copyright holder.
40
 */
41
42
package org.netbeans.modules.web.project.ui.customizer;
43
44
import java.awt.Component;
45
import java.beans.PropertyChangeEvent;
46
import java.beans.PropertyChangeListener;
47
import java.text.MessageFormat;
48
import java.util.ArrayList;
49
import java.util.List;
50
import java.util.Set;
51
import java.util.TreeSet;
52
import java.util.logging.Level;
53
import java.util.logging.Logger;
54
import javax.swing.AbstractListModel;
55
import javax.swing.ComboBoxModel;
56
import javax.swing.DefaultListCellRenderer;
57
import javax.swing.JButton;
58
import javax.swing.JList;
59
import javax.swing.ListCellRenderer;
60
import javax.swing.event.ListDataEvent;
61
import javax.swing.event.ListDataListener;
62
import org.netbeans.api.java.platform.JavaPlatform;
63
import org.netbeans.api.java.platform.JavaPlatformManager;
64
import org.netbeans.api.java.platform.Specification;
65
import org.netbeans.modules.j2ee.deployment.devmodules.api.J2eeModule;
66
import org.netbeans.modules.web.project.WebProjectType;
67
import org.netbeans.modules.web.project.UpdateHelper;
68
import org.netbeans.spi.project.support.ant.EditableProperties;
69
import org.openide.DialogDisplayer;
70
import org.openide.NotifyDescriptor;
71
import org.openide.awt.HtmlRenderer;
72
import org.openide.modules.SpecificationVersion;
73
import org.openide.util.NbBundle;
74
import org.openide.util.WeakListeners;
75
import org.w3c.dom.Element;
76
import org.w3c.dom.NodeList;
77
78
/**
79
 * Support class for {@link JavaPlatform} manipulation in webproject customizer.
80
 * @author tzezula
81
 */
82
public class PlatformUiSupport {
83
84
    private static final SpecificationVersion JDK_5 = new SpecificationVersion ("1.5");  //NOI18N
85
    private static final SpecificationVersion JDK_6 = new SpecificationVersion ("1.6");  //NOI18N
86
    private static final Logger LOGGER = Logger.getLogger(PlatformUiSupport.class.getName());
87
88
    private PlatformUiSupport() {
89
    }
90
91
    /**
92
     * Creates {@link ComboBoxModel} of J2SE platforms.
93
     * The model listens on the {@link JavaPlatformManager} and update its
94
     * state according to changes
95
     * @param activePlatform the active project's platform
96
     * @return {@link ComboBoxModel}
97
     */
98
    public static ComboBoxModel createPlatformComboBoxModel (String activePlatform) {
99
        return new PlatformComboBoxModel (activePlatform);
100
    }
101
102
    /**
103
     * Creates a {@link ListCellRenderer} for rendering items of the {@link ComboBoxModel}
104
     * created by the {@link PlatformUiSupport#createPlatformComboBoxModel} method.
105
     * @return {@link ListCellRenderer}
106
     */
107
    public static ListCellRenderer createPlatformListCellRenderer () {
108
        return new PlatformListCellRenderer ();
109
    }
110
111
    /**
112
     * Like {@link #storePlatform}, but platformName may be null (in which case the default platform is used)
113
     */
114
    public static void storePlatform (EditableProperties props, UpdateHelper helper, String platformName, SpecificationVersion sourceLevel) {
115
        PlatformKey platformKey;
116
        if (platformName != null) {
117
            platformKey = new PlatformKey(PlatformUiSupport.findPlatform(platformName));
118
        } else {
119
            platformKey = new PlatformKey(JavaPlatformManager.getDefault().getDefaultPlatform());
120
        }
121
        storePlatform(props, helper, platformKey, sourceLevel == null ? null : new SourceLevelKey(sourceLevel));
122
    }
123
124
    /**
125
     * Stores active platform, javac.source and javac.target into the project's metadata
126
     * @param props project's shared properties
127
     * @param helper to read/update project.xml
128
     * @param platformKey the PatformKey got from the platform model
129
     * @param sourceLevel source level
130
     */
131
    public static void storePlatform (EditableProperties props, UpdateHelper helper, Object platformKey, Object sourceLevelKey) {
132
        assert platformKey instanceof PlatformKey;
133
        PlatformKey pk = (PlatformKey) platformKey;
134
        JavaPlatform platform = getPlatform(pk);
135
        //null means active broken (unresolved) platform, no need to do anything
136
        if (platform != null) {
137
            SpecificationVersion jdk13 = new SpecificationVersion ("1.3");  //NOI18N
138
            String platformAntName = platform.getProperties().get("platform.ant.name");    //NOI18N
139
            assert platformAntName != null;
140
            props.put(WebProjectProperties.JAVA_PLATFORM, platformAntName);
141
            Element root = helper.getPrimaryConfigurationData(true);
142
            boolean defaultPlatform = pk.isDefaultPlatform();
143
            boolean changed = false;
144
            NodeList explicitPlatformNodes = root.getElementsByTagNameNS (WebProjectType.PROJECT_CONFIGURATION_NAMESPACE,"explicit-platform");   //NOI18N
145
            if (defaultPlatform) {
146
                if (explicitPlatformNodes.getLength()==1) {
147
                    root.removeChild(explicitPlatformNodes.item(0));
148
                    changed = true;
149
                }
150
            }
151
            else {
152
                Element explicitPlatform;
153
                switch (explicitPlatformNodes.getLength()) {
154
                    case 0:
155
                        explicitPlatform = root.getOwnerDocument().createElementNS(WebProjectType.PROJECT_CONFIGURATION_NAMESPACE, "explicit-platform"); //NOI18N
156
                        NodeList sourceRootNodes = root.getElementsByTagNameNS (WebProjectType.PROJECT_CONFIGURATION_NAMESPACE,"source-roots");   //NOI18N
157
                        assert sourceRootNodes.getLength() == 1 : "Broken project.xml file"; //NOI18N
158
                        root.insertBefore(explicitPlatform, sourceRootNodes.item(0));
159
                        changed = true;
160
                        break;
161
                    case 1:
162
                        explicitPlatform = (Element)explicitPlatformNodes.item(0);
163
                        break;
164
                    default:
165
                        throw new AssertionError("Broken project.xml file");   //NOI18N
166
                }
167
                String explicitSourceAttrValue = explicitPlatform.getAttribute("explicit-source-supported");    //NOI18N
168
                if (jdk13.compareTo(platform.getSpecification().getVersion())>=0 &&
169
                    !"false".equals(explicitSourceAttrValue)) {   //NOI18N
170
                    explicitPlatform.setAttribute("explicit-source-supported","false"); //NOI18N
171
                    changed = true;
172
                }
173
                else if (jdk13.compareTo(platform.getSpecification().getVersion())<0 &&
174
                    !"true".equals(explicitSourceAttrValue)) {  //NOI18N
175
                    explicitPlatform.setAttribute("explicit-source-supported","true"); //NOI18N
176
                    changed = true;
177
                }
178
            }
179
180
            SpecificationVersion sourceLevel;
181
            if (sourceLevelKey == null) {
182
                sourceLevel = platform.getSpecification().getVersion();
183
            }
184
            else {
185
                assert sourceLevelKey instanceof SourceLevelKey;
186
                sourceLevel = ((SourceLevelKey)sourceLevelKey).getSourceLevel();
187
            }
188
            String javacSource = sourceLevel.toString();
189
            String javacTarget = javacSource;
190
191
            //Issue #116490
192
            // Customizer value | -source | -targer
193
            // JDK 1.2            1.2        1.1
194
            // JDK 1.3            1.3        1.1
195
            // JDK 1.4            1.4        1.4
196
            // JDK 5              1.5        1.5
197
            // JDK 6              1.5        1.6
198
            // JDK 7              1.7        1.7  - should bring a new language features
199
            if (jdk13.compareTo(sourceLevel)>=0) {
200
                javacTarget = "1.1";        //NOI18N
201
            }
202
            else if (JDK_6.equals(sourceLevel)) {
203
                javacSource = JDK_5.toString();        //NOI18N
204
            }
205
206
            // #89131: these levels are not actually distinct from 1.5.
207
            if (javacSource.equals("1.6") || javacSource.equals("1.7")) {
208
                javacSource = "1.5";
209
            }
210
            if (!javacSource.equals(props.getProperty(WebProjectProperties.JAVAC_SOURCE))) {
211
                props.setProperty (WebProjectProperties.JAVAC_SOURCE, javacSource);
212
            }
213
            if (!javacTarget.equals(props.getProperty(WebProjectProperties.JAVAC_TARGET))) {
214
                props.setProperty (WebProjectProperties.JAVAC_TARGET, javacTarget);
215
            }
216
217
            if (changed) {
218
                helper.putPrimaryConfigurationData(root, true);
219
            }
220
        }
221
    }
222
223
    public static JavaPlatform findPlatform(String displayName) {
224
        JavaPlatform[] platforms = JavaPlatformManager.getDefault().getPlatforms(displayName, new Specification("j2se", null)); //NOI18N
225
        return platforms.length == 0 ? null : platforms[0];
226
    }
227
228
229
    /**
230
     * Returns a {@link JavaPlatform} for an item obtained from the ComboBoxModel created by
231
     * the {@link PlatformUiSupport#createComboBoxModel} method
232
     * @param platformKey an item obtained from ComboBoxModel created by {@link PlatformUiSupport#createComboBoxModel}
233
     * @return JavaPlatform or null in case when platform is broken
234
     * @exception {@link IllegalArgumentException} is thrown in case when parameter in not an object created by
235
     * platform combobox model.
236
     */
237
    public static JavaPlatform getPlatform (Object platformKey) {
238
       if (platformKey instanceof PlatformKey) {
239
           return getPlatform ((PlatformKey)platformKey);
240
       }
241
       else {
242
           throw new IllegalArgumentException ();
243
       }
244
    }
245
246
    /**
247
     * Creates {@link ComboBoxModel} of source levels for active platform.
248
     * The model listens on the platform's {@link ComboBoxModel} and update its
249
     * state according to changes
250
     * @param platformComboBoxModel the platform's model used for listenning
251
     * @param initialSourceLevel initial source level value
252
     * @param initialTargetLevel initial target level value
253
     * @return {@link ComboBoxModel} of {@link SpecificationVersion}
254
     */
255
    public static ComboBoxModel createSourceLevelComboBoxModel(ComboBoxModel platformComboBoxModel, String initialSourceLevel, String initialTargetLevel, String j2eePlatform) {
256
        return new SourceLevelComboBoxModel(platformComboBoxModel, initialSourceLevel, initialTargetLevel, j2eePlatform);
257
    }
258
259
    public static ListCellRenderer createSourceLevelListCellRenderer() {
260
        return new SourceLevelListCellRenderer();
261
    }
262
263
    private static JavaPlatform getPlatform (PlatformKey platformKey) {
264
        return platformKey.platform;
265
    }
266
267
    /**
268
     * This class represents a  JavaPlatform in the {@link ListModel}
269
     * created by the {@link PlatformUiSupport#createPlatformComboBoxModel}
270
     * method.
271
     */
272
    private static class PlatformKey implements Comparable {
273
274
        private String name;
275
        private JavaPlatform platform;
276
277
        /**
278
         * Creates a PlatformKey for a broken platform
279
         * @param name the ant name of the broken platform
280
         */
281
        public PlatformKey (String name) {
282
            assert name != null;
283
            this.name = name;
284
        }
285
286
        /**
287
         * Creates a PlatformKey for a platform
288
         * @param platform the {@link JavaPlatform}
289
         */
290
        public PlatformKey (JavaPlatform platform) {
291
            assert platform != null;
292
            this.platform = platform;
293
        }
294
295
        public int compareTo(Object o) {
296
            return this.getDisplayName().compareTo(((PlatformKey)o).getDisplayName());
297
        }
298
299
        public boolean equals (Object other) {
300
            if (other instanceof PlatformKey) {
301
                PlatformKey otherKey = (PlatformKey)other;
302
                return (this.platform == null ? otherKey.platform == null : this.platform.equals(otherKey.platform)) &&
303
                       otherKey.getDisplayName().equals (this.getDisplayName());
304
            }
305
            else {
306
                return false;
307
            }
308
        }
309
310
        public int hashCode () {
311
            return getDisplayName ().hashCode ();
312
        }
313
314
        public String toString () {
315
            return getDisplayName ();
316
        }
317
318
        public synchronized String getDisplayName () {
319
            if (this.name == null) {
320
                this.name = this.platform.getDisplayName();
321
            }
322
            return this.name;
323
        }
324
325
        public boolean isDefaultPlatform () {
326
            if (this.platform == null) {
327
                return false;
328
            }
329
            return this.platform.equals(JavaPlatformManager.getDefault().getDefaultPlatform());
330
        }
331
332
        public boolean isBroken () {
333
            return this.platform == null;
334
        }
335
336
    }
337
338
    private static final class SourceLevelKey implements Comparable {
339
340
        final SpecificationVersion sourceLevel;
341
        final boolean broken;
342
343
        public SourceLevelKey (final SpecificationVersion sourceLevel) {
344
            this (sourceLevel, false);
345
        }
346
347
        public SourceLevelKey (final SpecificationVersion sourceLevel, final boolean broken) {
348
            assert sourceLevel != null : "Source level cannot be null";     //NOI18N
349
            this.sourceLevel = sourceLevel;
350
            this.broken = broken;
351
        }
352
353
        public SpecificationVersion getSourceLevel () {
354
            return this.sourceLevel;
355
        }
356
357
        public boolean isBroken () {
358
            return this.broken;
359
        }
360
361
        public int compareTo (final Object other) {
362
            assert other instanceof SourceLevelKey : "Illegal argument of SourceLevelKey.compareTo()";  //NOI18N
363
            SourceLevelKey otherKey = (SourceLevelKey) other;
364
            return this.sourceLevel.compareTo(otherKey.sourceLevel);
365
        }
366
367
        public @Override boolean equals (final Object other) {
368
            return (other instanceof SourceLevelKey) &&
369
                   ((SourceLevelKey)other).sourceLevel.equals(this.sourceLevel);
370
        }
371
372
        public @Override int hashCode () {
373
            return this.sourceLevel.hashCode();
374
        }
375
376
        public @Override String toString () {
377
            StringBuffer buffer = new StringBuffer ();
378
            if (this.broken) {
379
                buffer.append("Broken: ");      //NOI18N
380
            }
381
            buffer.append(this.sourceLevel.toString());
382
            return buffer.toString();
383
        }
384
385
        public String getDisplayName () {
386
            String _tmp = sourceLevel.toString();
387
            if (JDK_5.compareTo(sourceLevel)<=0) {
388
                _tmp = _tmp.replaceFirst("^1\\.([5-9]|\\d\\d+)$", "$1");        //NOI18N
389
            }
390
            return NbBundle.getMessage(PlatformUiSupport.class, "LBL_JDK",_tmp);
391
        }
392
393
    }
394
395
    private static class PlatformComboBoxModel extends AbstractListModel implements ComboBoxModel, PropertyChangeListener {
396
397
        private final JavaPlatformManager pm;
398
        private PlatformKey[] platformNamesCache;
399
        private String initialPlatform;
400
        private PlatformKey selectedPlatform;
401
402
        public PlatformComboBoxModel (String initialPlatform) {
403
            this.pm = JavaPlatformManager.getDefault();
404
            this.pm.addPropertyChangeListener(WeakListeners.propertyChange(this, this.pm));
405
            this.initialPlatform = initialPlatform;
406
        }
407
408
        public int getSize () {
409
            PlatformKey[] platformNames = getPlatformNames ();
410
            return platformNames.length;
411
        }
412
413
        public Object getElementAt (int index) {
414
            PlatformKey[] platformNames = getPlatformNames ();
415
            assert index >=0 && index< platformNames.length;
416
            return platformNames[index];
417
        }
418
419
        public Object getSelectedItem () {
420
            this.getPlatformNames(); //Force setting of selectedPlatform if it is not alredy done
421
            return this.selectedPlatform;
422
        }
423
424
        public void setSelectedItem (Object obj) {
425
            this.selectedPlatform = (PlatformKey) obj;
426
            this.fireContentsChanged(this, -1, -1);
427
        }
428
429
        public void propertyChange (PropertyChangeEvent event) {
430
            if (JavaPlatformManager.PROP_INSTALLED_PLATFORMS.equals(event.getPropertyName())) {
431
                synchronized (this) {
432
                    this.platformNamesCache = null;
433
                }
434
                this.fireContentsChanged(this, -1, -1);
435
            }
436
        }
437
438
        private synchronized PlatformKey[] getPlatformNames () {
439
            if (this.platformNamesCache == null) {
440
                JavaPlatform[] platforms = pm.getPlatforms (null, new Specification("j2se",null));    //NOI18N
441
                Set/*<PlatformKey>*/ orderedNames = new TreeSet ();
442
                boolean activeFound = false;
443
                for (int i=0; i< platforms.length; i++) {
444
                    if (platforms[i].getInstallFolders().size()>0) {
445
                        PlatformKey pk = new PlatformKey(platforms[i]);
446
                        orderedNames.add (pk);
447
                        if (!activeFound && initialPlatform != null) {
448
                            String antName = (String) platforms[i].getProperties().get("platform.ant.name");    //NOI18N
449
                            if (initialPlatform.equals(antName)) {
450
                                if (this.selectedPlatform == null) {
451
                                    this.selectedPlatform = pk;
452
                                    initialPlatform = null;
453
                                }
454
                                activeFound = true;
455
                            }
456
                        }
457
                    }
458
                }
459
                if (!activeFound) {
460
                    if (initialPlatform == null) {
461
                        if (this.selectedPlatform == null || !orderedNames.contains(this.selectedPlatform)) {
462
                            this.selectedPlatform = new PlatformKey (JavaPlatformManager.getDefault().getDefaultPlatform());
463
                        }
464
                    }
465
                    else {
466
                        PlatformKey pk = new PlatformKey (this.initialPlatform);
467
                        orderedNames.add (pk);
468
                        if (this.selectedPlatform == null) {
469
                            this.selectedPlatform = pk;
470
                        }
471
                    }
472
                }
473
                this.platformNamesCache = (PlatformKey[]) orderedNames.toArray(new PlatformKey[orderedNames.size()]);
474
            }
475
            return this.platformNamesCache;
476
        }
477
478
    }
479
480
    private static class PlatformListCellRenderer extends DefaultListCellRenderer {
481
482
        public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
483
            assert value instanceof PlatformKey : "Wrong model";  //NOI18N
484
            PlatformKey key = (PlatformKey) value;
485
            String name;
486
            if (key.isBroken()) {
487
                name = NbBundle.getMessage (PlatformUiSupport.class,"TXT_BrokenPlatformFmt", key.getDisplayName());
488
            }
489
            else {
490
                name = key.getDisplayName();
491
            }
492
            return super.getListCellRendererComponent(list, name, index, isSelected, cellHasFocus);
493
        }
494
    }
495
496
    private static class SourceLevelComboBoxModel extends AbstractListModel implements ComboBoxModel, ListDataListener {
497
498
        private static final String VERSION_PREFIX = "1.";      //The version prefix
499
        private static final int INITIAL_VERSION_MINOR = 2;     //1.2
500
        // if project is JAVA EE 5 show only 1.5 and higher
501
        private static final int INITIAL_VERSION_MINOR_JAVA_EE_5 = 5;     // 1.5
502
503
        private SpecificationVersion selectedSourceLevel;
504
        private SpecificationVersion originalSourceLevel;
505
        private SourceLevelKey[] sourceLevelCache;
506
        private final ComboBoxModel platformComboBoxModel;
507
        private PlatformKey activePlatform;
508
        private String j2eePlatform = null;
509
510
        public SourceLevelComboBoxModel(ComboBoxModel platformComboBoxModel, String initialSourceLevel, String initialTargetLevel) {
511
            this.platformComboBoxModel = platformComboBoxModel;
512
            this.activePlatform = (PlatformKey) this.platformComboBoxModel.getSelectedItem();
513
            this.platformComboBoxModel.addListDataListener(this);
514
            if (initialSourceLevel != null && initialSourceLevel.length()>0) {
515
                try {
516
                    originalSourceLevel = new SpecificationVersion (initialSourceLevel);
517
                } catch (NumberFormatException nfe) {
518
                    // If the javac.source has invalid value, do not preselect and log it.
519
                    LOGGER.log(Level.INFO, "Invalid javac.source: " + initialSourceLevel);
520
                }
521
            }
522
            if (initialTargetLevel != null && initialTargetLevel.length() > 0) {
523
                try {
524
                    SpecificationVersion originalTargetLevel = new SpecificationVersion (initialTargetLevel);
525
                    if (this.originalSourceLevel == null || this.originalSourceLevel.compareTo(originalTargetLevel)<0) {
526
                        this.originalSourceLevel = originalTargetLevel;
527
                    }
528
                } catch (NumberFormatException nfe) {
529
                    //If the javac.target has invalid value, do not preselect and log it
530
                    LOGGER.warning("Invalid javac.target: "+initialTargetLevel);       //NOI18N
531
                }
532
            }
533
            this.selectedSourceLevel = this.originalSourceLevel;
534
        }
535
536
        public SourceLevelComboBoxModel(ComboBoxModel platformComboBoxModel, String initialSourceLevel, String initialTargetLevel, String j2eePlatform) {
537
            this(platformComboBoxModel, initialSourceLevel, initialTargetLevel);
538
            this.j2eePlatform = j2eePlatform;
539
        }
540
541
        public int getSize() {
542
            SourceLevelKey[] sLevels = getSourceLevels();
543
            return sLevels.length;
544
        }
545
546
        public Object getElementAt(int index) {
547
            SourceLevelKey[] sLevels = getSourceLevels();
548
            assert index >=0 && index< sLevels.length;
549
            return sLevels[index];
550
        }
551
552
        public Object getSelectedItem () {
553
            SourceLevelKey[] keys = getSourceLevels();
554
            for (int i=0; i<keys.length; i++) {
555
                if (keys[i].getSourceLevel().equals(this.selectedSourceLevel)) {
556
                    return keys[i];
557
                }
558
            }
559
            return null;
560
        }
561
562
        public void setSelectedItem (Object obj) {
563
            this.selectedSourceLevel = (obj == null ? null : ((SourceLevelKey) obj).getSourceLevel());
564
            this.fireContentsChanged(this, -1, -1);
565
        }
566
567
        public void intervalAdded(ListDataEvent e) {
568
        }
569
570
        public void intervalRemoved(ListDataEvent e) {
571
        }
572
573
        public void contentsChanged(ListDataEvent e) {
574
            PlatformKey selectedPlatform = (PlatformKey) this.platformComboBoxModel.getSelectedItem();
575
            JavaPlatform platform = getPlatform(selectedPlatform);
576
            if (platform != null) {
577
                SpecificationVersion version = platform.getSpecification().getVersion();
578
                if (this.selectedSourceLevel != null && this.selectedSourceLevel.compareTo(version)>0 &&
579
                        !shouldChangePlatform(selectedSourceLevel, version)) {
580
                    //Restore original
581
                    this.platformComboBoxModel.setSelectedItem(this.activePlatform);
582
                    return;
583
                }
584
                else {
585
                    this.originalSourceLevel = null;
586
                }
587
            }
588
            this.activePlatform = selectedPlatform;
589
            resetCache();
590
        }
591
592
        private void resetCache() {
593
            synchronized (this) {
594
                this.sourceLevelCache = null;
595
            }
596
            this.fireContentsChanged(this, -1, -1);
597
        }
598
599
        private SourceLevelKey[] getSourceLevels() {
600
            if (this.sourceLevelCache == null) {
601
                PlatformKey selectedPlatform = (PlatformKey) this.platformComboBoxModel.getSelectedItem();
602
                JavaPlatform platform = getPlatform(selectedPlatform);
603
                List<SourceLevelKey> sLevels = new ArrayList<SourceLevelKey>();
604
                //If platform == null broken platform, the source level range is unknown
605
                //The source level combo box should be empty and disabled
606
                boolean selSourceLevelValid = false;
607
                if (platform != null) {
608
                    SpecificationVersion version = platform.getSpecification().getVersion();
609
                    int index = INITIAL_VERSION_MINOR;
610
                    // #71619 - source level lower than 1.5 won't be shown for Java EE 5 project
611
                    if (j2eePlatform != null && j2eePlatform.equals(J2eeModule.JAVA_EE_5)) {
612
                        index = INITIAL_VERSION_MINOR_JAVA_EE_5;
613
                    }
614
                    SpecificationVersion template = new SpecificationVersion (VERSION_PREFIX + Integer.toString (index++));
615
                    boolean origSourceLevelValid = false;
616
617
                    while (template.compareTo(version)<=0) {
618
                        if (template.equals(this.originalSourceLevel)) {
619
                            origSourceLevelValid = true;
620
                        }
621
                        if (template.equals(this.selectedSourceLevel)) {
622
                            selSourceLevelValid = true;
623
                        }
624
                        sLevels.add (new SourceLevelKey (template));
625
                        template = new SpecificationVersion (VERSION_PREFIX + Integer.toString (index++));
626
                    }
627
                    if (this.originalSourceLevel != null && !origSourceLevelValid) {
628
                        if (originalSourceLevel.equals(this.selectedSourceLevel)) {
629
                            selSourceLevelValid = true;
630
                        }
631
                        sLevels.add (new SourceLevelKey(this.originalSourceLevel,true));
632
                    }
633
                }
634
                this.sourceLevelCache = sLevels.toArray(new SourceLevelKey[sLevels.size()]);
635
                if (!selSourceLevelValid) {
636
                    this.selectedSourceLevel = this.sourceLevelCache.length == 0 ?
637
                        null : this.sourceLevelCache[this.sourceLevelCache.length-1].getSourceLevel();
638
                }
639
            }
640
            return this.sourceLevelCache;
641
        }
642
643
        private static boolean shouldChangePlatform (SpecificationVersion selectedSourceLevel, SpecificationVersion platformSourceLevel) {
644
            JButton changeOption = new JButton (NbBundle.getMessage(PlatformUiSupport.class, "CTL_ChangePlatform"));
645
            changeOption.getAccessibleContext().setAccessibleDescription(NbBundle.getMessage(PlatformUiSupport.class, "AD_ChangePlatform"));
646
            String message = MessageFormat.format (NbBundle.getMessage(PlatformUiSupport.class,"TXT_ChangePlatform"),new Object[] {
647
                selectedSourceLevel.toString(),
648
                platformSourceLevel.toString(),
649
            });
650
            return DialogDisplayer.getDefault().notify(
651
                new NotifyDescriptor (message,
652
                        NbBundle.getMessage(PlatformUiSupport.class,"TXT_ChangePlatformTitle"),
653
                        NotifyDescriptor.DEFAULT_OPTION,
654
                        NotifyDescriptor.WARNING_MESSAGE,
655
                        new Object[] {
656
                            changeOption,
657
                            NotifyDescriptor.CANCEL_OPTION
658
                        },
659
                        changeOption)) == changeOption;
660
        }
661
    }
662
663
    private static class SourceLevelListCellRenderer implements ListCellRenderer {
664
665
        ListCellRenderer delegate;
666
667
        public SourceLevelListCellRenderer() {
668
            this.delegate = HtmlRenderer.createRenderer();
669
        }
670
671
        public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
672
            String message;
673
            if (value == null) {
674
                message = "";   //NOI18N
675
            }
676
            else {
677
                assert value instanceof SourceLevelKey;
678
                SourceLevelKey key = (SourceLevelKey) value;
679
                if (key.isBroken()) {
680
                    message = "<html><font color=\"#A40000\">" +    //NOI18N
681
                        NbBundle.getMessage(PlatformUiSupport.class,"TXT_InvalidSourceLevel",key.getDisplayName());
682
                }
683
                else {
684
                    message = key.getDisplayName();
685
                }
686
            }
687
            return this.delegate.getListCellRendererComponent(list, message, index, isSelected, cellHasFocus);
688
        }
689
    }
690
}
(-)a/web.project/src/org/netbeans/modules/web/project/ui/customizer/WebProjectProperties.java (-7 / +12 lines)
Lines 65-78 import org.netbeans.modules.j2ee.deploym Link Here
65
import org.netbeans.modules.j2ee.deployment.devmodules.api.AntDeploymentHelper;
65
import org.netbeans.modules.j2ee.deployment.devmodules.api.AntDeploymentHelper;
66
import org.netbeans.modules.web.project.ProjectWebModule;
66
import org.netbeans.modules.web.project.ProjectWebModule;
67
import org.netbeans.modules.web.project.SourceRoots;
68
import org.netbeans.modules.web.project.classpath.ClassPathSupport;
67
import org.netbeans.modules.web.project.classpath.ClassPathSupport;
69
import org.netbeans.modules.web.spi.webmodule.WebModuleExtender;
68
import org.netbeans.modules.web.spi.webmodule.WebModuleExtender;
70
import org.netbeans.spi.project.support.ant.PropertyEvaluator;
69
import org.netbeans.spi.project.support.ant.PropertyEvaluator;
71
import org.netbeans.spi.project.support.ant.ui.StoreGroup;
70
import org.netbeans.spi.project.support.ant.ui.StoreGroup;
72
import org.openide.filesystems.FileUtil;
71
import org.openide.filesystems.FileUtil;
73
import org.openide.modules.SpecificationVersion;
74
import org.openide.util.MutexException;
72
import org.openide.util.MutexException;
75
import org.openide.util.Mutex;
73
import org.openide.util.Mutex;
76
import org.netbeans.api.project.Project;
74
import org.netbeans.api.project.Project;
Lines 82-97 import org.netbeans.modules.j2ee.deploym Link Here
82
import org.netbeans.modules.j2ee.deployment.devmodules.api.Deployment;
80
import org.netbeans.modules.j2ee.deployment.devmodules.api.Deployment;
83
import org.netbeans.modules.j2ee.deployment.devmodules.api.J2eeModule;
81
import org.netbeans.modules.j2ee.deployment.devmodules.api.J2eeModule;
84
import org.netbeans.modules.j2ee.deployment.devmodules.api.J2eePlatform;
82
import org.netbeans.modules.j2ee.deployment.devmodules.api.J2eePlatform;
83
import org.netbeans.modules.java.api.common.SourceRoots;
84
import org.netbeans.modules.java.api.common.ant.UpdateHelper;
85
import org.netbeans.modules.java.api.common.ui.PlatformUiSupport;
86
import org.netbeans.modules.web.project.UpdateProjectImpl;
85
import org.netbeans.spi.project.support.ant.AntProjectHelper;
87
import org.netbeans.spi.project.support.ant.AntProjectHelper;
86
import org.netbeans.spi.project.support.ant.EditableProperties;
88
import org.netbeans.spi.project.support.ant.EditableProperties;
87
import org.netbeans.spi.project.support.ant.PropertyUtils;
89
import org.netbeans.spi.project.support.ant.PropertyUtils;
88
import org.netbeans.spi.project.support.ant.ReferenceHelper;
90
import org.netbeans.spi.project.support.ant.ReferenceHelper;
89
import org.netbeans.modules.web.project.WebProjectUtil;
91
import org.netbeans.modules.web.project.WebProjectUtil;
90
import org.netbeans.modules.web.project.UpdateHelper;
91
import org.netbeans.modules.web.project.Utils;
92
import org.netbeans.modules.web.project.Utils;
92
import org.netbeans.modules.web.project.WebProject;
93
import org.netbeans.modules.web.project.WebProject;
94
import org.netbeans.modules.web.project.WebProjectType;
93
import org.netbeans.modules.web.project.classpath.ClassPathSupport.Item;
95
import org.netbeans.modules.web.project.classpath.ClassPathSupport.Item;
94
import org.netbeans.modules.web.spi.webmodule.WebFrameworkProvider;
95
import org.netbeans.modules.websvc.spi.webservices.WebServicesConstants;
96
import org.netbeans.modules.websvc.spi.webservices.WebServicesConstants;
96
import org.openide.filesystems.FileObject;
97
import org.openide.filesystems.FileObject;
97
import org.openide.filesystems.URLMapper;
98
import org.openide.filesystems.URLMapper;
Lines 292-298 public class WebProjectProperties { Link Here
292
        this.updateHelper = updateHelper;
293
        this.updateHelper = updateHelper;
293
        //this is called from updatehelper when user confirms the project update
294
        //this is called from updatehelper when user confirms the project update
294
        updateHelper.setProjectUpdateListener(new UpdateHelper.ProjectUpdateListener() {
295
        project.getUpdateImplementation().setProjectUpdateListener(new UpdateProjectImpl.ProjectUpdateListener() {
295
            public void projectUpdated() {
296
            public void projectUpdated() {
296
                needsUpdate = true;
297
                needsUpdate = true;
297
            }
298
            }
Lines 337-343 public class WebProjectProperties { Link Here
337
        RUN_TEST_CLASSPATH_MODEL = ClassPathUiSupport.createListModel( cs.itemsIterator( (String)projectProperties.get( RUN_TEST_CLASSPATH ), null ) );
338
        RUN_TEST_CLASSPATH_MODEL = ClassPathUiSupport.createListModel( cs.itemsIterator( (String)projectProperties.get( RUN_TEST_CLASSPATH ), null ) );
338
        PLATFORM_MODEL = PlatformUiSupport.createPlatformComboBoxModel (evaluator.getProperty(JAVA_PLATFORM));
339
        PLATFORM_MODEL = PlatformUiSupport.createPlatformComboBoxModel (evaluator.getProperty(JAVA_PLATFORM));
339
        PLATFORM_LIST_RENDERER = PlatformUiSupport.createPlatformListCellRenderer();
340
        PLATFORM_LIST_RENDERER = PlatformUiSupport.createPlatformListCellRenderer();
340
        JAVAC_SOURCE_MODEL = PlatformUiSupport.createSourceLevelComboBoxModel (PLATFORM_MODEL, evaluator.getProperty(JAVAC_SOURCE), evaluator.getProperty(JAVAC_TARGET), evaluator.getProperty(J2EE_PLATFORM));
341
        PlatformUiSupport.JDK minimalSourceLevel = null;
342
        if (evaluator.getProperty(J2EE_PLATFORM).equals(J2eeModule.JAVA_EE_5)) {
343
            minimalSourceLevel = PlatformUiSupport.JDK.VERSION_5;
344
        }
345
        JAVAC_SOURCE_MODEL = PlatformUiSupport.createSourceLevelComboBoxModel (PLATFORM_MODEL, evaluator.getProperty(JAVAC_SOURCE), evaluator.getProperty(JAVAC_TARGET), minimalSourceLevel);
341
        JAVAC_SOURCE_RENDERER = PlatformUiSupport.createSourceLevelListCellRenderer ();
346
        JAVAC_SOURCE_RENDERER = PlatformUiSupport.createSourceLevelListCellRenderer ();
342
        // CustomizerCompile
347
        // CustomizerCompile
Lines 530-536 public class WebProjectProperties { Link Here
530
        projectProperties.setProperty( WAR_CONTENT_ADDITIONAL, war_includes );
535
        projectProperties.setProperty( WAR_CONTENT_ADDITIONAL, war_includes );
531
        //Handle platform selection and javac.source javac.target properties
536
        //Handle platform selection and javac.source javac.target properties
532
        PlatformUiSupport.storePlatform (projectProperties, updateHelper, PLATFORM_MODEL.getSelectedItem(), JAVAC_SOURCE_MODEL.getSelectedItem());
537
        PlatformUiSupport.storePlatform (projectProperties, updateHelper, WebProjectType.PROJECT_CONFIGURATION_NAMESPACE, PLATFORM_MODEL.getSelectedItem(), JAVAC_SOURCE_MODEL.getSelectedItem());
533
        // Handle other special cases
538
        // Handle other special cases
534
        if ( NO_DEPENDENCIES_MODEL.isSelected() ) { // NOI18N
539
        if ( NO_DEPENDENCIES_MODEL.isSelected() ) { // NOI18N
(-)a/web.project/src/org/netbeans/modules/web/project/ui/customizer/WebSourceRootsUi.java (-1 / +1 lines)
Lines 64-70 import org.netbeans.api.project.FileOwne Link Here
64
import org.netbeans.api.project.FileOwnerQuery;
64
import org.netbeans.api.project.FileOwnerQuery;
65
import org.netbeans.api.project.Project;
65
import org.netbeans.api.project.Project;
66
import org.netbeans.api.project.ProjectInformation;
66
import org.netbeans.api.project.ProjectInformation;
67
import org.netbeans.modules.web.project.SourceRoots;
67
import org.netbeans.modules.java.api.common.SourceRoots;
68
import org.openide.DialogDisplayer;
68
import org.openide.DialogDisplayer;
69
import org.openide.DialogDescriptor;
69
import org.openide.DialogDescriptor;
70
import org.openide.filesystems.FileUtil;
70
import org.openide.filesystems.FileUtil;
(-)a/web.project/test/unit/src/org/netbeans/modules/web/project/SourceRootsTest.java (+1 lines)
Lines 53-58 import org.netbeans.junit.NbTestCase; Link Here
53
import org.netbeans.junit.NbTestCase;
53
import org.netbeans.junit.NbTestCase;
54
import org.netbeans.api.project.ProjectManager;
54
import org.netbeans.api.project.ProjectManager;
55
import org.netbeans.api.project.Project;
55
import org.netbeans.api.project.Project;
56
import org.netbeans.modules.java.api.common.SourceRoots;
56
import org.netbeans.modules.web.project.test.TestBase;
57
import org.netbeans.modules.web.project.test.TestBase;
57
import org.netbeans.modules.web.project.test.TestUtil;
58
import org.netbeans.modules.web.project.test.TestUtil;
58
import org.netbeans.spi.project.support.ant.AntProjectHelper;
59
import org.netbeans.spi.project.support.ant.AntProjectHelper;

Return to bug 126741