[prev in list] [next in list] [prev in thread] [next in thread]
List: xml-cocoon-cvs
Subject: svn commit: r1573205 [4/5] - in /cocoon/branches/BRANCH_2_1_X-dojo1_1: ./ legal/ lib/ lib/core/ lib/
From: ilgrosso () apache ! org
Date: 2014-03-01 18:02:20
Message-ID: 20140301180225.CD5102388AA6 () eris ! apache ! org
[Download RAW message or body]
Modified: cocoon/branches/BRANCH_2_1_X-dojo1_1/src/java/org/apache/cocoon/components/flow/ContinuationsManagerImpl.java
URL: http://svn.apache.org/viewvc/cocoon/branches/BRANCH_2_1_X-dojo1_1/src/java/org/ap \
ache/cocoon/components/flow/ContinuationsManagerImpl.java?rev=1573205&r1=1573204&r2=1573205&view=diff
==============================================================================
--- cocoon/branches/BRANCH_2_1_X-dojo1_1/src/java/org/apache/cocoon/components/flow/ContinuationsManagerImpl.java \
(original)
+++ cocoon/branches/BRANCH_2_1_X-dojo1_1/src/java/org/apache/cocoon/components/flow/ContinuationsManagerImpl.java \
Sat Mar 1 18:02:14 2014 @@ -72,7 +72,7 @@ import org.apache.excalibur.instrument.V
* this setting for web applications. Set "session-bound-continuations"
* configuration option to true to activate this mode.</li>
* </ul>
- *
+ *
* @author <a href="mailto:ovidiu@cup.hp.com">Ovidiu Predescu </a>
* @author <a href="mailto:Michael.Melhem@managesoft.com">Michael Melhem </a>
* @since March 19, 2002
@@ -83,7 +83,7 @@ public class ContinuationsManagerImpl
extends AbstractLogEnabled
implements ContinuationsManager, Component, Configurable,
ThreadSafe, Instrumentable, Serviceable, Contextualizable {
-
+
private static final int CONTINUATION_ID_LENGTH = 20;
/**
@@ -141,7 +141,7 @@ public class ContinuationsManagerImpl
}
public void contextualize(Context context) throws ContextException {
- this.context = context;
+ this.context = context;
}
public void service(ServiceManager manager) throws ServiceException {
@@ -152,12 +152,12 @@ public class ContinuationsManagerImpl
this.defaultTimeToLive = config.getAttributeAsInteger("time-to-live", (3600 \
* 1000));
this.isContinuationSharingBugCompatible = \
config.getAttributeAsBoolean("continuation-sharing-bug-compatible", \
false);
this.bindContinuationsToSession = config.getAttributeAsBoolean( \
"session-bound-continuations", false );
-
+
// create a global ContinuationsHolder if this the \
"session-bound-continuations" parameter is set to false if \
(!this.bindContinuationsToSession) { this.continuationsHolder = new \
WebContinuationsHolder(); }
-
+
// create a thread that invalidates the continuations
final Configuration expireConf = config.getChild("expirations-check");
final long initialDelay = expireConf.getChild("offset", \
true).getValueAsLong(180000); @@ -200,7 +200,7 @@ public class \
ContinuationsManagerImpl public WebContinuation createWebContinuation(Object kont,
WebContinuation parent,
int timeToLive,
- String interpreterId,
+ String interpreterId,
ContinuationsDisposer disposer) {
int ttl = timeToLive == 0 ? defaultTimeToLive : timeToLive;
@@ -226,22 +226,22 @@ public class ContinuationsManagerImpl
if (continuationsHolder == null) {
return null;
}
-
+
WebContinuation kont = continuationsHolder.get(id);
if (kont == null) {
- return null;
+ return null;
}
-
+
if (kont.hasExpired()) {
removeContinuation(continuationsHolder, kont);
return null;
}
-
+
if (!kont.interpreterMatches(interpreterId)) {
if (getLogger().isWarnEnabled()) {
- getLogger().warn("WK: Continuation (" + kont.getId()
- + ") lookup for wrong interpreter. Bound to: "
- + kont.getInterpreterId() + ", looked up for: "
+ getLogger().warn("WK: Continuation (" + kont.getId()
+ + ") lookup for wrong interpreter. Bound to: "
+ + kont.getInterpreterId() + ", looked up for: "
+ interpreterId);
}
@@ -449,17 +449,21 @@ public class ContinuationsManagerImpl
* continuationsHolder.
*/
protected void invalidateContinuations(WebContinuationsHolder \
continuationsHolder) { + // It's not possible to just iterate over \
continuationsHolder.holder since _invalidate(..) + // calls remove(..) on the \
map leading to ConcurrentModification at the end. + WebContinuation[] \
continuations; synchronized (continuationsHolder.holder) {
- for (Iterator iter = continuationsHolder.holder.values().iterator(); \
iter.hasNext();) {
- WebContinuation wk = (WebContinuation) iter.next();
- _detach(wk);
- _invalidate(continuationsHolder, wk);
- }
+ continuations = new WebContinuation[continuationsHolder.holder.size()];
+ continuations = (WebContinuation[]) \
continuationsHolder.holder.values().toArray(continuations); + }
+ for (int i = 0; i < continuations.length; i++) {
+ _detach(continuations[i]);
+ _invalidate(continuationsHolder, continuations[i]);
}
}
/**
- * Lookup a proper web continuations holder.
+ * Lookup a proper web continuations holder.
* @param createNew
* should the manager create a continuations holder in session
* when none found?
@@ -468,7 +472,7 @@ public class ContinuationsManagerImpl
//there is only one holder if continuations are not bound to session
if (!this.bindContinuationsToSession)
return this.continuationsHolder;
-
+
//if continuations bound to session lookup a proper holder in the session
Map objectModel = ContextHelper.getObjectModel(this.context);
Request request = ObjectModelHelper.getRequest(objectModel);
@@ -477,7 +481,7 @@ public class ContinuationsManagerImpl
return null;
Session session = request.getSession(true);
- WebContinuationsHolder holder =
+ WebContinuationsHolder holder =
(WebContinuationsHolder) session.getAttribute(
WebContinuationsHolder.CONTINUATIONS_HOLDER);
if (!createNew)
@@ -503,7 +507,7 @@ public class ContinuationsManagerImpl
rootWebContinuations.add(webContinuation);
}
}
-
+
Set clonedRootWebContinuations = new HashSet();
for (Iterator iter = rootWebContinuations.iterator(); iter.hasNext();) {
WebContinuation rootContinuation = (WebContinuation) iter.next();
@@ -514,7 +518,7 @@ public class ContinuationsManagerImpl
/**
* Get a list of all web continuations (data only)
- *
+ *
* @deprecated
*/
public List getWebContinuationsDataBeanList() {
@@ -535,7 +539,7 @@ public class ContinuationsManagerImpl
*/
protected void displayExpireSet() {
StringBuffer wkSet = new StringBuffer("\nWK; Expire set size: ");
-
+
synchronized (this.expirations) {
wkSet.append(this.expirations.size());
for (Iterator i = this.expirations.iterator(); i.hasNext();) {
@@ -555,7 +559,7 @@ public class ContinuationsManagerImpl
/**
* Dump to Log file all <code>WebContinuation</code>s
* in the system.
- *
+ *
* This method will be changed to be an internal method solely for debugging
* purposes just like {@link #displayExpireSet()}.
*/
@@ -572,11 +576,11 @@ public class ContinuationsManagerImpl
/**
* A holder for WebContinuations. When bound to session notifies the
* continuations manager of session invalidation.
- *
+ *
* For thread-safe access you have to synchronize on the Map {@link #holder}!
*/
protected class WebContinuationsHolder implements HttpSessionBindingListener {
-
+
private final static String CONTINUATIONS_HOLDER = \
"o.a.c.c.f.SCMI.WebContinuationsHolder";
private Map holder = Collections.synchronizedMap(new HashMap());
@@ -593,14 +597,10 @@ public class ContinuationsManagerImpl
this.holder.remove(wk.getId());
}
- public Set getContinuationIds() {
- return holder.keySet();
- }
-
public boolean contains(String continuationId) {
return this.holder.containsKey(continuationId);
}
-
+
public boolean contains(WebContinuation wk) {
return contains(wk.getId());
}
Modified: cocoon/branches/BRANCH_2_1_X-dojo1_1/src/java/org/apache/cocoon/components/modules/input/XPathXMLFileModule.java
URL: http://svn.apache.org/viewvc/cocoon/branches/BRANCH_2_1_X-dojo1_1/src/java/org/ap \
ache/cocoon/components/modules/input/XPathXMLFileModule.java?rev=1573205&r1=1573204&r2=1573205&view=diff
==============================================================================
--- cocoon/branches/BRANCH_2_1_X-dojo1_1/src/java/org/apache/cocoon/components/modules/input/XPathXMLFileModule.java \
(original)
+++ cocoon/branches/BRANCH_2_1_X-dojo1_1/src/java/org/apache/cocoon/components/modules/input/XPathXMLFileModule.java \
Sat Mar 1 18:02:14 2014 @@ -1,515 +1,531 @@
-package org.apache.cocoon.components.modules.input;
-
-import org.apache.avalon.framework.service.ServiceException;
-import org.apache.avalon.framework.service.ServiceManager;
-import org.apache.avalon.framework.service.Serviceable;
-import org.apache.avalon.framework.thread.ThreadSafe;
-import org.apache.avalon.framework.configuration.Configuration;
-import org.apache.avalon.framework.configuration.ConfigurationException;
-import org.apache.excalibur.source.SourceResolver;
-import org.apache.excalibur.source.SourceValidity;
-import org.apache.excalibur.source.Source;
-import org.apache.excalibur.store.Store;
-import org.apache.cocoon.components.source.SourceUtil;
-import org.apache.cocoon.components.treeprocessor.variables.VariableResolverFactory;
-import org.apache.cocoon.components.treeprocessor.variables.VariableResolver;
-
-import org.apache.cocoon.sitemap.PatternException;
-import org.apache.cocoon.ProcessingException;
-import org.apache.commons.collections.map.ReferenceMap;
-import org.apache.commons.collections.map.AbstractReferenceMap;
-import org.w3c.dom.Document;
-import org.xml.sax.SAXException;
-
-import java.util.Map;
-import java.net.MalformedURLException;
-import java.io.IOException;
-
-/**
- * <grammar>
- * <define name="input.module.config.contents" combine="choice">
- * <optional><element name="cacheable"><data \
type="boolean"/></element></optional>
- * <optional><element name="reloadable"><data \
type="boolean"/></element></optional>
- * <optional>
- * <ref name="org.apache.cocoon.components.modules.input.XPathXMLFileModule:file">
- * </optional>
- * <optional><element name="cache-role"><data \
type="String"/></element></optional>
- * </define>
- * <p/>
- * <define name="input.module.runtime.contents" combine="choice">
- * <optional>
- * <ref name="org.apache.cocoon.components.modules.input.XPathXMLFileModule:file">
- * </optional>
- * </define>
- * <p/>
- * <define name="org.apache.cocoon.components.modules.input.XPathXMLFileModule:file">
- * <element name="file">
- * <attribute name="src"><data type="anyURI"/></attribute>
- * <optional><attribute name="cacheable"><data \
type="boolean"/></attribute></optional>
- * <optional><attribute name="reloadable"><data \
type="boolean"/></attribute></optional>
- * </element>
- * </define>
- * </grammar>
- * <p/>
- * This module provides an Input Module interface to any XML document, by using
- * XPath expressions as attribute keys.
- * The XML can be obtained from any Cocoon <code>Source</code> (e.g.,
- * <code>cocoon:/...</code>, <code>context://..</code>, and regular URLs).
- * Sources can be cached in memory for better performance and reloaded if
- * changed. The source can also contain references to other input modules to allow \
the source
- * file name to be determined dynamically.
- * <p/>
- * Caching and reloading can be turned on / off (default: caching on,
- * reloading off) through <code><reloadable>false</reloadable></code>
- * and <code><cacheable>false</cacheable></code>. The file
- * (source) to use is specified through <code><file
- * src="protocol:path/to/file.xml" reloadable="true" cacheable="true"/></code>
- * optionally overriding the defaults for caching and/or reloading. When specfied as \
attributes
- * to the file element the values for cacheable and reloadable may be input module \
references which
- * will be resolved on every call. These must resolve to 'true' or 'false'.
- * </>
- * The XML documents will be cached using the Store configured via the cache-role \
configuration
- * element. If not specified the default Store as specified in this classes ROLE \
attribute will
- * be used.
- * <p/>
- * In addition, xpath expressions can be cached for higher performance.
- * Thus, if an expression has been evaluated for a file, the result
- * is cached and will be reused, the expression is not evaluated
- * a second time. This can be turned off using the <code>cache-expressions</code>
- * configuration option.
- *
- * @version $Id: $
- */
-public class XPathXMLFileModule extends AbstractInputModule
- implements Serviceable, ThreadSafe
-{
- public static final String ROLE = Store.ROLE + "/XPathXMLFileTransientStore";
- /**
- * Contains all globally registered extension classes and
- * packages. Thus the lookup and loading of globally registered
- * extensions is done only once.
- */
- protected JXPathHelperConfiguration configuration;
-
- /**
- * Static (cocoon.xconf) configuration location, for error reporting
- */
- String staticConfLocation;
-
- /**
- * Cached documents
- */
- private Store cache;
-
- /**
- * Determines whether the configured source document should be cached.
- */
- private String cacheParm;
- private Boolean cacheSource;
-
- /**
- * Determines whether the configured source document should be reloaded.
- */
- private String reloadParm;
- private Boolean reloadSource;
-
- /**
- * Default value for reloadability of sources. Defaults to false.
- */
- boolean reloadAll;
- /**
- * Default value for cacheability of xpath expressions. Defaults to true.
- */
- private boolean cacheExpressions;
-
- /**
- * Whether the source needs to be resolved.
- */
- private boolean needsResolve;
-
- /**
- * Overrides attribute name
- */
- protected String parameter;
-
- /**
- * Default src
- */
- private String src;
-
- protected SourceResolver resolver;
- protected ServiceManager manager;
-
-
- /* (non-Javadoc)
- * @see org.apache.avalon.framework.service.Serviceable#service(org.apache.avalon.framework.service.ServiceManager)
- */
- public void service(ServiceManager manager) throws ServiceException {
- this.manager = manager;
- this.resolver = (SourceResolver) manager.lookup(SourceResolver.ROLE);
- }
-
- /**
- * Static (cocoon.xconf) configuration.
- * Configuration is expected to be of the form:
- * <...>
- * <reloadable><b>true</b>|false</reloadable>
- * <cacheable><b>true</b>|false</cacheable>
- * <cache-role>org.apache.excalibur.store.Store/TransientStore</cache-role>
- * <file src="<i>src</i>"/>
- * ...
- * </...>
- * <p/>
- * The <file/> element specifies a file pattern. Only one
- * <file> can be specified, however it can contain references to input \
modules which will be resolved
- * each time the module is used. The configured <i>src</i> is used if not
- * overridden via a file parameter in the sitemap.
- *
- * @param config a <code>Configuration</code> value, as described above.
- * @throws org.apache.avalon.framework.configuration.ConfigurationException
- * if an error occurs
- */
- public void configure(Configuration config) throws ConfigurationException {
- this.configuration = JXPathHelper.setup(config);
- this.staticConfLocation = config.getLocation();
- Configuration roleConfig = config.getChild("cache-role", true);
- boolean cacheAll = config.getChild("cacheable").getValueAsBoolean(true);
- this.reloadAll = config.getChild("reloadable").getValueAsBoolean(true);
- String cacheRole = roleConfig.getValue(ROLE);
-
- if (getLogger().isDebugEnabled()) {
- getLogger().debug("Using cache " + cacheRole);
- }
-
- try {
- this.cache = (Store) this.manager.lookup(cacheRole);
- } catch (ServiceException ce) {
- throw new ConfigurationException("Unable to lookup cache: " + cacheRole, \
ce);
- }
-
- Configuration fileConfig = config.getChild("file");
-
- this.src = fileConfig.getAttribute("src");
- this.cacheParm = fileConfig.getAttribute("cacheable", null);
- this.reloadParm = fileConfig.getAttribute("reloadable", null);
- if (this.cacheParm == null) {
- this.cacheSource = Boolean.valueOf(cacheAll);
- } else if (VariableResolverFactory.needsResolve(this.cacheParm)) {
- this.cacheSource = null;
- } else {
- this.cacheSource = Boolean.valueOf(this.cacheParm);
- }
- if (this.reloadParm == null) {
- this.reloadSource = Boolean.valueOf(this.reloadAll);
- } else if (VariableResolverFactory.needsResolve(this.reloadParm)) {
- this.reloadSource = null;
- } else {
- this.reloadSource = Boolean.valueOf(this.reloadParm);
- }
-
- // init caches
- this.cacheExpressions = \
config.getChild("cache-expressions").getValueAsBoolean(true);
- this.needsResolve = VariableResolverFactory.needsResolve(this.src);
- }
-
- /**
- * Dispose this component
- */
- public void dispose() {
- super.dispose();
- if (this.manager != null) {
- this.manager.release(this.resolver);
- this.manager.release(this.cache);
- this.resolver = null;
- this.cache = null;
- this.manager = null;
- }
- }
-
- public Object getAttribute(String name, Configuration modeConf, Map objectModel)
- throws ConfigurationException {
- return getAttribute(name, modeConf, objectModel, false);
- }
-
- public Object[] getAttributeValues(String name, Configuration modeConf, Map \
objectModel)
- throws ConfigurationException {
- Object result = getAttribute(name, modeConf, objectModel, true);
- return (result != null ? (Object[]) result : null);
- }
- /**
- * Get the DocumentInfo for the DOM object that JXPath will operate on when \
evaluating
- * attributes. This DOM is loaded from a Source, specified in the
- * modeConf, or (if modeConf is null) from the
- * {@link #configure(org.apache.avalon.framework.configuration.Configuration)}.
- *
- * @param name The JXPath to retrieve
- * @param modeConf The dynamic configuration for the current operation. May
- * be <code>null</code>, in which case static (cocoon.xconf) \
configuration
- * is used. Configuration is expected to have a <file> \
child node, and
- * be of the form:
- * <...>
- * <file src="..." reloadable="true|false"/>
- * </...>
- * @param objectModel Object Model for the current module operation.
- * @param getValues true if multiple values should be retrieve, false otherwise
- * @return the result of the XPath query into the XML document
- * @throws ConfigurationException if an error occurs.
- */
- private Object getAttribute(String name, Configuration modeConf, Map \
objectModel, boolean getValues)
- throws ConfigurationException {
-
- if (modeConf != null) {
- name = modeConf.getChild("parameter").getValue(this.parameter != null ? \
this.parameter : name);
- }
-
- boolean hasDynamicConf = false; // whether we have a <file src="..."> \
dynamic configuration
- Configuration fileConf = null; // the nested <file>, if any
-
- if (modeConf != null && modeConf.getChildren().length > 0) {
- fileConf = modeConf.getChild("file", false);
- if (fileConf == null) {
- if (getLogger().isDebugEnabled()) {
- getLogger().debug("Missing 'file' child element at " + \
modeConf.getLocation());
- }
- } else {
- hasDynamicConf = true;
- }
- }
-
- String src = this.src;
- Boolean cacheSource = this.cacheSource;
- Boolean reloadSource = this.cacheSource;
- boolean needsResolve = this.needsResolve;
- String cacheParm = this.cacheParm;
- String reloadParm = this.reloadParm;
-
- if (hasDynamicConf) {
- src = fileConf.getAttribute("src");
- cacheParm = fileConf.getAttribute("cacheable", this.cacheParm);
- reloadParm = fileConf.getAttribute("reloadable", this.reloadParm);
- if (cacheParm == null) {
- cacheSource = this.cacheSource;
- } else if (VariableResolverFactory.needsResolve(cacheParm)) {
- cacheSource = null;
- if (cacheSource == null) {
- try {
- VariableResolver varResolver = \
VariableResolverFactory.getResolver(cacheParm, this.manager);
- cacheSource = \
Boolean.valueOf(varResolver.resolve(objectModel));
- } catch (PatternException pe) {
- throw new ConfigurationException("Error resolving " + \
cacheParm, pe);
- }
- }
- } else {
- cacheSource = Boolean.valueOf(cacheParm);
- }
- if (reloadParm == null) {
- reloadSource = this.reloadSource;
- } else if (VariableResolverFactory.needsResolve(reloadParm)) {
- reloadSource = null;
- } else {
- reloadSource = Boolean.valueOf(reloadParm);
- }
- needsResolve = true;
- }
- if (cacheSource == null) {
- try {
- VariableResolver varResolver = \
VariableResolverFactory.getResolver(cacheParm, this.manager);
- cacheSource = Boolean.valueOf(varResolver.resolve(objectModel));
- } catch (PatternException pe) {
- throw new ConfigurationException("Error resolving " + cacheParm, \
pe);
- }
- }
- if (reloadSource == null) {
- try {
- VariableResolver varResolver =
- VariableResolverFactory.getResolver(reloadParm, this.manager);
- reloadSource = Boolean.valueOf(varResolver.resolve(objectModel));
- } catch (PatternException pe) {
- throw new ConfigurationException("Error resolving " + reloadParm, \
pe);
- }
- }
-
- if (src == null) {
- throw new ConfigurationException(
- "No source specified"
- + (modeConf != null ? ", either dynamically in " + \
modeConf.getLocation() + ", or " : "")
- + " statically in "
- + staticConfLocation);
- }
-
- if (needsResolve) {
- try {
- VariableResolver varResolver = \
VariableResolverFactory.getResolver(src, this.manager);
- src = varResolver.resolve(objectModel);
- } catch (PatternException pe) {
- throw new ConfigurationException("Error resolving variables for " + \
src, pe);
- }
- }
-
- Object result;
-
- if (cacheSource.booleanValue()) {
- DocumentInfo info = (DocumentInfo) this.cache.get(src);
- if (info == null || (reloadSource.booleanValue() && !info.isValid())) {
- Source docSource = null;
- try {
- docSource = resolver.resolveURI(src);
- DocumentInfo newInfo = new DocumentInfo(src, \
SourceUtil.toDOM(docSource),
- docSource.getValidity(), this.cacheExpressions, \
this.resolver);
- synchronized(this.cache) {
- DocumentInfo cachedInfo = (DocumentInfo)this.cache.get(src);
- if (cachedInfo == null || cachedInfo == info) {
- this.cache.store(src, newInfo);
- info = newInfo;
- } else {
- info = cachedInfo;
- }
- }
- } catch (MalformedURLException mue) {
- throw new ConfigurationException("Unable to resolve " + src, \
mue);
- } catch (IOException ioe) {
- throw new ConfigurationException("Unable to access" + src, ioe);
- } catch (ProcessingException pe) {
- throw new ConfigurationException("Unable to process " + src, \
pe);
- } catch (SAXException se) {
- throw new ConfigurationException("Error processing XML document \
" + src, se);
- } finally {
- if (docSource != null) {
- resolver.release(docSource);
- }
- }
- }
- if (info.cacheExpressions) {
- Map cache = getValues ? info.expressionValuesCache : \
info.expressionCache;
- synchronized (cache) {
- if (cache.containsKey(name)) {
- result = cache.get(name);
- if (getLogger().isDebugEnabled()) {
- getLogger().debug("for " + name + " using cached result \
" + result);
- }
- } else {
- result = getResult(name, info.document, modeConf, \
getValues);
- if (result != null) {
- cache.put(name, result);
- if (getLogger().isDebugEnabled()) {
- getLogger().debug("for " + name + " newly caching \
result " + result);
- }
- } else {
- if (getLogger().isDebugEnabled()) {
- getLogger().debug("for " + name + " result is \
null");
- }
- }
- }
- }
- } else {
- result = getResult(name, info.document, modeConf, getValues);
- if (getLogger().isDebugEnabled()) {
- getLogger().debug("for " + name + " result is " + result);
- }
- }
- } else {
- Source docSource = null;
- try {
- docSource = resolver.resolveURI(src);
- result = getResult(name, SourceUtil.toDOM(docSource), modeConf, \
getValues);
- if (getLogger().isDebugEnabled()) {
- getLogger().debug("for " + name + " result is " + result);
- }
- } catch (MalformedURLException mue) {
- throw new ConfigurationException("Unable to resolve " + src, mue);
- } catch (IOException ioe) {
- throw new ConfigurationException("Unable to access" + src, ioe);
- } catch (ProcessingException pe) {
- throw new ConfigurationException("Unable to process " + src, pe);
- } catch (SAXException se) {
- throw new ConfigurationException("Error processing XML document " + \
src, se);
- } finally {
- if (docSource != null) {
- resolver.release(docSource);
- }
- }
- }
-
- return result;
- }
-
- private Object getResult(String name, Document document, Configuration modeConf, \
boolean getValues)
- throws ConfigurationException {
- Object result;
-
- if (getValues) {
- result = JXPathHelper.getAttributeValues(name, modeConf, \
this.configuration, document);
- } else {
- result = JXPathHelper.getAttributeValue(name, modeConf, \
this.configuration, document);
- }
- return result;
- }
-
- /**
- * Used to keep track of the Document, its validity and any cached expressions.
- */
- private static class DocumentInfo
- {
- public DocumentInfo(String uri, Document doc, SourceValidity validity, \
boolean cacheExpressions,
- SourceResolver resolver) {
- this.cacheExpressions = cacheExpressions;
- if (cacheExpressions) {
- expressionCache = new ReferenceMap(AbstractReferenceMap.SOFT, \
AbstractReferenceMap.SOFT);
- expressionValuesCache = new ReferenceMap(AbstractReferenceMap.SOFT, \
AbstractReferenceMap.SOFT);
- }
- this.resolver = resolver;
- this.uri = uri;
- this.document = doc;
- this.validity = validity;
- }
-
- private boolean cacheExpressions;
-
- private final String uri;
-
- private final SourceValidity validity;
-
- private final SourceResolver resolver;
-
- /**
- * Source content cached as DOM Document
- */
- private final Document document;
-
- private Map expressionCache;
- private Map expressionValuesCache;
-
- /**
- * Returns true if the document is valid, false otherwise.
- * <p/>
- *
- * @return returns true if the document is valid, false otherwise.
- */
- private boolean isValid() {
- Source src = null;
- boolean result = true;
-
- try {
- int valid = validity == null ? SourceValidity.INVALID : \
validity.isValid();
- if (valid == SourceValidity.UNKNOWN) {
- // Get new source and validity
- src = resolver.resolveURI(this.uri);
- SourceValidity newValidity = src.getValidity();
- valid = validity.isValid(newValidity);
- }
- if (valid != SourceValidity.VALID) {
- result = false;
- }
- }
- catch (Exception ex) {
- result = false;
- }
- finally {
- if (src != null) {
- resolver.release(src);
- }
- }
- return result;
- }
- }
+/*
+ * 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.
+ */
+package org.apache.cocoon.components.modules.input;
+
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.service.Serviceable;
+import org.apache.avalon.framework.thread.ThreadSafe;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.excalibur.source.SourceResolver;
+import org.apache.excalibur.source.SourceValidity;
+import org.apache.excalibur.source.Source;
+import org.apache.excalibur.store.Store;
+import org.apache.cocoon.components.source.SourceUtil;
+import org.apache.cocoon.components.treeprocessor.variables.VariableResolverFactory;
+import org.apache.cocoon.components.treeprocessor.variables.VariableResolver;
+
+import org.apache.cocoon.sitemap.PatternException;
+import org.apache.cocoon.ProcessingException;
+import org.apache.commons.collections.map.ReferenceMap;
+import org.apache.commons.collections.map.AbstractReferenceMap;
+import org.w3c.dom.Document;
+import org.xml.sax.SAXException;
+
+import java.util.Map;
+import java.net.MalformedURLException;
+import java.io.IOException;
+
+/**
+ * <grammar>
+ * <define name="input.module.config.contents" combine="choice">
+ * <optional><element name="cacheable"><data \
type="boolean"/></element></optional> + * <optional><element \
name="reloadable"><data type="boolean"/></element></optional> + * <optional>
+ * <ref name="org.apache.cocoon.components.modules.input.XPathXMLFileModule:file">
+ * </optional>
+ * <optional><element name="cache-role"><data \
type="String"/></element></optional> + * </define>
+ * <p/>
+ * <define name="input.module.runtime.contents" combine="choice">
+ * <optional>
+ * <ref name="org.apache.cocoon.components.modules.input.XPathXMLFileModule:file">
+ * </optional>
+ * </define>
+ * <p/>
+ * <define name="org.apache.cocoon.components.modules.input.XPathXMLFileModule:file">
+ * <element name="file">
+ * <attribute name="src"><data type="anyURI"/></attribute>
+ * <optional><attribute name="cacheable"><data \
type="boolean"/></attribute></optional> + * <optional><attribute \
name="reloadable"><data type="boolean"/></attribute></optional> + * </element>
+ * </define>
+ * </grammar>
+ * <p/>
+ * This module provides an Input Module interface to any XML document, by using
+ * XPath expressions as attribute keys.
+ * The XML can be obtained from any Cocoon <code>Source</code> (e.g.,
+ * <code>cocoon:/...</code>, <code>context://..</code>, and regular URLs).
+ * Sources can be cached in memory for better performance and reloaded if
+ * changed. The source can also contain references to other input modules to allow \
the source + * file name to be determined dynamically.
+ * <p/>
+ * Caching and reloading can be turned on / off (default: caching on,
+ * reloading off) through <code><reloadable>false</reloadable></code>
+ * and <code><cacheable>false</cacheable></code>. The file
+ * (source) to use is specified through <code><file
+ * src="protocol:path/to/file.xml" reloadable="true" cacheable="true"/></code>
+ * optionally overriding the defaults for caching and/or reloading. When specfied as \
attributes + * to the file element the values for cacheable and reloadable may be \
input module references which + * will be resolved on every call. These must resolve \
to 'true' or 'false'. + * </>
+ * The XML documents will be cached using the Store configured via the cache-role \
configuration + * element. If not specified the default Store as specified in this \
classes ROLE attribute will + * be used.
+ * <p/>
+ * In addition, xpath expressions can be cached for higher performance.
+ * Thus, if an expression has been evaluated for a file, the result
+ * is cached and will be reused, the expression is not evaluated
+ * a second time. This can be turned off using the <code>cache-expressions</code>
+ * configuration option.
+ *
+ * @version $Id: $
+ */
+public class XPathXMLFileModule extends AbstractInputModule
+ implements Serviceable, ThreadSafe
+{
+ public static final String ROLE = Store.ROLE + "/XPathXMLFileTransientStore";
+ /**
+ * Contains all globally registered extension classes and
+ * packages. Thus the lookup and loading of globally registered
+ * extensions is done only once.
+ */
+ protected JXPathHelperConfiguration configuration;
+
+ /**
+ * Static (cocoon.xconf) configuration location, for error reporting
+ */
+ String staticConfLocation;
+
+ /**
+ * Cached documents
+ */
+ private Store cache;
+
+ /**
+ * Determines whether the configured source document should be cached.
+ */
+ private String cacheParm;
+ private Boolean cacheSource;
+
+ /**
+ * Determines whether the configured source document should be reloaded.
+ */
+ private String reloadParm;
+ private Boolean reloadSource;
+
+ /**
+ * Default value for reloadability of sources. Defaults to false.
+ */
+ boolean reloadAll;
+ /**
+ * Default value for cacheability of xpath expressions. Defaults to true.
+ */
+ private boolean cacheExpressions;
+
+ /**
+ * Whether the source needs to be resolved.
+ */
+ private boolean needsResolve;
+
+ /**
+ * Overrides attribute name
+ */
+ protected String parameter;
+
+ /**
+ * Default src
+ */
+ private String src;
+
+ protected SourceResolver resolver;
+ protected ServiceManager manager;
+
+
+ /* (non-Javadoc)
+ * @see org.apache.avalon.framework.service.Serviceable#service(org.apache.avalon.framework.service.ServiceManager)
+ */
+ public void service(ServiceManager manager) throws ServiceException {
+ this.manager = manager;
+ this.resolver = (SourceResolver) manager.lookup(SourceResolver.ROLE);
+ }
+
+ /**
+ * Static (cocoon.xconf) configuration.
+ * Configuration is expected to be of the form:
+ * <...>
+ * <reloadable><b>true</b>|false</reloadable>
+ * <cacheable><b>true</b>|false</cacheable>
+ * <cache-role>org.apache.excalibur.store.Store/TransientStore</cache-role>
+ * <file src="<i>src</i>"/>
+ * ...
+ * </...>
+ * <p/>
+ * The <file/> element specifies a file pattern. Only one
+ * <file> can be specified, however it can contain references to input \
modules which will be resolved + * each time the module is used. The configured \
<i>src</i> is used if not + * overridden via a file parameter in the sitemap.
+ *
+ * @param config a <code>Configuration</code> value, as described above.
+ * @throws org.apache.avalon.framework.configuration.ConfigurationException
+ * if an error occurs
+ */
+ public void configure(Configuration config) throws ConfigurationException {
+ this.configuration = JXPathHelper.setup(config);
+ this.staticConfLocation = config.getLocation();
+ Configuration roleConfig = config.getChild("cache-role", true);
+ boolean cacheAll = config.getChild("cacheable").getValueAsBoolean(true);
+ this.reloadAll = config.getChild("reloadable").getValueAsBoolean(true);
+ String cacheRole = roleConfig.getValue(ROLE);
+
+ if (getLogger().isDebugEnabled()) {
+ getLogger().debug("Using cache " + cacheRole);
+ }
+
+ try {
+ this.cache = (Store) this.manager.lookup(cacheRole);
+ } catch (ServiceException ce) {
+ throw new ConfigurationException("Unable to lookup cache: " + cacheRole, \
ce); + }
+
+ Configuration fileConfig = config.getChild("file");
+
+ this.src = fileConfig.getAttribute("src");
+ this.cacheParm = fileConfig.getAttribute("cacheable", null);
+ this.reloadParm = fileConfig.getAttribute("reloadable", null);
+ if (this.cacheParm == null) {
+ this.cacheSource = Boolean.valueOf(cacheAll);
+ } else if (VariableResolverFactory.needsResolve(this.cacheParm)) {
+ this.cacheSource = null;
+ } else {
+ this.cacheSource = Boolean.valueOf(this.cacheParm);
+ }
+ if (this.reloadParm == null) {
+ this.reloadSource = Boolean.valueOf(this.reloadAll);
+ } else if (VariableResolverFactory.needsResolve(this.reloadParm)) {
+ this.reloadSource = null;
+ } else {
+ this.reloadSource = Boolean.valueOf(this.reloadParm);
+ }
+
+ // init caches
+ this.cacheExpressions = \
config.getChild("cache-expressions").getValueAsBoolean(true); + \
this.needsResolve = VariableResolverFactory.needsResolve(this.src); + }
+
+ /**
+ * Dispose this component
+ */
+ public void dispose() {
+ super.dispose();
+ if (this.manager != null) {
+ this.manager.release(this.resolver);
+ this.manager.release(this.cache);
+ this.resolver = null;
+ this.cache = null;
+ this.manager = null;
+ }
+ }
+
+ public Object getAttribute(String name, Configuration modeConf, Map objectModel)
+ throws ConfigurationException {
+ return getAttribute(name, modeConf, objectModel, false);
+ }
+
+ public Object[] getAttributeValues(String name, Configuration modeConf, Map \
objectModel) + throws ConfigurationException {
+ Object result = getAttribute(name, modeConf, objectModel, true);
+ return (result != null ? (Object[]) result : null);
+ }
+ /**
+ * Get the DocumentInfo for the DOM object that JXPath will operate on when \
evaluating + * attributes. This DOM is loaded from a Source, specified in the
+ * modeConf, or (if modeConf is null) from the
+ * {@link #configure(org.apache.avalon.framework.configuration.Configuration)}.
+ *
+ * @param name The JXPath to retrieve
+ * @param modeConf The dynamic configuration for the current operation. May
+ * be <code>null</code>, in which case static (cocoon.xconf) \
configuration + * is used. Configuration is expected to have \
a <file> child node, and + * be of the form:
+ * <...>
+ * <file src="..." reloadable="true|false"/>
+ * </...>
+ * @param objectModel Object Model for the current module operation.
+ * @param getValues true if multiple values should be retrieve, false otherwise
+ * @return the result of the XPath query into the XML document
+ * @throws ConfigurationException if an error occurs.
+ */
+ private Object getAttribute(String name, Configuration modeConf, Map \
objectModel, boolean getValues) + throws ConfigurationException {
+
+ if (modeConf != null) {
+ name = modeConf.getChild("parameter").getValue(this.parameter != null ? \
this.parameter : name); + }
+
+ boolean hasDynamicConf = false; // whether we have a <file src="..."> \
dynamic configuration + Configuration fileConf = null; // the nested <file>, \
if any +
+ if (modeConf != null && modeConf.getChildren().length > 0) {
+ fileConf = modeConf.getChild("file", false);
+ if (fileConf == null) {
+ if (getLogger().isDebugEnabled()) {
+ getLogger().debug("Missing 'file' child element at " + \
modeConf.getLocation()); + }
+ } else {
+ hasDynamicConf = true;
+ }
+ }
+
+ String src = this.src;
+ Boolean cacheSource = this.cacheSource;
+ Boolean reloadSource = this.cacheSource;
+ boolean needsResolve = this.needsResolve;
+ String cacheParm = this.cacheParm;
+ String reloadParm = this.reloadParm;
+
+ if (hasDynamicConf) {
+ src = fileConf.getAttribute("src");
+ cacheParm = fileConf.getAttribute("cacheable", this.cacheParm);
+ reloadParm = fileConf.getAttribute("reloadable", this.reloadParm);
+ if (cacheParm == null) {
+ cacheSource = this.cacheSource;
+ } else if (VariableResolverFactory.needsResolve(cacheParm)) {
+ cacheSource = null;
+ if (cacheSource == null) {
+ try {
+ VariableResolver varResolver = \
VariableResolverFactory.getResolver(cacheParm, this.manager); + \
cacheSource = Boolean.valueOf(varResolver.resolve(objectModel)); + \
} catch (PatternException pe) { + throw new \
ConfigurationException("Error resolving " + cacheParm, pe); + }
+ }
+ } else {
+ cacheSource = Boolean.valueOf(cacheParm);
+ }
+ if (reloadParm == null) {
+ reloadSource = this.reloadSource;
+ } else if (VariableResolverFactory.needsResolve(reloadParm)) {
+ reloadSource = null;
+ } else {
+ reloadSource = Boolean.valueOf(reloadParm);
+ }
+ needsResolve = true;
+ }
+ if (cacheSource == null) {
+ try {
+ VariableResolver varResolver = \
VariableResolverFactory.getResolver(cacheParm, this.manager); + \
cacheSource = Boolean.valueOf(varResolver.resolve(objectModel)); + } catch \
(PatternException pe) { + throw new ConfigurationException("Error \
resolving " + cacheParm, pe); + }
+ }
+ if (reloadSource == null) {
+ try {
+ VariableResolver varResolver =
+ VariableResolverFactory.getResolver(reloadParm, this.manager);
+ reloadSource = Boolean.valueOf(varResolver.resolve(objectModel));
+ } catch (PatternException pe) {
+ throw new ConfigurationException("Error resolving " + reloadParm, \
pe); + }
+ }
+
+ if (src == null) {
+ throw new ConfigurationException(
+ "No source specified"
+ + (modeConf != null ? ", either dynamically in " + \
modeConf.getLocation() + ", or " : "") + + " statically in "
+ + staticConfLocation);
+ }
+
+ if (needsResolve) {
+ try {
+ VariableResolver varResolver = \
VariableResolverFactory.getResolver(src, this.manager); + src = \
varResolver.resolve(objectModel); + } catch (PatternException pe) {
+ throw new ConfigurationException("Error resolving variables for " + \
src, pe); + }
+ }
+
+ Object result;
+
+ if (cacheSource.booleanValue()) {
+ DocumentInfo info = (DocumentInfo) this.cache.get(src);
+ if (info == null || (reloadSource.booleanValue() && !info.isValid())) {
+ Source docSource = null;
+ try {
+ docSource = resolver.resolveURI(src);
+ DocumentInfo newInfo = new DocumentInfo(src, \
SourceUtil.toDOM(docSource), + docSource.getValidity(), \
this.cacheExpressions, this.resolver); + synchronized(this.cache) \
{ + DocumentInfo cachedInfo = \
(DocumentInfo)this.cache.get(src); + if (cachedInfo == null || \
cachedInfo == info) { + this.cache.store(src, newInfo);
+ info = newInfo;
+ } else {
+ info = cachedInfo;
+ }
+ }
+ } catch (MalformedURLException mue) {
+ throw new ConfigurationException("Unable to resolve " + src, \
mue); + } catch (IOException ioe) {
+ throw new ConfigurationException("Unable to access" + src, ioe);
+ } catch (ProcessingException pe) {
+ throw new ConfigurationException("Unable to process " + src, \
pe); + } catch (SAXException se) {
+ throw new ConfigurationException("Error processing XML document \
" + src, se); + } finally {
+ if (docSource != null) {
+ resolver.release(docSource);
+ }
+ }
+ }
+ if (info.cacheExpressions) {
+ Map cache = getValues ? info.expressionValuesCache : \
info.expressionCache; + synchronized (cache) {
+ if (cache.containsKey(name)) {
+ result = cache.get(name);
+ if (getLogger().isDebugEnabled()) {
+ getLogger().debug("for " + name + " using cached result \
" + result); + }
+ } else {
+ result = getResult(name, info.document, modeConf, \
getValues); + if (result != null) {
+ cache.put(name, result);
+ if (getLogger().isDebugEnabled()) {
+ getLogger().debug("for " + name + " newly caching \
result " + result); + }
+ } else {
+ if (getLogger().isDebugEnabled()) {
+ getLogger().debug("for " + name + " result is \
null"); + }
+ }
+ }
+ }
+ } else {
+ result = getResult(name, info.document, modeConf, getValues);
+ if (getLogger().isDebugEnabled()) {
+ getLogger().debug("for " + name + " result is " + result);
+ }
+ }
+ } else {
+ Source docSource = null;
+ try {
+ docSource = resolver.resolveURI(src);
+ result = getResult(name, SourceUtil.toDOM(docSource), modeConf, \
getValues); + if (getLogger().isDebugEnabled()) {
+ getLogger().debug("for " + name + " result is " + result);
+ }
+ } catch (MalformedURLException mue) {
+ throw new ConfigurationException("Unable to resolve " + src, mue);
+ } catch (IOException ioe) {
+ throw new ConfigurationException("Unable to access" + src, ioe);
+ } catch (ProcessingException pe) {
+ throw new ConfigurationException("Unable to process " + src, pe);
+ } catch (SAXException se) {
+ throw new ConfigurationException("Error processing XML document " + \
src, se); + } finally {
+ if (docSource != null) {
+ resolver.release(docSource);
+ }
+ }
+ }
+
+ return result;
+ }
+
+ private Object getResult(String name, Document document, Configuration modeConf, \
boolean getValues) + throws ConfigurationException {
+ Object result;
+
+ if (getValues) {
+ result = JXPathHelper.getAttributeValues(name, modeConf, \
this.configuration, document); + } else {
+ result = JXPathHelper.getAttributeValue(name, modeConf, \
this.configuration, document); + }
+ return result;
+ }
+
+ /**
+ * Used to keep track of the Document, its validity and any cached expressions.
+ */
+ private static class DocumentInfo
+ {
+ public DocumentInfo(String uri, Document doc, SourceValidity validity, \
boolean cacheExpressions, + SourceResolver resolver) {
+ this.cacheExpressions = cacheExpressions;
+ if (cacheExpressions) {
+ expressionCache = new ReferenceMap(AbstractReferenceMap.SOFT, \
AbstractReferenceMap.SOFT); + expressionValuesCache = new \
ReferenceMap(AbstractReferenceMap.SOFT, AbstractReferenceMap.SOFT); + }
+ this.resolver = resolver;
+ this.uri = uri;
+ this.document = doc;
+ this.validity = validity;
+ }
+
+ private boolean cacheExpressions;
+
+ private final String uri;
+
+ private final SourceValidity validity;
+
+ private final SourceResolver resolver;
+
+ /**
+ * Source content cached as DOM Document
+ */
+ private final Document document;
+
+ private Map expressionCache;
+ private Map expressionValuesCache;
+
+ /**
+ * Returns true if the document is valid, false otherwise.
+ * <p/>
+ *
+ * @return returns true if the document is valid, false otherwise.
+ */
+ private boolean isValid() {
+ Source src = null;
+ boolean result = true;
+
+ try {
+ int valid = validity == null ? SourceValidity.INVALID : \
validity.isValid(); + if (valid == SourceValidity.UNKNOWN) {
+ // Get new source and validity
+ src = resolver.resolveURI(this.uri);
+ SourceValidity newValidity = src.getValidity();
+ valid = validity.isValid(newValidity);
+ }
+ if (valid != SourceValidity.VALID) {
+ result = false;
+ }
+ }
+ catch (Exception ex) {
+ result = false;
+ }
+ finally {
+ if (src != null) {
+ resolver.release(src);
+ }
+ }
+ return result;
+ }
+ }
}
\ No newline at end of file
Propchange: cocoon/branches/BRANCH_2_1_X-dojo1_1/src/java/org/apache/cocoon/components/modules/input/XPathXMLFileModule.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: cocoon/branches/BRANCH_2_1_X-dojo1_1/src/java/org/apache/cocoon/components/pipeline/impl/AbstractCachingProcessingPipeline.java
URL: http://svn.apache.org/viewvc/cocoon/branches/BRANCH_2_1_X-dojo1_1/src/java/org/ap \
ache/cocoon/components/pipeline/impl/AbstractCachingProcessingPipeline.java?rev=1573205&r1=1573204&r2=1573205&view=diff
==============================================================================
--- cocoon/branches/BRANCH_2_1_X-dojo1_1/src/java/org/apache/cocoon/components/pipeline/impl/AbstractCachingProcessingPipeline.java \
(original)
+++ cocoon/branches/BRANCH_2_1_X-dojo1_1/src/java/org/apache/cocoon/components/pipeline/impl/AbstractCachingProcessingPipeline.java \
Sat Mar 1 18:02:14 2014 @@ -36,6 +36,8 @@ import org.apache.cocoon.caching.Caching
import org.apache.cocoon.caching.ComponentCacheKey;
import org.apache.cocoon.caching.PipelineCacheKey;
import org.apache.cocoon.environment.Environment;
+import org.apache.cocoon.environment.ObjectModelHelper;
+import org.apache.cocoon.environment.commandline.AbstractCommandLineEnvironment;
import org.apache.cocoon.environment.http.HttpEnvironment;
import org.apache.cocoon.transformation.Transformer;
import org.apache.cocoon.util.HashUtil;
@@ -193,6 +195,9 @@ public abstract class AbstractCachingPro
// Avoid deadlock with self (see JIRA COCOON-1985).
Object current = \
env.getObjectModel().get(HttpEnvironment.HTTP_REQUEST_OBJECT); + if \
(current==null){ + current = \
env.getObjectModel().get(AbstractCommandLineEnvironment.CLI_REQUEST_ID); + \
} if (lock != null && lock != current) {
if (getLogger().isDebugEnabled()) {
getLogger().debug("Waiting on Lock '" + lockKey + "'");
@@ -243,6 +248,9 @@ public abstract class AbstractCachingPro
}
} else {
Object lock = \
env.getObjectModel().get(HttpEnvironment.HTTP_REQUEST_OBJECT); + \
if (lock == null){ + lock = \
env.getObjectModel().get(AbstractCommandLineEnvironment.CLI_REQUEST_ID); + \
} try {
transientStore.store(lockKey, lock);
} catch (IOException e) {
Modified: cocoon/branches/BRANCH_2_1_X-dojo1_1/src/java/org/apache/cocoon/components/treeprocessor/ConcreteTreeProcessor.java
URL: http://svn.apache.org/viewvc/cocoon/branches/BRANCH_2_1_X-dojo1_1/src/java/org/ap \
ache/cocoon/components/treeprocessor/ConcreteTreeProcessor.java?rev=1573205&r1=1573204&r2=1573205&view=diff
==============================================================================
--- cocoon/branches/BRANCH_2_1_X-dojo1_1/src/java/org/apache/cocoon/components/treeprocessor/ConcreteTreeProcessor.java \
(original)
+++ cocoon/branches/BRANCH_2_1_X-dojo1_1/src/java/org/apache/cocoon/components/treeprocessor/ConcreteTreeProcessor.java \
Sat Mar 1 18:02:14 2014 @@ -35,6 +35,7 @@ import org.apache.cocoon.components.Coco
import org.apache.cocoon.components.pipeline.ProcessingPipeline;
import org.apache.cocoon.environment.Environment;
import org.apache.cocoon.environment.ForwardRedirector;
+import org.apache.cocoon.environment.PermanentRedirector;
import org.apache.cocoon.environment.Redirector;
import org.apache.cocoon.environment.wrapper.EnvironmentWrapper;
import org.apache.cocoon.environment.wrapper.MutableEnvironmentFacade;
@@ -287,8 +288,10 @@ public class ConcreteTreeProcessor exten
// Get the processor that should process this request
// (see https://issues.apache.org/jira/browse/COCOON-1990).
ConcreteTreeProcessor processor = this;
- if (uri.startsWith("cocoon://"))
+ if (uri.startsWith("cocoon://")) {
processor = ((TreeProcessor)getRootProcessor()).concreteProcessor;
+ newEnv.changeContext("", \
((TreeProcessor)getRootProcessor()).source.getURI()); + }
// Process the redirect
// No more reset since with TreeProcessorRedirector, we need to pop values \
from the redirect location @@ -298,8 +301,15 @@ public class ConcreteTreeProcessor \
exten if ( facade != null ) {
newEnv = facade.getDelegate();
}
- if ( ((ForwardEnvironmentWrapper)newEnv).getRedirectURL() != null ) {
- environment.redirect( false, \
((ForwardEnvironmentWrapper)newEnv).getRedirectURL() ); +
+ ForwardEnvironmentWrapper forwardEnv = (ForwardEnvironmentWrapper) newEnv;
+ if (forwardEnv.hasRedirected()) {
+ if (forwardEnv.isPermanentRedirection() && environment instanceof \
PermanentRedirector) { + ((PermanentRedirector \
)environment).permanentRedirect(false, forwardEnv.getRedirectURL()); + }
+ else {
+ environment.redirect( false, forwardEnv.getRedirectURL() );
+ }
}
return result;
}
Modified: cocoon/branches/BRANCH_2_1_X-dojo1_1/src/java/org/apache/cocoon/environment/commandline/AbstractCommandLineEnvironment.java
URL: http://svn.apache.org/viewvc/cocoon/branches/BRANCH_2_1_X-dojo1_1/src/java/org/ap \
ache/cocoon/environment/commandline/AbstractCommandLineEnvironment.java?rev=1573205&r1=1573204&r2=1573205&view=diff
==============================================================================
--- cocoon/branches/BRANCH_2_1_X-dojo1_1/src/java/org/apache/cocoon/environment/commandline/AbstractCommandLineEnvironment.java \
(original)
+++ cocoon/branches/BRANCH_2_1_X-dojo1_1/src/java/org/apache/cocoon/environment/commandline/AbstractCommandLineEnvironment.java \
Sat Mar 1 18:02:14 2014 @@ -22,6 +22,7 @@ import org.apache.cocoon.Constants;
import org.apache.cocoon.ProcessingException;
import org.apache.cocoon.components.source.SourceUtil;
import org.apache.cocoon.environment.AbstractEnvironment;
+import org.apache.cocoon.environment.ObjectModelHelper;
import org.apache.cocoon.environment.Redirector;
import org.apache.excalibur.source.Source;
import org.apache.excalibur.source.SourceException;
@@ -32,6 +33,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.MalformedURLException;
+import java.util.Map;
/**
* This environment is used to save the requested file to disk.
@@ -43,6 +45,8 @@ import java.net.MalformedURLException;
public abstract class AbstractCommandLineEnvironment
extends AbstractEnvironment
implements Redirector {
+
+ public static final String CLI_REQUEST_ID = "clirequest-id";
protected String contentType;
protected int contentLength;
@@ -56,11 +60,36 @@ implements Redirector {
Logger log)
throws MalformedURLException {
super(uri, view, context);
- this.enableLogging(log);
- this.outputStream = stream;
- this.statusCode = 0;
+ initCliEnvironment(stream, log);
+
}
+ private void initCliEnvironment(OutputStream stream, Logger log) {
+ this.enableLogging(log);
+ this.outputStream = stream;
+ this.statusCode = 0;
+ }
+ public AbstractCommandLineEnvironment(String uri,
+ Map attributes,
+ Map parameters,
+ Map headers,
+ String view,
+ File context,
+ CommandLineContext cliContext,
+ OutputStream stream,
+ Logger log)
+ throws MalformedURLException {
+ super(uri, view, context);
+ initCliEnvironment(stream, log);
+ CommandLineRequest request = new CommandLineRequest(this, null, uri, null, \
attributes, parameters, headers); + \
this.objectModel.put(ObjectModelHelper.REQUEST_OBJECT, + request);
+ this.objectModel.put(ObjectModelHelper.RESPONSE_OBJECT,
+ new CommandLineResponse());
+ this.objectModel.put(ObjectModelHelper.CONTEXT_OBJECT,
+ cliContext);
+ this.objectModel.put(CLI_REQUEST_ID, new String(uri));
+ }
/**
* Redirect the client to a new URL
*/
Modified: cocoon/branches/BRANCH_2_1_X-dojo1_1/src/java/org/apache/cocoon/environment/commandline/FileSavingEnvironment.java
URL: http://svn.apache.org/viewvc/cocoon/branches/BRANCH_2_1_X-dojo1_1/src/java/org/ap \
ache/cocoon/environment/commandline/FileSavingEnvironment.java?rev=1573205&r1=1573204&r2=1573205&view=diff
==============================================================================
--- cocoon/branches/BRANCH_2_1_X-dojo1_1/src/java/org/apache/cocoon/environment/commandline/FileSavingEnvironment.java \
(original)
+++ cocoon/branches/BRANCH_2_1_X-dojo1_1/src/java/org/apache/cocoon/environment/commandline/FileSavingEnvironment.java \
Sat Mar 1 18:02:14 2014 @@ -19,7 +19,6 @@ package org.apache.cocoon.environment.co
import org.apache.avalon.framework.logger.Logger;
import org.apache.cocoon.Constants;
-import org.apache.cocoon.environment.ObjectModelHelper;
import java.io.File;
import java.io.OutputStream;
@@ -51,13 +50,7 @@ public class FileSavingEnvironment exten
OutputStream stream,
Logger log)
throws MalformedURLException {
- super(uri, null, context, stream, log);
- this.objectModel.put(ObjectModelHelper.REQUEST_OBJECT,
- new CommandLineRequest(this, null, uri, null, \
attributes, parameters, headers));
- this.objectModel.put(ObjectModelHelper.RESPONSE_OBJECT,
- new CommandLineResponse());
- this.objectModel.put(ObjectModelHelper.CONTEXT_OBJECT,
- cliContext);
+ super(uri, attributes, parameters, headers, null, context, cliContext, \
stream, log); this.sourceLastModified = lastModified;
if (links != null) {
this.objectModel.put(Constants.LINK_OBJECT, links);
Modified: cocoon/branches/BRANCH_2_1_X-dojo1_1/src/java/org/apache/cocoon/environment/commandline/LinkSamplingEnvironment.java
URL: http://svn.apache.org/viewvc/cocoon/branches/BRANCH_2_1_X-dojo1_1/src/java/org/ap \
ache/cocoon/environment/commandline/LinkSamplingEnvironment.java?rev=1573205&r1=1573204&r2=1573205&view=diff
==============================================================================
--- cocoon/branches/BRANCH_2_1_X-dojo1_1/src/java/org/apache/cocoon/environment/commandline/LinkSamplingEnvironment.java \
(original)
+++ cocoon/branches/BRANCH_2_1_X-dojo1_1/src/java/org/apache/cocoon/environment/commandline/LinkSamplingEnvironment.java \
Sat Mar 1 18:02:14 2014 @@ -29,7 +29,6 @@ import java.util.Map;
import org.apache.avalon.framework.logger.Logger;
import org.apache.cocoon.Constants;
-import org.apache.cocoon.environment.ObjectModelHelper;
/**
* This environment is sample the links of the resource.
@@ -50,16 +49,10 @@ public class LinkSamplingEnvironment ext
CommandLineContext cliContext,
Logger log)
throws MalformedURLException, IOException {
- super(uri, Constants.LINK_VIEW, contextFile, new ByteArrayOutputStream(), \
log); + super(uri, attributes, parameters, headers, Constants.LINK_VIEW, \
contextFile, cliContext, new ByteArrayOutputStream(), log); if \
(getLogger().isDebugEnabled()) { getLogger().debug("uri = " + uri);
}
- this.objectModel.put(ObjectModelHelper.REQUEST_OBJECT,
- new CommandLineRequest(this, null, uri, null, \
attributes, parameters, headers));
- this.objectModel.put(ObjectModelHelper.RESPONSE_OBJECT,
- new CommandLineResponse());
- this.objectModel.put(ObjectModelHelper.CONTEXT_OBJECT,
- cliContext);
}
/**
Modified: cocoon/branches/BRANCH_2_1_X-dojo1_1/src/java/org/apache/cocoon/environment/http/HttpEnvironment.java
URL: http://svn.apache.org/viewvc/cocoon/branches/BRANCH_2_1_X-dojo1_1/src/java/org/ap \
ache/cocoon/environment/http/HttpEnvironment.java?rev=1573205&r1=1573204&r2=1573205&view=diff
==============================================================================
--- cocoon/branches/BRANCH_2_1_X-dojo1_1/src/java/org/apache/cocoon/environment/http/HttpEnvironment.java \
(original)
+++ cocoon/branches/BRANCH_2_1_X-dojo1_1/src/java/org/apache/cocoon/environment/http/HttpEnvironment.java \
Sat Mar 1 18:02:14 2014 @@ -75,8 +75,14 @@ public class HttpEnvironment extends Abs
super(uri, null, root, null);
this.request = new HttpRequest(req, this);
- this.request.setCharacterEncoding(defaultFormEncoding);
- this.request.setContainerEncoding(containerEncoding);
+
+ if (req.getCharacterEncoding() == null) { // use the value from web.xml
+ this.request.setContainerEncoding(containerEncoding != null ? \
containerEncoding : "ISO-8859-1"); + } else { // use what we have been given
+ this.request.setContainerEncoding(req.getCharacterEncoding());
+ }
+ this.request.setCharacterEncoding(defaultFormEncoding != null ? \
defaultFormEncoding : "UTF-8"); +
this.response = new HttpResponse(res);
this.webcontext = context;
Modified: cocoon/branches/BRANCH_2_1_X-dojo1_1/src/java/org/apache/cocoon/environment/http/HttpRequest.java
URL: http://svn.apache.org/viewvc/cocoon/branches/BRANCH_2_1_X-dojo1_1/src/java/org/ap \
ache/cocoon/environment/http/HttpRequest.java?rev=1573205&r1=1573204&r2=1573205&view=diff
==============================================================================
--- cocoon/branches/BRANCH_2_1_X-dojo1_1/src/java/org/apache/cocoon/environment/http/HttpRequest.java \
(original)
+++ cocoon/branches/BRANCH_2_1_X-dojo1_1/src/java/org/apache/cocoon/environment/http/HttpRequest.java \
Sat Mar 1 18:02:14 2014 @@ -324,23 +324,17 @@ public final class HttpRequest \
implement
public String getParameter(String name) {
String value = this.req.getParameter(name);
- if (this.form_encoding == null || this.container_encoding == null || value \
== null) {
- return value;
+ if (!this.container_encoding.equals(this.form_encoding)) {
+ value = decode(value);
}
- // Form and container encoding are equal, skip expensive value decoding
- if (this.container_encoding.equals(this.form_encoding)) {
- return value;
- }
- return decode(value);
+ return value;
}
private String decode(String str) {
if (str == null) return null;
try {
- if (this.container_encoding == null)
- this.container_encoding = "ISO-8859-1";
byte[] bytes = str.getBytes(this.container_encoding);
- return new String(bytes, form_encoding);
+ return new String(bytes, this.form_encoding);
} catch (UnsupportedEncodingException uee) {
throw new CascadingRuntimeException("Unsupported Encoding Exception", \
uee); }
@@ -353,7 +347,7 @@ public final class HttpRequest implement
public String[] getParameterValues(String name) {
String[] values = this.req.getParameterValues(name);
if (values == null) return null;
- if (this.form_encoding == null) {
+ if (this.container_encoding.equals(this.form_encoding)) {
return values;
}
String[] decoded_values = new String[values.length];
Modified: cocoon/branches/BRANCH_2_1_X-dojo1_1/src/java/org/apache/cocoon/environment/wrapper/EnvironmentWrapper.java
URL: http://svn.apache.org/viewvc/cocoon/branches/BRANCH_2_1_X-dojo1_1/src/java/org/ap \
ache/cocoon/environment/wrapper/EnvironmentWrapper.java?rev=1573205&r1=1573204&r2=1573205&view=diff
==============================================================================
--- cocoon/branches/BRANCH_2_1_X-dojo1_1/src/java/org/apache/cocoon/environment/wrapper/EnvironmentWrapper.java \
(original)
+++ cocoon/branches/BRANCH_2_1_X-dojo1_1/src/java/org/apache/cocoon/environment/wrapper/EnvironmentWrapper.java \
Sat Mar 1 18:02:14 2014 @@ -29,6 +29,8 @@ import org.apache.cocoon.Constants;
import org.apache.cocoon.environment.AbstractEnvironment;
import org.apache.cocoon.environment.Environment;
import org.apache.cocoon.environment.ObjectModelHelper;
+import org.apache.cocoon.environment.PermanentRedirector;
+import org.apache.cocoon.environment.Redirector;
import org.apache.cocoon.environment.Request;
import org.apache.cocoon.environment.Response;
import org.apache.cocoon.util.BufferedOutputStream;
@@ -42,7 +44,7 @@ import org.apache.cocoon.util.BufferedOu
* @author <a href="mailto:cziegeler@apache.org">Carsten Ziegeler</a>
* @version $Id$
*/
-public class EnvironmentWrapper extends AbstractEnvironment {
+public class EnvironmentWrapper extends AbstractEnvironment implements Redirector, \
PermanentRedirector {
/** The wrapped environment */
protected Environment environment;
@@ -52,7 +54,7 @@ public class EnvironmentWrapper extends
/** The redirect url */
protected String redirectURL;
-
+
/** The request object */
protected Request request;
@@ -63,6 +65,10 @@ public class EnvironmentWrapper extends
protected boolean internalRedirect = false;
+ protected boolean hasRedirected;
+
+ protected boolean permanentRedirection;
+
/**
* Constructs an EnvironmentWrapper object from a Request
* and Response objects
@@ -267,6 +273,7 @@ public class EnvironmentWrapper extends
public void redirect(boolean sessionmode, String newURL)
throws IOException {
this.redirectURL = newURL;
+ this.hasRedirected = true;
// check if session mode shall be activated
if (sessionmode) {
@@ -276,6 +283,31 @@ public class EnvironmentWrapper extends
}
/**
+ * Permanentlty redirect the client to a new URL is not allowed
+ */
+ public void permanentRedirect(boolean sessionmode, String newURL)
+ throws IOException {
+ this.redirect(sessionmode, newURL);
+ this.permanentRedirection = true;
+ }
+
+ public boolean hasRedirected() {
+ return this.hasRedirected;
+ }
+
+ /**
+ * Has a permanent redirection been asked
+ */
+ public boolean isPermanentRedirection() {
+ return this.permanentRedirection;
+ }
+
+ public void sendStatus(int sc) {
+ this.setStatus(sc);
+ this.hasRedirected = true;
+ }
+
+ /**
* Redirect in the first non-wrapped environment
*/
public void globalRedirect(boolean sessionmode, String newURL)
Modified: cocoon/branches/BRANCH_2_1_X-dojo1_1/src/java/org/apache/cocoon/reading/ImageReader.java
URL: http://svn.apache.org/viewvc/cocoon/branches/BRANCH_2_1_X-dojo1_1/src/java/org/apache/cocoon/reading/ImageReader.java?rev=1573205&r1=1573204&r2=1573205&view=diff
==============================================================================
--- cocoon/branches/BRANCH_2_1_X-dojo1_1/src/java/org/apache/cocoon/reading/ImageReader.java \
(original)
+++ cocoon/branches/BRANCH_2_1_X-dojo1_1/src/java/org/apache/cocoon/reading/ImageReader.java \
Sat Mar 1 18:02:14 2014 @@ -27,20 +27,20 @@ import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
+import java.util.Iterator;
import java.util.Map;
+
+import javax.imageio.ImageIO;
+import javax.imageio.ImageWriteParam;
+import javax.imageio.ImageWriter;
+import javax.imageio.stream.ImageOutputStream;
import javax.swing.ImageIcon;
import org.apache.avalon.framework.parameters.Parameters;
import org.apache.cocoon.ProcessingException;
import org.apache.cocoon.environment.SourceResolver;
-import org.apache.commons.lang.SystemUtils;
import org.xml.sax.SAXException;
-import com.sun.image.codec.jpeg.ImageFormatException;
-import com.sun.image.codec.jpeg.JPEGCodec;
-import com.sun.image.codec.jpeg.JPEGEncodeParam;
-import com.sun.image.codec.jpeg.JPEGImageEncoder;
-
/**
* The <code>ImageReader</code> component is used to serve binary image data
* in a sitemap pipeline. It makes use of HTTP Headers to determine if
@@ -97,9 +97,6 @@ final public class ImageReader extends R
private static final boolean ENLARGE_DEFAULT = true;
private static final boolean FIT_DEFAULT = false;
- /* See http://developer.java.sun.com/developer/bugParade/bugs/4502892.html */
- private static final boolean JVMBugFixed = \
SystemUtils.isJavaVersionAtLeast(1.4f);
-
private int width;
private int height;
private float[] scaleColor = new float[3];
@@ -263,28 +260,6 @@ final public class ImageReader extends R
+ " expires: " + expires);
}
- /*
- * NOTE (SM):
- * Due to Bug Id 4502892 (which is found in *all* JVM implementations \
from
- * 1.2.x and 1.3.x on all OS!), we must buffer the JPEG generation to \
avoid
- * that connection resetting by the peer (user pressing the stop button,
- * for example) crashes the entire JVM (yes, dude, the bug is *that* \
nasty
- * since it happens in JPEG routines which are native!)
- * I'm perfectly aware of the huge memory problems that this causes \
(almost
- * doubling memory consumption for each image and making the GC work \
twice
- * as hard) but it's *far* better than restarting the JVM every 2 \
minutes
- * (since this is the average experience for image-intensive web \
application
- * such as an image gallery).
- * Please, go to the <a \
href="http://developer.java.sun.com/developer/bugParade/bugs/4502892.html">Sun \
Developers Connection</a>
- * and vote this BUG as the one you would like fixed sooner rather than
- * later and all this hack will automagically go away.
- * Many deep thanks to Michael Hartle <mhartle@hartle-klug.com> for \
tracking
- * this down and suggesting the workaround.
- *
- * UPDATE (SM):
- * This appears to be fixed on JDK 1.4
- */
-
try {
byte content[] = readFully(inputStream);
ImageIcon icon = new ImageIcon(content);
@@ -321,25 +296,17 @@ final public class ImageReader extends R
colorFilter.filter(currentImage, currentImage);
}
- // JVM Bug handling
- if (JVMBugFixed) {
- JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
- JPEGEncodeParam p = \
encoder.getDefaultJPEGEncodeParam(currentImage);
- p.setQuality(this.quality[0], true);
- encoder.setJPEGEncodeParam(p);
- encoder.encode(currentImage);
- } else {
- ByteArrayOutputStream bstream = new ByteArrayOutputStream();
- JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(bstream);
- JPEGEncodeParam p = \
encoder.getDefaultJPEGEncodeParam(currentImage);
- p.setQuality(this.quality[0], true);
- encoder.setJPEGEncodeParam(p);
- encoder.encode(currentImage);
- out.write(bstream.toByteArray());
- }
+ Iterator writers = ImageIO.getImageWritersByFormatName("jpeg");
+ ImageOutputStream ios = ImageIO.createImageOutputStream(out);
+ ImageWriter writer = (ImageWriter) writers.next();
+ writer.setOutput(ios);
+ ImageWriteParam p = writer.getDefaultWriteParam();
+ p.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
+ p.setCompressionQuality(this.quality[0]);
+ writer.write(currentImage);
- out.flush();
- } catch (ImageFormatException e) {
+ ios.flush();
+ } catch (IOException e) {
throw new ProcessingException("Error reading the image. " +
"Note that only JPEG images are \
currently supported."); } finally {
Modified: cocoon/branches/BRANCH_2_1_X-dojo1_1/src/java/org/apache/cocoon/reading/ResourceReader.java
URL: http://svn.apache.org/viewvc/cocoon/branches/BRANCH_2_1_X-dojo1_1/src/java/org/ap \
ache/cocoon/reading/ResourceReader.java?rev=1573205&r1=1573204&r2=1573205&view=diff \
==============================================================================
--- cocoon/branches/BRANCH_2_1_X-dojo1_1/src/java/org/apache/cocoon/reading/ResourceReader.java \
(original)
+++ cocoon/branches/BRANCH_2_1_X-dojo1_1/src/java/org/apache/cocoon/reading/ResourceReader.java \
Sat Mar 1 18:02:14 2014 @@ -342,7 +342,9 @@ public class ResourceReader extends Abst
documents.put(request.getRequestURI(), inputSource.getURI());
}
} catch (IOException e) {
+ // COCOON-2307: if the client severed the connection, no matter for it \
that we rethrow the exception as it will never receive it
getLogger().debug("Received an IOException, assuming client severed \
connection on purpose"); + throw e;
}
}
Modified: cocoon/branches/BRANCH_2_1_X-dojo1_1/src/java/org/apache/cocoon/selection/HostSelector.java
URL: http://svn.apache.org/viewvc/cocoon/branches/BRANCH_2_1_X-dojo1_1/src/java/org/ap \
ache/cocoon/selection/HostSelector.java?rev=1573205&r1=1573204&r2=1573205&view=diff \
==============================================================================
--- cocoon/branches/BRANCH_2_1_X-dojo1_1/src/java/org/apache/cocoon/selection/HostSelector.java \
(original)
+++ cocoon/branches/BRANCH_2_1_X-dojo1_1/src/java/org/apache/cocoon/selection/HostSelector.java \
Sat Mar 1 18:02:14 2014 @@ -16,12 +16,13 @@
*/
package org.apache.cocoon.selection;
+import java.util.Map;
+
import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.configuration.ConfigurationException;
import org.apache.avalon.framework.parameters.Parameters;
-import org.apache.cocoon.environment.ObjectModelHelper;
-import java.util.Map;
+import org.apache.cocoon.environment.ObjectModelHelper;
/**
* A <code>Selector</code> that matches a string from within the host parameter
@@ -67,6 +68,6 @@ public class HostSelector extends NamedP
return false;
}
- return checkPatterns(expression, host);
+ return checkPatterns(expression, host, false);
}
}
Modified: cocoon/branches/BRANCH_2_1_X-dojo1_1/src/java/org/apache/cocoon/selection/NamedPatternsSelector.java
URL: http://svn.apache.org/viewvc/cocoon/branches/BRANCH_2_1_X-dojo1_1/src/java/org/ap \
ache/cocoon/selection/NamedPatternsSelector.java?rev=1573205&r1=1573204&r2=1573205&view=diff
==============================================================================
--- cocoon/branches/BRANCH_2_1_X-dojo1_1/src/java/org/apache/cocoon/selection/NamedPatternsSelector.java \
(original)
+++ cocoon/branches/BRANCH_2_1_X-dojo1_1/src/java/org/apache/cocoon/selection/NamedPatternsSelector.java \
Sat Mar 1 18:02:14 2014 @@ -16,18 +16,18 @@
*/
package org.apache.cocoon.selection;
-import org.apache.avalon.framework.configuration.Configurable;
-import org.apache.avalon.framework.configuration.Configuration;
-import org.apache.avalon.framework.configuration.ConfigurationException;
-import org.apache.avalon.framework.logger.AbstractLogEnabled;
-import org.apache.avalon.framework.thread.ThreadSafe;
-
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import org.apache.avalon.framework.configuration.Configurable;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+import org.apache.avalon.framework.thread.ThreadSafe;
+
/**
* Abstract class for selectors that select a value when it matches
* some patterns associated to the select expression.
@@ -39,7 +39,7 @@ import java.util.Map;
*/
public abstract class NamedPatternsSelector extends AbstractLogEnabled
- implements Configurable, ThreadSafe, Selector {
+ implements Configurable, ThreadSafe, \
Selector {
/**
* Association of names to String[] of values.
@@ -95,7 +95,7 @@ public abstract class NamedPatternsSelec
}
/**
- * Checks if <code>value</code> is a substring of one of the patterns associated
+ * Checks if <code>value</code> is a (case-sensitive) substring of one of the \
patterns associated
* to <code>expression</code>
*
* @param expression the expression that is selected
@@ -103,6 +103,19 @@ public abstract class NamedPatternsSelec
* @return true if <code>value</code> matches one of the patterns
*/
protected boolean checkPatterns(String expression, String value) {
+ return checkPatterns(expression, value, true);
+ }
+
+ /**
+ * Checks if <code>value</code> is a substring of one of the patterns associated
+ * to <code>expression</code>
+ *
+ * @param expression the expression that is selected
+ * @param value the value to check
+ * @param caseSensitive boolean switch whether comparison is done case-sensitive \
+ * @return true if <code>value</code> matches one of the patterns
+ */
+ protected boolean checkPatterns(String expression, String value, boolean \
caseSensitive) { if (value == null) {
getLogger().debug("No value given -- failing.");
return false;
@@ -114,9 +127,14 @@ public abstract class NamedPatternsSelec
return false;
}
+ if (!caseSensitive) {
+ value = value.toLowerCase();
+ }
+
// Does a pattern match 'value' ?
for (int i = 0; i < patterns.length; i++) {
- if (value.indexOf(patterns[i]) != -1) {
+ if ((caseSensitive && value.indexOf(patterns[i]) != -1)
+ || (!caseSensitive && value.indexOf(patterns[i].toLowerCase()) != \
-1)) {
getLogger().debug(expression + " selected value " + value);
return true;
}
Modified: cocoon/branches/BRANCH_2_1_X-dojo1_1/src/java/org/apache/cocoon/servlet/CocoonServlet.java
URL: http://svn.apache.org/viewvc/cocoon/branches/BRANCH_2_1_X-dojo1_1/src/java/org/ap \
ache/cocoon/servlet/CocoonServlet.java?rev=1573205&r1=1573204&r2=1573205&view=diff \
==============================================================================
--- cocoon/branches/BRANCH_2_1_X-dojo1_1/src/java/org/apache/cocoon/servlet/CocoonServlet.java \
(original)
+++ cocoon/branches/BRANCH_2_1_X-dojo1_1/src/java/org/apache/cocoon/servlet/CocoonServlet.java \
Sat Mar 1 18:02:14 2014 @@ -177,17 +177,17 @@ public class CocoonServlet extends \
HttpS /**
* Allow processing of upload requests (mime/multipart)
*/
- private boolean enableUploads;
- private boolean autoSaveUploads;
- private boolean allowOverwrite;
- private boolean silentlyRename;
- private int maxUploadSize;
-
- private File uploadDir;
- private File workDir;
- private File cacheDir;
- private String containerEncoding;
- private String defaultFormEncoding;
+ protected boolean enableUploads;
+ protected boolean autoSaveUploads;
+ protected boolean allowOverwrite;
+ protected boolean silentlyRename;
+ protected int maxUploadSize;
+
+ protected File uploadDir;
+ protected File workDir;
+ protected File cacheDir;
+ protected String containerEncoding;
+ protected String defaultFormEncoding;
protected ServletContext servletContext;
@@ -488,18 +488,26 @@ public class CocoonServlet extends HttpS
this.enableInstrumentation = \
getInitParameterAsBoolean("enable-instrumentation", false);
- this.requestFactory = new RequestFactory(this.autoSaveUploads,
- this.uploadDir,
- this.allowOverwrite,
- this.silentlyRename,
- this.maxUploadSize,
- this.containerEncoding);
+ createRequestFactory();
+
// Add the servlet configuration
this.appContext.put(CONTEXT_SERVLET_CONFIG, conf);
this.createCocoon();
}
/**
+ * Creates the {@link RequestFactory}.
+ */
+ protected void createRequestFactory(){
+ this.requestFactory = new RequestFactory(this.autoSaveUploads,
+ this.uploadDir,
+ this.allowOverwrite,
+ this.silentlyRename,
+ this.maxUploadSize,
+ this.containerEncoding);
+ }
+
+ /**
* Dispose Cocoon when servlet is destroyed
*/
public void destroy() {
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic