ExpandingFilterWriter.java

biz/hammurapi/eval/ExpandingFilterWriter.java

Violations

Inspector Message Severity Location
Java Inspector 031 Switch statement case without 'break' 1 126:29
Java Inspector 031 Switch statement case without 'break' 1 221:17
Java Inspector 048 Copyrights information should be present in each file. 1
Java Inspector 070-B Cyclomatic complexity is too high: 47, maximum allowed is 20 1 82:5
Java Inspector 070-A Cyclomatic complexity is too high: 47, maximum allowed is 12 2 82:5
Java Inspector 073 [java.lang.StringBuffer] In Java 5 use StringBuilder instead of StringBuffer if access is single-threaded, e.g. StringBuffer is used as a local variable . 2 70:5
Java Inspector 089 Type is not documented 2 42:1
Java Inspector 089 Undocumented field 2 52:5
Java Inspector 089 Undocumented constructor 2 58:5
Java Inspector 089 Undocumented constructor 2 62:5
Java Inspector 089 Undocumented method 2 82:5
Java Inspector 089 Undocumented method 2 275:5
Java Inspector 089 Undocumented method 2 291:5
Java Inspector 089 Undocumented method 2 297:5
Java Inspector 089 Undocumented method 2 303:5
Java Inspector 089 Method is not properly documented 2 313:9
Java Inspector 089 Parameter reader is not documented 2 313:9
Java Inspector 089 Parameter context is not documented 2 313:9
Java Inspector 089 Method return value is not properly documented 2 313:9
Java Inspector 024 Avoid hardwired character literals 3 84:22
Java Inspector 024 Avoid hardwired character literals 3 105:22
Java Inspector 024 Avoid hardwired character literals 3 121:22
Java Inspector 024 Avoid hardwired character literals 3 132:47
Java Inspector 024 Avoid hardwired character literals 3 133:47
Java Inspector 024 Avoid hardwired character literals 3 134:47
Java Inspector 024 Avoid hardwired character literals 3 175:71
Java Inspector 024 Avoid hardwired character literals 3 197:22
Java Inspector 024 Avoid hardwired character literals 3 204:43
Java Inspector 024 Avoid hardwired character literals 3 212:47
Java Inspector 024 Avoid hardwired character literals 3 228:43
Java Inspector 024 Avoid hardwired character literals 3 277:23
Java Inspector 024 Avoid hardwired character literals 3 279:23
Java Inspector 024 Avoid hardwired character literals 3 280:23
Java Inspector 026 Avoid hardwired string literals. Allowed literals: [] 3 102:55
Java Inspector 026 Avoid hardwired string literals. Allowed literals: [] 3 118:55
Java Inspector 026 Avoid hardwired string literals. Allowed literals: [] 3 142:43
Java Inspector 026 Avoid hardwired string literals. Allowed literals: [] 3 144:43
Java Inspector 026 Avoid hardwired string literals. Allowed literals: [] 3 151:78
Java Inspector 026 Avoid hardwired string literals. Allowed literals: [] 3 156:51
Java Inspector 026 Avoid hardwired string literals. Allowed literals: [] 3 158:51
Java Inspector 026 Avoid hardwired string literals. Allowed literals: [] 3 165:67
Java Inspector 026 Avoid hardwired string literals. Allowed literals: [] 3 194:55
Java Inspector 026 Avoid hardwired string literals. Allowed literals: [] 3 218:55
Java Inspector 026 Avoid hardwired string literals. Allowed literals: [] 3 236:55
Java Inspector 026 Avoid hardwired string literals. Allowed literals: [] 3 261:55
Java Inspector 051 It is good practice to call in any case super() in a constructor. 3 58:5

Source code

