Package wt.fc.collections

Provides Windchill-specific Collection objects, and a collection-based refresh API.

See:
          Description

Interface Summary
CollectionsManager A remote interface for managing WTCollections.
ReferenceBased Used by the default implementations of WTCollection to connect to other WTCollections.
WTCollection A Collection that provides QueryKey, WTReference, and Persistable-based views of its data.
WTKeyedMap A Map in which the keys are a WTSet.
WTList A WTCollection that implements the java.util.List interface.
WTSet Refines the contract of WTCollection to require that all the objects in the implementing collection are unique.
WTValuedMap A WTKeyedMap in which the values are a WTCollection.
 

Class Summary
CollectionsHelper Provides utility methods for dealing with WTCollections.
RefreshSpec Encapsulates the parameters that can be passed to the CollectionsManager refresh APIs.
WTArrayList An array-based implementation of WTArrayList
WTHashSet A hash-based implementation of WTSet.
WTKeyedHashMap Follows the patterns established by the default collection implementations.
WTValuedHashMap The key mask for the values collection can be specified in the constructor.
 

Exception Summary
CollectionContainsDeletedException

Supported API: true

Extendable: false
CollectionContainsStaleException

Supported API: true

Extendable: false
 

Package wt.fc.collections Description

Provides Windchill-specific Collection objects, and a collection-based refresh API.

Package Specification

The collections package is an extension of the Java Collections framework. It contains the following core interfaces: And the following basic implementation classes: In addition, the package provides a collections based refresh API.

Usage examples

The following commented code demonstrates the basic functionality of the collections package
      WTPart part1 = null;
      ObjectIdentifier part2_oid = null;
      WTDocument doc1 = null;
      ObjectIdentifier doc2_oid = null;
      
      WTCollection c1 = new WTArrayList();
      c1.add(part1);
      c1.add(part2_oid);
      c1.add(doc1);
      c1.add(doc2_oid);
      
      // Returns an Iterator of ObjectReferences. Does not inflate
      // part1_oid and doc2_oid
      Iterator i = c1.referenceIterator();
      
      // Returns an Iterator of ObjectIdentifiers
      i = c1.queryKeyIterator();
      
      // Returns an Iterator of Persistables. Performs a batch
      // inflate of part1_oid and doc2_oid
      try {
         i = c1.persistableIterator();
      }
      catch (WTException wte) {
         // Operations that may need to inflate a collection
         // throw WTExceptions
      }
            
      // Get a subcollection of the parts in c1
      WTCollection sub = c1.subCollection(WTPart.class);      
      assert sub.contains(part1);
      assert !sub.contains(doc1);           
      
      // Modifications to sub are reflected in the parent collection
      sub.remove(part1);
      assert !c1.contains(part1);
      
      //And vice versa
      c1.remove(part2_oid);
      assert !sub.contains(part2_oid);
      
      // Create a collection with a non-default key type
      // With just VERSION_FOREIGN_KEY enabled, the collection
      // can only contain Iterated objects, and will store them
      // by VersionForeignKey as opposed to by ObjectIdentifier
      WTCollection c2 = new WTArrayList(CollectionsHelper.VERSION_FOREIGN_KEY);
      c2.addAll(c1);
      
      // Returns an Iterator of VersionReferences
      i = c2.referenceIterator();
      
      // Returns an Iterator of VersionForeignKeys
      i = c2.queryKeyIterator();
      
      // Throws a ClassCastException because WTPartMaster is not Iterated
      c2.add(part1.getMaster());
      
      // Create a collection that supports both Iterated and non-Iterated
      // objects
      WTCollection c3 = new WTArrayList(CollectionsHelper.VERSION_FOREIGN_KEY | CollectionsHelper.OBJECT_IDENTIFIER);
      // Add an iterated object; will use its VersionForeignKey when needed
      c3.add(part1);
      
      // Throws ClassCastException, because collection only supports VersionForeignKey objects for Iterated objects
      c3.add(part2_oid);
      
      // OK, since WTPartMaster isn't iterated
      c3.add(part1.getMaster());
      
      // Returns an Iterator with a VersionReference for part1, 
      // and an ObjectReference for part1's master
      i = c3.referenceIterator();
      
      // Returns an Iterator with a VersionForeignKey for part1, 
      // and an ObjectIdentifier for part1's master
      i = c3.queryKeyIterator();
      
      // Create a map with Persistable keys and arbitrary values
      WTKeyedMap m1 = new WTKeyedHashMap();
      
      Object foo = new Object();
      Object bar = new Object();
      m1.put(part1, foo);
      m1.put(doc1, bar);
      
      // Get a WTSet of the keys in m1
      WTSet s = m1.wtKeySet();
      
      // Get a collection of the values in m1
      Collection v = m1.values();
      
      // Get a set of the Map.Entry objects in m1
      // For WTKeyedMaps, the objects will implement WTKeyedMap.WTEntry, and extension of Map.Entry.
      Set entries = m1.entrySet();
      
      // Iterate through the entry set
      for (Iterator j = entries.iterator(); j.hasNext();) {
         WTEntry e = (WTEntry)j.next();
         // You can get the key as a Persistable, WTReference, or QueryKey
         Persistable p = e.getKeyAsPersistable();
         Object o = e.getValue();
         // You can change the value
         e.setValue(new Object());
      }
      
      // A WTValuedMap is an extension of WTKeyedMap in which the values
      // must be Persistables, QueryKeys, or WTReferences, just like the keys
      WTValuedMap m2 = new WTValuedHashMap();
      
      // Throws a ClassCastException because the value is just an Object
      m2.put(part1, foo);
      
      m2.put(part1, doc1);
      m2.put(part2_oid, doc2_oid);
      
      // The values returned by a WTValuedMap implements WTCollection
      WTCollection v2 = m2.wtValues();
      
      // For WTValuedMaps, the objects will implmeent WTValuedMap.WTValuedEntry, 
      // an extension of WTKeyedMap.WTEntry
      entries = m2.entrySet();
      
      // Iterate through the entry set
      for (Iterator j = entries.iterator(); j.hasNext();) {
         WTValuedEntry e = (WTValuedEntry)j.next();
         // You can get the key as a Persistable, WTReference, or QueryKey
         Persistable key = e.getKeyAsPersistable();
         
         // You can get the value as a Persistable, WTReference, or QueryKey
         Persistable value = e.getValueAsPersistable();         
      }      

Design Goals

The collections package was designed with a few key use cases in mind: event dispatch, version-based APIs, persistence layer APIs, and performance.

Event dispatch

Multi-object events will carry one or more of these collections with them. To be effective in event listeners, the collection should:

Version-based service APIs

In the context of a given transaction, passing around version references is rarely needed. Version references are an effective way to represent longer term relationships, but typically, once an API is called then an object reference to the latest iteration is what the code actually needs. Since we have client APIs and database relationships that are version based, however, we need a way to represent a collection of these versions. Thus the collection should:

Persistence layer APIs

The persistence layer often deals with ObjectIdentifiers or just arrays of longs and classnames, rather than with Persistables or even with references. The collection should:

Performance

The collection implementations should facilitate batch operations while adding as little overhead as possible themselves. The collection should: