- /*
- * Copyright 2001-2004 The Apache Software Foundation
- *
- * Licensed 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;
-
- // java io classes
- import java.io.File;
- import java.io.FileInputStream;
- import java.io.IOException;
- import java.util.Enumeration;
- import java.util.Hashtable;
- import java.util.Properties;
- import java.util.Vector;
- import org.apache.tools.ant.BuildException;
- import org.apache.tools.ant.Project;
-
-
- /**
- * A set of filters to be applied to something.
- *
- * A filter set may have begintoken and endtokens defined.
- *
- */
- public class FilterSet extends DataType implements Cloneable {
-
- /**
- * Individual filter component of filterset
- *
- */
- public static class Filter {
- /** Token which will be replaced in the filter operation */
- String token;
-
- /** The value which will replace the token in the filtering operation */
- String value;
-
- /**
- * Constructor for the Filter object
- *
- * @param token The token which will be replaced when filtering
- * @param value The value which will replace the token when filtering
- */
- public Filter(String token, String value) {
- this.token = token;
- this.value = value;
- }
-
- /**
- * No argument conmstructor
- */
- public Filter() {
- }
-
- /**
- * Sets the Token attribute of the Filter object
- *
- * @param token The new Token value
- */
- public void setToken(String token) {
- this.token = token;
- }
-
- /**
- * Sets the Value attribute of the Filter object
- *
- * @param value The new Value value
- */
- public void setValue(String value) {
- this.value = value;
- }
-
- /**
- * Gets the Token attribute of the Filter object
- *
- * @return The Token value
- */
- public String getToken() {
- return token;
- }
-
- /**
- * Gets the Value attribute of the Filter object
- *
- * @return The Value value
- */
- public String getValue() {
- return value;
- }
- }
-
- /**
- * The filtersfile nested element.
- *
- */
- public class FiltersFile {
-
- /**
- * Constructor for the Filter object
- */
- public FiltersFile() {
- }
-
- /**
- * Sets the file from which filters will be read.
- *
- * @param file the file from which filters will be read.
- */
- public void setFile(File file) {
- readFiltersFromFile(file);
- }
- }
-
- /** The default token start string */
- public static final String DEFAULT_TOKEN_START = "@";
-
- /** The default token end string */
- public static final String DEFAULT_TOKEN_END = "@";
-
- private String startOfToken = DEFAULT_TOKEN_START;
- private String endOfToken = DEFAULT_TOKEN_END;
-
- /**
- * List of ordered filters and filter files.
- */
- private Vector filters = new Vector();
-
- /**
- * Default constructor
- */
- public FilterSet() {
- }
-
- /**
- * Create a Filterset from another filterset
- *
- * @param filterset the filterset upon which this filterset will be based.
- */
- protected FilterSet(FilterSet filterset) {
- super();
- this.filters = (Vector) filterset.getFilters().clone();
- }
-
- /**
- * Get the filters in the filter set
- *
- * @return a Vector of Filter instances
- */
- protected Vector getFilters() {
- if (isReference()) {
- return getRef().getFilters();
- }
- return filters;
- }
-
- /**
- * Get the referred filter set
- *
- * @return the filterset from the reference.
- */
- protected FilterSet getRef() {
- return (FilterSet) getCheckedRef(FilterSet.class, "filterset");
- }
-
- /**
- * Gets the filter hash of the FilterSet.
- *
- * @return The hash of the tokens and values for quick lookup.
- */
- public Hashtable getFilterHash() {
- int filterSize = getFilters().size();
- Hashtable filterHash = new Hashtable(filterSize + 1);
- for (Enumeration e = getFilters().elements(); e.hasMoreElements();) {
- Filter filter = (Filter) e.nextElement();
- filterHash.put(filter.getToken(), filter.getValue());
- }
- return filterHash;
- }
-
- /**
- * set the file containing the filters for this filterset.
- *
- * @param filtersFile sets the filter fil to read filters for this filter set from.
- * @exception BuildException if there is a problem reading the filters
- */
- public void setFiltersfile(File filtersFile) throws BuildException {
- if (isReference()) {
- throw tooManyAttributes();
- }
- readFiltersFromFile(filtersFile);
- }
-
- /**
- * The string used to id the beginning of a token.
- *
- * @param startOfToken The new Begintoken value
- */
- public void setBeginToken(String startOfToken) {
- if (isReference()) {
- throw tooManyAttributes();
- }
- if (startOfToken == null || "".equals(startOfToken)) {
- throw new BuildException("beginToken must not be empty");
- }
- this.startOfToken = startOfToken;
- }
-
- /**
- * Get the begin token for this filterset
- *
- * @return the filter set's begin token for filtering
- */
- public String getBeginToken() {
- if (isReference()) {
- return getRef().getBeginToken();
- }
- return startOfToken;
- }
-
-
- /**
- * The string used to id the end of a token.
- *
- * @param endOfToken The new Endtoken value
- */
- public void setEndToken(String endOfToken) {
- if (isReference()) {
- throw tooManyAttributes();
- }
- if (endOfToken == null || "".equals(endOfToken)) {
- throw new BuildException("endToken must not be empty");
- }
- this.endOfToken = endOfToken;
- }
-
- /**
- * Get the end token for this filterset
- *
- * @return the filter set's end token for replacement delimiting
- */
- public String getEndToken() {
- if (isReference()) {
- return getRef().getEndToken();
- }
- return endOfToken;
- }
-
-
- /**
- * Read the filters from the given file.
- *
- * @param filtersFile the file from which filters are read
- * @exception BuildException Throw a build exception when unable to read the
- * file.
- */
- public void readFiltersFromFile(File filtersFile) throws BuildException {
- if (isReference()) {
- throw tooManyAttributes();
- }
-
- if (!filtersFile.exists()) {
- throw new BuildException("Could not read filters from file "
- + filtersFile + " as it doesn't exist.");
- }
-
- if (filtersFile.isFile()) {
- log("Reading filters from " + filtersFile, Project.MSG_VERBOSE);
- FileInputStream in = null;
- try {
- Properties props = new Properties();
- in = new FileInputStream(filtersFile);
- props.load(in);
-
- Enumeration e = props.propertyNames();
- Vector filters = getFilters();
- while (e.hasMoreElements()) {
- String strPropName = (String) e.nextElement();
- String strValue = props.getProperty(strPropName);
- filters.addElement(new Filter(strPropName, strValue));
- }
- } catch (Exception ex) {
- throw new BuildException("Could not read filters from file: "
- + filtersFile);
- } finally {
- if (in != null) {
- try {
- in.close();
- } catch (IOException ioex) {
- // ignore
- }
- }
- }
- } else {
- throw new BuildException("Must specify a file not a directory in "
- + "the filtersfile attribute:" + filtersFile);
- }
- }
-
- /**
- * Does replacement on the given string with token matching.
- * This uses the defined begintoken and endtoken values which default
- * to @ for both.
- * This resets the passedTokens and calls iReplaceTokens to
- * do the actual replacements.
- *
- * @param line The line to process the tokens in.
- * @return The string with the tokens replaced.
- */
- public String replaceTokens(String line) {
- passedTokens = null; // reset for new line
- return iReplaceTokens(line);
- }
-
- /**
- * Does replacement on the given string with token matching.
- * This uses the defined begintoken and endtoken values which default
- * to @ for both.
- *
- * @param line The line to process the tokens in.
- * @return The string with the tokens replaced.
- */
- private String iReplaceTokens(String line) {
- String beginToken = getBeginToken();
- String endToken = getEndToken();
- int index = line.indexOf(beginToken);
-
- if (index > -1) {
- Hashtable tokens = getFilterHash();
- try {
- StringBuffer b = new StringBuffer();
- int i = 0;
- String token = null;
- String value = null;
-
- do {
- int endIndex = line.indexOf(endToken,
- index + beginToken.length() + 1);
- if (endIndex == -1) {
- break;
- }
- token
- = line.substring(index + beginToken.length(), endIndex);
- b.append(line.substring(i, index));
- if (tokens.containsKey(token)) {
- value = (String) tokens.get(token);
- if (!value.equals(token)) {
- // we have another token, let's parse it.
- value = replaceTokens(value, token);
- }
- log("Replacing: " + beginToken + token + endToken
- + " -> " + value, Project.MSG_VERBOSE);
- b.append(value);
- i = index + beginToken.length() + token.length()
- + endToken.length();
- } else {
- // just append beginToken and search further
- b.append(beginToken);
- i = index + beginToken.length();
- }
- } while ((index = line.indexOf(beginToken, i)) > -1);
-
- b.append(line.substring(i));
- return b.toString();
- } catch (StringIndexOutOfBoundsException e) {
- return line;
- }
- } else {
- return line;
- }
- }
-
- /** Contains a list of parsed tokens */
- private Vector passedTokens;
- /** if a ducplicate token is found, this is set to true */
- private boolean duplicateToken = false;
-
- /**
- * This parses tokens which point to tokens.
- * It also maintains a list of currently used tokens, so we cannot
- * get into an infinite loop
- * @param line the value / token to parse
- * @param parent the parant token (= the token it was parsed from)
- */
- private String replaceTokens(String line, String parent)
- throws BuildException {
- if (passedTokens == null) {
- passedTokens = new Vector();
- }
- if (passedTokens.contains(parent) && !duplicateToken) {
- duplicateToken = true;
- StringBuffer sb = new StringBuffer();
- sb.append("Infinite loop in tokens. Currently known tokens : ");
- sb.append(passedTokens);
- sb.append("\nProblem token : " + getBeginToken() + parent
- + getEndToken());
- sb.append(" called from " + getBeginToken()
- + passedTokens.lastElement());
- sb.append(getEndToken());
- System.out.println(sb.toString());
- return parent;
- }
- passedTokens.addElement(parent);
- String value = iReplaceTokens(line);
- if (value.indexOf(getBeginToken()) == -1 && !duplicateToken) {
- duplicateToken = false;
- passedTokens = null;
- } else if (duplicateToken) {
- // should always be the case...
- if (passedTokens.size() > 0) {
- value = (String) passedTokens.lastElement();
- passedTokens.removeElementAt(passedTokens.size() - 1);
- if (passedTokens.size() == 0) {
- value = getBeginToken() + value + getEndToken();
- duplicateToken = false;
- }
- }
- }
- return value;
- }
-
- /**
- * Create a new filter
- *
- * @param filter the filter to be added
- */
- public void addFilter(Filter filter) {
- if (isReference()) {
- throw noChildrenAllowed();
- }
- filters.addElement(filter);
- }
-
- /**
- * Create a new FiltersFile
- *
- * @return The filter that was created.
- */
- public FiltersFile createFiltersfile() {
- if (isReference()) {
- throw noChildrenAllowed();
- }
- return new FiltersFile();
- }
-
- /**
- * Add a new filter made from the given token and value.
- *
- * @param token The token for the new filter.
- * @param value The value for the new filter.
- */
- public void addFilter(String token, String value) {
- if (isReference()) {
- throw noChildrenAllowed();
- }
- filters.addElement(new Filter(token, value));
- }
-
- /**
- * Add a Filterset to this filter set
- *
- * @param filterSet the filterset to be added to this filterset
- */
- public void addConfiguredFilterSet(FilterSet filterSet) {
- if (isReference()) {
- throw noChildrenAllowed();
- }
- for (Enumeration e = filterSet.getFilters().elements(); e.hasMoreElements();) {
- filters.addElement(e.nextElement());
- }
- }
-
- /**
- * Test to see if this filter set it empty.
- *
- * @return Return true if there are filter in this set otherwise false.
- */
- public boolean hasFilters() {
- return getFilters().size() > 0;
- }
-
- /**
- * clone the filterset
- *
- * @return a deep clone of this filterset
- *
- * @throws BuildException if the clone cannot be performed.
- */
- public Object clone() throws BuildException {
- if (isReference()) {
- return ((FilterSet) getRef()).clone();
- } else {
- try {
- FilterSet fs = (FilterSet) super.clone();
- fs.filters = (Vector) getFilters().clone();
- fs.setProject(getProject());
- return fs;
- } catch (CloneNotSupportedException e) {
- throw new BuildException(e);
- }
- }
- }
-
- }
-
-
-