1 /**
2 * Copyright 2010, CSIRO Australia.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 package au.csiro.pidclient;
18
19 import java.io.BufferedReader;
20 import java.io.IOException;
21 import java.io.InputStream;
22 import java.io.InputStreamReader;
23 import java.io.StringReader;
24 import java.text.MessageFormat;
25 import java.util.ArrayList;
26 import java.util.List;
27 import java.util.Properties;
28
29 import javax.xml.parsers.DocumentBuilder;
30 import javax.xml.parsers.DocumentBuilderFactory;
31 import javax.xml.parsers.ParserConfigurationException;
32 import javax.xml.xpath.XPath;
33 import javax.xml.xpath.XPathConstants;
34 import javax.xml.xpath.XPathExpression;
35 import javax.xml.xpath.XPathExpressionException;
36 import javax.xml.xpath.XPathFactory;
37
38 import org.apache.commons.httpclient.HttpClient;
39 import org.apache.commons.httpclient.HttpException;
40 import org.apache.commons.httpclient.HttpStatus;
41 import org.apache.commons.httpclient.HttpsURL;
42 import org.apache.commons.httpclient.NameValuePair;
43 import org.apache.commons.httpclient.methods.PostMethod;
44 import org.apache.commons.httpclient.methods.RequestEntity;
45 import org.apache.commons.httpclient.methods.StringRequestEntity;
46 import org.apache.commons.lang.StringUtils;
47 import org.apache.log4j.Logger;
48 import org.w3c.dom.Document;
49 import org.w3c.dom.Node;
50 import org.w3c.dom.NodeList;
51 import org.xml.sax.InputSource;
52 import org.xml.sax.SAXException;
53
54 import au.csiro.pidclient.business.AndsPidIdentity;
55 import au.csiro.pidclient.business.AndsPidResponseProperty;
56
57 /**
58 * This is the main interface to the ANDS PID Client library. It allows the caller to
59 * interact with the
60 * <a href="http://www.ands.org.au/services/pid-m2m-identifiers.html">Persistent IDentifier Service</a>
61 * provided by the
62 * <a href="http://www.ands.org.au/">Australian National Data Service</a>. You will need to
63 * register with ANDS to be able to use the service.
64 * <p><b>Usage:</b>
65 * </p><p>
66 * Create a new instance of the class using either the empty constructor and
67 * then calling the four setters, or using the constructors. This should be
68 * compatible with use as a singleton bean in Spring or other DI (dependency
69 * injection) frameworks. Example:
70 * </p>
71 * <UL>
72 * <li>pidServiceHost - test.ands.org.au</li>
73 * <li>pidServicePort - 8443</li>
74 * <li>pidServicePath - /pids</li>
75 * <li>requestorIdentity.appId - 5d9a4da3580c528ba98d8e6f088dab93f680dd6b</li>
76 * <li>requestorIdentity.identifier - scott</li>
77 * <li>requestorIdentity.authDomain - mycomputer.edu.au</li>
78 * </UL>
79 * <p>
80 * You can then mint new handles using the {@link #mintHandle(HandleType, String) mintHandle}
81 * method, and manage the properties associated with the handle
82 * {@link #addValue(String, HandleType, String) addValue},
83 * {@link #modifyValueByIndex(String, int, String) modifyValueByIndex} and
84 * {@link #deleteValueByIndex(String, int) deleteValueByIndex} methods. Note that these
85 * methods return the raw XML response as a string. You can also use the FormattedResponse
86 * versions to get back an interpreted result as a standard Java bean.
87 *
88 * </p>
89 * Copyright 2010, CSIRO Australia All rights reserved.
90 *
91 * @author Robert Bridle on 05/02/2010
92 * @version $Revision: 7131 $ $Date: 2010-06-09 14:25:15 +1000 (Wed, 09 Jun 2010) $
93 */
94 public class AndsPidClient
95 {
96 /**
97 * Constant that defines the size of an array for storing triplet data.
98 */
99 private static final int TRIPLE = 3;
100
101 /**
102 * Constant that defines the logger to be used.
103 */
104 private static final Logger LOG = Logger.getLogger(AndsPidClient.class.getName());
105
106 /**
107 * Constant that defines the name of properties file to be used.
108 */
109 private static final String PROPERTIES_FILENAME = "/ands-pid-client.properties";
110
111 /**
112 * The name of the application, to be used by the HTTP client.
113 */
114 private static String applicationName;
115
116 /**
117 * The name of the method (RESTful web service) to call when minting a new handle.
118 */
119 private static String mintMethodName;
120
121 /**
122 * The name of the method (RESTful web service) to call when associating a new value with an existing handle.
123 */
124 private static String addValueMethodName;
125
126 /**
127 * The name of the method (RESTful web service) to call when associating a new value into the index of an existing
128 * handle.
129 */
130 private static String addValueByIndexMethodName;
131
132 /**
133 * The name of the method (RESTful web service) to call when modifying an existing handle.
134 */
135 private static String modifyValueByIndexMethodName;
136
137 /**
138 * The name of the method (RESTful web service) to call when deleting an existing handle value.
139 */
140 private static String deleteValueByIndexMethodName;
141
142 /**
143 * The name of the method (RESTful web service) to call when listing the handles owned by the requestor.
144 */
145 private static String listHandlesMethodName;
146
147 /**
148 * The name of the method (RESTful web service) to call when retrieving the values associated with a handle.
149 */
150 private static String getHandleMethodName;
151
152 /**
153 * Represents the identity information of the caller.
154 */
155 private AndsPidIdentity requestorIdentity;
156
157 /**
158 * The ANDS Persistent Identifier host name.
159 */
160 private String pidServiceHost;
161
162 /**
163 * The ANDS Persistent Identifier port number.
164 */
165 private int pidServicePort;
166
167 /**
168 * The ANDS Persistent Identifier path name (web application context name).
169 */
170 private String pidServicePath;
171
172 /**
173 * The possible types of properties that can be associated with a handle.
174 * Each handle (PID) can carry multiple (max of around 100) properties.
175 */
176 public enum HandleType
177 {
178 /**
179 * A property with no associated value.
180 */
181 EMPTY(""),
182 /**
183 * A property with a URL value.
184 */
185 URL("URL"),
186 /**
187 * A property with a descriptive text value.
188 */
189 DESC("DESC");
190
191 /**
192 * The value of the enumeration understood by the ANDS PID service.
193 */
194 private final String value;
195
196 HandleType(String value)
197 {
198 this.value = value;
199 }
200
201 /**
202 * @return the value of the enumeration.
203 */
204 public String value()
205 {
206 return this.value;
207 }
208
209 /**
210 * @return whether this enumeration is empty.
211 */
212 public boolean isEmpty()
213 {
214 return EMPTY.value().equals(this.value);
215 }
216 }
217
218 /**
219 * Loads the specified properties file.
220 */
221 private static void loadProperties()
222 {
223 InputStream is = AndsPidResponse.class.getResourceAsStream(PROPERTIES_FILENAME);
224 Properties props = new Properties();
225 try
226 {
227 props.load(is);
228 applicationName = props.getProperty("application.name");
229 mintMethodName = props.getProperty("method.mint");
230 addValueMethodName = props.getProperty("method.addValue");
231 addValueByIndexMethodName = props.getProperty("method.addValueByIndex");
232 modifyValueByIndexMethodName = props.getProperty("method.modifyValueByIndex");
233 deleteValueByIndexMethodName = props.getProperty("method.deleteValueByIndex");
234 listHandlesMethodName = props.getProperty("method.listHandles");
235 getHandleMethodName = props.getProperty("method.getHandle");
236 }
237 catch (IOException e)
238 {
239 LOG.error("Could not load properties file: " + PROPERTIES_FILENAME, e);
240 }
241 }
242
243 /**
244 * Default constructor. You will still need to supply the configuration data
245 * via the public setters.
246 */
247 public AndsPidClient()
248 {
249 this(null, 0, null, null, null, null);
250 }
251
252 /**
253 * @param pidServiceHost
254 * the ANDS Persistent Identifier host name.
255 * @param pidServicePort
256 * the ANDS Persistent Identifier port number.
257 * @param pidServicePath
258 * the ANDS Persistent Identifier path name (web application context name).
259 * @param appId
260 * the unique Id provided to the caller upon IP registration with the ANDS Persistent Identifier service.
261 * @param identifier
262 * the identifier or name of the repository calling the service.
263 * @param authDomain
264 * the domain of the organisation calling the service.
265 */
266 public AndsPidClient(String pidServiceHost, int pidServicePort, String pidServicePath, String appId,
267 String identifier, String authDomain)
268 {
269 this(pidServiceHost, pidServicePort, pidServicePath, new AndsPidIdentity(appId, identifier, authDomain));
270 }
271
272 /**
273 * @param pidServiceHost
274 * the ANDS Persistent Identifier host name.
275 * @param pidServicePort
276 * the ANDS Persistent Identifier port number.
277 * @param pidServicePath
278 * the ANDS Persistent Identifier path name (web application context name).
279 * @param requestorIdentity
280 * represents the identity information of the caller {@link AndsPidIdentity}.
281 */
282 public AndsPidClient(String pidServiceHost, int pidServicePort, String pidServicePath,
283 AndsPidIdentity requestorIdentity)
284 {
285 this.setPidServiceHost(pidServiceHost);
286 this.setPidServicePort(pidServicePort);
287 this.setPidServicePath(pidServicePath);
288 this.setRequestorIdentity(requestorIdentity);
289 loadProperties();
290 }
291
292 /**
293 * Responsible for the creation of a handle.
294 * <p>
295 * If the type and value arguments are both empty, a handle with no values is created. The handle is assigned to an
296 * owner, specified by the {@link AndsPidIdentity#getAppId()} value. If the owner is not known to the handle system,
297 * an owner is created from the {@link AndsPidIdentity#getIdentifier()} and {@link AndsPidIdentity#getIdentifier()}
298 * values.
299 *
300 * @param type
301 * the type {@link HandleType} of value which will be associated with the newly minted handle.
302 * @param value
303 * the value which will be associated with the newly minted handle.
304 * @return a formatted XML response that contains a handle, the handle is associated with the value argument.
305 * @throws IllegalStateException
306 * thrown if the parameters need to call the ANDS PID service have not been provided.
307 * @throws IllegalArgumentException
308 * thrown when method is called with invalid arguments.
309 * @throws IOException
310 * thrown when attempting to read response.
311 * @throws HttpException
312 * thrown when attempting to execute method call.
313 */
314 public String mintHandle(HandleType type, String value) throws IllegalStateException, IllegalArgumentException,
315 HttpException, IOException
316 {
317 this.validateState();
318
319 this.validateMintHandleArguments(type, value);
320
321 NameValuePair[] queryParams = {
322 new NameValuePair("type", type.value()),
323 new NameValuePair("value", value)
324 };
325
326 return executeMethod(queryParams, mintMethodName);
327 }
328
329 /**
330 * Responsible for the creation of a handle.
331 * <p>
332 * If the type and value arguments are both empty, a handle with no values is created. The handle is assigned to an
333 * owner, specified by the {@link AndsPidIdentity#getAppId()} value. If the owner is not known to the handle system,
334 * an owner is created from the {@link AndsPidIdentity#getIdentifier()} and {@link AndsPidIdentity#getIdentifier()}
335 * values.
336 * <p>
337 * The XML response is parsed and returned by the object {@link AndsPidResponse}.
338 *
339 * @param type
340 * the type {@link HandleType} of value which will be associated with the newly minted handle.
341 * @param value
342 * the value which will be associated with the newly minted handle.
343 * @return the ANDS Persistent Identifier service response represented by the object {@link AndsPidResponse}.
344 * @throws IllegalStateException
345 * thrown if the parameters need to call the ANDS PID service have not been provided.
346 * @throws IllegalArgumentException
347 * thrown when method is called with invalid arguments.
348 * @throws HttpException
349 * thrown when attempting to execute method call.
350 * @throws IOException
351 * thrown when attempting to read response.
352 * @throws XPathExpressionException
353 * thrown when attempting to execute XPath on XML response.
354 * @throws ParserConfigurationException
355 * thrown when attempting to convert response to an XML document.
356 * @throws SAXException
357 * thrown when attempting to convert response to an XML document.
358 */
359 public AndsPidResponse mintHandleFormattedResponse(HandleType type, String value) throws IllegalStateException,
360 IllegalArgumentException, HttpException, IOException, XPathExpressionException,
361 ParserConfigurationException, SAXException
362 {
363 return populateAndsPidResponse(mintHandle(type, value));
364 }
365
366 /**
367 * Responsible for the creation of a handle with a value at a specific index.
368 * <p>
369 * If the type and value arguments are both empty, a handle with no values is created. The handle is assigned
370 * to an owner, specified by the {@link AndsPidIdentity#getAppId()} value. If the owner is not known to the handle
371 * system, an owner is created from the {@link AndsPidIdentity#getIdentifier()} and
372 * {@link AndsPidIdentity#getIdentifier()} values.
373 *
374 * @param type
375 * the type {@link HandleType} of value which will be associated with the newly minted handle.
376 * @param index
377 * the index of the value which will be associated with the newly minted handle.
378 * @param value
379 * the value which will be associated with the newly minted handle.
380 * @return a formatted XML response that contains a handle, the handle is associated with the value argument.
381 * @throws IllegalStateException
382 * thrown if the parameters need to call the ANDS PID service have not been provided.
383 * @throws IllegalArgumentException
384 * thrown when method is called with invalid arguments.
385 * @throws IOException
386 * thrown when attempting to read response.
387 * @throws HttpException
388 * thrown when attempting to execute method call.
389 */
390 public String mintHandle(HandleType type, int index, String value) throws IllegalStateException,
391 IllegalArgumentException, HttpException, IOException
392 {
393 this.validateState();
394
395 this.validateMintHandleArguments(type, value);
396
397 NameValuePair[] queryParams = {
398 new NameValuePair("type", type.value()),
399 new NameValuePair("index", String.valueOf(index)),
400 new NameValuePair("value", value)
401 };
402 return executeMethod(queryParams, mintMethodName);
403 }
404
405 /**
406 * Responsible for the creation of a handle with a value at a specific index.
407 * <p>
408 * If the type and value arguments are both empty, a handle with no values is created. The handle is assigned
409 * to an owner, specified by the {@link AndsPidIdentity#getAppId()} value. If the owner is not known to the handle
410 * system, an owner is created from the {@link AndsPidIdentity#getIdentifier()} and
411 * {@link AndsPidIdentity#getIdentifier()} values.
412 * <p>
413 * The XML response is parsed and returned by the object {@link AndsPidResponse}.
414 *
415 * @param type
416 * the type {@link HandleType} of value which will be associated with the newly minted handle.
417 * @param index
418 * the index of the value which will be associated with the newly minted handle.
419 * @param value
420 * the value which will be associated with the newly minted handle.
421 * @return the ANDS Persistent Identifier service response represented by the object {@link AndsPidResponse}.
422 * @throws IllegalStateException
423 * thrown if the parameters need to call the ANDS PID service have not been provided.
424 * @throws IllegalArgumentException
425 * thrown when method is called with invalid arguments.
426 * @throws HttpException
427 * thrown when attempting to execute method call.
428 * @throws IOException
429 * thrown when attempting to read response.
430 * @throws XPathExpressionException
431 * thrown when attempting to execute XPath on XML response.
432 * @throws ParserConfigurationException
433 * thrown when attempting to convert response to an XML document.
434 * @throws SAXException
435 * thrown when attempting to convert response to an XML document.
436 */
437 public AndsPidResponse mintHandleFormattedResponse(HandleType type, int index, String value)
438 throws IllegalStateException, IllegalArgumentException, HttpException, IOException,
439 XPathExpressionException, ParserConfigurationException, SAXException
440 {
441 return populateAndsPidResponse(mintHandle(type, index, value));
442 }
443
444 /**
445 * Adds a value to an existing handle.
446 * <p>
447 * Only the owner of the handle is able to add a value to the handle and only values of type {@link HandleType#URL}
448 * or {@link HandleType#DESC} can be added.
449 *
450 * @param handle
451 * the handle to which a new value is to be associated.
452 * @param type
453 * the type of the value to be added to the handle, must be either {@link HandleType#URL} or
454 * {@link HandleType#DESC}.
455 * @param value
456 * the value to be added to the handle.
457 * @return a formatted XML response that contains the details of the updated handle.
458 * @throws IllegalStateException
459 * thrown if the parameters need to call the ANDS PID service have not been provided.
460 * @throws IllegalArgumentException
461 * thrown when method is called with invalid arguments.
462 * @throws IOException
463 * thrown when attempting to read response.
464 * @throws HttpException
465 * thrown when attempting to execute method call.
466 */
467 @SuppressWarnings(value = "all")
468 public String addValue(String handle, HandleType type, String value) throws IllegalStateException,
469 IllegalArgumentException, HttpException, IOException
470 {
471 this.validateState();
472
473 if (StringUtils.isEmpty(handle) || StringUtils.isEmpty(value) || type == null || type.equals(HandleType.EMPTY))
474 {
475 throw new IllegalArgumentException(MessageFormat.format(
476 "The method addValue() can not be called with null or empty arguments:\n type= {0}\n value= {1}\n",
477 new Object[] { (type == null) ? null : type.value(), value }));
478 }
479
480 NameValuePair[] queryParams = {
481 new NameValuePair("type", type.value()),
482 new NameValuePair("handle", handle),
483 new NameValuePair("value", value)
484 };
485 return executeMethod(queryParams, addValueMethodName);
486 }
487
488 /**
489 * Adds a value to an existing handle.
490 * <p>
491 * Only the owner of the handle is able to add a value to the handle and only values of type {@link HandleType#URL}
492 * or {@link HandleType#DESC} can be added.
493 * <p>
494 * The XML response is parsed and returned by the object {@link AndsPidResponse}.
495 *
496 * @param handle
497 * the handle to which a new value is to be associated.
498 * @param type
499 * the type of the value to be added to the handle, must be either {@link HandleType#URL} or
500 * {@link HandleType#DESC}.
501 * @param value
502 * the value to be minted.
503 * @return the ANDS Persistent Identifier service response represented by the object {@link AndsPidResponse}.
504 * @throws IllegalStateException
505 * thrown if the parameters need to call the ANDS PID service have not been provided.
506 * @throws IllegalArgumentException
507 * thrown when method is called with invalid arguments.
508 * @throws HttpException
509 * thrown when attempting to execute method call.
510 * @throws IOException
511 * thrown when attempting to read response.
512 * @throws XPathExpressionException
513 * thrown when attempting to execute XPath on XML response.
514 * @throws ParserConfigurationException
515 * thrown when attempting to convert response to an XML document.
516 * @throws SAXException
517 * thrown when attempting to convert response to an XML document.
518 */
519 public AndsPidResponse addValueFormattedResponse(String handle, HandleType type, String value)
520 throws IllegalStateException, IllegalArgumentException, HttpException, IOException,
521 XPathExpressionException, ParserConfigurationException, SAXException
522 {
523 // populate and return the response object
524 return populateAndsPidResponse(this.addValue(handle, type, value));
525 }
526
527 /**
528 * Adds a value to a particular index of an existing handle.
529 * <p>
530 * Only the owner of the handle is able to add a value to the handle and only values of type {@link HandleType#URL}
531 * or {@link HandleType#DESC} can be added.
532 *
533 * @param handle
534 * the handle to which a new value is to be associated.
535 * @param index
536 * the index in which to add the value.
537 * @param type
538 * the type of the value to be added to the handle, must be either {@link HandleType#URL} or
539 * {@link HandleType#DESC}.
540 * @param value
541 * the value to be added to the handle.
542 * @return a formatted XML response that contains the details of the updated handle.
543 * @throws IllegalStateException
544 * thrown if the parameters need to call the ANDS PID service have not been provided.
545 * @throws IllegalArgumentException
546 * thrown when method is called with invalid arguments.
547 * @throws IOException
548 * thrown when attempting to read response.
549 * @throws HttpException
550 * thrown when attempting to execute method call.
551 */
552 @SuppressWarnings(value = "all")
553 public String addValueByIndex(String handle, int index, HandleType type, String value)
554 throws IllegalStateException, IllegalArgumentException, HttpException, IOException
555 {
556 this.validateState();
557
558 if (StringUtils.isEmpty(handle) || StringUtils.isEmpty(value) || type == null || type.isEmpty())
559 {
560 throw new IllegalArgumentException(MessageFormat.format(
561 "The method addValueByIndex() can not be called with null or empty arguments:\n type= {0}\n value= {1}\n",
562 new Object[] { (type == null) ? null : type.value(), value }));
563 }
564
565 NameValuePair[] queryParams = {
566 new NameValuePair("handle", handle),
567 new NameValuePair("index", String.valueOf(index)),
568 new NameValuePair("type", type.value()),
569 new NameValuePair("value", value)
570 };
571 return executeMethod(queryParams, addValueByIndexMethodName);
572 }
573
574 /**
575 * Adds a value to a particular index of an existing handle.
576 * <p>
577 * Only the owner of the handle is able to add a value to the handle and only values of type {@link HandleType#URL}
578 * or {@link HandleType#DESC} can be added.
579 * <p>
580 * The XML response is parsed and returned by the object {@link AndsPidResponse}.
581 *
582 * @param handle
583 * the handle to which a new value is to be associated.
584 * @param index
585 * the index in which to add the value.
586 * @param type
587 * the type of the value to be added to the handle, must be either {@link HandleType#URL} or
588 * {@link HandleType#DESC}.
589 * @param value
590 * the value to be minted.
591 * @return the ANDS Persistent Identifier service response represented by the object {@link AndsPidResponse}.
592 * @throws IllegalStateException
593 * thrown if the parameters need to call the ANDS PID service have not been provided.
594 * @throws IllegalArgumentException
595 * thrown when method is called with invalid arguments.
596 * @throws HttpException
597 * thrown when attempting to execute method call.
598 * @throws IOException
599 * thrown when attempting to read response.
600 * @throws XPathExpressionException
601 * thrown when attempting to execute XPath on XML response.
602 * @throws ParserConfigurationException
603 * thrown when attempting to convert response to an XML document.
604 * @throws SAXException
605 * thrown when attempting to convert response to an XML document.
606 */
607 public AndsPidResponse addValueByIndexFormattedResponse(String handle, int index, HandleType type, String value)
608 throws IllegalStateException, IllegalArgumentException, HttpException, IOException,
609 XPathExpressionException, ParserConfigurationException, SAXException
610 {
611 // populate and return the response object
612 return populateAndsPidResponse(this.addValueByIndex(handle, index, type, value));
613 }
614
615 /**
616 * Changes a value associated with an existing handle.
617 * <p>
618 * Only the owner of the handle is able to modify a value associated with the handle and only values with the type
619 * {@link HandleType#URL} or {@link HandleType#DESC} can be modified.
620 *
621 * @param handle
622 * the handle that is to have one of its values modified.
623 * @param index
624 * the index of the value to modify.
625 * @param newValue
626 * the new value.
627 * @return a formatted XML response that contains the details of the updated handle.
628 * @throws IllegalStateException
629 * thrown if the parameters need to call the ANDS PID service have not been provided.
630 * @throws IllegalArgumentException
631 * thrown when method is called with invalid arguments.
632 * @throws HttpException
633 * thrown when attempting to execute method call.
634 * @throws IOException
635 * thrown when attempting to read response.
636 */
637 @SuppressWarnings(value = "all")
638 public String modifyValueByIndex(String handle, int index, String newValue) throws IllegalStateException,
639 IllegalArgumentException, HttpException, IOException
640 {
641 this.validateState();
642
643 if (StringUtils.isEmpty(handle) || StringUtils.isEmpty(newValue))
644 {
645 throw new IllegalArgumentException(
646 MessageFormat
647 .format(
648 "The method modifyValueByIndex() can not be called with null or empty arguments:" +
649 "\n handle={0}\n newValue={1}\n",
650 new Object[] { handle, newValue }));
651 }
652
653 NameValuePair[] queryParams = {
654 new NameValuePair("index", String.valueOf(index)),
655 new NameValuePair("handle", handle),
656 new NameValuePair("value", newValue)
657 };
658 return executeMethod(queryParams, modifyValueByIndexMethodName);
659 }
660
661 /**
662 * Changes a value associated with an existing handle.
663 * <p>
664 * Only the owner of the handle is able to modify a value associated with the handle and only values with the type
665 * {@link HandleType#URL} or {@link HandleType#DESC} can be modified.
666 * <p>
667 * The XML response is parsed and returned by the object {@link AndsPidResponse}.
668 *
669 * @param handle
670 * the handle that is to have one of its values modified.
671 * @param index
672 * the index of the value to modify.
673 * @param newValue
674 * the new value.
675 * @return the ANDS Persistent Identifier service response represented by the object {@link AndsPidResponse}.
676 * @throws IllegalStateException
677 * thrown if the parameters need to call the ANDS PID service have not been provided.
678 * @throws IllegalArgumentException
679 * thrown when method is called with invalid arguments.
680 * @throws HttpException
681 * thrown when attempting to execute method call.
682 * @throws IOException
683 * thrown when attempting to read response.
684 * @throws XPathExpressionException
685 * thrown when attempting to execute XPath on XML response.
686 * @throws ParserConfigurationException
687 * thrown when attempting to convert response to an XML document.
688 * @throws SAXException
689 * thrown when attempting to convert response to an XML document.
690 */
691 public AndsPidResponse modifyValueByIndexFormattedResponse(String handle, int index, String newValue)
692 throws IllegalStateException, IllegalArgumentException, HttpException, IOException,
693 XPathExpressionException, ParserConfigurationException, SAXException
694 {
695 return populateAndsPidResponse(modifyValueByIndex(handle, index, newValue));
696 }
697
698 /**
699 * Deletes a value associated with an existing handle.
700 * <p>
701 * Only the owner of the handle is able to delete a value associated to the handle and only values of type
702 * {@link HandleType#URL} or {@link HandleType#DESC} can be deleted.
703 *
704 * @param handle
705 * the handle that is to have one of its values deleted.
706 * @param index
707 * the index of the value to be deleted.
708 * @return a formatted XML response that contains the details of the updated handle.
709 * @throws IllegalStateException
710 * thrown if the parameters need to call the ANDS PID service have not been provided.
711 * @throws IllegalArgumentException
712 * thrown when method is called with invalid arguments.
713 * @throws HttpException
714 * thrown when attempting to execute method call.
715 * @throws IOException
716 * thrown when attempting to read response.
717 */
718 public String deleteValueByIndex(String handle, int index) throws IllegalStateException, IllegalArgumentException,
719 HttpException, IOException
720 {
721 this.validateState();
722
723 if (StringUtils.isEmpty(handle))
724 {
725 throw new IllegalArgumentException(MessageFormat.format(
726 "The method deleteValueByIndex() can not be called with null or empty arguments:\n handle={0}\n",
727 new Object[] { handle }));
728 }
729
730 NameValuePair[] queryParams = {
731 new NameValuePair("index", String.valueOf(index)),
732 new NameValuePair("handle", handle)};
733 return executeMethod(queryParams, deleteValueByIndexMethodName);
734 }
735
736 /**
737 * Deletes a value associated with an existing handle. Only values with the type {@link HandleType#URL} or
738 * {@link HandleType#DESC} can be deleted.
739 * <p>
740 * Only the owner of the handle is able to delete a value associated to the handle and only values of type
741 * {@link HandleType#URL} or {@link HandleType#DESC} can be deleted.
742 * <p>
743 * The XML response is parsed and returned by the object {@link AndsPidResponse}.
744 *
745 * @param handle
746 * the handle that is to have one of its indexes deleted.
747 * @param index
748 * the index to be deleted.
749 * @return the ANDS Persistent Identifier service response represented by the object {@link AndsPidResponse}.
750 * @throws IllegalStateException
751 * thrown if the parameters need to call the ANDS PID service have not been provided.
752 * @throws IllegalArgumentException
753 * thrown when method is called with invalid arguments.
754 * @throws HttpException
755 * thrown when attempting to execute method call.
756 * @throws IOException
757 * thrown when attempting to read response.
758 * @throws XPathExpressionException
759 * thrown when attempting to execute XPath on XML response.
760 * @throws ParserConfigurationException
761 * thrown when attempting to convert response to an XML document.
762 * @throws SAXException
763 * thrown when attempting to convert response to an XML document.
764 */
765 public AndsPidResponse deleteValueByIndexFormattedResponse(String handle, int index) throws IllegalStateException,
766 IllegalArgumentException, HttpException, IOException, XPathExpressionException,
767 ParserConfigurationException, SAXException
768 {
769 return populateAndsPidResponse(deleteValueByIndex(handle, index));
770 }
771
772 /**
773 * List the handles owned by the caller of the ANDS PID service.
774 * <p>
775 * This service is intended for listing a small number of handles in a GUI environment, therefore its response is
776 * limited in the number of handles returned.
777 *
778 * @return a formatted XML response that contains the details of the handles owned by the caller.
779 * @throws IllegalStateException
780 * thrown if the parameters need to call the ANDS PID service have not been provided.
781 * @throws HttpException
782 * thrown when attempting to execute method call.
783 * @throws IOException
784 * thrown when attempting to read response.
785 */
786 @SuppressWarnings(value = "all")
787 public String listHandles() throws IllegalStateException, HttpException, IOException
788 {
789 this.validateState();
790 NameValuePair[] queryParams = {new NameValuePair()};
791 return executeMethod(queryParams, listHandlesMethodName);
792 }
793
794 /**
795 * List the handles owned by the caller of the ANDS PID service.
796 * <p>
797 * This service is intended for listing a small number of handles in a GUI environment, therefore its response is
798 * limited in the number of handles returned.
799 * <p>
800 * The XML response is parsed and returned by the object {@link AndsPidResponse}.
801 *
802 * @return the ANDS Persistent Identifier service response represented by the object {@link AndsPidResponse}.
803 * @throws IllegalStateException
804 * thrown if the parameters need to call the ANDS PID service have not been provided.
805 * @throws HttpException
806 * thrown when attempting to execute method call.
807 * @throws IOException
808 * thrown when attempting to read response.
809 * @throws XPathExpressionException
810 * thrown when attempting to execute XPath on XML response.
811 * @throws ParserConfigurationException
812 * thrown when attempting to convert response to an XML document.
813 * @throws SAXException
814 * thrown when attempting to convert response to an XML document.
815 */
816 public AndsPidResponse listHandlesFormattedResponse() throws IllegalStateException, HttpException, IOException,
817 XPathExpressionException, ParserConfigurationException, SAXException
818 {
819 return populateAndsPidResponse(listHandles());
820 }
821
822 /**
823 * Retrieves the values associated with a given handle.
824 *
825 * @param handle
826 * the handle whose details are to be retrieved.
827 * @return a formatted XML response that contains the details of the handle.
828 * @throws IllegalStateException
829 * thrown if the parameters need to call the ANDS PID service have not been provided.
830 * @throws IllegalArgumentException
831 * thrown when method is called with invalid arguments.
832 * @throws HttpException
833 * thrown when attempting to execute method call.
834 * @throws IOException
835 * thrown when attempting to read response.
836 */
837 @SuppressWarnings(value = "all")
838 public String getHandle(String handle) throws IllegalStateException, IllegalArgumentException,
839 HttpException, IOException
840 {
841 this.validateState();
842
843 if (StringUtils.isEmpty(handle))
844 {
845 throw new IllegalArgumentException(MessageFormat.format(
846 "The method getHandle() can not be called with null or empty arguments:\n handle={0}\n",
847 new Object[] { handle }));
848 }
849
850 NameValuePair[] queryParams = {new NameValuePair("handle", handle)};
851 return executeMethod(queryParams, getHandleMethodName);
852 }
853
854 /**
855 * Retrieves the values associated with a given handle.
856 * <p>
857 * The XML response is parsed and returned by the object {@link AndsPidResponse}.
858 *
859 * @param handle
860 * the handle whose details are to be retrieved.
861 * @return the ANDS Persistent Identifier service response represented by the object {@link AndsPidResponse}.
862 * @throws IllegalStateException
863 * thrown if the parameters need to call the ANDS PID service have not been provided.
864 * @throws IllegalArgumentException
865 * thrown when method is called with invalid arguments.
866 * @throws HttpException
867 * thrown when attempting to execute method call.
868 * @throws IOException
869 * thrown when attempting to read response.
870 * @throws XPathExpressionException
871 * thrown when attempting to execute XPath on XML response.
872 * @throws ParserConfigurationException
873 * thrown when attempting to convert response to an XML document.
874 * @throws SAXException
875 * thrown when attempting to convert response to an XML document.
876 */
877 public AndsPidResponse getHandleFormattedResponse(String handle) throws IllegalStateException,
878 IllegalArgumentException, HttpException, IOException, XPathExpressionException,
879 ParserConfigurationException, SAXException
880 {
881 return populateAndsPidResponse(getHandle(handle));
882 }
883
884 /**
885 * Constructs and executes an HTTP POST call.
886 *
887 * @param queryParams
888 * the array of query parameters to provide the POST call.
889 * @param methodName
890 * the method to call.
891 * @return a formatted XML response.
892 * @throws IOException
893 * thrown when attempting to read response.
894 * @throws HttpException
895 * thrown when attempting to execute method call.
896 */
897 private String executeMethod(NameValuePair[] queryParams, String methodName) throws HttpException, IOException
898 {
899 HttpsURL url = new HttpsURL(/* String user */"", /* String password */"", this.getPidServiceHost(), this
900 .getPidServicePort(), this.getPidServicePath());
901
902 // if no path has been specified (i.e. path value is just '/') then we have:
903 // http://test.org.au:80/mint?type=URL&value=<some value>
904 if ("/".equals(url.getPath()))
905 {
906 url.setPath(url.getPath() + methodName);
907 }
908 else
909 // if a path has been specified then we have: http://test.org.au:80/<some path>/mint?type=URL&value=<some value>
910 {
911 url.setPath(url.getPath() + "/" + methodName);
912 }
913
914 String identityXML = this.getRequestorIdentity().toXML(methodName);
915
916 return executePostMethod(url.toString(), queryParams, identityXML);
917
918 }
919
920 /**
921 * Calls a POST method of the ANDS Persistent Identifier service in a RESTful web service manner. The query string
922 * of the URI defines the type of operation that is to be performed. The request body contains an XML fragment that
923 * identifies the caller.
924 *
925 * @param postMethodURL
926 * the URI of the RESTful ANDS Persistent Identifier web service.
927 * @param params
928 * the array of query parameters to provide the POST call.
929 * @param identityXML
930 * an XML fragment that details the identity of the caller.
931 * @return a formatted XML response.
932 * @throws IOException
933 * thrown when attempting to read response.
934 * @throws HttpException
935 * thrown when attempting to execute method call.
936 */
937 private String executePostMethod(String postMethodURL, NameValuePair[] params, String identityXML) throws HttpException, IOException
938 {
939 LOG.debug("Post method URL: " + postMethodURL);
940 LOG.debug("Identity XML: " + identityXML);
941
942 HttpClient client = new HttpClient();
943 client.getParams().setParameter("http.useragent", applicationName);
944 client.getParams().setParameter("Content-Type", "text/xml");
945 client.getParams().setParameter("Content-Encoding", "UTF-8");
946
947 PostMethod method = new PostMethod(postMethodURL);
948
949 BufferedReader br = null;
950 StringBuffer strBuf = new StringBuffer();
951
952 try
953 {
954 RequestEntity entity = new StringRequestEntity(identityXML, "text/xml", "UTF-8");
955 client.getParams().setParameter("Content-Length", entity.getContentLength());
956 method.setRequestEntity(entity);
957 method.setQueryString(params);
958 int returnCode = client.executeMethod(method);
959 if (returnCode == HttpStatus.SC_NOT_IMPLEMENTED)
960 {
961 LOG.error("The post method is not implemented by this URI");
962 // still consume the response body
963 method.getResponseBodyAsString();
964 }
965 else
966 {
967 br = new BufferedReader(new InputStreamReader(method.getResponseBodyAsStream()));
968 String readLine;
969 while (((readLine = br.readLine()) != null))
970 {
971 LOG.debug(readLine);
972 strBuf.append(readLine);
973 }
974 }
975 }
976 finally
977 {
978 if (br != null)
979 {
980 br.close();
981 }
982 method.releaseConnection();
983 }
984
985 return strBuf.toString();
986 }
987
988 /**
989 * Parses an XML document which contains an ANDS PID service response for a node that specifies whether the service
990 * call was successful.
991 *
992 * @param doc
993 * an XML document of the ANDS PID service response.
994 * @return whether the response represents a success
995 * @throws XPathExpressionException
996 * thrown when attempting to execute XPath on XML response.
997 * @throws ParserConfigurationException
998 * thrown when attempting to convert response to an XML document.
999 * @throws SAXException
1000 * thrown when attempting to convert response to an XML document.
1001 * @throws IOException
1002 * thrown when attempting to read response.
1003 */
1004 @SuppressWarnings(value = "all")
1005 private boolean parseForSuccess(Document doc) throws XPathExpressionException, ParserConfigurationException,
1006 SAXException, IOException
1007 {
1008 XPathFactory factory = XPathFactory.newInstance();
1009 XPath xpath = factory.newXPath();
1010
1011 // whether <response type="success"> was returned
1012 XPathExpression expr = xpath.compile("//response[@type]");
1013 Object result = expr.evaluate(doc, XPathConstants.NODESET);
1014 NodeList nodes = (NodeList) result;
1015 for (int i = 0; i < nodes.getLength(); i++)
1016 {
1017 for (int j = 0; j < nodes.item(i).getAttributes().getLength(); j++)
1018 {
1019 Node node = (Node) nodes.item(i).getAttributes().item(j);
1020 return "success".equals(node.getNodeValue());
1021 }
1022 }
1023 return false;
1024 }
1025
1026 /**
1027 * Parses an XML document which contains an ANDS PID service response
1028 * for a node that specifies what the response message is.
1029 *
1030 * @param doc
1031 * an XML document of the ANDS PID service response.
1032 * @return the response message
1033 * @throws XPathExpressionException
1034 * thrown when attempting to execute XPath on XML response.
1035 * @throws ParserConfigurationException
1036 * thrown when attempting to convert response to an XML document.
1037 * @throws SAXException
1038 * thrown when attempting to convert response to an XML document.
1039 * @throws IOException
1040 * thrown when attempting to read response.
1041 */
1042 @SuppressWarnings(value = "all")
1043 private String parseForMessage(Document doc) throws XPathExpressionException, ParserConfigurationException,
1044 SAXException, IOException
1045 {
1046 XPathFactory factory = XPathFactory.newInstance();
1047 XPath xpath = factory.newXPath();
1048
1049 XPathExpression expr = xpath.compile("//response/message");
1050 Object result = expr.evaluate(doc, XPathConstants.NODESET);
1051 NodeList nodes = (NodeList) result;
1052 for (int i = 0; i < nodes.getLength(); i++)
1053 {
1054 return nodes.item(i).getTextContent();
1055 }
1056 return null;
1057 }
1058
1059 /**
1060 * Parses an XML document which contains an ANDS PID service response for the nodes specifying the handles that were
1061 * used in the service call.
1062 *
1063 * @param doc
1064 * an XML document of the ANDS PID service response.
1065 * @return the handles associated with the service call.
1066 * @throws XPathExpressionException
1067 * thrown when attempting to execute XPath on XML response.
1068 * @throws ParserConfigurationException
1069 * thrown when attempting to convert response to an XML document.
1070 * @throws SAXException
1071 * thrown when attempting to convert response to an XML document.
1072 * @throws IOException
1073 * thrown when attempting to read response.
1074 */
1075 private List<String> parseForHandles(Document doc) throws XPathExpressionException, ParserConfigurationException,
1076 SAXException, IOException
1077 {
1078 List<String> handles = new ArrayList<String>();
1079
1080 XPathFactory factory = XPathFactory.newInstance();
1081 XPath xpath = factory.newXPath();
1082
1083 // look for the tag: <identifier handle="XXXX/X">
1084 XPathExpression expr = xpath.compile("//identifier[@handle]");
1085 Object result = expr.evaluate(doc, XPathConstants.NODESET);
1086 NodeList nodes = (NodeList) result;
1087 for (int i = 0; i < nodes.getLength(); i++)
1088 {
1089 for (int j = 0; j < nodes.item(i).getAttributes().getLength(); j++)
1090 {
1091 Node node = (Node) nodes.item(i).getAttributes().item(j);
1092 String handle = node.getNodeValue();
1093 handles.add(handle);
1094 }
1095 }
1096 return handles;
1097 }
1098
1099 /**
1100 * Parses an XML document which contains an ANDS PID service response for the nodes specifying the properties
1101 * associated with a handle.
1102 *
1103 * @param doc
1104 * an XML document of the ANDS PID service response.
1105 * @return the properties associated with the handle used in the service call.
1106 * @throws XPathExpressionException
1107 * thrown when attempting to execute XPath on XML response.
1108 * @throws ParserConfigurationException
1109 * thrown when attempting to convert response to an XML document.
1110 * @throws SAXException
1111 * thrown when attempting to convert response to an XML document.
1112 * @throws IOException
1113 * thrown when attempting to read response.
1114 */
1115 private static List<AndsPidResponseProperty> parseForProperties(Document doc)
1116 throws XPathExpressionException, ParserConfigurationException, SAXException, IOException
1117 {
1118 List<AndsPidResponseProperty> properties = new ArrayList<AndsPidResponseProperty>();
1119
1120 XPathFactory factory = XPathFactory.newInstance();
1121 XPath xpath = factory.newXPath();
1122
1123 // look for the tags: <property index="X" type="XXXX" values="XXXX"/>
1124 XPathExpression expr = xpath.compile("//property[@index]");
1125 Object result = expr.evaluate(doc, XPathConstants.NODESET);
1126 NodeList nodes = (NodeList) result;
1127 for (int i = 0; i < nodes.getLength(); i++)
1128 {
1129 String[] triple = new String[TRIPLE];
1130 for (int j = 0; j < Math.min(TRIPLE, nodes.item(i).getAttributes().getLength()); j++)
1131 {
1132 Node node = (Node) nodes.item(i).getAttributes().item(j);
1133 triple[j] = node.getNodeValue();
1134 }
1135 properties.add(new AndsPidResponseProperty(Integer.valueOf(triple[0]), triple[1], triple[2]));
1136 }
1137 return properties;
1138 }
1139
1140 /**
1141 * Helper method for converting formatted XML response into an XML document.
1142 *
1143 * @param xmlResponse
1144 * a formatted XML response.
1145 * @return an XML document.
1146 * @throws ParserConfigurationException
1147 * thrown when attempting to convert response to an XML document.
1148 * @throws SAXException
1149 * thrown when attempting to convert response to an XML document.
1150 * @throws IOException
1151 * thrown when attempting to read response.
1152 */
1153 private static Document parseXML(String xmlResponse) throws ParserConfigurationException, SAXException, IOException
1154 {
1155 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
1156 factory.setNamespaceAware(true);
1157 DocumentBuilder builder = factory.newDocumentBuilder();
1158 StringReader reader = new StringReader(xmlResponse);
1159 InputSource inputSource = new InputSource(reader);
1160 Document doc = builder.parse(inputSource);
1161 reader.close();
1162 return doc;
1163 }
1164
1165 /**
1166 * Populate a AndsPidResponse object from the XML response of an ANDS Persistent Identifier service call.
1167 *
1168 * @param xmlResponse
1169 * the raw xmlResponse from an ANDS Persistent Identifier service call.
1170 * @return an ANDS Persistent Identifier service response {@link AndsPidResponse}.
1171 * @throws XPathExpressionException
1172 * thrown when attempting to execute XPath on XML response.
1173 * @throws ParserConfigurationException
1174 * thrown when attempting to convert response to an XML document.
1175 * @throws SAXException
1176 * thrown when attempting to convert response to an XML document.
1177 * @throws IOException
1178 * thrown when attempting to read response.
1179 */
1180 private AndsPidResponse populateAndsPidResponse(String xmlResponse) throws XPathExpressionException,
1181 ParserConfigurationException, SAXException, IOException
1182 {
1183 AndsPidResponse response = new AndsPidResponse();
1184 response.setXmlResponse(xmlResponse);
1185
1186 Document doc = parseXML(xmlResponse);
1187 response.setMessage(parseForMessage(doc));
1188 response.setSuccess(parseForSuccess(doc));
1189 response.setHandles(parseForHandles(doc));
1190 response.setProperties(parseForProperties(doc));
1191 return response;
1192 }
1193
1194 /**
1195 * Checks that this class is in a valid state to call the ANDS PID service.
1196 *
1197 * @throws IllegalStateException
1198 * thrown if the parameters need to call the ANDS PID service have not been provided.
1199 */
1200 private void validateState() throws IllegalStateException
1201 {
1202 StringBuffer errorMsg = new StringBuffer();
1203 if (StringUtils.isEmpty(this.getPidServiceHost()))
1204 {
1205 errorMsg.append("The host name of the ANDS PID service has not been provided. e.g. test.org.au\n");
1206 }
1207 if (getRequestorIdentity() == null || StringUtils.isEmpty(this.getRequestorIdentity().getAppId()))
1208 {
1209 errorMsg
1210 .append("The appID of the caller has not been provided. " +
1211 "e.g. unique Id provided by ANDS upon IP registration.\n");
1212 }
1213 if (getRequestorIdentity() == null || StringUtils.isEmpty(this.getRequestorIdentity().getIdentifier()))
1214 {
1215 errorMsg
1216 .append("The identifier of the caller has not been provided. " +
1217 "e.g. identifier or name of the repository calling the service.\n");
1218 }
1219 if (getRequestorIdentity() == null || StringUtils.isEmpty(this.getRequestorIdentity().getAuthDomain()))
1220 {
1221 errorMsg
1222 .append("The authDomain of the caller has not been provided. " +
1223 "e.g. the domain of the organisation calling the service.");
1224 }
1225 // if we have error messages, throw the exception
1226 if (errorMsg.length() != 0)
1227 {
1228 throw new IllegalStateException(errorMsg.toString());
1229 }
1230 }
1231
1232
1233 /**
1234 * Checks the arguments passed to the {@link #mintHandle(HandleType, String)} and the
1235 * {@link #mintHandleByIndex(HandleType, int, String)} methods.
1236 *
1237 * @param type
1238 * the type of the value to be minted {@link HandleType}.
1239 * @param value
1240 * the value to be minted.
1241 * @throws IllegalStateException
1242 * thrown if the arguments provided to {@link #mintHandle(HandleType, String)} or to
1243 * {@link #mintHandleByIndex(HandleType, int, String)} are not valid.
1244 */
1245 private void validateMintHandleArguments(HandleType type, String value) throws IllegalArgumentException
1246 {
1247 // we should never accept a null HandleType
1248 if (type == null)
1249 {
1250 throw new IllegalArgumentException(
1251 "The method mintHandle() can not be called with a null HandleType argument.\n");
1252 }
1253
1254 // we can only accept the arguments if and only if both arguments are empty or both arguments are not empty
1255 // (logical equality).
1256 if (type.isEmpty() != StringUtils.isEmpty(value))
1257 {
1258 throw new IllegalArgumentException(MessageFormat.format(
1259 "The method mintHandle() can only be called if both arguments are empty "
1260 + "or both arguments are not empty:\n type= {0}\n value={1}\n", new Object[] {
1261 (type == null) ? null : type.value(), value }));
1262 }
1263 }
1264
1265 /**
1266 * Retrieve the current ANDS Persistent Identifier host name
1267 * @return the ANDS Persistent Identifier host name
1268 */
1269 public String getPidServiceHost()
1270 {
1271 return pidServiceHost;
1272 }
1273
1274 /**
1275 * Set the ANDS Persistent Identifier host name.
1276 * @param pidServiceHost
1277 * the ANDS Persistent Identifier host name to set
1278 */
1279 public void setPidServiceHost(String pidServiceHost)
1280 {
1281 this.pidServiceHost = pidServiceHost;
1282 }
1283
1284 /**
1285 * Retrieve the ANDS Persistent Identifier port number
1286 * @return the ANDS Persistent Identifier port number
1287 */
1288 public int getPidServicePort()
1289 {
1290 return pidServicePort;
1291 }
1292
1293 /**
1294 * Set the ANDS Persistent Identifier port number
1295 * @param pidServicePort
1296 * the ANDS Persistent Identifier port number to set
1297 */
1298 public void setPidServicePort(int pidServicePort)
1299 {
1300 this.pidServicePort = pidServicePort;
1301 }
1302
1303 /**
1304 * Retrieve the current ANDS Persistent Identifier path name (web application context name)
1305 * @return the ANDS Persistent Identifier path name
1306 */
1307 public String getPidServicePath()
1308 {
1309 return pidServicePath;
1310 }
1311
1312 /**
1313 * Set the current ANDS Persistent Identifier path name (web application context name)
1314 * @param pidServicePath
1315 * the ANDS Persistent Identifier path name to set
1316 */
1317 public void setPidServicePath(String pidServicePath)
1318 {
1319 this.pidServicePath = pidServicePath;
1320 }
1321
1322 /**
1323 * Retrieve the identity information of the calling application/organisation.
1324 * @return the identity of the caller
1325 */
1326 public AndsPidIdentity getRequestorIdentity()
1327 {
1328 return requestorIdentity;
1329 }
1330
1331 /**
1332 * Set the identity information of the calling application/organisation.
1333 * @param requestorIdentity
1334 * the identity object to set
1335 */
1336 public void setRequestorIdentity(AndsPidIdentity requestorIdentity)
1337 {
1338 this.requestorIdentity = requestorIdentity;
1339 }
1340
1341 }