View Javadoc

1   /*
2    * $Id: URLContentProvider.java,v 1.6 2010/01/27 14:55:37 oeuillot Exp $
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   * @author Olivier Oeuillot (latest modification by $Author: oeuillot $)
23   * @version $Revision: 1.6 $ $Date: 2010/01/27 14:55:37 $
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      * @author Olivier Oeuillot (latest modification by $Author: oeuillot $)
192      * @version $Revision: 1.6 $ $Date: 2010/01/27 14:55:37 $
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 }