Skip to main content
Jump to: navigation, search

IdAS API Extensibility

Revision as of 20:38, 19 December 2007 by Jimse.novell.com (Talk | contribs)

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.

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

{{{cpextender}}}

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

{{{cpextender}}}

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

{{{cpextender}}}

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

{{{cpextender}}}

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

{{{cpextender}}}

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

{{{idasimpl}}}

CP writer impact

<some description of the impact to context providers>

CP extender impact

{{{cpextender}}}

IdAS consumer experience

<some description of the impact to IdAS consumers>

Back to the top