The current view service system has been getting hacked on additions for a few months now, and it is to the point where it should be refactored. It seems like there are several places where there are redundant references. And the mechanisms by which the view services get setup is looking fragile.
These notes are based on a slightly refactored version of the code which has not been checked in yet.
Each view should have:
- a viewContainer which allows the view replace itself with another view.
- a viewContext which allows:
- access its sibling views
- method to create a viewFactory which can be used to make children views
- access to view services. This will replace the viewServiceProvider.
- if it creates a viewFactory
- its own viewFactory for creating sub views of referenced objects.
- this viewFactory will maintain references to these sub views so it can provide a viewContext to them.
Those three items can all be services or provided by services:
- viewContext can directly be a service, it will need to be created whether it is used or not.
- viewFactory can be created on demand from a viewFactoryFactory (or something like that)
- viewContainer can directly be a service,
The current JComponent specific versions of this same functionality should be modified to use the more abstract version.
Currently the view services are maintained by instances of OTViewFactoryImpl
OTViewFactoryImplS can have a parent OTViewFactoryImpl.
In this case the child first looks for services in itself and then in the parent.
View services are looked up using an OTViewServiceProvider interface which a view can access by implementing the OTViewServiceProviderAware interface.
The OTViewServiceProvider interface is implemented by an OTViewServiceProviderImpl class inside of OTViewFactoryImpl.
The OTViewFactoryImpl supplies the viewServiceProvider during the initView method.
Which is in turn called from the getView methods of the OTViewFactoryImpl class.
The main OTViewFactoryImpl is only instanciated in the registerServices call of the OTViewBundle class.
All other instances are created by the createChildViewFactory method.
The viewFactory itself is added as a service to itself.
So views can access their viewFactory through the their viewServiceProvider.
this is a confusing design - it would be better if the viewFactory didn't manage the viewServiceProvider. Then the viewFactory could be seen as just another service views can use.
The main use of the viewFactory is behind the OTViewContainerPanel. This is the class that most compound views use to display their children views.
The setCurrentObject method in OTViewContainerPanel indirectly calls getView on its viewFactory.
The OTViewContainerPanel now has a notion of being a topLevel container. In this case it maintains a shared controllerService for its view. The shared controller service is setup when the setOTViewFactory method is called on the OTViewContainerPanel.
In topLevel mode it also adds a new OTJComponentServiceFactory service which wraps the passed in viewFactory. Because this OTJComponentServiceFactory is how most compound views get their sub views this service needs to duplicated so the subviews have the correct viewFactory and hence the correct set of services. that could be fixed by requiring the user to pass in the viewFactory when calling OTJComponentServiceFactory.createJComponentService
the setOTViewFactory is called in 7 places. In several places the viewFactory set is from getChildViewFactory. This is how the caller can setup a nested set of services.
In the OTUDLSidebar case this nested factory is inside of another view so the service nesting matches the view containment hirearchy.
In the other cases the factory is used for a real top level container.
The OTViewContainerPanel also has the concept of parent containers. This is to support the new additions to the OTViewContainer interface that allows a view to look up the nearest "updatable" container. An updatable container is one whose current object can be changed or updated. This type of nesting of the containers is setup by the OTJComponentContainerHelper which knows about the current container and is used by objects to make sub containers.
Another key element is how the OTJComponentServiceFactory is used. Objects that need to make sub views use its createJComponentService method to make a "sub" component service. For one thing this alows the sub views to share a common OTJComponentViewContext so they can access their peers.