You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@cocoon.apache.org by vg...@apache.org on 2005/03/31 16:44:41 UTC

svn commit: r159599 - cocoon/trunk/src/java/org/apache/cocoon/matching/MountTableMatcher.java

Author: vgritsenko
Date: Thu Mar 31 06:44:40 2005
New Revision: 159599

URL: http://svn.apache.org/viewcvs?view=rev&rev=159599
Log:
fix memory leak

Modified:
    cocoon/trunk/src/java/org/apache/cocoon/matching/MountTableMatcher.java

Modified: cocoon/trunk/src/java/org/apache/cocoon/matching/MountTableMatcher.java
URL: http://svn.apache.org/viewcvs/cocoon/trunk/src/java/org/apache/cocoon/matching/MountTableMatcher.java?view=diff&r1=159598&r2=159599
==============================================================================
--- cocoon/trunk/src/java/org/apache/cocoon/matching/MountTableMatcher.java (original)
+++ cocoon/trunk/src/java/org/apache/cocoon/matching/MountTableMatcher.java Thu Mar 31 06:44:40 2005
@@ -1,12 +1,12 @@
 /*
- * Copyright 1999-2004 The Apache Software Foundation.
- * 
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
  * Licensed 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.
@@ -15,11 +15,6 @@
  */
 package org.apache.cocoon.matching;
 
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-
 import org.apache.avalon.framework.configuration.Configuration;
 import org.apache.avalon.framework.configuration.DefaultConfigurationBuilder;
 import org.apache.avalon.framework.logger.AbstractLogEnabled;
@@ -30,14 +25,21 @@
 import org.apache.avalon.framework.service.ServiceManager;
 import org.apache.avalon.framework.service.Serviceable;
 import org.apache.avalon.framework.thread.ThreadSafe;
+
 import org.apache.cocoon.components.source.SourceUtil;
 import org.apache.cocoon.environment.ObjectModelHelper;
 import org.apache.cocoon.environment.Request;
 import org.apache.cocoon.sitemap.PatternException;
+
 import org.apache.excalibur.source.Source;
 import org.apache.excalibur.source.SourceResolver;
 import org.apache.excalibur.source.SourceValidity;
 
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
 /**
  * A matcher that manages a "mount table", allowing to add subsitemaps to a Cocoon application without
  * modifying the main sitemap. This is especially useful for prototypes and demos where installing
@@ -70,20 +72,21 @@
  * <p>
  * This configuration is used in the main sitemap of Cocoon samples, to allow users to define their own mount
  * table, but not fail if it does not exist.
- * 
+ *
  * @author <a href="http://www.apache.org/~sylvain/">Sylvain Wallez</a>
- * @version CVS $Id$
+ * @version $Id$
  */
