Changeset 6821


Ignore:
Timestamp:
11/17/15 17:14:53 (9 years ago)
Author:
Oliver Schonefeld
Message:
  • implement basic SRU 2.0 query handling ... kind of ...
Location:
SRUServer/trunk/src/main/java/eu/clarin/sru/server
Files:
3 added
5 edited

Legend:

Unmodified
Added
Removed
  • SRUServer/trunk/src/main/java/eu/clarin/sru/server/SRUConstants.java

    r6816 r6821  
    206206
    207207
     208    // other constants
     209
     210    /**
     211     * shortqueryType identifier for cql
     212     */
     213    public static final String SRU_QUERY_TYPE_CQL = "cql";
     214
     215
    208216    /* hide constructor */
    209217    private SRUConstants() {
  • SRUServer/trunk/src/main/java/eu/clarin/sru/server/SRURequest.java

    r6816 r6821  
    100100    public SRURecordPacking getRecordPacking();
    101101
     102
    102103    /**
    103104     * Get the <em>query</em> parameter of this request. Only available for
    104105     * <em>searchRetrieve</em> requests.
    105106     *
    106      * @return the parsed query or <code>null</code> if not a
     107     * @return the parsed query as an AST or <code>null</code> if not a
    107108     *         <em>searchRetrieve</em> request
    108109     */
    109     public CQLNode getQuery();
     110    public SRUQuery<?> getQuery();
     111
     112
     113    /**
     114     * Get the <em>queryType</em> parameter of this request. Only available for
     115     * <em>searchRetrieve</em> requests.
     116     *
     117     * @return the queryType of the parsed query or <code>null</code> if not a
     118     *         <em>searchRetrieve</em> request
     119     */
     120    public String getQueryType();
     121
     122
     123    /**
     124     * Check if the request was made with the given queryType. Only available
     125     * for <em>searchRetrieve</em> requests.
     126     *
     127     * @param queryType
     128     *            the queryType to compare with
     129     * @return <code>true</code> if the queryType matches, <code>false</code>
     130     *         otherwise
     131     */
     132    public boolean isQueryType(String queryType);
    110133
    111134
    112135    /**
    113136     * Get the <em>startRecord</em> parameter of this request. Only available
    114      * for <em>searchRetrieve</em> requests. If the client did not provide
    115      * a value for the request, it is set to <code>1</code>.
     137     * for <em>searchRetrieve</em> requests. If the client did not provide a
     138     * value for the request, it is set to <code>1</code>.
    116139     *
    117140     * @return the number of the start record
  • SRUServer/trunk/src/main/java/eu/clarin/sru/server/SRURequestImpl.java

    r6818 r6821  
    2121import java.util.Collections;
    2222import java.util.Enumeration;
     23import java.util.HashMap;
    2324import java.util.List;
     25import java.util.Map;
    2426
    2527import javax.servlet.http.HttpServletRequest;
     
    8385    private SRURecordXmlEscaping recordXmlEscaping;
    8486    private SRURecordPacking recordPacking;
    85     private CQLNode query;
    86     private String queryType;
     87    private SRUQuery<?> query;
    8788    private int startRecord = DEFAULT_START_RECORD;
    8889    private int maximumRecords = -1;
     
    104105        HTTP_ACCEPT,
    105106        RESPONSE_TYPE,
    106         QUERY,
    107         QUERY_TYPE,
     107//        QUERY,
     108//        QUERY_TYPE,
    108109        START_RECORD,
    109110        MAXIMUM_RECORDS,
     
    147148            case RESPONSE_TYPE:
    148149                return PARAM_RESPONSE_TYPE;
    149             case QUERY:
    150                 return PARAM_QUERY;
    151             case QUERY_TYPE:
    152                 return PARAM_QUERY_TYPE;
     150//            case QUERY:
     151//                return PARAM_QUERY;
     152//            case QUERY_TYPE:
     153//                return PARAM_QUERY_TYPE;
    153154            case START_RECORD:
    154155                return PARAM_START_RECORD;
     
    168169            case RECORD_PACKING:
    169170                /*
    170                  * FIXME: make this better
     171                 * 'recordPacking' only exists in SRU 2.0; the old variant is
     172                 * handled by the case for RECORD_XML_ESCAPING
    171173                 */
    172174                if (version == SRUVersion.VERSION_2_0) {
    173175                    return PARAM_RECORD_PACKING;
    174176                } else {
    175                     throw new InternalError("should not happen");
     177                    return null;
    176178                }
    177179            case RECORD_SCHEMA:
     
    231233        new ParameterInfo(Parameter.RESPONSE_TYPE, false,
    232234                SRUVersion.VERSION_2_0, SRUVersion.VERSION_2_0),
    233         new ParameterInfo(Parameter.QUERY, true,
    234                 SRUVersion.VERSION_1_1, SRUVersion.VERSION_2_0),
    235         new ParameterInfo(Parameter.QUERY_TYPE, true,
    236                 SRUVersion.VERSION_2_0, SRUVersion.VERSION_2_0),
     235//        new ParameterInfo(Parameter.QUERY, true,
     236//                SRUVersion.VERSION_1_1, SRUVersion.VERSION_2_0),
     237//        new ParameterInfo(Parameter.QUERY_TYPE, true,
     238//                SRUVersion.VERSION_2_0, SRUVersion.VERSION_2_0),
    237239        new ParameterInfo(Parameter.START_RECORD, false,
    238240                SRUVersion.VERSION_1_1, SRUVersion.VERSION_2_0),
     
    290292                logger.debug("handling request as SRU 2.0, because no '{}' " +
    291293                        "parameter was found in the request", PARAM_VERSION);
    292                 if (getParameter(PARAM_QUERY, false, false) != null) {
    293                     logger.debug("found parameter '{}' therefore " +
     294                if ((getParameter(PARAM_QUERY, false, false) != null) ||
     295                        (getParameter(PARAM_QUERY_TYPE, false, false) != null)) {
     296                    logger.debug("found parameter '{}' or '{}' therefore " +
    294297                            "assuming '{}' operation",
    295                             PARAM_QUERY, SRUOperation.SEARCH_RETRIEVE);
     298                            PARAM_QUERY, PARAM_QUERY_TYPE,
     299                            SRUOperation.SEARCH_RETRIEVE);
    296300                    operation = SRUOperation.SEARCH_RETRIEVE;
    297301                } else if (getParameter(PARAM_SCAN_CLAUSE, false, false) != null) {
     
    429433            for (ParameterInfo parameter : parameter_set) {
    430434                final String name = parameter.getName(version);
     435                if (name == null) {
     436                    /*
     437                     * this parameter is not supported in the SRU version that
     438                     * was used for the request
     439                     */
     440                    continue;
     441                }
    431442                final String value = getParameter(name, true, true);
    432443                if (value != null) {
     
    472483                                            "\" is not supported.");
    473484                        }
    474                         break;
    475                     case QUERY:
    476                         query = parseCQLParameter(name, value);
    477                         break;
    478                     case QUERY_TYPE:
    479                         queryType = parseQueryTypeParameter(name, value);
    480485                        break;
    481486                    case START_RECORD:
     
    517522                        break;
    518523                    case SCAN_CLAUSE:
    519                         scanClause = parseCQLParameter(name, value);
     524                        scanClause = parseScanQueryParameter(name, value);
    520525                        break;
    521526                    case RESPONSE_POSITION:
     
    566571
    567572            /*
     573             * handle query and queryType
     574             */
     575            if (operation == SRUOperation.SEARCH_RETRIEVE) {
     576                /*
     577                 * determine queryType
     578                 */
     579                String queryType = null;
     580                if (version == SRUVersion.VERSION_2_0) {
     581                    parameterNames.remove(PARAM_QUERY_TYPE);
     582                    String value = getParameter(PARAM_QUERY_TYPE, true, true);
     583                    if (value == null) {
     584                        queryType = SRUConstants.SRU_QUERY_TYPE_CQL;
     585                    } else {
     586                        boolean badCharacters = false;
     587                        for (int i = 0; i < value.length(); i++) {
     588                            final char ch = value.charAt(i);
     589                            if (!((ch >= 'a' && ch <= 'z') ||
     590                                    (ch >= 'A' && ch <= 'Z') ||
     591                                    (ch >= '0' && ch <= '9') ||
     592                                    ((i > 0) && ((ch == '-') || ch == '_')))) {
     593                                addDiagnostic(SRUConstants.SRU_UNSUPPORTED_PARAMETER_VALUE,
     594                                        PARAM_QUERY_TYPE, "Value contains illegal characters.");
     595                                badCharacters = true;
     596                                break;
     597                            }
     598                        }
     599                        if (!badCharacters) {
     600                            queryType = value;
     601                        }
     602                    }
     603                } else {
     604                    // SRU 1.1 and SRU 1.2 only support CQL
     605                    queryType = SRUConstants.SRU_QUERY_TYPE_CQL;
     606                }
     607
     608
     609                if (queryType != null) {
     610                    logger.debug("looking for query parser for query type '{}'",
     611                            queryType);
     612                    final SRUQueryParser<?> queryParser =
     613                            config.findQueryParser(queryType);
     614                    if (queryParser != null) {
     615                        /*
     616                         * gather query parameters (as required by QueryParser
     617                         * implementation
     618                         */
     619                        final Map<String, String> queryParameters =
     620                                new HashMap<String, String>();
     621                        List<String> missingParameter = null;
     622                        for (String name : queryParser.getQueryParameterNames()) {
     623                            parameterNames.remove(name);
     624                            final String value = getParameter(name, true, false);
     625                            if (value != null) {
     626                                queryParameters.put(name, value);
     627                            } else {
     628                                if (missingParameter == null) {
     629                                    missingParameter = new ArrayList<String>();
     630                                }
     631                                missingParameter.add(name);
     632                            }
     633                        }
     634
     635                        if (missingParameter == null) {
     636                            logger.debug("parsing query with parser for " +
     637                                    "type '{}' and parameters {}",
     638                                    queryParser.getQueryType(),
     639                                    queryParameters);
     640                            query = queryParser.parseQuery(version,
     641                                    queryParameters, this);
     642                        } else {
     643                            logger.debug("parameters {} missing, cannot parse query",
     644                                    missingParameter);
     645                            for (String name : missingParameter) {
     646                                addDiagnostic(
     647                                        SRUConstants.SRU_MANDATORY_PARAMETER_NOT_SUPPLIED,
     648                                        name, "Mandatory parameter '" + name +
     649                                                "' is missing or empty. " +
     650                                                "Required to perform query " +
     651                                                "of query type '" +
     652                                                queryType + "'.");
     653                            }
     654                        }
     655                    } else {
     656                        logger.debug("no parser for query type '{}' found", queryType);
     657                        addDiagnostic(SRUConstants.SRU_CANNOT_PROCESS_QUERY_REASON_UNKNOWN, null,
     658                                "Cannot find query parser for query type '" + queryType + "'.");
     659                    }
     660                } else {
     661                    logger.debug("cannot determine query type");
     662                    addDiagnostic(SRUConstants.SRU_CANNOT_PROCESS_QUERY_REASON_UNKNOWN, null,
     663                            "Cannot determine query type.");
     664                }
     665            }
     666
     667
     668            /*
    568669             *  check if any parameters where not consumed and
    569670             *  add appropriate warnings
     
    702803
    703804    @Override
    704     public CQLNode getQuery() {
     805    public SRUQuery<?> getQuery() {
    705806        return query;
     807    }
     808
     809
     810    @Override
     811    public boolean isQueryType(String queryType) {
     812        if ((queryType != null) && (query != null)) {
     813            return query.getQueryType().equals(queryType);
     814        }
     815        return false;
     816    }
     817
     818
     819    @Override
     820    public String getQueryType() {
     821        if (query != null) {
     822            return query.getQueryType();
     823        }
     824        return null;
    706825    }
    707826
     
    8921011                if (diagnosticIfEmpty) {
    8931012                    addDiagnostic(SRUConstants.SRU_UNSUPPORTED_PARAMETER_VALUE,
    894                             name, "An empty parameter \"" + PARAM_OPERATION +
     1013                            name, "An empty parameter \"" + name +
    8951014                            "\" is not supported.");
    8961015                }
     
    9351054
    9361055
    937     private String parseQueryTypeParameter(String param, String value) {
    938         if (value != null) {
    939             for (int i = 0; i < value.length(); i++) {
    940                 final char ch = value.charAt(i);
    941                 if (!((ch >= 'a' && ch <= 'z') ||
    942                         (ch >= 'A' && ch <= 'Z') ||
    943                         (ch >= '0' && ch <= '9') ||
    944                         ((i > 0) && ((ch == '-') || ch == '_')))) {
    945                     addDiagnostic(SRUConstants.SRU_UNSUPPORTED_PARAMETER_VALUE,
    946                             param, "Value contains illegal characters.");
    947                 }
    948             }
    949         }
    950         return value;
    951     }
    952 
    953 
    9541056    private int parseNumberedParameter(String param, String value,
    9551057            int minValue) {
     
    9721074
    9731075
    974     private CQLNode parseCQLParameter(String param, String value) {
     1076    private CQLNode parseScanQueryParameter(String param, String value) {
    9751077        CQLNode result = null;
    9761078
  • SRUServer/trunk/src/main/java/eu/clarin/sru/server/SRUServer.java

    r6818 r6821  
    979979
    980980    private void writeEchoedSearchRetrieveRequest(SRUXMLStreamWriter out,
    981             SRUNamespaces ns, SRURequestImpl request, CQLNode cql)
     981            SRUNamespaces ns, SRURequestImpl request, SRUQuery<?> query)
    982982            throws XMLStreamException, SRUException {
    983983        // echoedSearchRetrieveRequest
     
    990990        }
    991991
    992         // echoedSearchRetrieveRequest/query
    993         out.writeStartElement(ns.getResponseNS(), "query");
    994         out.writeCharacters(request.getRawQuery());
    995         out.writeEndElement(); // "query"
    996 
    997         // echoedSearchRetrieveRequest/xQuery
    998         out.setDefaultNamespace(ns.getXcqlNS());
    999         out.writeStartElement(ns.getResponseNS(), "xQuery");
    1000         out.writeDefaultNamespace(ns.getXcqlNS());
    1001         out.writeXCQL(cql, true);
    1002         out.writeEndElement(); // "xQuery" element
     992        /*
     993         * XXX: unclear, if <query> should only be echoed if queryType is CQL!?
     994         */
     995        if (SRUConstants.SRU_QUERY_TYPE_CQL.equals(query.getQueryType())) {
     996            final CQLQueryParser.CQLQuery cql = (CQLQueryParser.CQLQuery) query;
     997            // echoedSearchRetrieveRequest/query
     998            out.writeStartElement(ns.getResponseNS(), "query");
     999            out.writeCharacters(cql.getRawQuery());
     1000            out.writeEndElement(); // "query"
     1001
     1002            // echoedSearchRetrieveRequest/xQuery
     1003            out.setDefaultNamespace(ns.getXcqlNS());
     1004            out.writeStartElement(ns.getResponseNS(), "xQuery");
     1005            out.writeDefaultNamespace(ns.getXcqlNS());
     1006            out.writeXCQL(cql.getParsedQuery(), true);
     1007            out.writeEndElement(); // "xQuery" element
     1008        }
    10031009
    10041010        // echoedSearchRetrieveRequest/startRecord
  • SRUServer/trunk/src/main/java/eu/clarin/sru/server/SRUServerConfig.java

    r6816 r6821  
    637637    private final IndexInfo indexInfo;
    638638    private final List<SchemaInfo> schemaInfo;
     639    private final List<SRUQueryParser<?>> queryParsers;
    639640
    640641
     
    659660            DatabaseInfo databaseinfo,
    660661            IndexInfo indexInfo,
    661             List<SchemaInfo> schemaInfo) {
     662            List<SchemaInfo> schemaInfo,
     663            List<SRUQueryParser<?>> queryParsers) {
    662664        this.minVersion                  = minVersion;
    663665        this.maxVersion                  = maxVersion;
     
    685687            this.schemaInfo = null;
    686688        }
     689        this.queryParsers = Collections.unmodifiableList(queryParsers);
    687690
    688691        // build baseUrl
     
    853856                        return schema;
    854857                    }
     858                }
     859            }
     860        }
     861        return null;
     862    }
     863
     864
     865    public SRUQueryParser<?> findQueryParser(String queryType) {
     866        if (queryType != null) {
     867            for (SRUQueryParser<?> queryParser : queryParsers) {
     868                if (queryParser.getQueryType().equals(queryType)) {
     869                    return queryParser;
    855870                }
    856871            }
     
    10791094                    SRU_RESPONSE_BUFFER_SIZE, false,
    10801095                    DEFAULT_RESPONSE_BUFFER_SIZE, 0, -1);
     1096
     1097            /*
     1098             * FIXME: add interface to register additional query parsers
     1099             */
     1100            List<SRUQueryParser<?>> queryParsers =
     1101                    new ArrayList<SRUQueryParser<?>>();
     1102            queryParsers.add(new CQLQueryParser());
    10811103
    10821104            return new SRUServerConfig(minVersion,
     
    11001122                    databaseInfo,
    11011123                    indexInfo,
    1102                     schemaInfo);
     1124                    schemaInfo,
     1125                    queryParsers);
    11031126        } catch (IOException e) {
    11041127            throw new SRUConfigException("error reading configuration file", e);
Note: See TracChangeset for help on using the changeset viewer.