KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > batik > util > ParsedURLData


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

18 package org.apache.batik.util;
19
20 import java.io.BufferedInputStream JavaDoc;
21 import java.io.IOException JavaDoc;
22 import java.io.InputStream JavaDoc;
23 import java.net.HttpURLConnection JavaDoc;
24 import java.net.MalformedURLException JavaDoc;
25 import java.net.URL JavaDoc;
26 import java.net.URLConnection JavaDoc;
27 import java.util.Iterator JavaDoc;
28 import java.util.LinkedList JavaDoc;
29 import java.util.List JavaDoc;
30 import java.util.zip.GZIPInputStream JavaDoc;
31 import java.util.zip.InflaterInputStream JavaDoc;
32 import java.util.zip.ZipException JavaDoc;
33
34 /**
35  * Holds the data for more URL's
36  *
37  * @author <a HREF="mailto:deweese@apache.org">Thomas DeWeese</a>
38  * @version $Id: ParsedURLData.java,v 1.16 2005/03/27 08:58:36 cam Exp $
39  */

40 public class ParsedURLData {
41     
42     String JavaDoc HTTP_USER_AGENT_HEADER = "User-Agent";
43
44     String JavaDoc HTTP_ACCEPT_HEADER = "Accept";
45     String JavaDoc HTTP_ACCEPT_LANGUAGE_HEADER = "Accept-Language";
46     String JavaDoc HTTP_ACCEPT_ENCODING_HEADER = "Accept-Encoding";
47
48     protected static List JavaDoc acceptedEncodings = new LinkedList JavaDoc();
49     static {
50         acceptedEncodings.add("gzip");
51     }
52
53     /**
54      * GZIP header magic number bytes, like found in a gzipped
55      * files, which are encoded in Intel format (i&#x2e;e&#x2e; little indian).
56      */

57     public final static byte GZIP_MAGIC[] = {(byte)0x1f, (byte)0x8b};
58
59     /**
60      * This is a utility function others can call that checks if
61      * is is a GZIP stream if so it returns a GZIPInputStream that
62      * will decode the contents, otherwise it returns (or a
63      * buffered version of is) untouched.
64      * @param is Stream that may potentially be a GZIP stream.
65      */

66     public static InputStream JavaDoc checkGZIP(InputStream JavaDoc is)
67         throws IOException JavaDoc {
68
69             if (!is.markSupported())
70                 is = new BufferedInputStream JavaDoc(is);
71             byte data[] = new byte[2];
72             try {
73                 is.mark(2);
74                 is.read(data);
75                 is.reset();
76             } catch (Exception JavaDoc ex) {
77                 is.reset();
78                 return is;
79             }
80         if ((data[0] == GZIP_MAGIC[0]) &&
81             (data[1] == GZIP_MAGIC[1]))
82             return new GZIPInputStream JavaDoc(is);
83
84         if (((data[0]&0x0F) == 8) &&
85             ((data[0]>>>4) <= 7)) {
86             // Check for a zlib (deflate) stream
87
int chk = ((((int)data[0])&0xFF)*256+
88                        (((int)data[1])&0xFF));
89             if ((chk %31) == 0) {
90                 try {
91                     // I'm not really as certain of this check
92
// as I would like so I want to force it
93
// to decode part of the stream.
94
is.mark(100);
95                     InputStream JavaDoc ret = new InflaterInputStream JavaDoc(is);
96                     if (!ret.markSupported())
97                         ret = new BufferedInputStream JavaDoc(ret);
98                     ret.mark(2);
99                     ret.read(data);
100                     is.reset();
101                     ret = new InflaterInputStream JavaDoc(is);
102                     return ret;
103                 } catch (ZipException JavaDoc ze) {
104                     is.reset();
105                     return is;
106                 }
107             }
108         }
109         
110         return is;
111     }
112
113     /**
114      * Since the Data instance is 'hidden' in the ParsedURL
115      * instance we make all our methods public. This makes it
116      * easy for the various Protocol Handlers to update an
117      * instance as parsing proceeds.
118      */

119     public String JavaDoc protocol = null;
120     public String JavaDoc host = null;
121     public int port = -1;
122     public String JavaDoc path = null;
123     public String JavaDoc ref = null;
124     public String JavaDoc contentType = null;
125     public String JavaDoc contentEncoding = null;
126
127     public InputStream JavaDoc stream = null;
128     public boolean hasBeenOpened = false;
129
130     /**
131      * Void constructor
132      */

133     public ParsedURLData() {
134     }
135
136     /**
137      * Build from an existing URL.
138      */

139     public ParsedURLData(URL JavaDoc url) {
140         protocol = url.getProtocol();
141         if ((protocol != null) && (protocol.length() == 0))
142             protocol = null;
143
144         host = url.getHost();
145         if ((host != null) && (host.length() == 0))
146             host = null;
147
148         port = url.getPort();
149
150         path = url.getFile();
151         if ((path != null) && (path.length() == 0))
152             path = null;
153
154         ref = url.getRef();
155         if ((ref != null) && (ref.length() == 0))
156             ref = null;
157     }
158
159     /**
160      * Attempts to build a normal java.net.URL instance from this
161      * URL.
162      */

163     protected URL JavaDoc buildURL() throws MalformedURLException JavaDoc {
164
165         // System.out.println("File: " + file);
166
// if (ref != null)
167
// file += "#" + ref;
168
// System.err.println("Building: " + protocol + " - " +
169
// host + " - " + path);
170

171         if ((protocol != null) && (host != null)) {
172             String JavaDoc file = "";
173             if (path != null)
174                 file = path;
175             if (port == -1)
176                 return new URL JavaDoc(protocol, host, file);
177
178             return new URL JavaDoc(protocol, host, port, file);
179         }
180
181         // System.err.println("toString: " + toString());
182
return new URL JavaDoc(toString());
183     }
184
185     /**
186      * Implement Object.hashCode.
187      */

188     public int hashCode() {
189         int hc = port;
190         if (protocol != null)
191             hc ^= protocol.hashCode();
192         if (host != null)
193             hc ^= host.hashCode();
194
195         // For some URLS path and ref can get fairly long
196
// and the most unique part is towards the end
197
// so we grab that part for HC purposes
198
if (path != null) {
199             int len = path.length();
200             if (len > 20)
201                 hc ^= path.substring(len-20).hashCode();
202             else
203                 hc ^= path.hashCode();
204         }
205         if (ref != null) {
206             int len = ref.length();
207             if (len > 20)
208                 hc ^= ref.substring(len-20).hashCode();
209             else
210                 hc ^= ref.hashCode();
211         }
212
213         return hc;
214     }
215
216     /**
217      * Implement Object.equals for ParsedURLData.
218      */

219     public boolean equals(Object JavaDoc obj) {
220         if (obj == null) return false;
221         if (! (obj instanceof ParsedURLData))
222             return false;
223
224         ParsedURLData ud = (ParsedURLData)obj;
225         if (ud.port != port)
226             return false;
227             
228         if (ud.protocol==null) {
229             if (protocol != null)
230                 return false;
231         } else if (protocol == null)
232             return false;
233         else if (!ud.protocol.equals(protocol))
234             return false;
235
236         if (ud.host==null) {
237             if (host !=null)
238                 return false;
239         } else if (host == null)
240             return false;
241         else if (!ud.host.equals(host))
242             return false;
243
244         if (ud.ref==null) {
245             if (ref !=null)
246                 return false;
247         } else if (ref == null)
248             return false;
249         else if (!ud.ref.equals(ref))
250             return false;
251
252         if (ud.path==null) {
253             if (path !=null)
254                 return false;
255         } else if (path == null)
256             return false;
257         else if (!ud.path.equals(path))
258             return false;
259
260         return true;
261     }
262
263     /**
264      * Returns the content type if available. This is only available
265      * for some protocols.
266      */

267     public String JavaDoc getContentType(String JavaDoc userAgent) {
268         if (contentType != null)
269             return contentType;
270
271         if (!hasBeenOpened) {
272             try {
273                 openStreamInternal(userAgent, null, null);
274             } catch (IOException JavaDoc ioe) { /* nothing */ }
275         }
276
277         return contentType;
278     }
279
280     /**
281      * Returns the content encoding if available. This is only available
282      * for some protocols.
283      */

284     public String JavaDoc getContentEncoding(String JavaDoc userAgent) {
285         if (contentEncoding != null)
286             return contentEncoding;
287
288         if (!hasBeenOpened) {
289             try {
290                 openStreamInternal(userAgent, null, null);
291             } catch (IOException JavaDoc ioe) { /* nothing */ }
292         }
293
294         return contentEncoding;
295     }
296
297     /**
298      * Returns true if the URL looks well formed and complete.
299      * This does not garuntee that the stream can be opened but
300      * is a good indication that things aren't totally messed up.
301      */

302     public boolean complete() {
303         try {
304             buildURL();
305         } catch (MalformedURLException JavaDoc mue) {
306             return false;
307         }
308         return true;
309     }
310
311     /**
312      * Open the stream and check for common compression types. If
313      * the stream is found to be compressed with a standard
314      * compression type it is automatically decompressed.
315      * @param userAgent The user agent opening the stream (may be null).
316      * @param mimeTypes The expected mime types of the content
317      * in the returned InputStream (mapped to Http accept
318      * header among other possability). The elements of
319      * the iterator must be strings (may be null)
320      */

321     public InputStream JavaDoc openStream(String JavaDoc userAgent, Iterator JavaDoc mimeTypes)
322         throws IOException JavaDoc {
323         InputStream JavaDoc raw = openStreamInternal(userAgent, mimeTypes,
324                                              acceptedEncodings.iterator());
325         if (raw == null)
326             return null;
327         stream = null;
328                 
329         return checkGZIP(raw);
330     }
331
332     /**
333      * Open the stream and returns it. No checks are made to see
334      * if the stream is compressed or encoded in any way.
335      * @param userAgent The user agent opening the stream (may be null).
336      * @param mimeTypes The expected mime types of the content
337      * in the returned InputStream (mapped to Http accept
338      * header among other possability). The elements of
339      * the iterator must be strings (may be null)
340      */

341     public InputStream JavaDoc openStreamRaw(String JavaDoc userAgent, Iterator JavaDoc mimeTypes)
342         throws IOException JavaDoc {
343         
344         InputStream JavaDoc ret = openStreamInternal(userAgent, mimeTypes, null);
345         stream = null;
346         return ret;
347     }
348
349     protected InputStream JavaDoc openStreamInternal(String JavaDoc userAgent,
350                                              Iterator JavaDoc mimeTypes,
351                                              Iterator JavaDoc encodingTypes)
352         throws IOException JavaDoc {
353         if (stream != null)
354             return stream;
355         
356         hasBeenOpened = true;
357
358         URL JavaDoc url = null;
359         try {
360             url = buildURL();
361         } catch (MalformedURLException JavaDoc mue) {
362             throw new IOException JavaDoc
363                 ("Unable to make sense of URL for connection");
364         }
365
366         if (url == null)
367             return null;
368
369         URLConnection JavaDoc urlC = url.openConnection();
370         if (urlC instanceof HttpURLConnection JavaDoc) {
371             if (userAgent != null)
372                 urlC.setRequestProperty(HTTP_USER_AGENT_HEADER, userAgent);
373
374             if (mimeTypes != null) {
375                 String JavaDoc acceptHeader = "";
376                 while (mimeTypes.hasNext()) {
377                     acceptHeader += mimeTypes.next();
378                     if (mimeTypes.hasNext())
379                         acceptHeader += ",";
380                 }
381                 urlC.setRequestProperty(HTTP_ACCEPT_HEADER, acceptHeader);
382             }
383
384             if (encodingTypes != null) {
385                 String JavaDoc encodingHeader = "";
386                 while (encodingTypes.hasNext()) {
387                     encodingHeader += encodingTypes.next();
388                     if (encodingTypes.hasNext())
389                         encodingHeader += ",";
390                 }
391                 urlC.setRequestProperty(HTTP_ACCEPT_ENCODING_HEADER,
392                                         encodingHeader);
393             }
394
395             contentType = urlC.getContentType();
396             contentEncoding = urlC.getContentEncoding();
397         }
398
399         return (stream = urlC.getInputStream());
400     }
401
402     /**
403      * Returns the URL up to and include the port number on
404      * the host. Does not include the path or fragment pieces.
405      */

406     public String JavaDoc getPortStr() {
407         String JavaDoc portStr ="";
408         if (protocol != null)
409             portStr += protocol + ":";
410
411         if ((host != null) || (port != -1)) {
412             portStr += "//";
413             if (host != null) portStr += host;
414             if (port != -1) portStr += ":" + port;
415         }
416
417         return portStr;
418     }
419
420     protected boolean sameFile(ParsedURLData other) {
421         if (this == other) return true;
422
423         // Check if the rest of the two PURLs matche other than
424
// the 'ref'
425
if ((port == other.port) &&
426             ((path == other.path)
427              || ((path!=null) && path.equals(other.path))) &&
428             ((host == other.host)
429              || ((host!=null) && host.equals(other.host))) &&
430             ((protocol == other.protocol)
431              || ((protocol!=null) && protocol.equals(other.protocol))))
432             return true;
433
434         return false;
435     }
436
437
438     /**
439      * Return a string representation of the data.
440      */

441     public String JavaDoc toString() {
442         String JavaDoc ret = getPortStr();
443         if (path != null)
444             ret += path;
445
446         if (ref != null)
447             ret += "#" + ref;
448
449         return ret;
450     }
451 }
452
453
Popular Tags