View Javadoc

1   /*
2    * Copyright 1999-2001,2004 The Apache Software Foundation.
3    * 
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    * 
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    * 
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */ 
16  
17  package org.apache.commons.workflow.io;
18  
19  
20  import java.io.BufferedInputStream;
21  import java.io.InputStream;
22  import java.io.InputStreamReader;
23  import java.io.IOException;
24  import java.net.MalformedURLException;
25  import java.net.URL;
26  import java.net.URLConnection;
27  import java.util.EmptyStackException;
28  import org.apache.commons.workflow.Context;
29  import org.apache.commons.workflow.StepException;
30  import org.apache.commons.workflow.base.BaseStep;
31  import org.apache.commons.workflow.util.WorkflowUtils;
32  
33  
34  /**
35   * <p>Retrieve the contents of a specified URL resource, and push the
36   * contents as a String object onto the evaluation stack.</p>
37   *
38   * <p>Supported Attributes:</p>
39   * <ul>
40   * <li><strong>url</strong> - URL of the resource to be retrieved, or
41   *     omitted to pop a computed String value from the top of the
42   *     evaluation stack.</li>
43   * </ul>
44   *
45   * <strong>DESIGN QUESTION - What about binary content?</strong>
46   *
47   * @version $Revision: 155475 $ $Date: 2005-02-26 13:31:11 +0000 (Sat, 26 Feb 2005) $
48   * @author Craig R. McClanahan
49   */
50  
51  public class GetStep extends BaseStep {
52  
53  
54      // ----------------------------------------------------------= Constructors
55  
56  
57      /**
58       * Construct a default instance of this Step.
59       */
60      public GetStep() {
61  
62          super();
63  
64      }
65  
66  
67      /**
68       * Construct an instance of this Step with the specified identifier.
69       *
70       * @param id Step identifier
71       */
72      public GetStep(String id) {
73  
74          super();
75          setId(id);
76  
77      }
78  
79  
80      /**
81       * Construct a fully configured instance of this Step.
82       *
83       * @param id Step identifier
84       * @param url Resource url
85       */
86      public GetStep(String id, String url) {
87  
88          super();
89          setId(id);
90          setUrl(url);
91  
92      }
93  
94  
95      // ------------------------------------------------------------- Properties
96  
97  
98      /**
99       * The URL of the resource to be retrieved.
100      */
101     protected String url = null;
102 
103     public String getUrl() {
104         return (this.url);
105     }
106 
107     public void setUrl(String url) {
108         this.url = url;
109     }
110 
111 
112     // --------------------------------------------------------- Public Methods
113 
114 
115     /**
116      * Perform the executable actions related to this Step, in the context of
117      * the specified Context.
118      *
119      * @param context The Context that is tracking our execution state
120      *
121      * @exception StepException if a processing error has occurred
122      */
123     public void execute(Context context) throws StepException {
124 
125         // Get the remote URL we will be contacting
126         Object remote = this.url;
127         URL remoteURL = null;
128         if (remote == null) {
129             try {
130                 remote = (String) context.pop();
131             } catch (EmptyStackException e) {
132                 throw new StepException("Evaluation stack is empty", this);
133             }
134         }
135         if (remote instanceof URL) {
136             remoteURL = (URL) remote;
137         } else if (remote instanceof String) {
138             try {
139                 remoteURL = new URL((String) remote);
140             } catch (MalformedURLException e) {
141                 throw new StepException("Invalid URL '" + remote + "'",
142                                         e, this);
143             }
144         } else {
145             try {
146                 remoteURL = new URL(remote.toString());
147             } catch (MalformedURLException e) {
148                 throw new StepException("Invalid URL '" + remote + "'",
149                                         e, this);
150             }
151         }
152 
153         // Define variables we will need later
154         URLConnection conn = null;
155         InputStream is = null;
156         BufferedInputStream bis = null;
157         InputStreamReader isr = null;
158         StringBuffer sb = null;
159         StepException se = null;
160 
161         try {
162 
163             // Open a connection to the specified URL
164             conn = remoteURL.openConnection();
165             conn.setDoInput(true);
166             conn.setDoOutput(false);
167             conn.connect();
168             int contentLength = conn.getContentLength();
169             if (contentLength < 2048)
170                 contentLength = 2048;
171             sb = new StringBuffer(contentLength);
172 
173             // Parse the character encoding to be used
174             String contentType = conn.getContentType();
175             String encoding =
176                 WorkflowUtils.parseCharacterEncoding(contentType);
177 
178             // Construct a suitable InputStreamReader
179             is = conn.getInputStream();
180             bis = new BufferedInputStream(is, 2048);
181             if (encoding == null)
182                 isr = new InputStreamReader(bis);
183             else
184                 isr = new InputStreamReader(bis, encoding);
185 
186             // Copy all characters from this resource
187             while (true) {
188                 int ch = isr.read();
189                 if (ch < 0)
190                     break;
191                 sb.append((char) ch);
192             }
193 
194             // Close the input file
195             isr.close();
196             isr = null;
197             bis = null;
198             is = null;
199 
200         } catch (IOException e) {
201 
202             se = new StepException("IOException processing '" + remoteURL +
203                                    "'", e, this);
204 
205         } finally {
206 
207             if (isr != null) {
208                 try {
209                     isr.close();
210                 } catch (Throwable t) {
211                     ;
212                 }
213             } else if (bis != null) {
214                 try {
215                     bis.close();
216                 } catch (Throwable t) {
217                     ;
218                 }
219             } else if (is != null) {
220                 try {
221                     is.close();
222                 } catch (Throwable t) {
223                     ;
224                 }
225             }
226 
227         }
228 
229         // Push results or throw exception as appropriate
230         if (se != null)
231             throw se;
232         context.push(sb.toString());
233 
234     }
235 
236 
237 }