📄 modifiedselector.java
字号:
/* * 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;// Javaimport java.util.Comparator;import java.util.Vector;import java.util.Iterator;import java.io.File;// Antimport org.apache.tools.ant.Project;import org.apache.tools.ant.IntrospectionHelper;import org.apache.tools.ant.BuildException;import org.apache.tools.ant.BuildListener;import org.apache.tools.ant.BuildEvent;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 simpliest 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/mycompony-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_START = "cache."; private static final String ALGORITHM_START = "algorithm."; private static final String COMPARATOR_START = "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 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 configParameter = new Vector(); /** * 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 specialParameter = new Vector(); /** 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 defaultComparator = new EqualComparator(); update = true; selectDirectories = true; // // ----- Set the main attributes, pattern '*' ----- // for (Iterator itConfig = configParameter.iterator(); itConfig.hasNext();) { Parameter par = (Parameter) itConfig.next(); if (par.getName().indexOf(".") > 0) { // this is a *.* parameter for later use specialParameter.add(par); } else { useParameter(par); } } configParameter = new Vector(); // specify the algorithm classname if (algoName != null) { // use Algorithm defined via name if ("hashvalue".equals(algoName.getValue())) { algorithm = new HashvalueAlgorithm();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -