Skip to main content
Jump to: navigation, search

Difference between revisions of "IdAS API Extensibility"

 
(6 intermediate revisions by 2 users not shown)
Line 1: Line 1:
 +
{{#eclipseproject:technology.higgins|eclipse_custom_style.css}}
 +
[[Image:Higgins_logo_76Wx100H.jpg|right]]
 
This [[https://bugs.eclipse.org/bugs/show_bug.cgi?id=196390 task]] asks for a way to "future-proof" IdAS interfaces by inventing some way that we can introduce new arguments and semantics to existing interface methods without actually revising those methods or adding overloaded versions of them
 
This [[https://bugs.eclipse.org/bugs/show_bug.cgi?id=196390 task]] asks for a way to "future-proof" IdAS interfaces by inventing some way that we can introduce new arguments and semantics to existing interface methods without actually revising those methods or adding overloaded versions of them
  
Line 4: Line 6:
  
 
Here, we list some possible ways of doing this, along with the impact each has on the cp-writer, and what the IdAS consumer's experience would look like.  I believe we can talk about the proposed ways in which extensions are passed/associated with existing methods separately from defining the format of the extension.  For now, we'll assume the format of the extensions is an Arg[]. Arg will be defined by us.
 
Here, we list some possible ways of doing this, along with the impact each has on the cp-writer, and what the IdAS consumer's experience would look like.  I believe we can talk about the proposed ways in which extensions are passed/associated with existing methods separately from defining the format of the extension.  For now, we'll assume the format of the extensions is an Arg[]. Arg will be defined by us.
 +
 +
Further, we'll want to have a page or pages which describe specific extensions.  I'm carving out for [[IdAS Extensions]] that.
 +
 +
===20080612 Update===
 +
On the weekly dev call today, it was decided to go with the first option, with these changes:
 +
* Add the new arg only on an as-needed basis
 +
* Add the new arg by overloading existing methods.  This way existing IdAS consumers continue to function.
  
 
{{IdasExtensibilityProposal
 
{{IdasExtensibilityProposal
Line 16: Line 25:
 
* There are already nearly 100 methods, this could double that.
 
* There are already nearly 100 methods, this could double that.
 
* IdAS maintainer must remember to always ensure there is an extension param (or overloaded method) for newly added methods
 
* IdAS maintainer must remember to always ensure there is an extension param (or overloaded method) for newly added methods
 +
|cpextender=
 +
Somehow, the extender would be presented with the operation being called along with the arguments (including the extensions).  This could occur at different points as the original CP processed the operation.  The extender might implement some traditional IdAS methods and register them so they would be called at these different points by the original CP.  There would probably be the need for the original CP to also pass as an argument (or arguments) cp-specific objects which the extender may make use of to perform different levels of functionality.  For example, an LDAP CP might need to pass an object which would allow the extender to add an LDAP control to.
 
|consumerexp=
 
|consumerexp=
 
Option (B) is very easy and intuitive for the IdAS consumer.
 
Option (B) is very easy and intuitive for the IdAS consumer.
Line 40: Line 51:
 
* For each method implementation, the cp would need to check this registry and call any that are registered in order to discover any extensions the IdAS consumer wishes to present.
 
* For each method implementation, the cp would need to check this registry and call any that are registered in order to discover any extensions the IdAS consumer wishes to present.
 
* At present, no proposal has been made to address the problem of concurrency.  That is, if two threads, or even two different layers of code in the same thread are using the same instance of a class (and thus the same callback registry), there would be unexcpected callbacks registered.
 
* At present, no proposal has been made to address the problem of concurrency.  That is, if two threads, or even two different layers of code in the same thread are using the same instance of a class (and thus the same callback registry), there would be unexcpected callbacks registered.
 +
|cpextender=
 +
See CP extender section on previous proposal.
 
|consumerexp=
 
|consumerexp=
 
The IdAS consumer would:
 
The IdAS consumer would:
Line 66: Line 79:
 
**** Even then, setExtensions may be called, and then execution returns up the call stack before any method was called.
 
**** Even then, setExtensions may be called, and then execution returns up the call stack before any method was called.
 
***** java.lang.SecurityManager.getClassContext can be used to associate the current call stack with each Arg.
 
***** java.lang.SecurityManager.getClassContext can be used to associate the current call stack with each Arg.
 +
|cpextender=
 +
See CP extender section on previous proposal.
 
|consumerexp=
 
|consumerexp=
 
The IdAS consumer would create the extensions, pass them to setExtensions, and then call the method as normal like:
 
The IdAS consumer would create the extensions, pass them to setExtensions, and then call the method as normal like:
Line 96: Line 111:
 
|cpimpact=
 
|cpimpact=
 
The CP would need to implement support for the new extendedOperation.  It could do this in any way it wishes, but a common approach would likely be where the CP overloads each method as described in [[#Add_just_one_more_argument]]. Then it could simply determine which method is being called and call the overloaded version, passing all args it received.
 
The CP would need to implement support for the new extendedOperation.  It could do this in any way it wishes, but a common approach would likely be where the CP overloads each method as described in [[#Add_just_one_more_argument]]. Then it could simply determine which method is being called and call the overloaded version, passing all args it received.
 +
|cpextender=
 +
See CP extender section on previous proposal.
 
|consumerexp=
 
|consumerexp=
 
The IdAS consumer would need to call extendedOperation rather than the normal method being called.  Further, it must place all args into arrays:
 
The IdAS consumer would need to call extendedOperation rather than the normal method being called.  Further, it must place all args into arrays:
Line 110: Line 127:
 
Traditional OO extensions
 
Traditional OO extensions
 
|propdesc=
 
|propdesc=
When new functionality needs to be added, simply extend the interface which needs to be extended.  For example, today we have IContext which declares around 30 methods.  Someone might find a need to pass additional information to 10 of those methods (say it's policy-related data), so they would extend IContext with something like IPolicyContext and add the 10 overloaded methods.
+
When new functionality needs to be added, simply extend the interface which needs to be extended.   
 
+
|idasimpl=
The drawbacks here are method bloat and potentially interface bloat.  For example, suppose we create 3 new interfaces, each extending IContext -- call them IXContext, IYContext, and IZContext.  Now someone wants the functionality of X and Y, so we need to create an IXYContext, then perhaps people want other permutations of X, Y, and Z functionality.  In all we could end up with 7 new interfaces.
+
For example, today we have IContext which declares around 30 methods.  Someone might find a need to pass additional information to 10 of those methods (say it's policy-related data), so they would extend IContext with something like IContextPolicy and add the 10 overloaded methods.
  
 +
The drawbacks here are method bloat and potentially interface bloat.  For example, suppose we create 3 new interfaces, each extending IContext -- call them IContextX, IContextY, and IContextZ.  Now someone wants the functionality of X and Y, so we need to create an IContextXY, then perhaps people want other permutations of X, Y, and Z functionality.  In all we could end up with 7 new interfaces.
 
|cpimpact=
 
|cpimpact=
 
The cp chooses which interface(s) it supports, and simply implements the methods declared by that interface.
 
The cp chooses which interface(s) it supports, and simply implements the methods declared by that interface.
 +
|cpextender=
 +
See CP extender section on previous proposal.
 +
Also, there could be a way for a CP extender to implement and register the sub-interfaces with the original CP, such that methods in the sub-interface instances get called.  The problem with this approach is that while CP extender's code may be able to "wrap" the functionality of the original CP, it would not have access to underlying objects that might be necessary to act upon in order to provide the functionality needed by the extension (think of the LDAP control example)
 
|consumerexp=
 
|consumerexp=
 
A consuming application might need to do something to cause an IdAS CP to produce the correct sub-interface of IContext (or other IdAS Interface).  It may also need to test the instance of an interface to see whether it supports the functionality needed.  Aside from that, it simply calls the methods it wants to call.
 
A consuming application might need to do something to cause an IdAS CP to produce the correct sub-interface of IContext (or other IdAS Interface).  It may also need to test the instance of an interface to see whether it supports the functionality needed.  Aside from that, it simply calls the methods it wants to call.
Line 125: Line 146:
 
|propdesc=
 
|propdesc=
 
<some proposal description>
 
<some proposal description>
 +
|idasimpl=
 +
<implemenatation at the idas level>
 
|cpimpact=
 
|cpimpact=
 
<some description of the impact to context providers>
 
<some description of the impact to context providers>
 +
|cpextender=
 +
<some description of how a cp extender might extend an existing cp to handle extended data/instructions>
 
|consumerexp=
 
|consumerexp=
 
<some description of the impact to IdAS consumers>
 
<some description of the impact to IdAS consumers>
 
}}
 
}}
 +
 +
[[Category:Higgins IdAS]]

Latest revision as of 09:36, 16 December 2008

{{#eclipseproject:technology.higgins|eclipse_custom_style.css}}

Higgins logo 76Wx100H.jpg

This [task] asks for a way to "future-proof" IdAS interfaces by inventing some way that we can introduce new arguments and semantics to existing interface methods without actually revising those methods or adding overloaded versions of them

The terms extension and extensions refer to the additional arguments which would be somehow conveyed to the method being called. An extension should consist of at least an identifier, and possibly some payload (data). The identifier is associated with (defines) both the semantics of an extension as well as with the payload.

Here, we list some possible ways of doing this, along with the impact each has on the cp-writer, and what the IdAS consumer's experience would look like. I believe we can talk about the proposed ways in which extensions are passed/associated with existing methods separately from defining the format of the extension. For now, we'll assume the format of the extensions is an Arg[]. Arg will be defined by us.

Further, we'll want to have a page or pages which describe specific extensions. I'm carving out for IdAS Extensions that.

20080612 Update

On the weekly dev call today, it was decided to go with the first option, with these changes:

  • Add the new arg only on an as-needed basis
  • Add the new arg by overloading existing methods. This way existing IdAS consumers continue to function.

Add just one more argument

Add to each method in the IdAS interfaces (Java Interfaces in org.eclipse.higgins.idas.api) one optional argument which allows the caller to pass extensions.

IdAS implementation

For each IdAS method, either: A: add one argument (Args[] args) as the last param, where args may be null, or B: overload each method by adding this additional param.

CP writer impact

  • Option (B) (which is preferred from the IdAS consumer point of view) causes the cp writer to implement twice as many methods.
    • this is trivial from the CP-writer's POV, just braindead work.
  • There are already nearly 100 methods, this could double that.
  • IdAS maintainer must remember to always ensure there is an extension param (or overloaded method) for newly added methods

CP extender impact

Somehow, the extender would be presented with the operation being called along with the arguments (including the extensions). This could occur at different points as the original CP processed the operation. The extender might implement some traditional IdAS methods and register them so they would be called at these different points by the original CP. There would probably be the need for the original CP to also pass as an argument (or arguments) cp-specific objects which the extender may make use of to perform different levels of functionality. For example, an LDAP CP might need to pass an object which would allow the extender to add an LDAP control to.

IdAS consumer experience

Option (B) is very easy and intuitive for the IdAS consumer. If option (B) is chosen (which is preferred from the consumer's POV, A consumer who might call a method like:

myContext.getSubject("frank");

would do this when calling the same method with an extension:

Args[] extensions = {<stuff>};
myContext.getSubject("frank", extensions);

Use callbacks

Allow the IdAS consumer to set up callbacks which will be called by the CP implementation of a method in order to gather extensions for that method.

IdAS implementation

For each method, or perhaps for sets of methods, a callback method would be defined. The implementation of that method would call the callback in order to gather extensions. This presumes some way of allowing the IdAS consumer to register these callbacks with the context provider so that it knows whether and which callback to call.

CP writer impact

  • The cp would need to implement a registry of callbacks for each method or set of methods.
  • For each method implementation, the cp would need to check this registry and call any that are registered in order to discover any extensions the IdAS consumer wishes to present.
  • At present, no proposal has been made to address the problem of concurrency. That is, if two threads, or even two different layers of code in the same thread are using the same instance of a class (and thus the same callback registry), there would be unexcpected callbacks registered.

CP extender impact

See CP extender section on previous proposal.

IdAS consumer experience

The IdAS consumer would:

  • Create a callback class and instantiate it at runtime
  • Add extensions to the callback class (may be done above)
  • Register the callback class
  • Call the method as normal

<someone needs to mock the code up>

Extension presets

Allow the caller to pre-load extensions prior to calling a method or methods.

IdAS implementation

  • Each IdAS interface would get one additional method called setExtensions(Arg[] extensions);
  • In this case, each Arg could also indicate whether it should be used only once or until setExtensions is called again.

CP writer impact

  • The CP writer would keep track of extensions passed to setExtensions and apply them to the next method(s) called.
  • This has the benefit of not requiring method overloading.
  • The issues around concurrency mentioned above still apply.
    • The CP can handle the thread issue by associating the current thread with each Arg passed in setExtensions and only apply those that were set by the current thread when processing a method.
    • There is still the possibility that code in different parts of the stack might surprise code below (or especially above) by setting a long-lived extension.
      • This could be dealt with by not allowing extensions to be set for more than the next method.
        • Even then, setExtensions may be called, and then execution returns up the call stack before any method was called.
          • java.lang.SecurityManager.getClassContext can be used to associate the current call stack with each Arg.

CP extender impact

See CP extender section on previous proposal.

IdAS consumer experience

The IdAS consumer would create the extensions, pass them to setExtensions, and then call the method as normal like:

Args[] extensions = {<stuff>};
myContext.setExtensions(extensions);
myContext.getSubject("frank");

extendedOperation method

Create one method per class called extendedOperation which takes as arguments: The class method the user wishes to invoke, along with it's normal set of arguments along with the set of extended arguments. </pre>

IdAS implementation

Add this method to each IdAS interface:

/**
 * @param method identifies the intended method to be called 
 * (such as the Method for IDigitalSubject.addAttribute)
 * @param methodArgs the arguments for method
 * @param extended args the additional arguments to be sent to the method
 */
public Object extendedOperation (Method method, Object[] methodArgs, Args[]
extendedArgs);

In addition, each interface would define public static Method identifiers for each method defined by the interface. This makes it easier on the IdAS consumer to call this method.

CP writer impact

The CP would need to implement support for the new extendedOperation. It could do this in any way it wishes, but a common approach would likely be where the CP overloads each method as described in #Add_just_one_more_argument. Then it could simply determine which method is being called and call the overloaded version, passing all args it received.

CP extender impact

See CP extender section on previous proposal.

IdAS consumer experience

The IdAS consumer would need to call extendedOperation rather than the normal method being called. Further, it must place all args into arrays:

Object[] args = {new String("frank")};
Args[] extensions = {<stuff>};
myContext.extendedOperation(IContext.M_GET_SUBJECT_STRING, args, extensions);

This has the benefit that existing methods don't need to be overloaded in the interfaces, but has the disadvantage that the more common an extension's use becomes, the more one sees calls to extendedOperation rather than the intended method.

Traditional OO extensions

When new functionality needs to be added, simply extend the interface which needs to be extended.

IdAS implementation

For example, today we have IContext which declares around 30 methods. Someone might find a need to pass additional information to 10 of those methods (say it's policy-related data), so they would extend IContext with something like IContextPolicy and add the 10 overloaded methods.

The drawbacks here are method bloat and potentially interface bloat. For example, suppose we create 3 new interfaces, each extending IContext -- call them IContextX, IContextY, and IContextZ. Now someone wants the functionality of X and Y, so we need to create an IContextXY, then perhaps people want other permutations of X, Y, and Z functionality. In all we could end up with 7 new interfaces.

CP writer impact

The cp chooses which interface(s) it supports, and simply implements the methods declared by that interface.

CP extender impact

See CP extender section on previous proposal. Also, there could be a way for a CP extender to implement and register the sub-interfaces with the original CP, such that methods in the sub-interface instances get called. The problem with this approach is that while CP extender's code may be able to "wrap" the functionality of the original CP, it would not have access to underlying objects that might be necessary to act upon in order to provide the functionality needed by the extension (think of the LDAP control example)

IdAS consumer experience

A consuming application might need to do something to cause an IdAS CP to produce the correct sub-interface of IContext (or other IdAS Interface). It may also need to test the instance of an interface to see whether it supports the functionality needed. Aside from that, it simply calls the methods it wants to call.

<some proposal title>

<some proposal description>

IdAS implementation

<implemenatation at the idas level>

CP writer impact

<some description of the impact to context providers>

CP extender impact

<some description of how a cp extender might extend an existing cp to handle extended data/instructions>

IdAS consumer experience

<some description of the impact to IdAS consumers>

Back to the top