1 44 package org.jpublish.repository; 45 46 import java.io.IOException ; 47 import java.io.InputStream ; 48 import java.util.Iterator ; 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 77 public class DefaultRepository extends AbstractRepository { 78 79 private final static String ATTRIBUTE_CLASSNAME = "classname"; 80 private final static String ATTRIBUTE_SCHEME = "scheme"; 81 private final static String 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 94 public synchronized CacheStorage getContentCache() { 95 if (contentCache == null) { 96 contentCache = new HashMapCacheStorage(); 97 } 98 return contentCache; 99 } 100 101 106 public void setContentCache(CacheStorage contentCache) { 107 this.contentCache = contentCache; 108 } 109 110 115 public synchronized CacheStorage getContentConfigurationCache() { 116 if (contentConfigurationCache == null) { 117 contentConfigurationCache = new HashMapCacheStorage(); 118 } 119 return contentConfigurationCache; 120 } 121 122 127 public void setContentConfigurationCache(CacheStorage 128 contentConfigurationCache) { 129 this.contentConfigurationCache = contentConfigurationCache; 130 } 131 132 138 public FileSystemManager getDescriptorFileSystemManager() 139 throws IOException { 140 return descriptorFileSystemManager; 141 } 142 143 148 protected void setDescriptorFileSystemManager(FileSystemManager descriptorFileSystemManager) { 149 this.descriptorFileSystemManager = descriptorFileSystemManager; 150 } 151 152 160 public Content getContent(String path) throws IOException , 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 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 210 211 public long getLastModified(String path) throws IOException { 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 225 226 public void loadConfiguration(Configuration configuration) 227 throws ConfigurationException { 228 super.loadConfiguration(configuration); 229 230 Configuration fileSystemConfiguration = 232 configuration.getChild("filesystem"); 233 if (fileSystemConfiguration == null) { 234 Object [] args = {}; 235 String 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 return; 247 } 248 249 configureDescriptorFileSystemManager(descriptorFileSystemConfiguration); 250 } 251 252 258 protected void configureContent(ContentInstance contentInstance) 259 throws IOException { 260 try { 261 FileSystemManager fileSystemManager = 262 getDescriptorFileSystemManager(); 263 if (fileSystemManager == null) { 264 return; 265 } 266 267 String path = contentInstance.getPath(); 269 270 String configurationPath = PathUtilities.toRelativePath(PathUtilities.extractPagePath(path)) + 271 getActualConfigurationSuffix(); 272 273 FileObject baseFile = fileSystemManager.getBaseFile(); 274 FileObject configurationFile = fileSystemManager.resolveFile(baseFile, configurationPath); 275 276 283 if (log.isDebugEnabled()) { 284 log.debug("Configuration file: " + configurationFile); 285 } 286 287 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 Object cacheObject = cacheEntry.getObject(); 307 log.debug("Cache object: " + cacheObject); 308 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 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 providerIter = fileSystemConfiguration.getChildren("provider").iterator(); 340 while (providerIter.hasNext()) { 341 342 Configuration providerConfiguration = 343 (Configuration) providerIter.next(); 344 String className = providerConfiguration.getAttribute(ATTRIBUTE_CLASSNAME); 345 String 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 e) { 353 Object [] args = {className, e.getMessage()}; 354 String msg = MessageUtilities.getMessage(getClass(), 355 JPublishEngine.MESSAGE_PACKAGE, "errorLoadingProvider", 356 args); 357 log.error(msg); 358 } 361 } 362 363 String 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 [] args = {base, e.getMessage()}; 370 String 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 389 private Configuration loadAndCacheConfiguration(FileObject file, 390 String path) throws IOException , ConfigurationException { 391 InputStream 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 |