KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > excalibur > source > impl > URLSource


1 /*
2  * Copyright 2002-2004 The Apache Software Foundation
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
12  * implied.
13  *
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */

17 package org.apache.excalibur.source.impl;
18
19 import java.io.IOException JavaDoc;
20 import java.io.InputStream JavaDoc;
21 import java.io.UnsupportedEncodingException JavaDoc;
22 import java.net.HttpURLConnection JavaDoc;
23 import java.net.URL JavaDoc;
24 import java.net.URLConnection JavaDoc;
25 import java.net.URLDecoder JavaDoc;
26 import java.util.Iterator JavaDoc;
27 import java.util.Map JavaDoc;
28
29 import org.apache.excalibur.source.Source;
30 import org.apache.excalibur.source.SourceException;
31 import org.apache.excalibur.source.SourceParameters;
32 import org.apache.excalibur.source.SourceResolver;
33 import org.apache.excalibur.source.SourceUtil;
34 import org.apache.excalibur.source.SourceValidity;
35 import org.apache.excalibur.source.impl.validity.TimeStampValidity;
36
37 /**
38  * Description of a source which is described by an URL.
39  *
40  * @author <a HREF="mailto:dev@avalon.apache.org">Avalon Development Team</a>
41  * @version CVS $Revision: 1.5 $ $Date: 2004/02/28 11:47:24 $
42  */

