1 19 package org.netbeans.modules.j2ee.jboss4.ide; 20 21 22 import java.io.BufferedReader ; 23 import java.io.File ; 24 import java.io.FileNotFoundException ; 25 import java.io.FileReader ; 26 import java.io.IOException ; 27 import java.io.InputStreamReader ; 28 import java.util.HashMap ; 29 import javax.enterprise.deploy.shared.ActionType ; 30 import javax.enterprise.deploy.shared.CommandType ; 31 import javax.enterprise.deploy.shared.StateType ; 32 import org.netbeans.modules.j2ee.deployment.profiler.api.ProfilerSupport; 33 import org.openide.ErrorManager; 34 import org.openide.util.NbBundle; 35 import org.openide.util.RequestProcessor; 36 import org.openide.util.RequestProcessor.Task; 37 import org.openide.windows.InputOutput; 38 import org.openide.windows.OutputWriter; 39 40 44 public final class JBLogWriter { 45 46 public static final boolean VERBOSE = 47 System.getProperty ("netbeans.serverplugins.jboss4.logging") != null; 48 49 private final static int DELAY = 500; 50 private static final int START_TIMEOUT = 900000; 51 52 55 private final Object READER_LOCK = new Object (); 56 57 61 private final Object START_LOCK = new Object (); 62 63 private static enum LOGGER_TYPE { PROCESS, FILE }; 65 66 private LOGGER_TYPE type; 68 69 private static final String THREAD_NAME = "JBoss Log Writer"; private static final String STOPPER_THREAD_NAME = "JBoss Log Writer Stopper"; 72 private JBStartServer.ACTION_STATUS actionStatus = JBStartServer.ACTION_STATUS.UNKNOWN; 73 74 JBStartServer startServer; 75 76 private final OutputWriter out; 78 volatile private BufferedReader reader; 80 private final String instanceName; 82 private Process process; 84 private File logFile; 86 87 Thread logWriterThread; 90 91 private static HashMap <String , JBLogWriter> instances = new HashMap <String , JBLogWriter>(); 93 94 private boolean read; 97 98 private String trailingLine = ""; 101 102 103 private JBLogWriter(InputOutput io, String instanceName) { 104 this.out = (io != null ? io.getOut() : null); 105 this.instanceName = instanceName; 106 } 107 108 synchronized public static JBLogWriter createInstance(InputOutput io, String instanceName) { 109 JBLogWriter instance = getInstance(instanceName); 110 if (instance == null) { 111 instance = new JBLogWriter(io, instanceName); 112 instances.put(instanceName, instance); 113 } 114 return instance; 115 } 116 117 synchronized public static JBLogWriter getInstance(String instanceName) { 118 return instances.get(instanceName); 119 } 120 121 124 public void start(File logFile) { 125 try { 126 this.logFile = logFile; 127 this.reader = new BufferedReader (new FileReader (logFile)); 128 } catch (FileNotFoundException ioe) { 129 ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, ioe); 130 } 131 132 startWriter(new LineProcessor() { 134 public void processLine(String line) { 136 if (out != null) { 137 if (line != null && line.indexOf(" INFO ") != -1) { 138 out.println(line); 139 } 140 } 141 } 142 }, LOGGER_TYPE.FILE); 143 } 144 145 154 JBStartServer.ACTION_STATUS start(Process process, final JBStartServer startServer) { 155 this.process = process; 156 this.startServer = startServer; 157 this.reader = new BufferedReader (new InputStreamReader (process.getInputStream())); 158 159 startWriter(new LineProcessor() { 161 162 private boolean checkStartProgress = true; 165 166 public void processLine(String line) { 167 if (line != null) { 169 if (out != null) { 170 out.println(line); 171 } 172 if (checkStartProgress) { 173 checkStartProgress(line); 174 } 175 } 176 } 177 178 182 private void checkStartProgress(String line) { 183 184 if (line.indexOf("Starting JBoss (MX MicroKernel)") > -1 || line.indexOf("Starting JBoss (Microcontainer)") > -1) { 187 if (VERBOSE) { 188 System.out.println("STARTING message fired"); } 190 fireStartProgressEvent(StateType.RUNNING, createProgressMessage("MSG_START_SERVER_IN_PROGRESS")); } 192 else 193 if ((line.indexOf("JBoss (MX MicroKernel)") > -1 || line.indexOf("JBoss (Microcontainer)") > -1) && line.indexOf("Started in") > -1) { 197 if (VERBOSE) { 198 System.out.println("STARTED message fired"); } 200 checkStartProgress = false; 201 actionStatus = JBStartServer.ACTION_STATUS.SUCCESS; 202 notifyStartupThread(); 203 } 204 else 205 if (line.indexOf("Shutdown complete") > -1) { checkStartProgress = false; 207 actionStatus = JBStartServer.ACTION_STATUS.FAILURE; 208 notifyStartupThread(); 209 } 210 } 211 212 }, LOGGER_TYPE.PROCESS); 213 214 try { 215 synchronized (START_LOCK) { 216 long start = System.currentTimeMillis(); 217 START_LOCK.wait(START_TIMEOUT); 219 if (System.currentTimeMillis() - start >= START_TIMEOUT) { 220 if (VERBOSE) { 221 System.out.println("Startup thread TIMEOUT EXPIRED"); 222 } 223 actionStatus = JBStartServer.ACTION_STATUS.UNKNOWN; 224 } 225 else { 226 if (VERBOSE) { 227 System.out.println("Startup thread NOTIFIED"); 228 } 229 } 230 } 231 } catch (InterruptedException ex) { 232 } 234 235 return actionStatus; 236 } 237 238 private void notifyStartupThread() { 239 synchronized (START_LOCK) { 240 START_LOCK.notify(); 241 } 242 } 243 244 private void fireStartProgressEvent(StateType stateType, String msg) { 245 startServer.fireHandleProgressEvent(null, new JBDeploymentStatus(ActionType.EXECUTE, CommandType.START, stateType, msg)); 246 } 247 248 private String createProgressMessage(final String resName) { 249 return NbBundle.getMessage(JBLogWriter.class, resName, instanceName); 250 } 251 252 255 private interface LineProcessor { 256 void processLine(String line); 257 } 258 259 275 private void startWriter(final LineProcessor lineProcessor, final LOGGER_TYPE type) { 276 277 if (isRunning()) { 278 logWriterThread.interrupt(); 280 if (VERBOSE) { 281 System.out.println("************INTERRUPT thread " + logWriterThread.getId()); 282 } 283 } 284 285 this.type = type; 286 287 logWriterThread = new Thread (THREAD_NAME) { 288 public void run() { 289 if (VERBOSE) { 290 System.out.println("************START thread " + Thread.currentThread().getId()); 291 } 292 read = true; 293 boolean interrupted = false; 294 long lastFileSize = -1; 295 boolean checkProfiler = (startServer != null && startServer.getMode() == JBStartServer.MODE.PROFILE); 296 while (read) { 297 if (checkProfiler) { 301 int state = ProfilerSupport.getState(); 302 if (state == ProfilerSupport.STATE_BLOCKING || 303 state == ProfilerSupport.STATE_RUNNING || 304 state == ProfilerSupport.STATE_PROFILING) { 305 fireStartProgressEvent(StateType.COMPLETED, createProgressMessage("MSG_PROFILED_SERVER_STARTED")); 306 checkProfiler = false; 307 notifyStartupThread(); 308 } 309 else 310 if (state == ProfilerSupport.STATE_INACTIVE) { 311 fireStartProgressEvent(StateType.FAILED, createProgressMessage("MSG_START_PROFILED_SERVER_FAILED")); 312 process.destroy(); 313 notifyStartupThread(); 314 break; 315 } 316 } 317 318 boolean ready = processInput(lineProcessor, type); 319 if (type == LOGGER_TYPE.FILE) { 320 if (ready) { lastFileSize = logFile.length(); 322 } 323 else if (lastFileSize != logFile.length()) { 325 if (VERBOSE) { 327 System.out.println("!!!!!!!!!DIFFERENCE found"); 328 } 329 refresh(); 330 } 331 } 332 else { 333 try { 334 process.exitValue(); 335 break; 337 } 338 catch (IllegalThreadStateException itse) { 339 } 341 } 342 try { 343 Thread.sleep(DELAY); } catch (InterruptedException e) { 345 interrupted = true; 346 break; 347 } 348 } 349 350 lineProcessor.processLine(trailingLine); 352 353 if (VERBOSE) { 354 System.out.println("************FINISH thread " + Thread.currentThread().getId()); 355 } 356 if (!interrupted) { 357 read = false; 361 instances.remove(instanceName); 362 } 363 } 364 }; 365 logWriterThread.start(); 366 367 } 368 369 372 void stop() { 373 read = false; 374 } 375 376 boolean isRunning(){ 377 return read; 378 } 379 380 384 public void refresh() { 385 if (type == LOGGER_TYPE.PROCESS || logFile == null) { 386 return; 387 } 388 389 synchronized (READER_LOCK) { 390 if (reader != null) { 391 try { 392 reader.close(); 393 } catch (IOException e) { 394 ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e); 395 } 396 } 397 try { 398 if (out != null) { 399 out.reset(); 400 } 401 if (VERBOSE) { 402 System.out.println("REFRESHING the output pane"); 403 } 404 reader = new BufferedReader (new FileReader (logFile)); 405 } catch (IOException e) { 406 ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e); 407 } 408 } 409 } 410 411 415 private boolean processInput(LineProcessor lineProcessor, final LOGGER_TYPE type) { 416 synchronized (READER_LOCK) { 417 boolean ready = false; 418 try { 419 if (type == LOGGER_TYPE.PROCESS) { 420 while (reader.ready()) { 421 ready = readLine(lineProcessor); 424 } 425 } 426 else { 427 while (reader.ready()) { 428 String line = reader.readLine(); 429 lineProcessor.processLine(line); 430 ready = true; 431 } 432 } 433 } catch (IOException e) { 434 ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e); 435 } 436 return ready; 437 } 438 } 439 440 466 private boolean readLine(LineProcessor lineProcessor) throws IOException { 467 char[] cbuf = new char[128]; 468 int size = -1; 469 if ((size = reader.read(cbuf)) != -1) { 470 String lines = (trailingLine != null ? trailingLine : ""); 472 lines += new String (cbuf, 0, size); 473 int tlLength = (trailingLine != null ? trailingLine.length() : 0); 474 int start = 0; 475 for (int i = 0; i < size; i++) { if (cbuf[i] == '\r' && (i+1 == size || cbuf[i+1] != '\n') || cbuf[i] == '\n') { 478 String line = lines.substring(start, tlLength + i); 479 start = tlLength + (i + 1); 481 lineProcessor.processLine(line); 482 } 483 else if (cbuf[i] == '\r' && (i+1 < size) && cbuf[i+1] == '\n') { 485 String line = lines.substring(start, tlLength + i); 486 i += 1; 488 start = tlLength + (i + 1); 490 lineProcessor.processLine(line); 491 } 492 } 493 if (start < lines.length()) { 494 trailingLine = lines.substring(start); 496 } 497 else { 498 trailingLine = null; 502 } 503 return true; 504 } 505 return false; 506 } 507 508 519 void waitForServerProcessFinished(long milliseconds) { 520 Task t = new RequestProcessor(STOPPER_THREAD_NAME, 1, true).post(new Runnable () { 521 public void run() { 522 try { 523 if (VERBOSE) { 524 System.out.println(STOPPER_THREAD_NAME + ": WAITING for the server process to stop"); 525 } 526 if (type == LOGGER_TYPE.PROCESS) { 527 process.waitFor(); 528 } 529 else { 530 Thread.sleep(2000); 531 } 532 } catch (InterruptedException ex) { 533 } 535 } 536 }); 537 try { 538 t.waitFinished(milliseconds); 539 } catch (InterruptedException ex) { 540 } 542 finally { 543 t.cancel(); 544 } 545 } 546 547 } 548 | Popular Tags |