001/* 002 * file StpResource.java 003 * 004 * Licensed Materials - Property of IBM 005 * Restricted Materials of IBM 006 * 007 * com.ibm.rational.wvcm.stp.StpResource 008 * 009 * (C) Copyright IBM Corporation 2004, 2011. All Rights Reserved. 010 * Note to U.S. Government Users Restricted Rights: Use, duplication or 011 * disclosure restricted by GSA ADP Schedule Contract with IBM Corp. 012 */ 013package com.ibm.rational.wvcm.stp; 014 015 016import static com.ibm.rational.wvcm.stpex.StpExBase.PROPERTY_NAMESPACE; 017 018import java.lang.annotation.ElementType; 019import java.lang.annotation.Retention; 020import java.lang.annotation.RetentionPolicy; 021import java.lang.annotation.Target; 022 023import javax.wvcm.Feedback; 024import javax.wvcm.PropertyNameList.PropertyName; 025import javax.wvcm.PropertyRequestItem; 026import javax.wvcm.Resource; 027import javax.wvcm.WvcmException; 028 029import com.ibm.rational.wvcm.stp.StpProperty.MetaPropertyName; 030import com.ibm.rational.wvcm.stpex.StpExBase; 031 032/** 033 * A proxy for a resource persisted in a repository or in a file area. 034 */ 035public interface StpResource extends javax.wvcm.Resource 036{ 037 /** 038 * Returns true iff it can be determined that this proxy references the same 039 * resource as the given proxy. Proxy equality is based either on the value 040 * of the proxy's Location or on the value of the proxy's 041 * RESOURCE_IDENTIFIER property. 042 * <p> 043 * This proxy equates to another proxy iff one of the following conditions 044 * is true... 045 * <ul> 046 * <li>The location() of this proxy equals the location() of the other 047 * proxy, OR 048 * <li>The other proxy defines the RESOURCE_IDENTIFIER property and the 049 * location().string() of this proxy equals the RESOURCE_IDENTIFIER of the 050 * other proxy, OR 051 * <li>This proxy defines the RESOURCE_IDENTIFIER property and it equals 052 * the location().string() of the other proxy, OR 053 * <li>Both proxies define the RESOURCE_IDENTIFIER property and they are 054 * equal 055 * </ul> 056 * 057 * @param rhs The Object against which to compare this proxy. If the Object 058 * is not a Resource, equals returns <b>false</b>. 059 * @return <b>true</b> if the proxies compare equal as defined above; 060 * <b>false</b> otherwise. 061 * @see Object#equals(java.lang.Object) 062 */ 063 boolean equals(Object rhs); 064 065 /** 066 * Returns the hashCode() for the value of this proxy's RESOURCE_IDENTIFIER 067 * property if the proxy has a value for it; otherwise returns the 068 * hashCode() for the proxy's Location object. 069 * 070 * @see Object#hashCode() 071 */ 072 int hashCode(); 073 074 /** 075 * Returns the collection of metadata components defined in this proxy for a 076 * given PropertyName. 077 * 078 * @param name A PropertyName identifying the property whose metadata is 079 * desired 080 * @return An StpProperty instance that contains the metadata for the given 081 * property requested from the server through this proxy. 082 * @throws WvcmException if no metadata for the given property has been 083 * requested from the server through this proxy. 084 */ 085 <T> StpProperty<T> getMetaProperties(PropertyName<T> name) 086 throws WvcmException; 087 088 /** 089 * Request the properties specified in <code>feedback</code> from the 090 * server resource represented by this proxy. A new proxy will be 091 * constructed whose property map contains just the requested properties. 092 * <p> 093 * Properties are computed relative to the given context. For example, the 094 * {@link com.ibm.rational.wvcm.stp.cc.CcVersion#VIEW_RELATIVE_PATH VIEW_RELATIVE_PATH} 095 * property of a CcVersion or CcElement resource can only be provided in the 096 * context of a CcView. Hence, you would use this form of doReadProperties 097 * to specify the CcView context that should be used. 098 * 099 * @param context An optional proxy (often CcView) providing context for the 100 * generation of certain properties in the returned report. 101 * May be <b>null</b>. 102 * @param feedback Provides optional feedback to the caller for long-running 103 * requests and/or a list of properties desired from the server. 104 * If the parameter is null or empty, a request is still made, 105 * and the returned proxy will have only the properties always 106 * requested from the server. 107 * @return A proxy containing the properties retrieved from the server (and 108 * error messages for those that could not be retrieved). The class 109 * of the returned proxy is the one most suited to the type of 110 * resource addressed. 111 * 112 * @throws WvcmException if failures occur 113 * 114 * @see StpResource#doReadProperties(Feedback) 115 */ 116 Resource doReadProperties(Resource context, 117 Feedback feedback) throws WvcmException; 118 119 /** 120 * Returns whether or not from this proxy uncorrupted property values can be 121 * obtained for all the properties and meta-properties specified by a given 122 * PropertyRequestItem, which may specify multiple and nested properties. 123 * <p> 124 * If <code>wantedProp</code> is a nested property request then the test 125 * is applied recursively to the non-null value(s) of the property named by 126 * <code>wantedProp.getRoot()</code> testing in each value for valid 127 * instances of the properties named by <code>wantedProp.getNested()</code>. 128 * If any of the values identified by the property name are invalid, then 129 * this method returns <code>false</code>. Note that if the value for the 130 * root property of a PropertyName is <code>null</code>, the test for 131 * that PropertyName is deemed valid even if the PropertyName had nested 132 * properties. 133 * 134 * @param wantedProp A PropertyRequestItem, possibly with multiple nested 135 * properties, to check the value for. Cannot be 136 * <code>null</code>. 137 * 138 * @return <code>true</code> if there is an entry in this proxy for all 139 * properties named at the top level of the PropertyRequestItem, and 140 * those entries contain a valid value (not in error) and for those 141 * property values that are resources any nested property request is 142 * also similarly satisfied; <code>false</code> otherwise. 143 */ 144 boolean hasProperties(PropertyRequestItem wantedProp); 145 146 /** 147 * Sets the value of the specified property in this resource proxy. 148 * This method differs from setProperty() in that this method does not mark 149 * the property "dirty", so subsequent calls to doWriteProperties() or other 150 * "do()" methods will not commit this new value to the underlying resource. 151 * @param name the name of the property. 152 * @param value the new value of the specified property. 153 * @see #setProperty 154 * @see #getProperty 155 */ 156 public <T> void setPropertyClean(PropertyName<T> name, T value); 157 158 /** 159 * Returns the StpPropertyException that would be thrown by getProperty if 160 * it were called with the given PropertyName. 161 * 162 * <p> 163 * If there was an error retrieving the property when requested, or the 164 * property was never defined in the proxy, an {@link StpPropertyException} 165 * is returned; otherwise <b>null</b> is returned. 166 * 167 * @param propertyName The property for which an exception is desired. 168 * Cannot be <b>null</b>. 169 * 170 * @return The exception that would be thrown by getProperty() if it were 171 * used to access the given <code>propertyName</code>; Will be 172 * <b> null</b> if no exception would be thrown. 173 */ 174 StpException getPropertyException(PropertyName<?> propertyName); 175 176 /** 177 * The most human-readable location for a resource. This is the form of 178 * location that clients should show to users when a precise location must 179 * be displayed--e.g. one which the user must remember and re-enter in a 180 * subsequent session. When such precision is not needed, the 181 * {@link javax.wvcm.Resource#DISPLAY_NAME} property would be a better 182 * choice for the presentation. 183 * <p> 184 * The USER_FRIENDLY_LOCATION is <i>usually</i> expressed by a 185 * user-friendly-selector scheme location, but other location schemes may 186 * also be used depending on the type of resource. 187 * <p> 188 * The value of this property is <i>not</i> always defined for every 189 * resource. If a resource does not have a USER_FRIENDLY_LOCATION, that is a 190 * strong indication that that resource should not be part of the normal 191 * object model presented to the user. If not defined, the value will be an 192 * empty string. 193 * <p> 194 * Note that the location used by a proxy returned by the server is 195 * formatted to provide the most efficient access to the resource in 196 * subsequent interactions with the server in the current session. That 197 * location is not necessarily the same as the resource's 198 * USER_FRIENDLY_LOCATION or its STABLE_LOCATION. 199 * 200 * @see #STABLE_LOCATION 201 * @see #EFFICIENT_LOCATION 202 */ 203 PropertyName<StpLocation> USER_FRIENDLY_LOCATION = 204 new PropertyName<StpLocation>(PROPERTY_NAMESPACE, 205 "user-friendly-location"); 206 207 /** 208 * Returns the value of the 209 * {@link #USER_FRIENDLY_LOCATION USER_FRIENDLY_LOCATION} property as 210 * defined by this proxy. 211 * 212 * @return The StpLocation value. Will never be <b>null</b>. 213 * 214 * @throws WvcmException if this proxy does not define a value for the 215 * {@link #USER_FRIENDLY_LOCATION USER_FRIENDLY_LOCATION} 216 * property. 217 */ 218 StpLocation getUserFriendlyLocation() throws WvcmException; 219 220 /** 221 * The most stable (over space and time) location available for this 222 * resource. Clients should use this form of location when archiving 223 * resource references for use between sessions. 224 * <p> 225 * The stable location is <i>usually</i> expressed by a repo-selector 226 * scheme location, but other location schemes may also be used depending on 227 * the type of resource. 228 * <p> 229 * The value of this property is always defined for every resource, but, in 230 * fact, <i>it may not be stable</i>. But, if the resource has a stable 231 * location, that location will be returned by this property. 232 * <p> 233 * The value returned always represents the identifier associated with the 234 * server state of the resource, even if the Resource on which it is 235 * requested has client-side state. 236 * <p> 237 * Note that the location used by a proxy returned by the server is 238 * formatted to provide the <i>most efficient</i> access to the resource in 239 * subsequent interactions with the server in the current session. That 240 * location is not necessarily the same as the resource's 241 * USER_FRIENDLY_LOCATION or its STABLE_LOCATION. 242 * 243 * @see #USER_FRIENDLY_LOCATION 244 * @see #EFFICIENT_LOCATION 245 */ 246 PropertyName<StpLocation> STABLE_LOCATION = 247 new PropertyName<StpLocation>(PROPERTY_NAMESPACE, "stable-location"); 248 249 /** 250 * Returns the value of the {@link #STABLE_LOCATION STABLE_LOCATION} 251 * property as defined by this proxy. 252 * 253 * @return The StpLocation value. Will never be <b>null</b>. 254 * 255 * @throws WvcmException if this proxy does not define a value for the 256 * {@link #STABLE_LOCATION STABLE_LOCATION} property. 257 */ 258 StpLocation getStableLocation() throws WvcmException; 259 260 /** 261 * The most efficient location available for this resource. Clients should 262 * use this form of location when it is not necessary to either show this 263 * location to users, nor to archive resource references for use between 264 * sessions. 265 * <p> 266 * The efficient location is <i>usually</i> expressed by a repo-selector 267 * scheme location, but other location schemes may also be used depending on 268 * the type of resource. 269 * <p> 270 * The value of this property is always defined for every resource, but, in 271 * fact, <i>it may not be more efficient than the other forms</i>. But, if 272 * the resource has an efficient location, that location will be returned by 273 * this property. 274 * <p> 275 * The value returned always represents the identifier associated with the 276 * server state of the resource, even if the Resource on which it is 277 * requested has client-side state. 278 * <p> 279 * This is the location format usually used in the proxies returned from the 280 * server. 281 * 282 * @see #USER_FRIENDLY_LOCATION 283 * @see #STABLE_LOCATION 284 */ 285 PropertyName<StpLocation> EFFICIENT_LOCATION = 286 new PropertyName<StpLocation>(PROPERTY_NAMESPACE, "efficient-location"); 287 288 /** 289 * Returns the value of the {@link #EFFICIENT_LOCATION EFFICIENT_LOCATION} 290 * property as defined by this proxy. 291 * 292 * @return The StpLocation value for the resources most efficient location. 293 * Will never be <b>null</b>. 294 * 295 * @throws WvcmException if this proxy does not define a value for the 296 * {@link #EFFICIENT_LOCATION EFFICIENT_LOCATION} property. 297 */ 298 StpLocation getEfficientLocation() throws WvcmException; 299 300 /** 301 * Note: the {@link #RESOURCE_IDENTIFIER} property is defined only for 302 * server resources (it's undefined for uncontrolled controllable resources) 303 * and it's value is not available locally via 304 * ControllableResource.readProperties(). 305 * 306 * @see javax.wvcm.Resource#getResourceIdentifier() 307 * @see javax.wvcm.Resource#RESOURCE_IDENTIFIER 308 */ 309 public String getResourceIdentifier() throws WvcmException; 310 311 /** 312 * The authentication realm in which this resource resides. When credentials 313 * are needed to access this resource this is string that should be 314 * presented to the user to identify what the user is to provide credentials 315 * for. 316 */ 317 PropertyName<String> AUTHENTICATION_REALM = 318 new PropertyName<String>(PROPERTY_NAMESPACE, "authentication-realm"); 319 320 /** 321 * Returns the value of the {@link #AUTHENTICATION_REALM 322 * AUTHENTICATION_REALM} property as defined by this proxy. 323 * 324 * @return A String containing the realm identifier passed to the 325 * authentication callback when accessing this resource. 326 * 327 * @throws WvcmException if this proxy does not define a value for the 328 * {@link #AUTHENTICATION_REALM AUTHENTICATION_REALM} property. 329 */ 330 String getAuthenticationRealm() throws WvcmException; 331 332 /** A list of the properties that are currently invalid for this resource */ 333 PropertyName<StpProperty.List<StpProperty<?>>> INVALID_PROPERTIES = 334 new PropertyName<StpProperty.List<StpProperty<?>>>(PROPERTY_NAMESPACE, 335 "invalid-properties"); 336 337 /** 338 * Returns the value of the {@link #INVALID_PROPERTIES INVALID_PROPERTIES} 339 * property as defined by this proxy. 340 * 341 * @return A Property.List of Property objects, each identifying one invalid 342 * property of this Resource 343 * 344 * @throws WvcmException if this proxy does not define a value for the 345 * {@link #INVALID_PROPERTIES INVALID_PROPERTIES} property. 346 */ 347 StpProperty.List<StpProperty<?>> getInvalidProperties() 348 throws WvcmException; 349 350 /** 351 * A list of all the properties that are defined on this resource. The 352 * returned properties can be retrieved as a list using getAllProperties() 353 * or individually, using 354 * {@link javax.wvcm.Resource#getProperty(javax.wvcm.PropertyNameList.PropertyName) getProperty} or an 355 * appropriate getter method. 356 */ 357 PropertyName<StpProperty.List<StpProperty<?>>> ALL_PROPERTIES = 358 new PropertyName<StpProperty.List<StpProperty<?>>>(StpExBase.PROPERTY_NAMESPACE, 359 "all-properties"); 360 361 /** 362 * Returns the properties defined in this proxy. Note, this "getter" will 363 * work even if ALL_PROPERTIES was not explicitly requested when building 364 * the proxy. 365 * 366 * @return An StpProperty.List containing a Property object for each 367 * property defined by this proxy. If there were errors in 368 * retrieving any meta-properties (including the VALUE 369 * meta-property), these errors can be discovered through the 370 * StpProperty interface. 371 */ 372 StpProperty.List<StpProperty<?>> getAllProperties(); 373 374 /** 375 * Returns the custom properties recorded in this proxy. Note, this "getter" 376 * will work even if ALL_CUSTOM_PROPERTIES was not explicitly requested when 377 * building the proxy. 378 * 379 * @return A Property.List containing a Property object for each custom 380 * (i.e. not defined by WVCM) property defined by this proxy. If 381 * there were errors in retrieving any meta-properties (including 382 * the VALUE meta-property), these errors can be discovered through 383 * the Property interface. 384 */ 385 StpProperty.List<StpProperty<?>> getCustomProperties(); 386 387 /** The StpRepository that contains this resource. */ 388 PropertyName<StpRepository> REPOSITORY = 389 new PropertyName<StpRepository>(PROPERTY_NAMESPACE, "repository"); 390 391 /** 392 * Returns the value of the {@link #REPOSITORY} property as defined by this 393 * proxy. 394 * 395 * @return The StpRepository that this resource is in. Will never be <b>null</b>. 396 * 397 * @throws WvcmException if this proxy does not define a value for the 398 * {@link #REPOSITORY} property. 399 */ 400 StpRepository getRepository() throws WvcmException; 401 402 /** 403 * The login name of the user that created this object. A request for this 404 * value can only be satisfied by a request to a server; it is not available 405 * locally. 406 */ 407 PropertyName<String> CREATOR_LOGIN_NAME = 408 new PropertyName<String>(PROPERTY_NAMESPACE, "creator-login-name"); 409 410 /** 411 * Returns the value of the {@link #CREATOR_LOGIN_NAME} property as defined 412 * by this proxy. 413 * 414 * @throws WvcmException Thrown if the property was never requested, or 415 * otherwise unavailable (e.g. requested in a client-context 416 * only). 417 */ 418 String getCreatorLoginName() throws WvcmException; 419 420 /** 421 * The group name of the user that created an object. This value can only be 422 * satisfied by a request to the server; it is not available locally. 423 */ 424 PropertyName<String> CREATOR_GROUP_NAME = 425 new PropertyName<String>(PROPERTY_NAMESPACE, "creator-group-name"); 426 427 /** 428 * Returns the value of the {@link #CREATOR_GROUP_NAME} property as defined 429 * by this proxy. 430 * 431 * @throws WvcmException Thrown if the property was never requested, or is 432 * otherwise unavailable (e.g. requested in a client-context 433 * only). 434 */ 435 String getCreatorGroupName() throws WvcmException; 436 437 /** 438 * Returns the Location of this proxy's Location cast as an StpLocation. 439 * 440 * @return The StpLocation for this Resource proxy. Will never be <b>null</b>. 441 */ 442 StpLocation stpLocation(); 443 444 /** 445 * Returns the value of the <i>resource error attribute</i> associated with 446 * this proxy. 447 * 448 * <p> 449 * If this attribute is not null it indicates that an error occurred when 450 * trying to access the resource addressed by this proxy (even though that 451 * address was actually generated by the server). In this case, none of the 452 * properties requested for this proxy will be defined. The value of the 453 * resource error attribute is an StpException that records the nature of 454 * the problem encountered by the server. 455 * 456 * <p> 457 * This attribute is set only when this proxy is returned as an indirect 458 * result of a server interaction. If this defective address was used by a 459 * client as the target of a server contact method or if it was the expected 460 * direct result of some server contact method, that contact method would 461 * have thrown an exception rather than setting this attribute. 462 * 463 * <p> 464 * Whenever the server returns a list of resources (either as a direct 465 * response to a request or as the value of a property) it is possible that 466 * the server can enumerate all of the members of the list but cannot 467 * actually access one or more of the enumerated members to access its 468 * properties. When this happens, the operation is not aborted and does not 469 * itself throw an exception. Instead, a proxy is generated and marked with 470 * this resource error attribute so that the problem is record and then the 471 * rest of the list is processed. 472 * 473 * @return <b>null</b> if no error is associated with the resource, 474 * otherwise a StpException describing the error. 475 */ 476 StpException getResourceError(); 477 478 /** 479 * @return Returns the StpProvider from which this proxy was obtained. 480 */ 481 StpProvider stpProvider(); 482 483 /** 484 * Sets the value of a meta-property of a property into this proxy without 485 * causing that property to be written to the resource on the next 486 * repository interaction. Like the setProperty() method, this method does 487 * not verify that the given object is a value suitable for the specified 488 * meta-property. This method also does not verify that the given 489 * PropertyName is appropriate for the type of resource represented by this 490 * proxy nor that the given MetaPropertyName is appropriate for the given 491 * PropertyName. 492 * <p> 493 * This method may be used in conjunction with 494 * {@link StpProvider#buildProxy(StpLocation, String, String) StpProvider.buildProxy()} 495 * to reconstruct proxies previously saved to persistent storage. Use 496 * buildProxy() to construct a proxy object of the appropriate type and then 497 * use this method to copy each saved meta-property value into that proxy 498 * object. 499 * <p> 500 * This method may also be used in conjunction with forgetProperty to merge 501 * meta-property values from one proxy into another and thereby facilitate 502 * the use of a proxy object as a long-lived cache for resource data. This 503 * approach is not recommended unless the client fully understands the 504 * pitfalls inherent in maintaining a cache of shared server data in a 505 * client for any length of time. 506 * <p style="padding-left:47;text-indent:-47"> 507 * Note 1: Since the primary intent of this method is to provide the client 508 * with a means to restore a proxy from archive, this method will throw an 509 * exception if an attempt is made to define a meta-property value already 510 * being defined by this proxy. 511 * <p style="padding-left:47"> 512 * If a client wants to use this method to update an existing meta-property 513 * entry within a proxy, that existing meta-property value must first be 514 * removed. Since the meta-properties of a property are usually tightly 515 * coupled, they cannot be removed independently. They can only be removed 516 * as a group using the javax.wvcm.forgetProperty() method. If the client 517 * wants to retain some of the existing meta-property values while updating 518 * others, it must first fetch all the existing meta-property values from 519 * the proxy (using getMetaProperties()), then remove their definitions from 520 * the proxy using forgetProperty(), and then redefine the individual 521 * meta-property entries via multiple invocations of this method, reusing 522 * the old values or computing new values in a manner appropriate to the 523 * client's needs. 524 * <p style="padding-left:47;text-indent:-47"> 525 * Note 2: Because of its role in the definition of Resource.equals() and 526 * Resource.hashCode(), the Resource.RESOURCE_IDENTIFIER property may only 527 * be initialized at the time of proxy construction; e.g., via 528 * Provider.buildProxy(). 529 * <p style="padding-left:47;text-indent:-47"> 530 * Note 3: A property value set by any of the setXXX methods defined by this 531 * interface (or any of its extensions) will activate the writing of that 532 * value to the repository by the next doXYZ method. Use of initProperty to 533 * set any of the meta-properties of such a property will fail until the 534 * property is successfully written to the repository. 535 * <p style="padding-left:47;text-indent:-47"> 536 * Note 4: If the entry in this proxy for the given PropertyName indicates 537 * that an error occurred on the last attempt to read the property from the 538 * repository, initMetaProperty will fail as if the meta-property being set 539 * were already defined; i.e. it will throw an exception. In this case, the 540 * client must execute forgetProperty() on the invalid entry before 541 * attempting to initialize any of its meta-properties. 542 * 543 * @param propertyName The PropertyName for the property whose meta-property 544 * is to be defined by the proxy. Must not be <b>null</b>, must 545 * not be equal to Resource.RESOURCE_IDENTIFIER, and must not be 546 * a PropertyName currently on the 547 * {@link javax.wvcm.Resource#updatedPropertyNameList()}. 548 * @param metaPropertyName The MetaPropertyName for the meta-property whose 549 * value is to be defined by the proxy. Must not be <b>null</b> 550 * and must not name a meta-property whose value is already 551 * defined by this proxy. 552 * @param value The initial value for the meta-property identified by the 553 * other two arguments of this method. May be <b>null</b>. 554 * @throws WvcmException If the meta-property is already defined by this 555 * proxy. 556 * 557 * @see StpProvider#buildProxy(StpLocation, String, String) 558 * @see javax.wvcm.Resource#forgetProperty(javax.wvcm.PropertyNameList.PropertyName) 559 */ 560 <T> void initMetaProperty(PropertyName<?> propertyName, 561 MetaPropertyName<T> metaPropertyName, 562 T value) throws WvcmException; 563 564 /** 565 * Returns an identifier that may be passed to StpProvider.buildProxy() to 566 * construct a proxy that supports the same interfaces as this proxy. 567 * 568 * @return A String object containing the proxy class information; will 569 * never be <b>null</b>. 570 */ 571 String proxyType(); 572 573 /** 574 * An annotation used on property getters or setters of a proxy interface to 575 * indicate that a property defined in a super interface is not supported by 576 * that proxy. 577 */ 578 @Retention(RetentionPolicy.RUNTIME) 579 @Target(ElementType.METHOD) 580 public @interface UnsupportedProperty { 581 /** 582 * @return The StpReasonCode of the StpException that will be thrown if 583 * the annotated method is used. 584 */ 585 StpException.StpReasonCode value(); 586 } 587}