1 /**
2 * AUTOHIT 2003
3 * Copyright Erich P Gatejen (c) 1989,1997,2003,2004
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or (at
8 * your option) any later version.
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 * Additional license information can be found in the documentation.
19 * @author Erich P Gatejen
20 */
21 package autohit.call.modules;
22
23 import java.io.BufferedWriter;
24 import java.io.OutputStream;
25 import java.io.OutputStreamWriter;
26
27 import autohit.call.CallException;
28 import autohit.common.AutohitErrorCodes;
29 import autohit.common.Constants;
30 import autohit.universe.UniverseException;
31
32 /**
33 * Text writer module. It will write strings and lines to a
34 * universe object or a buffer.<p>
35 *
36 * startbuffer(buffer) start a write to a buffer. Be sure to pass the buffer by reference, rather than value.<br>
37 * startuni(objname) start a write to a universe object<br>
38 * write(string) write a string<br>
39 * writeln(string) write a line terminated string<br>
40 * done() close the write read (do this for either type, please)<br>
41 *
42 * @author Erich P. Gatejen
43 * @version 1.0
44 * <i>Version History</i>
45 * <code>EPG - Initial - 7Jul03
46 */
47 public class TextWriterModule extends Module {
48
49 private final static String myNAME = "TextWriter";
50
51 /**
52 * Current destination, if universe object
53 */
54 private BufferedWriter out;
55
56 /**
57 * Current destination, if buffer
58 */
59 private StringBuffer buf;
60
61 /**
62 * Flag if this is a buffer, rather than a universe item
63 */
64 private boolean isBuffer;
65
66 /**
67 * Meaning it has started
68 */
69 private boolean isValid;
70
71 /**
72 * Line seperation sequence of host system
73 */
74 private String lineSep;
75
76 /**
77 * METHODS
78 */
79 private final static String method_STARTSTR = "startbuffer";
80 private final static String method_STARTSTR_1_BUFFERNAME = "buffer";
81 private final static String method_STARTUNI = "startuni";
82 private final static String method_STARTUNI_1_OBJNAME = "objname";
83 private final static String method_WRITE = "write";
84 private final static String method_WRITE_1_STRING = "string";
85 private final static String method_WRITELINE = "writeln";
86 private final static String method_WRITELINE_1_STRING = "string";
87 private final static String method_DONE = "done";
88
89 /**
90 * Constructor
91 */
92 public TextWriterModule() {
93
94 }
95
96 // IMPLEMENTORS
97
98 /**
99 * Execute a named method. You must implement this method.
100 * You can call any of the helpers for data and services.
101 * The returned object better be a string (for now).
102 * @param name name of the method
103 * @see autohit.common.NOPair
104 * @throws CallException
105 */
106 public Object execute_chain(String name) throws CallException {
107
108 Object response = Constants.EMPTY_LEFT;
109 String param1;
110
111 if (name.equals(method_STARTSTR)) {
112 Object paramb =
113 this.requiredType(
114 method_STARTSTR_1_BUFFERNAME,
115 StringBuffer.class, name);
116 this.startbuffer((StringBuffer) paramb);
117
118 } else if (name.equals(method_STARTUNI)) {
119 param1 = this.required(method_STARTUNI_1_OBJNAME, name);
120 this.startuni(param1);
121
122 } else if (name.equals(method_WRITE)) {
123 param1 = this.required(method_WRITE_1_STRING, name);
124 this.writestring(param1);
125
126 } else if (name.equals(method_WRITELINE)) {
127 param1 = this.required(method_WRITELINE_1_STRING, name);
128 this.writelnstring(param1);
129
130 } else if (name.equals(method_DONE)) {
131 this.done();
132
133 } else {
134 error("Not a provided method. method=" + name);
135 response = Constants.EMPTY_LEFT;
136 }
137 return response;
138 }
139
140 /**
141 * Allow the subclass a chance to initialize. At a minium, an
142 * implementor should create an empty method.
143 * @throws CallException
144 * @return the name
145 */
146 protected String instantiation_chain() throws CallException {
147
148 lineSep = System.getProperty("line.separator");
149 out = null;
150
151 // Make sure we aren't started
152 isValid = false;
153 isBuffer = false;
154 return myNAME;
155 }
156
157 /**
158 * Allow the subclass a chance to cleanup on free. At a minium, an
159 * implementor should create an empty method.
160 * @throws CallException
161 */
162 protected void free_chain() throws CallException {
163 // NOTHING AT THIS TIME
164 if (out != null) {
165 try {
166 out.close();
167 } catch (Exception e) {
168 // Ignore
169 }
170 }
171 }
172
173 // PRIVATE IMPLEMENTATIONS
174
175 /**
176 * Start buffer method. It will set the writer to a buffer in the core
177 * named the target. If it can't find the buffer (StringBuffer), it will throw a fault.
178 * If a session is already started, it will throw a fault.
179 * @param the buffer we are going to write to
180 * @throws CallException
181 */
182 private void startbuffer(StringBuffer target) throws CallException {
183
184 // Invalidate the stream first
185 isValid = false;
186 if (out != null) {
187 throw buildException(
188 "Tried to startstring a session over an existing session. You must call done() first to end the prior session.",
189 CallException.CODE_MODULE_FAULT);
190 }
191
192 // Validate it
193 buf = target;
194 isBuffer = true;
195 isValid = true;
196 }
197
198 /**
199 * Start method. It will set the write to stream from a universe object.
200 * If a session is already started, it will throw a fault.
201 * @param target the string we are going to read
202 * @throws CallException
203 */
204 private void startuni(String name) throws CallException {
205
206 // Invalidate the stream first
207 isValid = false;
208
209 if (out != null) {
210 throw buildException(
211 "Tried to startuni a session over an existing session. You must call done() first to end the prior session.",
212 CallException.CODE_MODULE_FAULT);
213 }
214
215 try {
216
217 OutputStream os = visUniverse.putStream(name);
218 out = new BufferedWriter(new OutputStreamWriter(os));
219
220 } catch (UniverseException ue) {
221 throw new CallException(
222 "Startuni failed with Universe exception. message="
223 + ue.getMessage(),
224 CallException.CODE_MODULE_FAULT,
225 ue);
226 } catch (Exception e) {
227 throw new CallException(
228 "Startuni failed to general exception. message="
229 + e.getMessage(),
230 CallException.CODE_MODULE_FAULT,
231 e);
232 }
233
234 // validate it
235 isBuffer = false;
236 isValid = true;
237 }
238
239 /**
240 * Closes the session.
241 * @throws CallException
242 */
243 private void done() throws CallException {
244
245 if (isValid) {
246 isValid = false;
247
248 if (out != null) {
249 try {
250 out.close();
251 } catch (Exception e) {
252 // ignore
253 }
254 }
255
256 } else {
257 error("Called done() when it wasn't started.");
258 }
259 }
260
261 /**
262 * write(string) Writes a string.
263 * @param item what to write.
264 * @return the next line or an empty string
265 */
266 private void writestring(String item) throws CallException {
267
268 if (isValid) {
269
270 if (isBuffer) {
271 buf.append(item);
272
273 } else {
274
275 // This is a write to a universe stream. Any IO exception
276 // is a serious problem. Invalidate the whole thing.
277 try {
278 out.write(item);
279 } catch (Exception e) {
280 // Serious problem
281 isValid = false;
282 try {
283 this.free_chain();
284 } catch (Exception ee) {
285 }
286 throw new CallException(
287 "module:"
288 + myNAME
289 + ":FAULT. Encountered an IO problem while writing to a Universe stream. The session is now invalid. exception="
290 + e.getMessage(),
291 AutohitErrorCodes.CODE_CALL_FAULT);
292 }
293 } // end if buffer
294
295 } else {
296 error("Called write(string) when it isn't started.");
297 }
298 }
299
300 /**
301 * writeln(string) Writes a string and adds a line terminator.
302 * @param item what to write.
303 * @return the next line or an empty string
304 */
305 private void writelnstring(String item) throws CallException {
306
307 if (isValid) {
308
309 if (isBuffer) {
310 buf.append(item);
311 buf.append(lineSep);
312
313 } else {
314
315 // This is a write to a universe stream. Any IO exception
316 // is a serious problem. Invalidate the whole thing.
317 try {
318 out.write(item);
319 out.newLine();
320 } catch (Exception e) {
321 // Serious problem
322 isValid = false;
323 try {
324 this.free_chain();
325 } catch (Exception ee) {
326 }
327 throw new CallException(
328 "module:"
329 + myNAME
330 + ":FAULT. Encountered an IO problem while writing to a Universe stream. The session is now invalid. exception="
331 + e.getMessage(),
332 AutohitErrorCodes.CODE_CALL_FAULT);
333 }
334 } // end if buffer
335
336 } else {
337 error("Called write(string) when it isn't started.");
338 }
339 }
340
341 }
|