Package org.geowebcache.config

Source Code of org.geowebcache.config.GetCapabilitiesConfiguration

/**
* This program 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 3 of the License, or
* (at your option) any later version.
*
*  This program 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 General Public License for more details.
*
*  You should have received a copy of the GNU Lesser General Public License
*  along with this program.  If not, see <http://www.gnu.org/licenses/>.
*
* @author Arne Kepp, The Open Planning Project, Copyright 2008
*/
package org.geowebcache.config;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Set;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.geotools.data.ows.CRSEnvelope;
import org.geotools.data.ows.Layer;
import org.geotools.data.ows.StyleImpl;
import org.geotools.data.ows.WMSCapabilities;
import org.geotools.data.wms.WebMapServer;
import org.geotools.data.wms.xml.Dimension;
import org.geotools.data.wms.xml.Extent;
import org.geotools.ows.ServiceException;
import org.geowebcache.GeoWebCacheException;
import org.geowebcache.config.meta.ServiceInformation;
import org.geowebcache.filter.parameters.NaiveWMSDimensionFilter;
import org.geowebcache.filter.parameters.ParameterFilter;
import org.geowebcache.grid.BoundingBox;
import org.geowebcache.grid.GridSet;
import org.geowebcache.grid.GridSetBroker;
import org.geowebcache.grid.GridSetFactory;
import org.geowebcache.grid.GridSubset;
import org.geowebcache.grid.GridSubsetFactory;
import org.geowebcache.grid.SRS;
import org.geowebcache.layer.TileLayer;
import org.geowebcache.layer.meta.LayerMetaInformation;
import org.geowebcache.layer.meta.MetadataURL;
import org.geowebcache.layer.wms.WMSHttpHelper;
import org.geowebcache.layer.wms.WMSLayer;

public class GetCapabilitiesConfiguration implements Configuration {
    private static Log log = LogFactory
            .getLog(org.geowebcache.config.GetCapabilitiesConfiguration.class);

    private GridSetBroker gridSetBroker;

    private String url = null;

    private int backendTimeout = 120;

    private String mimeTypes = null;

    private String metaTiling = null;

    private String vendorParameters = null;

    private boolean allowCacheBypass = false;

    private final HashMap<String, TileLayer> layers;

    private XMLConfiguration primaryConfig;

    public GetCapabilitiesConfiguration(GridSetBroker gridSetBroker, String url, String mimeTypes,
            String metaTiling, String allowCacheBypass) {
        this.gridSetBroker = gridSetBroker;
        this.url = url;
        this.mimeTypes = mimeTypes;
        this.metaTiling = metaTiling;
        this.layers = new HashMap<String, TileLayer>();
        if (Boolean.parseBoolean(allowCacheBypass)) {
            this.allowCacheBypass = true;
        }
        log.info("Constructing from url " + url);
    }

    public GetCapabilitiesConfiguration(GridSetBroker gridSetBroker, String url, String mimeTypes,
            String metaTiling, String vendorParameters, String allowCacheBypass) {
        this.gridSetBroker = gridSetBroker;
        this.url = url;
        this.mimeTypes = mimeTypes;
        this.metaTiling = metaTiling;
        this.vendorParameters = vendorParameters;
        this.layers = new HashMap<String, TileLayer>();
        if (Boolean.parseBoolean(allowCacheBypass)) {
            this.allowCacheBypass = true;
        }
        log.info("Constructing from url " + url);
    }

    /**
     * Optionally used by Spring
     *
     * @param backendTimeout
     */
    public void setBackendTimeout(int backendTimeout) {
        this.backendTimeout = backendTimeout;
    }

    /**
     * Identifier for this Configuration instance
     *
     * @return the URL given to the constructor
     */
    public String getIdentifier() {
        return url;
    }

    /**
     * Gets the XML document and parses it, creates WMSLayers for the relevant
     *
     * @return the layers described at the given URL
     */
    private synchronized List<TileLayer> getTileLayers(boolean reload) throws GeoWebCacheException {
        List<TileLayer> layers = null;

        WebMapServer wms = getWMS();
        if (wms == null) {
            throw new ConfigurationException("Unable to connect to " + this.url);
        }

        String wmsUrl = getWMSUrl(wms);
        log.info("Using " + wmsUrl + " to generate URLs for WMS requests");

        String urlVersion = parseVersion(url);

        layers = getLayers(wms, wmsUrl, urlVersion);

        if (layers == null || layers.size() < 1) {
            log.error("Unable to find any layers based on " + url);
        } else {
            log.info("Loaded " + layers.size() + " layers from " + url);
        }

        return layers;
    }

