View Javadoc

1   /*
2    * $Id: AbstractRepository.java,v 1.2 2008/12/09 16:37:13 oeuillot Exp $
3    */
4   package org.rcfaces.core.internal.repository;
5   
6   import java.io.IOException;
7   import java.util.Arrays;
8   import java.util.HashMap;
9   import java.util.HashSet;
10  import java.util.Iterator;
11  import java.util.Locale;
12  import java.util.Map;
13  import java.util.Set;
14  
15  import org.apache.commons.logging.Log;
16  import org.apache.commons.logging.LogFactory;
17  import org.rcfaces.core.internal.Constants;
18  import org.rcfaces.core.internal.webapp.URIParameters;
19  
20  /**
21   * 
22   * @author Olivier Oeuillot (latest modification by $Author: oeuillot $)
23   * @version $Revision: 1.2 $ $Date: 2008/12/09 16:37:13 $
24   */
25  public abstract class AbstractRepository implements IRepository {
26  
27      private static final String REVISION = "$Revision: 1.2 $";
28  
29      private static final long serialVersionUID = -3328226384749670660L;
30  
31      private static final Log LOG = LogFactory.getLog(AbstractRepository.class);
32  
33      protected static final IFile[] FILE_EMPTY_ARRAY = new IFile[0];
34  
35      private static final Object[] OBJECT_EMPTY_ARRAY = new Object[0];
36  
37      protected final Map filesByName = new HashMap();
38  
39      protected final Map filesByURI = new HashMap();
40  
41      protected final String repositoryVersion;
42  
43      protected final String servletURI;
44  
45      public AbstractRepository(String servletURI, String repositoryVersion) {
46          if (servletURI.length() > 0) {
47              if (servletURI.endsWith("/") && servletURI.length() > 1) {
48                  servletURI = servletURI.substring(0, servletURI.length() - 1);
49  
50              } else if (servletURI.startsWith("/") == false) {
51                  servletURI = "/" + servletURI;
52              }
53          }
54  
55          this.servletURI = servletURI;
56          this.repositoryVersion = repositoryVersion;
57      }
58  
59      public final String getVersion() {
60          return repositoryVersion;
61      }
62  
63      public IFile getFileByURI(String uri) {
64          return (IFile) filesByURI.get(uri);
65      }
66  
67      public IFile getFileByName(String name) {
68          return (IFile) filesByName.get(name);
69      }
70  
71      public IContext createContext(Locale locale) {
72          return new ContextImpl(locale);
73      }
74  
75      protected abstract IContentProvider getDefaultContentProvider();
76  
77      /**
78       * 
79       * @author Olivier Oeuillot (latest modification by $Author: oeuillot $)
80       * @version $Revision: 1.2 $ $Date: 2008/12/09 16:37:13 $
81       */
82      protected static class ContextImpl implements IContext {
83          private static final String REVISION = "$Revision: 1.2 $";
84  
85          private final Set files = new HashSet(32);
86  
87          private final Locale locale;
88  
89          public ContextImpl(Locale locale) {
90              this.locale = locale;
91          }
92  
93          public Locale getLocale() {
94              return locale;
95          }
96  
97          public boolean contains(IFile file) {
98              return files.contains(file);
99          }
100 
101         public boolean add(IFile file) {
102             return files.add(file);
103         }
104 
105         public IContext copy() {
106             ContextImpl ctx = new ContextImpl(locale);
107             ctx.files.addAll(files);
108 
109             return ctx;
110         }
111 
112         public void restoreState(IRepository repository, Object state) {
113             if (state == null) {
114                 return;
115             }
116 
117             Object fs[] = (Object[]) state;
118             for (int i = 0; i < fs.length; i++) {
119                 IFile file = ((BasicHierarchicalRepository) repository)
120                         .getFileById((String) fs[i]);
121 
122                 if (file == null) {
123                     continue;
124                 }
125 
126                 add(file);
127             }
128         }
129 
130         public Object saveState() {
131             if (files.isEmpty()) {
132                 return null;
133             }
134 
135             Iterator it = files.iterator();
136             Object ret[] = new Object[files.size()];
137             for (int i = 0; it.hasNext();) {
138                 IFile file = (IFile) it.next();
139 
140                 ret[i++] = ((File) file).getId();
141             }
142 
143             return ret;
144         }
145     }
146 
147     protected Locale adaptLocale(Locale locale, IFile file) {
148         return locale;
149     }
150 
151     /**
152      * 
153      * @author Olivier Oeuillot (latest modification by $Author: oeuillot $)
154      * @version $Revision: 1.2 $ $Date: 2008/12/09 16:37:13 $
155      */
156     protected class File implements IFile {
157 
158         private static final String REVISION = "$Revision: 1.2 $";
159 
160         private static final long serialVersionUID = -8396517787887070898L;
161 
162         private final String id;
163 
164         private final String filename;
165 
166         private final Object unlocalizedContentLocation;
167 
168         private final String unlocalizedURI;
169 
170         private final IContentProvider contentProvider;
171 
172         private final int hashCode;
173 
174         private LocalizedFile unlocalizedFile;
175 
176         private Map localizedFiles;
177 
178         public File(String name, String filename, String unlocalizedURI,
179                 Object unlocalizedContentLocation,
180                 IContentProvider contentProvider) {
181             this.id = name;
182             this.filename = filename;
183             this.unlocalizedURI = unlocalizedURI;
184             this.unlocalizedContentLocation = unlocalizedContentLocation;
185             this.contentProvider = contentProvider;
186             this.hashCode = filename.hashCode();
187         }
188 
189         public IRepository getRepository() {
190             return AbstractRepository.this;
191         }
192 
193         public final String getId() {
194             return id;
195         }
196 
197         public Object[] getContentReferences(Locale locale) {
198             LocalizedFile localizedFile = getLocalizedFile(locale);
199 
200             return localizedFile.getContentLocations();
201         }
202 
203         public String getFilename() {
204             return filename;
205         }
206 
207         public IContentProvider getContentProvider() {
208             if (contentProvider != null) {
209                 return contentProvider;
210             }
211 
212             return computeContentProvider();
213         }
214 
215         protected IContentProvider computeContentProvider() {
216             return getDefaultContentProvider();
217         }
218 
219         public String getURI(Locale locale) {
220             LocalizedFile localizedFile = getLocalizedFile(locale);
221 
222             return localizedFile.getURI();
223         }
224 
225         protected synchronized LocalizedFile getLocalizedFile(Locale locale) {
226             if (locale == null) {
227                 if (unlocalizedFile != null) {
228                     return unlocalizedFile;
229                 }
230 
231                 unlocalizedFile = new LocalizedFile(getContentProvider(), null,
232                         unlocalizedURI, unlocalizedContentLocation);
233                 return unlocalizedFile;
234             }
235 
236             locale = adaptLocale(locale, this);
237 
238             if (localizedFiles == null) {
239                 localizedFiles = new HashMap(4);
240             }
241 
242             LocalizedFile localizedFile = (LocalizedFile) localizedFiles
243                     .get(locale);
244             if (localizedFile != null) {
245                 return localizedFile;
246             }
247 
248             localizedFile = new LocalizedFile(getContentProvider(), locale,
249                     unlocalizedURI, unlocalizedContentLocation);
250             localizedFiles.put(locale, localizedFile);
251 
252             return localizedFile;
253         }
254 
255         public boolean equals(Object obj) {
256             if (obj == this) {
257                 return true;
258             }
259             if (obj == null || (obj instanceof File) == false) {
260                 return false;
261             }
262 
263             File f = (File) obj;
264 
265             return f.filename.equals(filename);
266         }
267 
268         public int hashCode() {
269             return hashCode;
270         }
271     }
272 
273     /**
274      * 
275      * @author Olivier Oeuillot (latest modification by $Author: oeuillot $)
276      * @version $Revision: 1.2 $ $Date: 2008/12/09 16:37:13 $
277      */
278     protected static class LocalizedFile {
279         private static final String REVISION = "$Revision: 1.2 $";
280 
281         private final String uri;
282 
283         private final Object[] contentLocations;
284 
285         public LocalizedFile(IContentProvider contentProvider, Locale locale,
286                 String uri, Object unlocalizedContentLocation) {
287             Object localizedContentLocation = null;
288 
289             if (locale != null) {
290                 URIParameters uriParameters = new URIParameters(uri);
291 
292                 if (locale != null) {
293                     uriParameters.appendLocale(locale);
294                 }
295 
296                 uri = uriParameters.computeParametredURI();
297             }
298 
299             if (locale != null) {
300                 if (unlocalizedContentLocation != null) {
301                     localizedContentLocation = contentProvider
302                             .searchLocalizedContentReference(
303                                     unlocalizedContentLocation, locale);
304 
305                     if (localizedContentLocation == null) {
306                         locale = Constants.REPOSITORY_DEFAULT_LOCALE;
307 
308                         localizedContentLocation = contentProvider
309                                 .searchLocalizedContentReference(
310                                         unlocalizedContentLocation, locale);
311                     }
312 
313                     if (localizedContentLocation != null) {
314                         if (LOG.isTraceEnabled()) {
315                             LOG.trace("Find localized version (" + locale
316                                     + ") of '" + uri + "' => "
317                                     + localizedContentLocation);
318 
319                         }
320                     } else {
321                         if (LOG.isTraceEnabled()) {
322                             LOG.trace("Can not find localized version ("
323                                     + locale + ") of '" + uri + "'.");
324 
325                         }
326                     }
327                 }
328             }
329 
330             if (unlocalizedContentLocation == null) {
331                 contentLocations = OBJECT_EMPTY_ARRAY;
332 
333             } else if (localizedContentLocation == null) {
334                 contentLocations = new Object[] { unlocalizedContentLocation };
335 
336             } else {
337                 contentLocations = new Object[] { unlocalizedContentLocation,
338                         localizedContentLocation };
339             }
340 
341             if (LOG.isDebugEnabled()) {
342                 LOG.debug("Content locations of " + this + " => "
343                         + Arrays.asList(contentLocations));
344             }
345 
346             this.uri = uri;
347         }
348 
349         public Object[] getContentLocations() {
350             return contentLocations;
351         }
352 
353         public String getURI() {
354             return uri;
355         }
356     }
357 
358     /**
359      * 
360      * @author Olivier Oeuillot (latest modification by $Author: oeuillot $)
361      * @version $Revision: 1.2 $ $Date: 2008/12/09 16:37:13 $
362      */
363     public static abstract class AbstractContent implements IContent {
364         private static final String REVISION = "$Revision: 1.2 $";
365 
366         public long getLastModified() throws IOException {
367             return -1;
368         }
369 
370         public long getLength() throws IOException {
371             return -1;
372         }
373 
374         public void release() {
375         }
376 
377     }
378 }