KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jpublish > repository > DefaultRepository


1 /*--
2  Copyright (C) 2001-2003 Aetrion LLC.
3  All rights reserved.
4
5  Redistribution and use in source and binary forms, with or without
6  modification, are permitted provided that the following conditions
7  are met:
8
9  1. Redistributions of source code must retain the above copyright
10     notice, this list of conditions, and the following disclaimer.
11
12  2. Redistributions in binary form must reproduce the above copyright
13     notice, this list of conditions, and the disclaimer that follows
14     these conditions in the documentation and/or other materials
15     provided with the distribution.
16  3. The name "JPublish" must not be used to endorse or promote products
17     derived from this software without prior written permission. For
18     written permission, please contact info@aetrion.com.
19
20  4. Products derived from this software may not be called "JPublish", nor
21     may "JPublish" appear in their name, without prior written permission
22     from Aetrion LLC (info@aetrion.com).
23
24  In addition, the authors of this software request (but do not require)
25  that you include in the end-user documentation provided with the
26  redistribution and/or in the software itself an acknowledgement equivalent
27  to the following:
28      "This product includes software developed by
29       Aetrion LLC (http://www.aetrion.com/)."
30  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
31  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
32  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
33  DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT,
34  INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
35  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
36  SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
37  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
38  STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
39  IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
40  POSSIBILITY OF SUCH DAMAGE.
41  For more information on JPublish, please see <http://www.jpublish.org/>.
42
43  */

44 package org.jpublish.repository;
45
46 import java.io.IOException JavaDoc;
47 import java.io.InputStream JavaDoc;
48 import java.util.Iterator JavaDoc;
49
50 import com.anthonyeden.lib.config.Configuration;
51 import com.anthonyeden.lib.config.ConfigurationException;
52 import com.anthonyeden.lib.config.ConfigurationFactory;
53 import com.anthonyeden.lib.config.sax.SAXConfigurationFactory;
54 import com.anthonyeden.lib.util.IOUtilities;
55 import com.anthonyeden.lib.util.MessageUtilities;
56 import org.apache.commons.logging.Log;
57 import org.apache.commons.logging.LogFactory;
58 import org.apache.commons.vfs.FileContent;
59 import org.apache.commons.vfs.FileObject;
60 import org.apache.commons.vfs.FileSystemException;
61 import org.apache.commons.vfs.FileSystemManager;
62 import org.apache.commons.vfs.impl.DefaultFileSystemManager;
63 import org.apache.commons.vfs.provider.FileProvider;
64 import org.jpublish.JPublishEngine;
65 import org.jpublish.JPublishRuntimeException;
66 import org.jpublish.cache.CacheEntry;
67 import org.jpublish.cache.CacheStorage;
68 import org.jpublish.cache.HashMapCacheStorage;
69 import org.jpublish.util.PathUtilities;
70 import org.jpublish.vfs.FileProviderFactory;
71
72 /**
73  * An implementation of the Repository interface which pulls content from the virtual files system.
74  *
75  * @author Anthony Eden
76  */

