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    }