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

