Merged context - design view
This paper discusses design issues related to implementation of merged
context. Context may contain:
- subcontexts
- bindings
- attributes related to context
- attributes related to binding
All of them may originally come from originall contexts (Delegates).
Every Delegate has its own priority according its index in array. The
lower index the higher priority. There is one and only one Delegate
with special meaning (ActiveDelegate) with the highest priority on root
context. Subcontexts of root context doesn't need to have
ActiveDelegate, which is created if necessary. Except ActiveDelegate
all other Delegates are considered as read-only. So, all modification
must go into ActiveDelegate including masks. Here is important to
stress that masks are considered to be on ActiveDelegate, where are
created. So, ActiveDelegate is context, where goes:
- newly created 1. - 4.
- modification of 2. - 4.
- delete 1. - 4., which may involve masking
Abreviations:
- ActiveDelegate = A
- read-only Delegates = D
- merged context = M
Principle of merging:
- 1. - 3. are all named and their names must be uniqueue (e.g.
context can contain only one binding with name "port"). All
subcontexts, binding and attributes related to context are plainly
merged according their names with respect to priority of
Delegates
providing 1. - 4.(almost the same as MultiFileSystem does).
- 4. are not merged at all. Attributes are taken from Delegate with
the highest priority. And changes and new attributes goes into
ActiveDelegate.
Operations on context with description
Create subcontext
- if subcontext with passed name already exits, then
ContextException is fired
- mask for subcontext is deleted if existed
- subcontext is created including its parent and all its ancestors
- fired one event SUBCONTEXT_ADDED from parent of newly created
context; this event is delivered to all listeners registered on parent
instance and it's ancestors including root context
Create binding
- mask for binding is deleted if existed
- binding is created on A
- if A doesn't exists, then also A is created
- fired one event BINDING_ADDED from context of newly created
binding; this event is delivered to all listeners registered on related
context and it's ancestors including root context
Create attribute related to context
- mask for attribute is deleted if existed
- attribute is created on A
- if A doesn't exists, then is created
- fired one event ATTRIBUTE_ADDED from context of newly created
attribute; this event is delivered to all listeners registered on
related
context and it's ancestors including root context
Create attribute related to binding
- mask for attribute is deleted if existed
- attribute is created on A
- if A doesn't exists, then also A is created
- if binding doesn't exist on A, then binding is copied from
D with highest priority into A
- fired one event ATTRIBUTE_ADDED from context of newly created
attribute; this event is delivered to all listeners registered on
related
context and it's ancestors including root context
Delete subcontext
- if subcontext with passed name does not exist, then
ContextException is fired
- deleted subcontext from A if exists
- if subcontext exists also on D, then is masked on A, then A must
be created if doesn't exist
- delete of subcontext also means, that its bindings
are lost
forever (means, that later unmasking of subcontext can't cause,
that
previous bindings appear again)
- delete of subcontext also means, that its attributes
are lost
forever (means, that later unmasking of subcontext can't cause, that
previous attributes appear again)
- fired one event SUBCONTEXT_REMOVED from parent of deleted
subcontext; this event is delivered to all listeners registered on
parent
instance and it's ancestors including root context
Delete binding
- never mind if binding with passed name does not exist, then no
ContextException is fired
- deleted binding from A if exists
- if binding exists also on D, then is masked on A, then A must be
created if doesn't exist
- delete of binding also means, that its attributes are
lost forever (means, that later unmasking of binding can't cause,
that previous attributes appear again)
- fired one event BINDING_REMOVED from context of deleted binding;
this event is delivered to all listeners registered on parent
instance and it's ancestors including root context
Delete attribute related to context
- never mind if attribute with passed name does not exist,
then no ContextException is fired
- deleted attribute from A if exists
- if attribute exists also on D, then is masked on A, then A must
be created if doesn't exist
- fired one event ATTRIBUTE_REMOVED from context of deleted
attribute; this event is delivered to all listeners registered on
parent
instance and it's ancestors including root context
Delete attribute related to binding
- never mind if attribute with passed name or binding does not
exist, then no ContextException is fired
- deleted attribute from A if exists
- if attribute exists also on D, then is masked on A, then A must
be created if doesn't exist
- fired
one event ATTRIBUTE_REMOVED from context of deleted attribute; this
event is delivered to all listeners registered on parent
instance and it's ancestors including root context
Modification of binding
- never mind if binding with passed name does not exist, then no
ContextException is fired
- binding is created on A if binding doesn't exist or is modified
on A
- A is created if doesn't exist
- fired one event BINDING_MODIFIED from context of modified
binding; this event is delivered to all listeners registered on parent
instance and it's ancestors including root context
Modification of attribute related to context
- never mind if attribute with passed name does not exist,
then no ContextException is fired
- attribute is created on A if attribute doesn't exist or is
modified on A
- A is created if doesn't exist
- fired
one event ATTRIBUTE_MODIFIED from context of modified attribute; this
event is delivered to all listeners registered on parent
instance and it's ancestors including root context
Modification of attribute related to binding
- never mind if attribute with passed name or binding does not
exist, then no ContextException is fired
- attribute is created on A if attribute doesn't exist or is
modified on A
- if A doesn't exists, then also A is created
- if binding doesn't exist on A, then binding is copied from
D with highest priority into A
- fired
one event ATTRIBUTE_MODIFIED from context of modified attribute; this
event is delivered to all listeners registered on parent
instance and it's ancestors including root context
Masking
- Mask for deleted subcontexts (e.g."projectCtx") is
subcontext sibling with special name ( "projectCtx_implementationDetail").
So, mask for context is again context in the same parent context.
- Mask for deleted binding (e.g."projectBinding")is binding
sibling with special name
("projectBinding_implementationDetail"). So, mask for
binding is again binding in the same context.
- Mask for deleted attribute (e.g."projectAttribute")is
attribute sibling with special name
("projectAttribute_implementationDetail"). So, mask for
attribute is again attribute in the same context for the same
binding.
Resettability
ResettableContext adds new functionality comparing with Context:
- isModified
- hasDefault
- revert
For more information see javadoc documentation. All these method
relates only to bindings. Here are specific information related to
merged context implemenattion:
- binding is considered as modified if there is binding on A
- binding has default value if there is binding on D
- after revert is deleted binding from A
Open issues
Following methods
would be needed in API for clients to identify and/or ignore masking
implementation. It is better to have explicit API rather then leting
clients compare the Strings directly. Not implemented yet.