Hi, Here's proposed SVGSerializer patch to support request parameters.
The following changes have been made: Configuration ============= 1. The <use-request-parametes> tag is recognized to allow the serializer to use request parameters. if true ==> All the declared batik keys can be overriden by request parameters. 3. The value attribute of the key now means it's a default value and is not mandatory anymore. 4. A default TranscodingHints is configured with all the keys entries which have a default value 5. A Map is used to keep information on batik transcoding keys and their "types" (INTEGER, ...) Processing ========== 1. The SVGSerializer implements the SitemapModelComponent 2. A current TranscodingHints is built overriding the default one and adding new key values if their "types" can be resolved. EXEMPLE ======= 1. in the batik block sitemap add this instead of the current the svg2png serializer: <map:serializer logger="sitemap.serializer.svg2png" name="svg2png" src="org.apache.cocoon.serialization.SVGSerializer" mime-type="image/png"> <use-request-parameters>true</use-request-parameters> <parameter name="indexed" type="integer" value="16"/> <parameter name="height" type="float"/> <parameter name="width" type="float"/> </map:serializer> 2. Try this: samples/batik/batikLogo.png ... the normal logo or samples/batik/batikLogo.png?width=200&height=100 ... small logo or samples/batik/batikLogo.png?width=200&height=100&indexed=2 ... ugly! ===== BORGES C. ___________________________________________________________ Do You Yahoo!? -- Une adresse @yahoo.fr gratuite et en fran�ais ! Yahoo! Mail : http://fr.mail.yahoo.com
Index: SVGSerializer.java
===================================================================
RCS file:
/home/cvspublic/cocoon-2.1/src/blocks/batik/java/org/apache/cocoon/serialization/SVGSerializer.java,v
retrieving revision 1.9
diff -u -r1.9 SVGSerializer.java
--- SVGSerializer.java 9 Oct 2003 15:26:54 -0000 1.9
+++ SVGSerializer.java 19 Nov 2003 17:44:26 -0000
@@ -51,7 +51,12 @@
package org.apache.cocoon.serialization;
import java.awt.Color;
+import java.io.IOException;
import java.io.OutputStream;
+import java.io.Serializable;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Map;
import org.apache.avalon.excalibur.pool.Poolable;
import org.apache.avalon.framework.component.ComponentManager;
@@ -62,6 +67,7 @@
import org.apache.avalon.framework.context.Context;
import org.apache.avalon.framework.context.ContextException;
import org.apache.avalon.framework.context.Contextualizable;
+import org.apache.avalon.framework.parameters.Parameters;
import org.apache.batik.transcoder.Transcoder;
import org.apache.batik.transcoder.TranscoderInput;
import org.apache.batik.transcoder.TranscoderOutput;
@@ -69,11 +75,16 @@
import org.apache.batik.transcoder.TranscoderException;
import org.apache.batik.util.ParsedURL;
import org.apache.cocoon.Constants;
+import org.apache.cocoon.ProcessingException;
import org.apache.cocoon.caching.CacheableProcessingComponent;
import org.apache.cocoon.components.transcoder.ExtendableTranscoderFactory;
import org.apache.cocoon.components.transcoder.TranscoderFactory;
import org.apache.cocoon.components.url.ParsedContextURLProtocolHandler;
import org.apache.cocoon.components.url.ParsedResourceURLProtocolHandler;
+import org.apache.cocoon.environment.ObjectModelHelper;
+import org.apache.cocoon.environment.Request;
+import org.apache.cocoon.environment.SourceResolver;
+import org.apache.cocoon.sitemap.SitemapModelComponent;
import org.apache.cocoon.util.ClassUtils;
import org.apache.cocoon.xml.dom.SVGBuilder;
import org.apache.excalibur.source.SourceValidity;
@@ -89,7 +100,7 @@
* @version CVS $Id: SVGSerializer.java,v 1.9 2003/10/09 15:26:54 sylvain Exp $
*/
public class SVGSerializer extends SVGBuilder
-implements Composable, Serializer, Configurable, Poolable,
CacheableProcessingComponent, Contextualizable {
+implements Composable, Serializer, Configurable, Poolable,
CacheableProcessingComponent, Contextualizable, SitemapModelComponent {
/**
* Get the context
@@ -112,7 +123,22 @@
/** The Transcoder Factory to use */
TranscoderFactory factory =
ExtendableTranscoderFactory.getTranscoderFactoryImplementation();
-
+
+ /** The current caching key */
+ private Serializable cachingKey;
+
+ /** The default Batik <code>TranscodingHints</code> set up in configuration step
*/
+ private TranscodingHints defaultTranscodingHints;
+
+ /** The current Batik <code>TranscodingHints</code> can overrides the default one
*/
+ private TranscodingHints currentTranscodingHints;
+
+ /** The map holding information for the Batik <code>TranscodingHints.Key</code>s
*/
+ private Map transcodingHintKeysInfo;
+
+ /** Override default <code>TranscodingHints</code> with request parameters? */
+ private boolean overrideTranscodingHints = false;
+ //private boolean _overrideTranscodingHints = false;
/**
* Set the <code>OutputStream</code> where the XML should be serialized.
*/
@@ -157,8 +183,10 @@
);
}
- // Now run through the other parameters, using them as hints
- // to the transcoder
+ // Now run through the other parameters, adding them to the
+ // default transcoding hints
+ defaultTranscodingHints = new TranscodingHints();
+ transcodingHintKeysInfo = new HashMap();
for (int i = 0; i < parameters.length; i++ ) {
String name = parameters[i].getAttribute("name");
// Skip over the parameters we've dealt with. Ensure this
@@ -169,48 +197,94 @@
// Now try and get the hints out
try {
- // Turn it into a key name (assume the current Batik style continues!
- name = ("KEY_" + name).toUpperCase();
- // Use reflection to get a reference to the key object
- TranscodingHints.Key key = (TranscodingHints.Key)
- (transcoder.getClass().getField(name).get(transcoder));
- Object value;
- String keyType = parameters[i].getAttribute("type",
"STRING").toUpperCase();
- if ("FLOAT".equals(keyType)) {
- // Can throw an exception.
- value = new Float(parameters[i].getAttributeAsFloat("value"));
- } else if ("INTEGER".equals(keyType)) {
- // Can throw an exception.
- value = new Integer(parameters[i].getAttributeAsInteger("value"));
- } else if ("BOOLEAN".equals(keyType)) {
- // Can throw an exception.
- value = new Boolean(parameters[i].getAttributeAsBoolean("value"));
- } else if ("COLOR".equals(keyType)) {
- // Can throw an exception
- String stringValue = parameters[i].getAttribute("value");
- if (stringValue.startsWith("#")) {
- stringValue = stringValue.substring(1);
+ String batikKeyName = "KEY_" + name.toUpperCase();
+ String batikKeyType = parameters[i].getAttribute("type",
"STRING").toUpperCase();
+ //Use reflection to get a reference to the key object
+ TranscodingHints.Key key = (TranscodingHints.Key)
(this.transcoder.getClass().getField(batikKeyName).get(this.transcoder));
+
+ //The value is not required. It can only declares a default value for
a key
+ Object value = computeBatikKeyValue(batikKeyType,
parameters[i].getAttribute("value", null));
+
+ // Adding transcoding hint value
+ if (value != null) {
+ if(getLogger().isDebugEnabled()) {
+ getLogger().debug("Adding default hint \"" + name + "\" with
value \"" + value.toString() + "\"");
}
- value = new Color(Integer.parseInt(stringValue, 16));
- } else {
- // Assume String, and get the value. Allow an empty string.
- value = parameters[i].getAttribute("value", "");
- }
- if(getLogger().isDebugEnabled()) {
- getLogger().debug("Adding hint \"" + name + "\" with value \"" +
value.toString() + "\"");
+ defaultTranscodingHints.put(key, value);
}
- transcoder.addTranscodingHint(key, value);
+
+ // Adding info for all declared keys
+ TranscodingHintKeyInfo keyInfo = new
TranscodingHintKeyInfo(batikKeyName, batikKeyType, key);
+ transcodingHintKeysInfo.put(name, keyInfo);
+
} catch (ClassCastException ex) {
// This is only thrown from the String keyType... line
throw new ConfigurationException("Specified key (" + name + ") is not
a valid Batik Transcoder key.", ex);
- } catch (ConfigurationException ex) {
- throw new ConfigurationException("Name or value not specified.", ex);
} catch (IllegalAccessException ex) {
throw new ConfigurationException("Cannot access the key for parameter
\"" + name + "\"", ex);
} catch (NoSuchFieldException ex) {
throw new ConfigurationException("No field available for parameter
\"" + name + "\"", ex);
}
}
+
+ // Setting default value to enable overriding default transcoding hints
+ overrideTranscodingHints =
+ conf.getChild("use-request-parameters").getValueAsBoolean(false);
+ if (getLogger().isDebugEnabled() && overrideTranscodingHints) {
+ getLogger().debug(
+ "The transcoding hints may be overrinden by request parameters");
+ }
+ }
+
+ /**
+ * Set the <code>SourceResolver</code>, the <code>Map</code> with
+ * the object model, the source and sitemap
+ * <code>Parameters</code> used to process the request.
+ */
+ public void setup(SourceResolver resolver, Map objectModel, String src,
Parameters par) throws ProcessingException, SAXException, IOException {
+ currentTranscodingHints = (TranscodingHints) defaultTranscodingHints.clone();
+ cachingKey = "1";
+ // Overrides configured batik tranciding hints values with request parameters?
+ //this._overrideTranscodingHints =
par.getParameterAsBoolean("use-request-parameters", overrideTranscodingHints);
+ if (this.overrideTranscodingHints) {
+ Request request = ObjectModelHelper.getRequest(objectModel);
+ Enumeration parameters = request.getParameterNames();
+ if (parameters != null) {
+ StringBuffer cachingKeyBuffer = new StringBuffer();
+ while (parameters.hasMoreElements()) {
+ String parameterName = (String) parameters.nextElement();
+ if (transcodingHintKeysInfo
+ .containsKey(parameterName)) {
+ TranscodingHintKeyInfo keyInfo = (TranscodingHintKeyInfo)
transcodingHintKeysInfo.get(parameterName);
+ String batikKeyName = keyInfo.getName();
+ String batikKeyType = keyInfo.getType();
+ TranscodingHints.Key batikKey =
keyInfo.getTranscodingHintKey();
+ String value = request.getParameter(parameterName);
+ Object batikKeyValue =
+ computeBatikKeyValue(batikKeyType, value);
+ if (batikKeyValue == null) {
+ getLogger().info("Cannot compute value for parameter " +
parameterName + " (" +batikKeyName + "). If a default value was set, it will be used
instead.");
+ } else {
+ if (getLogger().isDebugEnabled()) {
+ getLogger().debug("Setting " + parameterName + " (" +
batikKeyName + ") value to " + batikKeyValue.toString());
+ }
+ currentTranscodingHints.put(batikKey, batikKeyValue);
+ cachingKeyBuffer.append(";");
+ cachingKeyBuffer.append(parameterName);
+ cachingKeyBuffer.append("=");
+ cachingKeyBuffer.append(value);
+ }
+
+ }
+ }
+ String currentCachingKey = cachingKeyBuffer.toString().trim();
+ if (currentCachingKey.length() > 0) {
+ cachingKey = currentCachingKey;
+ }
+ }
+
+ }
+
}
/**
@@ -229,6 +303,8 @@
// Buffering is done by the pipeline (See shouldSetContentLength)
TranscoderOutput transOutput = new TranscoderOutput(this.output);
+ // Setting current transcoding hints to transcoder
+ transcoder.setTranscodingHints(currentTranscodingHints);
transcoder.transcode(transInput, transOutput);
} catch (TranscoderException ex) {
if (ex.getException() != null) {
@@ -265,8 +341,8 @@
* @return The generated key or <code>0</code> if the component
* is currently not cacheable.
*/
- public java.io.Serializable getKey() {
- return "1";
+ public Serializable getKey() {
+ return cachingKey;
}
/**
@@ -293,4 +369,119 @@
public boolean shouldSetContentLength() {
return true;
}
+
+ /**
+ * Computes the transcoding hint value for a key type declared in
+ * the configuration of this serializer.
+ *
+ * @param keyType The key type.
+ * @param value The string value to be converted into an object.
+ * @return The object value. it will return null if the value
+ * cannot be computed or the key type is unknown.
+ */
+ private Object computeBatikKeyValue(String type, String value) {
+ if (value == null) {
+ return null;
+ }
+ if ("STRING".equals(type)) {
+ return value;
+ }
+ if (value.length() == 0) {
+ return null;
+ }
+ if ("FLOAT".equals(type)) {
+ try {
+ return Float.valueOf(value);
+ } catch (NumberFormatException e) {
+ return null;
+ }
+ }
+ if ("INTEGER".equals(type)) {
+
+ try {
+ return Integer.valueOf(value);
+ } catch (NumberFormatException e) {
+ return null;
+ }
+
+ }
+ if ("BOOLEAN".equals(type)) {
+ return Boolean.valueOf(value);
+ }
+ if ("COLOR".equals(type)) {
+ // Can throw an exception
+ if (value.startsWith("#")) {
+ value = value.substring(1);
+ }
+ try {
+ return new Color(Integer.parseInt(value, 16));
+ } catch (NumberFormatException e) {
+ return null;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * This is a convinience class to hold information on the configured
+ * Batik keys
+ */
+ private static final class TranscodingHintKeyInfo {
+
+ /** key type as of INTEGER, ... */
+ private String type;
+
+ /** batik key name starting with KEY_ */
+ private String name;
+
+ /** batik <code>TranscodingHints.Key</code> */
+ private TranscodingHints.Key key;
+
+ /**
+ * Constructor
+ *
+ * @param name The batik key name
+ * @param type The configured key type
+ * @param batikKey The <code>TranscodingHints.Key</code>
+ */
+ public TranscodingHintKeyInfo(
+ String name,
+ String type,
+ TranscodingHints.Key batikKey){
+ this.name = name;
+ this.type = type;
+ this.key = batikKey;
+
+ }
+
+ /**
+ * Gets the batik key name
+ *
+ * @return The batik key name
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Gets the configured key type
+ *
+ * @return The key type
+ */
+ public String getType() {
+ return type;
+ }
+
+ /**
+ * Gets the <code>TranscodingHints.Key</code>
+ *
+ * @return The <code>TranscodingHints.Key</code>
+ */
+ public TranscodingHints.Key getTranscodingHintKey() {
+ return key;
+ }
+
+ }
+
+
}
SVGSerializer.java
Description: SVGSerializer.java