77 public class DefaultRepository extends AbstractRepository {
78
79     private final static String JavaDoc ATTRIBUTE_CLASSNAME = "classname";
80     private final static String JavaDoc ATTRIBUTE_SCHEME = "scheme";
81     private final static String JavaDoc ATTRIBUTE_BASE = "base";
82
83     private static Log log = LogFactory.getLog(DefaultRepository.class);
84
85     private CacheStorage contentCache = null;
86     private CacheStorage contentConfigurationCache = null;
87     private FileSystemManager descriptorFileSystemManager = null;
88
89     /**
90      * Get the content cache.
91      *
92      * @return The content cache
93      */

94     public synchronized CacheStorage getContentCache() {
95         if (contentCache == null) {
96             contentCache = new HashMapCacheStorage();
97         }
98         return contentCache;
99     }
100
101     /**
102      * Set the content cache.
103      *
104      * @param contentCache The content cache
105      */

106     public void setContentCache(CacheStorage contentCache) {
107         this.contentCache = contentCache;
108     }
109
110     /**
111      * Get the content configuration cache.
112      *
113      * @return The content configuration cache
114      */

115     public synchronized CacheStorage getContentConfigurationCache() {
116         if (contentConfigurationCache == null) {
117             contentConfigurationCache = new HashMapCacheStorage();
118         }
119         return contentConfigurationCache;
120     }
121
122     /**
123      * Set the content configuration cache.
124      *
125      * @param contentConfigurationCache The content cache
126      */

127     public void setContentConfigurationCache(CacheStorage
128             contentConfigurationCache) {
129         this.contentConfigurationCache = contentConfigurationCache;
130     }
131
132     /**
133      * Return the virtual file system manager for content descriptors.
134      *
135      * @return The descriptor FileSystemManager
136      * @throws IOException Description of the Exception
137      */

138     public FileSystemManager getDescriptorFileSystemManager()
139             throws IOException JavaDoc {
140         return descriptorFileSystemManager;
141     }
142
143     /**
144      * Set the virtual file system manager for content descriptors.
145      *
146      * @param descriptorFileSystemManager The descriptor file system manager
147      */

148     protected void setDescriptorFileSystemManager(FileSystemManager descriptorFileSystemManager) {
149         this.descriptorFileSystemManager = descriptorFileSystemManager;
150     }
151
152     /**
153      * Get the content from the given path.
154      *
155      * @param path The relative content path
156      * @return The content object
157      * @throws IOException Any IOException
158      * @throws ContentNotFoundException
159      */

160     public Content getContent(String JavaDoc path) throws IOException JavaDoc,
161             ContentNotFoundException {
162         if (log.isDebugEnabled()) {
163             log.debug("getContent(" + path + ")");
164         }
165
166         FileSystemManager fileSystemManager = getFileSystemManager();
167         FileObject baseFile = fileSystemManager.getBaseFile();
168         FileObject file = fileSystemManager.resolveFile(baseFile,
169                 PathUtilities.toRelativePath(path));
170         FileContent content = file.getContent();
171
172         // load the content instance
173
ContentInstance contentInstance = null;
174         CacheStorage contentCache = getContentCache();
175         if (log.isDebugEnabled()) {
176             log.debug("ContentCache: " + contentCache);
177         }
178
179         synchronized (contentCache) {
180             CacheEntry cacheEntry = (CacheEntry) contentCache.get(path);
181             if (cacheEntry == null) {
182                 contentInstance = new ContentInstance(siteContext, file, path, this);
183                 cacheEntry = new CacheEntry(contentInstance,
184                         content.getLastModifiedTime());
185                 contentCache.put(path, cacheEntry);
186             } else {
187                 contentInstance = (ContentInstance) cacheEntry.getObject();
188                 if (cacheEntry.getLastModified() !=
189                         content.getLastModifiedTime()) {
190                     contentInstance = new ContentInstance(siteContext, file, path, this);
191                     contentCache.put(path, new CacheEntry(contentInstance,
192                             content.getLastModifiedTime()));
193                 }
194             }
195         }
196
197         log.debug("Configuring content");
198         configureContent(contentInstance);
199
200         return new Content(contentInstance);
201     }
202
203     /**
204      * Get the last modified time in milliseconds for the given path.
205      *
206      * @param path The content path
207      * @return The last modified time in milliseconds
208      * @throws IOException Any IOException
209      */

210
211     public long getLastModified(String JavaDoc path) throws IOException JavaDoc {
212         FileObject baseFile = fileSystemManager.getBaseFile();
213         FileObject file = fileSystemManager.resolveFile(baseFile,
214                 PathUtilities.toRelativePath(path));
215         FileContent content = file.getContent();
216         return content.getLastModifiedTime();
217     }
218
219     /**
220      * Load the repository's configuration from the given configuration object.
221      *
222      * @param configuration The configuration object
223      * @throws ConfigurationException
224      */

225
226     public void loadConfiguration(Configuration configuration)
227             throws ConfigurationException {
228         super.loadConfiguration(configuration);
229
230         // load the file system
231
Configuration fileSystemConfiguration =
232                 configuration.getChild("filesystem");
233         if (fileSystemConfiguration == null) {
234             Object JavaDoc[] args = {};
235             String JavaDoc msg = MessageUtilities.getMessage(getClass(),
236                     JPublishEngine.MESSAGE_PACKAGE, "fileSystemRequired", args);
237             throw new ConfigurationException(msg, configuration);
238         }
239
240         configureFileSystemManager(fileSystemConfiguration);
241
242         Configuration descriptorFileSystemConfiguration =
243                 configuration.getChild("descriptor-filesystem");
244         if (descriptorFileSystemConfiguration == null) {
245             //descriptorFileSystemConfiguration = fileSystemConfiguration;
246
return;
247         }
248
249         configureDescriptorFileSystemManager(descriptorFileSystemConfiguration);
250     }
251
252     /**
253      * Description of the Method
254      *
255      * @param contentInstance Description of the Parameter
256      * @throws IOException Description of the Exception
257      */

258     protected void configureContent(ContentInstance contentInstance)
259             throws IOException JavaDoc {
260         try {
261             FileSystemManager fileSystemManager =
262                     getDescriptorFileSystemManager();
263             if (fileSystemManager == null) {
264                 return;
265             }
266
267             // find the content configuration if one exists
268
String JavaDoc path = contentInstance.getPath();
269
270             String JavaDoc configurationPath = PathUtilities.toRelativePath(PathUtilities.extractPagePath(path)) +
271                     getActualConfigurationSuffix();
272
273             FileObject baseFile = fileSystemManager.getBaseFile();
274             FileObject configurationFile = fileSystemManager.resolveFile(baseFile, configurationPath);
275
276             // Should content objects support a default configuration like
277
// pages do? -AE
278
/*
279             if(!configurationFile.exists()){
280                 configurationFile = baseFile.getChild(getDefaultPath());
281             }
282             */

283             if (log.isDebugEnabled()) {
284                 log.debug("Configuration file: " + configurationFile);
285             }
286
287             // load the content configuration
288
if (configurationFile.exists()) {
289                 log.debug("Configuration file exists");
290                 FileContent content = configurationFile.getContent();
291                 Configuration configuration = null;
292                 CacheStorage contentConfigurationCache =
293                         getContentConfigurationCache();
294                 if (log.isDebugEnabled()) {
295                     log.debug("ContentConfigurationCache: " +
296                             contentConfigurationCache);
297                 }
298
299                 synchronized (contentConfigurationCache) {
300                     CacheEntry cacheEntry =
301                             (CacheEntry) contentConfigurationCache.get(path);
302                     if (cacheEntry == null) {
303                         configuration = loadAndCacheConfiguration(configurationFile, path);
304                     } else {
305                         // debug
306
Object JavaDoc cacheObject = cacheEntry.getObject();
307                         log.debug("Cache object: " + cacheObject);
308                         // end debug
309
configuration = (Configuration) cacheEntry.getObject();
310                         if (cacheEntry.getLastModified() !=
311                                 content.getLastModifiedTime()) {
312                             configuration = loadAndCacheConfiguration(configurationFile, path);
313                         }
314                     }
315                 }
316
317                 contentInstance.loadConfiguration(configuration);
318             } else {
319                 log.debug("Configuration file does not exist");
320             }
321         } catch (ConfigurationException e) {
322             throw new JPublishRuntimeException(e.getMessage(), e);
323         }
324     }
325
326     /**
327      * Description of the Method
328      *
329      * @param fileSystemConfiguration Description of the Parameter
330      * @throws ConfigurationException Description of the Exception
331      */

332     protected void configureDescriptorFileSystemManager(Configuration fileSystemConfiguration)
333             throws ConfigurationException {
334         log.debug("Configuring descriptor FileSystemManager");
335
336         DefaultFileSystemManager fileSystemManager =
337                 new DefaultFileSystemManager();
338
339         Iterator JavaDoc providerIter = fileSystemConfiguration.getChildren("provider").iterator();
340         while (providerIter.hasNext()) {
341
342             Configuration providerConfiguration =
343                     (Configuration) providerIter.next();
344             String JavaDoc className = providerConfiguration.getAttribute(ATTRIBUTE_CLASSNAME);
345             String JavaDoc scheme = providerConfiguration.getAttribute(ATTRIBUTE_SCHEME);
346
347             try {
348                 FileProviderFactory factory =
349                         siteContext.getFileProviderFactory();
350                 FileProvider provider = factory.createProvider(className);
351                 fileSystemManager.addProvider(scheme, provider);
352             } catch (Exception JavaDoc e) {
353                 Object JavaDoc[] args = {className, e.getMessage()};
354                 String JavaDoc msg = MessageUtilities.getMessage(getClass(),
355                         JPublishEngine.MESSAGE_PACKAGE, "errorLoadingProvider",
356                         args);
357                 log.error(msg);
358                 //if(log.isDebugEnabled())
359
// e.printStackTrace();
360
}
361         }
362
363         String JavaDoc base = fileSystemConfiguration.getAttribute(ATTRIBUTE_BASE);
364         if (base != null) {
365             try {
366                 FileObject baseFile = fileSystemManager.resolveFile(base);
367                 fileSystemManager.setBaseFile(baseFile);
368             } catch (FileSystemException e) {
369                 Object JavaDoc[] args = {base, e.getMessage()};
370                 String JavaDoc msg = MessageUtilities.getMessage(getClass(),
371                         JPublishEngine.MESSAGE_PACKAGE, "baseFileError", args);
372                 throw new ConfigurationException(msg, e,
373                         fileSystemConfiguration);
374             }
375         }
376
377         setDescriptorFileSystemManager(fileSystemManager);
378     }
379
380     /**
381      * Description of the Method
382      *
383      * @param file Description of the Parameter
384      * @param path Description of the Parameter
385      * @return Description of the Return Value
386      * @throws IOException Description of the Exception
387      * @throws ConfigurationException Description of the Exception
388      */

389     private Configuration loadAndCacheConfiguration(FileObject file,
390             String JavaDoc path) throws IOException JavaDoc, ConfigurationException {
391         InputStream JavaDoc in = null;
392         try {
393             in = file.getContent().getInputStream();
394             ConfigurationFactory configFactory =
395                     SAXConfigurationFactory.getInstance();
396             Configuration configuration = configFactory.getConfiguration(path,
397                     in);
398             CacheEntry cacheEntry = new CacheEntry(configuration,
399                     file.getContent().getLastModifiedTime());
400             contentConfigurationCache.put(path, cacheEntry);
401             return configuration;
402         } finally {
403             IOUtilities.close(in);
404         }
405     }
406
407 }
408
409
Popular Tags