diff --git a/api.java/apichanges.xml b/api.java/apichanges.xml --- a/api.java/apichanges.xml +++ b/api.java/apichanges.xml @@ -76,6 +76,25 @@ + + + Added notifications about source level changes into SourceLevelQuery + + + + + +

+ The SourceLevelQuery did not allow listening on the source level changes. Such a + notifications are required by the annotation processor support and indexing. + This API change adds a SourceLevelQuery.getSourceLevel2 which returns a Result object + which allows listening like other queries. +

+
+ + + +
Introducing AnnotationProcessingQuery.Result.Trigger diff --git a/api.java/manifest.mf b/api.java/manifest.mf --- a/api.java/manifest.mf +++ b/api.java/manifest.mf @@ -1,6 +1,6 @@ Manifest-Version: 1.0 OpenIDE-Module: org.netbeans.api.java/1 -OpenIDE-Module-Specification-Version: 1.29 +OpenIDE-Module-Specification-Version: 1.30 OpenIDE-Module-Localizing-Bundle: org/netbeans/api/java/queries/Bundle.properties AutoUpdate-Show-In-Client: false diff --git a/api.java/nbproject/project.xml b/api.java/nbproject/project.xml --- a/api.java/nbproject/project.xml +++ b/api.java/nbproject/project.xml @@ -76,6 +76,14 @@ + org.openide.modules + + + + 7.18 + + + org.openide.util diff --git a/api.java/src/org/netbeans/api/java/queries/SourceLevelQuery.java b/api.java/src/org/netbeans/api/java/queries/SourceLevelQuery.java --- a/api.java/src/org/netbeans/api/java/queries/SourceLevelQuery.java +++ b/api.java/src/org/netbeans/api/java/queries/SourceLevelQuery.java @@ -47,9 +47,19 @@ import java.util.logging.Level; import java.util.logging.Logger; import java.util.regex.Pattern; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; +import org.netbeans.api.annotations.common.CheckForNull; +import org.netbeans.api.annotations.common.NonNull; import org.netbeans.spi.java.queries.SourceLevelQueryImplementation; +import org.netbeans.spi.java.queries.SourceLevelQueryImplementation2; import org.openide.filesystems.FileObject; +import org.openide.modules.SpecificationVersion; +import org.openide.util.ChangeSupport; import org.openide.util.Lookup; +import org.openide.util.Parameters; +import org.openide.util.Union2; +import org.openide.util.WeakListeners; /** * Returns source level of the given Java source file if it is known. @@ -66,6 +76,11 @@ private static final Lookup.Result implementations = Lookup.getDefault().lookupResult (SourceLevelQueryImplementation.class); + private static final Lookup.Result implementations2 = + Lookup.getDefault().lookupResult (SourceLevelQueryImplementation2.class); + + private static final Result EMPTY_RESULT = new Result(); + private SourceLevelQuery() { } @@ -78,6 +93,21 @@ * if it is not known */ public static String getSourceLevel(FileObject javaFile) { + for (SourceLevelQueryImplementation2 sqi : implementations2.allInstances()) { + final SourceLevelQueryImplementation2.Result result = sqi.getSourceLevel(javaFile); + if (result != null) { + final SpecificationVersion version = result.getSourceLevel(); + if (version != null){ + final String s = version.toString(); + if (!SOURCE_LEVEL.matcher(s).matches()) { + LOGGER.log(Level.WARNING, "#83994: Ignoring bogus source level {0} for {1} from {2}", new Object[] {s, javaFile, sqi}); //NOI18N + continue; + } + LOGGER.log(Level.FINE, "Found source level {0} for {1} from {2}", new Object[] {s, javaFile, sqi}); //NOI18N + return s; + } + } + } for (SourceLevelQueryImplementation sqi : implementations.allInstances()) { String s = sqi.getSourceLevel(javaFile); if (s != null) { @@ -93,4 +123,127 @@ return null; } + /** + * Returns a source level of the given Java file, Java package or source folder. For acceptable return values + * see the documentation of -source command line switch of + * javac compiler . + * @param javaFile Java source file, Java package or source folder in question + * @return a {@link Result} object encapsulating the source level of the Java file. Results created for source + * levels provided by the {@link SourceLevelQueryImplementation} do not support listening. Use {@link Result#supportsChanges()} + * to check if the result supports listening. + * @since 1.30 + */ + public static @NonNull Result getSourceLevel2(final @NonNull FileObject javaFile) { + for (SourceLevelQueryImplementation2 sqi : implementations2.allInstances()) { + final SourceLevelQueryImplementation2.Result result = sqi.getSourceLevel(javaFile); + if (result != null) { + LOGGER.log(Level.FINE, "Found source level {0} for {1} from {2}", new Object[] {result, javaFile, sqi}); //NOI18N + return new Result(result); + } + } + LOGGER.log(Level.FINE, "No source level found for {0}", javaFile); + for (SourceLevelQueryImplementation sqi : implementations.allInstances()) { + String s = sqi.getSourceLevel(javaFile); + if (s != null) { + if (!SOURCE_LEVEL.matcher(s).matches()) { + LOGGER.log(Level.WARNING, "#83994: Ignoring bogus source level {0} for {1} from {2}", new Object[] {s, javaFile, sqi}); + continue; + } + LOGGER.log(Level.FINE, "Found source level {0} for {1} from {2}", new Object[] {s, javaFile, sqi}); + return new Result(s); + } + } + return EMPTY_RESULT; + } + + /** + * Result of finding source level, encapsulating the answer as well as the + * ability to listen to it. + * @since 1.30 + */ + public static final class Result { + + private final Union2 delegate; + private final ChangeSupport cs = new ChangeSupport(this); + private /**@GuardedBy("this")*/ ChangeListener spiListener; + + private Result(@NonNull final SourceLevelQueryImplementation2.Result delegate) { + Parameters.notNull("delegate", delegate); //NOI18N + this.delegate = Union2.createFirst(delegate); + } + + private Result(@NonNull final String sourceLevel) { + Parameters.notNull("sourceLevel", sourceLevel); + this.delegate = Union2.createSecond(sourceLevel); + } + + private Result() { + this.delegate = null; + } + + /** + * Get the source level. + * @return a source level as a {@link SpecificationVersion} + * or null if the source level is unknown. + */ + public @CheckForNull SpecificationVersion getSourceLevel() { + return delegate == null ? null : + delegate.hasFirst() ? delegate.first().getSourceLevel() : new SpecificationVersion(delegate.second()); + } + + /** + * Add a listener to changes of source level. + * @param listener a listener to add + */ + public void addChangeListener(@NonNull ChangeListener listener) { + Parameters.notNull("listener", listener); //NOI18N + final SourceLevelQueryImplementation2.Result _delegate = getDelegate(); + if (_delegate == null) { + throw new UnsupportedOperationException("Listening is not supported"); //NOI18N + } + cs.addChangeListener(listener); + synchronized (this) { + if (spiListener == null) { + spiListener = new ChangeListener() { + @Override + public void stateChanged(ChangeEvent e) { + cs.fireChange(); + } + }; + _delegate.addChangeListener(WeakListeners.change(spiListener, _delegate)); + } + } + + } + + /** + * Remove a listener to changes of source level. + * @param listener a listener to add + */ + public void removeChangeListener(@NonNull ChangeListener listener) { + Parameters.notNull("listener", listener); //NOI18N + final SourceLevelQueryImplementation2.Result _delegate = getDelegate(); + if (_delegate == null) { + throw new UnsupportedOperationException("Listening is not supported"); //NOI18N + } + cs.removeChangeListener(listener); + } + + /** + * Returns true if the result support updates and client may + * listen on it. If false client should always ask again to + * obtain current value. The results created for values returned + * by the {@link SourceLevelQueryImplementation} do not support + * listening. + * @return true if the result supports changes and listening + */ + public boolean supportsChanges() { + return getDelegate() != null; + } + + private SourceLevelQueryImplementation2.Result getDelegate() { + return delegate != null && delegate.hasFirst() ? delegate.first() : null; + } + } + } diff --git a/api.java/src/org/netbeans/spi/java/queries/SourceLevelQueryImplementation2.java b/api.java/src/org/netbeans/spi/java/queries/SourceLevelQueryImplementation2.java new file mode 100644 --- /dev/null +++ b/api.java/src/org/netbeans/spi/java/queries/SourceLevelQueryImplementation2.java @@ -0,0 +1,109 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2010 Oracle and/or its affiliates. All rights reserved. + * + * Oracle and Java are registered trademarks of Oracle and/or its affiliates. + * Other names may be trademarks of their respective owners. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + * + * Contributor(s): + * + * Portions Copyrighted 2010 Sun Microsystems, Inc. + */ + +package org.netbeans.spi.java.queries; + +import javax.swing.event.ChangeListener; +import org.netbeans.api.annotations.common.CheckForNull; +import org.netbeans.api.annotations.common.NonNull; +import org.netbeans.api.java.queries.SourceLevelQuery; +import org.openide.filesystems.FileObject; +import org.openide.modules.SpecificationVersion; + +/** + * + * Permits providers to return specification source level of Java source file. + *

+ * A default implementation is registered by the + * org.netbeans.modules.java.project module which looks up the + * project corresponding to the file (if any) and checks whether that + * project has an implementation of this interface in its lookup. If so, it + * delegates to that implementation. Therefore it is not generally necessary + * for a project type provider to register its own global implementation of + * this query, if it depends on the Java Project module and uses this style. + *

+ * @see org.netbeans.api.java.queries.SourceLevelQuery + * @see org.netbeans.api.queries.FileOwnerQuery + * @see org.netbeans.api.project.Project#getLookup + * @see org.netbeans.api.java.classpath.ClassPath#BOOT + * @author Tomas Zezula + * @since 1.30 + */ +public interface SourceLevelQueryImplementation2 { + + /** + * Returns source level of the given Java file. For acceptable return values + * see the documentation of -source command line switch of + * javac compiler . + * @param javaFile Java source file in question + * @return source level of the Java file encapsulated as {@link Result}, or + * null if the file is not handled by this provider. + */ + Result getSourceLevel(FileObject javaFile); + + /** + * Result of finding source level, encapsulating the answer as well as the + * ability to listen to it. + * @since 1.30 + */ + interface Result { + + /** + * Get the source level. + * @return a source level as a {@link SpecificationVersion} + * or null if the source level is unknown. + */ + @CheckForNull SpecificationVersion getSourceLevel(); + + /** + * Add a listener to changes of source level. + * @param listener a listener to add + */ + void addChangeListener(@NonNull ChangeListener listener); + + /** + * Remove a listener to changes of source level. + * @param listener a listener to add + */ + void removeChangeListener(@NonNull ChangeListener listener); + } +} diff --git a/api.java/test/unit/src/org/netbeans/api/java/queries/SourceLevelQueryTest.java b/api.java/test/unit/src/org/netbeans/api/java/queries/SourceLevelQueryTest.java --- a/api.java/test/unit/src/org/netbeans/api/java/queries/SourceLevelQueryTest.java +++ b/api.java/test/unit/src/org/netbeans/api/java/queries/SourceLevelQueryTest.java @@ -44,11 +44,16 @@ package org.netbeans.api.java.queries; +import java.util.HashMap; +import java.util.Map; +import javax.swing.event.ChangeListener; import org.netbeans.junit.MockServices; import org.netbeans.junit.NbTestCase; import org.netbeans.spi.java.queries.SourceLevelQueryImplementation; +import org.netbeans.spi.java.queries.SourceLevelQueryImplementation2; import org.openide.filesystems.FileObject; import org.openide.filesystems.FileUtil; +import org.openide.modules.SpecificationVersion; /** * @author Jesse Glick @@ -59,12 +64,13 @@ super(n); } + private static Map slq2Files = new HashMap(); private static String LEVEL; private FileObject f; protected void setUp() throws Exception { super.setUp(); - MockServices.setServices(SLQ.class); + MockServices.setServices(SLQ.class,SLQ2.class); LEVEL = null; f = FileUtil.createMemoryFileSystem().getRoot(); } @@ -85,6 +91,21 @@ assertNull(SourceLevelQuery.getSourceLevel(f)); } + public void testSLQ2() throws Exception { + LEVEL = "1.3"; + FileObject f1 = f.createFolder("f1"); //NOI18N + FileObject f2 = f.createFolder("f2"); //NOI18N + assertEquals("1.3", SourceLevelQuery.getSourceLevel(f1)); //NOI18N + assertEquals("1.3", SourceLevelQuery.getSourceLevel(f2)); //NOI18N + slq2Files.put(f1, "1.5"); //NOI18N + assertEquals("1.5", SourceLevelQuery.getSourceLevel(f1)); //NOI18N + assertEquals("1.3", SourceLevelQuery.getSourceLevel(f2)); //NOI18N + assertEquals("1.5", SourceLevelQuery.getSourceLevel2(f1).getSourceLevel().toString()); //NOI18N + assertTrue(SourceLevelQuery.getSourceLevel2(f1).supportsChanges()); + assertEquals("1.3",SourceLevelQuery.getSourceLevel2(f2).getSourceLevel().toString()); //NOI18N + assertFalse(SourceLevelQuery.getSourceLevel2(f2).supportsChanges()); + } + public static final class SLQ implements SourceLevelQueryImplementation { public SLQ() {} @@ -92,6 +113,29 @@ public String getSourceLevel(FileObject javaFile) { return LEVEL; } + } + + public static final class SLQ2 implements SourceLevelQueryImplementation2 { + + @Override + public Result getSourceLevel(FileObject javaFile) { + final String sl = slq2Files.get(javaFile); + if (sl != null) { + return new SourceLevelQueryImplementation2.Result() { + @Override + public SpecificationVersion getSourceLevel() { + return new SpecificationVersion(sl); + } + @Override + public void addChangeListener(ChangeListener listener) { + } + @Override + public void removeChangeListener(ChangeListener listener) { + } + }; + } + return null; + } } diff --git a/java.api.common/apichanges.xml b/java.api.common/apichanges.xml --- a/java.api.common/apichanges.xml +++ b/java.api.common/apichanges.xml @@ -105,6 +105,21 @@ + + + Added a factory method to create SourceLevelQueryImplementation2 + + + + + +

+ Added a factory method to create default ant project based SourceLevelQueryImplementation2. +

+
+ + +
Support for mutable Sources diff --git a/java.api.common/manifest.mf b/java.api.common/manifest.mf --- a/java.api.common/manifest.mf +++ b/java.api.common/manifest.mf @@ -1,4 +1,4 @@ Manifest-Version: 1.0 OpenIDE-Module: org.netbeans.modules.java.api.common/0 OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/java/api/common/resources/Bundle.properties -OpenIDE-Module-Specification-Version: 1.21 +OpenIDE-Module-Specification-Version: 1.22 diff --git a/java.api.common/nbproject/project.xml b/java.api.common/nbproject/project.xml --- a/java.api.common/nbproject/project.xml +++ b/java.api.common/nbproject/project.xml @@ -29,40 +29,7 @@ 1 - 1.28 - -
- - org.netbeans.modules.java.source - - - - 0.2 - - - - org.netbeans.modules.java.sourceui - - - - 1 - 1.1 - - - - org.openide.execution - - - - 1.2 - - - - org.netbeans.libs.javacapi - - - - 0.5 + 1.30 @@ -84,6 +51,14 @@ + org.netbeans.libs.javacapi + + + + 0.5 + + + org.netbeans.modules.java.platform @@ -102,6 +77,23 @@ + org.netbeans.modules.java.source + + + + 0.2 + + + + org.netbeans.modules.java.sourceui + + + + 1 + 1.1 + + + org.netbeans.modules.project.ant @@ -170,6 +162,14 @@ + org.openide.execution + + + + 1.2 + + + org.openide.filesystems diff --git a/java.api.common/src/org/netbeans/modules/java/api/common/queries/QuerySupport.java b/java.api.common/src/org/netbeans/modules/java/api/common/queries/QuerySupport.java --- a/java.api.common/src/org/netbeans/modules/java/api/common/queries/QuerySupport.java +++ b/java.api.common/src/org/netbeans/modules/java/api/common/queries/QuerySupport.java @@ -57,6 +57,7 @@ import org.netbeans.spi.java.queries.MultipleRootsUnitTestForSourceQueryImplementation; import org.netbeans.spi.java.queries.SourceForBinaryQueryImplementation; import org.netbeans.spi.java.queries.SourceLevelQueryImplementation; +import org.netbeans.spi.java.queries.SourceLevelQueryImplementation2; import org.netbeans.spi.project.SourceGroupModifierImplementation; import org.netbeans.spi.project.support.ant.AntProjectHelper; import org.netbeans.spi.project.support.ant.AntProjectListener; @@ -207,6 +208,17 @@ } /** + * Create a new query to find out source level of Java source files (SourceLevelQueryImplementation2). + * @param evaluator {@link PropertyEvaluator} used for obtaining needed properties. + * @return a {@link SourceLevelQueryImplementation2} to find out source level of Java source files. + * @since 1.22 + */ + public static SourceLevelQueryImplementation2 createSourceLevelQuery2(@NonNull PropertyEvaluator evaluator) { + Parameters.notNull("evaluator", evaluator); // NOI18N + return new SourceLevelQueryImpl2(evaluator); + } + + /** * Create a new query to find Java package roots of unit tests for Java package root of sources and vice versa. * @param sourceRoots a list of source roots. * @param testRoots a list of test roots. diff --git a/java.api.common/src/org/netbeans/modules/java/api/common/queries/SourceLevelQueryImpl.java b/java.api.common/src/org/netbeans/modules/java/api/common/queries/SourceLevelQueryImpl.java --- a/java.api.common/src/org/netbeans/modules/java/api/common/queries/SourceLevelQueryImpl.java +++ b/java.api.common/src/org/netbeans/modules/java/api/common/queries/SourceLevelQueryImpl.java @@ -43,9 +43,6 @@ */ package org.netbeans.modules.java.api.common.queries; -import org.netbeans.api.java.platform.JavaPlatform; -import org.netbeans.api.java.platform.JavaPlatformManager; -import org.netbeans.api.java.platform.Specification; import org.netbeans.modules.java.api.common.util.CommonProjectUtils; import org.netbeans.spi.java.queries.SourceLevelQueryImplementation; import org.netbeans.spi.project.support.ant.PropertyEvaluator; @@ -67,16 +64,21 @@ this.evaluator = evaluator; } + @Override public String getSourceLevel(FileObject javaFile) { - final String activePlatform = evaluator.getProperty("platform.active"); //NOI18N + return findSourceLevel(evaluator); + } + + static String findSourceLevel (final PropertyEvaluator eval) { + final String activePlatform = eval.getProperty("platform.active"); //NOI18N if (CommonProjectUtils.getActivePlatform(activePlatform) != null) { - String sl = evaluator.getProperty("javac.source"); //NOI18N + String sl = eval.getProperty("javac.source"); //NOI18N if (sl != null && sl.length() > 0) { return sl; } return null; } - + EditableProperties props = PropertyUtils.getGlobalProperties(); String sl = props.get("default.javac.source"); //NOI18N if (sl != null && sl.length() > 0) { diff --git a/java.api.common/src/org/netbeans/modules/java/api/common/queries/SourceLevelQueryImpl2.java b/java.api.common/src/org/netbeans/modules/java/api/common/queries/SourceLevelQueryImpl2.java new file mode 100644 --- /dev/null +++ b/java.api.common/src/org/netbeans/modules/java/api/common/queries/SourceLevelQueryImpl2.java @@ -0,0 +1,121 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2010 Oracle and/or its affiliates. All rights reserved. + * + * Oracle and Java are registered trademarks of Oracle and/or its affiliates. + * Other names may be trademarks of their respective owners. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + * + * Contributor(s): + * + * Portions Copyrighted 2010 Sun Microsystems, Inc. + */ + +package org.netbeans.modules.java.api.common.queries; + +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import javax.swing.event.ChangeListener; +import org.netbeans.api.annotations.common.NonNull; +import org.netbeans.api.java.queries.SourceLevelQuery; +import org.netbeans.api.java.queries.SourceLevelQuery.Result; +import org.netbeans.spi.java.queries.SourceLevelQueryImplementation2; +import org.netbeans.spi.project.support.ant.PropertyEvaluator; +import org.openide.filesystems.FileObject; +import org.openide.modules.SpecificationVersion; +import org.openide.util.ChangeSupport; +import org.openide.util.Parameters; +import org.openide.util.WeakListeners; + +/** + * @author Tomas Zezula + */ +class SourceLevelQueryImpl2 implements SourceLevelQueryImplementation2 { + + private final PropertyEvaluator eval; + private final Result result; + + SourceLevelQueryImpl2(final @NonNull PropertyEvaluator eval) { + Parameters.notNull("eval", eval); //NOI18N + this.eval = eval; + this.result = new R(); + } + + @Override + public Result getSourceLevel(FileObject javaFile) { + return this.result; + } + + private class R implements Result, PropertyChangeListener { + + private final ChangeSupport cs = new ChangeSupport(this); + + @SuppressWarnings("LeakingThisInConstructor") + private R() { + eval.addPropertyChangeListener(WeakListeners.propertyChange(this, eval)); + } + + @Override + public SpecificationVersion getSourceLevel() { + final String ver = SourceLevelQueryImpl.findSourceLevel(eval); + return ver == null ? null : new SpecificationVersion(ver); + } + + @Override + public void addChangeListener(ChangeListener listener) { + this.cs.addChangeListener(listener); + } + + @Override + public void removeChangeListener(ChangeListener listener) { + this.cs.removeChangeListener(listener); + } + + @Override + public void propertyChange(PropertyChangeEvent evt) { + final String name = evt.getPropertyName(); + if (name == null || + "javac.source".equals(name) || //NOI18N + "platform.active".equals(name)) { //NOI18N + this.cs.fireChange(); + } + } + + @Override + public String toString() { + final SpecificationVersion sl = getSourceLevel(); + return sl == null ? "" : sl.toString(); //NOI18M + } + + } + +} diff --git a/java.api.common/test/unit/src/org/netbeans/modules/java/api/common/queries/SourceLevelQueryImplTest.java b/java.api.common/test/unit/src/org/netbeans/modules/java/api/common/queries/SourceLevelQueryImplTest.java --- a/java.api.common/test/unit/src/org/netbeans/modules/java/api/common/queries/SourceLevelQueryImplTest.java +++ b/java.api.common/test/unit/src/org/netbeans/modules/java/api/common/queries/SourceLevelQueryImplTest.java @@ -52,13 +52,18 @@ import java.util.List; import java.util.Map; import java.util.Properties; +import java.util.concurrent.atomic.AtomicInteger; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; import org.netbeans.api.java.classpath.ClassPath; import org.netbeans.api.java.platform.JavaPlatform; import org.netbeans.api.java.platform.Specification; +import org.netbeans.api.java.queries.SourceLevelQuery; import org.netbeans.api.project.Project; import org.netbeans.api.project.ProjectManager; import org.netbeans.junit.NbTestCase; import org.netbeans.modules.java.platform.JavaPlatformProvider; +import org.netbeans.spi.java.queries.SourceLevelQueryImplementation2; import org.netbeans.spi.project.support.ant.PropertyUtils; import org.openide.filesystems.FileObject; import org.netbeans.api.project.TestUtil; @@ -170,6 +175,38 @@ assertEquals(DEFAULT_JAVAC_SOURCE, sl); } + public void testSourceLevelQuery2() throws Exception { + this.prepareProject(TEST_PLATFORM); + final FileObject dummy = projdir.createData("Dummy.java"); + final SourceLevelQueryImplementation2 sourceLevelQuery = QuerySupport.createSourceLevelQuery2(eval); + final SourceLevelQueryImplementation2.Result result = sourceLevelQuery.getSourceLevel(dummy); + assertNotNull(result); + assertEquals(JAVAC_SOURCE, result.getSourceLevel().toString()); + } + + public void testFiring() throws Exception { + this.prepareProject(TEST_PLATFORM); + final FileObject dummy = projdir.createData("Dummy.java"); + final SourceLevelQueryImplementation2 sourceLevelQuery = QuerySupport.createSourceLevelQuery2(eval); + final SourceLevelQueryImplementation2.Result result = sourceLevelQuery.getSourceLevel(dummy); + assertNotNull(result); + assertEquals(JAVAC_SOURCE, result.getSourceLevel().toString()); + class TestChangeListener implements ChangeListener { + final AtomicInteger ec = new AtomicInteger(); + @Override + public void stateChanged(final ChangeEvent event) { + ec.incrementAndGet(); + } + } + final TestChangeListener tl = new TestChangeListener(); + result.addChangeListener(tl); + final EditableProperties props = helper.getProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH); + props.setProperty("javac.source", "1.7"); + helper.putProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH, props); + assertEquals(1, tl.ec.intValue()); + assertEquals("1.7", result.getSourceLevel().toString()); + } + private static class TestPlatformProvider implements JavaPlatformProvider { private JavaPlatform platform; diff --git a/java.j2seproject/nbproject/project.xml b/java.j2seproject/nbproject/project.xml --- a/java.j2seproject/nbproject/project.xml +++ b/java.j2seproject/nbproject/project.xml @@ -125,7 +125,7 @@ 0-1 - 1.21 + 1.22 diff --git a/java.j2seproject/src/org/netbeans/modules/java/j2seproject/J2SEProject.java b/java.j2seproject/src/org/netbeans/modules/java/j2seproject/J2SEProject.java --- a/java.j2seproject/src/org/netbeans/modules/java/j2seproject/J2SEProject.java +++ b/java.j2seproject/src/org/netbeans/modules/java/j2seproject/J2SEProject.java @@ -356,7 +356,7 @@ new ProjectXmlSavedHookImpl(), UILookupMergerSupport.createProjectOpenHookMerger(new ProjectOpenedHookImpl()), QuerySupport.createUnitTestForSourceQuery(getSourceRoots(), getTestSourceRoots()), - QuerySupport.createSourceLevelQuery(evaluator()), + QuerySupport.createSourceLevelQuery2(evaluator()), QuerySupport.createSources(this, helper, evaluator(), getSourceRoots(), getTestSourceRoots(), Roots.nonSourceRoots(ProjectProperties.BUILD_DIR, J2SEProjectProperties.DIST_DIR)), QuerySupport.createSharabilityQuery(helper, evaluator(), getSourceRoots(), getTestSourceRoots()), new CoSAwareFileBuiltQueryImpl(QuerySupport.createFileBuiltQuery(helper, evaluator(), getSourceRoots(), getTestSourceRoots()), this), diff --git a/java.project/nbproject/project.xml b/java.project/nbproject/project.xml --- a/java.project/nbproject/project.xml +++ b/java.project/nbproject/project.xml @@ -82,7 +82,7 @@ 1 - 1.18 + 1.30 diff --git a/java.project/src/org/netbeans/modules/java/project/ProjectSourceLevelQueryImpl2.java b/java.project/src/org/netbeans/modules/java/project/ProjectSourceLevelQueryImpl2.java new file mode 100644 --- /dev/null +++ b/java.project/src/org/netbeans/modules/java/project/ProjectSourceLevelQueryImpl2.java @@ -0,0 +1,71 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2010 Oracle and/or its affiliates. All rights reserved. + * + * Oracle and Java are registered trademarks of Oracle and/or its affiliates. + * Other names may be trademarks of their respective owners. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + * + * Contributor(s): + * + * Portions Copyrighted 2010 Sun Microsystems, Inc. + */ + +package org.netbeans.modules.java.project; + +import org.netbeans.api.java.queries.SourceLevelQuery.Result; +import org.netbeans.api.project.FileOwnerQuery; +import org.netbeans.api.project.Project; +import org.netbeans.spi.java.queries.SourceLevelQueryImplementation2; +import org.openide.filesystems.FileObject; +import org.openide.util.lookup.ServiceProvider; + +/** + * + * @author Tomas Zezula + */ +@ServiceProvider(service=SourceLevelQueryImplementation2.class,position=99) +public class ProjectSourceLevelQueryImpl2 implements SourceLevelQueryImplementation2 { + + @Override + public Result getSourceLevel(FileObject javaFile) { + final Project project = FileOwnerQuery.getOwner(javaFile); + if (project != null) { + SourceLevelQueryImplementation2 impl = project.getLookup().lookup(SourceLevelQueryImplementation2.class); + if (impl != null) { + return impl.getSourceLevel(javaFile); + } + } + return null; + } + +}