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.io.InputStream;
022: import java.io.BufferedInputStream;
023: import java.io.IOException;
024: import java.util.Iterator;
025:
026: import org.apache.tools.ant.Project;
027: import org.apache.tools.ant.ProjectComponent;
028: import org.apache.tools.ant.types.Resource;
029: import org.apache.tools.ant.types.ResourceCollection;
030:
031: /**
032: * Special <code>InputStream</code> that will
033: * concatenate the contents of Resources from a single ResourceCollection.
034: * @since Ant 1.7
035: */
036: public class ConcatResourceInputStream extends InputStream {
037:
038: private static final int EOF = -1;
039: private boolean eof = false;
040: private Iterator iter;
041: private InputStream currentStream;
042: private ProjectComponent managingPc;
043: private boolean ignoreErrors = false;
044:
045: /**
046: * Construct a new ConcatResourceInputStream
047: * for the specified ResourceCollection.
048: * @param rc the ResourceCollection to combine.
049: */
050: public ConcatResourceInputStream(ResourceCollection rc) {
051: iter = rc.iterator();
052: }
053:
054: /**
055: * Set whether this ConcatResourceInputStream ignores errors.
056: * @param b whether to ignore errors.
057: */
058: public void setIgnoreErrors(boolean b) {
059: ignoreErrors = b;
060: }
061:
062: /**
063: * Find out whether this ConcatResourceInputStream ignores errors.
064: * @return boolean ignore-errors flag.
065: */
066: public boolean isIgnoreErrors() {
067: return ignoreErrors;
068: }
069:
070: /**
071: * Close the stream.
072: * @throws IOException if there is an error.
073: */
074: public void close() throws IOException {
075: closeCurrent();
076: eof = true;
077: }
078:
079: /**
080: * Read a byte.
081: * @return the byte (0 - 255) or -1 if this is the end of the stream.
082: * @throws IOException if there is an error.
083: */
084: public int read() throws IOException {
085: if (eof) {
086: return EOF;
087: }
088: int result = readCurrent();
089: if (result == EOF) {
090: nextResource();
091: result = readCurrent();
092: }
093: return result;
094: }
095:
096: /**
097: * Set a managing <code>ProjectComponent</code> for
098: * this <code>ConcatResourceInputStream</code>.
099: * @param pc the managing <code>ProjectComponent</code>.
100: */
101: public void setManagingComponent(ProjectComponent pc) {
102: this .managingPc = pc;
103: }
104:
105: /**
106: * Log a message with the specified logging level.
107: * @param message the <code>String</code> message.
108: * @param loglevel the <code>int</code> logging level.
109: */
110: public void log(String message, int loglevel) {
111: if (managingPc != null) {
112: managingPc.log(message, loglevel);
113: } else {
114: (loglevel > Project.MSG_WARN ? System.out : System.err)
115: .println(message);
116: }
117: }
118:
119: private int readCurrent() throws IOException {
120: return eof || currentStream == null ? EOF : currentStream
121: .read();
122: }
123:
124: private void nextResource() throws IOException {
125: closeCurrent();
126: while (iter.hasNext()) {
127: Resource r = (Resource) iter.next();
128: if (!r.isExists()) {
129: continue;
130: }
131: log("Concating " + r.toLongString(), Project.MSG_VERBOSE);
132: try {
133: currentStream = new BufferedInputStream(r
134: .getInputStream());
135: return;
136: } catch (IOException eyeOhEx) {
137: if (!ignoreErrors) {
138: log("Failed to get input stream for " + r,
139: Project.MSG_ERR);
140: throw eyeOhEx;
141: }
142: }
143: }
144: eof = true;
145: }
146:
147: private void closeCurrent() {
148: FileUtils.close(currentStream);
149: currentStream = null;
150: }
151: }
|