1
2
3
4
5 package org.rcfaces.core.internal.util;
6
7 import java.io.IOException;
8 import java.io.InputStream;
9 import java.net.MalformedURLException;
10 import java.net.URL;
11 import java.net.URLConnection;
12 import java.util.Locale;
13
14 import org.apache.commons.logging.Log;
15 import org.apache.commons.logging.LogFactory;
16 import org.rcfaces.core.internal.repository.AbstractRepository.AbstractContent;
17 import org.rcfaces.core.internal.repository.IRepository.IContent;
18 import org.rcfaces.core.internal.repository.IRepository.IContentProvider;
19
20
21
22
23
24
25 public class URLContentProvider implements IContentProvider {
26 private static final String REVISION = "$Revision: 1.6 $";
27
28 private static final Log LOG = LogFactory.getLog(URLContentProvider.class);
29
30 public static final IContentProvider SINGLETON = new URLContentProvider();
31
32 protected URLContentProvider() {
33 }
34
35 public IContent getContent(Object contentReference, Locale locale) {
36 return new URLContent((URL) contentReference, locale);
37 }
38
39 public Object searchLocalizedContentReference(Object contentReference,
40 Locale locale) {
41
42 String localized = contentReference.toString();
43
44 int idx0 = localized.lastIndexOf('.');
45 if (idx0 <= 0) {
46 return null;
47 }
48
49 String variant = locale.getVariant();
50 String country = locale.getCountry();
51 String language = locale.getLanguage();
52
53 String suffix = "";
54 String baseURL = localized;
55 if (localized.lastIndexOf('/') < idx0) {
56 baseURL = localized.substring(0, idx0);
57 suffix = localized.substring(idx0);
58 }
59
60 if (language.length() > 0) {
61 int idx2 = baseURL.lastIndexOf('/');
62
63 baseURL = baseURL.substring(0, idx2) + '/' + language
64 + baseURL.substring(idx2);
65 }
66
67 if (LOG.isTraceEnabled()) {
68 LOG.trace("searchLocalizedContentReference ref='"
69 + contentReference + "' locale='" + locale
70 + "' => baseURL=" + baseURL);
71 }
72
73 try {
74 if (variant != null && variant.length() > 0) {
75 URL l = new URL(baseURL + "_" + language + "_" + country + "_"
76 + variant + suffix);
77
78 Locale tryLocale = locale;
79 if (testURL(l, tryLocale)) {
80 if (LOG.isDebugEnabled()) {
81 LOG.debug("Localized version '" + locale
82 + "' found for url '" + localized + "' => "
83 + tryLocale);
84 }
85
86 return l;
87 }
88 }
89
90 if (country != null && country.length() > 0) {
91 URL l = new URL(baseURL + "_" + language + "_" + country
92 + suffix);
93
94 Locale tryLocale = locale;
95 if (variant != null && variant.length() > 0) {
96 tryLocale = new Locale(language, country);
97 }
98
99 if (testURL(l, tryLocale)) {
100 if (LOG.isDebugEnabled()) {
101 LOG.debug("Localized version '" + locale
102 + "' found for url '" + localized + "' => "
103 + tryLocale);
104 }
105
106 return l;
107 }
108 }
109
110 if (language != null && language.length() > 0) {
111 URL l = new URL(baseURL + "_" + language + suffix);
112
113 Locale tryLocale = locale;
114 if ((country != null && country.length() > 0)
115 || (variant != null && variant.length() > 0)) {
116 tryLocale = new Locale(language);
117 }
118
119 if (testURL(l, tryLocale)) {
120 if (LOG.isDebugEnabled()) {
121 LOG.debug("Localized version '" + locale
122 + "' found for url '" + localized + "' => "
123 + tryLocale);
124 }
125
126 return l;
127 }
128 }
129 } catch (MalformedURLException ex) {
130 LOG.error("Can not search localized url of uri '" + localized
131 + "' for locale '" + locale + "'.", ex);
132
133 return null;
134 }
135
136 if (LOG.isDebugEnabled()) {
137 LOG.debug("Localized version '" + locale + "' not found for url '"
138 + localized + "'.");
139 }
140
141 return null;
142 }
143
144 private boolean testURL(URL contentReference, Locale locale) {
145 IContent content = getContent(contentReference, locale);
146
147 if (LOG.isTraceEnabled()) {
148 LOG.trace("TestURL '" + contentReference + "' locale='" + locale
149 + "'");
150 }
151
152 InputStream inputStream;
153 try {
154 inputStream = content.getInputStream();
155
156 } catch (IOException ex) {
157 if (LOG.isDebugEnabled()) {
158 LOG
159 .debug("URL '" + contentReference
160 + "' does not exist !", ex);
161 }
162 return false;
163 }
164
165 if (inputStream == null) {
166 if (LOG.isTraceEnabled()) {
167 LOG.trace("TestURL '" + contentReference + "' locale='"
168 + locale + "' => NOT FOUND");
169 }
170
171 return false;
172 }
173
174 try {
175 inputStream.close();
176
177 } catch (IOException ex) {
178 LOG.info("Can not close URL '" + contentReference + "'.", ex);
179 }
180
181 if (LOG.isTraceEnabled()) {
182 LOG.trace("TestURL '" + contentReference + "' locale='" + locale
183 + "' => FOUND");
184 }
185
186 return true;
187 }
188
189
190
191
192
193
194 protected static class URLContent extends AbstractContent {
195 private static final String REVISION = "$Revision: 1.6 $";
196
197 protected final URL url;
198
199 protected final Locale locale;
200
201 private URLConnection urlConnection;
202
203 private boolean opened;
204
205 public URLContent(URL url, Locale locale) {
206 this.url = url;
207 this.locale = locale;
208 }
209
210 public InputStream getInputStream() throws IOException {
211 return getInputStream(false);
212 }
213
214 protected InputStream getInputStream(boolean toClose)
215 throws IOException {
216 if (opened) {
217 throw new IOException("Already opened !");
218 }
219 opened = true;
220
221 return openInputStream(toClose);
222 }
223
224 protected InputStream openInputStream(boolean toClose)
225 throws IOException {
226 return getURLConnection().getInputStream();
227 }
228
229 protected URLConnection getURLConnection() throws IOException {
230 if (urlConnection != null) {
231 return urlConnection;
232 }
233
234 urlConnection = url.openConnection();
235
236 return urlConnection;
237 }
238
239 public long getLastModified() throws IOException {
240 URLConnection urlConnection = getURLConnection();
241
242 return urlConnection.getLastModified();
243 }
244
245 public long getLength() throws IOException {
246 URLConnection urlConnection = getURLConnection();
247
248 return urlConnection.getContentLength();
249 }
250
251 public void release() {
252 if (urlConnection == null || opened) {
253 return;
254 }
255
256 try {
257 InputStream in = getInputStream(true);
258 if (in != null) {
259 in.close();
260 }
261 } catch (IOException ex) {
262 }
263
264 urlConnection = null;
265 }
266 }
267 }