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, 2008. 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 * Returns the StpPropertyException that would be thrown by getProperty if 158 * it were called with the given PropertyName. 159 * 160 * <p> 161 * If there was an error retrieving the property when requested, or the 162 * property was never defined in the proxy, an {@link StpPropertyException} 163 * is returned; otherwise <b>null</b> is returned. 164 * 165 * @param propertyName The property for which an exception is desired. 166 * Cannot be <b>null</b>. 167 * 168 * @return The exception that would be thrown by getProperty() if it were 169 * used to access the given <code>propertyName</code>; Will be 170 * <b> null</b> if no exception would be thrown. 171 */ 172 StpException getPropertyException(PropertyName<?> propertyName); 173 174 /** 175 * The most human-readable location for a resource. This is the form of 176 * location that clients should show to users when a precise location must 177 * be displayed--e.g. one which the user must remember and re-enter in a 178 * subsequent session. When such precision is not needed, the 179 * {@link javax.wvcm.Resource#DISPLAY_NAME} property would be a better 180 * choice for the presentation. 181 * <p> 182 * The USER_FRIENDLY_LOCATION is <i>usually</i> expressed by a 183 * user-friendly-selector scheme location, but other location schemes may 184 * also be used depending on the type of resource. 185 * <p> 186 * The value of this property is <i>not</i> always defined for every 187 * resource. If a resource does not have a USER_FRIENDLY_LOCATION, that is a 188 * strong indication that that resource should not be part of the normal 189 * object model presented to the user. If not defined, the value will be an 190 * empty string. 191 * <p> 192 * Note that the location used by a proxy returned by the server is 193 * formatted to provide the most efficient access to the resource in 194 * subsequent interactions with the server in the current session. That 195 * location is not necessarily the same as the resource's 196 * USER_FRIENDLY_LOCATION or its STABLE_LOCATION. 197 * 198 * @see #STABLE_LOCATION 199 * @see #EFFICIENT_LOCATION 200 */ 201 PropertyName<StpLocation> USER_FRIENDLY_LOCATION = 202 new PropertyName<StpLocation>(PROPERTY_NAMESPACE, 203 "user-friendly-location"); 204 205 /** 206 * Returns the value of the 207 * {@link #USER_FRIENDLY_LOCATION USER_FRIENDLY_LOCATION} property as 208 * defined by this proxy. 209 * 210 * @return The StpLocation value. Will never be <b>null</b>. 211 * 212 * @throws WvcmException if this proxy does not define a value for the 213 * {@link #USER_FRIENDLY_LOCATION USER_FRIENDLY_LOCATION} 214 * property. 215 */ 216 StpLocation getUserFriendlyLocation() throws WvcmException; 217 218 /** 219 * The most stable (over space and time) location available for this 220 * resource. Clients should use this form of location when archiving 221 * resource references for use between sessions. 222 * <p> 223 * The stable location is <i>usually</i> expressed by a repo-selector 224 * scheme location, but other location schemes may also be used depending on 225 * the type of resource. 226 * <p> 227 * The value of this property is always defined for every resource, but, in 228 * fact, <i>it may not be stable</i>. But, if the resource has a stable 229 * location, that location will be returned by this property. 230 * <p> 231 * The value returned always represents the identifier associated with the 232 * server state of the resource, even if the Resource on which it is 233 * requested has client-side state. 234 * <p> 235 * Note that the location used by a proxy returned by the server is 236 * formatted to provide the <i>most efficient</i> access to the resource in 237 * subsequent interactions with the server in the current session. That 238 * location is not necessarily the same as the resource's 239 * USER_FRIENDLY_LOCATION or its STABLE_LOCATION. 240 * 241 * @see #USER_FRIENDLY_LOCATION 242 * @see #EFFICIENT_LOCATION 243 */ 244 PropertyName<StpLocation> STABLE_LOCATION = 245 new PropertyName<StpLocation>(PROPERTY_NAMESPACE, "stable-location"); 246 247 /** 248 * Returns the value of the {@link #STABLE_LOCATION STABLE_LOCATION} 249 * property as defined by this proxy. 250 * 251 * @return The StpLocation value. Will never be <b>null</b>. 252 * 253 * @throws WvcmException if this proxy does not define a value for the 254 * {@link #STABLE_LOCATION STABLE_LOCATION} property. 255 */ 256 StpLocation getStableLocation() throws WvcmException; 257 258 /** 259 * The most efficient location available for this resource. Clients should 260 * use this form of location when it is not necessary to either show this 261 * location to users, nor to archive resource references for use between 262 * sessions. 263 * <p> 264 * The efficient location is <i>usually</i> expressed by a repo-selector 265 * scheme location, but other location schemes may also be used depending on 266 * the type of resource. 267 * <p> 268 * The value of this property is always defined for every resource, but, in 269 * fact, <i>it may not be more efficient than the other forms</i>. But, if 270 * the resource has an efficient location, that location will be returned by 271 * this property. 272 * <p> 273 * The value returned always represents the identifier associated with the 274 * server state of the resource, even if the Resource on which it is 275 * requested has client-side state. 276 * <p> 277 * This is the location format usually used in the proxies returned from the 278 * server. 279 * 280 * @see #USER_FRIENDLY_LOCATION 281 * @see #STABLE_LOCATION 282 */ 283 PropertyName<StpLocation> EFFICIENT_LOCATION = 284 new PropertyName<StpLocation>(PROPERTY_NAMESPACE, "efficient-location"); 285 286 /** 287 * Returns the value of the {@link #EFFICIENT_LOCATION EFFICIENT_LOCATION} 288 * property as defined by this proxy. 289 * 290 * @return The StpLocation value for the resources most efficient location. 291 * Will never be <b>null</b>. 292 * 293 * @throws WvcmException if this proxy does not define a value for the 294 * {@link #EFFICIENT_LOCATION EFFICIENT_LOCATION} property. 295 */ 296 StpLocation getEfficientLocation() throws WvcmException; 297 298 /** 299 * Note: the {@link #RESOURCE_IDENTIFIER} property is defined only for 300 * server resources (it's undefined for uncontrolled controllable resources) 301 * and it's value is not available locally via 302 * ControllableResource.readProperties(). 303 * 304 * @see javax.wvcm.Resource#getResourceIdentifier() 305 * @see javax.wvcm.Resource#RESOURCE_IDENTIFIER 306 */ 307 public String getResourceIdentifier() throws WvcmException; 308 309 /** 310 * The authentication realm in which this resource resides. When credentials 311 * are needed to access this resource this is string that should be 312 * presented to the user to identify what the user is to provide credentials 313 * for. 314 */ 315 PropertyName<String> AUTHENTICATION_REALM = 316 new PropertyName<String>(PROPERTY_NAMESPACE, "authentication-realm"); 317 318 /** 319 * Returns the value of the {@link #AUTHENTICATION_REALM 320 * AUTHENTICATION_REALM} property as defined by this proxy. 321 * 322 * @return A String containing the realm identifier passed to the 323 * authentication callback when accessing this resource. 324 * 325 * @throws WvcmException if this proxy does not define a value for the 326 * {@link #AUTHENTICATION_REALM AUTHENTICATION_REALM} property. 327 */ 328 String getAuthenticationRealm() throws WvcmException; 329 330 /** A list of the properties that are currently invalid for this resource */ 331 PropertyName<StpProperty.List<StpProperty<?>>> INVALID_PROPERTIES = 332 new PropertyName<StpProperty.List<StpProperty<?>>>(PROPERTY_NAMESPACE, 333 "invalid-properties"); 334 335 /** 336 * Returns the value of the {@link #INVALID_PROPERTIES INVALID_PROPERTIES} 337 * property as defined by this proxy. 338 * 339 * @return A Property.List of Property objects, each identifying one invalid 340 * property of this Resource 341 * 342 * @throws WvcmException if this proxy does not define a value for the 343 * {@link #INVALID_PROPERTIES INVALID_PROPERTIES} property. 344 */ 345 StpProperty.List<StpProperty<?>> getInvalidProperties() 346 throws WvcmException; 347 348 /** 349 * A list of all the properties that are defined on this resource. The 350 * returned properties can be retrieved as a list using getAllProperties() 351 * or individually, using 352 * {@link javax.wvcm.Resource#getProperty(javax.wvcm.PropertyNameList.PropertyName) getProperty} or an 353 * appropriate getter method. 354 */ 355 PropertyName<StpProperty.List<StpProperty<?>>> ALL_PROPERTIES = 356 new PropertyName<StpProperty.List<StpProperty<?>>>(StpExBase.PROPERTY_NAMESPACE, 357 "all-properties"); 358 359 /** 360 * Returns the properties defined in this proxy. Note, this "getter" will 361 * work even if ALL_PROPERTIES was not explicitly requested when building 362 * the proxy. 363 * 364 * @return An StpProperty.List containing a Property object for each 365 * property defined by this proxy. If there were errors in 366 * retrieving any meta-properties (including the VALUE 367 * meta-property), these errors can be discovered through the 368 * StpProperty interface. 369 */ 370 StpProperty.List<StpProperty<?>> getAllProperties(); 371 372 /** 373 * Returns the custom properties recorded in this proxy. Note, this "getter" 374 * will work even if ALL_CUSTOM_PROPERTIES was not explicitly requested when 375 * building the proxy. 376 * 377 * @return A Property.List containing a Property object for each custom 378 * (i.e. not defined by WVCM) property defined by this proxy. If 379 * there were errors in retrieving any meta-properties (including 380 * the VALUE meta-property), these errors can be discovered through 381 * the Property interface. 382 */ 383 StpProperty.List<StpProperty<?>> getCustomProperties(); 384 385 /** The StpRepository that contains this resource. */ 386 PropertyName<StpRepository> REPOSITORY = 387 new PropertyName<StpRepository>(PROPERTY_NAMESPACE, "repository"); 388 389 /** 390 * Returns the value of the {@link #REPOSITORY} property as defined by this 391 * proxy. 392 * 393 * @return The StpRepository that this resource is in. Will never be <b>null</b>. 394 * 395 * @throws WvcmException if this proxy does not define a value for the 396 * {@link #REPOSITORY} property. 397 */ 398 StpRepository getRepository() throws WvcmException; 399 400 /** 401 * The login name of the user that created this object. A request for this 402 * value can only be satisfied by a request to a server; it is not available 403 * locally. 404 */ 405 PropertyName<String> CREATOR_LOGIN_NAME = 406 new PropertyName<String>(PROPERTY_NAMESPACE, "creator-login-name"); 407 408 /** 409 * Returns the value of the {@link #CREATOR_LOGIN_NAME} property as defined 410 * by this proxy. 411 * 412 * @throws WvcmException Thrown if the property was never requested, or 413 * otherwise unavailable (e.g. requested in a client-context 414 * only). 415 */ 416 String getCreatorLoginName() throws WvcmException; 417 418 /** 419 * The group name of the user that created an object. This value can only be 420 * satisfied by a request to the server; it is not available locally. 421 */ 422 PropertyName<String> CREATOR_GROUP_NAME = 423 new PropertyName<String>(PROPERTY_NAMESPACE, "creator-group-name"); 424 425 /** 426 * Returns the value of the {@link #CREATOR_GROUP_NAME} property as defined 427 * by this proxy. 428 * 429 * @throws WvcmException Thrown if the property was never requested, or is 430 * otherwise unavailable (e.g. requested in a client-context 431 * only). 432 */ 433 String getCreatorGroupName() throws WvcmException; 434 435 /** 436 * Returns the Location of this proxy's Location cast as an StpLocation. 437 * 438 * @return The StpLocation for this Resource proxy. Will never be <b>null</b>. 439 */ 440 StpLocation stpLocation(); 441 442 /** 443 * Returns the value of the <i>resource error attribute</i> associated with 444 * this proxy. 445 * 446 * <p> 447 * If this attribute is not null it indicates that an error occurred when 448 * trying to access the resource addressed by this proxy (even though that 449 * address was actually generated by the server). In this case, none of the 450 * properties requested for this proxy will be defined. The value of the 451 * resource error attribute is an StpException that records the nature of 452 * the problem encountered by the server. 453 * 454 * <p> 455 * This attribute is set only when this proxy is returned as an indirect 456 * result of a server interaction. If this defective address was used by a 457 * client as the target of a server contact method or if it was the expected 458 * direct result of some server contact method, that contact method would 459 * have thrown an exception rather than setting this attribute. 460 * 461 * <p> 462 * Whenever the server returns a list of resources (either as a direct 463 * response to a request or as the value of a property) it is possible that 464 * the server can enumerate all of the members of the list but cannot 465 * actually access one or more of the enumerated members to access its 466 * properties. When this happens, the operation is not aborted and does not 467 * itself throw an exception. Instead, a proxy is generated and marked with 468 * this resource error attribute so that the problem is record and then the 469 * rest of the list is processed. 470 * 471 * @return <b>null</b> if no error is associated with the resource, 472 * otherwise a StpException describing the error. 473 */ 474 StpException getResourceError(); 475 476 /** 477 * @return Returns the StpProvider from which this proxy was obtained. 478 */ 479 StpProvider stpProvider(); 480 481 /** 482 * Sets the value of a meta-property of a property into this proxy without 483 * causing that property to be written to the resource on the next 484 * repository interaction. Like the setProperty() method, this method does 485 * not verify that the given object is a value suitable for the specified 486 * meta-property. This method also does not verify that the given 487 * PropertyName is appropriate for the type of resource represented by this 488 * proxy nor that the given MetaPropertyName is appropriate for the given 489 * PropertyName. 490 * <p> 491 * This method may be used in conjunction with 492 * {@link StpProvider#buildProxy(StpLocation, String, String) StpProvider.buildProxy()} 493 * to reconstruct proxies previously saved to persistent storage. Use 494 * buildProxy() to construct a proxy object of the appropriate type and then 495 * use this method to copy each saved meta-property value into that proxy 496 * object. 497 * <p> 498 * This method may also be used in conjunction with forgetProperty to merge 499 * meta-property values from one proxy into another and thereby facilitate 500 * the use of a proxy object as a long-lived cache for resource data. This 501 * approach is not recommended unless the client fully understands the 502 * pitfalls inherent in maintaining a cache of shared server data in a 503 * client for any length of time. 504 * <p style="padding-left:47;text-indent:-47"> 505 * Note 1: Since the primary intent of this method is to provide the client 506 * with a means to restore a proxy from archive, this method will throw an 507 * exception if an attempt is made to define a meta-property value already 508 * being defined by this proxy. 509 * <p style="padding-left:47"> 510 * If a client wants to use this method to update an existing meta-property 511 * entry within a proxy, that existing meta-property value must first be 512 * removed. Since the meta-properties of a property are usually tightly 513 * coupled, they cannot be removed independently. They can only be removed 514 * as a group using the javax.wvcm.forgetProperty() method. If the client 515 * wants to retain some of the existing meta-property values while updating 516 * others, it must first fetch all the existing meta-property values from 517 * the proxy (using getMetaProperties()), then remove their definitions from 518 * the proxy using forgetProperty(), and then redefine the individual 519 * meta-property entries via multiple invocations of this method, reusing 520 * the old values or computing new values in a manner appropriate to the 521 * client's needs. 522 * <p style="padding-left:47;text-indent:-47"> 523 * Note 2: Because of its role in the definition of Resource.equals() and 524 * Resource.hashCode(), the Resource.RESOURCE_IDENTIFIER property may only 525 * be initialized at the time of proxy construction; e.g., via 526 * Provider.buildProxy(). 527 * <p style="padding-left:47;text-indent:-47"> 528 * Note 3: A property value set by any of the setXXX methods defined by this 529 * interface (or any of its extensions) will activate the writing of that 530 * value to the repository by the next doXYZ method. Use of initProperty to 531 * set any of the meta-properties of such a property will fail until the 532 * property is successfully written to the repository. 533 * <p style="padding-left:47;text-indent:-47"> 534 * Note 4: If the entry in this proxy for the given PropertyName indicates 535 * that an error occurred on the last attempt to read the property from the 536 * repository, initMetaProperty will fail as if the meta-property being set 537 * were already defined; i.e. it will throw an exception. In this case, the 538 * client must execute forgetProperty() on the invalid entry before 539 * attempting to initialize any of its meta-properties. 540 * 541 * @param propertyName The PropertyName for the property whose meta-property 542 * is to be defined by the proxy. Must not be <b>null</b>, must 543 * not be equal to Resource.RESOURCE_IDENTIFIER, and must not be 544 * a PropertyName currently on the 545 * {@link javax.wvcm.Resource#updatedPropertyNameList()}. 546 * @param metaPropertyName The MetaPropertyName for the meta-property whose 547 * value is to be defined by the proxy. Must not be <b>null</b> 548 * and must not name a meta-property whose value is already 549 * defined by this proxy. 550 * @param value The initial value for the meta-property identified by the 551 * other two arguments of this method. May be <b>null</b>. 552 * @throws WvcmException If the meta-property is already defined by this 553 * proxy. 554 * 555 * @see StpProvider#buildProxy(StpLocation, String, String) 556 * @see javax.wvcm.Resource#forgetProperty(javax.wvcm.PropertyNameList.PropertyName) 557 */ 558 <T> void initMetaProperty(PropertyName<?> propertyName, 559 MetaPropertyName<T> metaPropertyName, 560 T value) throws WvcmException; 561 562 /** 563 * Returns an identifier that may be passed to StpProvider.buildProxy() to 564 * construct a proxy that supports the same interfaces as this proxy. 565 * 566 * @return A String object containing the proxy class information; will 567 * never be <b>null</b>. 568 */ 569 String proxyType(); 570 571 /** 572 * An annotation used on property getters or setters of a proxy interface to 573 * indicate that a property defined in a super interface is not supported by 574 * that proxy. 575 */ 576 @Retention(RetentionPolicy.RUNTIME) 577 @Target(ElementType.METHOD) 578 public @interface UnsupportedProperty { 579 /** 580 * @return The StpReasonCode of the StpException that will be thrown if 581 * the annotated method is used. 582 */ 583 StpException.StpReasonCode value(); 584 } 585 }