Lines 47-55
Link Here
|
47 |
import java.util.logging.Level; |
47 |
import java.util.logging.Level; |
48 |
import java.util.logging.Logger; |
48 |
import java.util.logging.Logger; |
49 |
import java.util.regex.Pattern; |
49 |
import java.util.regex.Pattern; |
|
|
50 |
import javax.swing.event.ChangeEvent; |
51 |
import javax.swing.event.ChangeListener; |
52 |
import org.netbeans.api.annotations.common.CheckForNull; |
53 |
import org.netbeans.api.annotations.common.NonNull; |
50 |
import org.netbeans.spi.java.queries.SourceLevelQueryImplementation; |
54 |
import org.netbeans.spi.java.queries.SourceLevelQueryImplementation; |
|
|
55 |
import org.netbeans.spi.java.queries.SourceLevelQueryImplementation2; |
51 |
import org.openide.filesystems.FileObject; |
56 |
import org.openide.filesystems.FileObject; |
|
|
57 |
import org.openide.modules.SpecificationVersion; |
58 |
import org.openide.util.ChangeSupport; |
52 |
import org.openide.util.Lookup; |
59 |
import org.openide.util.Lookup; |
|
|
60 |
import org.openide.util.Parameters; |
61 |
import org.openide.util.Union2; |
62 |
import org.openide.util.WeakListeners; |
53 |
|
63 |
|
54 |
/** |
64 |
/** |
55 |
* Returns source level of the given Java source file if it is known. |
65 |
* Returns source level of the given Java source file if it is known. |
Lines 66-71
Link Here
|
66 |
private static final Lookup.Result<? extends SourceLevelQueryImplementation> implementations = |
76 |
private static final Lookup.Result<? extends SourceLevelQueryImplementation> implementations = |
67 |
Lookup.getDefault().lookupResult (SourceLevelQueryImplementation.class); |
77 |
Lookup.getDefault().lookupResult (SourceLevelQueryImplementation.class); |
68 |
|
78 |
|
|
|
79 |
private static final Lookup.Result<? extends SourceLevelQueryImplementation2> implementations2 = |
80 |
Lookup.getDefault().lookupResult (SourceLevelQueryImplementation2.class); |
81 |
|
82 |
private static final Result EMPTY_RESULT = new Result(); |
83 |
|
69 |
private SourceLevelQuery() { |
84 |
private SourceLevelQuery() { |
70 |
} |
85 |
} |
71 |
|
86 |
|
Lines 78-83
Link Here
|
78 |
* if it is not known |
93 |
* if it is not known |
79 |
*/ |
94 |
*/ |
80 |
public static String getSourceLevel(FileObject javaFile) { |
95 |
public static String getSourceLevel(FileObject javaFile) { |
|
|
96 |
for (SourceLevelQueryImplementation2 sqi : implementations2.allInstances()) { |
97 |
final SourceLevelQueryImplementation2.Result result = sqi.getSourceLevel(javaFile); |
98 |
if (result != null) { |
99 |
final SpecificationVersion version = result.getSourceLevel(); |
100 |
if (version != null){ |
101 |
final String s = version.toString(); |
102 |
if (!SOURCE_LEVEL.matcher(s).matches()) { |
103 |
LOGGER.log(Level.WARNING, "#83994: Ignoring bogus source level {0} for {1} from {2}", new Object[] {s, javaFile, sqi}); //NOI18N |
104 |
continue; |
105 |
} |
106 |
LOGGER.log(Level.FINE, "Found source level {0} for {1} from {2}", new Object[] {s, javaFile, sqi}); //NOI18N |
107 |
return s; |
108 |
} |
109 |
} |
110 |
} |
81 |
for (SourceLevelQueryImplementation sqi : implementations.allInstances()) { |
111 |
for (SourceLevelQueryImplementation sqi : implementations.allInstances()) { |
82 |
String s = sqi.getSourceLevel(javaFile); |
112 |
String s = sqi.getSourceLevel(javaFile); |
83 |
if (s != null) { |
113 |
if (s != null) { |
Lines 93-96
Link Here
|
93 |
return null; |
123 |
return null; |
94 |
} |
124 |
} |
95 |
|
125 |
|
|
|
126 |
/** |
127 |
* Returns a source level of the given Java file, Java package or source folder. For acceptable return values |
128 |
* see the documentation of <code>-source</code> command line switch of |
129 |
* <code>javac</code> compiler . |
130 |
* @param javaFile Java source file, Java package or source folder in question |
131 |
* @return a {@link Result} object encapsulating the source level of the Java file. Results created for source |
132 |
* levels provided by the {@link SourceLevelQueryImplementation} do not support listening. Use {@link Result#supportsChanges()} |
133 |
* to check if the result supports listening. |
134 |
* @since 1.30 |
135 |
*/ |
136 |
public static @NonNull Result getSourceLevel2(final @NonNull FileObject javaFile) { |
137 |
for (SourceLevelQueryImplementation2 sqi : implementations2.allInstances()) { |
138 |
final SourceLevelQueryImplementation2.Result result = sqi.getSourceLevel(javaFile); |
139 |
if (result != null) { |
140 |
LOGGER.log(Level.FINE, "Found source level {0} for {1} from {2}", new Object[] {result, javaFile, sqi}); //NOI18N |
141 |
return new Result(result); |
142 |
} |
143 |
} |
144 |
LOGGER.log(Level.FINE, "No source level found for {0}", javaFile); |
145 |
for (SourceLevelQueryImplementation sqi : implementations.allInstances()) { |
146 |
String s = sqi.getSourceLevel(javaFile); |
147 |
if (s != null) { |
148 |
if (!SOURCE_LEVEL.matcher(s).matches()) { |
149 |
LOGGER.log(Level.WARNING, "#83994: Ignoring bogus source level {0} for {1} from {2}", new Object[] {s, javaFile, sqi}); |
150 |
continue; |
151 |
} |
152 |
LOGGER.log(Level.FINE, "Found source level {0} for {1} from {2}", new Object[] {s, javaFile, sqi}); |
153 |
return new Result(s); |
154 |
} |
155 |
} |
156 |
return EMPTY_RESULT; |
157 |
} |
158 |
|
159 |
/** |
160 |
* Result of finding source level, encapsulating the answer as well as the |
161 |
* ability to listen to it. |
162 |
* @since 1.30 |
163 |
*/ |
164 |
public static final class Result { |
165 |
|
166 |
private final Union2<SourceLevelQueryImplementation2.Result,String> delegate; |
167 |
private final ChangeSupport cs = new ChangeSupport(this); |
168 |
private /**@GuardedBy("this")*/ ChangeListener spiListener; |
169 |
|
170 |
private Result(@NonNull final SourceLevelQueryImplementation2.Result delegate) { |
171 |
Parameters.notNull("delegate", delegate); //NOI18N |
172 |
this.delegate = Union2.<SourceLevelQueryImplementation2.Result,String>createFirst(delegate); |
173 |
} |
174 |
|
175 |
private Result(@NonNull final String sourceLevel) { |
176 |
Parameters.notNull("sourceLevel", sourceLevel); |
177 |
this.delegate = Union2.<SourceLevelQueryImplementation2.Result,String>createSecond(sourceLevel); |
178 |
} |
179 |
|
180 |
private Result() { |
181 |
this.delegate = null; |
182 |
} |
183 |
|
184 |
/** |
185 |
* Get the source level. |
186 |
* @return a source level as a {@link SpecificationVersion} |
187 |
* or null if the source level is unknown. |
188 |
*/ |
189 |
public @CheckForNull SpecificationVersion getSourceLevel() { |
190 |
return delegate == null ? null : |
191 |
delegate.hasFirst() ? delegate.first().getSourceLevel() : new SpecificationVersion(delegate.second()); |
192 |
} |
193 |
|
194 |
/** |
195 |
* Add a listener to changes of source level. |
196 |
* @param listener a listener to add |
197 |
*/ |
198 |
public void addChangeListener(@NonNull ChangeListener listener) { |
199 |
Parameters.notNull("listener", listener); //NOI18N |
200 |
final SourceLevelQueryImplementation2.Result _delegate = getDelegate(); |
201 |
if (_delegate == null) { |
202 |
throw new UnsupportedOperationException("Listening is not supported"); //NOI18N |
203 |
} |
204 |
cs.addChangeListener(listener); |
205 |
synchronized (this) { |
206 |
if (spiListener == null) { |
207 |
spiListener = new ChangeListener() { |
208 |
@Override |
209 |
public void stateChanged(ChangeEvent e) { |
210 |
cs.fireChange(); |
211 |
} |
212 |
}; |
213 |
_delegate.addChangeListener(WeakListeners.change(spiListener, _delegate)); |
214 |
} |
215 |
} |
216 |
|
217 |
} |
218 |
|
219 |
/** |
220 |
* Remove a listener to changes of source level. |
221 |
* @param listener a listener to add |
222 |
*/ |
223 |
public void removeChangeListener(@NonNull ChangeListener listener) { |
224 |
Parameters.notNull("listener", listener); //NOI18N |
225 |
final SourceLevelQueryImplementation2.Result _delegate = getDelegate(); |
226 |
if (_delegate == null) { |
227 |
throw new UnsupportedOperationException("Listening is not supported"); //NOI18N |
228 |
} |
229 |
cs.removeChangeListener(listener); |
230 |
} |
231 |
|
232 |
/** |
233 |
* Returns true if the result support updates and client may |
234 |
* listen on it. If false client should always ask again to |
235 |
* obtain current value. The results created for values returned |
236 |
* by the {@link SourceLevelQueryImplementation} do not support |
237 |
* listening. |
238 |
* @return true if the result supports changes and listening |
239 |
*/ |
240 |
public boolean supportsChanges() { |
241 |
return getDelegate() != null; |
242 |
} |
243 |
|
244 |
private SourceLevelQueryImplementation2.Result getDelegate() { |
245 |
return delegate != null && delegate.hasFirst() ? delegate.first() : null; |
246 |
} |
247 |
} |
248 |
|
96 |
} |
249 |
} |