Package org.geoserver.gwc

Source Code of org.geoserver.gwc.GWCCatalogListener

/**
* Copyright (c) 2001 - 2009 TOPP - www.openplans.org. All rights reserved.
* This code is licensed under the GPL 2.0 license, available at the root
* application directory.
*
* @author Arne Kepp / OpenGeo
*/
package org.geoserver.gwc;

import java.util.ArrayList;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.logging.Logger;

import org.geoserver.catalog.Catalog;
import org.geoserver.catalog.CatalogException;
import org.geoserver.catalog.LayerGroupInfo;
import org.geoserver.catalog.LayerInfo;
import org.geoserver.catalog.ResourceInfo;
import org.geoserver.catalog.StyleInfo;
import org.geoserver.catalog.event.CatalogAddEvent;
import org.geoserver.catalog.event.CatalogListener;
import org.geoserver.catalog.event.CatalogModifyEvent;
import org.geoserver.catalog.event.CatalogPostModifyEvent;
import org.geoserver.catalog.event.CatalogRemoveEvent;
import org.geoserver.catalog.impl.StyleInfoImpl;
import org.geoserver.ows.Dispatcher;
import org.geotools.geometry.jts.ReferencedEnvelope;
import org.geotools.referencing.CRS;
import org.geotools.util.logging.Logging;
import org.geowebcache.GeoWebCacheException;
import org.geowebcache.config.Configuration;
import org.geowebcache.config.meta.ServiceInformation;
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.TileLayerDispatcher;
import org.geowebcache.layer.wms.WMSGeoServerHelper;
import org.geowebcache.layer.wms.WMSLayer;
import org.geowebcache.util.ApplicationContextProvider;


/**
* This class implements a GeoWebCache configuration object, i.e.
* a source of WMS layer definitions, and a GeoServer catalog listener
* which is loaded on startup and listens for configuration changes.
*/
public class GWCCatalogListener implements CatalogListener, Configuration {

    private static Logger log = Logging.getLogger("org.geoserver.gwc.GWCCatalogListener");
   
    final protected Catalog cat;

    final protected Dispatcher gsDispatcher;
   
    final protected GridSetBroker gridSetBroker;
   
    final protected GWCCleanser cleanser;
   
    protected TileLayerDispatcher layerDispatcher;
   
    private List<String> mimeFormats = null;
   
    private int[] metaFactors = {4,4};
   
    private String wmsUrl = null;
   
    ArrayList<TileLayer> list;

    public GWCCatalogListener(
            Catalog cat,
            Dispatcher gsDispatcher,
            GridSetBroker gridSetBroker,
            ApplicationContextProvider ctxProv,
            GWCCleanser cleanser) {
       
        this.cat = cat;
       
        this.gridSetBroker = gridSetBroker;
       
        this.gsDispatcher = gsDispatcher;
       
        this.cleanser = cleanser;
       
        mimeFormats = new ArrayList<String>(5);
        mimeFormats.add("image/png");
        mimeFormats.add("image/gif");
        mimeFormats.add("image/png8");
        mimeFormats.add("image/jpeg");
        mimeFormats.add("application/vnd.google-earth.kml+xml");
       
        cat.addListener(this);
       
        log.fine("GWCCatalogListener registered with catalog");
    }
   
    public void setTileLayerDispatcher(TileLayerDispatcher layerDispatcher) {
        log.fine("TileLayerDispatcher was set");
        this.layerDispatcher = layerDispatcher;
    }
   
    public void handleAddEvent(CatalogAddEvent event) throws CatalogException {
        Object obj = event.getSource();
       
        WMSLayer wmsLayer = null;
       
        // We only handle layers here. Layer groups are initially empty
        if(obj instanceof LayerInfo) {
            LayerInfo layerInfo = (LayerInfo) obj;
            wmsLayer = getLayer(layerInfo);
        }
       
        if (wmsLayer != null && this.list != null) {
            addToList(wmsLayer);
            layerDispatcher.getLayers();
            layerDispatcher.add(wmsLayer);
            log.finer(wmsLayer.getName() + " added to TileLayerDispatcher");
        }
    }

