You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lenya.apache.org by an...@apache.org on 2008/02/02 00:25:29 UTC

svn commit: r617705 - in /lenya/trunk/src: java/org/apache/lenya/cms/cocoon/source/FallbackSourceFactory.java webapp/lenya/config/cocoon-xconf/source-factories/fallback-store.xconf

Author: andreas
Date: Fri Feb  1 15:25:23 2008
New Revision: 617705

URL: http://svn.apache.org/viewvc?rev=617705&view=rev
Log:
Adding cache for resolved fallback source URIs (disabled by default).

Added:
    lenya/trunk/src/webapp/lenya/config/cocoon-xconf/source-factories/fallback-store.xconf
Modified:
    lenya/trunk/src/java/org/apache/lenya/cms/cocoon/source/FallbackSourceFactory.java

Modified: lenya/trunk/src/java/org/apache/lenya/cms/cocoon/source/FallbackSourceFactory.java
URL: http://svn.apache.org/viewvc/lenya/trunk/src/java/org/apache/lenya/cms/cocoon/source/FallbackSourceFactory.java?rev=617705&r1=617704&r2=617705&view=diff
==============================================================================
--- lenya/trunk/src/java/org/apache/lenya/cms/cocoon/source/FallbackSourceFactory.java (original)
+++ lenya/trunk/src/java/org/apache/lenya/cms/cocoon/source/FallbackSourceFactory.java Fri Feb  1 15:25:23 2008
@@ -35,6 +35,7 @@
 import org.apache.excalibur.source.SourceResolver;
 import org.apache.excalibur.source.SourceUtil;
 import org.apache.excalibur.source.URIAbsolutizer;
+import org.apache.excalibur.store.impl.MRUMemoryStore;
 import org.apache.lenya.cms.module.ModuleManager;
 import org.apache.lenya.cms.publication.DocumentFactory;
 import org.apache.lenya.cms.publication.DocumentUtil;
@@ -43,6 +44,9 @@
 import org.apache.lenya.cms.publication.templating.ExistingSourceResolver;
 import org.apache.lenya.cms.publication.templating.PublicationTemplateManager;
 import org.apache.lenya.cms.publication.templating.VisitingSourceResolver;