    public ServiceInformation getServiceInformation() {
        return null;
    }

    /**
     * Finds URL to WMS service and attempts to slice away the service parameter, since we will add
     * that anyway.
     *
     * @param wms
     * @return
     */
    private String getWMSUrl(WebMapServer wms) {
        // // http://sigma.openplans.org:8080/geoserver/wms?SERVICE=WMS&
        String wmsUrl = wms.getCapabilities().getRequest().getGetCapabilities().getGet().toString();
        int queryStart = wmsUrl.lastIndexOf("?");
        if (queryStart > 0) {

            String preQuery = wmsUrl.substring(queryStart);
            if (preQuery.equalsIgnoreCase("?service=wms&")) {
                wmsUrl = wmsUrl.substring(0, wmsUrl.lastIndexOf("?"));
            }
        }
        return wmsUrl;
    }

    private List<TileLayer> getLayers(WebMapServer wms, String wmsUrl, String urlVersion)
            throws GeoWebCacheException {
        List<TileLayer> layers = new LinkedList<TileLayer>();

        WMSCapabilities capabilities = wms.getCapabilities();
        if (capabilities == null) {
            throw new ConfigurationException("Unable to get capabitilies from " + wmsUrl);
        }

        WMSHttpHelper sourceHelper = new WMSHttpHelper();

        List<Layer> layerList = capabilities.getLayerList();
        Iterator<Layer> layerIter = layerList.iterator();

        while (layerIter.hasNext()) {
            Layer layer = layerIter.next();
            String name = layer.getName();
            String stylesStr = "";

            String title = layer.getTitle();

            String description = layer.get_abstract();

            LayerMetaInformation layerMetaInfo = null;
            if (title != null || description != null) {
                layerMetaInfo = new LayerMetaInformation(title, description, null, null);
            }
            boolean queryable = layer.isQueryable();

            if (name != null) {
                List<StyleImpl> styles = layer.getStyles();

                StringBuffer buf = new StringBuffer();
                if (styles != null) {
                    Iterator<StyleImpl> iter = styles.iterator();
                    boolean hasOne = false;
                    while (iter.hasNext()) {
                        if (hasOne) {
                            buf.append(",");
                        }
                        buf.append(iter.next().getName());
                        hasOne = true;
                    }
                    stylesStr = buf.toString();
                }

                double minX = layer.getLatLonBoundingBox().getMinX();
                double minY = layer.getLatLonBoundingBox().getMinY();
                double maxX = layer.getLatLonBoundingBox().getMaxX();
                double maxY = layer.getLatLonBoundingBox().getMaxY();

                BoundingBox bounds4326 = new BoundingBox(minX, minY, maxX, maxY);

                log.info("Found layer: " + layer.getName() + " with LatLon bbox "
                        + bounds4326.toString());

                BoundingBox bounds3785 = new BoundingBox(longToSphericalMercatorX(minX),
                        latToSphericalMercatorY(minY), longToSphericalMercatorX(maxX),
                        latToSphericalMercatorY(maxY));

                String[] wmsUrls = { wmsUrl };

                LinkedList<ParameterFilter> paramFilters = new LinkedList<ParameterFilter>();
                for (Dimension dimension : layer.getDimensions().values()) {
                    Extent dimExtent = layer.getExtent(dimension.getName());
                    paramFilters.add(new NaiveWMSDimensionFilter(dimension, dimExtent));
                }

                WMSLayer wmsLayer = null;
                try {
                    wmsLayer = getLayer(name, wmsUrls, bounds4326, bounds3785, stylesStr,
                            queryable, layer.getBoundingBoxes(), paramFilters);
                } catch (GeoWebCacheException gwc) {
                    log.error("Error creating " + layer.getName() + ": " + gwc.getMessage());
                }

                if (wmsLayer != null) {

                    // Finalize with some defaults
                    wmsLayer.setCacheBypassAllowed(allowCacheBypass);
                    wmsLayer.setBackendTimeout(backendTimeout);

                    wmsLayer.setMetaInformation(layerMetaInfo);

                    if (urlVersion != null) {
                        wmsLayer.setVersion(urlVersion);
                    } else {
                        String wmsVersion = capabilities.getVersion();
                        if (wmsVersion != null && wmsVersion.length() > 0) {
                            wmsLayer.setVersion(wmsVersion);
                        }
                    }
                    wmsLayer.setSourceHelper(sourceHelper);

                    List<org.geotools.data.wms.xml.MetadataURL> metadataURLs = layer.getMetadataURL();
                    if (metadataURLs != null && !metadataURLs.isEmpty()) {
                        List<MetadataURL> convertedMetadataURLs = new ArrayList<MetadataURL>();
                        for (org.geotools.data.wms.xml.MetadataURL metadataURL : metadataURLs) {
                            convertedMetadataURLs.add(new MetadataURL(metadataURL.getType(), metadataURL.getFormat(), metadataURL.getUrl()));
                        }
                        wmsLayer.setMetadataURLs(convertedMetadataURLs);
                    }

                    layers.add(wmsLayer);
                }
            }
        }

        return layers;
    }

