You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@cocoon.apache.org by hu...@apache.org on 2002/02/06 22:18:49 UTC
cvs commit: xml-cocoon2/src/scratchpad/src/org/apache/cocoon/transformation EncodeURLTransformer.java
huber 02/02/06 13:18:49
Added: src/scratchpad/src/org/apache/cocoon/transformation
EncodeURLTransformer.java
Log:
rewrite URLs, matching specified patterns
using response.encodeURL()
Revision Changes Path
1.1 xml-cocoon2/src/scratchpad/src/org/apache/cocoon/transformation/EncodeURLTransformer.java
Index: EncodeURLTransformer.java
===================================================================
package org.apache.cocoon.transformation;
import java.io.IOException;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.apache.avalon.excalibur.pool.Poolable;
import org.apache.avalon.excalibur.pool.Recyclable;
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.parameters.Parameters;
import org.apache.cocoon.ProcessingException;
import org.apache.cocoon.environment.SourceResolver;
import org.apache.cocoon.environment.http.HttpEnvironment;
import org.apache.cocoon.transformation.AbstractTransformer;
import org.apache.regexp.RE;
import org.apache.regexp.RESyntaxException;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.AttributesImpl;
/**
* The encodeURL transformer emits encoded URLs.
* <p>
* This transformer applies encodeURL method to URLs.
* You may want to use this transform to avoid doing the manually
* encodeURL() call.
* </p>
* <p>
* Usually this transformer is appended as last transformer before
* the serialization process. In this case it is possible to encode
* URLs introduced in the generator, and xslt transformer phase.
* </p>
* <p>
* You can specify which attributes hold URL values in order to restrict
* URL rewriting to specific attributes only.
* </p>
* <p>
* Usage in a sitemap:
* </p>
* <pre><tt>
* <map:composition>
* ...
* <map:transformers>
* ...
* <map:transformer type="encodeURL"
* src="org.apache.cocoon.optional.transformation.EncodeURLTransformer">
* <exclude-name>img/@src</exclude-name>
* <include-name>.&asterik;/@href|.&asterik;/@src|.&asterik;/@action</include-name>
* </map:transformer>
* ...
* <map:pipelines>
* <map:pipeline>
* ...
* <map:transform type="encodeURL"/>
* ...
* </pre></tt>
*
* @author <a href="mailto:bh22351@i-one.at">Bernhard Huber</a>
* @version CVS $Id: EncodeURLTransformer.java,v 1.1 2002/02/06 21:18:49 huber Exp $
*
* @cocoon:name encodeURL
* @cocoon:status scratchpad
* @cocoon:parameter name="exclude-name"
* default-value="img/@src"
* description="RE pattern for excluding attributes from encode URL rewriting"
* @cocoon:parameter name="include-name"
* default-value=".&asterik;/@href|.&asterik;/@src|.&asterik;/@action"
* description="RE pattern for including attributes from encode URL rewriting"
*
*/
public class EncodeURLTransformer extends AbstractTransformer implements Configurable, Recyclable {
/**
* Configuration name for specifying excluding patterns,
* ie exclude-name.
*
* @since
*/
public final static String EXCLUDE_NAME = "exclude-name";
/**
* Configuration name for specifying including patterns,
* ie include-name.
*
* @since
*/
public final static String INCLUDE_NAME = "include-name";
/**
* Configuration default exclude pattern,
* ie img/@src
*
* @since
*/
public final static String EXCLUDE_NAME_DEFAULT = "img/@src";
/**
* Configuration default exclude pattern,
* ie .*\/@href|.*\/@action|frame/@src
*
* @since
*/
public final static String INCLUDE_NAME_DEFAULT = ".*/@href|.*/@action|frame/@src";
private String includeNameConfigure = INCLUDE_NAME_DEFAULT;
private String excludeNameConfigure = EXCLUDE_NAME_DEFAULT;
private String includeName;
private String excludeName;
private ElementAttributeMatching elementAttributeMatching;
private HttpServletResponse response;
private HttpServletRequest request;
/**
* Setup the transformer.
* <p>
* Setup include, and exclude patterns from the parameters
* </p>
*
* @param resolver source resolver
* @param objectModel sitemap objects
* @param parameters request parameters
*
*/
public void setup(SourceResolver resolver, Map objectModel, String source, Parameters parameters)
throws ProcessingException, SAXException, IOException {
includeName = parameters.getParameter(EncodeURLTransformer.INCLUDE_NAME, this.includeNameConfigure);
excludeName = parameters.getParameter(EncodeURLTransformer.EXCLUDE_NAME, this.excludeNameConfigure);
try {
elementAttributeMatching = new ElementAttributeMatching(includeName, excludeName);
} catch (RESyntaxException reex) {
String message = "Cannot parse include-name: " + includeName + " " +
"or exclude-name: " + excludeName + "!";
throw new ProcessingException(message, reex);
}
response =
(HttpServletResponse) objectModel.get(HttpEnvironment.HTTP_RESPONSE_OBJECT);
request =
(HttpServletRequest) objectModel.get(HttpEnvironment.HTTP_REQUEST_OBJECT);
}
/**
* BEGIN SitemapComponent methods
*
* @param configuration Description of Parameter
* @exception ConfigurationException Description of Exception
* @since
*/
public void configure(Configuration configuration) throws ConfigurationException {
if (configuration != null) {
Configuration child;
child = configuration.getChild(EncodeURLTransformer.INCLUDE_NAME);
this.includeNameConfigure = child.getValue(INCLUDE_NAME_DEFAULT);
child = configuration.getChild(EncodeURLTransformer.EXCLUDE_NAME);
this.excludeNameConfigure = child.getValue(EXCLUDE_NAME_DEFAULT);
}
if (this.includeNameConfigure == null) {
String message = "Configure " + INCLUDE_NAME + "!";
throw new ConfigurationException(message);
}
if (this.excludeNameConfigure == null) {
String message = "Configure " + EXCLUDE_NAME + "!";
throw new ConfigurationException(message);
}
}
/**
*Description of the Method
*
* @since
*/
public void recycle() {
response = null;
request = null;
elementAttributeMatching = null;
}
/**
* Start parsing an element
*
* @param uri of the element
* @param name of the element
* @param raw name of the element
* @param attributes list
* @exception SAXException Description of Exception
* @since
*/
public void startElement(String uri, String name, String raw, Attributes attributes)
throws SAXException {
String lname = name;
if (response != null && elementAttributeMatching != null) {
if (attributes != null && attributes.getLength() > 0) {
AttributesImpl new_attributes = new AttributesImpl(attributes);
for (int i = 0; i < new_attributes.getLength(); i++) {
String attr_lname = new_attributes.getLocalName(i);
String value = new_attributes.getValue(i);
if (elementAttributeMatching.matchesElementAttribute(lname, attr_lname)) {
String new_value = encodeURL(value, request, response);
if (getLogger().isDebugEnabled()) {
this.getLogger().debug("element/@attribute matches: " + name + "/@" + attr_lname);
this.getLogger().debug("encodeURL: " + value + " -> " + new_value);
}
new_attributes.setValue(i, new_value);
}
}
// parent handles element using encoded attribute values
super.contentHandler.startElement(uri, name, raw, new_attributes);
return;
}
}
// no match, parent handles element as-is
super.contentHandler.startElement(uri, name, raw, attributes);
}
/**
* Encode a URL.
* <p>
* This method calculates from a given url the encoded url
* </p>
*
* @param url the URL probably without sessionid.
* @param request the http request
* @param response the http response
* @return String the original url inclusive the sessionid
* @since
*/
private String encodeURL(String url, HttpServletRequest request, HttpServletResponse response) {
String encoded_url;
if (response != null) {
// As some servlet-engine does not check if url has been already rewritten
HttpSession session = request.getSession(false);
if (session != null && url.indexOf(session.getId()) > -1) {
encoded_url = url;
} else {
encoded_url = response.encodeURL(url);
}
} else {
encoded_url = url;
}
return encoded_url;
}
/**
* A helper class for matching element names, and attribute names.
*
* <p>
* For given include-name, exclude-name decide if element-attribute pair
* matches. This class defines the precedence and matching algorithm.
* </p>
*
* @author <a href="mailto:bh22351@i-one.at">Bernhard Huber</a>
* @version CVS $Id: EncodeURLTransformer.java,v 1.1 2002/02/06 21:18:49 huber Exp $
*/
public class ElementAttributeMatching {
/**
* Regular expression of including patterns
*
* @since
*/
protected RE includeNameRE;
/**
* Regular expression of excluding patterns
*
* @since
*/
protected RE excludeNameRE;
/**
*Constructor for the ElementAttributeMatching object
*
* @param includeName Description of Parameter
* @param excludeName Description of Parameter
* @exception RESyntaxException Description of Exception
* @since
*/
public ElementAttributeMatching(String includeName, String excludeName) throws RESyntaxException {
includeNameRE = new RE(includeName, RE.MATCH_CASEINDEPENDENT);
excludeNameRE = new RE(excludeName, RE.MATCH_CASEINDEPENDENT);
}
/**
* Return true iff element_name attr_name pair is not matched by exclude-name,
* but is matched by include-name
*
* @param element_name
* @param attr_name
* @return boolean true iff value of attribute_name should get rewritten, else
* false.
* @since
*/
public boolean matchesElementAttribute(String element_name, String attr_name) {
String element_attr_name = canonicalizeElementAttribute(element_name, attr_name);
if (excludeNameRE != null && includeNameRE != null) {
return !matchesExcludesElementAttribute(element_attr_name) &&
matchesIncludesElementAttribute(element_attr_name);
} else {
return false;
}
}
/**
* Build from elementname, and attribute name a single string.
* <p>
* String concatenated <code>element name + "/@" + attribute name</code>
* is matched against the include and excluding patterns.
* </p>
*
* @param element_name Description of Parameter
* @param attr_name Description of Parameter
* @return Description of the Returned Value
* @since
*/
String canonicalizeElementAttribute(String element_name, String attr_name) {
StringBuffer element_attr_name = new StringBuffer();
element_attr_name.append(element_name);
element_attr_name.append("/@");
element_attr_name.append(attr_name);
return element_attr_name.toString();
}
/**
* Return true iff element_name attr_name pair is matched by exclude-name.
*
* @param element_attr_name
* @return boolean true iff exclude-name matches element_name, attr_name, else
* false.
* @since
*/
private boolean matchesExcludesElementAttribute(String element_attr_name) {
boolean match = excludeNameRE.match(element_attr_name);
return match;
}
/**
* Return true iff element_name attr_name pair is matched by include-name.
*
* @param element_attr_name
* @return boolean true iff include-name matches element_name, attr_name, else
* false.
* @since
*/
private boolean matchesIncludesElementAttribute(String element_attr_name) {
boolean match = includeNameRE.match(element_attr_name);
return match;
}
}
}
----------------------------------------------------------------------
In case of troubles, e-mail: webmaster@xml.apache.org
To unsubscribe, e-mail: cocoon-cvs-unsubscribe@xml.apache.org
For additional commands, e-mail: cocoon-cvs-help@xml.apache.org