1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: UrlToFileMapper.java,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
30 package com
.sun
.star
.lib
.util
;
33 import java
.lang
.reflect
.Constructor
;
34 import java
.lang
.reflect
.InvocationTargetException
;
35 import java
.lang
.reflect
.Method
;
37 import java
.net
.URLDecoder
;
38 import java
.net
.URLEncoder
;
41 * Maps Java URL representations to File representations, on any Java version.
45 public final class UrlToFileMapper
{
47 // java.net.URLEncoder.encode(String, String) and java.net.URI are only
48 // available since Java 1.4:
49 private static Method urlEncoderEncode
;
50 private static Constructor uriConstructor
;
51 private static Constructor fileConstructor
;
54 urlEncoderEncode
= URLEncoder
.class.getMethod(
55 "encode", new Class
[] { String
.class, String
.class });
56 Class uriClass
= Class
.forName("java.net.URI");
57 uriConstructor
= uriClass
.getConstructor(
58 new Class
[] { String
.class });
59 fileConstructor
= File
.class.getConstructor(
60 new Class
[] { uriClass
});
61 } catch (ClassNotFoundException e
) {
62 } catch (NoSuchMethodException e
) {
67 * Maps Java URL representations to File representations.
69 * @param url some URL, possibly null.
70 * @return a corresponding File, or null on failure.
72 public static File
mapUrlToFile(URL url
) {
75 } else if (fileConstructor
== null) {
76 // If java.net.URI is not available, hope that the following works
77 // well: First, check that the given URL has a certain form.
78 // Second, use the URLDecoder to decode the URL path (taking care
79 // not to change any plus signs to spaces), hoping that the used
80 // default encoding is the proper one for file URLs. Third, create
81 // a File from the decoded path.
82 return url
.getProtocol().equalsIgnoreCase("file")
83 && url
.getAuthority() == null && url
.getQuery() == null
84 && url
.getRef() == null
85 ?
new File(URLDecoder
.decode(
86 StringHelper
.replace(url
.getPath(), '+', "%2B")))
89 // If java.net.URI is avaliable, do
90 // URI uri = new URI(encodedUrl);
92 // return new File(uri);
93 // } catch (IllegalArgumentException e) {
96 // where encodedUrl is url.toString(), but since that may contain
97 // unsafe characters (e.g., space, " "), it is encoded, as otherwise
98 // the URI constructor might throw java.net.URISyntaxException (in
99 // Java 1.5, URL.toURI might be used instead).
100 String encodedUrl
= encode(url
.toString());
102 Object uri
= uriConstructor
.newInstance(
103 new Object
[] { encodedUrl
});
105 return (File
) fileConstructor
.newInstance(
106 new Object
[] { uri
});
107 } catch (InvocationTargetException e
) {
108 if (e
.getTargetException() instanceof
109 IllegalArgumentException
) {
115 } catch (InstantiationException e
) {
116 throw new RuntimeException("This cannot happen: " + e
);
117 } catch (IllegalAccessException e
) {
118 throw new RuntimeException("This cannot happen: " + e
);
119 } catch (InvocationTargetException e
) {
120 if (e
.getTargetException() instanceof Error
) {
121 throw (Error
) e
.getTargetException();
122 } else if (e
.getTargetException() instanceof RuntimeException
) {
123 throw (RuntimeException
) e
.getTargetException();
125 throw new RuntimeException("This cannot happen: " + e
);
133 private static String
encode(String url
) {
134 StringBuffer buf
= new StringBuffer();
135 for (int i
= 0; i
< url
.length(); ++i
) {
136 char c
= url
.charAt(i
);
137 // The RFC 2732 <uric> characters: !$&'()*+,-./:;=?@[]_~ plus digits
138 // and letters; additionally, do not encode % again.
139 if (c
>= 'a' && c
<= 'z' || c
>= '?' && c
<= '['
140 || c
>= '$' && c
<= ';' || c
== '!' || c
== '=' || c
== ']'
141 || c
== '_' || c
== '~')
144 } else if (c
== ' ') {
149 enc
= (String
) urlEncoderEncode
.invoke(
151 new Object
[] { new Character(c
).toString(), "UTF-8" });
152 } catch (IllegalAccessException e
) {
153 throw new RuntimeException("This cannot happen: " + e
);
154 } catch (InvocationTargetException e
) {
155 throw new RuntimeException("This cannot happen: " + e
);
160 return buf
.toString();
163 private UrlToFileMapper() {}