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.FilterReader;
  19. import java.io.IOException;
  20. import java.io.Reader;
  21. import java.io.StringReader;
  22. import org.apache.tools.ant.Project;
  23. import org.apache.tools.ant.util.FileUtils;
  24. /**
  25. * Base class for core filter readers.
  26. *
  27. */
  28. public abstract class BaseFilterReader extends FilterReader {
  29. /** Buffer size used when reading */
  30. private static final int BUFFER_SIZE = 8192;
  31. /** Have the parameters passed been interpreted? */
  32. private boolean initialized = false;
  33. /** The Ant project this filter is part of. */
  34. private Project project = null;
  35. /**
  36. * Constructor used by Ant's introspection mechanism.
  37. * The original filter reader is only used for chaining
  38. * purposes, never for filtering purposes (and indeed
  39. * it would be useless for filtering purposes, as it has
  40. * no real data to filter). ChainedReaderHelper uses
  41. * this placeholder instance to create a chain of real filters.
  42. */
  43. public BaseFilterReader() {
  44. super(new StringReader(new String()));
  45. try {
  46. close();
  47. } catch (IOException ioe) {
  48. // Ignore
  49. }
  50. }
  51. /**
  52. * Creates a new filtered reader.
  53. *
  54. * @param in A Reader object providing the underlying stream.
  55. * Must not be <code>null</code>.
  56. *
  57. */
  58. public BaseFilterReader(final Reader in) {
  59. super(in);
  60. }
  61. /**
  62. * Reads characters into a portion of an array. This method will block
  63. * until some input is available, an I/O error occurs, or the end of the
  64. * stream is reached.
  65. *
  66. * @param cbuf Destination buffer to write characters to.
  67. * Must not be <code>null</code>.
  68. * @param off Offset at which to start storing characters.
  69. * @param len Maximum number of characters to read.
  70. *
  71. * @return the number of characters read, or -1 if the end of the
  72. * stream has been reached
  73. *
  74. * @exception IOException If an I/O error occurs
  75. */
  76. public final int read(final char[] cbuf, final int off,
  77. final int len) throws IOException {
  78. for (int i = 0; i < len; i++) {
  79. final int ch = read();
  80. if (ch == -1) {
  81. if (i == 0) {
  82. return -1;
  83. } else {
  84. return i;
  85. }
  86. }
  87. cbuf[off + i] = (char) ch;
  88. }
  89. return len;
  90. }
  91. /**
  92. * Skips characters. This method will block until some characters are
  93. * available, an I/O error occurs, or the end of the stream is reached.
  94. *
  95. * @param n The number of characters to skip
  96. *
  97. * @return the number of characters actually skipped
  98. *
  99. * @exception IllegalArgumentException If <code>n</code> is negative.
  100. * @exception IOException If an I/O error occurs
  101. */
  102. public final long skip(final long n)
  103. throws IOException, IllegalArgumentException {
  104. if (n < 0L) {
  105. throw new IllegalArgumentException("skip value is negative");
  106. }
  107. for (long i = 0; i < n; i++) {
  108. if (read() == -1) {
  109. return i;
  110. }
  111. }
  112. return n;
  113. }
  114. /**
  115. * Sets the initialized status.
  116. *
  117. * @param initialized Whether or not the filter is initialized.
  118. */
  119. protected final void setInitialized(final boolean initialized) {
  120. this.initialized = initialized;
  121. }
  122. /**
  123. * Returns the initialized status.
  124. *
  125. * @return whether or not the filter is initialized
  126. */
  127. protected final boolean getInitialized() {
  128. return initialized;
  129. }
  130. /**
  131. * Sets the project to work with.
  132. *
  133. * @param project The project this filter is part of.
  134. * Should not be <code>null</code>.
  135. */
  136. public final void setProject(final Project project) {
  137. this.project = project;
  138. }
  139. /**
  140. * Returns the project this filter is part of.
  141. *
  142. * @return the project this filter is part of
  143. */
  144. protected final Project getProject() {
  145. return project;
  146. }
  147. /**
  148. * Reads a line of text ending with '\n' (or until the end of the stream).
  149. * The returned String retains the '\n'.
  150. *
  151. * @return the line read, or <code>null</code> if the end of the stream
  152. * has already been reached
  153. *
  154. * @exception IOException if the underlying reader throws one during
  155. * reading
  156. */
  157. protected final String readLine() throws IOException {
  158. int ch = in.read();
  159. if (ch == -1) {
  160. return null;
  161. }
  162. StringBuffer line = new StringBuffer();
  163. while (ch != -1) {
  164. line.append ((char) ch);
  165. if (ch == '\n') {
  166. break;
  167. }
  168. ch = in.read();
  169. }
  170. return line.toString();
  171. }
  172. /**
  173. * Reads to the end of the stream, returning the contents as a String.
  174. *
  175. * @return the remaining contents of the reader, as a String
  176. *
  177. * @exception IOException if the underlying reader throws one during
  178. * reading
  179. */
  180. protected final String readFully() throws IOException {
  181. return FileUtils.readFully(in, BUFFER_SIZE);
  182. }
  183. }