001 /* 002 * Copyright 1999-2001,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.commons.workflow.io; 018 019 020 import java.io.BufferedInputStream; 021 import java.io.InputStream; 022 import java.io.InputStreamReader; 023 import java.io.IOException; 024 import java.net.MalformedURLException; 025 import java.net.URL; 026 import java.net.URLConnection; 027 import java.util.EmptyStackException; 028 import org.apache.commons.workflow.Context; 029 import org.apache.commons.workflow.StepException; 030 import org.apache.commons.workflow.base.BaseStep; 031 import org.apache.commons.workflow.util.WorkflowUtils; 032 033 034 /** 035 * <p>Retrieve the contents of a specified URL resource, and push the 036 * contents as a String object onto the evaluation stack.</p> 037 * 038 * <p>Supported Attributes:</p> 039 * <ul> 040 * <li><strong>url</strong> - URL of the resource to be retrieved, or 041 * omitted to pop a computed String value from the top of the 042 * evaluation stack.</li> 043 * </ul> 044 * 045 * <strong>DESIGN QUESTION - What about binary content?</strong> 046 * 047 * @version $Revision: 155475 $ $Date: 2005-02-26 13:31:11 +0000 (Sat, 26 Feb 2005) $ 048 * @author Craig R. McClanahan 049 */ 050 051 public class GetStep extends BaseStep { 052 053 054 // ----------------------------------------------------------= Constructors 055 056 057 /** 058 * Construct a default instance of this Step. 059 */ 060 public GetStep() { 061 062 super(); 063 064 } 065 066 067 /** 068 * Construct an instance of this Step with the specified identifier. 069 * 070 * @param id Step identifier 071 */ 072 public GetStep(String id) { 073 074 super(); 075 setId(id); 076 077 } 078 079 080 /** 081 * Construct a fully configured instance of this Step. 082 * 083 * @param id Step identifier 084 * @param url Resource url 085 */ 086 public GetStep(String id, String url) { 087 088 super(); 089 setId(id); 090 setUrl(url); 091 092 } 093 094 095 // ------------------------------------------------------------- Properties 096 097 098 /** 099 * 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 }