Package org.apache.cocoon.serialization

Source Code of org.apache.cocoon.serialization.SVGSerializer

/*
* Copyright 1999-2004 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.cocoon.serialization;

import java.awt.Color;
import java.io.OutputStream;
import java.io.Serializable;

import org.apache.avalon.excalibur.pool.Poolable;
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.context.Context;
import org.apache.avalon.framework.context.ContextException;
import org.apache.avalon.framework.context.Contextualizable;
import org.apache.batik.transcoder.Transcoder;
import org.apache.batik.transcoder.TranscoderInput;
import org.apache.batik.transcoder.TranscoderOutput;
import org.apache.batik.transcoder.TranscodingHints;
import org.apache.batik.transcoder.TranscoderException;
import org.apache.batik.util.ParsedURL;
import org.apache.cocoon.Constants;
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.util.ClassUtils;
import org.apache.cocoon.xml.dom.SVGBuilder;
import org.apache.excalibur.source.SourceValidity;
import org.apache.excalibur.source.impl.validity.NOPValidity;
import org.w3c.dom.Document;
import org.xml.sax.SAXException;

/**
* A <a href="http://xml.apache.org/batik/">Batik</a> based Serializer for generating PNG/JPEG images
*
* @author <a href="mailto:dims@yahoo.com">Davanum Srinivas</a>
* @author <a href="mailto:rossb@apache.org">Ross Burton</a>
* @version CVS $Id: SVGSerializer.java,v 1.16 2004/03/28 05:29:04 antonio Exp $
*/
public class SVGSerializer extends SVGBuilder
implements Serializer, Configurable, Poolable, CacheableProcessingComponent, Contextualizable {

    /**
     * Get the context
     */
    public void contextualize(Context context) throws ContextException {
        ParsedContextURLProtocolHandler.setContext(
            (org.apache.cocoon.environment.Context)context.get(Constants.CONTEXT_ENVIRONMENT_CONTEXT));
        ParsedURL.registerHandler(new ParsedContextURLProtocolHandler());
        ParsedURL.registerHandler(new ParsedResourceURLProtocolHandler());
    }

    /** The current <code>OutputStream</code>. */
    private OutputStream output;

    /** The current <code>mime-type</code>. */
    private String mimetype;

    /** The current <code>Transcoder</code>.  */
    Transcoder transcoder;

    /** The Transcoder Factory to use */
    TranscoderFactory factory = ExtendableTranscoderFactory.getTranscoderFactoryImplementation();
   
//    private ServiceManager manager;

//    private SourceResolver resolver;

    /**
     * Set the <code>OutputStream</code> where the XML should be serialized.
     */
    public void setOutputStream(OutputStream out) {
        this.output = out;
       
        // Give the source resolver to Batik
        //SourceProtocolHandler.setup(this.resolver);
    }
   
/*    public void service(ServiceManager manager) throws ServiceException {
        this.manager = manager;
        this.resolver = (SourceResolver)this.manager.lookup(SourceResolver.ROLE);
    }

    public void dispose() {
        this.manager.release(this.resolver);
    }
*/
    /**
     * Set the configurations for this serializer.
     */
    public void configure(Configuration conf) throws ConfigurationException {
        this.mimetype = conf.getAttribute("mime-type");
        if (getLogger().isDebugEnabled()) {
            getLogger().debug("mime-type: " + mimetype);
        }

        // Using the Transcoder Factory, get the default transcoder
        // for this MIME type.
        this.transcoder = factory.createTranscoder(mimetype);

        // Iterate through the parameters, looking for a transcoder reference
        Configuration[] parameters = conf.getChildren("parameter");
        for (int i = 0; i < parameters.length; i++) {
            String name = parameters[i].getAttribute("name");
            if ("transcoder".equals(name)) {
                String transcoderName = parameters[i].getAttribute("value");
                try {
                    this.transcoder = (Transcoder)ClassUtils.newInstance(transcoderName);
                } catch (Exception ex) {
                    if (getLogger().isDebugEnabled()) {
                        getLogger().debug("Cannot load  class " + transcoderName, ex);
                    }
                    throw new ConfigurationException("Cannot load class " + transcoderName, ex);
                }
            }
        }
        // Do we have a transcoder yet?
        if (this.transcoder == null ) {
            throw new ConfigurationException(
                "Could not autodetect transcoder for SVGSerializer and "
                + "no transcoder was specified in the sitemap configuration."
            );
        }

        // Now run through the other parameters, using them as hints
        // to the transcoder
        for (int i = 0; i < parameters.length; i++ ) {
            String name = parameters[i].getAttribute("name");
            // Skip over the parameters we've dealt with. Ensure this
            // is kept in sync with the above list!
            if ("transcoder".equals(name)) {
                continue;
            }

            // 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);
                    }
                    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() + "\"");
                }
                transcoder.addTranscodingHint(key, value);
            } 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);
            }
        }
    }

    /**
     * Receive notification of a successfully completed DOM tree generation.
     */
    public void notify(Document doc) throws SAXException {
       
        try {
            TranscoderInput transInput = new TranscoderInput(doc);

            // Buffering is done by the pipeline (See shouldSetContentLength)
            TranscoderOutput transOutput = new TranscoderOutput(this.output);
            transcoder.transcode(transInput, transOutput);
        } catch (TranscoderException ex) {
            if (ex.getException() != null) {
                if (getLogger().isDebugEnabled()) {
                    getLogger().debug("Got transcoder exception writing image, rethrowing nested exception", ex);
                }
                throw new SAXException("Exception writing image", ex.getException());
            }

            if (getLogger().isDebugEnabled()) {
                getLogger().debug("Got transcoder exception writing image, rethrowing", ex);
            }
            throw new SAXException("Exception writing image", ex);
        } catch (Exception ex) {
            if (getLogger().isDebugEnabled()) {
                getLogger().debug("Got exception writing image, rethrowing", ex);
            }
            throw new SAXException("Exception writing image", ex);
        }
    }

    /**
     * Return the MIME type.
     */
    public String getMimeType() {
        return mimetype;
    }

    /**
     * Generate the unique key.
     * This key must be unique inside the space of this component.
     * This method must be invoked before the getValidity() method.
     *
     * @return The generated key or <code>0</code> if the component
     *              is currently not cacheable.
     */
    public Serializable getKey() {
        return "1";
    }

    /**
     * Generate the validity object.
     * Before this method can be invoked the getKey() method
     * must be invoked.
     *
     * @return The generated validity object or <code>null</code> if the
     *         component is currently not cacheable.
     */
    public SourceValidity getValidity() {
        return NOPValidity.SHARED_INSTANCE;
    }

    /**
     * Returns true so the pipeline implementation will buffer generated
     * output and write content length to the response.
     * <p>Batik's PNGTranscoder closes the output stream, therefore we
     * cannot pass the output stream directly to Batik and have to
     * instruct pipeline to buffer it. If we do not buffer, we would get
     * an exception when
     * {@link org.apache.cocoon.Cocoon#process(org.apache.cocoon.environment.Environment)}
     * tries to close the stream.
     */
    public boolean shouldSetContentLength() {
        return true;
    }
}
TOP

Related Classes of org.apache.cocoon.serialization.SVGSerializer

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.