Package org.vfny.geoserver.wms.responses.featureInfo

Source Code of org.vfny.geoserver.wms.responses.featureInfo.HTMLTableFeatureInfoResponse

/* Copyright (c) 2001 - 2007 TOPP - www.openplans.org.  All rights reserved.
* This code is licensed under the GPL 2.0 license, availible at the root
* application directory.
*/
package org.vfny.geoserver.wms.responses.featureInfo;

import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.nio.charset.Charset;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;

import org.geoserver.catalog.CoverageInfo;
import org.geoserver.catalog.FeatureTypeInfo;
import org.geoserver.platform.ServiceException;
import org.geoserver.template.FeatureWrapper;
import org.geoserver.template.GeoServerTemplateLoader;
import org.geoserver.wms.WMS;
import org.geotools.feature.FeatureCollection;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;
import org.opengis.feature.type.Name;
import org.vfny.geoserver.wms.requests.GetFeatureInfoRequest;

import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;


/**
* Produces a FeatureInfo response in HTML.  Relies on {@link AbstractFeatureInfoResponse} and
* the feature delegate to do most of the work, just implements an HTML based
* writeTo method.
*
* <p>
* In the future James suggested that we allow some sort of template system, so
* that one can control the formatting of the html output, since now we just
* hard code some minimal header stuff. See
* http://jira.codehaus.org/browse/GEOS-196
* </p>
*
* @author James Macgill, PSU
* @author Andrea Aime, TOPP
* @version $Id: HTMLTableFeatureInfoResponse.java 13472 2009-10-10 09:39:53Z aaime $
*/
public class HTMLTableFeatureInfoResponse extends AbstractFeatureInfoResponse {
    private static Configuration templateConfig;

    static {
        // initialize the template engine, this is static to maintain a cache
        // over instantiations of kml writer
        templateConfig = new Configuration();
        templateConfig.setObjectWrapper(new FeatureWrapper());
    }
   
    GeoServerTemplateLoader templateLoader;
   
   
    /**
     *
     */
    public HTMLTableFeatureInfoResponse() {
        format = "text/html";
        supportedFormats = Collections.singletonList(format);
    }

    /**
     * Returns any extra headers that this service might want to set in the HTTP response object.
     * @see org.vfny.geoserver.Response#getResponseHeaders()
     */
    public HashMap getResponseHeaders() {
        return new HashMap();
    }

    /**
     * Writes the image to the client.
     *
     * @param out The output stream to write to.
     *
     * @throws org.vfny.geoserver.ServiceException For problems with geoserver
     * @throws java.io.IOException For problems writing the output.
     */
    @Override
    public void writeTo(OutputStream out)
        throws ServiceException, java.io.IOException {
        // setup the writer
        final GetFeatureInfoRequest request = getRequest();
        final WMS wmsConfig = request.getWMS();
        final Charset charSet = wmsConfig.getCharSet();
        final OutputStreamWriter osw = new OutputStreamWriter(out, charSet);
       
        // if there is only one feature type loaded, we allow for header/footer customization,
        // otherwise we stick with the generic ones
        Template header = null;
        Template footer = null;
        if(results.size() == 1) {
            SimpleFeatureType templateFeatureType = ((FeatureCollection<SimpleFeatureType, SimpleFeature>) results.get(0)).getSchema();
            header = getTemplate(templateFeatureType, "header.ftl", charSet);
            footer = getTemplate(templateFeatureType, "footer.ftl", charSet);
        } else {
            // load the default ones
            header = getTemplate(null, "header.ftl", charSet);
            footer = getTemplate(null, "footer.ftl", charSet);
        }
       
        try {
            header.process(null, osw);
        } catch (TemplateException e) {
            String msg = "Error occured processing header template.";
            throw (IOException) new IOException(msg).initCause(e);
        }
       
        //process content template for all feature collections found
        for (Iterator it = results.iterator(); it.hasNext();) {
            FeatureCollection<SimpleFeatureType, SimpleFeature> fc = (FeatureCollection) it.next();
            if(fc.size() > 0) {
                SimpleFeatureType ft = fc.getSchema();
                Template content = getTemplate(ft, "content.ftl", charSet);
                try {
                    content.process(fc, osw);
                } catch(TemplateException e) {
                    String msg = "Error occured processing content template " +
                    content.getName() + " for " + ft.getTypeName();
                    throw (IOException) new IOException(msg).initCause(e);
                }
            }
        }
       
        // if a template footer was loaded (ie, there were only one feature
        // collection), process it
        if(footer != null){
            try {
                footer.process(null, osw);
            } catch (TemplateException e) {
                String msg = "Error occured processing footer template.";
                throw (IOException) new IOException(msg).initCause(e);
            }
        }
        osw.flush();
    }

    /**
     * Uses a {@link GeoServerTemplateLoader TemplateLoader} too look up for the template file
     * named <code>templateFilename</code> for the given <code>featureType</code>.
     *
     * @param featureType the featureType to look the template for, may well correspond to an
     * actually registered feature type or to a wrapper feature type used to adapt the result of
     * the feature info request over a raster coverage. In case you want to load the default template
     * you can leave this argument null
     * @param templateFileName the name of the template to look for
     * @param charset the encoding to apply to the resulting {@link Template}
     * @return the template named <code>templateFileName</code>
     * @throws IOException if the template can't be loaded
     */
    Template getTemplate(SimpleFeatureType featureType, String templateFileName, Charset charset) throws IOException {
        // setup template subsystem
        if(templateLoader == null) {
            templateLoader = new GeoServerTemplateLoader(getClass());
        }
       
        if(featureType != null) {
            final Name name = featureType.getName();
            final WMS wms = getRequest().getWMS();

            FeatureTypeInfo featureTypeInfo = wms.getFeatureTypeInfo(name);

            if(featureTypeInfo == null){
                //It may be a wrapped coverage
                CoverageInfo cInfo = wms.getCoverageInfo(name);
                if(cInfo != null){
                    templateLoader.setCoverage(cInfo);
                }else{
                    throw new IllegalArgumentException("Can't find neither a FeatureType nor " +
                            "a CoverageInfo named " + name);
                }
            } else {
                templateLoader.setFeatureType(featureType);
            }
        }

        synchronized (templateConfig) {
            templateConfig.setTemplateLoader(templateLoader);
            Template t = templateConfig.getTemplate(templateFileName);
            t.setEncoding(charset.name());
            return t;
        }
    }
}
TOP

Related Classes of org.vfny.geoserver.wms.responses.featureInfo.HTMLTableFeatureInfoResponse

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.