+import org.apache.lenya.cms.repository.RepositoryUtil;
+import org.apache.lenya.cms.repository.Session;
+import org.apache.lenya.util.ServletHelper;
 
 /**
  * <p>
@@ -58,19 +62,86 @@
 public class FallbackSourceFactory extends AbstractLogEnabled implements SourceFactory,
         Serviceable, Contextualizable, URIAbsolutizer {
 
-    /**
-     * Ctor.
-     */
-    public FallbackSourceFactory() {
-        super();
+    private static MRUMemoryStore store;
+    private boolean useCache = false;
+    
+    protected static final String STORE_ROLE = FallbackSourceFactory.class.getName() + "Store";
+    
+    protected MRUMemoryStore getStore() {
+        if (store == null) {
+            try {
+                store = (MRUMemoryStore) this.manager.lookup(STORE_ROLE);
+            } catch (ServiceException e) {
+                throw new RuntimeException(e);
+            }
+        }
+        return store;
     }
-
+    
     /**
      * @see org.apache.excalibur.source.SourceFactory#getSource(java.lang.String, java.util.Map)
      */
     public Source getSource(final String location, Map parameters) throws IOException,
             MalformedURLException {
 
+        MRUMemoryStore store = getStore();
+        Source source;
+        final String cacheKey = getCacheKey(location);
+        final String cachedSourceUri = (String) store.get(cacheKey);
+
+        if (!useCache || cachedSourceUri == null) {
+            source = findSource(location, parameters);
+            final String resolvedSourceUri = source.getURI();
+            store.hold(cacheKey, resolvedSourceUri);
+            if (getLogger().isDebugEnabled()) {
+                getLogger().debug("No cached source URI for key " + cacheKey + ", caching URI " + resolvedSourceUri);
+            }
+        } else {
+            SourceResolver resolver = null;
+            try {
+                resolver = (SourceResolver) this.manager.lookup(SourceResolver.ROLE);
+                source = resolver.resolveURI(cachedSourceUri);
+            } catch (ServiceException e) {
+                throw new RuntimeException(e);
+            } finally {
+                if (resolver != null) {
+                    this.manager.release(resolver);
+                }
+            }
+            if (getLogger().isDebugEnabled()) {
+                getLogger().debug("Using cached source URI " + cachedSourceUri + " for key " + cacheKey);
+            }
+        }
+        return source;
+    }
+
+    protected String getCacheKey(final String location) {
+        String pubId = getPublicationId();
+        String cacheKey = pubId == null ? location : pubId + ":" + location;
+        return cacheKey;
+    }
+
+    protected String getPublicationId() {
+        Request request = ContextHelper.getRequest(this.context);
+        String webappUri = ServletHelper.getWebappURI(request);
+        URLInformation info = new URLInformation(webappUri);
+        String pubId = null;
+        try {
+            Session session = RepositoryUtil.getSession(this.manager, request);
+            DocumentFactory factory = DocumentUtil.createDocumentFactory(this.manager, session);
+            String pubIdCandidate = info.getPublicationId();
+            if (pubIdCandidate != null && factory.existsPublication(pubIdCandidate)) {
+                pubId = pubIdCandidate;
+            }
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+        return pubId;
+    }
+
+    protected Source findSource(final String location, Map parameters) throws IOException,
+            MalformedURLException {
+
         // Remove the protocol and the first '//'
         int pos = location.indexOf("://");
 
@@ -78,11 +149,11 @@
             throw new RuntimeException("The location [" + location
                     + "] does not contain the string '://'");
         }
-        
+
         String path = location.substring(pos + 3);
-        
+
         String publicationId = null;
-        
+
         // extract publication ID
         String prefix = location.substring(0, pos);
         StringTokenizer tokens = new StringTokenizer(prefix, ":");
@@ -90,13 +161,13 @@
             tokens.nextToken();
             publicationId = tokens.nextToken();
         }
-        
+
         // remove query string
         int questionMarkIndex = path.indexOf("?");
         if (questionMarkIndex > -1) {
             path = path.substring(0, questionMarkIndex);
         }
-        
+
         if (path.length() == 0) {
             throw new RuntimeException("The path after the protocol must not be empty!");
         }
@@ -112,12 +183,14 @@
         try {
             sourceResolver = (SourceResolver) this.manager.lookup(SourceResolver.ROLE);
 
-            templateManager = (PublicationTemplateManager) this.manager.lookup(PublicationTemplateManager.ROLE);
+            templateManager = (PublicationTemplateManager) this.manager
+                    .lookup(PublicationTemplateManager.ROLE);
 
             Request request = ContextHelper.getRequest(this.context);
-            
+
             if (publicationId == null) {
-                String webappUrl = request.getRequestURI().substring(request.getContextPath().length());
+                String webappUrl = request.getRequestURI().substring(
+                        request.getContextPath().length());
 
                 URLInformation info = new URLInformation(webappUrl);
                 publicationId = info.getPublicationId();
@@ -138,7 +211,8 @@
                         moduleMgr = (ModuleManager) this.manager.lookup(ModuleManager.ROLE);
                         final String moduleShortcut = path.split("/")[2];
                         String baseUri = moduleMgr.getBaseURI(moduleShortcut);
-                        final String modulePath = path.substring(("lenya/modules/" + moduleShortcut).length());
+                        final String modulePath = path
+                                .substring(("lenya/modules/" + moduleShortcut).length());
                         source = sourceResolver.resolveURI(baseUri + modulePath);
                     } finally {
                         if (moduleMgr != null) {
@@ -177,7 +251,7 @@
 
     /** The ServiceManager */
     private ServiceManager manager;
-
+    
     /**
      * @see org.apache.avalon.framework.service.Serviceable#service(org.apache.avalon.framework.service.ServiceManager)
      */
@@ -223,4 +297,5 @@
     public String absolutize(String baseURI, String location) {
         return SourceUtil.absolutize(baseURI, location, true);
     }
+
 }

Added: lenya/trunk/src/webapp/lenya/config/cocoon-xconf/source-factories/fallback-store.xconf
URL: http://svn.apache.org/viewvc/lenya/trunk/src/webapp/lenya/config/cocoon-xconf/source-factories/fallback-store.xconf?rev=617705&view=auto
==============================================================================
--- lenya/trunk/src/webapp/lenya/config/cocoon-xconf/source-factories/fallback-store.xconf (added)
+++ lenya/trunk/src/webapp/lenya/config/cocoon-xconf/source-factories/fallback-store.xconf Fri Feb  1 15:25:23 2008
@@ -0,0 +1,24 @@
+<?xml version="1.0"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+-->
+
+<xconf xpath="/cocoon" unless="/cocoon/component[@role = 'org.apache.lenya.cms.cocoon.source.FallbackSourceFactoryStore']">
+  <component role="org.apache.lenya.cms.cocoon.source.FallbackSourceFactoryStore"
+    class="org.apache.excalibur.store.impl.MRUMemoryStore" logger="lenya.source.fallback.store">
+    <parameter name="maxobjects" value="10000"/>
+  </component>
+</xconf>



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@lenya.apache.org
For additional commands, e-mail: commits-help@lenya.apache.org