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

Last change on this file since 2024 was 2024, checked in by oschonef, 12 years ago
  • be more robust, when parsing responses
  • add mechanism to send invalid requests (NB: use to provoke errors when testing endpoints for protocol conformance)
  • Property svn:eol-style set to native
File size: 8.9 KB
Line 
1package eu.clarin.sru.client;
2
3import java.net.URI;
4import java.util.HashMap;
5import java.util.Map;
6
7
8public abstract class SRUAbstractRequest {
9    protected static final String PARAM_OPERATION         = "operation";
10    protected static final String PARAM_VERSION           = "version";
11    protected static final String PARAM_RECORD_PACKING    = "recordPacking";
12    protected static final String PARAM_STYLESHEET        = "stylesheet";
13    protected static final String PARAM_QUERY             = "query";
14    protected static final String PARAM_START_RECORD      = "startRecord";
15    protected static final String PARAM_MAXIMUM_RECORDS   = "maximumRecords";
16    protected static final String PARAM_RECORD_SCHEMA     = "recordSchema";
17    protected static final String PARAM_RECORD_X_PATH     = "recordXPath";
18    protected static final String PARAM_RESULT_SET_TTL    = "resultSetTTL";
19    protected static final String PARAM_SORT_KEYS         = "sortKeys";
20    protected static final String PARAM_SCAN_CLAUSE       = "scanClause";
21    protected static final String PARAM_RESPONSE_POSITION = "responsePosition";
22    protected static final String PARAM_MAXIMUM_TERMS     = "maximumTerms";
23    protected static final String RECORD_PACKING_XML      = "xml";
24    protected static final String RECORD_PACKING_STRING   = "string";
25    private static final String OP_EXPLAIN                = "explain";
26    private static final String OP_SCAN                   = "scan";
27    private static final String OP_SEARCH_RETRIEVE        = "searchRetrieve";
28    private static final String VERSION_1_1               = "1.1";
29    private static final String VERSION_1_2               = "1.2";
30    private static final String PARAM_EXTENSION_PREFIX    = "x-";
31    /** for end-point conformance testing only. never use in production */
32    public static final String X_MALFORMED_VERSION       =
33            "x-malformed-version";
34    /** for end-point conformance testing only. never use in production */
35    public static final String X_MALFORMED_OPERATION     =
36            "x-maformed-operation";
37    /** for end-point conformance testing only. never use in production */
38    public static final String MALFORMED_OMIT            = "omit";
39
40    protected enum SRUOperation {
41        EXPLAIN, SCAN, SEARCH_RETRIEVE
42    } // enum SRUOperation
43
44    protected class URIBuilder {
45        private final StringBuilder sb;
46        private boolean firstParam = true;
47
48        private URIBuilder(String endpointURI) {
49            this.sb = new StringBuilder(endpointURI);
50        }
51
52
53        public URIBuilder append(String name, String value) {
54            if (name == null) {
55                throw new NullPointerException("name == null");
56            }
57            if (name.isEmpty()) {
58                throw new IllegalArgumentException("name is empty");
59            }
60            if (value == null) {
61                throw new NullPointerException("vale == null");
62            }
63            if (value.isEmpty()) {
64                throw new IllegalArgumentException("value is empty");
65            }
66
67            if (firstParam) {
68                sb.append('?');
69                firstParam = false;
70            } else {
71                sb.append('&');
72            }
73            sb.append(name).append('=').append(value);
74            return this;
75        }
76
77
78        public URIBuilder append(String name, int value) {
79            return append(name, Integer.toString(value));
80        }
81
82
83        private URI makeURI() {
84            return URI.create(sb.toString());
85        }
86    } // class
87    protected final String endpointURI;
88    protected SRUVersion version;
89    protected Map<String, String> extraRequestData;
90    private SRUVersion versionPreformed;
91
92
93    protected SRUAbstractRequest(String endpointURI) {
94        if (endpointURI == null) {
95            throw new NullPointerException("endpointURI == null");
96        }
97        this.endpointURI = endpointURI;
98    }
99
100
101    public String getEndpointURI() {
102        return endpointURI;
103    }
104
105
106    public void setVersion(SRUVersion version) {
107        this.version = version;
108    }
109
110
111    public SRUVersion getVersion() {
112        return version;
113    }
114
115
116    public SRUVersion getVersionPerformed() {
117        return versionPreformed;
118    }
119
120
121    public void setExtraRequestData(String name, String value) {
122        if (name == null) {
123            throw new NullPointerException("name == null");
124        }
125        if (name.isEmpty()) {
126            throw new IllegalArgumentException("name is an empty string");
127        }
128        if (!name.startsWith(PARAM_EXTENSION_PREFIX)) {
129            throw new IllegalArgumentException("name must start with '" +
130                    PARAM_EXTENSION_PREFIX + "'");
131        }
132        if (value == null) {
133            throw new NullPointerException("value == null");
134        }
135        if (value.isEmpty()) {
136            throw new IllegalArgumentException("value is an empty string");
137        }
138        if (extraRequestData == null) {
139            extraRequestData = new HashMap<String, String>();
140        }
141        extraRequestData.put(name, value);
142    }
143
144
145    public String getExtraRequestData(String name) {
146        if (name == null) {
147            throw new NullPointerException("name == null");
148        }
149        if (name.isEmpty()) {
150            throw new IllegalArgumentException("name is an empty string");
151        }
152        if (!name.startsWith("x-")) {
153            throw new IllegalArgumentException("name must start with 'x-'");
154        }
155        if (extraRequestData != null) {
156            return extraRequestData.get(name);
157        }
158        return null;
159    }
160
161
162    final URI makeURI(SRUVersion defaultVersion)
163            throws SRUClientException {
164        if (defaultVersion == null) {
165            throw new NullPointerException("defaultVersion == null");
166        }
167        URIBuilder uriBuilder = new URIBuilder(endpointURI);
168
169        /*
170         * append operation parameter
171         *
172         * NB: Setting "x-operation-version" as an extra request parameter makes
173         * the client to send invalid requests. This is intended to use for
174         * testing endpoints for protocol conformance (i.e. provoke an error)
175         * and SHOULD NEVER be used in production!
176         */
177        final String malformedOperation =
178                getExtraRequestData(X_MALFORMED_OPERATION);
179        if (malformedOperation == null) {
180            switch (getOperation()) {
181            case EXPLAIN:
182                uriBuilder.append(PARAM_OPERATION, OP_EXPLAIN);
183                break;
184            case SCAN:
185                uriBuilder.append(PARAM_OPERATION, OP_SCAN);
186                break;
187            case SEARCH_RETRIEVE:
188                uriBuilder.append(PARAM_OPERATION, OP_SEARCH_RETRIEVE);
189                break;
190            default:
191                throw new SRUClientException(
192                        "unsupported operation: " + getOperation());
193            } // switch
194        } else {
195            if (!malformedOperation.equals(MALFORMED_OMIT)) {
196                uriBuilder.append(PARAM_OPERATION, malformedOperation);
197            }
198        }
199
200        /*
201         * append version parameter
202         *
203         * NB: Setting "x-malformed-version" as an extra request parameter makes
204         * the client to send invalid requests. This is intended to use for
205         * testing endpoints for protocol conformance (i.e. provoke an error)
206         * and SHOULD NEVER be used in production!
207         */
208        final String malformedVersion =
209                getExtraRequestData(X_MALFORMED_VERSION);
210        if (malformedVersion == null) {
211            versionPreformed = (version != null) ? version : defaultVersion;
212            switch (versionPreformed) {
213            case VERSION_1_1:
214                uriBuilder.append(PARAM_VERSION, VERSION_1_1);
215                break;
216            case VERSION_1_2:
217                uriBuilder.append(PARAM_VERSION, VERSION_1_2);
218                break;
219            default:
220                throw new SRUClientException("unsupported version: " +
221                        versionPreformed);
222            } // switch
223        } else {
224            if (!malformedVersion.equalsIgnoreCase(MALFORMED_OMIT)) {
225                uriBuilder.append(PARAM_VERSION, malformedVersion);
226            }
227        }
228
229        // request specific parameters
230        addParametersToURI(uriBuilder);
231
232        // extraRequestData
233        if ((extraRequestData != null) && !extraRequestData.isEmpty()) {
234            for (Map.Entry<String, String> entry :
235                extraRequestData.entrySet()) {
236                String key = entry.getKey();
237                if (key.equals(X_MALFORMED_OPERATION) ||
238                        key.equals(X_MALFORMED_VERSION)) {
239                    continue;
240                }
241                uriBuilder.append(key, entry.getValue());
242            }
243        }
244        return uriBuilder.makeURI();
245    }
246
247
248    protected abstract SRUOperation getOperation();
249
250
251    protected abstract void addParametersToURI(URIBuilder uri)
252            throws SRUClientException;
253
254} // class AbstractSRURequest
Note: See TracBrowser for help on using the repository browser.