    private WMSLayer getLayer(String name, String[] wmsurl, BoundingBox bounds4326,
            BoundingBox bounds3785, String stylesStr, boolean queryable,
            Map<String, CRSEnvelope> additionalBounds, List<ParameterFilter> paramFilters)
            throws GeoWebCacheException {

        Hashtable<String, GridSubset> grids = new Hashtable<String, GridSubset>(2);
        grids.put(gridSetBroker.WORLD_EPSG4326.getName(),
                GridSubsetFactory.createGridSubSet(gridSetBroker.WORLD_EPSG4326, bounds4326, 0, 30));
        grids.put(gridSetBroker.WORLD_EPSG3857.getName(),
                GridSubsetFactory.createGridSubSet(gridSetBroker.WORLD_EPSG3857, bounds3785, 0, 30));

        if (additionalBounds != null && additionalBounds.size() > 0) {
            Iterator<CRSEnvelope> iter = additionalBounds.values().iterator();
            while (iter.hasNext()) {
                CRSEnvelope env = iter.next();
                SRS srs = null;
                if (env.getEPSGCode() != null) {
                    srs = SRS.getSRS(env.getEPSGCode());
                }

                if (srs == null) {
                    log.error(env.toString() + " has no EPSG code");
                } else if (srs.getNumber() == 4326 || srs.getNumber() == 900913
                        || srs.getNumber() == 3857) {
                    log.debug("Skipping " + srs.toString() + " for " + name);
                } else {
                    String gridSetName = name + ":" + srs.toString();
                    BoundingBox extent = new BoundingBox(env.getMinX(), env.getMinY(),
                            env.getMaxX(), env.getMaxY());

                    GridSet gridSet = GridSetFactory.createGridSet(gridSetName, srs, extent, false,
                            25, null, GridSetFactory.DEFAULT_PIXEL_SIZE_METER, 256, 256, false);
                    grids.put(gridSetName, GridSubsetFactory.createGridSubSet(gridSet));
                }
            }

        }

        List<String> mimeFormats = null;
        if (this.mimeTypes != null) {
            String[] mimeFormatArray = this.mimeTypes.split(",");
            mimeFormats = new ArrayList<String>(mimeFormatArray.length);

            // This is stupid... but oh well, we're only doing it once
            for (int i = 0; i < mimeFormatArray.length; i++) {
                mimeFormats.add(mimeFormatArray[i]);
            }
        } else {
            mimeFormats = new ArrayList<String>(3);
            mimeFormats.add("image/png");
            mimeFormats.add("image/png8");
            mimeFormats.add("image/jpeg");
        }

        String[] metaStrings = this.metaTiling.split("x");

        int[] metaWidthHeight = { Integer.parseInt(metaStrings[0]),
                Integer.parseInt(metaStrings[1]) };

        return new WMSLayer(name, wmsurl, stylesStr, name, mimeFormats, grids, paramFilters,
                metaWidthHeight, this.vendorParameters, queryable, null);
    }

    WebMapServer getWMS() {
        try {
            return new WebMapServer(new URL(url));
        } catch (IOException ioe) {
            log.error(url + " -> " + ioe.getMessage());
        } catch (ServiceException se) {
            log.error(se.getMessage());
        }
        return null;
    }

    private String parseVersion(String url) {
        String tmp = url.toLowerCase();
        int start = tmp.indexOf("version=");
        if (start == -1) {
            return null;
        }

        start += "version=".length();

        int stop = tmp.indexOf("&", start);
        if (stop > 0) {
            return tmp.substring(start, stop);
        } else {
            return tmp.substring(start);
        }
    }

    private double longToSphericalMercatorX(double x) {
        return (x / 180.0) * 20037508.34;
    }

