1. /*
  2. * Copyright 2002-2004 The Apache Software Foundation
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. *
  16. */
  17. package org.apache.tools.ant.filters;
  18. import java.io.IOException;
  19. import java.io.Reader;
  20. import java.util.Vector;
  21. import org.apache.tools.ant.types.Parameter;
  22. import org.apache.tools.ant.types.RegularExpression;
  23. import org.apache.tools.ant.util.regexp.Regexp;
  24. /**
  25. * Filter which includes only those lines that contain the user-specified
  26. * regular expression matching strings.
  27. *
  28. * Example:
  29. * <pre><linecontainsregexp>
  30. * <regexp pattern="foo*">
  31. * </linecontainsregexp></pre>
  32. *
  33. * Or:
  34. *
  35. * <pre><filterreader classname="org.apache.tools.ant.filters.LineContainsRegExp">
  36. * <param type="regexp" value="foo*"/>
  37. * </filterreader></pre>
  38. *
  39. * This will fetch all those lines that contain the pattern <code>foo</code>
  40. *
  41. */
  42. public final class LineContainsRegExp
  43. extends BaseParamFilterReader
  44. implements ChainableReader {
  45. /** Parameter name for the regular expression to filter on. */
  46. private static final String REGEXP_KEY = "regexp";
  47. /** Vector that holds the expressions that input lines must contain. */
  48. private Vector regexps = new Vector();
  49. /**
  50. * Remaining line to be read from this filter, or <code>null</code> if
  51. * the next call to <code>read()</code> should read the original stream
  52. * to find the next matching line.
  53. */
  54. private String line = null;
  55. /**
  56. * Constructor for "dummy" instances.
  57. *
  58. * @see BaseFilterReader#BaseFilterReader()
  59. */
  60. public LineContainsRegExp() {
  61. super();
  62. }
  63. /**
  64. * Creates a new filtered reader.
  65. *
  66. * @param in A Reader object providing the underlying stream.
  67. * Must not be <code>null</code>.
  68. */
  69. public LineContainsRegExp(final Reader in) {
  70. super(in);
  71. }
  72. /**
  73. * Returns the next character in the filtered stream, only including
  74. * lines from the original stream which match all of the specified
  75. * regular expressions.
  76. *
  77. * @return the next character in the resulting stream, or -1
  78. * if the end of the resulting stream has been reached
  79. *
  80. * @exception IOException if the underlying stream throws an IOException
  81. * during reading
  82. */
  83. public final int read() throws IOException {
  84. if (!getInitialized()) {
  85. initialize();
  86. setInitialized(true);
  87. }
  88. int ch = -1;
  89. if (line != null) {
  90. ch = line.charAt(0);
  91. if (line.length() == 1) {
  92. line = null;
  93. } else {
  94. line = line.substring(1);
  95. }
  96. } else {
  97. line = readLine();
  98. final int regexpsSize = regexps.size();
  99. while (line != null) {
  100. for (int i = 0; i < regexpsSize; i++) {
  101. RegularExpression regexp = (RegularExpression)
  102. regexps.elementAt(i);
  103. Regexp re = regexp.getRegexp(getProject());
  104. boolean matches = re.matches(line);
  105. if (!matches) {
  106. line = null;
  107. break;
  108. }
  109. }
  110. if (line == null) {
  111. // line didn't match
  112. line = readLine();
  113. } else {
  114. break;
  115. }
  116. }
  117. if (line != null) {
  118. return read();
  119. }
  120. }
  121. return ch;
  122. }
  123. /**
  124. * Adds a <code>regexp</code> element.
  125. *
  126. * @param regExp The <code>regexp</code> element to add.
  127. * Must not be <code>null</code>.
  128. */
  129. public final void addConfiguredRegexp(final RegularExpression regExp) {
  130. this.regexps.addElement(regExp);
  131. }
  132. /**
  133. * Sets the vector of regular expressions which must be contained within
  134. * a line read from the original stream in order for it to match this
  135. * filter.
  136. *
  137. * @param regexps A vector of regular expressions which must be contained
  138. * within a line in order for it to match in this filter. Must not be
  139. * <code>null</code>.
  140. */
  141. private void setRegexps(final Vector regexps) {
  142. this.regexps = regexps;
  143. }
  144. /**
  145. * Returns the vector of regular expressions which must be contained within
  146. * a line read from the original stream in order for it to match this
  147. * filter.
  148. *
  149. * @return the vector of regular expressions which must be contained within
  150. * a line read from the original stream in order for it to match this
  151. * filter. The returned object is "live" - in other words, changes made to
  152. * the returned object are mirrored in the filter.
  153. */
  154. private final Vector getRegexps() {
  155. return regexps;
  156. }
  157. /**
  158. * Creates a new LineContainsRegExp using the passed in
  159. * Reader for instantiation.
  160. *
  161. * @param rdr A Reader object providing the underlying stream.
  162. * Must not be <code>null</code>.
  163. *
  164. * @return a new filter based on this configuration, but filtering
  165. * the specified reader
  166. */
  167. public final Reader chain(final Reader rdr) {
  168. LineContainsRegExp newFilter = new LineContainsRegExp(rdr);
  169. newFilter.setRegexps(getRegexps());
  170. newFilter.setInitialized(true);
  171. return newFilter;
  172. }
  173. /**
  174. * Parses parameters to add user defined regular expressions.
  175. */
  176. private final void initialize() {
  177. Parameter[] params = getParameters();
  178. if (params != null) {
  179. for (int i = 0; i < params.length; i++) {
  180. if (REGEXP_KEY.equals(params[i].getType())) {
  181. String pattern = params[i].getValue();
  182. RegularExpression regexp = new RegularExpression();
  183. regexp.setPattern(pattern);
  184. regexps.addElement(regexp);
  185. }
  186. }
  187. }
  188. }
  189. }