    public void handleModifyEvent(CatalogModifyEvent event) throws CatalogException {
        // Not dealing with this one just yet
    }

    public void handlePostModifyEvent(CatalogPostModifyEvent event) throws CatalogException {
        Object obj = event.getSource();
       
        if(obj instanceof StyleInfoImpl) {
           // TODO First pass only considers default styles,
           // which is all GWC will accept anyway
           StyleInfoImpl si = (StyleInfoImpl) obj;
           String styleName = si.getName();
          
           LinkedList<String> layerNameList = new LinkedList<String>();
          
           // First we collect all the layers that use this style
           Iterator<LayerInfo> liter = cat.getLayers().iterator();
           while(liter.hasNext()) {
               LayerInfo li = liter.next();
               if(li.getDefaultStyle().getName().equals(styleName)) {
                   String prefixedName = li.getResource().getPrefixedName();
                   layerNameList.add(prefixedName);
                   cleanser.deleteLayer(prefixedName);
               }
           }
          
           // Now we check for layer groups that are affected
           Iterator<LayerGroupInfo> lgiter = cat.getLayerGroups().iterator();
           while(lgiter.hasNext()) {
               LayerGroupInfo lgi = lgiter.next();
               boolean truncate = false;
              
               // First we check for referenced to affected layers
               liter = lgi.getLayers().iterator();
               while(! truncate && liter.hasNext()) {
                   LayerInfo li = liter.next();
                   if(layerNameList.contains(li.getResource().getPrefixedName())){
                       truncate = true;
                   }
               }
              
               // Finally we need to check whether the style is used explicitly
               if(! truncate) {
                   Iterator<StyleInfo> siiter = lgi.getStyles().iterator();
                   while(! truncate && siiter.hasNext()) {
                       StyleInfo si2 = siiter.next();
                       if(si2 != null && si2.getName().equals(si.getName())) {
                           truncate = true;
                       }
                   }
               }
              
               if(truncate) {
                   cleanser.deleteLayer(lgi.getName());
               }
               // Next layer group
           }
          
        } else {

        WMSLayer wmsLayer = null; //getLayer(obj);

        if(obj instanceof LayerInfo) {
            LayerInfo li = (LayerInfo) obj;
            wmsLayer = getLayer(li);
        } else
        if(obj instanceof LayerGroupInfo) {
            LayerGroupInfo lgInfo = (LayerGroupInfo) obj;
            wmsLayer = getLayer(lgInfo);
        }
       
        if (wmsLayer != null && this.list != null) {           
            updateList(wmsLayer);
            layerDispatcher.getLayers();
            layerDispatcher.update(wmsLayer);
            log.finer(wmsLayer.getName() + " updated on TileLayerDispatcher");
            cleanser.deleteLayer(wmsLayer.getName());
        }
        }
    }

    public void handleRemoveEvent(CatalogRemoveEvent event) throws CatalogException {
        Object obj = event.getSource();
      
        String prefixedName = null;
       
        if(obj instanceof LayerGroupInfo) {
            LayerGroupInfo lgInfo = (LayerGroupInfo) obj;
            prefixedName = lgInfo.getName();
        } else
        if(obj instanceof LayerInfo) {
            LayerInfo layerInfo = (LayerInfo) obj;
            prefixedName = layerInfo.getResource().getPrefixedName();
        }
       
        if(null != prefixedName) {
            removeFromList(prefixedName);
            layerDispatcher.remove(prefixedName);
            cleanser.deleteLayer(prefixedName);
        }
    }

    public void reloaded() {
        try {
            layerDispatcher.reInit();
        } catch (GeoWebCacheException gwce) {
            log.fine("Unable to reinit TileLayerDispatcher gwce.getMessage()");
        }
    }

