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

Attachment: SVGSerializer.java
Description: SVGSerializer.java

Reply via email to