source: SRUClient/trunk/src/main/java/eu/clarin/sru/client/SRUAbstractRequest.java @ 2168

Last change on this file since 2168 was 2168, checked in by oschonef, 12 years ago
  • update copyright
  • add missing copyright statements
  • Property svn:eol-style set to native
File size: 11.5 KB
Line 
1/**
2 * This software is copyright (c) 2011-2012 by
3 *  - Institut fuer Deutsche Sprache (http://www.ids-mannheim.de)
4 * This is free software. You can redistribute it
5 * and/or modify it under the terms described in
6 * the GNU General Public License v3 of which you
7 * should have received a copy. Otherwise you can download
8 * it from
9 *
10 *   http://www.gnu.org/licenses/gpl-3.0.txt
11 *
12 * @copyright Institut fuer Deutsche Sprache (http://www.ids-mannheim.de)
13 *
14 * @license http://www.gnu.org/licenses/gpl-3.0.txt
15 *  GNU General Public License v3
16 */
17package eu.clarin.sru.client;
18
19import java.net.URI;
20import java.util.HashMap;
21import java.util.Map;
22
23
24
25/**
26 * Abstract base class for SRU requests.
27 *
28 * @see SRUExplainResponse
29 * @see SRUScanResponse
30 * @see SRUSearchRetrieveResponse
31 */
32abstract class SRUAbstractRequest {
33    static final String PARAM_OPERATION                = "operation";
34    static final String PARAM_VERSION                  = "version";
35    static final String PARAM_RECORD_PACKING           = "recordPacking";
36    static final String PARAM_STYLESHEET               = "stylesheet";
37    static final String PARAM_QUERY                    = "query";
38    static final String PARAM_START_RECORD             = "startRecord";
39    static final String PARAM_MAXIMUM_RECORDS          = "maximumRecords";
40    static final String PARAM_RECORD_SCHEMA            = "recordSchema";
41    static final String PARAM_RECORD_X_PATH            = "recordXPath";
42    static final String PARAM_RESULT_SET_TTL           = "resultSetTTL";
43    static final String PARAM_SORT_KEYS                = "sortKeys";
44    static final String PARAM_SCAN_CLAUSE              = "scanClause";
45    static final String PARAM_RESPONSE_POSITION        = "responsePosition";
46    static final String PARAM_MAXIMUM_TERMS            = "maximumTerms";
47    static final String RECORD_PACKING_XML             = "xml";
48    static final String RECORD_PACKING_STRING          = "string";
49    private static final String OP_EXPLAIN             = "explain";
50    private static final String OP_SCAN                = "scan";
51    private static final String OP_SEARCH_RETRIEVE     = "searchRetrieve";
52    private static final String VERSION_1_1            = "1.1";
53    private static final String VERSION_1_2            = "1.2";
54    private static final String PARAM_EXTENSION_PREFIX = "x-";
55    /** for end-point conformance testing only. never use in production. */
56    public static final String X_MALFORMED_OPERATION   =
57            "x-malformed-operation";
58    /** for end-point conformance testing only. never use in production. */
59    public static final String X_MALFORMED_VERSION     =
60            "x-malformed-version";
61    /** for end-point conformance testing only. never use in production. */
62    public static final String MALFORMED_OMIT          = "omit";
63    private static final String MALFORMED_KEY_PREFIX   = "x-malformed";
64
65
66    enum SRUOperation {
67        EXPLAIN, SCAN, SEARCH_RETRIEVE
68    } // enum SRUOperation
69
70
71    class URIBuilder {
72        private final StringBuilder sb;
73        private boolean firstParam = true;
74
75        private URIBuilder(String endpointURI) {
76            this.sb = new StringBuilder(endpointURI);
77        }
78
79
80        public URIBuilder append(String name, String value) {
81            if (name == null) {
82                throw new NullPointerException("name == null");
83            }
84            if (name.isEmpty()) {
85                throw new IllegalArgumentException("name is empty");
86            }
87            if (value == null) {
88                throw new NullPointerException("value == null");
89            }
90            if (value.isEmpty()) {
91                throw new IllegalArgumentException("value is empty");
92            }
93
94            if (firstParam) {
95                sb.append('?');
96                firstParam = false;
97            } else {
98                sb.append('&');
99            }
100            sb.append(name).append('=').append(value);
101            return this;
102        }
103
104
105        public URIBuilder append(String name, int value) {
106            return append(name, Integer.toString(value));
107        }
108
109
110        private URI makeURI() {
111            return URI.create(sb.toString());
112        }
113    } // class
114    /** The URL of the endpoint. */
115    protected final String endpointURI;
116    /** The version to be sued  for this request. */
117    protected SRUVersion version;
118    /** A map of extra request data parameters. */
119    protected Map<String, String> extraRequestData;
120    private SRUVersion versionPreformed;
121
122
123    /**
124     * Constructor.
125     *
126     * @param endpointURI
127     *            the URI of the endpoint
128     * @throws NullPointerException
129     *             if any required argument is null
130     */
131    protected SRUAbstractRequest(String endpointURI) {
132        if (endpointURI == null) {
133            throw new NullPointerException("endpointURI == null");
134        }
135        this.endpointURI = endpointURI;
136    }
137
138
139    /**
140     * Get the endpoint URI.
141     *
142     * @return the endpoint URI
143     */
144    public String getEndpointURI() {
145        return endpointURI;
146    }
147
148
149    /**
150     * Set the version for this request.
151     *
152     * @param version a version of <code>null</code> for client default
153     */
154    public void setVersion(SRUVersion version) {
155        this.version = version;
156    }
157
158
159    /**
160     * Get the version for this request.
161     *
162     * @return version for this request or <code>null</code> of client default
163     *         is used
164     */
165    public SRUVersion getVersion() {
166        return version;
167    }
168
169
170    /**
171     * Set an extra request parameter for this request.
172     *
173     * @param name
174     *            the name for the extra request data parameter
175     * @param value
176     *            the value for the extra request data parameter
177     * @throws NullPointerException
178     *             if any required argument is <code>null</code>
179     * @throws IllegalArgumentException
180     *             if any argument is invalid
181     * @see <a href="http://www.loc.gov/standards/sru/specs/extra-data.html">SRU
182     *      Extra Data / Extensions</a>
183     */
184    public void setExtraRequestData(String name, String value) {
185        if (name == null) {
186            throw new NullPointerException("name == null");
187        }
188        if (name.isEmpty()) {
189            throw new IllegalArgumentException("name is an empty string");
190        }
191        if (!name.startsWith(PARAM_EXTENSION_PREFIX)) {
192            throw new IllegalArgumentException("name must start with '" +
193                    PARAM_EXTENSION_PREFIX + "'");
194        }
195        if (value == null) {
196            throw new NullPointerException("value == null");
197        }
198        if (value.isEmpty()) {
199            throw new IllegalArgumentException("value is an empty string");
200        }
201        if (extraRequestData == null) {
202            extraRequestData = new HashMap<String, String>();
203        }
204        extraRequestData.put(name, value);
205    }
206
207
208    /**
209     * Set the value of extra request parameter for this request.
210     *
211     * @param name
212     *            the name for the extra request data parameter
213     * @return the value for the extra request data parameter or
214     *         <code>null</code> if parameter was not set
215     * @throws NullPointerException
216     *             if any required argument is <code>null</code>
217     * @throws IllegalArgumentException
218     *             if any argument is invalid
219     * @see <a href="http://www.loc.gov/standards/sru/specs/extra-data.html">SRU
220     *      Extra Data / Extensions</a>
221     */
222    public String getExtraRequestData(String name) {
223        if (name == null) {
224            throw new NullPointerException("name == null");
225        }
226        if (name.isEmpty()) {
227            throw new IllegalArgumentException("name is an empty string");
228        }
229        if (!name.startsWith(PARAM_EXTENSION_PREFIX)) {
230            throw new IllegalArgumentException("name must start with '" +
231                    PARAM_EXTENSION_PREFIX + "'");
232        }
233        if (extraRequestData != null) {
234            return extraRequestData.get(name);
235        }
236        return null;
237    }
238
239
240    final SRUVersion getVersionPerformed() {
241        return versionPreformed;
242    }
243
244
245    final URI makeURI(SRUVersion defaultVersion)
246            throws SRUClientException {
247        if (defaultVersion == null) {
248            throw new NullPointerException("defaultVersion == null");
249        }
250        URIBuilder uriBuilder = new URIBuilder(endpointURI);
251
252        /*
253         * append operation parameter
254         *
255         * NB: Setting "x-malformed-operation" as an extra request parameter
256         * makes the client to send invalid requests. This is intended to use
257         * for testing endpoints for protocol conformance (i.e. provoke an
258         * error) and SHOULD NEVER be used in production!
259         */
260        final String malformedOperation =
261                getExtraRequestData(X_MALFORMED_OPERATION);
262        if (malformedOperation == null) {
263            switch (getOperation()) {
264            case EXPLAIN:
265                uriBuilder.append(PARAM_OPERATION, OP_EXPLAIN);
266                break;
267            case SCAN:
268                uriBuilder.append(PARAM_OPERATION, OP_SCAN);
269                break;
270            case SEARCH_RETRIEVE:
271                uriBuilder.append(PARAM_OPERATION, OP_SEARCH_RETRIEVE);
272                break;
273            default:
274                throw new SRUClientException(
275                        "unsupported operation: " + getOperation());
276            } // switch
277        } else {
278            if (!malformedOperation.equals(MALFORMED_OMIT)) {
279                uriBuilder.append(PARAM_OPERATION, malformedOperation);
280            }
281        }
282
283        /*
284         * append version parameter
285         *
286         * NB: Setting "x-malformed-version" as an extra request parameter makes
287         * the client to send invalid requests. This is intended to use for
288         * testing endpoints for protocol conformance (i.e. provoke an error)
289         * and SHOULD NEVER be used in production!
290         */
291        final String malformedVersion =
292                getExtraRequestData(X_MALFORMED_VERSION);
293        if (malformedVersion == null) {
294            versionPreformed = (version != null) ? version : defaultVersion;
295            switch (versionPreformed) {
296            case VERSION_1_1:
297                uriBuilder.append(PARAM_VERSION, VERSION_1_1);
298                break;
299            case VERSION_1_2:
300                uriBuilder.append(PARAM_VERSION, VERSION_1_2);
301                break;
302            default:
303                throw new SRUClientException("unsupported version: " +
304                        versionPreformed);
305            } // switch
306        } else {
307            if (!malformedVersion.equalsIgnoreCase(MALFORMED_OMIT)) {
308                uriBuilder.append(PARAM_VERSION, malformedVersion);
309            }
310        }
311
312        // request specific parameters
313        addParametersToURI(uriBuilder);
314
315        // extraRequestData
316        if ((extraRequestData != null) && !extraRequestData.isEmpty()) {
317            for (Map.Entry<String, String> entry :
318                extraRequestData.entrySet()) {
319                String key = entry.getKey();
320                if (key.startsWith(MALFORMED_KEY_PREFIX)) {
321                    continue;
322                }
323                uriBuilder.append(key, entry.getValue());
324            }
325        }
326        return uriBuilder.makeURI();
327    }
328
329
330    /**
331     * <em>Note: this method is not a part of public API.</em>
332     * @return a constant for this
333     */
334    abstract SRUOperation getOperation();
335
336
337    abstract void addParametersToURI(URIBuilder uri) throws SRUClientException;
338
339} // class AbstractSRURequest
Note: See TracBrowser for help on using the repository browser.