001/*
002 * file CqContextResource.java
003 *
004 * Licensed Materials - Property of IBM
005 * Restricted Materials of IBM 
006 *
007 * com.ibm.rational.wvcm.stp.cq.CqContextResource
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 */
013package com.ibm.rational.wvcm.stp.cq;
014
015import java.util.List;
016
017import javax.wvcm.Feedback;
018import javax.wvcm.Resource;
019import javax.wvcm.WvcmException;
020import javax.wvcm.PropertyNameList.PropertyName;
021
022import com.ibm.rational.wvcm.stp.cq.CqProvider;
023import com.ibm.rational.wvcm.stpex.StpExBase;
024import com.ibm.rational.wvcm.stp.StpException;
025import com.ibm.rational.wvcm.stp.StpResource;
026
027
028/**
029 * A CqContextResource is a ClearQuest user database resource that may be
030 * temporarily held in a change context while it is being modified and before
031 * those modifications are committed to the database. The server maintains a
032 * separate and private change context for each database a client is logged
033 * into. The new and modified resources in the change context are visible only
034 * to the client and to the hooks the client fires and will not be visible to
035 * other clients of the database until the resources in the change context are
036 * delivered to the database.
037 * 
038 * <p>
039 * The process of modifying context resources involves three steps:
040 * </p>
041 * 
042 * <ul>
043 * <li><b>Initiate:</b> A new context resource is created, one or more
044 * properties of an existing context resource are updated, or an existing
045 * context resource is deleted. For records and attachments, this initial step
046 * requires the specification of an action to be used, thus declaring the
047 * business rules to be followed in making the modifications.</li>
048 * <li><b>Modify:</b> Modifications are made to the copy of the resource in
049 * the change context. As changes are written to the server they are verified on
050 * the server according to the business rules of the schema. Note that moribund
051 * resources (resources in the change context that have been deleted) cannot be
052 * modified.</li>
053 * <li><b>Deliver:</b> When all resource modifications have been completed,
054 * the modified resources are delivered to the user database to make changes
055 * permanent.</li>
056 * </ul>
057 * 
058 * <p>
059 * This modification process allows the client to work with its user to make
060 * coordinated changes to multiple resources, with the option of altering or
061 * abandoning at any time changes to any of the resources involved. In its full
062 * generality, this modification process could involve three or more
063 * interactions with the server, but for simple cases, the API allows the steps
064 * to be combined such that most modifications can be completed in only one
065 * interaction with the server.
066 * </p>
067 * 
068 * <p>
069 * Once a modification has been initiated by a client for a user, changes made
070 * to the resources involved are not visible to other users or clients until the
071 * modifications are delivered to the user database. The changes (including
072 * creation and deletion) are confined to the change context used and visible
073 * only through proxies obtained from the provider that made the changes.
074 * </p>
075 * 
076 * <p>
077 * The precise locking semantics of this modification process depend on the type
078 * of resource being modified. The only guarantee is that if an
079 * initiate-modify-deliver sequence is successfully completed by a client, the
080 * resources modified did not change in the database while they were being
081 * modified by that client.
082 * </p>
083 * 
084 * <p>
085 * When the modification of a resource is initiated, a writable version of the
086 * resource is created in the change context associated with the proxy used.
087 * Unless the resource is being created, the properties of the original resource
088 * are subsequently copied to this new version. Subsequent operations targeting
089 * the original resource through a proxy from the same provider will be
090 * redirected to operate on the version cached by the change context.
091 * </p>
092 * 
093 * <p>
094 * The delivery of modified resources from a change context to the database is
095 * controlled by the delivery order list parameter of any "do" method designed
096 * to operate on change context resources. Such "do" methods are specified in
097 * this interface and its extensions. See also
098 * {@link CqUserDb#doDeliver(Feedback, List)}.
099 * <p>
100 * The delivery order list parameter specifies which resources are to be
101 * delivered after successful completion of the operation. The resources are
102 * delivered in the order in which they appear in the delivery order list.
103 * Unique delivery order list values are defined by {@link CqProvider}} for
104 * specifying the delivery of the entire change context or just the resources
105 * modified by the current operation.
106 * </p>
107 * <p>
108 * Modifications (creations or deletions) initiated in a change context can be
109 * abandoned before they are delivered by removing the modified resource from
110 * the change context. "do" methods are defined for clearing the entire change
111 * context ({@link CqUserDb#doClearContext(Feedback)}, reverting any
112 * individual resource ({@link #doRevert(Feedback)} or reverting a list of
113 * resources ({@link CqUserDb#doRevert(Feedback, List)}.
114 * </p>
115 * <p>
116 * The {@link #doWriteProperties(Feedback, List)} and
117 * {@link #doUnbindAll(Feedback, List)} methods in this interface overload
118 * methods defined by the WVCM standard. If the standard methods are applied to
119 * a context resource, they behave as if the {@link CqProvider#AUTO} delivery
120 * order list was used in the extended method. If the targeted context resource
121 * is not yet in the change context, {@link CqProvider#AUTO} behaves like the
122 * {@link CqProvider#DELIVER}, causing any changes made by the method to be
123 * immediately delivered from the change context. If the targeted resource is
124 * already in the change context, {@link CqProvider#AUTO} behaves like
125 * {@link CqProvider#HOLD}, leaving the modified resource still in the change
126 * context. Since the generic WVCM client would not be aware of the change
127 * context, it looks to the WVCM client as if doWriteProperties is simply
128 * writing properties directly to the resource on the server.
129 * </p>
130 * 
131 * @see CqUserDb#doClearContext(Feedback)
132 * @see CqUserDb#doDeliver(Feedback, List)
133 * @see CqUserDb#doRevert(Feedback, List)
134 * @see CqUserDb#getModifiedResourcesList()
135 * @see CqUserDb#getMoribundResourcesList()
136 * @see CqProvider#HOLD
137 * @see CqProvider#DELIVER
138 * @see CqProvider#DELIVER_ALL
139 * @see CqProvider#AUTO
140 * 
141 */
142public interface CqContextResource extends CqUserDbMember
143{
144    /**
145     * Attempts to deliver this resource to the database.
146     * 
147     * @param feedback A request for the properties of this resource that are to
148     *            be included in the proxy returned by this operation.
149     * @return A proxy for the delivered resource populated with the requested
150     *         properties.
151     * @throws WvcmException if this resource has no modifications to deliver to
152     *             the database or if any of the modifications are invalid.
153     */
154    CqContextResource doDeliver(Feedback feedback) throws WvcmException;
155    
156    /**
157     * Removes the modified or moribund resource referenced by this proxy from
158     * the client's change context, thereby revealing at that location the
159     * resource, if any, in the database. This is <i>not</i> an undo operation
160     * applied only to the most recent modification of the resource. If removes
161     * <i>all</i> modifications made to the resource since it was last
162     * delivered to the database.
163     * <p>
164     * Note: other resources in the change context, even though initiated by
165     * changes to this resource, are not removed from the change context by this
166     * operation.
167     * <P>
168     * Since the target of this operation is being removed it makes little sense
169     * to write dirty properties to that resource before it is removed.
170     * Consequently, any dirty properties in the proxy are ignored.
171     * 
172     * @param feedback A Feedback object requesting property values from the
173     *            resource after the resource has been reverted. May be <b>null</b>
174     *            if no properties are desired.
175     * @return A proxy for the resource made visible after removing the modified
176     *         or moribund resource from the change context. Will be <b>null</b>
177     *         if no such resource exists.
178     * 
179     * @throws WvcmException if the resource was not writable or if there were
180     *             problems reverting it.
181     */
182    CqContextResource doRevert(Feedback feedback)
183        throws WvcmException;
184
185    /**
186     * Writes dirty properties from this proxy to the targeted context resource
187     * using implicitly {@link CqProvider#AUTO} as the delivery order list value.
188     * <p>
189     * This method is intended primarily for the use of generic WVCM clients,
190     * who have no knowledge of change contexts and their semantics and would
191     * expect context resources to behave simply as non-versioned resources. The
192     * net impact of this operation on the change context is nil; it will
193     * neither add new resources to the change context nor remove existing
194     * resources from the change context.
195     * <p>
196     * If the resource to be modified is not in the change context prior to
197     * calling this method, then the modified resource is immediately written
198     * back to the database when the property update succeeds and is removed
199     * from the change context when the update fails.
200     * <p>
201     * If the resource is already modified in the change context, then the
202     * resource remains in the change context after the operation whether the
203     * property update succeeds or fails.
204     * <p>
205     * If this proxy contains no dirty properties, no action is started, and no
206     * delivery takes place. If, in addition, the PropertyRequest for the result
207     * proxy provided by the feedback argument is null, no interaction with the
208     * server is initiated and, hence, the proxy location is not verified. A
209     * non-null (but possibly empty) PropertyRequest for the result proxy will
210     * force a server interaction and verification of the proxy location.
211     * 
212     * @return A proxy for this resource (after delivery if a delivery happens)
213     *         populated with the properties requested by the Feedback object
214     *         for the result.
215     * 
216     * @throws WvcmException If there are errors when attempting update
217     *             properties or deliver the resource back to the database.
218     */
219    Resource doWriteProperties(Feedback feedback)
220        throws WvcmException;
221
222    /**
223     * Writes dirty properties to the change context-copy of this resource and,
224     * optionally, requests that modified or moribund resources in the change
225     * context be delivered to or deleted from the database.
226     * <p>
227     * If the change context does not already have a copy of this resource, one
228     * is created in the change context. If an action is required and one is not
229     * specified by a {@link CqRecord#ACTION} property value in this proxy, a
230     * MODIFY-type action is started if one is uniquely defined for the
231     * resource.
232     * <p>
233     * Updated properties are not written back to the database until delivery of
234     * those changes to the database is requested by the client through the use
235     * of a delivery order list parameter or invocation of a doDeliver method.
236     * <p>
237     * If this proxy contains no dirty properties, no action is started and the
238     * state of the resource in the change context is not modified. If, in
239     * addition, the PropertyRequest for the result proxy provided by the
240     * feedback argument is <b>null</b> and also not delivery is requested, no
241     * interaction with the server is initiated and, hence, the proxy location
242     * is not verified.
243     * <p>
244     * A non-null (but possibly empty) PropertyRequest for the result proxy will
245     * force a server interaction and verification of the proxy location, even
246     * if the proxy contains no dirty properties and no delivery is indicated.
247     * 
248     * @param feedback An instance of Feedback requesting properties for this
249     *            resource and for the resources delivered by this operation.
250     *            May be <b>null</b> if no feedback is desired.
251     * 
252     * @param deliveryOrder If {@link CqProvider#HOLD} the modified resource is
253     *            left in a writable state in the change context--the modified
254     *            resource in the change context must be delivered before the
255     *            modifications become visible to other providers. If not
256     *            {@link CqProvider#HOLD}, the modified and moribund resources
257     *            specified by this parameter will be delivered to or deleted
258     *            from the database in the order indicated. To deliver all
259     *            modified and moribund resources in an arbitrary order, use
260     *            {@link CqProvider#DELIVER_ALL}. To deliver just this modified
261     *            resource, use {@link CqProvider#DELIVER}. Must not be <b>null</b>.
262     * @return A proxy for this resource populated with the properties requested
263     *         by the Feedback object for the result. The properties reflect the
264     *         state of the resource after delivery if delivery has been
265     *         requested.
266     * 
267     * @throws WvcmException If there are errors when attempting to write
268     *             properties or deliver the resource.
269     */
270    CqContextResource doWriteProperties(Feedback feedback,
271                                        List<CqContextResource> deliveryOrder)
272        throws WvcmException;
273
274    /**
275     * Initiates the deletion of this context resource from the database using
276     * implicitly {@link CqProvider#AUTO} as the delivery order list value.
277     * The deletion of the resource becomes permanent and visible to other
278     * proxies only after this deletion has been delivered. Prior to delivery,
279     * the deletion of the resource may be canceled by executing
280     * {@link #doRevert(Feedback)} on the resource.
281     * <p>
282     * This method is intended primarily for the use of generic WVCM clients,
283     * who have no knowledge of change contexts and their semantics and would
284     * expect context resources to behave simply as non-versioned resources. The
285     * net impact of this operation on the change context is nil; it will
286     * neither add new resources to the change context nor remove existing
287     * resources from the change context.
288     * <p>
289     * Between the time a resource is deleted and that deletion becomes
290     * permanent, the resource is said to be <i>moribund</i> (near death). A
291     * moribund resource can be targeted only by a {@link #doDeliver(Feedback)}
292     * or {@link #doRevert(Feedback)} operation. Any other method targeted to a
293     * moribund resource will throw a RESOURCE_NOT_FOUND exception. Moribund
294     * resources may also appear in a delivery order list parameter.
295     * <p>
296     * If an action must be started to perform the deletion, another action must
297     * not already be active on this resource. If no action is specified by a
298     * {@link CqRecord#ACTION} property value in this proxy and a DELETE-type
299     * action is not uniquely defined for this type of resource an
300     * {@link com.ibm.rational.wvcm.stp.StpException.StpReasonCode#UNKNOWN_ACTION} exception is thrown.
301     * <p>
302     * If the resource was not in the change context when this method was
303     * invoked, the deletion becomes permanent immediately--before the method
304     * returns. If it was already in the change context, however, then no
305     * delivery is attempted and delivery will have to be requested directly to
306     * complete the deletion.
307     * 
308     * @throws WvcmException If the resource does not exist or cannot be deleted
309     *             using the default DELETE action.
310     * 
311     * @see StpResource#doUnbindAll(Feedback)
312     */
313    void doUnbindAll(Feedback feedback)
314        throws WvcmException;
315
316    /**
317     * Initiates the deletion of this context resource from the database. The
318     * deletion of the resource becomes permanent and visible to other proxies
319     * only after this deletion has been delivered. Prior to delivery, the
320     * deletion of the resource may be canceled by executing
321     * {@link #doRevert(Feedback)} on the resource.
322     * <p>
323     * Between the time a resource is deleted and that deletion becomes
324     * permanent, the resource is said to be <i>moribund</i> (near death). A
325     * moribund resource can be accessed only by a {@link #doDeliver(Feedback)}
326     * or {@link #doRevert(Feedback)} operation. Any other method will throw a
327     * RESOURCE_NOT_FOUND exception.
328     * <p>
329     * If an action must be started to perform the deletion, another action must
330     * not already be active on this resource. If no action is specified by a
331     * {@link CqRecord#ACTION} property value in this proxy and a DELETE-type
332     * action is not uniquely defined for this type of resource an
333     * {@link com.ibm.rational.wvcm.stp.StpException.StpReasonCode#UNKNOWN_ACTION} exception is thrown.
334     * <p>
335     * The disposition of the change context after the deletion succeeds is
336     * controlled by the deliveryOrder parameter
337     * </p>
338     * 
339     * @param feedback A Feedback object requesting the properties desired from
340     *            resources modified during this operation. May be null if no
341     *            properties are desired.
342     * @param deliveryOrder If {@link CqProvider#HOLD} the moribund resource is
343     *            left in the change context and not actually deleted--it must
344     *            be delivered before the deletion becomes visible to other
345     *            providers. If not {@link CqProvider#HOLD}, the modified and
346     *            moribund resources specified by this parameter will be
347     *            delivered to or deleted from the database in the order
348     *            indicated. To deliver all modified and moribund resources in
349     *            an arbitrary order, use {@link CqProvider#DELIVER_ALL}. To
350     *            deliver just this moribund resource, use
351     *            {@link CqProvider#DELIVER}. Must not be <b>null</b>.
352     * 
353     * @throws WvcmException If the resource does not exist or cannot be deleted
354     *             using the default DELETE action.
355     * 
356     * @see StpResource#doUnbindAll(Feedback)
357     */
358    void doUnbindAll(Feedback feedback, 
359                     List<CqContextResource> deliveryOrder)
360        throws WvcmException;
361   
362    /**
363     * True if a modified copy of this resource exists in this clients database
364     * change context.
365     */
366    PropertyName<Boolean> IS_MODIFIED =
367        new PropertyName<Boolean>(StpExBase.PROPERTY_NAMESPACE, "is-modified" /*NOI18N*/);
368
369    /**
370     * Returns the value of the {@link #IS_MODIFIED IS_MODIFIED} property as
371     * defined by this proxy.
372     * 
373     * @return <b>true</b> if this proxy refers to a resource whose properties
374     *         were modified in this client's change context; otherwise <b>false</b>.
375     * 
376     * @throws WvcmException if this proxy does not define a value for the
377     *             {@link #IS_MODIFIED IS_MODIFIED} property.
378     */
379    boolean getIsModified()
380        throws WvcmException;
381}