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; }