43 public class URLSource extends AbstractSource implements Source
44 {
45
46     /** The URL of the source */
47     protected URL JavaDoc m_url;
48
49     /** The connection for a real URL */
50     protected URLConnection JavaDoc m_connection;
51
52     /** The <code>SourceParameters</code> used for a post*/
53     protected SourceParameters m_parameters;
54
55     /** The encoding of the <code>SourceParameters</code>*/
56     protected String JavaDoc m_encoding;
57
58     /** Is this a post? */
59     protected boolean m_isPost = false;
60
61     /** Does this source exist ? */
62     protected boolean m_exists = false;
63
64     /** the prev returned SourceValidity */
65     protected SourceValidity m_cachedValidity;
66
67     protected long m_cachedLastModificationDate;
68
69     /** The content type (if known) */
70     protected String JavaDoc m_mimeType;
71
72     /**
73      * Constructor
74      */

75     public URLSource()
76     {
77     }
78
79     /**
80      * Initialize a new object from a <code>URL</code>.
81      * @param parameters This is optional
82      */

83     public void init(URL JavaDoc url, Map JavaDoc parameters) throws IOException JavaDoc
84     {
85         String JavaDoc systemId = url.toExternalForm();
86         setSystemId(systemId);
87         setScheme(SourceUtil.getScheme(systemId));
88
89         m_url = url;
90         m_isPost = false;
91         // get the default system encoding in case no encoding is specified
92
m_encoding = System.getProperties().getProperty("file.property", "ISO-8859-1");
93
94         if (null != parameters)
95         {
96             m_parameters = (SourceParameters) parameters.get(SourceResolver.URI_PARAMETERS);
97             final String JavaDoc method = (String JavaDoc) parameters.get(SourceResolver.METHOD);
98             
99             if ("POST".equalsIgnoreCase(method))
100                 m_isPost = true;
101
102             final String JavaDoc encoding = (String JavaDoc) parameters.get(SourceResolver.URI_ENCODING);
103             if (encoding != null && !"".equals(encoding))
104                 m_encoding = encoding;
105         }
106         
107         if (null != m_parameters && m_parameters.hasParameters() && !m_isPost)
108         {
109             StringBuffer JavaDoc urlBuffer = new StringBuffer JavaDoc(systemId);
110             String JavaDoc key;
111             final Iterator JavaDoc i = m_parameters.getParameterNames();
112             Iterator JavaDoc values;
113             String JavaDoc value;
114             boolean first = (systemId.indexOf('?') == -1);
115             if (first == true)
116                 urlBuffer.append('?');
117             while (i.hasNext())
118             {
119                 key = (String JavaDoc) i.next();
120                 values = m_parameters.getParameterValues(key);
121                 while (values.hasNext() == true)
122                 {
123                     value = SourceUtil.encode((String JavaDoc) values.next(), m_encoding);
124                     if (first == false)
125                         urlBuffer.append('&');
126                     first = false;
127                     urlBuffer.append(key);
128                     urlBuffer.append('=');
129                     urlBuffer.append(value);
130                 }
131             }
132
133             m_url = new URL JavaDoc(urlBuffer.toString());
134             m_parameters = null;
135         }
136     }
137
138     /**
139      * Get the last modification date and content length of the source.
140      * Any exceptions are ignored.
141      * Override this to get the real information
142      */

143     protected void getInfos()
144     {
145         // exists will be set below depending on the m_url type
146
m_exists = false;
147
148         if (!m_isPost)
149         {
150             try
151             {
152                 if (null == m_connection)
153                 {
154                     m_connection = m_url.openConnection();
155                     String JavaDoc userInfo = getUserInfo();
156                     if (m_url.getProtocol().startsWith("http") && userInfo != null){
157                         m_connection.setRequestProperty("Authorization", "Basic " + SourceUtil.encodeBASE64(userInfo));
158                     }
159                 }
160                 setLastModified(m_connection.getLastModified());
161                 setContentLength(m_connection.getContentLength());
162                 m_mimeType = m_connection.getContentType();
163                 m_exists = true;
164             }
165             catch (IOException JavaDoc ignore)
166             {
167                 super.getInfos();
168             }
169         }
170         else
171         {
172             // do not open m_connection when using post!
173
super.getInfos();
174         }
175     }
176
177     /**
178      * Does this source exist ?
179      */

180     public boolean exists()
181     {
182         checkInfos();
183         return m_exists;
184     }
185
186     /**
187      * Return an <code>InputStream</code> object to read from the source.
188      *
189      * @throws SourceException if file not found or
190      * HTTP location does not exist.
191      * @throws IOException if I/O error occured.
192      */

193     public InputStream JavaDoc getInputStream() throws IOException JavaDoc, SourceException
194     {
195         checkInfos();
196         InputStream JavaDoc input = null;
197         if (m_connection == null)
198         {
199             m_connection = m_url.openConnection();
200
201             String JavaDoc userInfo = getUserInfo();
202             if (m_url.getProtocol().startsWith("http") && userInfo != null)
203             {
204                 m_connection.setRequestProperty("Authorization", "Basic " + SourceUtil.encodeBASE64(userInfo));
205             }
206
207             // do a post operation
208
if (m_connection instanceof HttpURLConnection JavaDoc && m_isPost)
209             {
210                 StringBuffer JavaDoc buffer = new StringBuffer JavaDoc(2000);
211                 String JavaDoc key;
212                 Iterator JavaDoc i = m_parameters.getParameterNames();
213                 Iterator JavaDoc values;
214                 String JavaDoc value;
215                 boolean first = true;
216                 while (i.hasNext())
217                 {
218                     key = (String JavaDoc) i.next();
219                     values = m_parameters.getParameterValues(key);
220                     while (values.hasNext() == true)
221                     {
222                         value = SourceUtil.encode((String JavaDoc) values.next(), m_encoding);
223                         if (first == false)
224                             buffer.append('&');
225                         first = false;
226                         buffer.append(key.toString());
227                         buffer.append('=');
228                         buffer.append(value);
229                     }
230                 }
231                 HttpURLConnection JavaDoc httpCon = (HttpURLConnection JavaDoc) m_connection;
232                 httpCon.setDoInput(true);
233
234                 if (buffer.length() > 1)
235                 { // only post if we have parameters
236
String JavaDoc postString = buffer.toString();
237                     httpCon.setRequestMethod("POST"); // this is POST
238
httpCon.setDoOutput(true);
239                     httpCon.setRequestProperty("Content-type", "application/x-www-form-urlencoded");
240
241                     // A content-length header must be contained in a POST request
242
httpCon.setRequestProperty("Content-length", Integer.toString(postString.length()));
243                     java.io.OutputStream JavaDoc out = new java.io.BufferedOutputStream JavaDoc(httpCon.getOutputStream());
244                     out.write(postString.getBytes());
245                     out.close();
246                 }
247                 input = httpCon.getInputStream();
248                 m_connection = null; // make sure a new m_connection is created next time
249
return input;
250             }
251         }
252         input = m_connection.getInputStream();
253         m_connection = null; // make sure a new m_connection is created next time
254
return input;
255     }
256
257     /**
258      * Get the Validity object. This can either wrap the last modification
259      * date or the expires information or...
260      * If it is currently not possible to calculate such an information
261      * <code>null</code> is returned.
262      */

263     public SourceValidity getValidity()
264     {
265         final long lm = getLastModified();
266         if (lm > 0)
267         {
268             if (lm == m_cachedLastModificationDate)
269                 return m_cachedValidity;
270
271             m_cachedLastModificationDate = lm;
272             m_cachedValidity = new TimeStampValidity(lm);
273             return m_cachedValidity;
274         }
275         return null;
276     }
277
278     /**
279      * Refresh this object and update the last modified date
280      * and content length.
281      */

282     public void refresh()
283     {
284         // reset m_connection
285
m_connection = null;
286         super.refresh();
287     }
288
289     /**
290      * The mime-type of the content described by this object.
291      * If the source is not able to determine the mime-type by itself
292      * this can be null.
293      */

294     public String JavaDoc getMimeType()
295     {
296         return m_mimeType;
297     }
298     
299     /**
300      * The decoded userinfo for this source.
301      * null, if no userinfo exists
302      */

303     protected String JavaDoc getUserInfo()
304     {
305         if (m_url == null) return null;
306         String JavaDoc ui = m_url.getUserInfo();
307         if (ui == null) return null;
308     
309         try
310         {
311             ui = URLDecoder.decode(ui,"UTF-8");
312         }
313         catch (UnsupportedEncodingException JavaDoc e)
314         {
315             // Platform does not support UTF-8. This should never happen.
316
// e.printStackTrace();
317
}
318         return ui;
319     }
320 }
321
Popular Tags