    public String getIdentifier() throws GeoWebCacheException {
        return "GeoServer Catalog Listener";
    }

    public ServiceInformation getServiceInformation() throws GeoWebCacheException {
        // TODO Auto-generated method stub
        return null;
    }

    public List<TileLayer> getTileLayers(boolean reload) throws GeoWebCacheException {
        if(! reload && list != null) {
            return list;
        }
       
        list = new ArrayList<TileLayer>(cat.getLayers().size());
       
        // Adding vector layers
        Iterator<LayerInfo> lIter = cat.getLayers().iterator();
        while(lIter.hasNext()) {
            LayerInfo li = lIter.next();           
            TileLayer tl = getLayer(li.getResource());
            //System.out.println(tl.getName() + " layerinfo");
            list.add(tl);
        }
               
        // Adding layer groups
        Iterator<LayerGroupInfo> lgIter = cat.getLayerGroups().iterator();
        while(lgIter.hasNext()) {
            LayerGroupInfo lgi = lgIter.next();
           
            TileLayer tl = getLayer(lgi);
            //System.out.println(tl.getName() + " layergroupinfo");
            list.add(tl);
        }
       
        log.fine("Responding with " + list.size() + " to getTileLayers() request from TileLayerDispatcher");
       
        return list;
    }
   
    synchronized private void updateList(WMSLayer wmsLayer) {
        if(this.list != null) {
            removeFromList(wmsLayer);
            addToList(wmsLayer);
        }
    }
   
    private void removeFromList(WMSLayer wmsLayer) {
        removeFromList(wmsLayer.getName());
    }
   
    synchronized private void removeFromList(String layerName) {
        if(this.list != null) {
            Iterator<TileLayer> iter = list.iterator();
            int i = 0;
            while(iter.hasNext()) {
                TileLayer tl = iter.next();
                if(tl != null && tl.getName().equals(layerName)) {
                    list.remove(i);
                    return;
                }
                i++;
            }
            log.finer("Did not find " + layerName + " in list.");
        }
    }
   
    synchronized private void addToList(WMSLayer wmsLayer) {
        if(this.list != null) {
            list.add(wmsLayer);
        }
    }
   
    private WMSLayer getLayer(LayerInfo li) {
        return getLayer(li.getResource());
    }
   
    private WMSLayer getLayer(LayerGroupInfo lgi) {
        ReferencedEnvelope bounds = null;
        ReferencedEnvelope latLonBounds = null;
        String nativeSRSName = null;
       
        try {
            bounds = lgi.getBounds();
            nativeSRSName = "EPSG:" + CRS.lookupEpsgCode(bounds.getCoordinateReferenceSystem(), true);
            latLonBounds = lgi.getBounds().transform(CRS.decode("EPSG:4326"), true);
        } catch (Exception e) {
            log.warning(e.getMessage());
        }
       
        if(latLonBounds == null) {
            log.severe("GWCCatalogListener had problems getting or reprojecting "
                    + lgi.getBounds() + " to EPSG:4326");
           
            return null;
        }
       
        WMSLayer retLayer = new WMSLayer(
                lgi.getName(),
                getWMSUrl(),
                null, // Styles
                lgi.getName(),
                mimeFormats,
                getGrids(lgi.getName(), latLonBounds, bounds, nativeSRSName),
                metaFactors,
                null,
                true);
       
        retLayer.setBackendTimeout(120);
        retLayer.setSourceHelper(new WMSGeoServerHelper(this.gsDispatcher));
       
        retLayer.initialize(gridSetBroker);
        return retLayer;
    }
   
