org.kalypsodeegree_impl.graphics.sld.ExternalGraphic_Impl.java Source code

Java tutorial

Introduction

Here is the source code for org.kalypsodeegree_impl.graphics.sld.ExternalGraphic_Impl.java

Source

/** This file is part of kalypso/deegree.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * history:
 * 
 * Files in this package are originally taken from deegree and modified here
 * to fit in kalypso. As goals of kalypso differ from that one in deegree
 * interface-compatibility to deegree is wanted but not retained always.
 * 
 * If you intend to use this software in other ways than in kalypso
 * (e.g. OGC-web services), you should consider the latest version of deegree,
 * see http://www.deegree.org .
 *
 * all modifications are licensed as deegree,
 * original copyright:
 *
 * Copyright (C) 2001 by:
 * EXSE, Department of Geography, University of Bonn
 * http://www.giub.uni-bonn.de/exse/
 * lat/lon GmbH
 * http://www.lat-lon.de
 */
package org.kalypsodeegree_impl.graphics.sld;

import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferInt;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;

import javax.media.jai.JAI;
import javax.media.jai.RenderedOp;

import org.apache.batik.transcoder.SVGAbstractTranscoder;
import org.apache.batik.transcoder.TranscoderException;
import org.apache.batik.transcoder.TranscoderInput;
import org.apache.batik.transcoder.TranscoderOutput;
import org.apache.batik.transcoder.image.PNGTranscoder;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.graphics.PaletteData;
import org.kalypso.contribs.eclipse.core.runtime.StatusUtilities;
import org.kalypso.contribs.java.net.IUrlResolver2;
import org.kalypsodeegree.KalypsoDeegreePlugin;
import org.kalypsodeegree.graphics.sld.ExternalGraphic;
import org.kalypsodeegree.xml.Marshallable;

import com.sun.media.jai.codec.MemoryCacheSeekableStream;

/**
 * The ExternalGraphic element allows a reference to be made to an external graphic file with a Web URL. The
 * OnlineResource sub-element gives the URL and the Format sub-element identifies the expected document MIME type of a
 * successful fetch. Knowing the MIME type in advance allows the styler to select the best- supported format from the
 * list of URLs with equivalent content.
 * <p>
 * ----------------------------------------------------------------------
 * </p>
 * 
 * @author <a href="mailto:poth@lat-lon.de">Andreas Poth </a>
 * @version $Revision$ $Date$
 */
public class ExternalGraphic_Impl implements ExternalGraphic, Marshallable {
    private BufferedImage m_image = null;

    private String m_format = null;

    private String m_onlineResource = null;

    private final IUrlResolver2 m_resolver;

    private ByteArrayOutputStream m_bos;

    private TranscoderOutput m_output;

    private PNGTranscoder m_transcoder;

    private TranscoderInput m_transcoderInput;

    /**
     * Creates a new ExternalGraphic_Impl object.
     * 
     * @param format
     * @param onlineResource
     */
    ExternalGraphic_Impl(final IUrlResolver2 resolver, final String format, final String onlineResource) {
        m_resolver = resolver;
        setFormat(format);
        setOnlineResource(onlineResource);
    }

    /**
     * the Format sub-element identifies the expected document MIME type of a successful fetch.
     * 
     * @return Format of the external graphic
     */
    @Override
    public String getFormat() {
        return m_format;
    }

    /**
     * sets the format (MIME type)
     * 
     * @param format
     *          Format of the external graphic
     */
    @Override
    public void setFormat(final String format) {
        m_format = format;
    }

    /**
     * The OnlineResource gives the URL of the external graphic
     * 
     * @return URL of the external graphic
     */
    @Override
    public String getOnlineResource() {
        return m_onlineResource;
    }

    /**
     * @see org.kalypsodeegree.graphics.sld.ExternalGraphic#getOnlineResourceURL()
     */
    @Override
    public URL getOnlineResourceURL() throws MalformedURLException {
        return m_resolver.resolveURL(m_onlineResource);
    }

    /**
     * sets the online resource / URL of the external graphic
     * 
     * @param onlineResource
     *          URL of the external graphic
     */
    @Override
    public void setOnlineResource(final String onlineResource) {
        m_image = null;

        m_onlineResource = onlineResource;

        try {
            final URL url = getOnlineResourceURL();
            if (url == null)
                return;

            final String file = url.getFile();
            // FIXME: ???
            final int idx = file.indexOf("$");
            if (idx == -1) {
                retrieveImage(url);
            }
        } catch (final Throwable e) {
            final String msg = String.format("Failed to load resource: %s", onlineResource);
            final IStatus status = new Status(IStatus.WARNING, KalypsoDeegreePlugin.getID(), msg, e);
            KalypsoDeegreePlugin.getDefault().getLog().log(status);
        }
    }

