/** * Configures this Selector. Does this work only once per Selector object. * * <p>Because some problems while configuring from <custom>Selector the configuration is done in * the following order: * * <ol> * <li>collect the configuration data * <li>wait for the first isSelected() call * <li>set the default values * <li>set values for name pattern '*': update, cache, algorithm, comparator * <li>set values for name pattern '*.*: cache.cachefile, ... * </ol> * * <p>This configuration algorithm is needed because you don't know the order of arriving * config-data. E.g. if you first set the <i>cache.cachefilename</i> and after that the * <i>cache</i> itself, the default value for cachefilename is used, because setting the cache * implies creating a new Cache instance - with its defaults. */ public void configure() { // // ----- The "Singleton" ----- // if (isConfigured) { return; } isConfigured = true; // // ----- Set default values ----- // Project p = getProject(); String filename = "cache.properties"; File cachefile = null; if (p != null) { // normal use inside Ant cachefile = new File(p.getBaseDir(), filename); // set self as a BuildListener to delay cachefile saves getProject().addBuildListener(this); } else { // no reference to project - e.g. during normal JUnit tests cachefile = new File(filename); setDelayUpdate(false); } Cache defaultCache = new PropertiesfileCache(cachefile); Algorithm defaultAlgorithm = new DigestAlgorithm(); Comparator<? super String> defaultComparator = new EqualComparator(); // // ----- Set the main attributes, pattern '*' ----- // for (Parameter parameter : configParameter) { if (parameter.getName().indexOf(".") > 0) { // this is a *.* parameter for later use specialParameter.add(parameter); } else { useParameter(parameter); } } configParameter = new Vector<Parameter>(); // specify the algorithm classname if (algoName != null) { // use Algorithm defined via name if ("hashvalue".equals(algoName.getValue())) { algorithm = new HashvalueAlgorithm(); } else if ("digest".equals(algoName.getValue())) { algorithm = new DigestAlgorithm(); } else if ("checksum".equals(algoName.getValue())) { algorithm = new ChecksumAlgorithm(); } } else { if (algorithmClass != null) { // use Algorithm specified by classname algorithm = (Algorithm) loadClass(algorithmClass, "is not an Algorithm.", Algorithm.class); } else { // nothing specified - use default algorithm = defaultAlgorithm; } } // specify the cache classname if (cacheName != null) { // use Cache defined via name if ("propertyfile".equals(cacheName.getValue())) { cache = new PropertiesfileCache(); } } else { if (cacheClass != null) { // use Cache specified by classname cache = (Cache) loadClass(cacheClass, "is not a Cache.", Cache.class); } else { // nothing specified - use default cache = defaultCache; } } // specify the comparator classname if (compName != null) { // use Algorithm defined via name if ("equal".equals(compName.getValue())) { comparator = new EqualComparator(); } else if ("rule".equals(compName.getValue())) { // TODO there is a problem with the constructor for the RBC. // you have to provide the rules in the constructors - no setters // available. throw new BuildException("RuleBasedCollator not yet supported."); // Have to think about lazy initialization here... JHM // comparator = new java.text.RuleBasedCollator(); } } else { if (comparatorClass != null) { // use Algorithm specified by classname @SuppressWarnings("unchecked") Comparator<? super String> localComparator = loadClass(comparatorClass, "is not a Comparator.", Comparator.class); comparator = localComparator; } else { // nothing specified - use default comparator = defaultComparator; } } // // ----- Set the special attributes, pattern '*.*' ----- // for (Iterator<Parameter> itSpecial = specialParameter.iterator(); itSpecial.hasNext(); ) { Parameter par = itSpecial.next(); useParameter(par); } specialParameter = new Vector<Parameter>(); }