Package org.geoserver.csw.kvp

Source Code of org.geoserver.csw.kvp.GetRecordsKvpRequestReader

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

package org.geoserver.csw.kvp;

import java.io.StringReader;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.xml.namespace.QName;

import net.opengis.cat.csw20.Csw20Factory;
import net.opengis.cat.csw20.DistributedSearchType;
import net.opengis.cat.csw20.ElementSetNameType;
import net.opengis.cat.csw20.ElementSetType;
import net.opengis.cat.csw20.GetRecordsType;
import net.opengis.cat.csw20.QueryType;

import org.geoserver.csw.records.RecordDescriptor;
import org.geoserver.platform.GeoServerExtensions;
import org.geoserver.platform.ServiceException;
import org.geotools.csw.CSW;
import org.geotools.filter.text.cql2.CQL;
import org.geotools.filter.v1_1.OGC;
import org.geotools.filter.v1_1.OGCConfiguration;
import org.geotools.xml.Parser;
import org.opengis.filter.Filter;
import org.opengis.filter.sort.SortBy;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.xml.sax.helpers.NamespaceSupport;

/**
* GetRecords KVP request reader
*
* @author Andrea Aime, GeoSolutions
*/
public class GetRecordsKvpRequestReader extends CSWKvpRequestReader implements ApplicationContextAware {
   
    private static final String FILTER = "FILTER";
    private static final String CQL_TEXT = "CQL_TEXT";
    private static final String CONSTRAINTLANGUAGE = "constraintlanguage";
    private static final String CONSTRAINT = "constraint";
   
    /**
     * Resolves the type names into proper QName objects
     */
    TypeNamesResolver resolver = new TypeNamesResolver();
   
    HashMap<String, RecordDescriptor> descriptors;

    public GetRecordsKvpRequestReader() {
        super(GetRecordsType.class);
        setRepeatedParameters(true);
    }

    @Override
    public Object read(Object request, Map kvp, Map rawKvp) throws Exception {
        // fix distributed search before we get into EMF reflection mode
        String ds = (String) kvp.remove("distributedSearch");
        Integer hopCount = (Integer) kvp.remove("hopCount");
        if (rawKvp.containsKey("distributedSearch")) {

            if ("true".equalsIgnoreCase(ds)) {
                DistributedSearchType dst = Csw20Factory.eINSTANCE.createDistributedSearchType();
                if (hopCount != null) {
                    dst.setHopCount(hopCount);
                } else {
                    dst.setHopCount(2);
                }
                kvp.put("distributedSearch", dst);
            }
        }

        // parse the query
        QueryType query = readQuery(kvp, request);
        kvp.put("query", query);

        return super.read(request, kvp, rawKvp);
    }

    private QueryType readQuery(Map kvp, Object request) throws Exception {
        Csw20Factory factory = Csw20Factory.eINSTANCE;
        QueryType query = factory.createQueryType();

        // parse the type names
        String typeNamesString = (String) kvp.get("typeNames");
        if(typeNamesString == null) {
            throw new ServiceException("Mandatory parameter typeNames is missing", ServiceException.MISSING_PARAMETER_VALUE, "typeNames");
        }
        NamespaceSupport namespaces = (NamespaceSupport) kvp.get("namespace");
        if (namespaces == null) {
            // by spec, "NAMSPACE, If not included, all qualified names are in default namespace"
            String outputSchema = (String) kvp.get("outputSchema");
            if (outputSchema == null || descriptors.get(outputSchema) == null) {
                outputSchema = CSW.NAMESPACE;
            }
            namespaces = descriptors.get( outputSchema).getNamespaceSupport();
        }
        List<QName> typeNames = resolver.parseQNames(typeNamesString, namespaces);
        query.setTypeNames(typeNames);
       
        // handle the element set
        ElementSetType elementSet = (ElementSetType) kvp.remove("ELEMENTSETNAME");
        if (elementSet != null) {
            ElementSetNameType esn = Csw20Factory.eINSTANCE.createElementSetNameType();
            esn.setValue(elementSet);
            esn.setTypeNames(typeNames);
            query.setElementSetName(esn);
        }
       
        // and the element names
        String elementNamesString = (String) kvp.remove("ELEMENTNAME");
        if(elementNamesString != null) {
            List<QName> elementNames = resolver.parseQNames(elementNamesString, namespaces);
            query.getElementName().addAll(elementNames);
        }

        // the filter
        if (kvp.get(CONSTRAINT) != null) {
            query.setConstraint(factory.createQueryConstraintType());
            Object language = kvp.get(CONSTRAINTLANGUAGE);
            String constraint = (String) kvp.get(CONSTRAINT);
            if (CQL_TEXT.equals(language) || language == null) {
                Filter filter = null;
                try {
                    filter = CQL.toFilter(constraint);
                } catch (Exception e) {
                    ServiceException se = new ServiceException("Invalid CQL expression: " + constraint,
                            ServiceException.INVALID_PARAMETER_VALUE, CONSTRAINT);
                    se.initCause(e);
                    throw se;
                }
                query.getConstraint().setCqlText(constraint);
                query.getConstraint().setFilter(filter);
            } else if (FILTER.equals(language)) {
                try {
                    Parser parser = new Parser(new OGCConfiguration());
                    parser.setFailOnValidationError(true);
                    parser.setValidating(true);
                    parser.getNamespaces().declarePrefix("ogc", OGC.NAMESPACE);
                    Filter filter = (Filter) parser.parse(new StringReader(constraint));
                    query.getConstraint().setFilter(filter);
                    query.getConstraint().setVersion("1.1.0");
                } catch(Exception e) {
                    ServiceException se = new ServiceException("Invalid FILTER 1.1 expression: " + constraint,
                            ServiceException.INVALID_PARAMETER_VALUE, CONSTRAINT);
                    se.initCause(e);
                    throw se;
                }
            } else {
                throw new ServiceException("Invalid constraint language: " + language
                        + ", valid values are " + CQL_TEXT + " and " + FILTER,
                        ServiceException.INVALID_PARAMETER_VALUE, CONSTRAINTLANGUAGE);
            }
        }
       
        // check if we have to sort the request
        if(kvp.get("SORTBY") != null) {
            query.setSortBy((SortBy[]) kvp.get("SORTBY"));
        }

        return query;
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        descriptors = new HashMap<String, RecordDescriptor>();
                       
        // gather all the prefix to namespace associations in the set of records we are going to
        // support, we will use them to qualify the property names in the filters
        List<RecordDescriptor> allDescriptors = GeoServerExtensions.extensions(RecordDescriptor.class, applicationContext);
        for (RecordDescriptor rd : allDescriptors) {
            descriptors.put(rd.getOutputSchema(), rd);
        }
    }

 
}
TOP

Related Classes of org.geoserver.csw.kvp.GetRecordsKvpRequestReader

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.