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 }