1 19 20 package org.netbeans.modules.tomcat5; 21 22 import java.net.HttpURLConnection ; 23 import java.net.URL ; 24 import java.net.URLConnection ; 25 import java.net.URLEncoder ; 26 import java.util.StringTokenizer ; 27 import javax.enterprise.deploy.shared.ActionType ; 28 import javax.enterprise.deploy.shared.CommandType ; 29 import javax.enterprise.deploy.shared.StateType ; 30 import javax.enterprise.deploy.spi.Target ; 31 import javax.enterprise.deploy.spi.TargetModuleID ; 32 import javax.enterprise.deploy.spi.exceptions.OperationUnsupportedException ; 33 import javax.enterprise.deploy.spi.status.ClientConfiguration ; 34 import javax.enterprise.deploy.spi.status.DeploymentStatus ; 35 import javax.enterprise.deploy.spi.status.ProgressListener ; 36 import javax.enterprise.deploy.spi.status.ProgressObject ; 37 import org.netbeans.modules.tomcat5.config.gen.Context; 38 import org.netbeans.modules.tomcat5.config.gen.Engine; 39 import org.netbeans.modules.tomcat5.config.gen.Host; 40 import org.netbeans.modules.tomcat5.config.gen.SContext; 41 import org.netbeans.modules.tomcat5.config.gen.Server; 42 import org.netbeans.modules.tomcat5.config.gen.Service; 43 import org.netbeans.modules.tomcat5.progress.ProgressEventSupport; 44 import org.netbeans.modules.tomcat5.progress.Status; 45 import org.openide.ErrorManager; 46 import org.openide.util.RequestProcessor; 47 import org.openide.util.NbBundle; 48 import java.io.*; 49 import org.netbeans.modules.tomcat5.util.TomcatProperties; 50 51 55 public class TomcatManagerImpl implements ProgressObject , Runnable { 56 57 58 private static RequestProcessor rp; 59 60 61 private static synchronized RequestProcessor rp () { 62 if (rp == null) { 63 rp = new RequestProcessor ("Tomcat management", 1); } 65 return rp; 66 } 67 68 69 private ProgressEventSupport pes; 70 71 72 private String command; 73 74 75 private String output; 76 77 78 private CommandType cmdType; 79 80 81 private InputStream istream; 82 83 private TomcatManager tm; 84 85 86 private boolean authorized; 87 88 89 private TomcatModule tmId; 90 91 public TomcatManagerImpl (TomcatManager tm) { 92 this.tm = tm; 93 pes = new ProgressEventSupport (this); 94 } 95 96 public void deploy (Target t, InputStream is, InputStream deplPlan) { 97 Context ctx; 98 try { 99 ctx = Context.createGraph(deplPlan); 100 } catch (RuntimeException e) { 101 String msg = NbBundle.getMessage(TomcatManagerImpl.class, "MSG_DeployBrokenContextXml"); 102 pes.fireHandleProgressEvent(null, new Status (ActionType.EXECUTE, cmdType, msg, StateType.FAILED)); 103 return; 104 } 105 String ctxPath = ctx.getAttributeValue ("path"); tmId = new TomcatModule (t, ctxPath); 107 command = "deploy?path=" + encodePath(tmId.getPath()); cmdType = CommandType.DISTRIBUTE; 109 String msg = NbBundle.getMessage(TomcatManagerImpl.class, "MSG_DeploymentInProgress"); 110 pes.fireHandleProgressEvent (null, new Status (ActionType.EXECUTE, cmdType, msg, StateType.RUNNING)); 111 istream = is; 112 rp ().post (this, 0, Thread.NORM_PRIORITY); 113 } 114 115 118 public void install (Target t, File wmfile, File deplPlan) { 119 String docBase = wmfile.toURI ().toASCIIString (); 121 if (docBase.endsWith ("/")) { docBase = docBase.substring (0, docBase.length ()-1); 123 } 124 if (wmfile.isFile ()) { 125 docBase = "jar:"+docBase+"!/"; } 128 String ctxPath = null; 130 try { 131 if (!deplPlan.exists ()) { 132 if (wmfile.isDirectory ()) { 133 ctxPath = "/"+wmfile.getName (); } 135 else { 136 ctxPath = "/"+wmfile.getName ().substring (0, wmfile.getName ().lastIndexOf ('.')); } 138 tmId = new TomcatModule (t, ctxPath); command = "deploy?update=true&path="+encodePath(ctxPath)+"&war="+docBase; } 141 else { 142 FileInputStream in = new FileInputStream (deplPlan); 143 Context ctx; 144 try { 145 ctx = Context.createGraph(in); 146 } catch (RuntimeException e) { 147 String msg = NbBundle.getMessage(TomcatManagerImpl.class, "MSG_DeployBrokenContextXml"); 148 pes.fireHandleProgressEvent(null, new Status (ActionType.EXECUTE, cmdType, msg, StateType.FAILED)); 149 return; 150 } 151 if (wmfile.isDirectory ()) { 156 ctxPath = "/"+wmfile.getName (); } 158 else { 159 ctxPath = "/"+wmfile.getName ().substring (0, wmfile.getName ().lastIndexOf ('.')); } 161 ctxPath = ctx.getAttributeValue ("path"); 162 tmId = new TomcatModule (t, ctxPath); command = "deploy?update=true&path="+encodePath(tmId.getPath())+"&war="+docBase; } 165 166 cmdType = CommandType.DISTRIBUTE; 168 String msg = NbBundle.getMessage(TomcatManagerImpl.class, "MSG_DeploymentInProgress"); 169 pes.fireHandleProgressEvent (null, new Status (ActionType.EXECUTE, cmdType, msg, StateType.RUNNING)); 170 171 rp ().post (this, 0, Thread.NORM_PRIORITY); 172 } 173 catch (java.io.FileNotFoundException fnfe) { 174 pes.fireHandleProgressEvent (null, new Status (ActionType.EXECUTE, cmdType, fnfe.getLocalizedMessage (), StateType.FAILED)); 175 } 176 177 } 178 179 public void initialDeploy (Target t, File contextXml, File dir) { 180 try { 181 FileInputStream in = new FileInputStream (contextXml); 182 Context ctx = Context.createGraph (in); 183 String docBaseURI = dir.getAbsoluteFile().toURI().toASCIIString(); 184 String docBase = dir.getAbsolutePath (); 185 String ctxPath = ctx.getAttributeValue ("path"); 186 this.tmId = new TomcatModule (t, ctxPath, docBase); File tmpContextXml = createTempContextXml(docBase, ctx); 188 if (tm.isTomcat50()) { 189 command = "deploy?config=" + tmpContextXml.toURI ().toASCIIString () + "&war=" + docBaseURI; } else { 191 command = "deploy?config=" + tmpContextXml.toURI ().toASCIIString () + "&path=" + encodePath(tmId.getPath()); } 193 cmdType = CommandType.DISTRIBUTE; 194 String msg = NbBundle.getMessage(TomcatManagerImpl.class, "MSG_DeploymentInProgress"); 195 pes.fireHandleProgressEvent (null, new Status (ActionType.EXECUTE, cmdType, msg, StateType.RUNNING)); 196 rp ().post (this, 0, Thread.NORM_PRIORITY); 197 } catch (java.io.IOException ioex) { 198 pes.fireHandleProgressEvent (null, new Status (ActionType.EXECUTE, cmdType, ioex.getLocalizedMessage (), StateType.FAILED)); 199 } catch (RuntimeException e) { 200 String msg = NbBundle.getMessage(TomcatManagerImpl.class, "MSG_DeployBrokenContextXml"); 201 pes.fireHandleProgressEvent(null, new Status (ActionType.EXECUTE, cmdType, msg, StateType.FAILED)); 202 } 203 } 204 205 public void remove(TomcatModule tmId) { 206 Server server = tm.getRoot(); 208 if (server != null && removeContextFromServer(server, tmId.getPath())) { 209 File f = null; 210 try { 211 f = tm.getTomcatProperties().getServerXml(); 212 server.write(f); 213 } catch (Exception e) { 214 pes.fireHandleProgressEvent(tmId, new Status (ActionType.EXECUTE, 216 CommandType.UNDEPLOY, 217 NbBundle.getMessage(TomcatManagerImpl.class, "MSG_ServerXml_RO", f.getAbsolutePath()), 218 StateType.FAILED)); 219 return; 220 } 221 } 222 this.tmId = tmId; 223 command = "undeploy?path="+encodePath(tmId.getPath()); cmdType = CommandType.UNDEPLOY; 225 String msg = NbBundle.getMessage(TomcatManagerImpl.class, "MSG_UndeploymentInProgress"); 226 pes.fireHandleProgressEvent (null, new Status (ActionType.EXECUTE, cmdType, msg, StateType.RUNNING)); 227 rp ().post (this, 0, Thread.NORM_PRIORITY); 228 } 229 230 235 private boolean removeContextFromServer(Server server, String path) { 236 if (path.equals("/")) path = ""; Service[] service = server.getService(); 239 if (service.length > 0) { 240 Engine engine = service[0].getEngine(); 241 if (engine != null) { 242 Host[] host = engine.getHost(); 243 if (host.length > 0) { 244 SContext[] sContext = host[0].getSContext(); 245 for (int i = 0; i < sContext.length; i++) { 246 if (sContext[i].getAttributeValue("path").equals(path)) { host[0].removeSContext(sContext[i]); 248 return true; 249 } 250 } 251 } 252 } 253 } 254 return false; 255 } 256 257 258 public void start (TomcatModule tmId) { 259 this.tmId = tmId; 260 command = "start?path="+encodePath(tmId.getPath()); cmdType = CommandType.START; 262 String msg = NbBundle.getMessage(TomcatManagerImpl.class, "MSG_StartInProgress"); 263 pes.fireHandleProgressEvent (null, new Status (ActionType.EXECUTE, cmdType, msg, StateType.RUNNING)); 264 rp ().post (this, 0, Thread.NORM_PRIORITY); 265 } 266 267 268 public void stop (TomcatModule tmId) { 269 this.tmId = tmId; 270 command = "stop?path="+encodePath(tmId.getPath()); cmdType = CommandType.STOP; 272 String msg = NbBundle.getMessage(TomcatManagerImpl.class, "MSG_StopInProgress"); 273 pes.fireHandleProgressEvent (null, new Status (ActionType.EXECUTE, cmdType, msg, StateType.RUNNING)); 274 rp ().post (this, 0, Thread.NORM_PRIORITY); 275 } 276 277 278 public void reload (TomcatModule tmId) { 279 this.tmId = tmId; 280 command = "reload?path="+encodePath(tmId.getPath()); cmdType = CommandType.REDEPLOY; 282 String msg = NbBundle.getMessage(TomcatManagerImpl.class, "MSG_ReloadInProgress"); 283 pes.fireHandleProgressEvent (null, new Status (ActionType.EXECUTE, cmdType, msg, StateType.RUNNING)); 284 rp ().post (this, 0, Thread.NORM_PRIORITY); 285 } 286 287 public void incrementalRedeploy (TomcatModule tmId) { 288 try { 289 this.tmId = tmId; 290 String docBase = tmId.getDocRoot (); 291 assert docBase != null; 292 String docBaseURI = new File (docBase).toURI().toASCIIString(); 293 File contextXml = new File (docBase + "/META-INF/context.xml"); FileInputStream in = new FileInputStream (contextXml); 295 Context ctx = Context.createGraph (in); 296 File tmpContextXml = createTempContextXml(docBase, ctx); 297 if (tm.isTomcat50()) { 298 command = "deploy?config=" + tmpContextXml.toURI ().toASCIIString () + "&war=" + docBaseURI; } else { 300 command = "deploy?config=" + tmpContextXml.toURI ().toASCIIString () + "&path=" + encodePath(tmId.getPath()); } 302 cmdType = CommandType.DISTRIBUTE; 303 String msg = NbBundle.getMessage(TomcatManagerImpl.class, "MSG_DeployInProgress"); 304 pes.fireHandleProgressEvent (null, new Status (ActionType.EXECUTE, cmdType, msg, StateType.RUNNING)); 305 rp ().post (this, 0, Thread.NORM_PRIORITY); 306 } catch (java.io.IOException ioex) { 307 pes.fireHandleProgressEvent (null, new Status (ActionType.EXECUTE, cmdType, ioex.getLocalizedMessage (), StateType.FAILED)); 308 } catch (RuntimeException e) { 309 String msg = NbBundle.getMessage(TomcatManagerImpl.class, "MSG_DeployBrokenContextXml"); 310 pes.fireHandleProgressEvent(null, new Status (ActionType.EXECUTE, cmdType, msg, StateType.FAILED)); 311 return; 312 } 313 } 314 315 318 private static String encodePath(String str) { 319 try { 320 StringTokenizer st = new StringTokenizer (str, "/"); if (!st.hasMoreTokens()) { 322 return str; 323 } 324 StringBuilder result = new StringBuilder (); 325 while (st.hasMoreTokens()) { 326 result.append("/").append(URLEncoder.encode(st.nextToken(), "UTF-8")); } 328 return result.toString(); 329 } catch (UnsupportedEncodingException e) { 330 throw new RuntimeException (e); } 332 } 333 334 338 private File createTempContextXml(String docBase, Context ctx) throws IOException { 339 File tmpContextXml = File.createTempFile("context", ".xml"); tmpContextXml.deleteOnExit(); 341 if (!docBase.equals (ctx.getAttributeValue ("docBase"))) { ctx.setAttributeValue ("docBase", docBase); FileOutputStream fos = new FileOutputStream (tmpContextXml); 344 ctx.write (fos); 345 fos.close (); 346 } 347 return tmpContextXml; 348 } 349 350 358 TargetModuleID [] list (Target t, int state) throws IllegalStateException { 359 this.tmId = tmId; 360 command = "list"; run (); 362 if (!authorized) { 363 String errMsg = NbBundle.getMessage(TomcatManagerImpl.class, "MSG_AuthorizationFailed"); 365 IllegalStateException ise = new IllegalStateException (errMsg); 366 throw (IllegalStateException )ise.initCause(new AuthorizationException()); 367 } 368 java.util.List modules = new java.util.ArrayList (); 370 boolean first = true; 371 StringTokenizer stok = new StringTokenizer (output, "\r\n"); while (stok.hasMoreTokens ()) { 373 String line = stok.nextToken (); 374 if (first) { 375 first = false; 376 } 377 else { 378 StringTokenizer ltok = new StringTokenizer (line, ":"); try { 380 String ctx = ltok.nextToken (); 381 String s = ltok.nextToken (); 382 String tag = ltok.nextToken (); 383 String path = null; 384 if (ltok.hasMoreTokens()) { 387 path = line.substring (ctx.length () + s.length () + tag.length () + 3); 388 } 389 if ("running".equals (s) 390 && (state == TomcatManager.ENUM_AVAILABLE || state == TomcatManager.ENUM_RUNNING)) { 391 modules.add (new TomcatModule (t, ctx, path)); 392 } 393 if ("stopped".equals (s) 394 && (state == TomcatManager.ENUM_AVAILABLE || state == TomcatManager.ENUM_NONRUNNING)) { 395 modules.add (new TomcatModule (t, ctx, path)); 396 } 397 } 398 catch (java.util.NoSuchElementException e) { 399 e.printStackTrace (); 401 } 402 } 403 } 404 return (TargetModuleID []) modules.toArray (new TargetModuleID [modules.size ()]); 405 } 406 407 411 public String jmxProxy (String query) { 412 command = "jmxproxy/"+query; run (); 414 return output; 416 } 417 418 419 public ClientConfiguration getClientConfiguration (TargetModuleID targetModuleID) { 420 return null; } 422 423 424 public DeploymentStatus getDeploymentStatus () { 425 return pes.getDeploymentStatus (); 426 } 427 428 429 public TargetModuleID [] getResultTargetModuleIDs () { 430 return new TargetModuleID [] { tmId }; 431 } 432 433 434 public boolean isCancelSupported () { 435 return false; 436 } 437 438 439 public void cancel () 440 throws OperationUnsupportedException { 441 throw new OperationUnsupportedException ("cancel not supported in Tomcat deployment"); } 443 444 445 public boolean isStopSupported () { 446 return false; 447 } 448 449 450 public void stop () throws OperationUnsupportedException { 451 throw new OperationUnsupportedException ("stop not supported in Tomcat deployment"); } 453 454 455 public void addProgressListener (ProgressListener l) { 456 pes.addProgressListener (l); 457 } 458 459 460 public void removeProgressListener (ProgressListener l) { 461 pes.removeProgressListener (l); 462 } 463 464 465 public synchronized void run () { 466 TomcatFactory.getEM ().log(ErrorManager.INFORMATIONAL, command); 467 pes.fireHandleProgressEvent (tmId, new Status (ActionType.EXECUTE, cmdType, command , StateType.RUNNING)); 468 469 output = ""; 470 authorized = true; 471 472 int retries = 4; 473 474 URLConnection conn = null; 476 InputStreamReader reader = null; 477 478 URL urlToConnectTo = null; 479 480 boolean failed = false; 481 String msg = null; 482 while (retries >= 0) { 483 retries = retries - 1; 484 try { 485 486 String uri = tm.getPlainUri (); 488 String withoutSpaces = (uri + command).replaceAll(" ", "%20"); urlToConnectTo = new URL (withoutSpaces); 490 491 if (Boolean.getBoolean("org.netbeans.modules.tomcat5.LogManagerCommands")) { String message = "Tomcat 5 sending manager command: " + urlToConnectTo; 493 System.out.println(message); 494 ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, new Exception (message)); 495 } 496 497 conn = urlToConnectTo.openConnection(); 498 HttpURLConnection hconn = (HttpURLConnection ) conn; 499 500 hconn.setAllowUserInteraction(false); 502 hconn.setDoInput(true); 503 hconn.setUseCaches(false); 504 if (istream != null) { 505 hconn.setDoOutput(true); 506 hconn.setRequestMethod("PUT"); hconn.setRequestProperty("Content-Type", "application/octet-stream"); } else { 509 hconn.setDoOutput(false); 510 hconn.setRequestMethod("GET"); } 512 hconn.setRequestProperty("User-Agent", "NetBeansIDE-Tomcat-Manager/1.0"); TomcatProperties tp = tm.getTomcatProperties(); 516 String input = tp.getUsername () + ":" + tp.getPassword (); 517 String auth = new String (Base64.encode(input.getBytes())); 518 hconn.setRequestProperty("Authorization", "Basic " + auth); 521 hconn.connect(); 523 int respCode = hconn.getResponseCode(); 524 if (respCode == HttpURLConnection.HTTP_UNAUTHORIZED 525 || respCode == HttpURLConnection.HTTP_FORBIDDEN) { 526 authorized = false; 528 String errMsg = NbBundle.getMessage(TomcatManagerImpl.class, "MSG_AuthorizationFailed"); 529 pes.fireHandleProgressEvent (null, new Status (ActionType.EXECUTE, cmdType, errMsg, StateType.FAILED)); 530 return; 531 } 532 if (Boolean.getBoolean("org.netbeans.modules.tomcat5.LogManagerCommands")) { int code = hconn.getResponseCode(); 534 String message = "Tomcat 5 receiving response, code: " + code; 535 System.out.println(message); 536 ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, new Exception (message)); 537 } 538 if (istream != null) { 540 BufferedOutputStream ostream = 541 new BufferedOutputStream(hconn.getOutputStream(), 1024); 542 byte buffer[] = new byte[1024]; 543 while (true) { 544 int n = istream.read(buffer); 545 if (n < 0) { 546 break; 547 } 548 ostream.write(buffer, 0, n); 549 } 550 ostream.flush(); 551 ostream.close(); 552 istream.close(); 553 } 554 555 reader = new InputStreamReader(hconn.getInputStream(),"UTF-8"); retries = -1; 558 StringBuffer buff = new StringBuffer (); 559 String error = null; 560 msg = null; 561 boolean first = !command.startsWith ("jmxproxy"); while (true) { 563 int ch = reader.read(); 564 if (ch < 0) { 565 output += buff.toString ()+"\n"; break; 567 } else if ((ch == '\r') || (ch == '\n')) { 568 String line = buff.toString(); 569 buff.setLength(0); 570 TomcatFactory.getEM ().log(ErrorManager.INFORMATIONAL, line); 571 if (first) { 572 String japaneseOK="\u6210\u529f"; msg = line; 575 if (line.indexOf("java.lang.ThreadDeath") != -1) { String warning = NbBundle.getMessage(TomcatManagerImpl.class, "MSG_ThreadDeathWarning"); 578 pes.fireHandleProgressEvent( 579 tmId, 580 new Status (ActionType.EXECUTE, cmdType, warning, StateType.RUNNING) 581 ); 582 } else if (!(line.startsWith("OK -") || line.startsWith(japaneseOK))) { error = line; 584 } 585 first = false; 586 } 587 output += line+"\n"; } else { 589 buff.append((char) ch); 590 } 591 } 592 if (buff.length() > 0) { 593 TomcatFactory.getEM ().log(ErrorManager.INFORMATIONAL, buff.toString()); 594 } 595 if (error != null) { 596 TomcatFactory.getEM().log("TomcatManagerImpl connecting to: " + urlToConnectTo); TomcatFactory.getEM ().log (error); 598 pes.fireHandleProgressEvent (tmId, new Status (ActionType.EXECUTE, cmdType, error, StateType.FAILED)); 599 failed = true; 600 } 601 602 } catch (Exception e) { 603 if (retries < 0) { 604 TomcatFactory.getEM().log("TomcatManagerImpl connecting to: " + urlToConnectTo); TomcatFactory.getEM ().notify (ErrorManager.INFORMATIONAL, e); 606 pes.fireHandleProgressEvent (tmId, new Status (ActionType.EXECUTE, cmdType, e.getLocalizedMessage (), StateType.FAILED)); 607 failed = true; 608 } 609 } finally { 611 if (reader != null) { 612 try { 613 reader.close(); 614 } catch (java.io.IOException ioe) { } 616 reader = null; 617 } 618 if (istream != null) { 619 try { 620 istream.close(); 621 } catch (java.io.IOException ioe) { } 623 istream = null; 624 } 625 } 626 if (retries >=0) { 627 try { 628 Thread.sleep(3000); 629 } catch (InterruptedException e) {} 630 } 631 } if (!failed) { 633 pes.fireHandleProgressEvent (tmId, new Status (ActionType.EXECUTE, cmdType, msg, StateType.COMPLETED)); 634 } 635 } 636 } 637 | Popular Tags |