    private double latToSphericalMercatorY(double y) {
        if (y > 85.05112) {
            y = 85.05112;
        }

        if (y < -85.05112) {
            y = -85.05112;
        }

        y = (Math.PI / 180.0) * y;
        double tmp = Math.PI / 4.0 + y / 2.0;
        return 20037508.34 * Math.log(Math.tan(tmp)) / Math.PI;
    }

    /**
     * @see org.geowebcache.config.Configuration#isRuntimeStatsEnabled()
     */
    public boolean isRuntimeStatsEnabled() {
        return false;
    }

    /**
     * @see org.geowebcache.config.Configuration#initialize(org.geowebcache.grid.GridSetBroker)
     */
    public int initialize(GridSetBroker gridSetBroker) throws GeoWebCacheException {
        this.gridSetBroker = gridSetBroker;
        List<TileLayer> tileLayers = getTileLayers(true);
        this.layers.clear();
        for (TileLayer layer : tileLayers) {
            layer.initialize(gridSetBroker);
            if(primaryConfig!=null) {
                primaryConfig.setDefaultValues(layer);
            } else if (log.isErrorEnabled()) {
                log.error("GetCapabilitiesConfiguration could not initialize a layer with default "+
                        "values as it does not have a global configuration to delegate to.");
            }
            layers.put(layer.getName(), layer);
        }
        return tileLayers.size();
    }

    /**
     * @see org.geowebcache.config.Configuration#getTileLayers()
     * @deprecated
     */
    public List<TileLayer> getTileLayers() {
        return Collections.unmodifiableList(new ArrayList<TileLayer>(layers.values()));
    }

    /**
     * @see org.geowebcache.config.Configuration#getLayers()
     */
    public Iterable<? extends TileLayer> getLayers() {
        return Collections.unmodifiableList(new ArrayList<TileLayer>(layers.values()));
    }

    /**
     * @see org.geowebcache.config.Configuration#getTileLayerNames()
     */
    public Set<String> getTileLayerNames() {
        return new HashSet<String>(layers.keySet());
    }

    /**
     * @see org.geowebcache.config.Configuration#containsLayer(java.lang.String)
     */
    public boolean containsLayer(String tileLayerId) {
        return getTileLayerById(tileLayerId) != null;
    }

    /**
     * @see org.geowebcache.config.Configuration#getTileLayerById(java.lang.String)
     */
    public TileLayer getTileLayerById(String layerId) {
        // this configuration does not differentiate between layer identifier and identity
        return getTileLayer(layerId);
    }

    /**
     * @see org.geowebcache.config.Configuration#getTileLayer(java.lang.String)
     */
    public TileLayer getTileLayer(String layerName) {
        return layers.get(layerName);
    }

    /**
     * @see org.geowebcache.config.Configuration#getTileLayerCount()
     */
    public int getTileLayerCount() {
        return layers.size();
    }

    /**
     * @see org.geowebcache.config.Configuration#removeLayer(java.lang.String)
     */
    public boolean removeLayer(String layerName) {
        return layers.remove(layerName) != null;
    }

    /**
     * @see org.geowebcache.config.Configuration#modifyLayer(org.geowebcache.layer.TileLayer)
     */
    public void modifyLayer(TileLayer tl) throws NoSuchElementException {
        throw new UnsupportedOperationException("modifyLayer is not supported by "
                + getClass().getSimpleName());
    }

    /**
     * @see org.geowebcache.config.Configuration#save()
     */
    public void save() throws IOException {
        // silently do nothing
    }

    /**
     * @return {@code false}
     * @see org.geowebcache.config.Configuration#canSave(org.geowebcache.layer.TileLayer)
     */
    public boolean canSave(TileLayer tl) {
        return false;
    }

    /**
     * @see org.geowebcache.config.Configuration#addLayer(org.geowebcache.layer.TileLayer)
     */
    public void addLayer(TileLayer tl) throws IllegalArgumentException {
        if (tl == null) {
            throw new NullPointerException();
        }
        throw new IllegalArgumentException(
                "This is a read only configuration object, can't add tile layer " + tl.getName());
    }
   
    /**
     * Get the global configuration delegated to.
     */
    protected XMLConfiguration getPrimaryConfig() {
        return primaryConfig;
    }

    /**
     * Set the global configuration object to delegate to.
     */
     public void setPrimaryConfig(XMLConfiguration primaryConfig) {
        this.primaryConfig = primaryConfig;
    }
   
}
TOP

Related Classes of org.geowebcache.config.GetCapabilitiesConfiguration

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.