Update ooo320-m1
[ooovba.git] / jurt / com / sun / star / lib / util / UrlToFileMapper.java
blobc1448184ee06ee2a985ec245f3d36e7474354cb6
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: UrlToFileMapper.java,v $
10 * $Revision: 1.5 $
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;
32 import java.io.File;
33 import java.lang.reflect.Constructor;
34 import java.lang.reflect.InvocationTargetException;
35 import java.lang.reflect.Method;
36 import java.net.URL;
37 import java.net.URLDecoder;
38 import java.net.URLEncoder;
40 /**
41 * Maps Java URL representations to File representations, on any Java version.
43 * @since UDK 3.2.8
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;
52 static {
53 try {
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) {
66 /**
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) {
73 if (url == null) {
74 return null;
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")))
87 : null;
88 } else {
89 // If java.net.URI is avaliable, do
90 // URI uri = new URI(encodedUrl);
91 // try {
92 // return new File(uri);
93 // } catch (IllegalArgumentException e) {
94 // return null;
95 // }
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());
101 try {
102 Object uri = uriConstructor.newInstance(
103 new Object[] { encodedUrl });
104 try {
105 return (File) fileConstructor.newInstance(
106 new Object[] { uri });
107 } catch (InvocationTargetException e) {
108 if (e.getTargetException() instanceof
109 IllegalArgumentException) {
110 return null;
111 } else {
112 throw e;
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();
124 } else {
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 == '~')
143 buf.append(c);
144 } else if (c == ' ') {
145 buf.append("%20");
146 } else {
147 String enc;
148 try {
149 enc = (String) urlEncoderEncode.invoke(
150 null,
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);
157 buf.append(enc);
160 return buf.toString();
163 private UrlToFileMapper() {}