Changeset 5038
- Timestamp:
- 2003-07-25T16:36:39+12:00 (21 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/gli/src/org/greenstone/gatherer/shell/GShell.java
r4364 r5038 45 45 import org.greenstone.gatherer.shell.GShellListener; 46 46 import org.greenstone.gatherer.shell.GShellProgressMonitor; 47 import org.greenstone.gatherer.util.StaticStrings; 47 48 /** The <strong>GShell</strong> is reponsible for running a separately threaded process in the command shell. This is necessary for executing the Perl Scripts and also for other system related funcitonality. 48 49 */ … … 118 119 /** Any threaded class must include this method to allow the thread body to be run. 119 120 */ 121 private MessageDispatcher dispatcher; 120 122 public void run() { 123 // Create a new message dispatcher to merge then send off messages at a predetermined rate. 124 dispatcher = new MessageDispatcher(250); 125 dispatcher.start(); 121 126 // Setup 122 127 if(progress != null) { … … 125 130 // Determine if the user has asked for an outfile. 126 131 String out_name = null; 127 FileOutputStream fos = null;128 BufferedOutputStream bos = null;129 132 if(type == IMPORT || type == BUILD) { 130 133 if(type == IMPORT) { … … 139 142 if(out.exists()) { 140 143 boolean append = true; 141 fos = new FileOutputStream(out, append); 142 bos = new BufferedOutputStream(fos); 144 dispatcher.setBOS(new BufferedOutputStream(new FileOutputStream(out, append))); 143 145 } 144 146 } … … 151 153 fireProcessBegun(type, status); 152 154 try { 155 153 156 String command = ""; 154 157 for(int i = 0; i < args.length; i++) { 155 158 command = command + args[i] + " "; 156 159 } 157 ///ystem.err.println("Command: " + command); 158 fireMessage(type, get("Command") + ": " + command, status); 159 message(Message.EVENT, get("Command") + ": " + command); 160 ///ystem.err.println("Command: " + command); 161 dispatcher.standardMessage(type, get("Command") + ": " + command, status); 160 162 161 163 Runtime rt = Runtime.getRuntime(); … … 165 167 BufferedReader ebr = new BufferedReader( eisr ); 166 168 BufferedReader stdinbr = new BufferedReader( stdinisr ); 167 // Captures the std err of a program and pipes it into 168 // std in of java 169 // Captures the std err of a program and pipes it into std in of java 169 170 String eline = null; 170 171 String stdinline = null; … … 174 175 progress.parse(eline); 175 176 } 176 if(bos != null) { 177 bos.write(eline.getBytes(), 0, eline.length()); 178 } 179 ///ystem.err.println("stderr: " + eline); 180 fireMessage(type, typeAsString(type) + "> " + eline, 181 status); 182 message(Message.INFO, eline); 177 dispatcher.errorMessage(type, typeAsString(type) + "> " + eline, status); 183 178 } 184 179 if(stdinline != null) { 185 if(bos != null) { 186 //bos.write(stdinline.getBytes(), 0, stdinline.length()); 187 } 188 ///ystem.err.println("stdin: " + stdinline); 189 fireMessage(type, typeAsString(type) + "> " + stdinline, 190 status); 191 message(Message.INFO, stdinline); 180 dispatcher.standardMessage(type, typeAsString(type) + "> " + stdinline, status); 181 192 182 } 193 183 } … … 199 189 if(prcs.exitValue() == 0) { 200 190 status = OK; 201 fireMessage(type, typeAsString(type) + "> " + get("Success"), status);202 message(Message.MAIN, get("Success"));191 dispatcher.standardMessage(type, typeAsString(type) + "> " + get("Success"), status); 192 203 193 } else { 204 194 status = ERROR; 205 fireMessage(type, typeAsString(type) + "> " + get("Failure"), status);206 message(Message.ERROR, get("Failure"));195 dispatcher.standardMessage(type, typeAsString(type) + "> " + get("Failure"), status); 196 207 197 } 208 198 } … … 216 206 // Exception 217 207 catch (Exception error) { 218 message(Message.ERROR, get("Failure"));219 message(Message.ERROR, error.toString());220 208 Gatherer.printStackTrace(error); 221 209 status = ERROR; … … 223 211 // If no error occured, and this was an import process we now extract any new metadata from the archive directory. 224 212 if(status == OK && type == IMPORT) { 225 fireMessage(type, typeAsString(type) + "> " + get("Parsing_Metadata_Start"), status);213 dispatcher.standardMessage(type, typeAsString(type) + "> " + get("Parsing_Metadata_Start"), status); 226 214 new GreenstoneArchiveParser(progress, this); 227 fireMessage(type, typeAsString(type) + "> " + get("Parsing_Metadata_Complete"), status);215 dispatcher.standardMessage(type, typeAsString(type) + "> " + get("Parsing_Metadata_Complete"), status); 228 216 } 229 217 // Tidy up. … … 231 219 progress.stop(); 232 220 } 233 if(bos != null) {234 try {235 bos.close();236 }237 catch (Exception e) {238 }239 }240 221 // We're done. 241 222 fireProcessComplete(type, status); 223 dispatcher.processComplete(); 224 dispatcher = null; 242 225 } 243 226 /** Method for firing a message to all interested listeners. … … 255 238 } 256 239 } 240 241 public void message(int type, String message, int status) { 242 if(dispatcher != null) { 243 dispatcher.standardMessage(type, message, status); 244 } 245 } 246 257 247 /** Method for firing a process begun event which is called, strangly enough, when the process begins. 258 248 * @param type An <strong>int</strong> indicating the process type. … … 301 291 return has_signalled_stop; 302 292 } 303 /** Creates and dispatches a message given the initial details. 304 * @param level An <strong>int</strong> indicating the message level for this message. 305 * @param message A <strong>String</strong> which contains the payload of this message. 306 */ 307 private void message(int level, String message) { 308 Message msg = new Message(msg_type, level, message); 309 if(Gatherer.g_man != null) { 310 Gatherer.log.add(msg); 311 } 312 } 293 313 294 /** Converts a type into a text representation. 314 295 * @param type An <strong>int</strong> which maps to a shell process type. … … 332 313 return name; 333 314 } 315 316 /** Rather than bombard the progress logs with thousands of individual lines, which can actually slow build times by 200-1000%, we instead fire off quarter second updates with all of the strings retrieved in that time, if any. */ 317 private class MessageDispatcher 318 extends Thread { 319 private boolean process_complete; 320 private BufferedOutputStream bos; 321 private int last_status; 322 private int last_type; 323 private int wait_time; 324 private StringBuffer bos_buffer; 325 private StringBuffer buffer; 326 public MessageDispatcher(int wait_time) { 327 this.bos = bos; 328 this.bos_buffer = new StringBuffer(); 329 this.buffer = new StringBuffer(); 330 this.process_complete = false; 331 this.wait_time = wait_time; 332 } 333 334 public synchronized void errorMessage(int type, String message, int status) { 335 buffer.append(message); 336 buffer.append(StaticStrings.NEW_LINE_CHARACTER); 337 if(bos != null) { 338 bos_buffer.append(message); 339 bos_buffer.append(StaticStrings.NEW_LINE_CHARACTER); 340 } 341 last_status = status; 342 last_type = type; 343 } 344 345 public void processComplete() { 346 process_complete = true; 347 } 348 349 public void run() { 350 while(!process_complete) { 351 try { 352 wait(wait_time); 353 } 354 catch(Exception error) { 355 } 356 message(); 357 } 358 // If there is still something in buffer send it 359 message(); 360 // Close bos if it exists 361 if(bos != null) { 362 try { 363 bos.close(); 364 } 365 catch (Exception e) { 366 } 367 } 368 } 369 370 public void setBOS(BufferedOutputStream bos) { 371 this.bos = bos; 372 } 373 374 public synchronized void standardMessage(int type, String message, int status) { 375 buffer.append(message); 376 buffer.append(StaticStrings.NEW_LINE_CHARACTER); 377 last_status = status; 378 last_type = type; 379 } 380 381 private synchronized void message() { 382 if(bos != null && bos_buffer.length() > 0) { 383 try { 384 bos.write(bos_buffer.toString().getBytes(), 0, bos_buffer.length()); 385 } 386 catch(Exception error) { 387 Gatherer.printStackTrace(error); 388 } 389 bos_buffer.delete(0, bos_buffer.length()); 390 } 391 if(buffer.length() > 0) { 392 fireMessage(last_type, buffer.toString(), last_status); 393 buffer.delete(0, buffer.length()); 394 } 395 } 396 } 334 397 }
Note:
See TracChangeset
for help on using the changeset viewer.