All,
In the past, there has been a kind of unspoken understanding (at least in
my mind) as to where certain CP objects must come from. For example,
I've been under the assumption that in order to pass an instance of IAttribute
to method like IContext.createSubject, the caller needs to get that instance
from the CP somehow. This explains why we have createXYZ methods all
over the place.
When people started implementing CP's, I added a number of basic
implementations of IdAS interfaces (like BasicAttribute). I did this to
make life easier for CP implementers, not intending that an IdAS consumer
would directly instantiate them. In fact, I was thinking we needed to
state that an IdAS consumer must never directly instantiate them, but rather
use the createXYZ factory type methods provided by the CP. This thinking
was based in a belief that the CP could/would potentially create object
instances that had special smarts in them (for example, a CP might choose to
do syntax checking as the IdAS consumer is in the act of adding values to a
phone number attribute).
Ok, so one problem with this model was that the IdAS consumer had to have
an instance of whatever object contained the createXYZ factory method for
whatever it was they needed an instance of. Sometimes the consumer
didn't have anything beyond an IContext instance (for example, when they need
to create a filter containing an attribute assertion, or when they needed to
create a new digital subject). To solve that, I began thinking we should
move all the createXYZ factory methods over to the model package.
Well, in retrospect, I wonder if we should just go ahead and allow
consumers to instantiate things like BasicAttribute and pass them into
functions that take things like IAttribute. This just means the CPs have
to honor the contract (that's already implied). For example, for a method
like doSomething(IAttribute attr) means that the CP (the implementor of
doSomething) must be able to handle any implementation of IAttribute
(rather than only implementations it knows about). For the places where
consumers need to pass in objects (update and filter-based operations), I
think this seems pretty reasonable.
Jim