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