Creating Facets: Faceted and the FacetRegistry

An object implements Interface org.favabeans.base.FacetedFaceted in order to be tightly integrated into the Interface org.favabeans.base.FacetFacet system. An object returns a Interface org.favabeans.base.FacetFacet of itself of a requested Class org.favabeans.base.TypeType via its Method org.favabeans.base.Faceted.getFacet(org.favabeans.base.Type)Faceted.getFacet(Type) method. Any lifecycle management of Interface org.favabeans.base.FacetsFacets is the responsibility of the Interface org.favabeans.base.FacetedFaceted object.

More typically -- and more powerfully -- we can create a Interface org.favabeans.base.FacetFacet for an object that is not aware of the Interface org.favabeans.base.FacetFacet system; we do this with the help of a Interface org.favabeans.base.FacetRegistryFacetRegistry. Some "startup" component initializes a Class org.favabeans.base.FacetRegistryFacetRegistry (typically that available via class Class org.favabeans.base.FavaBeansFavaBeans) with information about the Class org.favabeans.base.TypeTypes of objects for which Interface org.favabeans.base.FacetFacets may be created, and some Interface org.favabeans.base.FacetFactoryFacetFactory objects to which the Interface org.favabeans.base.FacetRegistryFacetRegistry may delegate the responsibility for actually constructing Interface org.favabeans.base.FacetFacets. A Interface org.favabeans.base.FacetRegistryFacetRegistry is responsible for maintaining a list of already constructed Interface org.favabeans.base.FacetFacets for an object.

A typical interaction with a Interface org.favabeans.base.FacetRegistryFacetRegistry starts by adding some Interface org.favabeans.base.FacetFactoryFacetFactory objects. Given:

interface WebAccessible { /* ... */ }
interface HtmlAccessible extends WebAccessible { /* ... */ }

interface Vehicle { /* ... */ }

Vehicle theVehicle; /* assuming already exists */
FacetFactory fac0, fac1; /* assuming these already exist */

FacetRegistry theFacets = /* ... */;

We could add:

theFacets.addFactory(new JavaType(Vehicle.class),
                     new JavaType(WebAccessible.class), 
                     fac0);

theFacets.addFactory(new JavaType(Vehicle.class),
                     new JavaType(HtmlAccessible.class), 
                     fac1);

We could then use the Interface org.favabeans.base.FacetRegistryFacetRegistry to obtain an HtmlAccessible Interface org.favabeans.base.FacetFacet of the Vehicle object:

HtmlAccessible h0 = (HtmlAccessible)
  theFacets.getFacet(theVehicle, new JavaType(HtmlAccessible.class));

The Class org.favabeans.base.FacetRegistryFacetRegistry would cache this Interface org.favabeans.base.FacetFacet so that:

theFacets.getFacet(theVehicle, new JavaType(HtmlAccessible.class)) == h0;

and would return the same Interface org.favabeans.base.FacetFacet for compatible supertypes of that for which it was originally constructed:

theFacets.getFacet(theVehicle, new JavaType(WebAccessible.class)) == h0;

until the Method org.favabeans.base.FacetRegistry.clearFacets(java.lang.Object)FacetRegistry.clearFacets(Object) method is called:

theFacets.clearFacets(theVehicle);

after which Interface org.favabeans.base.FacetFacets for this object are created anew:

HtmlAccessible h1 = (HtmlAccessible)
  theFacets.getFacet(theVehicle, new JavaType(HtmlAccessible.class));
h1 != h0;

Important

We need to address lifecycle issues for Interface org.favabeans.base.FacetFacet objects. This will apply to all things like views, etc., and will be generally useful. This is all complicated by the messy strong references in Java AWT and Swing for event listeners, which may prevent some components from getting garbage collected correctly. This will need to be addressed at some point.