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 }