KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jpublish > page > DefaultPageManager


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

48
49 package org.jpublish.page;
50
51 import java.io.IOException JavaDoc;
52 import java.io.InputStream JavaDoc;
53
54 import com.anthonyeden.lib.config.Configuration;
55 import com.anthonyeden.lib.config.ConfigurationException;
56 import com.anthonyeden.lib.util.ClassUtilities;
57 import com.anthonyeden.lib.util.IOUtilities;
58 import com.anthonyeden.lib.util.MessageUtilities;
59 import org.apache.commons.logging.Log;
60 import org.apache.commons.logging.LogFactory;
61 import org.apache.commons.vfs.FileContent;
62 import org.apache.commons.vfs.FileObject;
63 import org.apache.commons.vfs.FileSystemManager;
64 import org.jpublish.JPublishEngine;
65 import org.jpublish.JPublishRuntimeException;
66 import org.jpublish.ManagerBase;
67 import org.jpublish.SiteContext;
68 import org.jpublish.cache.CacheEntry;
69 import org.jpublish.cache.CacheStorage;
70 import org.jpublish.cache.HashMapCacheStorage;
71 import org.jpublish.util.PathUtilities;
72
73 /**
74  * The PageManager is a central access point for locating pages. Pages are loaded and cached automatically. The cache
75  * will check the file's last modification time and will update if the last modified times do not match.
76  *
77  * <p>This PageManager implementation will fall back to the default.xml page descriptor if the path's expected page
78  * descriptor is not found.</p>
79  *
80  * @author Anthony Eden
81  */

