001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: *
017: */
018:
019: package org.apache.tools.ant.util;
020:
021: import java.util.Vector;
022: import org.apache.tools.ant.BuildException;
023: import org.apache.tools.ant.util.regexp.RegexpMatcher;
024: import org.apache.tools.ant.util.regexp.RegexpMatcherFactory;
025:
026: /**
027: * Implementation of FileNameMapper that does regular expression
028: * replacements.
029: *
030: */
031: public class RegexpPatternMapper implements FileNameMapper {
032: // CheckStyle:VisibilityModifier OFF - bc
033: protected RegexpMatcher reg = null;
034: protected char[] to = null;
035: protected StringBuffer result = new StringBuffer();
036:
037: // CheckStyle:VisibilityModifier ON
038:
039: /**
040: * Constructor for RegexpPatternMapper.
041: * @throws BuildException on error.
042: */
043: public RegexpPatternMapper() throws BuildException {
044: reg = (new RegexpMatcherFactory()).newRegexpMatcher();
045: }
046:
047: private boolean handleDirSep = false;
048: private int regexpOptions = 0;
049:
050: /**
051: * Attribute specifing whether to ignore the difference
052: * between / and \ (the two common directory characters).
053: * @param handleDirSep a boolean, default is false.
054: * @since Ant 1.6.3
055: */
056: public void setHandleDirSep(boolean handleDirSep) {
057: this .handleDirSep = handleDirSep;
058: }
059:
060: /**
061: * Attribute specifing whether to ignore the case difference
062: * in the names.
063: *
064: * @param caseSensitive a boolean, default is false.
065: * @since Ant 1.6.3
066: */
067: public void setCaseSensitive(boolean caseSensitive) {
068: if (!caseSensitive) {
069: regexpOptions = RegexpMatcher.MATCH_CASE_INSENSITIVE;
070: } else {
071: regexpOptions = 0;
072: }
073: }
074:
075: /**
076: * Sets the "from" pattern. Required.
077: * @param from the from pattern.
078: * @throws BuildException on error.
079: */
080: public void setFrom(String from) throws BuildException {
081: try {
082: reg.setPattern(from);
083: } catch (NoClassDefFoundError e) {
084: // depending on the implementation the actual RE won't
085: // get instantiated in the constructor.
086: throw new BuildException(
087: "Cannot load regular expression matcher", e);
088: }
089: }
090:
091: /**
092: * Sets the "to" pattern. Required.
093: * @param to the to pattern.
094: * @throws BuildException on error.
095: */
096: public void setTo(String to) {
097: this .to = to.toCharArray();
098: }
099:
100: /**
101: * Returns null if the source file name doesn't match the
102: * "from" pattern, an one-element array containing the
103: * translated file otherwise.
104: * @param sourceFileName the source file name
105: * @return a one-element array containing the translated file or
106: * null if the to pattern did not match
107: */
108: public String[] mapFileName(String sourceFileName) {
109: if (handleDirSep) {
110: if (sourceFileName.indexOf("\\") != -1) {
111: sourceFileName = sourceFileName.replace('\\', '/');
112: }
113: }
114: if (reg == null || to == null
115: || !reg.matches(sourceFileName, regexpOptions)) {
116: return null;
117: }
118: return new String[] { replaceReferences(sourceFileName) };
119: }
120:
121: /**
122: * Replace all backreferences in the to pattern with the matched
123: * groups of the source.
124: * @param source the source file name.
125: * @return the translated file name.
126: */
127: protected String replaceReferences(String source) {
128: Vector v = reg.getGroups(source, regexpOptions);
129:
130: result.setLength(0);
131: for (int i = 0; i < to.length; i++) {
132: if (to[i] == '\\') {
133: if (++i < to.length) {
134: int value = Character.digit(to[i], 10);
135: if (value > -1) {
136: result.append((String) v.elementAt(value));
137: } else {
138: result.append(to[i]);
139: }
140: } else {
141: // XXX - should throw an exception instead?
142: result.append('\\');
143: }
144: } else {
145: result.append(to[i]);
146: }
147: }
148: return result.substring(0);
149: }
150:
151: }
|