1/*
2 * hgcommons 9
3 * Hammurapi Group Common Library
4 * Copyright (C) 2003 Hammurapi Group
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 *
20 * URL: http://www.hammurapi.biz/hammurapi-biz/ef/xmenu/hammurapi-group/products/products/hgcommons/index.html
21 * e-Mail: support@hammurapi.biz
22 */
23package biz.hammurapi.eval;
24
25import java.io.FilterWriter;
26import java.io.IOException;
27import java.io.Reader;
28import java.io.StringReader;
29import java.io.StringWriter;
30import java.io.Writer;
31import java.util.Collection;
32import java.util.HashSet;
33import java.util.Iterator;
34import java.util.Set;
35
36import biz.hammurapi.config.Context;
37
38/**
39 * @author Pavel Vlasov
40 * @version $Revision$
41 */
42public class ExpandingFilterWriter extends FilterWriter {
43 private Context context;
44 private boolean stop;
45
46 /**
47 * When pragma:stop token is encountered subsequent characters are not
48 * expanded until pragma:start token is encountered. pragma:start and pragma:stop are not output to
49 * filtered writer.
50 */
51 public static final String PRAGMA_STOP = "pragma:stop";
52 public static final String PRAGMA_START = "pragma:start";
53
54// private static final Logger logger = Logger.getLogger(ExpandingFilterWriter.class);
55
56 private Set keySet;
57
58 public ExpandingFilterWriter(Writer out, Context context) {
59 this(out, context, new HashSet());
60 }
61
62 protected ExpandingFilterWriter(Writer out, Context context, Set keySet) {
63 super(out);
64 this.context = context;
65 this.keySet=keySet;
66 }
67
68 private int lastChar;
69
70 private StringBuffer keyBuffer;
71
72 private static final int STATE_NORMAL = 0;
73
74 private static final int STATE_DOLLAR = 1;
75
76 private static final int STATE_EXPRESSION = 2;
77
78 private static final int STATE_QUOTE = 3;
79
80 private int state = STATE_NORMAL;
81
82 public void write(int c) throws IOException {
83 switch (c) {
84 case '$':
85 switch (state) {
86 case STATE_NORMAL:
87 state = STATE_DOLLAR;
88 break;
89 case STATE_DOLLAR:
90 state = STATE_NORMAL;
91 out.write(c);
92 if (stop) {
93 out.write(c);
94 }
95// out.write(b);
96 break;
97 case STATE_EXPRESSION:
98 case STATE_QUOTE:
99 toBuffer(c);
100 break;
101 default:
102 throw new IOException("Invalid lexer state: " + state);
103 }
104 break;
105 case '{':
106 switch (state) {
107 case STATE_EXPRESSION:
108 case STATE_QUOTE:
109 toBuffer(c);
110 break;
111 case STATE_NORMAL:
112 out.write(c);
113 break;
114 case STATE_DOLLAR:
115 state = STATE_EXPRESSION;
116 break;
117 default:
118 throw new IOException("Invalid lexer state: " + state);
119 }
120 break;
121 case '}':
122 switch (state) {
123 case STATE_NORMAL:
124 out.write(c);
125 break;
126 case STATE_DOLLAR:
127 state = STATE_NORMAL;
128 out.write(c);
129 case STATE_EXPRESSION:
130 state = STATE_NORMAL;
131 if (keyBuffer == null || keyBuffer.length()==0) {
132 out.write('$');
133 out.write('{');
134 out.write('}');
135 } else if (PRAGMA_START.equals(keyBuffer.toString())){
136 stop=false;
137 keyBuffer=null;
138 } else if (PRAGMA_STOP.equals(keyBuffer.toString())){
139 stop=true;
140 keyBuffer=null;
141 } else if (stop) {
142 out.write("${");
143 out.write(keyBuffer.toString());
144 out.write("}");
145 keyBuffer=null;
146 } else {
147 String key = keyBuffer.toString();
148 keyBuffer = null;
149
150 if (keySet.contains(key)) {
151 throw new CircularReferenceException("Circular reference: "+key);
152 }
153
154 Object o=context.get(key);
155 if (o==null) {
156 out.write("${");
157 out.write(key);
158 out.write("}");
159 } else {
160 if (o instanceof Collection) {
161 Iterator it = ((Collection) o).iterator();
162 while (it.hasNext()) {
163 Object object = it.next();
164 if (object == null) {
165 out.write("(null)");
166 } else {
167 try {
168 keySet.add(key);
169 out.write(toString(object, context, keySet));
170 } finally {
171 keySet.remove(key);
172 }
173
174 if (it.hasNext()) {
175 out.write(' ');
176 }
177 }
178 }
179 } else {
180 try {
181 keySet.add(key);
182 out.write(toString(o, context, keySet));
183 } finally {
184 keySet.remove(key);
185 }
186 }
187 }
188 }
189 break;
190 case STATE_QUOTE:
191 toBuffer(c);
192 break;
193 default:
194 throw new IOException("Invalid lexer state: " + state);
195 }
196 break;
197 case '"':
198 switch (state) {
199 case STATE_NORMAL:
200 out.write(c);
201 break;
202 case STATE_DOLLAR:
203 state=STATE_NORMAL;
204 out.write('$');
205 out.write(c);
206 break;
207 case STATE_EXPRESSION:
208 state=STATE_QUOTE;
209 toBuffer(c);
210 break;
211 case STATE_QUOTE:
212 if (lastChar!='\\') {
213 state=STATE_EXPRESSION;
214 }
215 toBuffer(c);
216 break;
217 default:
218 throw new IOException("Invalid lexer state: " + state);
219 }
220 break;
221 default:
222 switch (state) {
223 case STATE_NORMAL:
224 out.write(c);
225 break;
226 case STATE_DOLLAR:
227 state=STATE_NORMAL;
228 out.write('$');
229 out.write(c);
230 break;
231 case STATE_EXPRESSION:
232 case STATE_QUOTE:
233 toBuffer(c);
234 break;
235 default:
236 throw new IOException("Invalid lexer state: " + state);
237 }
238 }
239 lastChar = c;
240 }
241
242 /**
243 * @param object
244 * @return
245 */
246 private static String toString(Object object, Context context, Set keySet) {
247 try {
248 StringWriter sw=new StringWriter();
249 ExpandingFilterWriter efw=new ExpandingFilterWriter(sw, context, keySet);
250 char[] buf=new char[1024];
251 StringReader reader=new StringReader(object.toString());
252 int l;
253 while ((l=reader.read(buf))!=-1) {
254 efw.write(buf, 0, l);
255 }
256 efw.close();
257 sw.close();
258 reader.close();
259 return sw.toString();
260 } catch (IOException e) {
261 throw new EvaluationException("Shall never happen", e);
262 }
263 }
264
265 /**
266 * @param b
267 */
268 private void toBuffer(int b) {
269 if (keyBuffer == null) {
270 keyBuffer = new StringBuffer();
271 }
272 keyBuffer.append((char) b);
273 }
274
275 public void close() throws IOException {
276 if (state == STATE_DOLLAR) {
277 out.write('$');
278 } else if (state == STATE_EXPRESSION /*|| state == STATE_QUOTE */) {
279 out.write('$');
280 out.write('{');
281 }
282
283 if (keyBuffer != null) {
284 out.write(keyBuffer.toString());
285 keyBuffer = null;
286 }
287 out.close();
288 super.close();
289 }
290
291 public void write(char[] cbuf, int off, int len) throws IOException {
292 for (int i=0; i<len; i++) {
293 write(cbuf[i+off]);
294 }
295 }
296
297 public void write(String str, int off, int len) throws IOException {
298 for (int i=0; i<len; i++) {
299 write(str.charAt(i+off));
300 }
301 }
302
303 public static Reader expand(Reader reader, Context context) throws IOException {
304 return new StringReader(expandToString(reader, context));
305 }
306
307 /**
308 * @param reader
309 * @param context
310 * @return
311 * @throws IOException
312 */
313 public static String expandToString(Reader reader, Context context) throws IOException {
314 StringWriter sw=new StringWriter();
315 ExpandingFilterWriter efw=new ExpandingFilterWriter(sw, context);
316 char[] buf=new char[1024];
317 int l;
318 while ((l=reader.read(buf))!=-1) {
319 efw.write(buf, 0, l);
320 }
321 efw.close();
322 sw.close();
323 reader.close();
324 return sw.toString();
325 }
326}
327