KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jdesktop > swing > actions > ServerAction


1 /*
2  * $Id: ServerAction.java,v 1.2 2004/07/16 18:43:57 rameshgupta Exp $
3  *
4  * Copyright 2004 Sun Microsystems, Inc., 4150 Network Circle,
5  * Santa Clara, California 95054, U.S.A. All rights reserved.
6  */

7
8 /**
9  * Copyright 2004 Sun Microsystems, Inc. All Rights Reserved.
10  *
11  * Redistribution and use in source and binary forms, with or
12  * without modification, are permitted provided that the following
13  * conditions are met:
14  *
15  * - Redistributions of source code must retain the above copyright
16  * notice, this list of conditions and the following disclaimer.
17  *
18  * - Redistribution in binary form must reproduce the above
19  * copyright notice, this list of conditions and the following
20  * disclaimer in the documentation and/or other materials
21  * provided with the distribution.
22  *
23  * Neither the name of Sun Microsystems, Inc. or the names of
24  * contributors may be used to endorse or promote products derived
25  * from this software without specific prior written permission.
26  *
27  * This software is provided "AS IS," without a warranty of any
28  * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
29  * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
30  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
31  * EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY
32  * DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT OF OR
33  * RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE OR
34  * ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE
35  * FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT,
36  * SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
37  * CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF
38  * THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS
39  * BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
40  *
41  * You acknowledge that this software is not designed, licensed or
42  * intended for use in the design, construction, operation or
43  * maintenance of any nuclear facility.
44  *
45  */

46 package org.jdesktop.swing.actions;
47
48 import java.awt.event.ActionEvent JavaDoc;
49
50 import java.io.BufferedReader JavaDoc;
51 import java.io.ByteArrayOutputStream JavaDoc;
52 import java.io.InputStream JavaDoc;
53 import java.io.InputStreamReader JavaDoc;
54 import java.io.IOException JavaDoc;
55 import java.io.PrintWriter JavaDoc;
56 import java.io.UnsupportedEncodingException JavaDoc;
57
58 import java.net.MalformedURLException JavaDoc;
59 import java.net.HttpURLConnection JavaDoc;
60 import java.net.UnknownHostException JavaDoc;
61 import java.net.URL JavaDoc;
62 import java.net.URLConnection JavaDoc;
63 import java.net.URLEncoder JavaDoc;
64
65 import java.security.AccessControlException JavaDoc;
66
67 import java.util.Map JavaDoc;
68 import java.util.HashMap JavaDoc;
69 import java.util.Iterator JavaDoc;
70 import java.util.Set JavaDoc;
71
72 import javax.swing.AbstractAction JavaDoc;
73 import javax.swing.Action JavaDoc;
74 import javax.swing.Icon JavaDoc;
75
76 import org.jdesktop.swing.Application;
77
78
79 /**
80  * An action which will invoke an http POST operation.
81  *
82  * @author Mark Davidson
83  */

