001/*
002 * file CqRecord.java
003 *
004 * IBM and/or HCL Confidential
005 * OCO Source Materials
006 * (C) Copyright IBM Corp. 2006, 2011. All Rights Reserved.
007 * (C) Copyright HCL Technologies Ltd. 2016, 2018.  All Rights Reserved.
008 *
009 * com.ibm.rational.wvcm.stp.cq.CqRecord
010 *
011 * (C) Copyright IBM Corporation 2004, 2011.  All Rights Reserved.
012 * Note to U.S. Government Users Restricted Rights:  Use, duplication or 
013 * disclosure restricted by GSA ADP  Schedule Contract with IBM Corp.
014 */
015
016package com.ibm.rational.wvcm.stp.cq;
017import static com.ibm.rational.wvcm.stpex.StpExBase.PROPERTY_NAMESPACE;
018
019import java.util.Date;
020import java.util.List;
021
022import javax.wvcm.Feedback;
023import javax.wvcm.PropertyNameList;
024import javax.wvcm.PropertyNameList.PropertyName;
025import javax.wvcm.ResourceList;
026import javax.wvcm.WvcmException;
027
028import com.ibm.rational.wvcm.stp.StpActivity;
029import com.ibm.rational.wvcm.stp.StpErrorMessageException;
030import com.ibm.rational.wvcm.stp.StpProperty;
031import com.ibm.rational.wvcm.stp.StpResource;
032import com.ibm.rational.wvcm.stpex.StpExBase;
033import com.ibm.rational.wvcm.stpex.StpExEnumeration;
034
035/**
036 * A CqRecord resource proxy provides access to a record in a database, possibly
037 * through its change context.
038 * 
039 * <p>
040 * To ensure the integrity of record field data, the modification of a record is
041 * a multi-step process.
042 * 
043 * <ul>
044 * <li>First, a writable copy of the record is added to the database's change
045 * context using the current field values from the database. This writable copy
046 * of the record is visible only in the provider where it was created. While it
047 * exists in the change context, it hides the record in the database as seen
048 * through the provider.
049 * <li>Field values are modified in the CqRecord proxy by the client.
050 * <li>As needed, modified field values are written to the writable copy of the
051 * record on the server. (see
052 * {@link CqContextResource#doWriteProperties(Feedback, List) doWriteProperties}.)
053 * <li>The client modifies a record or a set of records in this fashion until
054 * all have been modified and made consistent to the client's satisfaction. Then
055 * they are written back to the database is a single atomic operation. (See
056 * {@link com.ibm.rational.wvcm.stp.cq.CqUserDb#doDeliver(Feedback, List)} or
057 * {@link com.ibm.rational.wvcm.stp.cq.CqContextResource#doDeliver(Feedback)} or
058 * {@link CqContextResource#doWriteProperties(Feedback, List) doWriteProperties}.)
059 * </ul>
060 * 
061 * If these steps succeed, the client can be assured that the data written back
062 * to the record is faithfully derived from the data read from the record.
063 * 
064 * <p>
065 * If doWriteProperties is applied to a record that is not yet writable, an
066 * action must be started under which the record will be modified. If an action
067 * is not specified as the value of the ACTION property of this proxy, the
068 * default MODIFY-type action for the record is used.
069 * 
070 * <p>
071 * The fields of a record manifest themselves as properties of the record
072 * resource and thus record field values are made available to the client via
073 * the normal property request mechanism. The names, types, and other
074 * characteristics of the fields of a record are available as properties of the
075 * {@link CqFieldDefinition CqFieldDefinition} resources enumerated by the
076 * CqRecordType resource associated with the record.
077 * 
078 * <p>
079 * In addition to their value, record fields also have meta-properties such as
080 * their requiredness, their original value, and a list of their legal values.
081 * Each of these can be requested using a MetaPropertyName object in a
082 * nested PropertyRequest of the field PropertyName.
083 * <p>
084 * The user-friendly specification for the location of a record has the form
085 * 
086 * <pre>
087 *  <b>cq.record:</b><i>&lt;record-type&gt;</i>/<i>&lt;record-id&gt;</i>@<i>&lt;db-set&gt;</i>/<i>&lt;user-db&gt;</i>
088 * </pre>
089 * 
090 * @see CqRecordType
091 * @see CqFieldDefinition
092 * @see CqFieldValue
093 */
094public interface CqRecord extends StpActivity, CqContextResource
095{
096    /**
097     * Defines the value of the specified property for this proxy. The
098     * PropertyName may specify a record field name, in which case the Object
099     * may be a {@link CqFieldValue CqFieldValue} structure or the actual value
100     * of the field.
101     * 
102     * @see StpResource#setProperty(PropertyNameList.PropertyName, Object)
103     */
104    <T> void setProperty(PropertyName<T> name,
105                         T value);
106
107    /**
108     * Returns the value defined by this proxy for the property specified by the
109     * given PropertyName. The PropertyName may specify a record field, in which
110     * case the Object returned is <i>not</i> a
111     * {@link CqFieldValue CqFieldValue} structure, but the actual value of the
112     * field. (Clients may use {@link #getField getField} or
113     * {@link com.ibm.rational.wvcm.stp.StpResource#getMetaProperties(javax.wvcm.PropertyNameList.PropertyName)}
114     * to obtain a CqFieldValue structure if the additional information provided
115     * by the CqFieldValue structure is needed.).
116     * 
117     * @see javax.wvcm.Resource#getProperty(javax.wvcm.PropertyNameList.PropertyName)
118     */
119    <T> T getProperty(PropertyName<T> name) throws WvcmException;
120
121    /**
122     * A CqRecordType proxy for the record-type resource that defines what kind
123     * of record this is.
124     */
125    PropertyName<CqRecordType> RECORD_TYPE =
126        new PropertyName<CqRecordType>(StpExBase.PROPERTY_NAMESPACE,
127                                       "record-type");
128
129    /**
130     * A CqRecordType proxy for the record-type resource that defines what kind
131     * of record this is.
132     * 
133     * @return A proxy for the record-type of this record is returned.
134     * 
135     * @throws WvcmException if this proxy does not define a value for the
136     *             {@link #RECORD_TYPE RECORD_TYPE} property.
137     */
138    CqRecordType getRecordType() throws WvcmException;
139
140    /**
141     * A subclass of PropertyName used for naming the record resource properties
142     * that are schema-defined fields of a ClearQuest record. Note that, as with
143     * PropertyName, the type parameter specifies the field's value type.
144     */
145    public static class FieldName<T> extends PropertyName<T>
146    {
147        /**
148         * Constructs a PropertyName designating the resource property that
149         * corresponds to a field of a ClearQuest record.
150         * 
151         * @param fieldName The schema-defined name of the record field. Must
152         *            not be null.
153         */
154        public FieldName(String fieldName)
155        {
156            super(StpExBase.FIELD_NAMESPACE, fieldName);
157        }
158    }
159
160    /**
161     * Returns the meta-property bundle of a record field defined by this proxy.
162     * Since CqFieldValue is an extension of StpProperty, this method is merely
163     * a type-specialized version of
164     * {@link StpResource#getMetaProperties(javax.wvcm.PropertyNameList.PropertyName)}.
165     * 
166     * @param fieldName The name of the desired field expressed as a FieldName
167     *            object. Cannot be <code>null</code>.
168     * 
169     * @return A CqFieldValue structure is returned containing the field
170     *         value(s) and/or attributes defined by this proxy.
171     * 
172     * @throws WvcmException If the field value denoted by the given field name
173     *             is not defined by this proxy--that is, if no field values or
174     *             attributes were requested or could not be retrieved when
175     *             requested.
176     */
177    <T> CqFieldValue<T> getFieldInfo(FieldName<T> fieldName)
178        throws WvcmException;
179
180    /**
181     * Defines a new meta-property bundle for a record field in this proxy. Only
182     * the VALUE meta-property of the CqFieldValue is written to the resource,
183     * but the TYPE meta-property is often useful to the library for
184     * interpreting the VALUE when expressed as a String image.
185     * 
186     * @param fieldName The name of the field to be updated expressed as a
187     *            FieldName object. Cannot be <code>null</code>.
188     * 
189     * @param value A CqFieldValue object containing the new field value. Must
190     *            not be <b>null</b>
191     */
192    <T> void setFieldInfo(FieldName<T> fieldName,
193                          CqFieldValue<T> value);
194
195    /**
196     * Defines in this proxy, a new value for a field of this record. The field
197     * will not be updated until this proxy is used to invoke a "do" method.
198     * 
199     * @param fieldName The name of the field whose value is to be set
200     * @param value The new value for the field expressed as a native Java
201     *            object. The String image of the value may be used.
202     */
203    void setField(String fieldName,
204                  Object value);
205
206    /**
207     * Retrieves the value of a field previously requested by an instance of
208     * FieldName having the same fieldName parameter as this method. To retrieve
209     * other meta-properties requested for the field, use
210     * {@link #getFieldInfo(com.ibm.rational.wvcm.stp.cq.CqRecord.FieldName)}.
211     * 
212     * @param fieldName The name of the field for which a value was requested.
213     * @return The value of the requested field returned by the server expressed
214     *         as a native Java object (not just its String image).
215     * @throws WvcmException If the field value was not requested or could not
216     *             be retrieved.
217     */
218    Object getField(String fieldName) throws WvcmException;
219
220    /**
221     * Creates a new record at the location specified by this proxy, initialized
222     * with the dirty properties of this proxy. The type of record created is
223     * determined by the parent location of this proxy (which must name an
224     * existing record type resource).
225     * <p>
226     * An action must be started under which the record will be created. If an
227     * action is not specified as the value of the ACTION property of this
228     * proxy, the default SUBMIT-type action for the record is used.
229     * <p>
230     * The server is permitted to modify the location as it deems fit. The proxy
231     * returned by this method is a proxy that addresses the location actually
232     * chosen by the server.
233     * 
234     * @param feedback A Feedback object requesting the properties desired from
235     *            the record created by this operation. May be <b>null</b> if
236     *            no properties are desired.
237     * 
238     * @return An CqRecord proxy for the created record. This proxy will define
239     *         the properties specified in the feedback argument.
240     * 
241     * @throws WvcmException If the record cannot be created with the given
242     *             properties.
243     */
244    CqRecord doCreateRecord(Feedback feedback) throws WvcmException;
245
246    /**
247     * Creates a new record at the location specified by this proxy, initialized
248     * with the dirty properties of this proxy. The type of record created is
249     * determined by the parent location of this proxy (which must name an
250     * existing record type resource).
251     * <p>
252     * An action must be started under which the record will be created. If an
253     * action is not specified as the value of the ACTION property of this
254     * proxy, the default SUBMIT-type action for the record is used.
255     * <p>
256     * The server is permitted to modify the location as it deems fit. The proxy
257     * returned by this method is a proxy that addresses the location actually
258     * chosen by the server.
259     * 
260     * @param feedback A Feedback object requesting the properties desired from
261     *            the record created by this operation. May be <b>null</b> if
262     *            no properties are desired.
263     * 
264     * @param deliveryOrder If {@link CqProvider#HOLD} the created record is
265     *            left in a writable state in the change context--the new record
266     *            in the change context must be delivered before the it becomes
267     *            visible to other providers. If not {@link CqProvider#HOLD},
268     *            the modified and moribund resources specified by this
269     *            parameter will be delivered to or deleted from the database in
270     *            the order indicated. To deliver all modified and moribund
271     *            resources in an arbitrary order, use
272     *            {@link CqProvider#DELIVER_ALL}. To deliver just this new
273     *            record, use {@link CqProvider#DELIVER}. Must not be <b>null</b>.
274     * @return A CqRecord proxy for the created record. This proxy will define
275     *         the properties specified in the feedback argument.
276     * 
277     * @throws WvcmException If the record cannot be created with the given
278     *             properties.
279     */
280    CqRecord doCreateRecord(Feedback feedback,
281                            List<CqContextResource> deliveryOrder)
282        throws WvcmException;
283
284    /**
285     * Executes a hook (record script) named in the NAMED_HOOK_LIST property of
286     * this record's RECORD_TYPE resource. Additionally a global hook can be
287     * executed if the global hook's name is known in advance. The impact on 
288     * the change context in which the hook is executed is essentially
289     * the same as executing 
290     * {@link com.ibm.rational.wvcm.stp.cq.CqContextResource#doWriteProperties(Feedback, List)}
291     * in that context (where the hook is in control of which properties are
292     * written).
293     * <p>
294     * As with doWriteProperties, the record need not be editable prior to
295     * invoking this method, but, unlike doWriteProperties, if it isn't editable
296     * and the hook wants to modify it, then the hook must be prepared to start
297     * an action itself to do so. An implicit Modify-type action is not
298     * automatically started for the hook (except in the case noted below).
299     * <p>
300     * If this proxy contains updated property values when this method is
301     * invoked, an attempt will be made to write those new property values to
302     * the server <i>before</i> the hook is executed. If such an update is
303     * required and this record isn't editable, it will be made editable using
304     * the default Modify-type action and the hook will be applied to that
305     * editable version of the record before delivering the changes to the
306     * database. If the property update fails, this operation fails immediately
307     * and subsequent execution of the hook will not be attempted.
308     * 
309     * @param hook A CqHook proxy for the named hook to be fired. If the client
310     *            knows the name of the hook to be fired, it should construct a
311     *            CqHook proxy at the computed location <i>record</i><code>.stpLocation().recomposeWithNamespace(Namespace.HOOK).parent().child(</code><i>hook-name</i><code>)</code>
312     *            If the client does not know the name of the hook to be fired,
313     *            a list of available hooks to choose from can be obtained from
314     *            the NAMED_HOOK_LIST property of the parent record type of this
315     *            record.
316     *            Additionally, the client can specify a global hook. If using
317     *            a global hook, the client must know the name in advance and
318     *            should construct a CqHook proxy at the computed location 
319     *            <i>record</i><code>.stpLocation().recomposeWithMods(Namespace.HOOK,</code><i>hook-name</i><code>,</code><i>null</i><code>,</code><i>null</i><code>)</code>
320     * @param parameters A String containing any parameters required by the
321     *            hook. The format and content of this parameter string is
322     *            prescribed solely by the hook, which is also responsible for
323     *            parsing it into a usable value or values.
324     * @param feedback Properties to be retrieved from the target record and/or
325     *            those records changed by the execution of the hook (and after
326     *            delivery if delivery has been requested).
327     * @param deliveryOrder Delivery of the changes made to the record will be
328     *            considered only if the hook succeeds. If this argument is
329     *            {@link CqProvider#HOLD} the modified record is left in a
330     *            writable state in the change context--the modified record must
331     *            be delivered before the changes made by the hook become
332     *            visible outside the change context. If not
333     *            {@link CqProvider#HOLD}, the modified and moribund resources
334     *            specified by this parameter will be delivered to or deleted
335     *            from the database in the order indicated. To deliver all
336     *            modified and moribund resources in an arbitrary order, use
337     *            {@link CqProvider#DELIVER_ALL}. To deliver just this modified
338     *            record, use {@link CqProvider#DELIVER}. Must not be <b>null</b>.
339     * @return A CqRecord proxy for the modified record, populated with the
340     *         resources requested by the feedback argument.
341     * @throws WvcmException if there are problems finding or executing the
342     *             named hook, writing updated properties, or starting the
343     *             implied action.
344     * @throws StpErrorMessageException if the hook returns a non-empty result
345     */
346    CqRecord doFireNamedHook(CqHook hook,
347                             String parameters,
348                             Feedback feedback,
349                             List<CqContextResource> deliveryOrder)
350        throws WvcmException, StpErrorMessageException;
351
352    /**
353     * Causes the execution of an action of type
354     * CqAction.Type.RECORD_SCRIPT_ALIAS. Such actions are defined solely by a
355     * hook script, which is executed when the action is applied to a record.
356     * When this method is called, the action is started on this record and the
357     * action's hook script is executed as the sole content of that action and
358     * then the action is committed. The impact of this operation on the change
359     * context is essentially equivalent to executing in the same context
360     * {@link com.ibm.rational.wvcm.stp.cq.CqContextResource#doWriteProperties(Feedback, List)}
361     * where the deliveryOrder argument forces an immediate delivery of the
362     * change context.
363     * <p>
364     * Because of this prescribed processing
365     * <ul>
366     * <li>This record must not be editable when this method is called so that
367     * the specified RECORD_SCRIPT_ALIAS action can be started on it.
368     * <li> This record must not contain updated property values because only
369     * the record script of the action is allowed to make modifications to the
370     * record once the action has started.
371     * <li>If the action script succeeds, delivery of the targeted record is
372     * immediate and cannot be deferred--i.e., CqProvider.HOLD <i>may not</i>
373     * be used for the delivery order list. Furthermore, the targeted record is
374     * delivered first, regardless of the content of the delivery order list.
375     * <li>If the action script fails, no delivery will be attempted and the
376     * change context will remain as it was before invoking this method.
377     * </ul>
378     * <p>
379     * Typically, schema designers have associated arbitrary executable code
380     * with a record type, represented in a GUI as a button with the display
381     * name of the record type action.
382     * 
383     * @param action A CqAction for an action of type RECORD_SCRIPT_ALIAS. This
384     *            action must be defined by the record type of this record
385     *            instance.
386     * @param feedback A Feedback object requesting the properties desired from
387     *            resources involved in this operation. May be <b>null</b> if
388     *            no properties are desired.
389     * @param deliveryOrder Upon successful execution of the action script, the
390     *            target record will be delivered to its database. Then, any
391     *            other resources specified by this argument will be delivered.
392     *            Must not be <b>null</b> and must not be CqProvider.HOLD.
393     * @return A String containing the return value computed by the hook script.
394     * @throws WvcmException if there are problems
395     *             <ul>
396     *             <li>finding the record,
397     *             <li>finding a RECORD_SCRIPT_ALIAS as specified
398     *             <li>starting the action
399     *             <li>executing the script
400     *             <li>delivering the changes to the database
401     *             </ul>
402     */
403    String doFireRecordScriptAlias(CqAction action,
404                                   Feedback feedback,
405                                   List<CqContextResource> deliveryOrder)
406        throws WvcmException;
407
408    /**
409     * Returns the date of the submit action in the record history field.
410     * 
411     * @see javax.wvcm.Resource#getCreationDate()
412     */
413    Date getCreationDate() throws WvcmException;
414
415    /**
416     * Returns the date of the last action applied to the record from its
417     * history
418     * 
419     * @see javax.wvcm.Resource#getLastModified()
420     */
421    Date getLastModified() throws WvcmException;
422
423    /**
424     * Returns the login name of the user who submitted the record
425     * 
426     * @see com.ibm.rational.wvcm.stp.StpResource#getCreatorLoginName()
427     */
428    String getCreatorLoginName() throws WvcmException;
429
430    /**
431     * The error message generated when the record, in its current state, was
432     * validated against the repository schema for compliance with its rules.
433     * This property will be empty if the record is fully compliant (which is
434     * always the case if the record is not open for edit).
435     * <p>
436     * When this property is requested for a record open for editing, the record
437     * is validated before any other properties are retrieved. Thus, all
438     * properties returned with this property reflect the state of the record
439     * after validation was attempted.
440     * <p>
441     * Before a record being edited can be delivered, it must be validated (even
442     * if no fields have been changed). Normally, validation is performed as the
443     * first phase of a delivery and any validation errors cause the delivery to
444     * be aborted. Requesting this property will force validation of the record
445     * without attempting to deliver it. The time and resources needed to 
446     * perform a record validation vary with the schema. Unless you have 
447     * specific knowledge of the target database's schema, it is best to assume
448     * that the validation process is an expensive operation and design your
449     * application to request this property only when validation is really 
450     * required.
451     * <p>
452     * If you are changing the contents of a record programmatically, you should
453     * make sure that your code provides valid data.
454     * <p>
455     * You should not attempt to parse and interpret the returned String
456     * programmatically, because the error text may change in future releases.
457     * If you want to try to correct the value in an field with incorrect
458     * values, you can use the INVALID_FIELDS property to discover which fields
459     * are invalid. The MESSAGE_TEXT meta-property of those fields will identify
460     * problems specific to the field.
461     */
462    PropertyName<String> VALIDATION_ERROR =
463        new PropertyName<String>(StpExBase.PROPERTY_NAMESPACE,
464                                 "validation-error");
465
466    /**
467     * Returns the value of the {@link #VALIDATION_ERROR VALIDATION_ERROR}
468     * property as defined by this proxy.
469     * 
470     * @return Returns a String containing the error message generated when this
471     *         record was validated against the repository schema. Will never be
472     *         <b>null</b>, but may be empty is the record field values are
473     *         fully compliant with the rules of the schema.
474     * 
475     * @throws WvcmException if this proxy does not define a value for the
476     *             {@link #VALIDATION_ERROR VALIDATION_ERROR } property.
477     */
478    String getValidationError() throws WvcmException;
479
480    /**
481     * The action under which this record is being modified; null if the record
482     * is not being modified.
483     */
484    PropertyName<CqAction> ACTION =
485        new PropertyName<CqAction>(StpExBase.PROPERTY_NAMESPACE, "action");
486
487    /**
488     * Returns the value of the {@link #ACTION ACTION} property as defined by
489     * this proxy.
490     * 
491     * @return Returns an Action proxy representing the action associated with
492     *         this record.
493     * 
494     * @throws WvcmException if this proxy does not define a value for the
495     *             {@link #ACTION ACTION} property.
496     */
497    CqAction getAction() throws WvcmException;
498
499    /**
500     * Defines a new value for the {@link #ACTION ACTION} property of this
501     * proxy. Set this value prior to invoking doWriteProperties,
502     * doCreateRecord, or doUnbindAll to specify an action other than the
503     * default action specified for those operations. If this property is not
504     * set prior to invocation of these methods, an action of the required type
505     * will be used if one is unique defined.
506     * 
507     * @param action A CqAction proxy identifying the action under which this
508     *            record is to be created, modified, or deleted. Must not be
509     *            <b>null</b>. For the update to succeed, the given action must
510     *            be on the LEGAL_ACTIONs list for this record.
511     */
512    CqRecord setAction(CqAction action);
513
514    /**
515     * The type of the action under which this record is being modified,
516     * Type.NIL if the record is not being modified
517     */
518    PropertyName<CqAction.Type> ACTION_TYPE =
519        new PropertyName<CqAction.Type>(StpExBase.PROPERTY_NAMESPACE,
520                                        "action-type");
521
522    /**
523     * Returns the value of the {@link #ACTION ACTION} property as defined by
524     * this proxy.
525     * 
526     * @return An Action.Type enumerator indicating the type of action
527     *         associated with this record.
528     * 
529     * @throws WvcmException if this proxy does not define a value for the
530     *             {@link #ACTION_TYPE ACTION_TYPE} property.
531     */
532    CqAction.Type getActionType() throws WvcmException;
533
534    /**
535     * A list of {@link CqFieldValue CqFieldValue} objects corresponding to all
536     * of the fields of this record. By default, no meta-property of any field
537     * is included in the CqFieldValue's on this list. So, essentially, the
538     * result is just a list of field property names. Using a NestedPropertyName
539     * in the PropertyRequest of this property would allow the client to request
540     * any or all meta-properties of the fields in the list.
541     * <code>
542     * new PropertyRequest(ALL_FIELD_VALUES.nest(VALUE.nest(VALUE))), 
543     * </code>
544     * for example, would request the value of each field of the record.
545     */
546    PropertyName<StpProperty.List<CqFieldValue<?>>> ALL_FIELD_VALUES =
547        new PropertyName<StpProperty.List<CqFieldValue<?>>>(PROPERTY_NAMESPACE,
548                                                            "all-field-values");
549
550    /**
551     * Returns the value of the {@link #ALL_FIELD_VALUES ALL_FIELD_VALUES}
552     * property as defined by this proxy.
553     * 
554     * @return An StpProperty.List containing a CqFieldValue instance for each
555     *         field of this record. Each CqFieldValue instance defines all of
556     *         the metadata requested from the server for the field.
557     * 
558     * @throws WvcmException if this proxy does not define a value for the
559     *             {@link #ALL_FIELD_VALUES ALL_FIELD_VALUES} property.
560     */
561    StpProperty.List<CqFieldValue<?>> getAllFieldValues() throws WvcmException;
562
563    /** The default action associated with the current state of this record. */
564    PropertyName<CqAction> DEFAULT_ACTION =
565        new PropertyName<CqAction>(StpExBase.PROPERTY_NAMESPACE,
566                                   "default-action");
567
568    /**
569     * Returns the value of the {@link #DEFAULT_ACTION DEFAULT_ACTION} property
570     * as defined by this proxy.
571     * 
572     * @return A CqAction proxy representing the default action associated with
573     *         this record in its current state. Will be null if a default
574     *         action is not defined for this record.
575     * 
576     * @throws WvcmException if this proxy does not define a value for the
577     *             {@link #DEFAULT_ACTION DEFAULT_ACTION} property.
578     */
579    CqAction getDefaultAction() throws WvcmException;
580
581    /** Whether this record has been marked as a duplicate of another record. */
582    PropertyName<Boolean> IS_DUPLICATE =
583        new PropertyName<Boolean>(StpExBase.PROPERTY_NAMESPACE, "is-duplicate");
584
585    /**
586     * Returns the value of the {@link #IS_DUPLICATE IS_DUPLICATE} property as
587     * defined by this proxy.
588     * 
589     * @return <b>true</b> if this record has been recorded as a duplicate of
590     *         another record.
591     * 
592     * @throws WvcmException if this proxy does not define a value for the
593     *             {@link #IS_DUPLICATE IS_DUPLICATE} property.
594     * 
595     * @see #getAllDuplicates()
596     * @see #getDuplicates()
597     * @see #getHasDuplicates()
598     */
599    boolean getIsDuplicate() throws WvcmException;
600
601    /**
602     * The CqRecord that is marked as the original of this duplicate record.
603     */
604    PropertyName<CqRecord> ORIGINAL =
605        new PropertyName<CqRecord>(StpExBase.PROPERTY_NAMESPACE, "original");
606
607    /**
608     * Returns the value of the {@link #ORIGINAL ORIGINAL} property as defined
609     * by this proxy.
610     * 
611     * @return A CqRecord proxy representing the record of which this is a
612     *         duplicate. Will be <b>null</b> if this record is not a
613     *         duplicate.
614     * 
615     * @throws WvcmException if this proxy does not define a value for the
616     *             {@link #ORIGINAL ORIGINAL} property.
617     */
618    CqRecord getOriginal() throws WvcmException;
619
620    /** The visible ID of this object's original record. */
621    PropertyName<String> ORIGINAL_ID =
622        new PropertyName<String>(StpExBase.PROPERTY_NAMESPACE, "original-id");
623
624    /**
625     * Returns the value of the {@link #ORIGINAL_ID ORIGINAL_ID} property as
626     * defined by this proxy.
627     * 
628     * @return A String containing the record id for the record that this record
629     *         is a duplicate of. Will be <b>null</b> if this record is not a
630     *         duplicate.
631     * 
632     * @throws WvcmException if this proxy does not define a value for the
633     *             {@link #ORIGINAL_ID ORIGINAL_ID} property.
634     */
635    String getOriginalId() throws WvcmException;
636
637    /**
638     * Whether other records have been marked as being duplicates of this record
639     */
640    PropertyName<Boolean> HAS_DUPLICATES =
641        new PropertyName<Boolean>(StpExBase.PROPERTY_NAMESPACE,
642                                  "has-duplicates");
643
644    /**
645     * Returns the value of the {@link #HAS_DUPLICATES HAS_DUPLICATES} property
646     * as defined by this proxy.
647     * 
648     * @return <b>true</b> if records have been marked as duplicates of this
649     *         record.
650     * 
651     * @throws WvcmException if this proxy does not define a value for the
652     *             {@link #HAS_DUPLICATES HAS_DUPLICATES} property.
653     * 
654     * @see #getDuplicates()
655     * @see #getAllDuplicates()
656     * @see #getIsOriginal()
657     */
658    boolean getHasDuplicates() throws WvcmException;
659
660    /**
661     * True if this record has duplicates but is not itself a duplicate (i.e.
662     * !IS_DUPLICATE & HAS_DUPLICATES)
663     */
664    PropertyName<Boolean> IS_ORIGINAL =
665        new PropertyName<Boolean>(StpExBase.PROPERTY_NAMESPACE, "is-original");
666
667    /**
668     * Returns the value of the {@link #IS_ORIGINAL IS_ORIGINAL} property as
669     * defined by this proxy.
670     * 
671     * @return <b>true</b> if this record has duplicates but is not, itself, a
672     *         duplicate of another record.
673     * 
674     * @throws WvcmException if this proxy does not define a value for the
675     *             {@link #IS_ORIGINAL IS_ORIGINAL} property.
676     */
677    boolean getIsOriginal() throws WvcmException;
678
679    /** The immediate duplicates of this record. */
680    PropertyName<ResourceList<CqRecord>> DUPLICATES =
681        new PropertyName<ResourceList<CqRecord>>(StpExBase.PROPERTY_NAMESPACE,
682                                                 "duplicates");
683
684    /**
685     * Returns the value of the {@link #DUPLICATES DUPLICATES} property as
686     * defined by this proxy.
687     * 
688     * @return A ResourceList of CqRecord proxies representing all of the
689     *         records that have been explicitly marked as a duplicate of this
690     *         record.
691     * 
692     * @throws WvcmException if this proxy does not define a value for the
693     *             {@link #DUPLICATES DUPLICATES} property.
694     * 
695     * @see #getAllDuplicates()
696     */
697    ResourceList<CqRecord> getDuplicates() throws WvcmException;
698
699    /**
700     * All of the duplicates of this record, including duplicates of duplicates,
701     * etc.
702     */
703    PropertyName<ResourceList<CqRecord>> ALL_DUPLICATES =
704        new PropertyName<ResourceList<CqRecord>>(StpExBase.PROPERTY_NAMESPACE,
705                                                 "all-duplicates");
706
707    /**
708     * Returns the value of the {@link #ALL_DUPLICATES ALL_DUPLICATES} property
709     * as defined by this proxy.
710     * 
711     * @return A ResourceList of CqRecord proxies representing all of the
712     *         records marked as duplicates of this record or (recursively) one
713     *         of its duplicates.
714     * 
715     * @throws WvcmException if this proxy does not define a value for the
716     *             {@link #ALL_DUPLICATES ALL_DUPLICATES} property.
717     */
718    ResourceList<CqRecord> getAllDuplicates() throws WvcmException;
719
720    /**
721     * A list of the fields that were modified by the on-going action applied to
722     * this record.
723     */
724    PropertyName<StpProperty.List<CqFieldValue<?>>> FIELDS_UPDATED_THIS_ACTION =
725        new PropertyName<StpProperty.List<CqFieldValue<?>>>(StpExBase.PROPERTY_NAMESPACE,
726                                                            "fields-updated-this-action");
727
728    /**
729     * Returns the value of the {@link #FIELDS_UPDATED_THIS_ACTION
730     * FIELDS_UPDATED_THIS_ACTION} property as defined by this proxy.
731     * 
732     * @return An StpProperty.List containing a CqFieldValue for each field
733     *         updated since the beginning of the current action on this record.
734     *         Each CqFieldValue defines the metadata requested when this
735     *         property was retrieved from the server.
736     * 
737     * @throws WvcmException if this proxy does not define a value for the
738     *             {@link #FIELDS_UPDATED_THIS_ACTION
739     *             FIELDS_UPDATED_THIS_ACTION} property.
740     */
741    StpProperty.List<CqFieldValue<?>> getFieldsUpdatedThisAction()
742        throws WvcmException;
743
744    /**
745     * A list of the fields that were modified under the current action since
746     * the last time this property was set.
747     * 
748     * @see #setFieldsUpdatedThisGroup()
749     */
750    PropertyName<StpProperty.List<CqFieldValue<?>>> FIELDS_UPDATED_THIS_GROUP =
751        new PropertyName<StpProperty.List<CqFieldValue<?>>>(StpExBase.PROPERTY_NAMESPACE,
752                                                            "fields-updated-this-group");
753
754    /**
755     * Returns the value of the {@link #FIELDS_UPDATED_THIS_GROUP
756     * FIELDS_UPDATED_THIS_GROUP} property as defined by this proxy.
757     * 
758     * @return An StpProperty.List containing a CqFieldValue instance for each
759     *         field updated since the last time the
760     *         {@link #FIELDS_UPDATED_THIS_GROUP} property was set.
761     * 
762     * @throws WvcmException if this proxy does not define a value for the
763     *             {@link #FIELDS_UPDATED_THIS_GROUP FIELDS_UPDATED_THIS_GROUP}
764     *             property.
765     */
766    StpProperty.List<CqFieldValue<?>> getFieldsUpdatedThisGroup()
767        throws WvcmException;
768
769    /**
770     * Clears the FIELDS_UPDATED_THIS_GROUP property. Only fields updated after
771     * this value is set will be returned by subsequent requests for the
772     * FIELDS_UPDATED_THIS_GROUP property.
773     */
774    void setFieldsUpdatedThisGroup();
775
776    /**
777     * The fields that were modified by the last field update.
778     */
779    PropertyName<StpProperty.List<CqFieldValue<?>>> FIELDS_UPDATED_THIS_SET_VALUE =
780        new PropertyName<StpProperty.List<CqFieldValue<?>>>(StpExBase.PROPERTY_NAMESPACE,
781                                                            "fields-updated-this-set-value");
782
783    /**
784     * Returns the value of the {@link #FIELDS_UPDATED_THIS_SET_VALUE
785     * FIELDS_UPDATED_THIS_SET_VALUE} property as defined by this proxy.
786     * 
787     * @return An StpProperty.List containing a CqFieldValue instance for each
788     *         field modified by the most recent client-initiated field update.
789     * 
790     * @throws WvcmException if this proxy does not define a value for the
791     *             {@link #FIELDS_UPDATED_THIS_SET_VALUE
792     *             FIELDS_UPDATED_THIS_SET_VALUE} property.
793     */
794    StpProperty.List<CqFieldValue<?>> getFieldsUpdatedThisSetValue()
795        throws WvcmException;
796
797    /**
798     * A list of the record's invalid fields.
799     */
800    PropertyName<StpProperty.List<CqFieldValue<?>>> INVALID_FIELDS =
801        new PropertyName<StpProperty.List<CqFieldValue<?>>>(StpExBase.PROPERTY_NAMESPACE,
802                                                            "invalid-fields");
803
804    /**
805     * Returns the value of the {@link #INVALID_FIELDS INVALID_FIELDS} property
806     * as defined by this proxy.
807     * 
808     * @return An StpProperty.list of CqFieldValue instances identifying the
809     *         fields of this record that are currently invalid.
810     * 
811     * @throws WvcmException if this proxy does not define a value for the
812     *             {@link #INVALID_FIELDS INVALID_FIELDS} property.
813     */
814    StpProperty.List<CqFieldValue<?>> getInvalidFields() throws WvcmException;
815
816    /**
817     * A list of the record's hidden fields.
818     */
819    PropertyName<StpProperty.List<CqFieldValue<?>>> HIDDEN_FIELDS =
820            new PropertyName<StpProperty.List<CqFieldValue<?>>>(StpExBase.PROPERTY_NAMESPACE,
821                                                                "hidden-fields");
822
823    /**
824     * Returns the value of the {@link #HIDDEN_FIELDS HIDDEN_FIELDS} property
825     * as defined by this proxy.
826     * 
827     * @return An StpProperty.list of CqFieldValue instances identifying the
828     *         fields of this record that are currently hidden.
829     * 
830     * @throws WvcmException if this proxy does not define a value for the
831     *             {@link #HIDDEN_FIELDS HIDDEN_FIELDS} property.
832     */
833    StpProperty.List<CqFieldValue<?>> getHiddenFields() throws WvcmException;
834
835    /**
836     * The Form that the UI is asking CQ Core to use.
837     */
838    PropertyName<String> VIEW_FORM_NAME =
839            new PropertyName<String>(StpExBase.PROPERTY_NAMESPACE, "view-form-name");
840
841    /**
842     * Defines a new value for the {@link #CQ_VIEW_FORM_NAME CQ_VIEW_FORM_NAME}
843     * property of this proxy.
844     * 
845     * @param master A CqReplica proxy identifying the Form that should
846     *            be used by CQ Core.
847     */
848    void setViewFormName(String formName);
849    
850    /**
851     * Returns the value of the {@link #VIEW_FORM_NAME VIEW_FORM_NAME} property
852     * as defined by this proxy.
853     * 
854     * @return A String which holds the form-name.
855     * 
856     * @throws WvcmException if this proxy does not define a value for the
857     *             {@link #VIEW_FORM_NAME VIEW_FORM_NAME} property.
858     */
859    String getViewFormName() throws WvcmException;
860
861    /**
862     * The Tab that the UI is asking CQ Core to use.
863     */
864    PropertyName<String> VIEW_TAB_NAME =
865            new PropertyName<String>(StpExBase.PROPERTY_NAMESPACE, "view-tab-name");
866
867    /**
868     * Defines a new value for the {@link #CQ_VIEW_TAB_NAME CQ_VIEW_TAB_NAME}
869     * property of this proxy.
870     * 
871     * @param master A CqReplica proxy identifying the Tab that should
872     *            be used by CQ Core.
873     */
874    void setViewTabName(String tabName);
875    
876    /**
877     * Returns the value of the {@link #VIEW_TAB_NAME VIEW_TAB_NAME} property
878     * as defined by this proxy.
879     * 
880     * @return A String which holds the tab-name.
881     * 
882     * @throws WvcmException if this proxy does not define a value for the
883     *             {@link #VIEW_TAB_NAME VIEW_TAB_NAME} property.
884     */
885    String getViewTabName() throws WvcmException;
886
887    /**
888     * The actions that can be legally applied to this record in its current
889     * state.
890     */
891    PropertyName<ResourceList<CqAction>> LEGAL_ACTIONS =
892        new PropertyName<ResourceList<CqAction>>(StpExBase.PROPERTY_NAMESPACE,
893                                                 "legal-actions");
894
895    /**
896     * Returns the value of the {@link #LEGAL_ACTIONS LEGAL_ACTIONS} property as
897     * defined by this proxy.
898     * 
899     * @return A list of CqAction proxies representing the actions that are
900     *         currently legal for this record.
901     * 
902     * @throws WvcmException if this proxy does not define a value for the
903     *             {@link #LEGAL_ACTIONS LEGAL_ACTIONS} property.
904     */
905    ResourceList<CqAction> getLegalActions() throws WvcmException;
906
907    /** The type (state-based or stateless) of the record. */
908    PropertyName<CqRecord.Class> RECORD_CLASS =
909        new PropertyName<CqRecord.Class>(StpExBase.PROPERTY_NAMESPACE,
910                                         "record-class");
911
912    /**
913     * Returns the value of the {@link #RECORD_CLASS RECORD_CLASS} property as
914     * defined by this proxy.
915     * 
916     * @return A CqRecord.Class enumeration identifying the class of this record.
917     * 
918     * @throws WvcmException if this proxy does not define a value for the
919     *             {@link #RECORD_CLASS RECORD_CLASS} property.
920     */
921    Class getRecordClass() throws WvcmException;
922
923    /**
924     * The CqAttachmentFolder resources that correspond to the fields of this
925     * record that have or may have attachments. The display name of the 
926     * attachment folder is the same as the name of the attachment field.
927     */
928    PropertyName<ResourceList<CqAttachmentFolder>> ATTACHMENT_FOLDERS =
929        new PropertyName<ResourceList<CqAttachmentFolder>>(StpExBase.PROPERTY_NAMESPACE,
930                                                           "attachment-folders");
931
932    /**
933     * Returns the value of the {@link #ATTACHMENT_FOLDERS ATTACHMENT_FOLDERS}
934     * property as defined by this proxy.
935     * 
936     * @return A ResourceList contain CqAttachmentFolder proxies identifying the
937     *         attachment folders of this record.
938     * 
939     * @throws WvcmException if this proxy does not define a value for the
940     *             {@link #ATTACHMENT_FOLDERS ATTACHMENT_FOLDERS} property.
941     */
942    ResourceList<CqAttachmentFolder> getAttachmentFolders()
943        throws WvcmException;
944
945    /**
946     * An enumeration of the possible types of records; state-based or
947     * stateless.
948     */
949    public static enum Class implements StpExEnumeration
950    {
951        /** A record type having no state table. */
952        STATELESS,
953
954        /**
955         * A record type whose records progress from state to state along
956         * prescribed paths based on the actions applied to them.
957         */
958        STATE_BASED;
959    }
960
961    /** The name of the record's current state. */
962    PropertyName<String> STATE_NAME =
963        new PropertyName<String>(StpExBase.PROPERTY_NAMESPACE, "state-name");
964
965    /**
966     * Returns the value of the {@link #STATE_NAME STATE} property as defined by
967     * this proxy.
968     * 
969     * @return A String containing the name of the state the record is currently
970     *         in.
971     * 
972     * @throws WvcmException if this proxy does not define a value for the
973     *             {@link #STATE_NAME STATE} property.
974     */
975    String getStateName() throws WvcmException;
976
977    /**
978     * The replica that has mastership of this record.
979     */
980    PropertyName<CqReplica> CQ_MASTER_REPLICA =
981        new PropertyName<CqReplica>(StpExBase.PROPERTY_NAMESPACE,
982                                    "cq-master-replica");
983
984    /**
985     * Returns the value of the {@link #CQ_MASTER_REPLICA CQ_MASTER_REPLICA}
986     * property as defined by this proxy.
987     * 
988     * @return A CqReplica proxy for the replica that has mastership of this
989     *         record
990     * 
991     * @throws WvcmException if this proxy does not define a value for the
992     *             {@link #CQ_MASTER_REPLICA CQ_MASTER_REPLICA} property.
993     */
994    CqReplica getCqMasterReplica() throws WvcmException;
995
996    /**
997     * Defines a new value for the {@link #CQ_MASTER_REPLICA CQ_MASTER_REPLICA}
998     * property of this proxy.
999     * 
1000     * @param master A CqReplica proxy identifying the replica that should
1001     *            assume mastership of this resource.
1002     */
1003    void setCqMasterReplica(CqReplica master);
1004
1005    /**
1006     * A list of all the fields that were modified by the on-going action
1007     * applied to this record. Unlike the {@link #FIELDS_UPDATED_THIS_ACTION}
1008     * property, this list includes fields modified by the hooks that ran during
1009     * start up of the action.
1010     */
1011    PropertyName<StpProperty.List<CqFieldValue<?>>> FIELDS_UPDATED_THIS_ENTIRE_ACTION =
1012        new PropertyName<StpProperty.List<CqFieldValue<?>>>(StpExBase.PROPERTY_NAMESPACE,
1013                                                            "fields-updated-this-entire-action");
1014
1015    /**
1016     * Returns the value of the
1017     * {@link #FIELDS_UPDATED_THIS_ENTIRE_ACTION FIELDS_UPDATED_THIS_ENTIRE_ACTION}
1018     * property as defined by this proxy.
1019     * 
1020     * @return An StpProperty.List containing a CqFieldValue for each field
1021     *         modified during the initialization and execution of the current
1022     *         action. Will never be <b>null</b>, but may be empty.
1023     * 
1024     * @throws WvcmException if this proxy does not define a value for the
1025     *             {@link #FIELDS_UPDATED_THIS_ENTIRE_ACTION FIELDS_UPDATED_THIS_ENTIRE_ACTION}
1026     *             property.
1027     */
1028    StpProperty.List<CqFieldValue<?>> getFieldsUpdatedThisEntireAction()
1029        throws WvcmException;
1030
1031    /**
1032     * A list of the fields of this record of
1033     * {@link CqFieldValue.ValueType#JOURNAL}
1034     */
1035    PropertyName<StpProperty.List<CqHistoryFieldValue>> HISTORY_FIELDS =
1036        new PropertyName<StpProperty.List<CqHistoryFieldValue>>(StpExBase.PROPERTY_NAMESPACE,
1037                                                                "history-fields");
1038
1039    /**
1040     * Returns the value of the {@link #HISTORY_FIELDS HISTORY_FIELDS} property
1041     * as defined by this proxy.
1042     * 
1043     * @return An StpProperty.List containing a CqFieldValue instance for each
1044     *         field of the record whose field value type is JOURNAL. Will never
1045     *         be <b>null</b>, but may be empty.
1046     * 
1047     * @throws WvcmException if this proxy does not define a value for the
1048     *             {@link #HISTORY_FIELDS HISTORY_FIELDS} property.
1049     */
1050    StpProperty.List<CqHistoryFieldValue> getHistoryFields()
1051        throws WvcmException;
1052
1053    /**
1054     * A list of the actions that the current user may apply to this record.
1055     */
1056    PropertyName<ResourceList<CqAction>> LEGAL_ACCESSIBLE_ACTIONS =
1057        new PropertyName<ResourceList<CqAction>>(StpExBase.PROPERTY_NAMESPACE,
1058                                                 "legal-accessible-actions");
1059
1060    /**
1061     * Returns the value of the
1062     * {@link #LEGAL_ACCESSIBLE_ACTIONS LEGAL_ACCESSIBLE_ACTIONS} property as
1063     * defined by this proxy.
1064     * 
1065     * @return A ResourceList of CqAction proxies enumerating the actions that
1066     *         the current user may apply to this record in its current state.
1067     *         Will never be <b>null</b>, but may be empty.
1068     * 
1069     * @throws WvcmException if this proxy does not define a value for the
1070     *             {@link #LEGAL_ACCESSIBLE_ACTIONS LEGAL_ACCESSIBLE_ACTIONS}
1071     *             property.
1072     */
1073    ResourceList<CqAction> getLegalAccessibleActions() throws WvcmException;
1074
1075    /**
1076     * The site-extension field for this record.
1077     */
1078    PropertyName<String> SITE_EXTENSION =
1079        new PropertyName<String>(StpExBase.PROPERTY_NAMESPACE, "site-extension");
1080
1081    /**
1082     * Returns the value of the {@link #SITE_EXTENSION SITE_EXTENSION} property
1083     * as defined by this proxy.
1084     * 
1085     * @return A String containing the site-extension field used for this record
1086     *         when forming its site-extended name. Will never be <b>null</b>.
1087     * 
1088     * @throws WvcmException if this proxy does not define a value for the
1089     *             {@link #SITE_EXTENSION SITE_EXTENSION} property.
1090     */
1091    String getSiteExtension() throws WvcmException;
1092
1093    /**
1094     * A list of all the records of this record type whose names differ from the
1095     * name of this record only in their site extensions.
1096     */
1097    PropertyName<ResourceList<CqRecord>> SITE_EXTENDED_NAMES =
1098        new PropertyName<ResourceList<CqRecord>>(StpExBase.PROPERTY_NAMESPACE,
1099                                                 "site-extended-names");
1100
1101    /**
1102     * Returns the value of the {@link #SITE_EXTENDED_NAMES SITE_EXTENDED_NAMES}
1103     * property as defined by this proxy.
1104     * 
1105     * @return A ResourceList containing a proxy for each CqRecord resource
1106     *         whose name differs from the name of this record only in the
1107     *         site extensions used.
1108     * 
1109     * @throws WvcmException if this proxy does not define a value for the
1110     *             {@link #SITE_EXTENDED_NAMES SITE_EXTENDED_NAMES} property.
1111     */
1112    public ResourceList<CqRecord> getSiteExtendedNames() throws WvcmException;
1113
1114    /**
1115     * The login name of the user currently holding a lock on this record ("*"
1116     * if the current user is not permitted to see user names). A zero-length
1117     * string indicates that the record is not locked. Setting this property to
1118     * the user's login-name or to a zero-length string locks or unlocks the
1119     * record, respectively.
1120     */
1121    PropertyName<String> LOCK_OWNER =
1122        new PropertyName<String>(PROPERTY_NAMESPACE, "lock-owner");
1123
1124    /**
1125     * Returns the value of the {@link #LOCK_OWNER LOCK_OWNER} property as
1126     * defined by this proxy.
1127     * 
1128     * @return A String containing the login name of the user that has a lock on
1129     *         this record ("*" if the current user is not permitted to see
1130     *         other's login names). If no user has a lock on this record, a
1131     *         zero-length String is returned.
1132     * 
1133     * @throws WvcmException if this proxy does not define a value for the
1134     *             {@link #LOCK_OWNER LOCK_OWNER} property.
1135     */
1136    String getLockOwner() throws WvcmException;
1137
1138    /**
1139     * Defines a new value for the {@link #LOCK_OWNER LOCK_OWNER} property of
1140     * this proxy.
1141     * <p>
1142     * Unlike the other writable properties of a record, updating the LOCK_OWNER
1143     * property <i>does not</i> require that an action be started or be in
1144     * progress. And if an action is started or is in progress, the record is
1145     * locked immediately and will remain locked only until the action is
1146     * delivered or reverted.
1147     * 
1148     * @param owner Either a zero-length String or a String containing the login
1149     *            name of the current user. Setting the value to a zero-length
1150     *            String will unlock the record. Setting a non-zero length value
1151     *            will lock the record.
1152     * 
1153     * @return This proxy.
1154     */
1155    CqRecord setLockOwner(String owner);
1156}