001/* 002 * file StpProperty.java 003 * 004 * Licensed Materials - StpProperty of IBM 005 * Restricted Materials of IBM 006 * 007 * com.ibm.rational.wvcm.stp.StpProperty 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 014package com.ibm.rational.wvcm.stp; 015 016import static com.ibm.rational.wvcm.stpex.StpExBase.METADATA_NAMESPACE; 017 018import java.util.ArrayList; 019import java.util.List; 020 021import javax.wvcm.PropertyNameList; 022import javax.wvcm.Resource; 023import javax.wvcm.WvcmException; 024import javax.wvcm.PropertyNameList.PropertyName; 025 026import com.ibm.rational.wvcm.stp.cq.CqFieldValue.ValueType; 027import com.ibm.rational.wvcm.stpex.StpExBase; 028import com.ibm.rational.wvcm.stpex.StpExEnumeration; 029import com.ibm.rational.wvcm.stpex.StpExEnumerationBase; 030 031/** 032 * A property is a named collection of metadata associated with a resource. The 033 * collection is named by its PropertyName. 034 * 035 * <h2>Meta-Properties</h2> 036 * 037 * <p> 038 * Each metadata component is called a meta-property and is a (name, value) 039 * pair. That is, a property is a named collection of meta-properties. The name 040 * of a meta-property is denoted by a {@link MetaPropertyName MetaPropertyName} 041 * object. The value is an arbitrary Object. 042 * </p> 043 * 044 * <p> 045 * The term "meta-property" is used here rather loosely. Meta-properties specify 046 * more than just static attributes of a property (such as its type or name), 047 * but often define very dynamic aspects of the property (e.g., what resource it 048 * came from) or its value (e.g. whether or not the value is null). There is 049 * even a VALUE meta-property, whose value is the value of the property. 050 * </p> 051 * 052 * <p> 053 * Just like a PropertyName, a MetaPropertyName is composed from a namespace and 054 * a simple name. (In fact, to simplify this API, MetaPropertyName is a subclass 055 * of javax.wvcm.PropertyNameList.PropertyName.) The PropertyName and 056 * MetaPropertyName namespaces cannot overlap. 057 * </p> 058 * 059 * <p> 060 * Every property has the meta-properties defined in this class; namely 061 * {@link #NAME NAME}, {@link #NAMESPACE NAMESPACE}, {@link #PROPERTY_NAME 062 * PROPERTY_NAME}, {@link #RESOURCE RESOURCE} and {@link #VALUE VALUE}. Each 063 * property may have additional meta-properties of its own as well. 064 * </p> 065 * 066 * <p> 067 * When we speak of the "<i>value of a property</i>", we are actually 068 * referring to the value of the VALUE meta-property of the property. 069 * </p> 070 * 071 * <h2>Requesting Meta-properties</h2> 072 * 073 * <p> 074 * An StpProperty object is a client-side proxy for a property; just as a 075 * Resource object is a client-side proxy for a resource. Like a resource proxy, 076 * each StpProperty instance defines only those meta-properties that have been 077 * explicitly requested from the server. (The NAME, NAMESPACE, and PROPERTY_NAME 078 * meta-properties are an exception since they are required to construct a 079 * StpProperty instance and are always present.) 080 * </p> 081 * 082 * <p> 083 * An StpProperty instance does not provide an interface for changing the value 084 * of a meta-property. Clients can change only property values, which may have 085 * the side-effect of changing other meta-properties for that property or 086 * meta-properties for other properties. 087 * </p> 088 * 089 * <p> 090 * Property meta-properties are available only in the context of a specific 091 * resource and the request for property meta-properties is tied directly to 092 * that resource using the same mechanism used to request properties from that 093 * resource. 094 * </p> 095 * 096 * <h3>MetaPropertyName Objects in a NestedPropertyName</h3> 097 * 098 * <p> 099 * To request a meta-property of a property, a MetaPropertyName object for the 100 * meta-property is included in the PropertyRequest argument to 101 * PropertyName.nest(). MetaPropertyName objects and PropertyName objects can 102 * coexist in the same nested PropertyRequest; the nested MetaPropertyName 103 * objects request meta-properties of the property, while the nested ProperyName 104 * objects request properties of the resource named by the value of the 105 * property. 106 * </p> 107 * 108 * <p> 109 * To request the meta-properties of a property-valued property, the 110 * MetaPropertyNames must be nested within a NestedPropertyName. The root 111 * meta-property of this request will be StpProperty.VALUE and the desired 112 * meta-properties of the value will be nested in the PropertyRequest of the 113 * NestedPropertyName. 114 * </p> 115 * 116 * <p> 117 * Examples 118 * </p> 119 * 120 * <pre> 121 * PropertyRequest wanted=new PropertyRequest( 122 * // The value of the DISPLAY_NAME property 123 * Resource.DISPLAY_NAME, 124 * Resource.WORKSPACE_FOLDER_LIST.nest( 125 * // The type of the WORKSPACE_FOLDER_LIST property 126 * StpProperty.TYPE, 127 * // The value of the CHILD_LIST property for each folder 128 * // named by the WORKSPACE_FOLDER_LIST 129 * Folder.CHILD_LIST), 130 * Resource.INVALID_PROPERTIES.nest( 131 * // The type of the INVALID_PROPERTIES property 132 * StpProperty.TYPE, 133 * StpProperty.VALUE.nest( 134 * // The type of each property named by the value of the 135 * // INVALID_PROPERTIES property. 136 * StpProperty.TYPE, 137 * // The value of each property named by the value of the 138 * // INVALID_PROPERTIES property. 139 * StpProperty.VALUE), 140 * ); 141 * </pre> 142 * 143 * <h3>The VALUE Meta-Property</h3> 144 * 145 * <p> 146 * Every property has a VALUE meta-property. The use of a PropertyName by itself 147 * implicitly requests this meta-property. A NestedPropertyName containing 148 * nested ProperyNames also implicitly requests the VALUE meta-property (since 149 * it would be impossible to request properties of the value without also 150 * requesting the value itself). 151 * </p> 152 * 153 * <p> 154 * On the other hand, a NestedPropertyName that contains only nested 155 * MetaPropertyNames must include StpProperty.VALUE if the value of the property 156 * is desired. This makes it possible for a client to request information about 157 * a property (such as is size) without actually retrieving the value itself. 158 * </p> 159 * 160 * <h2>Accessing Meta-Properties</h2> 161 * 162 * <p> 163 * Like property values, meta-properties retrieved from the server are stored in 164 * the resource proxy and accessed via methods defined in the StpResource class. 165 * The principal method is {@link 166 * com.ibm.rational.wvcm.stp.StpResource#getMetaProperties(PropertyNameList.PropertyName) 167 * Resource.getMetaProperties(PropertyName)}, which returns an StpProperty object 168 * containing all of the meta-properties for a given property retrieved from the 169 * server and diagnostic information for those meta-properties that couldn't be 170 * retrieved. 171 * </p> 172 * 173 * <p> 174 * As long as the PropertyName was mentioned in the request and that property is 175 * defined by the resource, getMetaProperties will return a StpProperty object 176 * for that PropertyName. An exception is thrown only if the property is not 177 * defined by the resource or no meta-property of the property was requested. 178 * </p> 179 * 180 * <p> 181 * {@link javax.wvcm.Resource#getProperty(PropertyNameList.PropertyName) 182 * Resource.getProperty(PropertyName)} returns the value of the VALUE 183 * meta-property of the property and will throw an exception if that 184 * meta-property was not requested or the server reported an error in attempting 185 * to retrieve the value. If the value of a property is, itself, a property, 186 * getProperty will return an StpProperty object. 187 * </p> 188 * 189 * <p> 190 * From the StpProperty object, the client can access the retrieved 191 * meta-properties, either generically using the {@link 192 * StpProperty#getMetaProperty(StpProperty.MetaPropertyName) getMetaProperty()} 193 * method and an explicit MetaPropertyName or using the specialized methods, 194 * such as {@link #getName getName} and {@link #getValue getValue}, where the 195 * MetaPropertyName is implicit. Subclasses of Resource may define subclasses of 196 * StpProperty and provide typed accessors for them. The subclasses of 197 * StpProperty may, in turn, define more typed accessors for meta-properties 198 * they know about. (See, for example 199 * {@link com.ibm.rational.wvcm.stp.cq.CqRecord Record} and 200 * {@link com.ibm.rational.wvcm.stp.cq.CqFieldValue CqFieldValue}.) 201 * </p> 202 * <p> 203 * The type parameter of an StpProperty instance specifies the type of the 204 * property's VALUE meta-property. 205 */ 206public interface StpProperty<T> 207{ 208 /** 209 * A List of Properties. 210 */ 211 public static class List<S extends StpProperty> 212 extends ArrayList<S> 213 { 214 /** 215 * 216 */ 217 private static final long serialVersionUID = 1181176128014802915L; 218 219 /** 220 * Returns the names of the properties in the list 221 * 222 * @return A PropertyNameList containing a PropertyName for each element 223 * of the list. 224 */ 225 public PropertyNameList getPropertyNameList() 226 { 227 int n = size(); 228 PropertyName[] names = new PropertyName[n]; 229 230 for (int i = 0; i < n; ++i) 231 names[i] = get(i).getPropertyName(); 232 233 return new PropertyNameList(names); 234 } 235 236 /* (non-Javadoc) 237 * @see java.util.ArrayList#add(java.lang.Object) 238 */ 239 @Override 240 public boolean add(S arg0) 241 { 242 return super.add(arg0); 243 } 244 } 245 246 /** 247 * An object representing the name of a meta-property. This class extends 248 * PropertyName so that MetaPropertyName objects may be included in a 249 * PropertyRequest. Otherwise, MetaPropertyName and PropertyName are not 250 * interchangeable. The type parameter specifies the type of meta-property's 251 * value. 252 */ 253 public static class MetaPropertyName<V> 254 extends PropertyName<V> 255 { 256 /** 257 * Creates a new MetaPropertyName from a simple name and a specified 258 * namespace. 259 * 260 * @param namespace the namespace for this MetaPropertyName. May not 261 * be <b>null</b>. 262 * @param name the name for this property. May not be <b>null</b>. 263 */ 264 public MetaPropertyName( 265 String namespace, 266 String name) 267 { 268 super(namespace, name); 269 } 270 271 /** 272 * Parameterized method for constructing MetaPropertyName<?> 273 * 274 * @param <U> The value type for the MetaPropertyName 275 * @param namespace The namespace for this MetaPropertyName. May not be 276 * <b>null</b>. 277 * @param name the name for this property. May not be <b>null</b>. 278 * @return A new instanceof MetaPropertyName using the given namespace 279 * and name 280 */ 281 public static final <U> MetaPropertyName<U> build(String namespace, 282 String name) 283 { 284 return new MetaPropertyName<U>(namespace, name); 285 } 286 } 287 288 /** 289 * Returns the value of the given meta-property defined by this StpProperty 290 * instance. 291 * 292 * @param name A MetaPropertyName object identifying the meta-property 293 * desired. 294 * 295 * @return An Object representing the value of the meta-property requested. 296 * 297 * @throws WvcmException if this StpProperty instance does not define a 298 * value for the named meta-property. 299 */ 300 public <U> U getMetaProperty(MetaPropertyName<U> name) 301 throws WvcmException; 302 303 /** 304 * Returns the names of meta-properties available on this client StpProperty 305 * proxy. This is the analog of Resource.propertyNameList. A meta-property 306 * is available if it would not throw an exception if retrieved from this 307 * StpProperty. Failing to retrieve a meta-property would cause a 308 * meta-property name to not appear in the metaPropertyNames result and 309 * forgetting or removing a meta-property would remove that property from 310 * the metaPropertyNames result. 311 * 312 * @return the list of MetaPropertyName objects identifying the 313 * meta-properties available on this client StpProperty proxy. 314 * 315 * @see javax.wvcm.Resource#propertyNameList() 316 */ 317 public MetaPropertyName<?>[] metaPropertyNames(); 318 319 /** 320 * Returns an array of StpPropertyException objects, each of which 321 * represents a meta-property whose value was requested but could not be 322 * successfully retrieved. 323 * 324 * @return An array containing an StpPropertyException object for each 325 * meta-property that could not be retrieved. The PropertyName field 326 * of the PropertyException identifies the meta-property that could 327 * not be retrieved. 328 */ 329 public StpPropertyException[] metaPropertyExceptions(); 330 331 /** 332 * Returns the StpPropertyException that would be thrown if getMetaProperty 333 * were invoked on a specified meta-property. 334 * 335 * @param name The name of the meta-property whose retrieval status is being 336 * interrogated. 337 * @return an StpPropertyException is returned if the named meta-property 338 * could not be retrieved or if it's retrieval was not requested; 339 * otherwise <b>null</b>. 340 */ 341 public StpPropertyException metaPropertyException(MetaPropertyName<?> name); 342 343 /** 344 * A list of all the meta-property names defined for this property. This is 345 * the analog of Resource.doGetPropertyNameList. Since properties may not be 346 * addressed directly, this analogous capability is expressed as a 347 * meta-property. 348 */ 349 public static final MetaPropertyName<PropertyNameList> META_PROPERTY_NAMES = 350 new MetaPropertyName<PropertyNameList>(METADATA_NAMESPACE, 351 "meta-property-names"); 352 353 /** 354 * Returns the value of the {@link #META_PROPERTY_NAMES META_PROPERTY_NAMES} 355 * meta-property as defined by this StpProperty instance. 356 * 357 * @return A PropertyRequest containing a MetaPropertyName for each meta- 358 * property defined by this StpProperty. 359 * 360 * @throws WvcmException if this StpProperty instance does not define a value 361 * for the {@link 362 * #META_PROPERTY_NAMES META_PROPERTY_NAMES} 363 * meta-property. 364 */ 365 public PropertyNameList getMetaPropertyNames() 366 throws WvcmException; 367 368 /** 369 * The meta-property whose value is the value of the property. (The type of 370 * the value is specified by the TYPE meta-property.) This meta-property is 371 * defined for all properties. 372 */ 373 public static final MetaPropertyName<?> VALUE = 374 new MetaPropertyName(StpExBase.METADATA_NAMESPACE, "value"); 375 376 /** 377 * Returns the value of the {@link #VALUE VALUE} meta-property as defined by 378 * this StpProperty instance. 379 * 380 * @return An Object representing the value of the property represented by 381 * this StpProperty instance. 382 * 383 * @throws WvcmException if this StpProperty instance does not define a 384 * value for the {@link #VALUE VALUE} meta-property. 385 */ 386 public T getValue() 387 throws WvcmException; 388 389 /** 390 * An enumeration of the possible property types. Subclasses may extend this 391 * list to include any new data types introduced by that subclass. 392 */ 393 public enum Type 394 implements StpExEnumeration 395 { 396 /** An initial value for Type variables */ 397 UNKNOWN, 398 399 /** An integer in the range -9999999999 to 9999999999 */ 400 INTEGER, 401 402 /** 403 * A GMT date/time between 12:00:01 AM January 1, 1970 and 11:59:59 PM 404 * January 18, 2038. 405 */ 406 DATE_TIME, 407 408 /** A proxy for a Resource of a specific ResourceType. */ 409 RESOURCE, 410 411 /** A list of proxies for a Resource of a specific ResourceType */ 412 RESOURCE_LIST, 413 414 /** A floating point value */ 415 FLOAT, 416 417 /** A generic string value */ 418 STRING, 419 420 /** An StpLocation property value. */ 421 LOCATION, 422 423 /** A Locale property value. */ 424 LOCALE, 425 426 /** A property value that is a list of Strings. */ 427 STRING_LIST, 428 429 /** A long property value. */ 430 LONG, 431 432 /** An double property value. */ 433 DOUBLE, 434 435 /** A boolean property value. */ 436 BOOL, 437 438 /** A ResourceType property value */ 439 RESOURCE_TYPE, 440 441 /** A property value derived from StpExEnumerationBase */ 442 ENUMERATED_TYPE, 443 444 /** A list of values derived from StpExEnumerationBase */ 445 ENUMERATED_LIST, 446 447 /** A PropertyName property value */ 448 PROPERTY_NAME, 449 450 /** A PropertyNameList property value */ 451 PROPERTY_NAME_LIST, 452 453 /** An StpProperty property value */ 454 PROPERTY, 455 456 /** An StpProperty.List property value */ 457 PROPERTY_LIST, 458 459 /** A structure derived from Object */ 460 OBJECT, 461 462 /** A list of structures derived from Object */ 463 OBJECT_LIST, 464 465 /** An XML content property value. */ 466 XML, 467 468 /** A pair of long values specifying a range. */ 469 RANGE; 470 } 471 472 /** 473 * An enumerator denoting the type of this property's VALUE meta-property 474 * value. 475 */ 476 public static final MetaPropertyName<Type> TYPE = 477 new MetaPropertyName<Type>(StpExBase.METADATA_NAMESPACE, "type"); 478 479 /** 480 * Returns the value of the {@link #TYPE TYPE} meta-property as defined by 481 * this StpProperty instance. 482 * 483 * @return A Type enumeration representing the type of this property's 484 * VALUE meta-property. 485 * 486 * @throws WvcmException if this StpProperty instance does not define a value 487 * for the {@link #TYPE TYPE} meta-property. 488 */ 489 public Type getType() 490 throws WvcmException; 491 492 /** A PropertyName object for this property. */ 493 public static final MetaPropertyName<PropertyName<?>> PROPERTY_NAME = 494 new MetaPropertyName<PropertyName<?>>(StpExBase.METADATA_NAMESPACE, "property-name"); 495 496 /** 497 * Returns the value of the {@link #PROPERTY_NAME PROPERTY_NAME} 498 * meta-property as defined by this StpProperty instance. Note that this 499 * meta-property is always defined by a property and does not need to be 500 * requested. 501 * 502 * @return This object as a PropertyName. 503 */ 504 public PropertyName<T> getPropertyName(); 505 506 /** The simple name for this property. */ 507 public static final MetaPropertyName<String> NAME = 508 new MetaPropertyName<String>(StpExBase.METADATA_NAMESPACE, "name"); 509 510 /** 511 * Returns the value of the {@link #NAME NAME} meta-property as defined by 512 * this StpProperty instance. Note that this meta-property is always defined 513 * by a property and does not need to be requested. 514 * 515 * @return A string representing the simple name of this property's 516 * PropertyName 517 */ 518 public String getName(); 519 520 /** The namespace for this property. */ 521 public static final MetaPropertyName<String> NAMESPACE = 522 new MetaPropertyName<String>(StpExBase.METADATA_NAMESPACE, "namespace"); 523 524 /** 525 * Returns the value of the {@link #NAMESPACE NAMESPACE} meta-property as 526 * defined by this StpProperty instance. Note that this meta-property is 527 * always defined by a property and does not need to be requested. 528 * 529 * @return A String representing the namespace in which this property is 530 * defined. 531 */ 532 public String getNamespace(); 533 534 /** The resource of which this is a property. */ 535 public static final MetaPropertyName<Resource> RESOURCE = 536 new MetaPropertyName<Resource>(StpExBase.METADATA_NAMESPACE, "resource"); 537 538 /** 539 * Returns the value of the {@link #RESOURCE RESOURCE} meta-property as 540 * defined by this StpProperty instance. 541 * 542 * @return A Resource proxy for the resource this property belongs to. 543 * 544 * @throws WvcmException if this StpProperty instance does not define a 545 * value for the {@link #RESOURCE RESOURCE} meta-property 546 * component. 547 */ 548 public Resource getResource() 549 throws WvcmException; 550 551 /** 552 * A metric relating to the size of the property value, such as the number 553 * of characters in a string, or the number of items in a list. Not all 554 * properties define this meta-property; see the property documentation. 555 */ 556 public static final MetaPropertyName<Long> SIZE = 557 new MetaPropertyName<Long>(StpExBase.METADATA_NAMESPACE, "size"); 558 559 /** 560 * Returns the value of the {@link #SIZE SIZE} meta-property as defined by 561 * this StpProperty instance. 562 * 563 * @return An non-negative integer. 564 * 565 * @throws WvcmException if this StpProperty instance does not define a 566 * value for the {@link #SIZE SIZE} meta-property component. 567 */ 568 public long getSize() 569 throws WvcmException; 570 571 /** 572 * Whether or not the value of this property is empty/null. Not all 573 * properties define this meta-property; see the property documentation. 574 */ 575 public static final MetaPropertyName<Boolean> IS_EMPTY = 576 new MetaPropertyName<Boolean>(StpExBase.METADATA_NAMESPACE, "is-empty"); 577 578 /** 579 * Returns the value of the {@link #IS_EMPTY IS_EMPTY} meta-property as 580 * defined by this StpProperty instance. 581 * 582 * @return <b>true</b> if the value of this StpProperty is empty or null; 583 * <b> false</b> otherwise. 584 * 585 * @throws WvcmException if this StpProperty instance does not define a 586 * value for the {@link #IS_EMPTY IS_EMPTY} meta-property 587 * component. 588 */ 589 public boolean getIsEmpty() 590 throws WvcmException; 591}