diff options
Diffstat (limited to 'framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/modifiedselector/ModifiedSelector.java')
-rw-r--r-- | framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/modifiedselector/ModifiedSelector.java | 971 |
1 files changed, 971 insertions, 0 deletions
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/modifiedselector/ModifiedSelector.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/modifiedselector/ModifiedSelector.java new file mode 100644 index 00000000..9f538098 --- /dev/null +++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/modifiedselector/ModifiedSelector.java @@ -0,0 +1,971 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.tools.ant.types.selectors.modifiedselector; + + +// Java +import java.io.File; +import java.util.Comparator; +import java.util.Iterator; +import java.util.Vector; + +import org.apache.tools.ant.BuildEvent; +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.BuildListener; +import org.apache.tools.ant.IntrospectionHelper; +// Ant +import org.apache.tools.ant.Project; +import org.apache.tools.ant.types.EnumeratedAttribute; +import org.apache.tools.ant.types.Parameter; +import org.apache.tools.ant.types.Path; +import org.apache.tools.ant.types.Resource; +import org.apache.tools.ant.types.resources.FileResource; +import org.apache.tools.ant.types.resources.selectors.ResourceSelector; +import org.apache.tools.ant.types.selectors.BaseExtendSelector; +import org.apache.tools.ant.util.FileUtils; +import org.apache.tools.ant.util.ResourceUtils; + + +/** + * <p>Selector class that uses <i>Algorithm</i>, <i>Cache</i> and <i>Comparator</i> + * for its work. + * The <i>Algorithm</i> is used for computing a hashvalue for a file. + * The <i>Comparator</i> decides whether to select or not. + * The <i>Cache</i> stores the other value for comparison by the <i>Comparator</i> + * in a persistent manner.</p> + * + * <p>The ModifiedSelector is implemented as a <b>CoreSelector</b> and uses default + * values for all its attributes therefore the simplest example is <pre> + * <copy todir="dest"> + * <filelist dir="src"> + * <modified/> + * </filelist> + * </copy> + * </pre></p> + * + * <p>The same example rewritten as CoreSelector with setting the all values + * (same as defaults are) would be <pre> + * <copy todir="dest"> + * <filelist dir="src"> + * <modified update="true" + * cache="propertyfile" + * algorithm="digest" + * comparator="equal"> + * <param name="cache.cachefile" value="cache.properties"/> + * <param name="algorithm.algorithm" value="MD5"/> + * </modified> + * </filelist> + * </copy> + * </pre></p> + * + * <p>And the same rewritten as CustomSelector would be<pre> + * <copy todir="dest"> + * <filelist dir="src"> + * <custom class="org.apache.tools.ant.type.selectors.ModifiedSelector"> + * <param name="update" value="true"/> + * <param name="cache" value="propertyfile"/> + * <param name="algorithm" value="digest"/> + * <param name="comparator" value="equal"/> + * <param name="cache.cachefile" value="cache.properties"/> + * <param name="algorithm.algorithm" value="MD5"/> + * </custom> + * </filelist> + * </copy> + * </pre></p> + * + * <p>If you want to provide your own interface implementation you can do + * that via the *classname attributes. If the classes are not on Ant's core + * classpath, you will have to provide the path via nested <classpath> + * element, so that the selector can find the classes. <pre> + * <modified cacheclassname="com.mycompany.MyCache"> + * <classpath> + * <pathelement location="lib/mycompany-antutil.jar"/> + * </classpath> + * </modified> + * </pre></p> + * + * <p>All these three examples copy the files from <i>src</i> to <i>dest</i> + * using the ModifiedSelector. The ModifiedSelector uses the <i>PropertyfileCache + * </i>, the <i>DigestAlgorithm</i> and the <i>EqualComparator</i> for its + * work. The PropertyfileCache stores key-value-pairs in a simple java + * properties file. The filename is <i>cache.properties</i>. The <i>update</i> + * flag lets the selector update the values in the cache (and on first call + * creates the cache). The <i>DigestAlgorithm</i> computes a hashvalue using the + * java.security.MessageDigest class with its MD5-Algorithm and its standard + * provider. The new computed hashvalue and the stored one are compared by + * the <i>EqualComparator</i> which returns 'true' (more correct a value not + * equals zero (1)) if the values are not the same using simple String + * comparison.</p> + * + * <p>A useful scenario for this selector is inside a build environment + * for homepage generation (e.g. with <a href="http://forrest.apache.org/"> + * Apache Forrest</a>). <pre> + * <target name="generate-and-upload-site"> + * <echo> generate the site using forrest </echo> + * <antcall target="site"/> + * + * <echo> upload the changed files </echo> + * <ftp server="${ftp.server}" userid="${ftp.user}" password="${ftp.pwd}"> + * <fileset dir="htdocs/manual"> + * <modified/> + * </fileset> + * </ftp> + * </target> + * </pre> Here all <b>changed</b> files are uploaded to the server. The + * ModifiedSelector saves therefore much upload time.</p> + * + * + * <p>This selector uses reflection for setting the values of its three interfaces + * (using org.apache.tools.ant.IntrospectionHelper) therefore no special + * 'configuration interfaces' has to be implemented by new caches, algorithms or + * comparators. All present <i>set</i>XX methods can be used. E.g. the DigestAlgorithm + * can use a specified provider for computing its value. For selecting this + * there is a <i>setProvider(String providername)</i> method. So you can use + * a nested <i><param name="algorithm.provider" value="MyProvider"/></i>. + * + * + * @since Ant 1.6 + */ +public class ModifiedSelector extends BaseExtendSelector + implements BuildListener, ResourceSelector { + + private static final String CACHE_PREFIX = "cache."; + private static final String ALGORITHM_PREFIX = "algorithm."; + private static final String COMPARATOR_PREFIX = "comparator."; + + + // ----- attributes ----- + + + /** Cache name for later instantiation. */ + private CacheName cacheName = null; + + /** User specified classname for Cache. */ + private String cacheClass; + + /** Algorithm name for later instantiation. */ + private AlgorithmName algoName = null; + + /** User specified classname for Algorithm. */ + private String algorithmClass; + + /** Comparator name for later instantiation. */ + private ComparatorName compName = null; + + /** User specified classname for Comparator. */ + private String comparatorClass; + + /** Should the cache be updated? */ + private boolean update = true; + + /** Are directories selected? */ + private boolean selectDirectories = true; + + /** + * Should Resources whithout an InputStream, and + * therefore without checking, be selected? + */ + private boolean selectResourcesWithoutInputStream = true; + + /** Delay the writing of the cache file */ + private boolean delayUpdate = true; + + + // ----- internal member variables ----- + + + /** How should the cached value and the new one compared? */ + private Comparator<? super String> comparator = null; + + /** Algorithm for computing new values and updating the cache. */ + private Algorithm algorithm = null; + + /** The Cache containing the old values. */ + private Cache cache = null; + + /** Count of modified properties */ + private int modified = 0; + + /** Flag whether this object is configured. Configuration is only done once. */ + private boolean isConfigured = false; + + /** + * Parameter vector with parameters for later initialization. + * @see #configure + */ + private Vector<Parameter> configParameter = new Vector<Parameter>(); + + /** + * Parameter vector with special parameters for later initialization. + * The names have the pattern '*.*', e.g. 'cache.cachefile'. + * These parameters are used <b>after</b> the parameters with the pattern '*'. + * @see #configure + */ + private Vector<Parameter> specialParameter = new Vector<Parameter>(); + + /** The classloader of this class. */ + private ClassLoader myClassLoader = null; + + /** provided classpath for the classloader */ + private Path classpath = null; + + + // ----- constructors ----- + + + /** Bean-Constructor. */ + public ModifiedSelector() { + } + + + // ----- configuration ----- + + + /** Overrides BaseSelector.verifySettings(). */ + public void verifySettings() { + configure(); + if (cache == null) { + setError("Cache must be set."); + } else if (algorithm == null) { + setError("Algorithm must be set."); + } else if (!cache.isValid()) { + setError("Cache must be proper configured."); + } else if (!algorithm.isValid()) { + setError("Algorithm must be proper configured."); + } + } + + + /** + * 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> + * <li> wait for the first isSelected() call </li> + * <li> set the default values </li> + * <li> set values for name pattern '*': update, cache, algorithm, comparator </li> + * <li> set values for name pattern '*.*: cache.cachefile, ... </li> + * </ol></p> + * <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.</p> + */ + 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 = 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 = 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>(); + } + + + /** + * Loads the specified class and initializes an object of that class. + * Throws a BuildException using the given message if an error occurs during + * loading/instantiation or if the object is not from the given type. + * @param classname the classname + * @param msg the message-part for the BuildException + * @param type the type to check against + * @return a castable object + */ + protected <T> T loadClass(String classname, String msg, Class<? extends T> type) { + try { + // load the specified class + ClassLoader cl = getClassLoader(); + Class<?> clazz = null; + if (cl != null) { + clazz = cl.loadClass(classname); + } else { + clazz = Class.forName(classname); + } + + Object rv = clazz.newInstance(); + + if (!type.isInstance(rv)) { + throw new BuildException("Specified class (" + classname + ") " + msg); + } + return (T) rv; + } catch (ClassNotFoundException e) { + throw new BuildException("Specified class (" + classname + ") not found."); + } catch (Exception e) { + throw new BuildException(e); + } + } + + + // ----- the selection work ----- + + + /** + * Implementation of ResourceSelector.isSelected(). + * + * @param resource The resource to check + * @return whether the resource is selected + * @see ResourceSelector#isSelected(Resource) + */ + public boolean isSelected(Resource resource) { + if (resource.isFilesystemOnly()) { + // We have a 'resourced' file, so reconvert it and use + // the 'old' implementation. + FileResource fileResource = (FileResource) resource; + File file = fileResource.getFile(); + String filename = fileResource.getName(); + File basedir = fileResource.getBaseDir(); + return isSelected(basedir, filename, file); + } else { + try { + // How to handle non-file-Resources? I copy temporarily the + // resource to a file and use the file-implementation. + FileUtils fu = FileUtils.getFileUtils(); + File tmpFile = fu.createTempFile("modified-", ".tmp", null, true, false); + Resource tmpResource = new FileResource(tmpFile); + ResourceUtils.copyResource(resource, tmpResource); + boolean isSelected = isSelected(tmpFile.getParentFile(), + tmpFile.getName(), + resource.toLongString()); + tmpFile.delete(); + return isSelected; + } catch (UnsupportedOperationException uoe) { + log("The resource '" + + resource.getName() + + "' does not provide an InputStream, so it is not checked. " + + "Akkording to 'selres' attribute value it is " + + ((selectResourcesWithoutInputStream) ? "" : " not") + + "selected.", Project.MSG_INFO); + return selectResourcesWithoutInputStream; + } catch (Exception e) { + throw new BuildException(e); + } + } + } + + + /** + * Implementation of BaseExtendSelector.isSelected(). + * + * @param basedir as described in BaseExtendSelector + * @param filename as described in BaseExtendSelector + * @param file as described in BaseExtendSelector + * @return as described in BaseExtendSelector + */ + public boolean isSelected(File basedir, String filename, File file) { + return isSelected(basedir, filename, file.getAbsolutePath()); + } + + + /** + * The business logic of this selector for use as ResourceSelector of + * FileSelector. + * + * @param basedir as described in BaseExtendSelector + * @param filename as described in BaseExtendSelector + * @param cacheKey the name for the key for storing the hashvalue + * @return <tt>true</tt> if the file is selected otherwise <tt>false</tt> + */ + private boolean isSelected(File basedir, String filename, String cacheKey) { + validate(); + File f = new File(basedir, filename); + + // You can not compute a value for a directory + if (f.isDirectory()) { + return selectDirectories; + } + + // Get the values and do the comparison + String cachedValue = String.valueOf(cache.get(f.getAbsolutePath())); + String newValue = algorithm.getValue(f); + + boolean rv = (comparator.compare(cachedValue, newValue) != 0); + + // Maybe update the cache + if (update && rv) { + cache.put(f.getAbsolutePath(), newValue); + setModified(getModified() + 1); + if (!getDelayUpdate()) { + saveCache(); + } + } + + return rv; + } + + + /** + * save the cache file + */ + protected void saveCache() { + if (getModified() > 0) { + cache.save(); + setModified(0); + } + } + + + // ----- attribute and nested element support ----- + + + /** + * Setter for algorithmClass. + * @param classname new value + */ + public void setAlgorithmClass(String classname) { + algorithmClass = classname; + } + + + /** + * Setter for comparatorClass. + * @param classname new value + */ + public void setComparatorClass(String classname) { + comparatorClass = classname; + } + + + /** + * Setter for cacheClass. + * @param classname new value + */ + public void setCacheClass(String classname) { + cacheClass = classname; + } + + + /** + * Support for <i>update</i> attribute. + * @param update new value + */ + public void setUpdate(boolean update) { + this.update = update; + } + + + /** + * Support for <i>seldirs</i> attribute. + * @param seldirs new value + */ + public void setSeldirs(boolean seldirs) { + selectDirectories = seldirs; + } + + + /** + * Support for <i>selres</i> attribute. + * @param newValue the new value + */ + public void setSelres(boolean newValue) { + this.selectResourcesWithoutInputStream = newValue; + } + + + /** + * Getter for the modified count + * @return modified count + */ + public int getModified() { + return modified; + } + + + /** + * Setter for the modified count + * @param modified count + */ + public void setModified(int modified) { + this.modified = modified; + } + + + /** + * Getter for the delay update + * @return true if we should delay for performance + */ + public boolean getDelayUpdate() { + return delayUpdate; + } + + + /** + * Setter for the delay update + * @param delayUpdate true if we should delay for performance + */ + public void setDelayUpdate(boolean delayUpdate) { + this.delayUpdate = delayUpdate; + } + + + /** + * Add the classpath. + * @param path the classpath + */ + public void addClasspath(Path path) { + if (classpath != null) { + throw new BuildException("<classpath> can be set only once."); + } + classpath = path; + } + + + /** + * Returns and initializes the classloader for this class. + * @return the classloader + */ + public ClassLoader getClassLoader() { + if (myClassLoader == null) { + myClassLoader = (classpath == null) + // the usual classloader + ? getClass().getClassLoader() + // additional use the provided classpath + // Memory leak in line below + : getProject().createClassLoader(classpath); + } + return myClassLoader; + } + + + /** + * Set the used ClassLoader. + * If you invoke this selector by API (e.g. inside some testcases) the selector + * will use a different classloader for loading the interface implementations than + * the caller. Therefore you will get a ClassCastException if you get the + * implementations from the selector and cast them. + * @param loader the ClassLoader to use + */ + public void setClassLoader(ClassLoader loader) { + myClassLoader = loader; + } + + + /** + * Support for nested <param> tags. + * @param key the key of the parameter + * @param value the value of the parameter + */ + public void addParam(String key, Object value) { + Parameter par = new Parameter(); + par.setName(key); + par.setValue(String.valueOf(value)); + configParameter.add(par); + } + + + /** + * Support for nested <param> tags. + * @param parameter the parameter object + */ + public void addParam(Parameter parameter) { + configParameter.add(parameter); + } + + + /** + * Defined in org.apache.tools.ant.types.Parameterizable. + * Overwrite implementation in superclass because only special + * parameters are valid. + * @see #addParam(String,Object). + * @param parameters the parameters to set. + */ + public void setParameters(Parameter[] parameters) { + if (parameters != null) { + for (int i = 0; i < parameters.length; i++) { + configParameter.add(parameters[i]); + } + } + } + + + /** + * Support for nested <param name="" value=""/> tags. + * Parameter named <i>cache</i>, <i>algorithm</i>, + * <i>comparator</i> or <i>update</i> are mapped to + * the respective set-Method. + * Parameter which names starts with <i>cache.</i> or + * <i>algorithm.</i> or <i>comparator.</i> are tried + * to set on the appropriate object via its set-methods. + * Other parameters are invalid and an BuildException will + * be thrown. + * + * @param parameter Key and value as parameter object + */ + public void useParameter(Parameter parameter) { + String key = parameter.getName(); + String value = parameter.getValue(); + if ("cache".equals(key)) { + CacheName cn = new CacheName(); + cn.setValue(value); + setCache(cn); + } else if ("algorithm".equals(key)) { + AlgorithmName an = new AlgorithmName(); + an.setValue(value); + setAlgorithm(an); + } else if ("comparator".equals(key)) { + ComparatorName cn = new ComparatorName(); + cn.setValue(value); + setComparator(cn); + } else if ("update".equals(key)) { + boolean updateValue = + ("true".equalsIgnoreCase(value)) + ? true + : false; + setUpdate(updateValue); + } else if ("delayupdate".equals(key)) { + boolean updateValue = + ("true".equalsIgnoreCase(value)) + ? true + : false; + setDelayUpdate(updateValue); + } else if ("seldirs".equals(key)) { + boolean sdValue = + ("true".equalsIgnoreCase(value)) + ? true + : false; + setSeldirs(sdValue); + } else if (key.startsWith(CACHE_PREFIX)) { + String name = key.substring(CACHE_PREFIX.length()); + tryToSetAParameter(cache, name, value); + } else if (key.startsWith(ALGORITHM_PREFIX)) { + String name = key.substring(ALGORITHM_PREFIX.length()); + tryToSetAParameter(algorithm, name, value); + } else if (key.startsWith(COMPARATOR_PREFIX)) { + String name = key.substring(COMPARATOR_PREFIX.length()); + tryToSetAParameter(comparator, name, value); + } else { + setError("Invalid parameter " + key); + } + } + + + /** + * Try to set a value on an object using reflection. + * Helper method for easier access to IntrospectionHelper.setAttribute(). + * @param obj the object on which the attribute should be set + * @param name the attributename + * @param value the new value + */ + protected void tryToSetAParameter(Object obj, String name, String value) { + Project prj = (getProject() != null) ? getProject() : new Project(); + IntrospectionHelper iHelper + = IntrospectionHelper.getHelper(prj, obj.getClass()); + try { + iHelper.setAttribute(prj, obj, name, value); + } catch (org.apache.tools.ant.BuildException e) { + // no-op + } + } + + + // ----- 'beautiful' output ----- + + + /** + * Override Object.toString(). + * @return information about this selector + */ + public String toString() { + StringBuffer buf = new StringBuffer("{modifiedselector"); + buf.append(" update=").append(update); + buf.append(" seldirs=").append(selectDirectories); + buf.append(" cache=").append(cache); + buf.append(" algorithm=").append(algorithm); + buf.append(" comparator=").append(comparator); + buf.append("}"); + return buf.toString(); + } + + + // ----- BuildListener interface methods ----- + + + /** + * Signals that the last target has finished. + * @param event received BuildEvent + */ + public void buildFinished(BuildEvent event) { + if (getDelayUpdate()) { + saveCache(); + } + } + + + /** + * Signals that a target has finished. + * @param event received BuildEvent + */ + public void targetFinished(BuildEvent event) { + if (getDelayUpdate()) { + saveCache(); + } + } + + + /** + * Signals that a task has finished. + * @param event received BuildEvent + */ + public void taskFinished(BuildEvent event) { + if (getDelayUpdate()) { + saveCache(); + } + } + + + /** + * Signals that a build has started. + * @param event received BuildEvent + */ + public void buildStarted(BuildEvent event) { + // no-op + } + + + /** + * Signals that a target is starting. + * @param event received BuildEvent + */ + public void targetStarted(BuildEvent event) { + // no-op + } + + + + /** + * Signals that a task is starting. + * @param event received BuildEvent + */ + public void taskStarted(BuildEvent event) { + // no-op + } + + + /** + * Signals a message logging event. + * @param event received BuildEvent + */ + public void messageLogged(BuildEvent event) { + // no-op + } + + + // The EnumeratedAttributes for the three interface implementations. + // Name-Classname mapping is done in the configure() method. + + + /** + * Get the cache type to use. + * @return the enumerated cache type + */ + public Cache getCache() { + return cache; + } + + /** + * Set the cache type to use. + * @param name an enumerated cache type. + */ + public void setCache(CacheName name) { + cacheName = name; + } + + /** + * The enumerated type for cache. + * The values are "propertyfile". + */ + public static class CacheName extends EnumeratedAttribute { + /** + * {@inheritDoc} + * @see EnumeratedAttribute#getValues() + */ + public String[] getValues() { + return new String[] {"propertyfile" }; + } + } + + /** + * Get the algorithm type to use. + * @return the enumerated algorithm type + */ + public Algorithm getAlgorithm() { + return algorithm; + } + + /** + * Set the algorithm type to use. + * @param name an enumerated algorithm type. + */ + public void setAlgorithm(AlgorithmName name) { + algoName = name; + } + + /** + * The enumerated type for algorithm. + * The values are "hashValue", "digest" and "checksum". + */ + public static class AlgorithmName extends EnumeratedAttribute { + /** + * {@inheritDoc} + * @see EnumeratedAttribute#getValues() + */ + public String[] getValues() { + return new String[] {"hashvalue", "digest", "checksum" }; + } + } + + /** + * Get the comparator type to use. + * @return the enumerated comparator type + */ + public Comparator<? super String> getComparator() { + return comparator; + } + + /** + * Set the comparator type to use. + * @param name an enumerated comparator type. + */ + public void setComparator(ComparatorName name) { + compName = name; + } + + /** + * The enumerated type for algorithm. + * The values are "equal" and "rule". + */ + public static class ComparatorName extends EnumeratedAttribute { + /** + * {@inheritDoc} + * @see EnumeratedAttribute#getValues() + */ + public String[] getValues() { + return new String[] {"equal", "rule" }; + } + } + +} |