    /**
     * @param onlineResource
     */
    private void retrieveImage(final URL onlineResource) {
        try {
            final String t = onlineResource.toExternalForm();
            if (t.trim().toLowerCase().endsWith(".svg")) {
                // initialize the the classes required for svg handling
                m_bos = new ByteArrayOutputStream(2000);
                m_output = new TranscoderOutput(m_bos);
                // PNGTranscoder is needed to handle transparent parts
                // of a SVG
                m_transcoder = new PNGTranscoder();
                try {
                    final String externalForm = onlineResource.toExternalForm();
                    m_transcoderInput = new TranscoderInput(externalForm);
                } catch (final Exception e) {
                    e.printStackTrace();
                }
            } else {
                final InputStream is = onlineResource.openStream();
                final MemoryCacheSeekableStream mcss = new MemoryCacheSeekableStream(is);
                final RenderedOp rop = JAI.create("stream", mcss);
                m_image = rop.getAsBufferedImage();
                mcss.close();
                is.close();
            }
        } catch (final IOException e) {
            System.out.println("Yikes: " + e);
        }
    }

    /**
     * returns the external graphic as an image. this method is not part of the sld specifications but it is added for
     * speed up applications
     * 
     * @return the external graphic as BufferedImage
     */
    @Override
    public BufferedImage getAsImage(final int targetSizeX, final int targetSizeY) {
        if (m_image == null) {
            if (m_transcoderInput != null) {
                m_transcoder.addTranscodingHint(SVGAbstractTranscoder.KEY_HEIGHT, new Float(targetSizeX));
                m_transcoder.addTranscodingHint(SVGAbstractTranscoder.KEY_WIDTH, new Float(targetSizeY));
                try {
                    m_transcoder.transcode(m_transcoderInput, m_output);
                    try {
                        m_bos.flush();
                        m_bos.close();
                    } catch (final IOException e3) {
                        e3.printStackTrace();
                    }
                } catch (final TranscoderException e) {
                    e.printStackTrace();
                }
                try {
                    final ByteArrayInputStream is = new ByteArrayInputStream(m_bos.toByteArray());
                    final MemoryCacheSeekableStream mcss = new MemoryCacheSeekableStream(is);
                    final RenderedOp rop = JAI.create("stream", mcss);
                    m_image = rop.getAsBufferedImage();
                    mcss.close();
                } catch (final IOException e1) {
                    e1.printStackTrace();
                }
            }
        }

        return m_image;
    }

    /**
     * @see org.kalypsodeegree.graphics.sld.ExternalGraphic#paintAwt(java.awt.Graphics2D)
     */
    @Override
    public void paintAwt(final Graphics2D g, final int targetSizeX, final int targetSizeY) {
        /* Make sure buffered image is created */
        getAsImage(targetSizeX, targetSizeY);

        // Is there a better way? Isn't it possible to render a Jai-Image directly into an awt-graphics?
        if (m_image != null) {
            g.drawImage(m_image, 0, 0, m_image.getWidth(), m_image.getHeight(), null);
        }
    }

    @Override
    public void paint(final GC gc) {
        if (m_image == null)
            return;

        Image swtImage = null;
        try {
            swtImage = makeSWTImage(m_image);
            gc.drawImage(swtImage, 0, 0);
            swtImage.dispose();
        } catch (final Exception e) {
            KalypsoDeegreePlugin.getDefault().getLog().log(StatusUtilities.statusFromThrowable(e));
        } finally {
            if (swtImage != null)
                swtImage.dispose();
        }
    }

    /**
     * implementation taken from http://dev.eclipse.org/newslists/news.eclipse.platform.swt/msg10712.html<br/>
     * FIXME: move into helper
     */
    private static Image makeSWTImage(final java.awt.Image ai) throws Exception {
        // TODO transparent pixel (ATM transparent pixels are converted into black pixels)

        final int width = ai.getWidth(null);
        final int height = ai.getHeight(null);

        final BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);

        final Graphics2D g2d = bufferedImage.createGraphics();
        g2d.drawImage(ai, 0, 0, null);
        g2d.dispose();

        final int[] data = ((DataBufferInt) bufferedImage.getData().getDataBuffer()).getData();
        final ImageData imageData = new ImageData(width, height, 24, new PaletteData(0xFF0000, 0x00FF00, 0x0000FF));
        imageData.setPixels(0, 0, data.length, data, 0);

        final ImageDescriptor descriptor = ImageDescriptor.createFromImageData(imageData);
        return descriptor.createImage();
    }

    /**
     * exports the content of the ExternalGraphic as XML formated String
     * 
     * @return xml representation of the ExternalGraphic
     */
    @Override
    public String exportAsXML() {
        final StringBuffer sb = new StringBuffer(200);
        sb.append("<ExternalGraphic>");
        sb.append("<OnlineResource xmlns:xlink='http://www.w3.org/1999/xlink' ");
        sb.append("xlink:type='simple' xlink:href='");
        // sb.append( NetWorker.url2String( m_onlineResource ) + "'/>" );
        sb.append(m_onlineResource + "'/>");
        sb.append("<Format>").append(m_format).append("</Format>");
        sb.append("</ExternalGraphic>");

        return sb.toString();
    }

    @Override
    public IUrlResolver2 getResolver() {
        return m_resolver;
    }
}