Line 0
Link Here
|
|
|
1 |
/* |
2 |
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. |
3 |
* |
4 |
* Copyright 2013 Oracle and/or its affiliates. All rights reserved. |
5 |
* |
6 |
* Oracle and Java are registered trademarks of Oracle and/or its affiliates. |
7 |
* Other names may be trademarks of their respective owners. |
8 |
* |
9 |
* The contents of this file are subject to the terms of either the GNU |
10 |
* General Public License Version 2 only ("GPL") or the Common |
11 |
* Development and Distribution License("CDDL") (collectively, the |
12 |
* "License"). You may not use this file except in compliance with the |
13 |
* License. You can obtain a copy of the License at |
14 |
* http://www.netbeans.org/cddl-gplv2.html |
15 |
* or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the |
16 |
* specific language governing permissions and limitations under the |
17 |
* License. When distributing the software, include this License Header |
18 |
* Notice in each file and include the License file at |
19 |
* nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this |
20 |
* particular file as subject to the "Classpath" exception as provided |
21 |
* by Oracle in the GPL Version 2 section of the License file that |
22 |
* accompanied this code. If applicable, add the following below the |
23 |
* License Header, with the fields enclosed by brackets [] replaced by |
24 |
* your own identifying information: |
25 |
* "Portions Copyrighted [year] [name of copyright owner]" |
26 |
* |
27 |
* If you wish your version of this file to be governed by only the CDDL |
28 |
* or only the GPL Version 2, indicate your decision by adding |
29 |
* "[Contributor] elects to include this software in this distribution |
30 |
* under the [CDDL or GPL Version 2] license." If you do not indicate a |
31 |
* single choice of license, a recipient has the option to distribute |
32 |
* your version of this file under either the CDDL, the GPL Version 2 or |
33 |
* to extend the choice of license to its licensees as provided above. |
34 |
* However, if you add GPL Version 2 code and therefore, elected the GPL |
35 |
* Version 2 license, then the option applies only if the new code is |
36 |
* made subject to such option by the copyright holder. |
37 |
* |
38 |
* Contributor(s): |
39 |
* |
40 |
* Portions Copyrighted 2013 Sun Microsystems, Inc. |
41 |
*/ |
42 |
|
43 |
package org.netbeans.modules.java.api.common.project; |
44 |
|
45 |
import java.beans.PropertyChangeEvent; |
46 |
import java.beans.PropertyChangeListener; |
47 |
import java.beans.PropertyChangeSupport; |
48 |
import java.io.IOException; |
49 |
import java.io.InputStream; |
50 |
import java.text.Collator; |
51 |
import java.util.ArrayDeque; |
52 |
import java.util.ArrayList; |
53 |
import java.util.Collection; |
54 |
import java.util.Collections; |
55 |
import java.util.Comparator; |
56 |
import java.util.HashMap; |
57 |
import java.util.HashSet; |
58 |
import java.util.List; |
59 |
import java.util.Map; |
60 |
import java.util.Objects; |
61 |
import java.util.Properties; |
62 |
import java.util.Queue; |
63 |
import java.util.Set; |
64 |
import java.util.logging.Level; |
65 |
import java.util.logging.Logger; |
66 |
import org.netbeans.api.annotations.common.CheckForNull; |
67 |
import org.netbeans.api.annotations.common.NonNull; |
68 |
import org.netbeans.api.annotations.common.NullAllowed; |
69 |
import org.netbeans.api.project.Project; |
70 |
import org.netbeans.api.project.ProjectManager; |
71 |
import org.netbeans.modules.java.api.common.ant.UpdateHelper; |
72 |
import org.netbeans.spi.project.ProjectConfiguration; |
73 |
import org.netbeans.spi.project.ProjectConfigurationProvider; |
74 |
import org.netbeans.spi.project.support.ant.AntProjectHelper; |
75 |
import org.netbeans.spi.project.support.ant.EditableProperties; |
76 |
import org.netbeans.spi.project.support.ant.FilterPropertyProvider; |
77 |
import org.netbeans.spi.project.support.ant.PropertyEvaluator; |
78 |
import org.netbeans.spi.project.support.ant.PropertyProvider; |
79 |
import org.netbeans.spi.project.support.ant.PropertyUtils; |
80 |
import org.openide.filesystems.FileChangeAdapter; |
81 |
import org.openide.filesystems.FileChangeListener; |
82 |
import org.openide.filesystems.FileEvent; |
83 |
import org.openide.filesystems.FileObject; |
84 |
import org.openide.filesystems.FileRenameEvent; |
85 |
import org.openide.filesystems.FileUtil; |
86 |
import org.openide.util.NbBundle; |
87 |
import org.openide.util.Parameters; |
88 |
import org.openide.util.Utilities; |
89 |
|
90 |
/** |
91 |
* Support for {@link ProjectConfiguration}s in Ant based project. |
92 |
* @author Jesse Glick |
93 |
* @author Tomas Zezula |
94 |
* @since 1.64 |
95 |
*/ |
96 |
public class ProjectConfigurations { |
97 |
|
98 |
private static final Logger LOGGER = Logger.getLogger(ProjectConfigurations.class.getName()); |
99 |
|
100 |
/** |
101 |
* Path to the file holding the active configuration. |
102 |
*/ |
103 |
public static final String CONFIG_PROPS_PATH = "nbproject/private/config.properties"; // NOI18N |
104 |
|
105 |
private ProjectConfigurations() { |
106 |
throw new IllegalStateException("No instance allowed"); //NOI18N |
107 |
} |
108 |
|
109 |
/** |
110 |
* Creates a {@link ConfigurationProviderBuilder}. |
111 |
* @param project the {@link Project} to create builder for |
112 |
* @param eval the {@link Project}'s {@link PropertyEvaluator} |
113 |
* @param updateHelper the {@link Project}'s {@link UpdateHelper} |
114 |
* @return the {@link ConfigurationProviderBuilder} |
115 |
*/ |
116 |
@NonNull |
117 |
public static ConfigurationProviderBuilder createConfigurationProviderBuilder( |
118 |
@NonNull final Project project, |
119 |
@NonNull final PropertyEvaluator eval, |
120 |
@NonNull final UpdateHelper updateHelper) { |
121 |
return new ConfigurationProviderBuilder(project, eval, updateHelper); |
122 |
} |
123 |
|
124 |
/** |
125 |
* Creates a {@link PropertyEvaluator} with {@link ProjectConfiguration} support. |
126 |
* @param project the project to create {@link PropertyEvaluator} for |
127 |
* @param helper the {@link Project}'s {@link AntProjectHelper} |
128 |
* @param additionalPropertyProviders the additional {@link PropertyProvider}s |
129 |
* @return a new {@link PropertyEvaluator} |
130 |
*/ |
131 |
@NonNull |
132 |
public static PropertyEvaluator createPropertyEvaluator( |
133 |
@NonNull final Project project, |
134 |
@NonNull final AntProjectHelper helper, |
135 |
@NonNull final PropertyProvider... additionalPropertyProviders) { |
136 |
Parameters.notNull("project", project); //NOI18N |
137 |
Parameters.notNull("helper", helper); //NOI18N |
138 |
Parameters.notNull("additionalPropertyProviders", additionalPropertyProviders); //NOI18N |
139 |
|
140 |
PropertyEvaluator baseEval1 = PropertyUtils.sequentialPropertyEvaluator( |
141 |
helper.getStockPropertyPreprovider(), |
142 |
helper.getPropertyProvider(ProjectConfigurations.CONFIG_PROPS_PATH)); |
143 |
PropertyEvaluator baseEval2 = PropertyUtils.sequentialPropertyEvaluator( |
144 |
helper.getStockPropertyPreprovider(), |
145 |
helper.getPropertyProvider(AntProjectHelper.PRIVATE_PROPERTIES_PATH)); |
146 |
final Queue<PropertyProvider> providers = new ArrayDeque<>(additionalPropertyProviders.length + 7); |
147 |
providers.offer(helper.getPropertyProvider(ProjectConfigurations.CONFIG_PROPS_PATH)); |
148 |
providers.offer(new ConfigPropertyProvider(baseEval1, "nbproject/private/configs", helper)); //NOI18N |
149 |
providers.offer(helper.getPropertyProvider(AntProjectHelper.PRIVATE_PROPERTIES_PATH)); |
150 |
providers.offer(helper.getProjectLibrariesPropertyProvider()); |
151 |
providers.offer(PropertyUtils.userPropertiesProvider(baseEval2, |
152 |
"user.properties.file", FileUtil.toFile(project.getProjectDirectory()))); //NOI18N |
153 |
providers.offer(new ConfigPropertyProvider(baseEval1, "nbproject/configs", helper)); //NOI18N |
154 |
providers.offer(helper.getPropertyProvider(AntProjectHelper.PROJECT_PROPERTIES_PATH)); |
155 |
Collections.addAll(providers, additionalPropertyProviders); |
156 |
return PropertyUtils.sequentialPropertyEvaluator( |
157 |
helper.getStockPropertyPreprovider(), |
158 |
providers.toArray(new PropertyProvider[providers.size()])); |
159 |
} |
160 |
|
161 |
/** |
162 |
* Builder for {@link ProjectConfigurationProvider}. |
163 |
*/ |
164 |
public static final class ConfigurationProviderBuilder { |
165 |
|
166 |
private final Project project; |
167 |
private final PropertyEvaluator eval; |
168 |
private final UpdateHelper updateHelper; |
169 |
private final Set<String> configurationsAffectActions; |
170 |
private Runnable customizerAction; |
171 |
|
172 |
private ConfigurationProviderBuilder( |
173 |
@NonNull final Project project, |
174 |
@NonNull final PropertyEvaluator eval, |
175 |
@NonNull final UpdateHelper updateHelper) { |
176 |
Parameters.notNull("project", project); //NOI18N |
177 |
Parameters.notNull("eval", eval); //NOI18N |
178 |
Parameters.notNull("updateHelper", updateHelper); //NOI18N |
179 |
this.project = project; |
180 |
this.eval = eval; |
181 |
this.updateHelper = updateHelper; |
182 |
this.configurationsAffectActions = new HashSet<>(); |
183 |
} |
184 |
|
185 |
/** |
186 |
* Sets actions affected by the configurations. |
187 |
* @param commands the actions affected by configurations |
188 |
* @return the {@link ConfigurationProviderBuilder} |
189 |
*/ |
190 |
@NonNull |
191 |
public ConfigurationProviderBuilder addConfigurationsAffectActions(@NonNull final String... commands) { |
192 |
Parameters.notNull("commands", commands); //NOI18N |
193 |
Collections.addAll(configurationsAffectActions, commands); |
194 |
return this; |
195 |
} |
196 |
|
197 |
/** |
198 |
* Sets an action showing the customizer for {@link ProjectConfiguration}s. |
199 |
* @param action the action |
200 |
* @return the {@link ConfigurationProviderBuilder} |
201 |
*/ |
202 |
@NonNull |
203 |
public ConfigurationProviderBuilder setCustomizerAction(@NonNull final Runnable action) { |
204 |
Parameters.notNull("action", action); //NOI18N |
205 |
this.customizerAction = action; |
206 |
return this; |
207 |
} |
208 |
|
209 |
/** |
210 |
* Creates a configured {@link ProjectConfigurationProvider}. |
211 |
* @return a new configured instance of {@link ProjectConfigurationProvider} |
212 |
*/ |
213 |
@NonNull |
214 |
public ProjectConfigurationProvider<? extends ProjectConfiguration> build() { |
215 |
return new ConfigurationProviderImpl( |
216 |
project, |
217 |
eval, |
218 |
updateHelper, |
219 |
configurationsAffectActions, |
220 |
customizerAction); |
221 |
} |
222 |
} |
223 |
|
224 |
/** |
225 |
* The {@link ProjectConfiguration} implementation. |
226 |
*/ |
227 |
public static final class Configuration implements ProjectConfiguration { |
228 |
private final String name; |
229 |
private final String displayName; |
230 |
|
231 |
private Configuration( |
232 |
@NullAllowed final String name, |
233 |
@NonNull final String displayName) { |
234 |
Parameters.notNull("displayName", displayName); //NOI18N |
235 |
this.name = name; |
236 |
this.displayName = displayName; |
237 |
} |
238 |
|
239 |
/** |
240 |
* Returns the system name of the configuration. |
241 |
* @return the system name of configuration |
242 |
*/ |
243 |
@CheckForNull |
244 |
public String getName() { |
245 |
return name; |
246 |
} |
247 |
|
248 |
/** |
249 |
* Checks if the {@link Configuration} is a default one. |
250 |
* @return true when the {@link Configuration} is default |
251 |
*/ |
252 |
public boolean isDefault() { |
253 |
return name == null; |
254 |
} |
255 |
|
256 |
@Override |
257 |
@NonNull |
258 |
public String getDisplayName() { |
259 |
return displayName; |
260 |
} |
261 |
|
262 |
@Override |
263 |
public int hashCode() { |
264 |
return Objects.hashCode(name); |
265 |
} |
266 |
|
267 |
@Override |
268 |
public boolean equals(Object o) { |
269 |
return (o instanceof Configuration) && Objects.equals(name, ((Configuration) o).name); |
270 |
} |
271 |
|
272 |
@Override |
273 |
public String toString() { |
274 |
return "Config[" + name + "," + displayName + "]"; // NOI18N |
275 |
} |
276 |
} |
277 |
|
278 |
private static final class ConfigurationProviderImpl implements ProjectConfigurationProvider<Configuration> { |
279 |
|
280 |
private static final Configuration DEFAULT = new Configuration( |
281 |
null, |
282 |
NbBundle.getMessage(ProjectConfigurations.class, "TXT_DefaultConfig")); |
283 |
|
284 |
private final Project p; |
285 |
private final PropertyEvaluator eval; |
286 |
private final UpdateHelper updateHelper; |
287 |
private final Set<String> configurationsAffectActions; |
288 |
private final Runnable customizerAction; |
289 |
private final PropertyChangeSupport pcs = new PropertyChangeSupport(this); |
290 |
private final FileChangeListener fcl = new FileChangeAdapter() { |
291 |
@Override |
292 |
public void fileFolderCreated(@NonNull final FileEvent fe) { |
293 |
update(fe); |
294 |
} |
295 |
|
296 |
@Override |
297 |
public void fileDataCreated(@NonNull final FileEvent fe) { |
298 |
update(fe); |
299 |
} |
300 |
|
301 |
@Override |
302 |
public void fileDeleted(@NonNull final FileEvent fe) { |
303 |
update(fe); |
304 |
} |
305 |
|
306 |
@Override |
307 |
public void fileRenamed(@NonNull final FileRenameEvent fe) { |
308 |
update(fe); |
309 |
} |
310 |
|
311 |
private void update(@NonNull final FileEvent ev) { |
312 |
Parameters.notNull("ev", ev); //NOI18N |
313 |
LOGGER.log(Level.FINEST, "Received {0}", ev); |
314 |
Set<String> oldConfigs = configs != null ? configs.keySet() : Collections.<String>emptySet(); |
315 |
configDir = p.getProjectDirectory().getFileObject("nbproject/configs"); // NOI18N |
316 |
if (configDir != null) { |
317 |
configDir.removeFileChangeListener(fclWeak); |
318 |
configDir.addFileChangeListener(fclWeak); |
319 |
LOGGER.log(Level.FINEST, "(Re-)added listener to {0}", configDir); |
320 |
} else { |
321 |
LOGGER.log(Level.FINEST, "No nbproject/configs exists"); |
322 |
} |
323 |
calculateConfigs(); |
324 |
Set<String> newConfigs = configs.keySet(); |
325 |
if (!oldConfigs.equals(newConfigs)) { |
326 |
LOGGER.log(Level.FINER, "Firing " + ProjectConfigurationProvider.PROP_CONFIGURATIONS + ": {0} -> {1}", new Object[] {oldConfigs, newConfigs}); |
327 |
pcs.firePropertyChange(ProjectConfigurationProvider.PROP_CONFIGURATIONS, null, null); |
328 |
// XXX also fire PROP_ACTIVE_CONFIGURATION? |
329 |
} |
330 |
} |
331 |
}; |
332 |
private final FileChangeListener fclWeak; |
333 |
private FileObject configDir; |
334 |
private Map<String,Configuration> configs; |
335 |
private FileObject nbp; |
336 |
|
337 |
public ConfigurationProviderImpl( |
338 |
@NonNull final Project p, |
339 |
@NonNull final PropertyEvaluator eval, |
340 |
@NonNull final UpdateHelper updateHelper, |
341 |
@NonNull final Set<String> configurationsAffectActions, |
342 |
@NullAllowed final Runnable customizerAction) { |
343 |
Parameters.notNull("p", p); //NOI18N |
344 |
Parameters.notNull("eval", eval); //NOI18N |
345 |
Parameters.notNull("updateHelper", updateHelper); //NOI18N |
346 |
Parameters.notNull("configurationsAffectActions", configurationsAffectActions); //NOI18N |
347 |
this.p = p; |
348 |
this.eval = eval; |
349 |
this.updateHelper = updateHelper; |
350 |
this.configurationsAffectActions = configurationsAffectActions; |
351 |
this.customizerAction = customizerAction; |
352 |
fclWeak = FileUtil.weakFileChangeListener(fcl, null); |
353 |
nbp = p.getProjectDirectory().getFileObject("nbproject"); // NOI18N |
354 |
if (nbp != null) { |
355 |
nbp.addFileChangeListener(fclWeak); |
356 |
LOGGER.log(Level.FINEST, "Added listener to {0}", nbp); |
357 |
configDir = nbp.getFileObject("configs"); // NOI18N |
358 |
if (configDir != null) { |
359 |
configDir.addFileChangeListener(fclWeak); |
360 |
LOGGER.log(Level.FINEST, "Added listener to {0}", configDir); |
361 |
} |
362 |
} |
363 |
eval.addPropertyChangeListener(new PropertyChangeListener() { |
364 |
@Override |
365 |
public void propertyChange(@NonNull final PropertyChangeEvent evt) { |
366 |
if (ProjectProperties.PROP_PROJECT_CONFIGURATION_CONFIG.equals(evt.getPropertyName())) { |
367 |
LOGGER.log(Level.FINER, "Refiring " + ProjectProperties.PROP_PROJECT_CONFIGURATION_CONFIG + " -> " + ProjectConfigurationProvider.PROP_CONFIGURATION_ACTIVE); |
368 |
Set<String> oldConfigs = configs != null ? configs.keySet() : Collections.<String>emptySet(); |
369 |
calculateConfigs(); |
370 |
Set<String> newConfigs = configs.keySet(); |
371 |
if (!oldConfigs.equals(newConfigs)) { |
372 |
LOGGER.log(Level.FINER, "Firing " + ProjectConfigurationProvider.PROP_CONFIGURATIONS + ": {0} -> {1}", new Object[] {oldConfigs, newConfigs}); |
373 |
pcs.firePropertyChange(ProjectConfigurationProvider.PROP_CONFIGURATIONS, null, null); |
374 |
} |
375 |
pcs.firePropertyChange(ProjectConfigurationProvider.PROP_CONFIGURATION_ACTIVE, null, null); |
376 |
} |
377 |
} |
378 |
}); |
379 |
} |
380 |
|
381 |
private void calculateConfigs() { |
382 |
configs = new HashMap<String,Configuration>(); |
383 |
if (configDir != null) { |
384 |
for (FileObject kid : configDir.getChildren()) { |
385 |
if (!kid.hasExt("properties")) { //NOI18N |
386 |
continue; |
387 |
} |
388 |
try { |
389 |
try (InputStream is = kid.getInputStream()) { |
390 |
final Properties props = new Properties(); |
391 |
props.load(is); |
392 |
final String name = kid.getName(); |
393 |
final String label = props.getProperty("$label"); // NOI18N |
394 |
configs.put(name, new Configuration(name, label != null ? label : name)); |
395 |
} |
396 |
} catch (IOException x) { |
397 |
LOGGER.log(Level.INFO, null, x); |
398 |
} |
399 |
} |
400 |
} |
401 |
LOGGER.log(Level.FINEST, "Calculated configurations: {0}", configs); |
402 |
} |
403 |
|
404 |
@NonNull |
405 |
@Override |
406 |
public Collection<Configuration> getConfigurations() { |
407 |
calculateConfigs(); |
408 |
List<Configuration> l = new ArrayList<Configuration>(); |
409 |
l.addAll(configs.values()); |
410 |
Collections.sort(l, new Comparator<Configuration>() { |
411 |
Collator c = Collator.getInstance(); |
412 |
@Override |
413 |
public int compare(Configuration c1, Configuration c2) { |
414 |
return c.compare(c1.getDisplayName(), c2.getDisplayName()); |
415 |
} |
416 |
}); |
417 |
l.add(0, DEFAULT); |
418 |
return l; |
419 |
} |
420 |
|
421 |
@NonNull |
422 |
@Override |
423 |
public Configuration getActiveConfiguration() { |
424 |
calculateConfigs(); |
425 |
String config = eval.getProperty(ProjectProperties.PROP_PROJECT_CONFIGURATION_CONFIG); |
426 |
if (config != null && configs.containsKey(config)) { |
427 |
return configs.get(config); |
428 |
} else { |
429 |
return DEFAULT; |
430 |
} |
431 |
} |
432 |
|
433 |
@Override |
434 |
public void setActiveConfiguration(@NonNull final Configuration c) throws IllegalArgumentException, IOException { |
435 |
if (c != DEFAULT && !configs.values().contains(c)) { |
436 |
throw new IllegalArgumentException(String.valueOf(c)); |
437 |
} |
438 |
final String n = c.name; |
439 |
EditableProperties ep = updateHelper.getProperties(CONFIG_PROPS_PATH); |
440 |
if (Utilities.compareObjects(n, ep.getProperty(ProjectProperties.PROP_PROJECT_CONFIGURATION_CONFIG))) { |
441 |
return; |
442 |
} |
443 |
if (n != null) { |
444 |
ep.setProperty(ProjectProperties.PROP_PROJECT_CONFIGURATION_CONFIG, n); |
445 |
} else { |
446 |
ep.remove(ProjectProperties.PROP_PROJECT_CONFIGURATION_CONFIG); |
447 |
} |
448 |
updateHelper.putProperties(CONFIG_PROPS_PATH, ep); |
449 |
pcs.firePropertyChange(ProjectConfigurationProvider.PROP_CONFIGURATION_ACTIVE, null, null); |
450 |
ProjectManager.getDefault().saveProject(p); |
451 |
assert p.getProjectDirectory().getFileObject(CONFIG_PROPS_PATH) != null; |
452 |
} |
453 |
|
454 |
@Override |
455 |
public boolean hasCustomizer() { |
456 |
return customizerAction != null; |
457 |
} |
458 |
|
459 |
@Override |
460 |
public void customize() { |
461 |
if (customizerAction != null) { |
462 |
customizerAction.run(); |
463 |
} |
464 |
} |
465 |
|
466 |
|
467 |
@Override |
468 |
public boolean configurationsAffectAction(@NonNull final String command) { |
469 |
return configurationsAffectActions.contains(command); |
470 |
} |
471 |
|
472 |
@Override |
473 |
public void addPropertyChangeListener(@NonNull final PropertyChangeListener lst) { |
474 |
Parameters.notNull("lst", lst); //NOI18N |
475 |
pcs.addPropertyChangeListener(lst); |
476 |
} |
477 |
|
478 |
@Override |
479 |
public void removePropertyChangeListener(@NonNull final PropertyChangeListener lst) { |
480 |
Parameters.notNull("lst", lst); //NOI18N |
481 |
pcs.removePropertyChangeListener(lst); |
482 |
} |
483 |
} |
484 |
|
485 |
private static final class ConfigPropertyProvider extends FilterPropertyProvider implements PropertyChangeListener { |
486 |
private final PropertyEvaluator baseEval; |
487 |
private final String prefix; |
488 |
private final AntProjectHelper helper; |
489 |
|
490 |
@SuppressWarnings("LeakingThisInConstructor") |
491 |
public ConfigPropertyProvider(PropertyEvaluator baseEval, String prefix, AntProjectHelper helper) { |
492 |
super(computeDelegate(baseEval, prefix, helper)); |
493 |
this.baseEval = baseEval; |
494 |
this.prefix = prefix; |
495 |
this.helper = helper; |
496 |
baseEval.addPropertyChangeListener(this); |
497 |
} |
498 |
|
499 |
@Override |
500 |
public void propertyChange(PropertyChangeEvent ev) { |
501 |
if (ProjectProperties.PROP_PROJECT_CONFIGURATION_CONFIG.equals(ev.getPropertyName())) { |
502 |
setDelegate(computeDelegate(baseEval, prefix, helper)); |
503 |
} |
504 |
} |
505 |
|
506 |
private static PropertyProvider computeDelegate(PropertyEvaluator baseEval, String prefix, AntProjectHelper helper) { |
507 |
String config = baseEval.getProperty(ProjectProperties.PROP_PROJECT_CONFIGURATION_CONFIG); |
508 |
if (config != null) { |
509 |
return helper.getPropertyProvider(prefix + "/" + config + ".properties"); // NOI18N |
510 |
} else { |
511 |
return PropertyUtils.fixedPropertyProvider(Collections.<String,String>emptyMap()); |
512 |
} |
513 |
} |
514 |
} |
515 |
} |