001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041:
042: package org.netbeans.modules.tomcat5;
043:
044: import java.net.HttpURLConnection;
045: import java.net.URL;
046: import java.net.URLConnection;
047: import java.net.URLEncoder;
048: import java.util.StringTokenizer;
049: import javax.enterprise.deploy.shared.ActionType;
050: import javax.enterprise.deploy.shared.CommandType;
051: import javax.enterprise.deploy.shared.StateType;
052: import javax.enterprise.deploy.spi.Target;
053: import javax.enterprise.deploy.spi.TargetModuleID;
054: import javax.enterprise.deploy.spi.exceptions.OperationUnsupportedException;
055: import javax.enterprise.deploy.spi.status.ClientConfiguration;
056: import javax.enterprise.deploy.spi.status.DeploymentStatus;
057: import javax.enterprise.deploy.spi.status.ProgressListener;
058: import javax.enterprise.deploy.spi.status.ProgressObject;
059: import org.netbeans.modules.tomcat5.config.gen.Context;
060: import org.netbeans.modules.tomcat5.config.gen.Engine;
061: import org.netbeans.modules.tomcat5.config.gen.Host;
062: import org.netbeans.modules.tomcat5.config.gen.SContext;
063: import org.netbeans.modules.tomcat5.config.gen.Server;
064: import org.netbeans.modules.tomcat5.config.gen.Service;
065: import org.netbeans.modules.tomcat5.progress.ProgressEventSupport;
066: import org.netbeans.modules.tomcat5.progress.Status;
067: import org.openide.util.RequestProcessor;
068: import org.openide.util.NbBundle;
069: import java.io.*;
070: import java.util.logging.Level;
071: import java.util.logging.Logger;
072: import org.netbeans.modules.tomcat5.util.TomcatProperties;
073:
074: /** Implemtation of management task that provides info about progress
075: *
076: * @author Radim Kubacki
077: */
078: public class TomcatManagerImpl implements ProgressObject, Runnable {
079:
080: /** RequestProcessor processor that serializes management tasks. */
081: private static RequestProcessor rp;
082:
083: /** Returns shared RequestProcessor. */
084: private static synchronized RequestProcessor rp() {
085: if (rp == null) {
086: rp = new RequestProcessor("Tomcat management", 1); // NOI18N
087: }
088: return rp;
089: }
090:
091: /** Support for progress notifications. */
092: private ProgressEventSupport pes;
093:
094: /** Command that is executed on running server. */
095: private String command;
096:
097: /** Output of executed command (parsed for list commands). */
098: private String output;
099:
100: /** Command type used for events. */
101: private CommandType cmdType;
102:
103: /** InputStream of application data. */
104: private InputStream istream;
105:
106: private TomcatManager tm;
107:
108: /** Has been the last access to tomcat manager web app authorized? */
109: private boolean authorized;
110:
111: /** TargetModuleID of module that is managed. */
112: private TomcatModule tmId;
113:
114: private static final Logger LOGGER = Logger
115: .getLogger(TomcatManagerImpl.class.getName());
116:
117: public TomcatManagerImpl(TomcatManager tm) {
118: this .tm = tm;
119: pes = new ProgressEventSupport(this );
120: }
121:
122: public void deploy(Target t, InputStream is, InputStream deplPlan) {
123: Context ctx;
124: try {
125: ctx = Context.createGraph(deplPlan);
126: } catch (RuntimeException e) {
127: String msg = NbBundle.getMessage(TomcatManagerImpl.class,
128: "MSG_DeployBrokenContextXml");
129: pes
130: .fireHandleProgressEvent(null, new Status(
131: ActionType.EXECUTE, cmdType, msg,
132: StateType.FAILED));
133: return;
134: }
135: String ctxPath = ctx.getAttributeValue("path"); // NOI18N
136: tmId = new TomcatModule(t, ctxPath);
137: command = "deploy?path=" + encodePath(tmId.getPath()); // NOI18N
138: cmdType = CommandType.DISTRIBUTE;
139: String msg = NbBundle.getMessage(TomcatManagerImpl.class,
140: "MSG_DeploymentInProgress");
141: pes.fireHandleProgressEvent(null, new Status(
142: ActionType.EXECUTE, cmdType, msg, StateType.RUNNING));
143: istream = is;
144: rp().post(this , 0, Thread.NORM_PRIORITY);
145: }
146:
147: /** Deploys WAR file or directory to Tomcat using deplPlan as source
148: * of conetx configuration data.
149: */
150: public void install(Target t, File wmfile, File deplPlan) {
151: // WAR file
152: String docBase = wmfile.toURI().toASCIIString();
153: if (docBase.endsWith("/")) { // NOI18N
154: docBase = docBase.substring(0, docBase.length() - 1);
155: }
156: if (wmfile.isFile()) {
157: // WAR file
158: docBase = "jar:" + docBase + "!/"; // NOI18N
159: }
160: // config or path
161: String ctxPath = null;
162: try {
163: if (!deplPlan.exists()) {
164: if (wmfile.isDirectory()) {
165: ctxPath = "/" + wmfile.getName(); // NOI18N
166: } else {
167: ctxPath = "/"
168: + wmfile.getName().substring(0,
169: wmfile.getName().lastIndexOf('.')); // NOI18N
170: }
171: tmId = new TomcatModule(t, ctxPath); // NOI18N
172: command = "deploy?update=true&path="
173: + encodePath(ctxPath) + "&war=" + docBase; // NOI18N
174: } else {
175: FileInputStream in = new FileInputStream(deplPlan);
176: Context ctx;
177: try {
178: ctx = Context.createGraph(in);
179: } catch (RuntimeException e) {
180: String msg = NbBundle.getMessage(
181: TomcatManagerImpl.class,
182: "MSG_DeployBrokenContextXml");
183: pes.fireHandleProgressEvent(null, new Status(
184: ActionType.EXECUTE, cmdType, msg,
185: StateType.FAILED));
186: return;
187: }
188: //PENDING #37763
189: // tmId = new TomcatModule (t, ctx.getAttributeValue ("path")); // NOI18N
190: // command = "install?update=true&config="+deplPlan.toURI ()+ // NOI18N
191: // "&war="+docBase; // NOI18N
192: if (wmfile.isDirectory()) {
193: ctxPath = "/" + wmfile.getName(); // NOI18N
194: } else {
195: ctxPath = "/"
196: + wmfile.getName().substring(0,
197: wmfile.getName().lastIndexOf('.')); // NOI18N
198: }
199: ctxPath = ctx.getAttributeValue("path");
200: tmId = new TomcatModule(t, ctxPath); // NOI18N
201: command = "deploy?update=true&path="
202: + encodePath(tmId.getPath()) + "&war="
203: + docBase; // NOI18N
204: }
205:
206: // call the command
207: cmdType = CommandType.DISTRIBUTE;
208: String msg = NbBundle.getMessage(TomcatManagerImpl.class,
209: "MSG_DeploymentInProgress");
210: pes.fireHandleProgressEvent(null,
211: new Status(ActionType.EXECUTE, cmdType, msg,
212: StateType.RUNNING));
213:
214: rp().post(this , 0, Thread.NORM_PRIORITY);
215: } catch (java.io.FileNotFoundException fnfe) {
216: pes.fireHandleProgressEvent(null, new Status(
217: ActionType.EXECUTE, cmdType, fnfe
218: .getLocalizedMessage(), StateType.FAILED));
219: }
220:
221: }
222:
223: public void initialDeploy(Target t, File contextXml, File dir) {
224: try {
225: FileInputStream in = new FileInputStream(contextXml);
226: Context ctx = Context.createGraph(in);
227: String docBaseURI = dir.getAbsoluteFile().toURI()
228: .toASCIIString();
229: String docBase = dir.getAbsolutePath();
230: String ctxPath = ctx.getAttributeValue("path");
231: this .tmId = new TomcatModule(t, ctxPath, docBase); //NOI18N
232: File tmpContextXml = createTempContextXml(docBase, ctx);
233: if (tm.isTomcat50()) {
234: command = "deploy?config="
235: + tmpContextXml.toURI().toASCIIString()
236: + "&war=" + docBaseURI; // NOI18N
237: } else {
238: command = "deploy?config="
239: + tmpContextXml.toURI().toASCIIString()
240: + "&path=" + encodePath(tmId.getPath()); // NOI18N
241: }
242: cmdType = CommandType.DISTRIBUTE;
243: String msg = NbBundle.getMessage(TomcatManagerImpl.class,
244: "MSG_DeploymentInProgress");
245: pes.fireHandleProgressEvent(null,
246: new Status(ActionType.EXECUTE, cmdType, msg,
247: StateType.RUNNING));
248: rp().post(this , 0, Thread.NORM_PRIORITY);
249: } catch (java.io.IOException ioex) {
250: pes.fireHandleProgressEvent(null, new Status(
251: ActionType.EXECUTE, cmdType, ioex
252: .getLocalizedMessage(), StateType.FAILED));
253: } catch (RuntimeException e) {
254: String msg = NbBundle.getMessage(TomcatManagerImpl.class,
255: "MSG_DeployBrokenContextXml");
256: pes
257: .fireHandleProgressEvent(null, new Status(
258: ActionType.EXECUTE, cmdType, msg,
259: StateType.FAILED));
260: }
261: }
262:
263: public void remove(TomcatModule tmId) {
264: // remove context from server.xml
265: Server server = tm.getRoot();
266: if (server != null
267: && removeContextFromServer(server, tmId.getPath())) {
268: File f = null;
269: try {
270: f = tm.getTomcatProperties().getServerXml();
271: server.write(f);
272: } catch (Exception e) {
273: // cannot save changes
274: pes.fireHandleProgressEvent(tmId, new Status(
275: ActionType.EXECUTE, CommandType.UNDEPLOY,
276: NbBundle
277: .getMessage(TomcatManagerImpl.class,
278: "MSG_ServerXml_RO", f
279: .getAbsolutePath()),
280: StateType.FAILED));
281: return;
282: }
283: }
284: this .tmId = tmId;
285: command = "undeploy?path=" + encodePath(tmId.getPath()); // NOI18N
286: cmdType = CommandType.UNDEPLOY;
287: String msg = NbBundle.getMessage(TomcatManagerImpl.class,
288: "MSG_UndeploymentInProgress");
289: pes.fireHandleProgressEvent(null, new Status(
290: ActionType.EXECUTE, cmdType, msg, StateType.RUNNING));
291: rp().post(this , 0, Thread.NORM_PRIORITY);
292: }
293:
294: /**
295: * Remove context with the specified path from the Server tree.
296: * Look for the first appearance of the service and host element.
297: * (ide currently does not support multiple service and host elements).
298: */
299: private boolean removeContextFromServer(Server server, String path) {
300: // root web application is specified as an empty string
301: if (path.equals("/"))
302: path = ""; // NOI18N
303: Service[] service = server.getService();
304: if (service.length > 0) {
305: Engine engine = service[0].getEngine();
306: if (engine != null) {
307: Host[] host = engine.getHost();
308: if (host.length > 0) {
309: SContext[] sContext = host[0].getSContext();
310: for (int i = 0; i < sContext.length; i++) {
311: if (sContext[i].getAttributeValue("path")
312: .equals(path)) { // NOI18N
313: host[0].removeSContext(sContext[i]);
314: return true;
315: }
316: }
317: }
318: }
319: }
320: return false;
321: }
322:
323: /** Starts web module. */
324: public void start(TomcatModule tmId) {
325: this .tmId = tmId;
326: command = "start?path=" + encodePath(tmId.getPath()); // NOI18N
327: cmdType = CommandType.START;
328: String msg = NbBundle.getMessage(TomcatManagerImpl.class,
329: "MSG_StartInProgress");
330: pes.fireHandleProgressEvent(null, new Status(
331: ActionType.EXECUTE, cmdType, msg, StateType.RUNNING));
332: rp().post(this , 0, Thread.NORM_PRIORITY);
333: }
334:
335: /** Stops web module. */
336: public void stop(TomcatModule tmId) {
337: this .tmId = tmId;
338: command = "stop?path=" + encodePath(tmId.getPath()); // NOI18N
339: cmdType = CommandType.STOP;
340: String msg = NbBundle.getMessage(TomcatManagerImpl.class,
341: "MSG_StopInProgress");
342: pes.fireHandleProgressEvent(null, new Status(
343: ActionType.EXECUTE, cmdType, msg, StateType.RUNNING));
344: rp().post(this , 0, Thread.NORM_PRIORITY);
345: }
346:
347: /** Reloads web module. */
348: public void reload(TomcatModule tmId) {
349: this .tmId = tmId;
350: command = "reload?path=" + encodePath(tmId.getPath()); // NOI18N
351: cmdType = CommandType.REDEPLOY;
352: String msg = NbBundle.getMessage(TomcatManagerImpl.class,
353: "MSG_ReloadInProgress");
354: pes.fireHandleProgressEvent(null, new Status(
355: ActionType.EXECUTE, cmdType, msg, StateType.RUNNING));
356: rp().post(this , 0, Thread.NORM_PRIORITY);
357: }
358:
359: public void incrementalRedeploy(TomcatModule tmId) {
360: try {
361: this .tmId = tmId;
362: String docBase = tmId.getDocRoot();
363: assert docBase != null;
364: String docBaseURI = new File(docBase).toURI()
365: .toASCIIString();
366: File contextXml = new File(docBase
367: + "/META-INF/context.xml"); // NO18N
368: FileInputStream in = new FileInputStream(contextXml);
369: Context ctx = Context.createGraph(in);
370: File tmpContextXml = createTempContextXml(docBase, ctx);
371: if (tm.isTomcat50()) {
372: command = "deploy?config="
373: + tmpContextXml.toURI().toASCIIString()
374: + "&war=" + docBaseURI; // NOI18N
375: } else {
376: command = "deploy?config="
377: + tmpContextXml.toURI().toASCIIString()
378: + "&path=" + encodePath(tmId.getPath()); // NOI18N
379: }
380: cmdType = CommandType.DISTRIBUTE;
381: String msg = NbBundle.getMessage(TomcatManagerImpl.class,
382: "MSG_DeployInProgress");
383: pes.fireHandleProgressEvent(null,
384: new Status(ActionType.EXECUTE, cmdType, msg,
385: StateType.RUNNING));
386: rp().post(this , 0, Thread.NORM_PRIORITY);
387: } catch (java.io.IOException ioex) {
388: pes.fireHandleProgressEvent(null, new Status(
389: ActionType.EXECUTE, cmdType, ioex
390: .getLocalizedMessage(), StateType.FAILED));
391: } catch (RuntimeException e) {
392: String msg = NbBundle.getMessage(TomcatManagerImpl.class,
393: "MSG_DeployBrokenContextXml");
394: pes
395: .fireHandleProgressEvent(null, new Status(
396: ActionType.EXECUTE, cmdType, msg,
397: StateType.FAILED));
398: return;
399: }
400: }
401:
402: /**
403: * Translates a context path string into <code>application/x-www-form-urlencoded</code> format.
404: */
405: private static String encodePath(String str) {
406: try {
407: StringTokenizer st = new StringTokenizer(str, "/"); // NOI18N
408: if (!st.hasMoreTokens()) {
409: return str;
410: }
411: StringBuilder result = new StringBuilder();
412: while (st.hasMoreTokens()) {
413: result.append("/").append(
414: URLEncoder.encode(st.nextToken(), "UTF-8")); // NOI18N
415: }
416: return result.toString();
417: } catch (UnsupportedEncodingException e) {
418: throw new RuntimeException(e); // this should never happen
419: }
420: }
421:
422: /**
423: * Create a temporary copy of context.xml and set a docBase attribute
424: * in it. This does not modify the existing context.xml.
425: */
426: private File createTempContextXml(String docBase, Context ctx)
427: throws IOException {
428: File tmpContextXml = File.createTempFile("context", ".xml"); // NOI18N
429: tmpContextXml.deleteOnExit();
430: if (!docBase.equals(ctx.getAttributeValue("docBase"))) { //NOI18N
431: ctx.setAttributeValue("docBase", docBase); //NOI18N
432: FileOutputStream fos = new FileOutputStream(tmpContextXml);
433: ctx.write(fos);
434: fos.close();
435: }
436: return tmpContextXml;
437: }
438:
439: /** Lists web modules.
440: * This method runs synchronously.
441: * @param target server target
442: * @param state one of ENUM_ constants.
443: *
444: * @throws IllegalStateException when access to tomcat manager has not been
445: * authorized and therefore list of target modules could not been retrieved
446: */
447: TargetModuleID[] list(Target t, int state)
448: throws IllegalStateException {
449: command = "list"; // NOI18N
450: run();
451: if (!authorized) {
452: // connection to tomcat manager has not been authorized
453: String errMsg = NbBundle.getMessage(
454: TomcatManagerImpl.class, "MSG_AuthorizationFailed");
455: IllegalStateException ise = new IllegalStateException(
456: errMsg);
457: throw (IllegalStateException) ise
458: .initCause(new AuthorizationException());
459: }
460: // PENDING : error check
461: java.util.List modules = new java.util.ArrayList();
462: boolean first = true;
463: StringTokenizer stok = new StringTokenizer(output, "\r\n"); // NOI18N
464: while (stok.hasMoreTokens()) {
465: String line = stok.nextToken();
466: if (first) {
467: first = false;
468: } else {
469: StringTokenizer ltok = new StringTokenizer(line, ":"); // NOI18N
470: try {
471: String ctx = ltok.nextToken();
472: String s = ltok.nextToken();
473: String tag = ltok.nextToken();
474: String path = null;
475: //take the rest of line as path (it can contain ':')
476: // #50410 - path information is missing in the Japanese localization of Tomcat Manager
477: if (ltok.hasMoreTokens()) {
478: path = line.substring(ctx.length() + s.length()
479: + tag.length() + 3);
480: }
481: if ("running".equals(s)
482: && (state == TomcatManager.ENUM_AVAILABLE || state == TomcatManager.ENUM_RUNNING)) {
483: modules.add(new TomcatModule(t, ctx, path));
484: }
485: if ("stopped".equals(s)
486: && (state == TomcatManager.ENUM_AVAILABLE || state == TomcatManager.ENUM_NONRUNNING)) {
487: modules.add(new TomcatModule(t, ctx, path));
488: }
489: } catch (java.util.NoSuchElementException e) {
490: // invalid value
491: e.printStackTrace();
492: }
493: }
494: }
495: return (TargetModuleID[]) modules
496: .toArray(new TargetModuleID[modules.size()]);
497: }
498:
499: /** Queries Tomcat server to get JMX beans containing management information
500: * @param param encoded parameter(s) for query
501: * @return server output
502: */
503: public String jmxProxy(String query) {
504: command = "jmxproxy/" + query; // NOI18N
505: run();
506: // PENDING : error check
507: return output;
508: }
509:
510: /** JSR88 method. */
511: public ClientConfiguration getClientConfiguration(
512: TargetModuleID targetModuleID) {
513: return null; // PENDING
514: }
515:
516: /** JSR88 method. */
517: public DeploymentStatus getDeploymentStatus() {
518: return pes.getDeploymentStatus();
519: }
520:
521: /** JSR88 method. */
522: public TargetModuleID[] getResultTargetModuleIDs() {
523: return new TargetModuleID[] { tmId };
524: }
525:
526: /** JSR88 method. */
527: public boolean isCancelSupported() {
528: return false;
529: }
530:
531: /** JSR88 method. */
532: public void cancel() throws OperationUnsupportedException {
533: throw new OperationUnsupportedException(
534: "cancel not supported in Tomcat deployment"); // NOI18N
535: }
536:
537: /** JSR88 method. */
538: public boolean isStopSupported() {
539: return false;
540: }
541:
542: /** JSR88 method. */
543: public void stop() throws OperationUnsupportedException {
544: throw new OperationUnsupportedException(
545: "stop not supported in Tomcat deployment"); // NOI18N
546: }
547:
548: /** JSR88 method. */
549: public void addProgressListener(ProgressListener l) {
550: pes.addProgressListener(l);
551: }
552:
553: /** JSR88 method. */
554: public void removeProgressListener(ProgressListener l) {
555: pes.removeProgressListener(l);
556: }
557:
558: /** Executes one management task. */
559: public synchronized void run() {
560: LOGGER.log(Level.FINE, command);
561: pes.fireHandleProgressEvent(tmId, new Status(
562: ActionType.EXECUTE, cmdType, command /* message */,
563: StateType.RUNNING));
564:
565: output = "";
566: authorized = true;
567:
568: int retries = 4;
569:
570: // similar to Tomcat's Ant task
571: URLConnection conn = null;
572: InputStreamReader reader = null;
573:
574: URL urlToConnectTo = null;
575:
576: boolean failed = false;
577: String msg = null;
578: while (retries >= 0) {
579: retries = retries - 1;
580: try {
581:
582: // Create a connection for this command
583: String uri = tm.getPlainUri();
584: String withoutSpaces = (uri + command).replaceAll(" ",
585: "%20"); //NOI18N
586: urlToConnectTo = new URL(withoutSpaces);
587:
588: if (Boolean
589: .getBoolean("org.netbeans.modules.tomcat5.LogManagerCommands")) { // NOI18N
590: String message = "Tomcat 5 sending manager command: "
591: + urlToConnectTo;
592: Logger.getLogger(TomcatManagerImpl.class.getName())
593: .log(Level.FINE, null,
594: new Exception(message));
595: }
596:
597: conn = urlToConnectTo.openConnection();
598: HttpURLConnection hconn = (HttpURLConnection) conn;
599:
600: // Set up standard connection characteristics
601: hconn.setAllowUserInteraction(false);
602: hconn.setDoInput(true);
603: hconn.setUseCaches(false);
604: if (istream != null) {
605: hconn.setDoOutput(true);
606: hconn.setRequestMethod("PUT"); // NOI18N
607: hconn.setRequestProperty("Content-Type",
608: "application/octet-stream"); // NOI18N
609: } else {
610: hconn.setDoOutput(false);
611: hconn.setRequestMethod("GET"); // NOI18N
612: }
613: hconn.setRequestProperty("User-Agent", // NOI18N
614: "NetBeansIDE-Tomcat-Manager/1.0"); // NOI18N
615: // Set up an authorization header with our credentials
616: TomcatProperties tp = tm.getTomcatProperties();
617: String input = tp.getUsername() + ":"
618: + tp.getPassword();
619: String auth = new String(Base64
620: .encode(input.getBytes()));
621: hconn.setRequestProperty("Authorization", // NOI18N
622: "Basic " + auth); // NOI18N
623:
624: // Establish the connection with the server
625: hconn.connect();
626: int respCode = hconn.getResponseCode();
627: if (respCode == HttpURLConnection.HTTP_UNAUTHORIZED
628: || respCode == HttpURLConnection.HTTP_FORBIDDEN) {
629: // connection to tomcat manager has not been allowed
630: authorized = false;
631: String errMsg = NbBundle.getMessage(
632: TomcatManagerImpl.class,
633: "MSG_AuthorizationFailed");
634: pes.fireHandleProgressEvent(null, new Status(
635: ActionType.EXECUTE, cmdType, errMsg,
636: StateType.FAILED));
637: return;
638: }
639: if (Boolean
640: .getBoolean("org.netbeans.modules.tomcat5.LogManagerCommands")) { // NOI18N
641: int code = hconn.getResponseCode();
642: String message = "Tomcat 5 receiving response, code: "
643: + code;
644: System.out.println(message);
645: Logger.getLogger(TomcatManagerImpl.class.getName())
646: .log(Level.INFO, null,
647: new Exception(message));
648: }
649: // Send the request data (if any)
650: if (istream != null) {
651: BufferedOutputStream ostream = new BufferedOutputStream(
652: hconn.getOutputStream(), 1024);
653: byte buffer[] = new byte[1024];
654: while (true) {
655: int n = istream.read(buffer);
656: if (n < 0) {
657: break;
658: }
659: ostream.write(buffer, 0, n);
660: }
661: ostream.flush();
662: ostream.close();
663: istream.close();
664: }
665:
666: // Process the response message
667: reader = new InputStreamReader(hconn.getInputStream(),
668: "UTF-8"); //NOI18N
669: retries = -1;
670: StringBuffer buff = new StringBuffer();
671: String error = null;
672: msg = null;
673: boolean first = !command.startsWith("jmxproxy"); // NOI18N
674: while (true) {
675: int ch = reader.read();
676: if (ch < 0) {
677: output += buff.toString() + "\n"; // NOI18N
678: break;
679: } else if ((ch == '\r') || (ch == '\n')) {
680: String line = buff.toString();
681: buff.setLength(0);
682: LOGGER.log(Level.FINE, line);
683: if (first) {
684: // hard fix to accept the japanese localization of manager app
685: String japaneseOK = "\u6210\u529f"; //NOI18N
686: msg = line;
687: // see issue #62529
688: if (line.indexOf("java.lang.ThreadDeath") != -1) { // NOI18N
689: String warning = NbBundle.getMessage(
690: TomcatManagerImpl.class,
691: "MSG_ThreadDeathWarning");
692: pes.fireHandleProgressEvent(tmId,
693: new Status(ActionType.EXECUTE,
694: cmdType, warning,
695: StateType.RUNNING));
696: } else if (!(line.startsWith("OK -") || line
697: .startsWith(japaneseOK))) { // NOI18N
698: error = line;
699: }
700: first = false;
701: }
702: output += line + "\n"; // NOI18N
703: } else {
704: buff.append((char) ch);
705: }
706: }
707: if (buff.length() > 0) {
708: LOGGER.log(Level.FINE, buff.toString());
709: }
710: if (error != null) {
711: LOGGER.log(Level.INFO,
712: "TomcatManagerImpl connecting to: "
713: + urlToConnectTo, error); // NOI18N
714: pes.fireHandleProgressEvent(tmId, new Status(
715: ActionType.EXECUTE, cmdType, error,
716: StateType.FAILED));
717: failed = true;
718: }
719: if (msg == null) {
720: msg = buff.toString();
721: }
722: } catch (Exception e) {
723: if (retries < 0) {
724: LOGGER.log(Level.INFO,
725: "TomcatManagerImpl connecting to: "
726: + urlToConnectTo, e); // NOI18N
727: pes.fireHandleProgressEvent(tmId, new Status(
728: ActionType.EXECUTE, cmdType, e
729: .getLocalizedMessage(),
730: StateType.FAILED));
731: failed = true;
732: }
733: // throw t;
734: } finally {
735: if (reader != null) {
736: try {
737: reader.close();
738: } catch (java.io.IOException ioe) { // ignore this
739: }
740: reader = null;
741: }
742: if (istream != null) {
743: try {
744: istream.close();
745: } catch (java.io.IOException ioe) { // ignore this
746: }
747: istream = null;
748: }
749: }
750: if (retries >= 0) {
751: try {
752: Thread.sleep(3000);
753: } catch (InterruptedException e) {
754: }
755: }
756: } // while
757: if (!failed) {
758: pes.fireHandleProgressEvent(tmId, new Status(
759: ActionType.EXECUTE, cmdType, msg,
760: StateType.COMPLETED));
761: }
762: }
763: }
|