82
83 public class DefaultPageManager extends ManagerBase implements PageManager {
84
85     /**
86      * The default path (default.xml).
87      */

88     public static final String JavaDoc DEFAULT_PATH = "default.xml";
89
90     private static final String JavaDoc ATTRIBUTE_CLASSNAME = "classname";
91
92     private Log log = LogFactory.getLog(DefaultPageManager.class);
93     private CacheStorage pageCache = null;
94     private String JavaDoc defaultPath = DEFAULT_PATH;
95
96     /**
97      * Return the virtual file system manager. This method may return null if the implementation does not support a
98      * virtual file system.
99      *
100      * @return The FileSystemManager
101      */

102
103     public synchronized FileSystemManager getFileSystemManager()
104             throws IOException JavaDoc {
105         if (fileSystemManager == null) {
106             configureDefaultFileSystemManager(SiteContext.DEFAULT_PAGE_ROOT);
107         }
108         return fileSystemManager;
109     }
110
111     /**
112      * Get the page cache.
113      *
114      * @return The page cache
115      */

116
117     public synchronized CacheStorage getPageCache() {
118         if (pageCache == null) {
119             pageCache = new HashMapCacheStorage();
120         }
121         return pageCache;
122     }
123
124     /**
125      * Set the page cache.
126      *
127      * @param pageCache The new page cache
128      */

129
130     public void setPageCache(CacheStorage pageCache) {
131         this.pageCache = pageCache;
132     }
133
134     /**
135      * Get the path to the default descriptor.
136      *
137      * @return The default path
138      */

139
140     public String JavaDoc getDefaultPath() {
141         return defaultPath;
142     }
143
144     /**
145      * Set the path to the default descriptor.
146      *
147      * @param defaultPath
148      */

149
150     public void setDefaultPath(String JavaDoc defaultPath) {
151         if (defaultPath == null) {
152             this.defaultPath = DEFAULT_PATH;
153         } else {
154             this.defaultPath = defaultPath;
155         }
156     }
157
158     /**
159      * Get a PageInstance from the given path. If no page can be found then this method will throw a
160      * FileNotFoundException.
161      *
162      * @param path The page path
163      * @return The Page
164      * @throws IOException Any IOException
165      * @throws PageNotFoundException
166      */

167
168     public synchronized PageInstance getPage(String JavaDoc path)
169             throws IOException JavaDoc, PageNotFoundException {
170         FileSystemManager fileSystemManager = getFileSystemManager();
171         FileObject baseFile = fileSystemManager.getBaseFile();
172         FileObject file = fileSystemManager.resolveFile(baseFile,
173                 PathUtilities.toRelativePath(path));
174         FileObject parentFolder = file.getParent();
175
176         String JavaDoc pageName = PathUtilities.extractPageName(path);
177         String JavaDoc pageType = PathUtilities.extractPageType(path);
178         String JavaDoc pagePath = PathUtilities.extractPagePath(path);
179         String JavaDoc pageParent = PathUtilities.extractPageParent(path);
180
181         if (log.isDebugEnabled()) {
182             log.debug("Page name: " + pageName);
183             log.debug("Page type: " + pageType);
184             log.debug("Page path: " + pagePath);
185             log.debug("Page parent: " + pageParent);
186         }
187
188         String JavaDoc suffix = getActualConfigurationSuffix();
189         if (log.isDebugEnabled()) {
190             log.debug("Resolving page " + pageName + suffix);
191         }
192         FileObject xmlFile = parentFolder.resolveFile(pageName + suffix);
193
194         if (!xmlFile.exists()) {
195             log.debug("Configuration file not found");
196             xmlFile = baseFile.getChild(getDefaultPath());
197             if (xmlFile == null || !xmlFile.exists()) {
198                 Object JavaDoc[] args = {path};
199                 String JavaDoc msg = MessageUtilities.getMessage(getClass(),
200                         JPublishEngine.MESSAGE_PACKAGE, "pageNotFound", args);
201                 throw new PageNotFoundException(msg);
202             }
203         }
204
205         if (log.isDebugEnabled()) {
206             log.debug("Looking for page:" + xmlFile);
207         }
208
209         FileContent content = xmlFile.getContent();
210         
211         // check the cache and load the page definition if necessary
212
CacheStorage pageCache = getPageCache();
213         CacheEntry cacheEntry = (CacheEntry) pageCache.get(pagePath);
214
215         PageInstance page = null;
216         PageDefinition pageDefinition = null;
217         InputStream JavaDoc in = null;
218         try {
219             if (cacheEntry == null) {
220                 if (log.isDebugEnabled()) {
221                     log.debug("Page definition (" + pagePath +
222                             ") not found in cache.");
223                 }
224
225                 if (log.isDebugEnabled()) {
226                     log.debug("Loading page definition configuration: " + xmlFile);
227                 }
228
229                 in = content.getInputStream();
230
231                 pageDefinition = new PageDefinition(siteContext, pagePath);
232                 pageDefinition.loadConfiguration(in);
233
234                 pageCache.put(pagePath, new CacheEntry(pageDefinition,
235                         content.getLastModifiedTime()));
236             } else {
237                 if (log.isDebugEnabled()) {
238                     log.debug("Page definition (" + pagePath +
239                             ") found in cache.");
240                 }
241
242                 pageDefinition = (PageDefinition) cacheEntry.getObject();
243                 if (cacheEntry.getLastModified() !=
244                         content.getLastModifiedTime()) {
245                     log.debug("Page modification dates do not match.");
246                     log.debug("Reloading page definition.");
247                     long lastModified = content.getLastModifiedTime();
248
249                     in = content.getInputStream();
250
251                     pageDefinition = new PageDefinition(siteContext, pagePath);
252                     pageDefinition.loadConfiguration(in);
253
254                     pageCache.put(pagePath, new CacheEntry(pageDefinition,
255                             lastModified));
256                 }
257             }
258         } catch (ConfigurationException e) {
259             throw new JPublishRuntimeException(e.getMessage(), e);
260         } finally {
261             IOUtilities.close(in);
262         }
263
264         if (pageDefinition != null) {
265             try {
266                 if (log.isDebugEnabled()) {
267                     log.debug("Getting page instance for " + path);
268                 }
269                 page = pageDefinition.getPageInstance(path);
270             } catch (ConfigurationException e) {
271                 throw new JPublishRuntimeException(e.getMessage(), e);
272             }
273         }
274
275         return page;
276     }
277
278     /**
279      * Get the last modified time of the page with the given path. This method may return -1 if the last modified time
280      * is not known.
281      *
282      * @param path The page path
283      * @return The last modified time
284      * @throws IOException Any IOException
285      */

286
287     public long getLastModified(String JavaDoc path) throws IOException JavaDoc {
288         FileSystemManager fileSystemManager = getFileSystemManager();
289         FileObject baseFile = fileSystemManager.getBaseFile();
290         FileObject file = fileSystemManager.resolveFile(baseFile,
291                 PathUtilities.toRelativePath(path));
292         FileContent content = file.getContent();
293         return content.getLastModifiedTime();
294     }
295
296     /**
297      * Load the PageManager's configuration.
298      *
299      * @param configuration The Configuration object
300      * @throws ConfigurationException
301      */

302
303     public void loadConfiguration(Configuration configuration)
304             throws ConfigurationException {
305         super.loadConfiguration(configuration);
306         
307         // set default path
308
setDefaultPath(configuration.getChildValue("default-path"));
309         
310         // set the cache storage type
311
String JavaDoc className = null;
312         try {
313             Configuration cacheStorageElement = configuration.getChild("cache-storage");
314             if (cacheStorageElement != null) {
315                 className = cacheStorageElement.getAttribute(ATTRIBUTE_CLASSNAME, HashMapCacheStorage.class.getName());
316                 CacheStorage cache = (CacheStorage) ClassUtilities.loadClass(className).newInstance();
317                 cache.loadConfiguration(cacheStorageElement);
318                 setPageCache(cache);
319             }
320         } catch (ClassNotFoundException JavaDoc e) {
321             Object JavaDoc[] args = {className};
322             String JavaDoc msg = MessageUtilities.getMessage(getClass(),
323                     JPublishEngine.MESSAGE_PACKAGE, "cacheStorageClassNotFound",
324                     args);
325             throw new ConfigurationException(msg, e);
326         } catch (InstantiationException JavaDoc e) {
327             Object JavaDoc[] args = {};
328             String JavaDoc msg = MessageUtilities.getMessage(getClass(),
329                     JPublishEngine.MESSAGE_PACKAGE,
330                     "cacheStorageInstantiationError", args);
331             throw new ConfigurationException(msg, e);
332         } catch (IllegalAccessException JavaDoc e) {
333             Object JavaDoc[] args = {};
334             String JavaDoc msg = MessageUtilities.getMessage(getClass(),
335                     JPublishEngine.MESSAGE_PACKAGE,
336                     "cacheStorageIllegalAccessError", args);
337             throw new ConfigurationException(msg, e);
338         }
339     }
340
341 }
342
Popular Tags