On Aug 30, 2008, at 12:28 AM, Vincent Massol wrote:

[snip]

>>> For 2) I'd like to propose:
>>>
>>> * Create an interface for Velocity APIs. Something like  
>>> VelocityBridge
>>> (or VelocityAccess or VelocityApi or...). It would be empty.
>>> * Each component that want to be accessed from velocity will need to
>>> implement a component implementing VelocityBridge. It'll have a  
>>> role-
>>> hint being the name under which it'll be access from Velocity.
>>> * Create a VelocityService class (component) which has a single
>>> get(String name) method and which uses the ComponentManager to  
>>> look up
>>> components which implement VelocityBridge using the name as the role
>>> hint.
>>> * Put that VelocityService in the Velocity context under the name
>>> "services".
>>>
>>> In practice this means that users will be able to access all our
>>> components through the VelocityBridge implementations with a syntax
>>> like:
>>>
>>> $services.office.convert(...)
>>> $services.translation.translate(...)
>>> ...
>>>
>>> Note1: We would need to be careful that it would be forbidden for  
>>> any
>>> java code to use a VelocityBridge. This is to ensure all code  
>>> logic is
>>> put into components and not into the bridges. We should use the  
>>> maven
>>> enforcer plugin to enforce this rule.
>>> Note2: This means we'll have 2 APIs to maintain: the velocity one  
>>> (the
>>> bridges) + the "Java"' one (the main components). But I don't see  
>>> any
>>> other way...
>>>
>>> WDYT?
>>
>> Why we can't just proxy "java" api with secure invocation handlers  
>> with
>> using annotation rights as proposed some times ago?
>
> Yes that's a good question. I'm not sure but suddenly it seemed to  
> me easier to implement this way (less magic).
>
> However you're right that this forces to expose the full api in the  
> velocity bridge implementation class.
>
>> Anyway, I think it is easier to not use proxy for some cases,
>> so +1.
>>
>> But I think it should be possible to use only one "java" api for some
>> services.
>
> We should have only 1 mechanism so we need to decide.
>
> The problem with annotation I guess is when there's a strong  
> impedance mismatch between the Java API and the velocity one. In  
> that case there's no method to attach the annotation too although  
> the class could be used in those cases...
>
> The annotation mechanism will require to write some velocity  
> uberspectors to intercept the method calls and redirect to the  
> correct velocity method handler.
>
> To be honest, I'm not sure which solution is best. We should  
> probably take an existing module and see what the velocity API would  
> be for it. We could take the rendering module one.
>
> I'm not ready to do that just now but I'll try to do the exercise  
> next week.

Ok here's what I propose:

* A module can have one or VelocityBridge components
* A VelocityBridge component can override or create new methods
* A VelocityBridge is registered as a component with a role-hint of  
the class being bridged
* A VelocityBridge has a getName() method. That's the name under which  
it'll be known in velocity (more below)
* A VelocityBridge has a getWrappedService() method which returns the  
instance of the class being wrapped.
* There's a MethodSwapUberspector uberspector which has a high  
priority and thus intercepts all calls.
* On init the MethodSwapUberspector looks for all VelocityBridge  
components and stores them in a hashmap indexed on their names.
* When "services.<name>.<method>" is called from Velocity, the  
MethodSwapUberspector gets called and it looks in its hashmap for a  
bridge named <name>. If found it looks for the <method> method in that  
class (with the same signature). If found it calls it. If not found it  
tries to call the method directly by calling it on getWrappedService().

WDYT?

Thanks
-Vincent

_______________________________________________
devs mailing list
[email protected]
http://lists.xwiki.org/mailman/listinfo/devs

Reply via email to