001 /*
002 * file CqFieldValue.java
003 *
004 * Licensed Materials - Property of IBM
005 * Restricted Materials of IBM
006 *
007 * com.ibm.rational.wvcm.stp.cq.CqFieldValue
008 *
009 * (C) Copyright IBM Corporation 2004, 2008. All Rights Reserved.
010 * Note to U.S. Government Users Restricted Rights: Use, duplication or
011 * disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
012 */
013
014 package com.ibm.rational.wvcm.stp.cq;
015
016 import static com.ibm.rational.wvcm.stpex.StpExBase.METADATA_NAMESPACE;
017
018 import java.util.EnumMap;
019
020 import javax.wvcm.WvcmException;
021
022 import com.ibm.rational.wvcm.stp.StpProperty;
023 import com.ibm.rational.wvcm.stp.cq.CqQuery.DisplayField;
024 import com.ibm.rational.wvcm.stp.cq.CqQuery.DisplayField.FieldType;
025 import com.ibm.rational.wvcm.stpex.StpExBase;
026 import com.ibm.rational.wvcm.stpex.StpExEnumeration;
027 import com.ibm.rational.wvcm.stpex.StpExEnumerationBase;
028
029
030 /**
031 * The representation for the value of a record field as an extended StpProperty
032 * object.
033 */
034 public interface CqFieldValue<T>
035 extends StpProperty<T>
036 {
037 /**
038 * An enumeration of the possible types of values that can be stored in a
039 * record field. This enumeration is more precise than the StpProperty.Type
040 * enumeration in specifying the type of a field value.
041 */
042 public enum ValueType implements StpExEnumeration
043 {
044 /** An initial value for ValueType variables */
045 UNKNOWN(Type.UNKNOWN),
046
047 /**
048 * A single-line of text up to 254 characters. Leading and trailing
049 * whitespace is trimmed when stored in a record.
050 */
051 SHORT_STRING(Type.STRING),
052
053 /**
054 * An arbitrarily long string of characters, possibly containing one or
055 * more newline characters.
056 */
057 MULTILINE_STRING(Type.STRING),
058
059 /** An integer in the range -9999999999 to 9999999999 */
060 INTEGER(Type.INTEGER),
061
062 /**
063 * A GMT date/time between 12:00:01 AM January 1, 1970 and 11:59:59 PM
064 * January 18, 2038.
065 */
066 DATE_TIME(Type.DATE_TIME),
067
068 /** A proxy for a Resource of a specific ResourceValueType. */
069 RESOURCE(Type.RESOURCE),
070
071 /** A list of proxies for a Resource of a specific ResourceValueType */
072 RESOURCE_LIST(Type.RESOURCE_LIST),
073
074 /** A floating point value */
075 FLOAT(Type.FLOAT),
076
077 /** A field containing attachments */
078 ATTACHMENT_LIST(Type.RESOURCE_LIST),
079
080 /** A record id (alphanumeric) field */
081 ID(Type.STRING),
082
083 /** A field containing the name of the record's current state */
084 STATE(Type.STRING),
085
086 /** A field recording events in the history of the record */
087 JOURNAL(Type.OBJECT),
088
089 /** A database id (integer) field */
090 DBID(Type.LONG),
091
092 /** A field containing the type of the record's current state */
093 STATE_TYPE(Type.STRING),
094
095 /** A field containing the record's record type name */
096 RECORD_TYPE(Type.STRING);
097
098 /**
099 * The StpProperty.Type that corresponds to this field type.
100 *
101 * @return An StpProperty.Type enumerator specifying as closely as
102 * possible the Java representation of this type of value
103 * corresponding
104 */
105 public Type toPropertyType()
106 {
107 return m_type;
108 }
109
110 /**
111 * Returns the ValueType that exactly matches a given PropertyType;
112 * otherwise UNKNOWN.
113 *
114 * @param type a Type enumerator
115 * @return the ValueType that exactly matches the given Type
116 * PropertyType; otherwise UNKNOWN.
117 */
118 static public ValueType fromPropertyType(Type type)
119 {
120 for (ValueType vt: values())
121 if (vt.toPropertyType() == type)
122 return vt;
123
124 return UNKNOWN;
125 }
126
127 /**
128 * The CqQuery.DisplayField.FieldType that corresponds to this field type.
129 *
130 * @return An CqQuery.DisplayField.FieldType enumerator specifying as closely as
131 * possible the Java representation of this type of value
132 * corresponding
133 */
134 public FieldType toFieldType()
135 {
136 for(FieldType ft: FieldType.values())
137 if (ft.valueType() == this)
138 return ft;
139
140 switch (m_type) {
141 case RESOURCE:
142 return FieldType.REFERENCE;
143 case STRING:
144 return FieldType.MULTILINE_STRING;
145 case OBJECT:
146 case RESOURCE_LIST:
147 return FieldType.BINARY;
148 }
149
150 return FieldType.UNKNOWN;
151 }
152
153 private ValueType(Type type)
154 {
155 m_type = type;
156 }
157
158 private Type m_type;
159 }
160
161 /**
162 * An enumeration indicating the validity of a field value.
163 */
164 public enum ValidationStatus
165 implements StpExEnumeration
166 {
167 /** The field value has been validated and found to be valid. */
168 VALID,
169
170 /** The field value has been validated and found to be invalid. */
171 INVALID,
172
173 /**
174 * The field value has not yet been validated and so it is unknown
175 * whether it is valid or not.
176 */
177 NEEDS_VALIDATION;
178 }
179
180 /**
181 * An enumeration indicating whether or not a field has a value.
182 */
183 public enum ValueStatus
184 implements StpExEnumeration
185 {
186 /** The field has a value. */
187 HAS_A_VALUE,
188
189 /** The field has no value set. */
190 HAS_NO_VALUE,
191
192 /**
193 * The current state of the field prevents it from returning a value.
194 */
195 VALUE_NOT_AVAILABLE;
196 }
197
198 /**
199 * @return the PropertyName of this CqFieldValue property as a
200 * CqRecord.FieldName
201 */
202 CqRecord.FieldName<T> getFieldName();
203
204 /** The record instance of which this field is a part. */
205 MetaPropertyName<CqRecord> RECORD =
206 new MetaPropertyName<CqRecord>(METADATA_NAMESPACE, "resource");
207
208
209 /**
210 * Returns the value of the {@link #RECORD RECORD} metadata component as
211 * defined by this Property instance.
212 *
213 * @return A Record proxy for the record of which this field is a member.
214 *
215 * @throws WvcmException if this Property instance does not define a value
216 * for the {@link #RECORD RECORD} metadata
217 * component.
218 */
219 CqRecord getRecord()
220 throws WvcmException;
221
222 /**
223 * The field definition that defines all static properties of this field.
224 */
225 MetaPropertyName<CqFieldDefinition> FIELD_DEFINITION =
226 new MetaPropertyName<CqFieldDefinition>(METADATA_NAMESPACE,
227 "field-definition");
228
229 /**
230 * Returns the value of the {@link #FIELD_DEFINITION FIELD_DEFINITION}
231 * metadata component as defined by this Property instance.
232 *
233 * @return A CqFieldDefinition proxy specifying the static properties of this
234 * field.
235 *
236 * @throws WvcmException if this Property instance does not define a value
237 * for the {@link #FIELD_DEFINITION FIELD_DEFINITION
238 * } metadata component.
239 */
240 CqFieldDefinition getFieldDefinition()
241 throws WvcmException;
242
243 /** Identifies the requiredness of the specified field. */
244 MetaPropertyName<CqFieldDefinition.Requiredness> REQUIREDNESS =
245 new MetaPropertyName<CqFieldDefinition.Requiredness>(METADATA_NAMESPACE,
246 "requiredness");
247
248 /**
249 * Returns the value of the {@link #REQUIREDNESS REQUIREDNESS} metadata
250 * component as defined by this Property instance.
251 *
252 * @return A Requiredness enumerator specifying whether this field cannot,
253 * may, or must have a value in the current state.
254 *
255 * @throws WvcmException if this Property instance does not define a value
256 * for the {@link #REQUIREDNESS REQUIREDNESS}
257 * metadata component.
258 */
259 public CqFieldDefinition.Requiredness getRequiredness()
260 throws WvcmException;
261
262 /**
263 * The current list of possible values for this field. If this list is empty
264 * and {@link CqFieldDefinition#HAS_OPEN_CHOICE_LIST} is true, it neither
265 * implies that all values are permitted nor that no values are permitted;
266 * it just means that the schema designer has not provided any hints about
267 * the values permitted in the field. On the other hand, if
268 * {@link CqFieldDefinition#HAS_OPEN_CHOICE_LIST} is false then the choice
269 * list contains only the values currently permitted for the field.
270 * <p>
271 * In general, the content of a field's choice list is quite volatile and
272 * can depend on the state of the record it is in, the value of other fields
273 * of that record or related records, the current user's permissions, and
274 * other dynamic aspects of the database environment known only to the
275 * schema. So, in general, the choice list must be obtained in the context
276 * in which it is to be used at the time it is to be used. In this
277 * interface, that very dynamic value is expressed as the value of this
278 * meta-property.
279 * <p>
280 * {@link CqFieldValue#CHOICE_LIST} always returns the choice list for the
281 * field whether that list is static or not. If the schema is designed such
282 * that the choice list for a field in all records in all contexts is fixed
283 * by the schema, then this meta-property will always return the same list
284 * for that field. In this static case, the list returned by this
285 * meta-property will be the same as the list returned by the
286 * {@link CqFieldDefinition#CHOICE_LIST} property.
287 * <p>
288 * Choice lists can be voluminous and, so, should be read from the server
289 * only when needed. Yet, as explained above, they can also be quite
290 * volatile and may easily change during the course of a session and not
291 * necessarily in direct response to anything the client is doing. To
292 * mitigate this problem, a choice-list-id is provided to help the client
293 * know when it should request a new copy of the list. Every choice list has
294 * a choice-list-id. The value of the choice-list-id changes when and only
295 * when the content of the associated choice list changes.
296 * <p>
297 * If a client does not know that a given field has a static choice list, it
298 * must assume that it is not and monitor the field's CHOICE_LIST_ID
299 * to know when to load/reload its content.
300 */
301 MetaPropertyName<java.util.List<String>> CHOICE_LIST =
302 new MetaPropertyName<java.util.List<String>>(METADATA_NAMESPACE,
303 "choice-list");
304
305 /**
306 * Returns the value of the {@link #CHOICE_LIST CHOICE_LIST} metadata
307 * component as defined by this Property instance.
308 *
309 * @return A List of Strings, each containing a possible value for this
310 * field.
311 *
312 * @throws WvcmException if this Property instance does not define a value
313 * for the {@link #CHOICE_LIST CHOICE_LIST} metadata
314 * component.
315 */
316 java.util.List<String> getChoiceList()
317 throws WvcmException;
318
319 /** A String explaining why the value stored in the field is invalid. */
320 MetaPropertyName<String> MESSAGE_TEXT =
321 new MetaPropertyName<String>(METADATA_NAMESPACE, "message-text");
322
323 /**
324 * Returns the value of the {@link #MESSAGE_TEXT MESSAGE_TEXT} metadata
325 * component as defined by this Property instance.
326 *
327 * @return A String containing any message currently associated with this
328 * field.
329 *
330 * @throws WvcmException if this Property instance does not define a value
331 * for the {@link #MESSAGE_TEXT MESSAGE_TEXT}
332 * metadata component.
333 */
334 String getMessageText()
335 throws WvcmException;
336
337 /** Identifies whether the field's value is valid. */
338 MetaPropertyName<ValidationStatus> VALIDATION_STATUS =
339 new MetaPropertyName<ValidationStatus>(METADATA_NAMESPACE,
340 "validation-status");
341
342 /**
343 * Returns the value of the {@link #VALIDATION_STATUS VALIDATION_STATUS}
344 * metadata component as defined by this Property instance.
345 *
346 * @return A ValidationStatus enumerator identifying the validation status
347 * of this field.
348 *
349 * @throws WvcmException if this Property instance does not define a value
350 * for the {@link #VALIDATION_STATUS
351 * VALIDATION_STATUS} metadata component.
352 */
353 ValidationStatus getValidationStatus()
354 throws WvcmException;
355
356 /** Identifies whether the field currently has a value. */
357 MetaPropertyName<ValueStatus> VALUE_STATUS =
358 new MetaPropertyName<ValueStatus>(METADATA_NAMESPACE, "value-status");
359
360 /**
361 * Returns the value of the {@link #VALUE_STATUS VALUE_STATUS} metadata
362 * component as defined by this Property instance.
363 *
364 * @return A ValueStatus enumeration indicating whether or not this field
365 * has a value.
366 *
367 * @throws WvcmException if this Property instance does not define a value
368 * for the {@link #VALUE_STATUS VALUE_STATUS}
369 * metadata component.
370 */
371 ValueStatus getValueStatus()
372 throws WvcmException;
373
374 /** The type of this field's VALUE meta-property value. */
375 public static final MetaPropertyName<ValueType> FIELD_TYPE =
376 new MetaPropertyName<ValueType>(METADATA_NAMESPACE, "field-type");
377
378 /**
379 * Returns the value of the {@link #FIELD_TYPE FIELD_TYPE} meta-property as
380 * defined by this CqFieldValue instance.
381 *
382 * @return A VAlueType enumeration representing the type of this property's
383 * VALUE meta-property.
384 *
385 * @throws WvcmException if this Property instance does not define a value
386 * for the {@link #FIELD_TYPE FIELD_TYPE} meta-property.
387 */
388 public ValueType getFieldType()
389 throws WvcmException;
390
391 /** True if the field's validity was changed by the current action. */
392 MetaPropertyName<Boolean> VALIDITY_CHANGED_THIS_ACTION =
393 new MetaPropertyName<Boolean>(METADATA_NAMESPACE,
394 "validity-changed-this-action");
395
396 /**
397 * Returns the value of the {@link #VALIDITY_CHANGED_THIS_ACTION
398 * VALIDITY_CHANGED_THIS_ACTION} metadata component as defined by this
399 * Property instance.
400 *
401 * @return <b>true</b> if the field validity changed during the current
402 * action
403 *
404 * @throws WvcmException if this Property instance does not define a value
405 * for the {@link #VALIDITY_CHANGED_THIS_ACTION
406 * VALIDITY_CHANGED_THIS_ACTION} metadata component.
407 */
408 boolean getValidityChangedThisAction()
409 throws WvcmException;
410
411 /**
412 * True if the field's validity was changed by the most recent SetFieldValue
413 * call.
414 */
415 MetaPropertyName<Boolean> VALIDITY_CHANGED_THIS_SET_VALUE =
416 new MetaPropertyName<Boolean>(METADATA_NAMESPACE,
417 "validity-changed-this-set-value");
418
419 /**
420 * Returns the value of the {@link #VALIDITY_CHANGED_THIS_SET_VALUE
421 * VALIDITY_CHANGED_THIS_SET_VALUE} metadata component as defined by this
422 * Property instance.
423 *
424 * @return <b>true</b> if the field validity was changed by the most recent
425 * property update.
426 *
427 * @throws WvcmException if this Property instance does not define a value
428 * for the {@link #VALIDITY_CHANGED_THIS_SET_VALUE
429 * VALIDITY_CHANGED_THIS_SET_VALUE} metadata
430 * component.
431 */
432 boolean getValidityChangedThisSetValue()
433 throws WvcmException;
434
435 /**
436 * True if the field's validity was changed by the most recent group of
437 * SetFieldValue calls.
438 */
439 MetaPropertyName<Boolean> VALIDITY_CHANGED_THIS_GROUP =
440 new MetaPropertyName<Boolean>(METADATA_NAMESPACE,
441 "validity-changed-this-group");
442
443 /**
444 * Returns the value of the {@link #VALIDITY_CHANGED_THIS_GROUP
445 * VALIDITY_CHANGED_THIS_GROUP} metadata component as defined by this
446 * Property instance.
447 *
448 * @return <b>true</b> if this field's validity has changed since the last
449 * setting of {@link CqRecord#FIELDS_UPDATED_THIS_GROUP} in this
450 * field's record.
451 *
452 * @throws WvcmException if this Property instance does not define a value
453 * for the {@link #VALIDITY_CHANGED_THIS_GROUP
454 * VALIDITY_CHANGED_THIS_GROUP} metadata component.
455 */
456 boolean getValidityChangedThisGroup()
457 throws WvcmException;
458
459 /** True if this field's value was modified by the current action. */
460 MetaPropertyName<Boolean> VALUE_CHANGED_THIS_ACTION =
461 new MetaPropertyName<Boolean>(METADATA_NAMESPACE,
462 "value-changed-this-action");
463
464 /**
465 * Returns the value of the {@link #VALUE_CHANGED_THIS_ACTION
466 * VALUE_CHANGED_THIS_ACTION} metadata component as defined by this Property
467 * instance.
468 *
469 * @return <b>true</b> if this field's value has changed during the current
470 * action.
471 *
472 * @throws WvcmException if this Property instance does not define a value
473 * for the {@link #VALUE_CHANGED_THIS_ACTION
474 * VALUE_CHANGED_THIS_ACTION} metadata component.
475 */
476 boolean getValueChangedThisAction()
477 throws WvcmException;
478
479 /**
480 * True if this field's value was modified by the most recent property
481 * update interaction with the server.
482 */
483 MetaPropertyName<Boolean> VALUE_CHANGED_THIS_SET_VALUE =
484 new MetaPropertyName<Boolean>(METADATA_NAMESPACE,
485 "value-changed-this-set-value");
486
487 /**
488 * Returns the value of the {@link #VALUE_CHANGED_THIS_SET_VALUE
489 * VALUE_CHANGED_THIS_SET_VALUE} metadata component as defined by this
490 * Property instance.
491 *
492 * @return <b>true</b> if this fields value changed during the latest
493 * property-update interaction with the server
494 *
495 * @throws WvcmException if this Property instance does not define a value
496 * for the {@link #VALUE_CHANGED_THIS_SET_VALUE
497 * VALUE_CHANGED_THIS_SET_VALUE} metadata component.
498 */
499 boolean getValueChangedThisSetValue()
500 throws WvcmException;
501
502 /**
503 * True if the field's value was modified by the most recent group of
504 * SetFieldValue calls.
505 */
506 MetaPropertyName<Boolean> VALUE_CHANGED_THIS_GROUP =
507 new MetaPropertyName<Boolean>(METADATA_NAMESPACE,
508 "value-changed-this-group");
509
510 /**
511 * Returns the value of the {@link #VALUE_CHANGED_THIS_GROUP
512 * VALUE_CHANGED_THIS_GROUP} metadata component as defined by this Property
513 * instance.
514 *
515 * @return <b>true</b> if this field's value has changed since the last
516 * setting of {@link CqRecord#FIELDS_UPDATED_THIS_GROUP} in this
517 * field's record.
518 *
519 * @throws WvcmException if this Property instance does not define a value
520 * for the {@link #VALUE_CHANGED_THIS_GROUP
521 * VALUE_CHANGED_THIS_GROUP} metadata component.
522 */
523 boolean getValueChangedThisGroup()
524 throws WvcmException;
525
526 /**
527 * The field's value as it was retrieved from the database at the start of
528 * the action.
529 */
530 MetaPropertyName<?> ORIGINAL_VALUE =
531 MetaPropertyName.build(StpExBase.METADATA_NAMESPACE, "original-value");
532
533 /**
534 * Returns the value of the {@link #ORIGINAL_VALUE ORIGINAL_VALUE} metadata
535 * component as defined by this Property instance.
536 *
537 * @return An Object representing the value of this field just prior to
538 * being made editable in this workspace.
539 *
540 * @throws WvcmException if this Property instance does not define a value
541 * for the {@link #ORIGINAL_VALUE ORIGINAL_VALUE}
542 * metadata component.
543 */
544 T getOriginalValue()
545 throws WvcmException;
546
547 /**
548 * The field's value status as it was retrieved from the database at the
549 * start of the action.
550 */
551 MetaPropertyName<ValueStatus> ORIGINAL_VALUE_STATUS =
552 new MetaPropertyName<ValueStatus>(StpExBase.METADATA_NAMESPACE, "original-value-status");
553
554 /**
555 * Returns the value of the {@link #ORIGINAL_VALUE_STATUS
556 * ORIGINAL_VALUE_STATUS} metadata component as defined by this Property
557 * instance.
558 *
559 * @return A ValueStatus enumerator representing the status of this field's
560 * value just prior to being made editable in this workspace.
561 *
562 * @throws WvcmException if this Property instance does not define a value
563 * for the {@link
564 * #ORIGINAL_VALUE_STATUS ORIGINAL_VALUE_STATUS}
565 * metadata component.
566 */
567 ValueStatus getOriginalValueStatus()
568 throws WvcmException;
569
570 /**
571 * Initializes the values of this field value structure.
572 *
573 * @param values A list of value images that are to be the new field value
574 * images. May be null to indicate a null field value.
575 */
576 void initialize(java.util.List<String> values);
577
578 /**
579 * Initializes the value of this field value structure.
580 *
581 * @param value The string value that is to be the new field value image.
582 * May be null to indicate a null field value.
583 *
584 * @throws WvcmException if the field value is a record or list of records
585 * and the specified String is not a valid StpLocation image.
586 */
587 void initialize(String value) throws WvcmException;
588
589 /**
590 * Initializes the value of this field value structure using the value
591 * object rather than its image.
592 *
593 * @param value The value of the field. Must be a native representation of
594 * one of the supported field types.
595 */
596 void initialize(Object value) throws WvcmException;
597
598 /**
599 * Returns the number of individual values in an aggregated field value.
600 *
601 * @return Returns 0 for a null value, 1 for a scalar value, and the count
602 * of the number of individual values in a aggregated value.
603 *
604 * @throws WvcmException if the field value is a record or list of records
605 * and the value specified as a String is not a valid StpLocation image.
606 */
607 long valueCount();
608
609 /**
610 * Returns the character image of the i-th element of an aggregated value.
611 *
612 * @param i The (zero-origin) index of the value whose character image is
613 * desired. Must be zero or less than {@link #valueCount()
614 * valueCount}.
615 *
616 * @return The character image of the i-th element of the field value. If
617 * the field value is null, {@link #NULL_VALUE_IMAGE
618 * NULL_VALUE_IMAGE} is returned for index 0.
619 *
620 * @throws WvcmException If an i-th value exists in this fields value
621 * list.
622 */
623 String characterImage(int i)
624 throws WvcmException;
625
626 /**
627 * Returns the character image of the (first) field value.
628 *
629 * @return Returns {@link #characterImage(int) characterImage(0)}.
630 *
631 * @throws WvcmException If the value is null (valueCount == 0).
632 */
633 String characterImage()
634 throws WvcmException;
635
636 /**
637 * The special string value returned by characterImage for a null field
638 * value
639 */
640 String NULL_VALUE_IMAGE = "<CTG:NULL_VALUE/>";
641 }