84 public class ServerAction extends AbstractAction JavaDoc {
85     // Server action support
86

87     private static final String JavaDoc PARAMS = "action-params";
88     private static final String JavaDoc HEADERS = "action-headers";
89     private static final String JavaDoc URL = "action-url";
90
91     private static final String JavaDoc URL_CACHE = "_URL-CACHE__";
92
93     public ServerAction() {
94     this("action");
95     }
96
97     public ServerAction(String JavaDoc name) {
98     super(name);
99     }
100
101     /**
102      * @param name display name of the action
103      * @param command the value of the action command key
104      */

105     public ServerAction(String JavaDoc name, String JavaDoc command) {
106     this(name, command, null);
107     }
108
109     public ServerAction(String JavaDoc name, Icon JavaDoc icon) {
110     super(name, icon);
111     }
112
113     /**
114      * @param name display name of the action
115      * @param command the value of the action command key
116      * @param icon icon to display
117      */

118     public ServerAction(String JavaDoc name, String JavaDoc command, Icon JavaDoc icon) {
119     super(name, icon);
120     putValue(Action.ACTION_COMMAND_KEY, command);
121     }
122
123     /**
124      * Set the url for the action.
125      * <p>
126      * @param url a string representation of the url
127      */

128     public void setURL(String JavaDoc url) {
129     putValue(URL, url);
130     putValue(URL_CACHE, null);
131     }
132
133     public String JavaDoc getURL() {
134     return (String JavaDoc)getValue(URL);
135     }
136
137     private Map JavaDoc getParams() {
138     return (Map JavaDoc)getValue(PARAMS);
139     }
140
141     private void setParams(Map JavaDoc params) {
142     putValue(PARAMS, params);
143     }
144
145     /**
146      * Adds a name value pair which represents a url parameter in an http
147      * POST request.
148      */

149     public void addParam(String JavaDoc name, String JavaDoc value) {
150     Map JavaDoc params = getParams();
151     if (params == null) {
152         params = new HashMap JavaDoc();
153         setParams(params);
154     }
155     params.put(name, value);
156     }
157
158     /**
159      * Return a parameter value corresponding to name or null if it doesn't exist.
160      */

161     public String JavaDoc getParamValue(String JavaDoc name) {
162     Map JavaDoc params = getParams();
163     return params == null ? null : (String JavaDoc)params.get(name);
164     }
165
166     /**
167      * Return a set of parameter names or null if there are no params
168      */

169     public Set JavaDoc getParamNames() {
170     Map JavaDoc params = getParams();
171     return params == null ? null : params.keySet();
172     }
173
174     private Map JavaDoc getHeaders() {
175     return (Map JavaDoc)getValue(HEADERS);
176     }
177
178     private void setHeaders(Map JavaDoc headers) {
179     putValue(HEADERS, headers);
180     }
181
182     /**
183      * Adds a name value pair which represents a url connection request property.
184      * For example, name could be "Content-Type" and the value could be
185      * "application/x-www-form-urlencoded"
186      */

187     public void addHeader(String JavaDoc name, String JavaDoc value) {
188     Map JavaDoc map = getHeaders();
189     if (map != null) {
190         map = new HashMap JavaDoc();
191         setHeaders(map);
192     }
193     map.put(name, value);
194     }
195
196     /**
197      * Return a header value corresponding to name or null if it doesn't exist.
198      */

199     public String JavaDoc getHeaderValue(String JavaDoc name) {
200     Map JavaDoc headers = getHeaders();
201     return headers == null ? null : (String JavaDoc)headers.get(name);
202     }
203
204     /**
205      * Return a set of parameter names or null if there are no params
206      */

207     public Set JavaDoc getHeaderNames() {
208     Map JavaDoc headers = getHeaders();
209     return headers == null ? null : headers.keySet();
210     }
211
212     /**
213      * Invokes the server operation when the action has been invoked.
214      */

215     public void actionPerformed(ActionEvent JavaDoc evt) {
216     URL JavaDoc execURL = (URL JavaDoc)getValue(URL_CACHE);
217     if (execURL == null && !"".equals(getURL())) {
218         try {
219         String JavaDoc url = getURL();
220         if (url.startsWith("http")) {
221             execURL = new URL JavaDoc(url);
222         } else {
223             // Create the URL based on the enclosing applet.
224
execURL = Application.getURL(url, this);
225         }
226         if (execURL == null) {
227             // XXX TODO: send a message
228
return;
229         } else {
230             // Cache this value.
231
putValue(URL_CACHE, execURL);
232         }
233
234         /*
235         if (Debug.debug) {
236             System.out.println("ServerAction: URL created: " + execURL.toString());
237         }
238         */

239         } catch (MalformedURLException JavaDoc ex) {
240         ex.printStackTrace();
241         }
242     }
243
244     try {
245         URLConnection JavaDoc uc = execURL.openConnection();
246
247         // Get all the header name/value pairs ans set the request headers
248
Set JavaDoc headerNames = getHeaderNames();
249         if (headerNames != null && !headerNames.isEmpty()) {
250         Iterator JavaDoc iter = headerNames.iterator();
251         while (iter.hasNext()) {
252             String JavaDoc name = (String JavaDoc)iter.next();
253             uc.setRequestProperty(name, getHeaderValue(name));
254         }
255         }
256         uc.setUseCaches(false);
257         uc.setDoOutput(true);
258
259         ByteArrayOutputStream JavaDoc byteStream = new ByteArrayOutputStream JavaDoc(512);
260         PrintWriter JavaDoc out = new PrintWriter JavaDoc(byteStream, true);
261         out.print(getPostData());
262         out.flush();
263
264         // POST requests must have a content-length.
265
String JavaDoc length = String.valueOf(byteStream.size());
266         uc.setRequestProperty("Content-length", length);
267
268         // Write POST data to real output stream.
269
byteStream.writeTo(uc.getOutputStream());
270
271         BufferedReader JavaDoc buf = null;
272         if (uc instanceof HttpURLConnection JavaDoc) {
273         HttpURLConnection JavaDoc huc = (HttpURLConnection JavaDoc)uc;
274         int code = huc.getResponseCode();
275         String JavaDoc message = huc.getResponseMessage();
276
277         // Handle the result.
278
if (code < 400) {
279             // action succeeded send to status bar
280
// XXX TODO: setStatusMessage(createMessage(code, message));
281
// Format the response
282
// TODO: This should load asychnonously
283
buf = new BufferedReader JavaDoc(new InputStreamReader JavaDoc(uc.getInputStream()));
284
285         } else {
286             // action has failed show dialog
287
// XXX TODO: setStatusMessage(createMessage(code, message));
288
buf = new BufferedReader JavaDoc(new InputStreamReader JavaDoc(huc.getErrorStream()));
289         }
290         String JavaDoc line;
291
292         StringBuffer JavaDoc buffer = new StringBuffer JavaDoc();
293         while ((line = buf.readLine()) != null) {
294             // RG: Fix for J2SE 5.0; Can't cascade append() calls because
295
// return type in StringBuffer and AbstractStringBuilder are different
296
buffer.append(line);
297             buffer.append('\n');
298         }
299         if (Debug.debug) {
300             // XXX So now that we have results in the StringBuffer, we should do something
301
// with it.
302
System.out.println(buffer.toString());
303         }
304         }
305     } catch (UnknownHostException JavaDoc uhe) {
306         Debug.printException("UnknownHostException detected. Could it be a proxy issue?\n" +
307                  uhe.getMessage(), uhe);
308     } catch (AccessControlException JavaDoc aex) {
309         Debug.printException("AccessControlException detected\n" +
310                 aex.getMessage(), aex);
311     } catch (IOException JavaDoc ex) {
312         Debug.printException("IOException detected\n" +
313                  ex.getMessage(), ex);
314     }
315     }
316
317     /**
318      * Retrieves a string which represents the parameter data for a server action.
319      * @return a string of name value pairs prefixed by a '?' and delimited by an '&'
320      */

321     private String JavaDoc getPostData() {
322     // Write the data into local buffer
323
StringBuffer JavaDoc postData = new StringBuffer JavaDoc();
324
325     // TODO: the action should be configured to retrieve the data.
326

327     // Get all the param name/value pairs and build the data string
328
Set JavaDoc paramNames = getParamNames();
329     if (paramNames != null && !paramNames.isEmpty()) {
330         Iterator JavaDoc iter = paramNames.iterator();
331         try {
332             while (iter.hasNext()) {
333                 String JavaDoc name = (String JavaDoc) iter.next();
334                 postData.append('&').append(name).append('=');
335                 postData.append(getParamValue(name));
336             }
337         }
338         catch (Exception JavaDoc ex) { // RG: append(char) throws IOException in J2SE 5.0
339
/** @todo Log it */
340         }
341         // Replace the first & with a ?
342
postData.setCharAt(0, '?');
343     }
344     if (Debug.debug) {
345         System.out.println("ServerAction: POST data: " + postData.toString());
346     }
347     return postData.toString();
348     }
349
350     /**
351      * Retrieves the text from the text component.
352      * TODO: should use selection criteria to select text.
353      */

354     private StringBuffer JavaDoc getDataBuffer() throws UnsupportedEncodingException JavaDoc {
355     StringBuffer JavaDoc buffer = new StringBuffer JavaDoc("content=");
356     /*
357     if (listener != null) {
358         buffer.append(URLEncoder.encode(listener.getText(), "UTF-8"));
359     } else {
360         buffer.append("ServerAction ERROR: text component has not been set");
361         }*/

362     return buffer;
363     }
364
365     /**
366      * Creates a human readable message from the server code and message result.
367      * @param code an http error code.
368      * @param msg server message
369      */

370     private String JavaDoc createMessage(int code, String JavaDoc msg) {
371     StringBuffer JavaDoc buffer = new StringBuffer JavaDoc("The action \"");
372     buffer.append(getValue(NAME));
373
374     if (code < 400) {
375         buffer.append("\" has succeeded ");
376     } else {
377         buffer.append("\" has failed\nPlease check the Java console for more details.\n");
378     }
379     // RG: Fix for J2SE 5.0; Can't cascade append() calls because
380
// return type in StringBuffer and AbstractStringBuilder are different
381
buffer.append("\nServer response:\nCode: ");
382     buffer.append(code);
383     buffer.append(" Message: ");
384     buffer.append(msg);
385
386     return buffer.toString();
387     }
388 }
389
Popular Tags