KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > mmbase > util > transformers > ChainedCharTransformer


1 /*
2
3 This software is OSI Certified Open Source Software.
4 OSI Certified is a certification mark of the Open Source Initiative.
5
6 The license (Mozilla version 1.0) can be read at the MMBase site.
7 See http://www.MMBase.org/license
8
9 */

10 package org.mmbase.util.transformers;
11
12 import java.io.*;
13 import java.util.*;
14 import org.mmbase.util.ThreadPools;
15
16 import org.mmbase.util.logging.*;
17
18 /**
19  * A CharTransformer which wraps N other CharTransformers, and links them with N - 1 new Threads,
20  * effectively working as a 'chained' transformer.
21  *
22  * The first transformation is done by the ChainedCharTransformer instance itself, after starting
23  * the N - 1 Threads for the other N - 1 transformations.
24  *
25  * If no CharTransformers are added, and 'transform' is called, logically, nothing will happen. Add
26  * the CopyCharTransformer if necessary.
27  *
28  * Schematicly:
29  *
30  <pre>
31
32   new ChainedCharTransformer().add(T1).add(T2)....add(TN).transform(R, W);
33
34   ___________ __________ _________
35  / \/ \ / \
36  | R --> PW - PR --> PW -...- PR --> W |
37  | T1 | T2 | | TN |
38  \___________/ \_________/ \_________/
39   
40
41  R: reader, PR: piped reader, W: writer, PW, piped writer, T1 - TN: transformers
42
43   </pre>
44  *
45  * @author Michiel Meeuwissen
46  * @since MMBase-1.7
47  * @version $Id: ChainedCharTransformer.java,v 1.24 2005/05/24 21:42:54 michiel Exp $
48  */

49
50 public class ChainedCharTransformer extends ReaderTransformer implements CharTransformer {
51     private static Logger log = Logging.getLoggerInstance(ChainedCharTransformer.class);
52    
53     private List charTransformers = new ArrayList();
54
55     public ChainedCharTransformer() {
56         super();
57     }
58
59     /**
60      * Adds a CharTranformer to the chain of CharTransformers. If the
61      * CharTransformer is a ChainedCharTransformer, then it will not
62      * be added itself, but its elements will be added.
63      */

64     public ChainedCharTransformer add(CharTransformer ct) {
65         if (ct instanceof ChainedCharTransformer) {
66             addAll(((ChainedCharTransformer)ct).charTransformers);
67         } else {
68             charTransformers.add(ct);
69         }
70         return this;
71     }
72
73     /**
74      * Adds a Collection of CharTranformers to the chain of CharTransformers.
75      *
76      * @throws ClassCastException if collecion does not contain only CharTransformers
77      */

78     public ChainedCharTransformer addAll(Collection col) {
79         Iterator i = col.iterator();
80         while (i.hasNext()) {
81             CharTransformer c = (CharTransformer) i.next();
82             add(c);
83         }
84         return this;
85     }
86
87     /**
88      * Implementation without Threads. Not needed when transforming by String.
89      */

90     public String JavaDoc transform(String JavaDoc string) {
91         ListIterator i = charTransformers.listIterator();
92         while (i.hasNext()) {
93             CharTransformer ct = (CharTransformer) i.next();
94             string = ct.transform(string);
95         }
96         return string;
97         
98     }
99
100     // javadoc inherited
101
public Writer transform(Reader startReader, Writer endWriter) {
102         try {
103             PipedReader r = null;
104             Writer w = endWriter;
105             boolean closeWriterAfterUse = false; // This boolean indicates if 'w' must be flushed/closed after use.
106

107             List links = new ArrayList(); // keep track of the started threads, needing to wait
108
// for them later.
109

110             // going to loop backward through the list of CharTransformers, and starting threads for
111
// every transformation, besides the last one (which is the first in the chain). This
112
// transformation is performed, and the then started other Threads catch the result.
113

114             ListIterator i = charTransformers.listIterator(charTransformers.size());
115             while (i.hasPrevious()) {
116                 CharTransformer ct = (CharTransformer) i.previous();
117                 if (i.hasPrevious()) { // needing a new Thread!
118
r = new PipedReader();
119                     CharTransformerLink link = new CharTransformerLink(ct, r, w, closeWriterAfterUse);
120                     links.add(link);
121                     w = new PipedWriter(r);
122                     closeWriterAfterUse = true;
123                     ThreadPools.filterExecutor.execute(link);
124                 } else { // arrived at first in chain, start transforming
125
ct.transform(startReader, w);
126                     if (closeWriterAfterUse) {
127                         w.close();
128                     }
129                 }
130             }
131             // wait until all threads are ready, because only then this transformation is actually ready
132
Iterator ti = links.iterator();
133             while (ti.hasNext()) {
134                 CharTransformerLink l = (CharTransformerLink) ti.next();
135                 try {
136                     while (!l.ready()) {
137                         synchronized(l) { // make sure we have the lock.
138
l.wait();
139                         }
140                     }
141                 } catch (InterruptedException JavaDoc ie) {
142                     log.warn("" + ie);
143                 }
144             }
145         } catch (IOException e) {
146             log.error(e.toString());
147             log.info(Logging.stackTrace(e));
148         }
149         return endWriter;
150     }
151
152     public String JavaDoc toString() {
153         return "CHAINED" + charTransformers;
154     }
155
156
157
158     // main for testing purposes
159
public static void main(String JavaDoc[] args) throws IOException {
160         ChainedCharTransformer t = new ChainedCharTransformer().add(new UnicodeEscaper()).add(new SpaceReducer()).add(new UpperCaser()).add(new Trimmer());
161         System.out.println("Starting transform");
162         
163         t.transform(new InputStreamReader(System.in), new OutputStreamWriter(System.out)).flush();
164         //System.out.println(t.transform(new StringReader("hello world")));
165

166         System.out.println(t.transform("test test test test "));
167
168         System.out.println("Finished transform");
169  
170     }
171     
172 }
173
Popular Tags