1. /*
  2. * Copyright 2003-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.io.File;
  21. import java.io.BufferedReader;
  22. import java.io.FileReader;
  23. import org.apache.tools.ant.types.Parameter;
  24. /**
  25. * Concats a file before and/or after the file.
  26. *
  27. * <p>Example:<pre>
  28. * <copy todir="build">
  29. * <fileset dir="src" includes="*.java"/>
  30. * <filterchain>
  31. * <concatfilter prepend="apache-license-java.txt"/>
  32. * </filterchain>
  33. * </copy>
  34. * </pre>
  35. * Copies all java sources from <i>src</i> to <i>build</i> and adds the
  36. * content of <i>apache-license-java.txt</i> add the beginning of each
  37. * file.</p>
  38. *
  39. * @since 1.6
  40. * @version 2003-09-23
  41. */
  42. public final class ConcatFilter extends BaseParamFilterReader
  43. implements ChainableReader {
  44. /** File to add before the content. */
  45. private File prepend;
  46. /** File to add after the content. */
  47. private File append;
  48. /** Reader for prepend-file. */
  49. private Reader prependReader = null;
  50. /** Reader for append-file. */
  51. private Reader appendReader = null;
  52. /**
  53. * Constructor for "dummy" instances.
  54. *
  55. * @see BaseFilterReader#BaseFilterReader()
  56. */
  57. public ConcatFilter() {
  58. super();
  59. }
  60. /**
  61. * Creates a new filtered reader.
  62. *
  63. * @param in A Reader object providing the underlying stream.
  64. * Must not be <code>null</code>.
  65. */
  66. public ConcatFilter(final Reader in) {
  67. super(in);
  68. }
  69. /**
  70. * Returns the next character in the filtered stream. If the desired
  71. * number of lines have already been read, the resulting stream is
  72. * effectively at an end. Otherwise, the next character from the
  73. * underlying stream is read and returned.
  74. *
  75. * @return the next character in the resulting stream, or -1
  76. * if the end of the resulting stream has been reached
  77. *
  78. * @exception IOException if the underlying stream throws an IOException
  79. * during reading
  80. */
  81. public int read() throws IOException {
  82. // do the "singleton" initialization
  83. if (!getInitialized()) {
  84. initialize();
  85. setInitialized(true);
  86. }
  87. int ch = -1;
  88. // The readers return -1 if they end. So simply read the "prepend"
  89. // after that the "content" and at the end the "append" file.
  90. if (prependReader != null) {
  91. ch = prependReader.read();
  92. if (ch == -1) {
  93. // I am the only one so I have to close the reader
  94. prependReader.close();
  95. prependReader = null;
  96. }
  97. }
  98. if (ch == -1) {
  99. ch = super.read();
  100. }
  101. if (ch == -1) {
  102. // donīt call super.close() because that reader is used
  103. // on other places ...
  104. if (appendReader != null) {
  105. ch = appendReader.read();
  106. if (ch == -1) {
  107. // I am the only one so I have to close the reader
  108. appendReader.close();
  109. appendReader = null;
  110. }
  111. }
  112. }
  113. return ch;
  114. }
  115. /**
  116. * Sets <i>prepend</i> attribute.
  117. * @param prepend new value
  118. */
  119. public void setPrepend(final File prepend) {
  120. this.prepend = prepend;
  121. }
  122. /**
  123. * Returns <i>prepend</i> attribute.
  124. * @return prepend attribute
  125. */
  126. public File getPrepend() {
  127. return prepend;
  128. }
  129. /**
  130. * Sets <i>append</i> attribute.
  131. * @param append new value
  132. */
  133. public void setAppend(final File append) {
  134. this.append = append;
  135. }
  136. /**
  137. * Returns <i>append</i> attribute.
  138. * @return append attribute
  139. */
  140. public File getAppend() {
  141. return append;
  142. }
  143. /**
  144. * Creates a new ConcatReader using the passed in
  145. * Reader for instantiation.
  146. *
  147. * @param rdr A Reader object providing the underlying stream.
  148. * Must not be <code>null</code>.
  149. *
  150. * @return a new filter based on this configuration, but filtering
  151. * the specified reader
  152. */
  153. public Reader chain(final Reader rdr) {
  154. ConcatFilter newFilter = new ConcatFilter(rdr);
  155. newFilter.setPrepend(getPrepend());
  156. newFilter.setAppend(getAppend());
  157. // Usually the initialized is set to true. But here it must not.
  158. // Because the prepend and append readers have to be instantiated
  159. // on runtime
  160. //newFilter.setInitialized(true);
  161. return newFilter;
  162. }
  163. /**
  164. * Scans the parameters list for the "lines" parameter and uses
  165. * it to set the number of lines to be returned in the filtered stream.
  166. * also scan for skip parameter.
  167. */
  168. private void initialize() throws IOException {
  169. // get parameters
  170. Parameter[] params = getParameters();
  171. if (params != null) {
  172. for (int i = 0; i < params.length; i++) {
  173. if ("prepend".equals(params[i].getName())) {
  174. setPrepend(new File(params[i].getValue()));
  175. continue;
  176. }
  177. if ("append".equals(params[i].getName())) {
  178. setAppend(new File(params[i].getValue()));
  179. continue;
  180. }
  181. }
  182. }
  183. if (prepend != null) {
  184. if (!prepend.isAbsolute()) {
  185. prepend = new File(getProject().getBaseDir(), prepend.getPath());
  186. }
  187. prependReader = new BufferedReader(new FileReader(prepend));
  188. }
  189. if (append != null) {
  190. if (!append.isAbsolute()) {
  191. append = new File(getProject().getBaseDir(), append.getPath());
  192. }
  193. appendReader = new BufferedReader(new FileReader(append));
  194. }
  195. }
  196. }