Source code for /engineering/autohit-2003/src/autohit/call/modules/TextWriterModule.javaOriginal file TextWriterModule.java
   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 }