    private WMSLayer getLayer(ResourceInfo fti) {
        ReferencedEnvelope nativeEnv = null;
        try {
            nativeEnv = fti.boundingBox();
        } catch (Exception e) {
            e.printStackTrace();
        }
       
        WMSLayer retLayer = new WMSLayer(
                fti.getPrefixedName(),
                getWMSUrl(),
                null, // Styles
                fti.getPrefixedName(),
                mimeFormats,
                getGrids(fti.getPrefixedName(), fti.getLatLonBoundingBox(), nativeEnv, fti.getSRS()),
                metaFactors,
                null,
                true);
        retLayer.setBackendTimeout(120);
        retLayer.setSourceHelper(new WMSGeoServerHelper(this.gsDispatcher));
       
        retLayer.initialize(gridSetBroker);
        return retLayer;
    }
   
//    private WMSLayer getLayer(CoverageInfo ci) {
//        WMSLayer retLayer = new WMSLayer(
//                ci.getPrefixedName(),
//                getWMSUrl(),
//                null, // Styles
//                ci.getPrefixedName(),
//                mimeFormats,
//                getGrids(ci.getLatLonBoundingBox()),
//                metaFactors,
//                null,
//                false);
//       
//        retLayer.setBackendTimeout(120);
//        retLayer.setSourceHelper(new WMSGeoServerHelper(this.gsDispatcher));
//       
//        retLayer.initialize(gridSetBroker);
//        return retLayer;  
//    }

    private String[] getWMSUrl() {
        String[] strs = { wmsUrl };
        return strs;
    }
   
    private Hashtable<String,GridSubset> getGrids(String layerName, ReferencedEnvelope latLonEnv,
            ReferencedEnvelope nativeEnv, String nativeSRSName) {       
        // LatLon stuff
        double minX = latLonEnv.getMinX();
        double minY = latLonEnv.getMinY();
        double maxX = latLonEnv.getMaxX();
        double maxY = latLonEnv.getMaxY();

        BoundingBox bounds4326 = new BoundingBox(minX,minY,maxX,maxY);
        BoundingBox bounds900913 = new BoundingBox(
                longToSphericalMercatorX(minX),
                latToSphericalMercatorY(minY),
                longToSphericalMercatorX(maxX),
                latToSphericalMercatorY(maxY));
       
        Hashtable<String,GridSubset> grids = new Hashtable<String,GridSubset>(3);
       
        GridSubset gridSubset4326 = GridSubsetFactory.createGridSubSet(
                gridSetBroker.WORLD_EPSG4326,
                bounds4326, 0, 25 );
       
        grids.put(gridSetBroker.WORLD_EPSG4326.getName(), gridSubset4326);
       
        GridSubset gridSubset900913 = GridSubsetFactory.createGridSubSet(
                gridSetBroker.WORLD_EPSG3857,
                bounds900913, 0, 25 );
       
        grids.put(gridSetBroker.WORLD_EPSG3857.getName(), gridSubset900913);
       
        // Native stuff
        if(nativeSRSName != null && ! nativeSRSName.equalsIgnoreCase("EPSG:4326")) {
           
            minX = nativeEnv.getMinX();
            minY = nativeEnv.getMinY();
            maxX = nativeEnv.getMaxX();
            maxY = nativeEnv.getMaxY();

            BoundingBox nativeBounds = new BoundingBox(minX,minY,maxX,maxY);
           
            SRS srs = null;
            try {
                srs = SRS.getSRS(nativeSRSName);
            } catch (GeoWebCacheException e) {
                e.printStackTrace();
            }
           
            String gridSetKey = nativeSRSName + "_" + layerName;
           
            GridSet gs = GridSetFactory.createGridSet(
                    gridSetKey, srs,
                    nativeBounds, false,
                    25, null,
                    0.00028,
                    256, 256);
           
            gridSetBroker.put(gs);
           
            GridSubset gsub = GridSubsetFactory.createGridSubSet(
                   gs, nativeBounds, 0, 24 );
           
            grids.put(gridSetKey, gsub);
           
        }
              
        return grids;
    }
   
    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;
    }

}
TOP

Related Classes of org.geoserver.gwc.GWCCatalogListener

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.