Skip to main content

Notice: this Wiki will be going read only early in 2024 and edits will no longer be possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.

Jump to: navigation, search

Difference between revisions of "IdAS API Extensibility"

Line 35: Line 35:
 
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.
 
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.
 
|idasimpl=
 
|idasimpl=
<idas description here>
+
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.
 
|cpimpact=
 
|cpimpact=
<cp writer impact here>
+
* 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.
 
|consumerexp=
 
|consumerexp=
<consumer experience here>
+
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
 +
I'm not going to mock the code up
 
}}
 
}}
  
 
{{IdasExtensibilityProposal
 
{{IdasExtensibilityProposal
 
|prop=
 
|prop=
<proposal here>
+
Extension presets
 
|propdesc=
 
|propdesc=
<proposal description here>
+
Allow the caller to pre-load extensions prior to calling a method or methods.
 
|idasimpl=
 
|idasimpl=
<idas description here>
+
* 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.
 
|cpimpact=
 
|cpimpact=
<cp writer impact here>
+
* 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.
 +
|consumerexp=
 +
The IdAS consumer would create the extensions, pass them to setExtensions, and then call the method as normal like:
 +
<pre>
 +
Args[] extensions = {<stuff>};
 +
myContext.setExtensions(extensions);
 +
myContext.getSubject("frank");
 +
</pre>
 +
}}
 +
 
 +
{{IdasExtensibilityProposal
 +
|prop=
 +
extendedOperation method
 +
|propdesc=
 +
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>
 +
|idasimpl=
 +
Add this method to each IdAS interface:
 +
<pre>
 +
/**
 +
* @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);
 +
</pre>
 +
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.
 +
|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]]
 
|consumerexp=
 
|consumerexp=
 
<consumer experience here>
 
<consumer experience here>
 
}}
 
}}

Revision as of 21:28, 30 November 2007

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.
    • There are already nearly 100 methods to deal with
  • Adds another arg to everything
  • IdAS maintainer must remember to always ensure there is an extension param 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

I'm not going 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

CP extender impact

{{{cpextender}}}

IdAS consumer experience

<consumer experience here>

Back to the top