Package org.geoserver.wms.eo

Source Code of org.geoserver.wms.eo.EOGetFeatureInfoChecker

/* (c) 2014 Open Source Geospatial Foundation - all rights reserved
* (c) 2013 OpenPlans
* This code is licensed under the GPL 2.0 license, available at the root
* application directory.
*/
package org.geoserver.wms.eo;

import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.geoserver.catalog.CoverageInfo;
import org.geoserver.catalog.LayerInfo;
import org.geoserver.catalog.MetadataMap;
import org.geoserver.ows.AbstractDispatcherCallback;
import org.geoserver.ows.DispatcherCallback;
import org.geoserver.ows.Request;
import org.geoserver.platform.Operation;
import org.geoserver.platform.ServiceException;
import org.geoserver.wms.GetFeatureInfoRequest;
import org.geoserver.wms.MapLayerInfo;
import org.geotools.coverage.grid.io.GridCoverage2DReader;
import org.geotools.factory.GeoTools;
import org.geotools.gce.imagemosaic.ImageMosaicFormat;
import org.geotools.gce.imagemosaic.MergeBehavior;
import org.geotools.util.NullProgressListener;
import org.opengis.coverage.grid.GridCoverageReader;
import org.opengis.parameter.ParameterDescriptor;
import org.opengis.referencing.ReferenceIdentifier;

/**
* {@link EOGetFeatureInfoChecker} is supposed to manipulate the GetFeatureInfo request in
* order to comply with WMS-EO Requirements.
*
* @author Simone Giannecchini, GeoSolutions SAS
*
*/
public class EOGetFeatureInfoChecker extends AbstractDispatcherCallback implements
        DispatcherCallback {

    @SuppressWarnings({ "rawtypes", "unchecked" })
    @Override
    public Operation operationDispatched(Request request, Operation operation) {
        // paranoiac checks
        if(operation==null||operation.getParameters().length<=0){
            return super.operationDispatched(request, operation);
        }
       
       
        // === get the underlying operation and check if this is a feature info or not
        final Object o=operation.getParameters()[0];
        if(!(o instanceof GetFeatureInfoRequest)){
            return super.operationDispatched(request, operation);
        }
       
        // === k, this is a getfeatureinfo request let's check if it is 1.3.0
        org.geoserver.wms.GetFeatureInfoRequest featureinfoReq = (GetFeatureInfoRequest) o;
        if(!featureinfoReq.getVersion().equalsIgnoreCase("1.3.0")){
            return super.operationDispatched(request, operation);
        }
       
        // === ok, it is a getfeatureinfo and 1.3.0, let's do the magic!

        // inspect the incoming request for custom dimensions
        final Map<String, String> rawKvpMap = request.getRawKvp();
        Map<String,List> customDomains = new HashMap<String, List>();
        if (rawKvpMap != null) {
            for (Map.Entry<String, String> kvp : rawKvpMap.entrySet()) {
                String name = kvp.getKey();
                if (name.startsWith("DIM_")) {
                    name = name.substring(4);
                    if(name.length()>0&&name != null) {
                            final ArrayList<String> val = new ArrayList<String>(1);
                            if(kvp.getValue().indexOf(",")>0){
                                String[] elements = kvp.getValue().split(",");
                                val.addAll(Arrays.asList(elements));
                            }else{
                                val.add(kvp.getValue());
                            }
                            customDomains.put(name, val);
                       
                    }
                }
            }
        }       
       
        // cycle on all the requested layers and make sure we check the custom dimensions
        final List<MapLayerInfo> queryLayers = featureinfoReq.getQueryLayers();
        for(MapLayerInfo queryLayerInfo:queryLayers){
           
            // geoserver info objects
            final CoverageInfo cInfo=queryLayerInfo.getCoverage();
            final LayerInfo layerInfo=queryLayerInfo.getLayerInfo();
           
            // is it a BANDS Layer?
            final MetadataMap metadata = layerInfo.getMetadata();
            if(metadata.containsKey(EoLayerType.KEY)&&metadata.get(EoLayerType.KEY).equals(EoLayerType.BAND_COVERAGE.name())){
               
                // check the MERGE_BEHAVIOR as flat (this is harmless anyway)
                Map<String, Serializable> params = cInfo.getParameters();
                for(Entry<String, Serializable> entry:params.entrySet()){
                    if(entry.getKey().equalsIgnoreCase(ImageMosaicFormat.MERGE_BEHAVIOR.getName().getCode())){
                        entry.setValue(MergeBehavior.STACK.toString());
                        break;
                    }
                }
                try{
                    // check the #of requested values
                    // get the read parameters for this reader
                    final GridCoverageReader gridCoverageReader = cInfo.getGridCoverageReader(new NullProgressListener(), GeoTools.getDefaultHints());
                    final Set<ParameterDescriptor<List>> dynamicParameters = ((GridCoverage2DReader)gridCoverageReader).getDynamicParameters();
                    if(dynamicParameters.isEmpty()){
                        throw new IllegalStateException("Layer "+cInfo.getTitle()+ " has no additional dimensions which are required for an EO BANDS layer");
                    }
                    final Set<ReferenceIdentifier> dynamicParametersNames= new HashSet<ReferenceIdentifier>();
                    for(ParameterDescriptor<List> param:dynamicParameters){
                        dynamicParametersNames.add(param.getName());               
                    }
                   
                    // inspect the incoming request
                    for(ParameterDescriptor<List> readParam:dynamicParameters){
                        final String name=readParam.getName().getCode();
                       
                        // ok, do we have this one in the request? If so, do we have 1 or 3 values?
                        if(customDomains.containsKey(name)){
                            final List values=customDomains.get(name);
                            // 1 or 3, 0 to leave default kick in
                            if(values.size()!=0&&values.size()!=1&& values.size()!=3){
                                throw new ServiceException("Dimension DIM_"+name+" has been request with wrong number of values: "+values.size(), "InvalidDimensionValue");
                            }
                           
                            // NOTICE that implicitly we leave the default do its magic if no val
                        }
                    }
                   
                } catch (IOException e) {
                    throw new IllegalStateException("Unable to acquire a reader for CoverageInfo: "+cInfo,e);
                }
            }
        }
        return super.operationDispatched(request, operation);
    }
}
TOP

Related Classes of org.geoserver.wms.eo.EOGetFeatureInfoChecker

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.