001: /*
002: * Copyright 2002,2004 The Apache Software Foundation.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016:
017: package org.apache.catalina.ant;
018:
019: import java.io.BufferedOutputStream;
020: import java.io.InputStream;
021: import java.io.InputStreamReader;
022: import java.net.HttpURLConnection;
023: import java.net.URL;
024: import java.net.URLConnection;
025: import org.apache.catalina.util.Base64;
026: import org.apache.tools.ant.BuildException;
027: import org.apache.tools.ant.Project;
028: import org.apache.tools.ant.Task;
029:
030: /**
031: * Abstract base class for Ant tasks that interact with the
032: * <em>Manager</em> web application for dynamically deploying and
033: * undeploying applications. These tasks require Ant 1.4 or later.
034: *
035: * @author Craig R. McClanahan
036: * @version $Revision: 1.3 $ $Date: 2004/02/27 14:58:40 $
037: * @since 4.1
038: */
039:
040: public abstract class AbstractCatalinaTask extends Task {
041:
042: // ----------------------------------------------------- Instance Variables
043:
044: /**
045: * manager webapp's encoding.
046: */
047: private static String CHARSET = "utf-8";
048:
049: // ------------------------------------------------------------- Properties
050:
051: /**
052: * The login password for the <code>Manager</code> application.
053: */
054: protected String password = null;
055:
056: public String getPassword() {
057: return (this .password);
058: }
059:
060: public void setPassword(String password) {
061: this .password = password;
062: }
063:
064: /**
065: * The URL of the <code>Manager</code> application to be used.
066: */
067: protected String url = "http://localhost:8080/manager";
068:
069: public String getUrl() {
070: return (this .url);
071: }
072:
073: public void setUrl(String url) {
074: this .url = url;
075: }
076:
077: /**
078: * The login username for the <code>Manager</code> application.
079: */
080: protected String username = null;
081:
082: public String getUsername() {
083: return (this .username);
084: }
085:
086: public void setUsername(String username) {
087: this .username = username;
088: }
089:
090: // --------------------------------------------------------- Public Methods
091:
092: /**
093: * Execute the specified command. This logic only performs the common
094: * attribute validation required by all subclasses; it does not perform
095: * any functional logic directly.
096: *
097: * @exception BuildException if a validation error occurs
098: */
099: public void execute() throws BuildException {
100:
101: if ((username == null) || (password == null) || (url == null)) {
102: throw new BuildException(
103: "Must specify all of 'username', 'password', and 'url'");
104: }
105:
106: }
107:
108: // ------------------------------------------------------ Protected Methods
109:
110: /**
111: * Execute the specified command, based on the configured properties.
112: *
113: * @param command Command to be executed
114: *
115: * @exception BuildException if an error occurs
116: */
117: public void execute(String command) throws BuildException {
118:
119: execute(command, null, null, -1);
120:
121: }
122:
123: /**
124: * Execute the specified command, based on the configured properties.
125: * The input stream will be closed upon completion of this task, whether
126: * it was executed successfully or not.
127: *
128: * @param command Command to be executed
129: * @param istream InputStream to include in an HTTP PUT, if any
130: * @param contentType Content type to specify for the input, if any
131: * @param contentLength Content length to specify for the input, if any
132: *
133: * @exception BuildException if an error occurs
134: */
135: public void execute(String command, InputStream istream,
136: String contentType, int contentLength)
137: throws BuildException {
138:
139: URLConnection conn = null;
140: InputStreamReader reader = null;
141: try {
142:
143: // Create a connection for this command
144: conn = (new URL(url + command)).openConnection();
145: HttpURLConnection hconn = (HttpURLConnection) conn;
146:
147: // Set up standard connection characteristics
148: hconn.setAllowUserInteraction(false);
149: hconn.setDoInput(true);
150: hconn.setUseCaches(false);
151: if (istream != null) {
152: hconn.setDoOutput(true);
153: hconn.setRequestMethod("PUT");
154: if (contentType != null) {
155: hconn.setRequestProperty("Content-Type",
156: contentType);
157: }
158: if (contentLength >= 0) {
159: hconn.setRequestProperty("Content-Length", ""
160: + contentLength);
161: }
162: } else {
163: hconn.setDoOutput(false);
164: hconn.setRequestMethod("GET");
165: }
166: hconn.setRequestProperty("User-Agent",
167: "Catalina-Ant-Task/1.0");
168:
169: // Set up an authorization header with our credentials
170: String input = username + ":" + password;
171: String output = new String(Base64.encode(input.getBytes()));
172: hconn
173: .setRequestProperty("Authorization", "Basic "
174: + output);
175:
176: // Establish the connection with the server
177: hconn.connect();
178:
179: // Send the request data (if any)
180: if (istream != null) {
181: BufferedOutputStream ostream = new BufferedOutputStream(
182: hconn.getOutputStream(), 1024);
183: byte buffer[] = new byte[1024];
184: while (true) {
185: int n = istream.read(buffer);
186: if (n < 0) {
187: break;
188: }
189: ostream.write(buffer, 0, n);
190: }
191: ostream.flush();
192: ostream.close();
193: istream.close();
194: }
195:
196: // Process the response message
197: reader = new InputStreamReader(hconn.getInputStream(),
198: CHARSET);
199: StringBuffer buff = new StringBuffer();
200: String error = null;
201: boolean first = true;
202: while (true) {
203: int ch = reader.read();
204: if (ch < 0) {
205: break;
206: } else if ((ch == '\r') || (ch == '\n')) {
207: String line = buff.toString();
208: buff.setLength(0);
209: log(line, Project.MSG_INFO);
210: if (first) {
211: if (!line.startsWith("OK -")) {
212: error = line;
213: }
214: first = false;
215: }
216: } else {
217: buff.append((char) ch);
218: }
219: }
220: if (buff.length() > 0) {
221: log(buff.toString(), Project.MSG_INFO);
222: }
223: if (error != null) {
224: throw new BuildException(error);
225: }
226:
227: } catch (Throwable t) {
228: throw new BuildException(t);
229: } finally {
230: if (reader != null) {
231: try {
232: reader.close();
233: } catch (Throwable u) {
234: ;
235: }
236: reader = null;
237: }
238: if (istream != null) {
239: try {
240: istream.close();
241: } catch (Throwable u) {
242: ;
243: }
244: istream = null;
245: }
246: }
247:
248: }
249:
250: }
|