001: /*
002:
003: This software is OSI Certified Open Source Software.
004: OSI Certified is a certification mark of the Open Source Initiative.
005:
006: The license (Mozilla version 1.0) can be read at the MMBase site.
007: See http://www.MMBase.org/license
008:
009: */
010: package org.mmbase.util.transformers;
011:
012: import java.io.*;
013:
014: import org.mmbase.util.logging.*;
015:
016: /**
017: * A Filtering Reader based on CharTransformers.
018: <pre>
019:
020: _________ ____
021: / \/ \
022: | R --> PW - this |
023: | T | PR |
024: \_________/ \____/
025:
026:
027: PW: piped writer, this PR: this reader, T: transformer
028:
029: </pre>
030: * This reader can be instantiated with another Reader and a CharTransformer. All reading from this
031: * reader will be transformed output from reading on the given Reader.
032: *
033: * @author Michiel Meeuwissen
034: * @since MMBase-1.8
035: * @see ChainedCharTransformer
036: * @see TransformingWriter
037: */
038:
039: public class TransformingReader extends PipedReader {
040:
041: private static final Logger log = Logging
042: .getLoggerInstance(TransformingReader.class);
043:
044: private final Reader in;
045: private final CharTransformerLink link;
046:
047: public TransformingReader(Reader in, CharTransformer charTransformer) {
048: super ();
049: this .in = in;
050: PipedWriter w = new PipedWriter();
051: try {
052: connect(w);
053: } catch (IOException ioe) {
054: log.error(ioe.getMessage(), ioe);
055: }
056: link = new CharTransformerLink(charTransformer, in, w, true);
057:
058: // this works:
059: //Thread t = new Thread(link);
060: //t.start();
061:
062: // this too, but main does not finish immediately. I suppose that is ok though:
063: // Costed me some time to realise this....
064: org.mmbase.util.ThreadPools.filterExecutor.execute(link);
065:
066: }
067:
068: public synchronized int read() throws IOException {
069: int result = super .read();
070: if (result == -1) { // nothing to read any more, wait until transformation is ready.
071: waitReady();
072: in.close();
073: }
074: return result;
075: }
076:
077: public synchronized int read(char cbuf[], int off, int len)
078: throws IOException {
079: int result = super .read(cbuf, off, len);
080: if (result == -1) {
081: waitReady();
082: // in.close();
083: }
084: return result;
085: }
086:
087: /**
088: * Wait until the transformation is ready
089: */
090: protected void waitReady() {
091: try {
092: while (!link.ready()) {
093: synchronized (link) { // make sure we have the lock
094: link.wait();
095: }
096: }
097: } catch (InterruptedException ie) {
098: log.warn("" + ie.getMessage(), ie);
099: }
100: }
101:
102: /**
103: * {@inheritDoc}
104: * ALso closes the wrapped Reader.
105: */
106: public void close() throws IOException {
107: super .close();
108: in.close();
109: }
110:
111: // main for testing purposes
112: public static void main(String[] args) {
113:
114: /*
115: String testString = "use argument to change this string";
116: if (args.length > 0) {
117: testString = args[0];
118: }
119:
120:
121: BufferedReader reader = new BufferedReader(new TransformingReader(new StringReader(testString), new UnicodeEscaper()));
122:
123: try {
124: while(true) {
125: String line = reader.readLine();
126: if (line == null) break;
127: System.out.println(line);
128: }
129: } catch (Exception e) {
130: log.error(e + Logging.stackTrace(e));
131: }
132:
133:
134: ChainedCharTransformer t = new ChainedCharTransformer();
135: t.add(new UnicodeEscaper());
136: t.add(new UpperCaser());
137: t.add(new SpaceReducer());
138: t.add(new Trimmer());
139: */
140: {
141: BufferedReader reader = new BufferedReader(
142: new TransformingReader(new InputStreamReader(
143: System.in), new UpperCaser()));
144:
145: try {
146: while (true) {
147: String line = reader.readLine();
148: if (line == null) {
149: break;
150: }
151: System.out.println(line);
152: }
153: } catch (Exception e) {
154: log.error(e.getMessage(), e);
155: }
156: }
157: org.mmbase.util.ThreadPools.filterExecutor.shutdown();
158: }
159:
160: }
|