-public class MountTableMatcher extends AbstractLogEnabled implements Matcher, ThreadSafe, Serviceable, Parameterizable {
+public class MountTableMatcher extends AbstractLogEnabled
+                               implements Matcher, ThreadSafe, Serviceable, Parameterizable {
 
     private ServiceManager manager;
     private SourceResolver resolver;
     private Map mountTables = Collections.synchronizedMap(new HashMap());
-    private boolean ignoreMissingTables = false;
+    private boolean ignoreMissingTables;
 
     public void service(ServiceManager manager) throws ServiceException {
         this.manager = manager;
-        this.resolver = (SourceResolver)this.manager.lookup(SourceResolver.ROLE);
+        this.resolver = (SourceResolver) this.manager.lookup(SourceResolver.ROLE);
     }
 
     public void parameterize(Parameters params) throws ParameterException {
@@ -91,108 +94,117 @@
     }
 
     private Map getMountTable(String src) throws Exception {
-        Source source = resolver.resolveURI(src);
-        String uri = source.getURI();
-        
-        // Check if source exists
-        if (!source.exists()) {
-            resolver.release(source);
-            if (this.ignoreMissingTables) {
-                return Collections.EMPTY_MAP;
+        Source source = null;
+        try {
+            source = this.resolver.resolveURI(src);
+            final String uri = source.getURI();
+
+            // Check if source exists
+            if (!source.exists()) {
+                if (this.ignoreMissingTables) {
+                    return Collections.EMPTY_MAP;
+                } else {
+                    throw new PatternException("Mount table does not exist: '" + uri + "'");
+                }
+            }
+
+            // Source exists
+            Object[] values = (Object[]) this.mountTables.get(uri);
+            if (values != null) {
+                // Check validity
+                SourceValidity oldValidity = (SourceValidity) values[1];
+
+                int valid = oldValidity != null ? oldValidity.isValid() : SourceValidity.INVALID;
+                if (valid == SourceValidity.VALID) {
+                    // Valid without needing the new validity
+                    return (Map) values[0];
+                }
+
+                if (valid == SourceValidity.UNKNOWN &&
+                        oldValidity.isValid(source.getValidity()) == SourceValidity.VALID) {
+                    // Valid after comparing with the new validity
+                    return (Map) values[0];
+                }
+
+                // Invalid: fallback below to read the mount table
             } else {
-                throw new PatternException("Mount table does not exist: '" + uri + "'");
+                values = new Object[2];
             }
-        }
-        
-        // Source exists
-        Object[] values = (Object[])this.mountTables.get(uri);
-        
-        if (values != null) {
-            // Check validity
-            SourceValidity oldValidity = (SourceValidity)values[1];
-            
-            int valid = oldValidity != null ? oldValidity.isValid() : SourceValidity.INVALID;
-            
-            if (valid == SourceValidity.VALID) {
-                // Valid without needing the new validity
-                return (Map)values[0];
-            }
-            
-            if (valid == SourceValidity.UNKNOWN &&
-                oldValidity.isValid(source.getValidity()) == SourceValidity.VALID) {
-                // Valid after comparing with the new validity
-                return (Map)values[0];
-            }
-            
-            // Invalid: fallback below to read the mount table
-        } else {
-            values = new Object[2];
-        }
-        
-        // Read the mount table
-        Map mounts = new HashMap();
-        DefaultConfigurationBuilder builder = new DefaultConfigurationBuilder();
-        Configuration config = builder.build(SourceUtil.getInputSource(source));
-        this.resolver.release(source);
-        
-        Configuration[] children = config.getChildren();
-        for (int i = 0; i < children.length; i++) {
-            Configuration child = children[i];
-            if ("mount".equals(child.getName())) {
-                String prefix = children[i].getAttribute("uri-prefix");
-                // Append a '/' at the end of a not-empty prefix
-                // this avoids flat uri matching which would cause
-                // exceptions in the sub sitemap!
-                if (!prefix.endsWith("/") && prefix.length() != 0) {
-                    prefix = prefix + '/';
+
+            // Read the mount table
+            Map mounts = new HashMap();
+            DefaultConfigurationBuilder builder = new DefaultConfigurationBuilder();
+            Configuration config = builder.build(SourceUtil.getInputSource(source));
+
+            Configuration[] children = config.getChildren();
+            for (int i = 0; i < children.length; i++) {
+                Configuration child = children[i];
+                if ("mount".equals(child.getName())) {
+                    String prefix = children[i].getAttribute("uri-prefix");
+                    // Append a '/' at the end of a not-empty prefix
+                    // this avoids flat uri matching which would cause
+                    // exceptions in the sub sitemap!
+                    if (!prefix.endsWith("/") && prefix.length() != 0) {
+                        prefix = prefix + '/';
+                    }
+                    mounts.put(prefix, children[i].getAttribute("src"));
+                } else {
+                    throw new PatternException(
+                        "Unexpected element '" + child.getName() + "' (awaiting 'mount'), at " + child.getLocation());
                 }
-                mounts.put(prefix, children[i].getAttribute("src"));
+            }
+            values[0] = mounts;
+            values[1] = source.getValidity();
+
+            // Cache it with the source validity
+            this.mountTables.put(uri, values);
+
+            return mounts;
+
+        } catch (SecurityException e) {
+            if (this.ignoreMissingTables) {
+                return Collections.EMPTY_MAP;
             } else {
-                throw new PatternException(
-                    "Unexpected element '" + child.getName() + "' (awaiting 'mount'), at " + child.getLocation());
+                throw new PatternException("Mount table is not accessible: '" + src + "' (" + e + ")");
+            }
+
+        } finally {
+            if (source != null) {
+                this.resolver.release(source);
             }
         }
-        values[0] = mounts;
-        values[1] = source.getValidity();
-        
-        // Cache it with the source validity
-        this.mountTables.put(uri, values);
-        
-        return mounts;
-        
     }
 
     public Map match(String pattern, Map objectModel, Parameters parameters) throws PatternException {
         Map mounts;
-        
         try {
             mounts = getMountTable(pattern);
-        } catch(PatternException pe) {
+        } catch (PatternException pe) {
             throw pe;
-        } catch(Exception e) {
+        } catch (Exception e) {
             throw new PatternException(e);
         }
-        
+
         // Get the request URI
         Request request = ObjectModelHelper.getRequest(objectModel);
         String uri = request.getSitemapURI();
-        
+
         // and search for a matching prefix
         Iterator iter = mounts.entrySet().iterator();
-        while(iter.hasNext()) {
-            Map.Entry entry = (Map.Entry)iter.next();
-            String prefix = (String)entry.getKey();
+        while (iter.hasNext()) {
+            Map.Entry entry = (Map.Entry) iter.next();
+            String prefix = (String) entry.getKey();
             if (uri.startsWith(prefix)) {
                 // Found it
                 Map result = new HashMap(2);
                 result.put("uri-prefix", prefix);
                 result.put("src", entry.getValue());
-                
+
                 // Return immediately
                 return result;
             }
         }
-        
+
         // Not found
         return null;
     }