[xwiki-devs] [Proposal] Components and svn directory organization
Hi devs, Right now we have: platform/ |_ core/ |_ xwiki-core/ |_ (others)/ |_ plugins/ |_ ... The problem I see is twofold: 1) We can have platform components that are not core components (for example I'd like to commit the office component done by Wang Ning). 2) I'd like that we decide to deprecate the plugins/ system going forward and that all new code only write components. For 1) I'd like to propose: platform/ |_ components/ (contains (others)/ from above) |_ core/ (is the core/xwiki-core from above, to be removed once fully split into components) |_ plugins/ (to be removed once fully split into components) |_ ... 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? Thanks -Vincent
So, if I want to create MyService I'd have to: myservice/ |_ internal/ | |_ DefaultMyService implements MyService | |_ DefaultMyServiceVelocityBridge implements MyServiceVelocityBridge |_ MyService // component interface |_ MyServiceVelocityBridge extends MyService, VelocityBridge // empty And DefaultMyServiceVelocityBridge#doService will call DefaultMyService#doService. Right? Looks great to me. +1
Hi devs,
Right now we have:
platform/ |_ core/ |_ xwiki-core/ |_ (others)/ |_ plugins/ |_ ...
The problem I see is twofold: 1) We can have platform components that are not core components (for example I'd like to commit the office component done by Wang Ning). 2) I'd like that we decide to deprecate the plugins/ system going forward and that all new code only write components.
For 1) I'd like to propose:
platform/ |_ components/ (contains (others)/ from above) |_ core/ (is the core/xwiki-core from above, to be removed once fully split into components) |_ plugins/ (to be removed once fully split into components) |_ ...
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?
Thanks -Vincent
_______________________________________________ devs mailing list [email protected] http://lists.xwiki.org/mailman/listinfo/devs
On Aug 29, 2008, at 9:16 AM, Marius Dumitru Florea wrote:
So, if I want to create MyService I'd have to:
myservice/ |_ internal/ | |_ DefaultMyService implements MyService | |_ DefaultMyServiceVelocityBridge implements MyServiceVelocityBridge |_ MyService // component interface |_ MyServiceVelocityBridge extends MyService, VelocityBridge // empty
And DefaultMyServiceVelocityBridge#doService will call DefaultMyService#doService. Right?
yes exactly except that there's no MyServiceVelocityBridge interface (so only 3 files). The component implementation will just implement VelocityBridge. The reason It'll work (I think) is because the velocity services component will be able to lookup all components implementing VelocityBridge ROLE and register them in the Velocity Context. Since Velocity uses reflection to call the methods it'll work even though the interface doesn't have any methods in it. The pro (side effect but a great one) is that this will prevent anyone from using DefaultMyServiceVelocityBridge from java! (since it would require doing reflection). Thanks -Vincent
Looks great to me. +1
Hi devs,
Right now we have:
platform/ |_ core/ |_ xwiki-core/ |_ (others)/ |_ plugins/ |_ ...
The problem I see is twofold: 1) We can have platform components that are not core components (for example I'd like to commit the office component done by Wang Ning). 2) I'd like that we decide to deprecate the plugins/ system going forward and that all new code only write components.
For 1) I'd like to propose:
platform/ |_ components/ (contains (others)/ from above) |_ core/ (is the core/xwiki-core from above, to be removed once fully split into components) |_ plugins/ (to be removed once fully split into components) |_ ...
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?
Thanks -Vincent
Vincent Massol wrote:
Right now we have:
platform/ |_ core/ |_ xwiki-core/ |_ (others)/ |_ plugins/ |_ ...
The problem I see is twofold: 1) We can have platform components that are not core components (for example I'd like to commit the office component done by Wang Ning). 2) I'd like that we decide to deprecate the plugins/ system going forward and that all new code only write components.
For 1) I'd like to propose:
platform/ |_ components/ (contains (others)/ from above) |_ core/ (is the core/xwiki-core from above, to be removed once fully split into components) |_ plugins/ (to be removed once fully split into components) |_ ...
+1
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? 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. -- Artem Melentyev
On Aug 30, 2008, at 12:15 AM, Artem Melentyev wrote:
Vincent Massol wrote:
Right now we have:
platform/ |_ core/ |_ xwiki-core/ |_ (others)/ |_ plugins/ |_ ...
The problem I see is twofold: 1) We can have platform components that are not core components (for example I'd like to commit the office component done by Wang Ning). 2) I'd like that we decide to deprecate the plugins/ system going forward and that all new code only write components.
For 1) I'd like to propose:
platform/ |_ components/ (contains (others)/ from above) |_ core/ (is the core/xwiki-core from above, to be removed once fully split into components) |_ plugins/ (to be removed once fully split into components) |_ ...
+1
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. What do others think? Thanks -Vincent
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
Vincent Massol wrote:
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(). Two questions :
* How do you do when you want a method from the wrapped service not be callable from velocity ? override and throw a specific exception ? * I guess the velocity bridge would still be the one responsible for checking programming rights, right ? One would have do something like @Programming public void myMethod(){ getWrappedService.myMethod(); } is this correct ? Jerome.
WDYT?
Thanks -Vincent
_______________________________________________ devs mailing list [email protected] http://lists.xwiki.org/mailman/listinfo/devs
On Sep 1, 2008, at 9:38 PM, Jerome Velociter wrote:
Vincent Massol wrote:
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(). Two questions :
* How do you do when you want a method from the wrapped service not be callable from velocity ? override and throw a specific exception ? * I guess the velocity bridge would still be the one responsible for checking programming rights, right ? One would have do something like @Programming public void myMethod(){ getWrappedService.myMethod(); } is this correct ?
Yes one idea we have discussed is to have annotations for rights like: @permission(programming) @permission(admin) etc... But this is separate from the current proposal (although related). There would be another uberspector to check for permissions. Thanks -Vincent
Vincent Massol wrote:
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().
+1 -- Sergiu Dumitriu http://purl.org/net/sergiu/
+1 On Mon, Sep 1, 2008 at 10:22 PM, Vincent Massol <[email protected]> wrote:
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
-- Thomas Mortagne
Vincent Massol wrote:
...
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.
Is wrappedService.class == role-hint? Or what's the difference?
* 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.
How can I disable some bridges? Some configuration option?
* 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?
+1. -- Artem Melentyev
Artem Melentyev wrote:
Vincent Massol wrote:
...
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.
Is wrappedService.class == role-hint? Or what's the difference?
Yes, it is (at the toString() level). wrappedService will be a java object, and not a classname. Right, Vincent?
* 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.
How can I disable some bridges? Some configuration option?
Just edit the corresponding plexus.xml
* 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?
+1.
-- Sergiu Dumitriu http://purl.org/net/sergiu/
Vincent Massol wrote:
Hi devs,
Right now we have:
platform/ |_ core/ |_ xwiki-core/ |_ (others)/ |_ plugins/ |_ ...
The problem I see is twofold: 1) We can have platform components that are not core components (for example I'd like to commit the office component done by Wang Ning). 2) I'd like that we decide to deprecate the plugins/ system going forward and that all new code only write components.
For 1) I'd like to propose:
platform/ |_ components/ (contains (others)/ from above) |_ core/ (is the core/xwiki-core from above, to be removed once fully split into components) |_ plugins/ (to be removed once fully split into components) |_ ...
+1. This means that we can't normally have components that depend on the core, since when building the whole trunks, the component will be built before the core, which is a pre-dependency. But this is a good restriction, anyway.
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".
This looks good. However, what will happen with the VelocityContextInitializer component? Is it to be used only for special purposes, like setting the $doc variables, the $services and other essential elements?
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...
I still prefer the automatic velocity API exposure from the actual java class, using annotations and uberspectors. -- Sergiu Dumitriu http://purl.org/net/sergiu/
Hi Sergiu, On Sep 1, 2008, at 9:07 AM, Sergiu Dumitriu wrote:
Vincent Massol wrote:
Hi devs,
Right now we have:
platform/ |_ core/ |_ xwiki-core/ |_ (others)/ |_ plugins/ |_ ...
The problem I see is twofold: 1) We can have platform components that are not core components (for example I'd like to commit the office component done by Wang Ning). 2) I'd like that we decide to deprecate the plugins/ system going forward and that all new code only write components.
For 1) I'd like to propose:
platform/ |_ components/ (contains (others)/ from above) |_ core/ (is the core/xwiki-core from above, to be removed once fully split into components) |_ plugins/ (to be removed once fully split into components) |_ ...
+1. This means that we can't normally have components that depend on the core, since when building the whole trunks, the component will be built before the core, which is a pre-dependency. But this is a good restriction, anyway.
This is not true. First there won't be any "core" module in the future so that's only a immediate concern. However even if you have components that depen on core that'll still work since maven will know which they are and build them before core.
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".
This looks good. However, what will happen with the VelocityContextInitializer component? Is it to be used only for special purposes, like setting the $doc variables, the $services and other essential elements?
Yes it could be used and the VelocityService thing above could be implemented as a VelocityContextInitializer.
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...
I still prefer the automatic velocity API exposure from the actual java class, using annotations and uberspectors.
I'm experimenting with this. The first step is refactoring the current introspector package to make uberspector components. I have sent you a patch for this for review + some questions since I'm not sure why we have both chainable and linking implementations. Thanks -Vincent
Sergiu Dumitriu wrote:
Vincent Massol wrote:
Hi devs,
Right now we have:
platform/ |_ core/ |_ xwiki-core/ |_ (others)/ |_ plugins/ |_ ...
The problem I see is twofold: 1) We can have platform components that are not core components (for example I'd like to commit the office component done by Wang Ning). 2) I'd like that we decide to deprecate the plugins/ system going forward and that all new code only write components.
For 1) I'd like to propose:
platform/ |_ components/ (contains (others)/ from above) |_ core/ (is the core/xwiki-core from above, to be removed once fully split into components) |_ plugins/ (to be removed once fully split into components) |_ ...
+1. This means that we can't normally have components that depend on the core, since when building the whole trunks, the component will be built before the core, which is a pre-dependency. But this is a good restriction, anyway.
But how is this compatible with the plugins transformation to components? Don't plugins (at least some) use/need the core?
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".
This looks good. However, what will happen with the VelocityContextInitializer component? Is it to be used only for special purposes, like setting the $doc variables, the $services and other essential elements?
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...
I still prefer the automatic velocity API exposure from the actual java class, using annotations and uberspectors.
On Sep 1, 2008, at 9:23 AM, Anca Paula Luca wrote:
Sergiu Dumitriu wrote:
Vincent Massol wrote:
Hi devs,
Right now we have:
platform/ |_ core/ |_ xwiki-core/ |_ (others)/ |_ plugins/ |_ ...
The problem I see is twofold: 1) We can have platform components that are not core components (for example I'd like to commit the office component done by Wang Ning). 2) I'd like that we decide to deprecate the plugins/ system going forward and that all new code only write components.
For 1) I'd like to propose:
platform/ |_ components/ (contains (others)/ from above) |_ core/ (is the core/xwiki-core from above, to be removed once fully split into components) |_ plugins/ (to be removed once fully split into components) |_ ...
+1. This means that we can't normally have components that depend on the core, since when building the whole trunks, the component will be built before the core, which is a pre-dependency. But this is a good restriction, anyway.
But how is this compatible with the plugins transformation to components? Don't plugins (at least some) use/need the core?
Plugins are in plugins/ dir and will stay there until they're transformed into components. Then there's no restriction about depending on core till it's split into small components. Thanks -Vincent
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".
This looks good. However, what will happen with the VelocityContextInitializer component? Is it to be used only for special purposes, like setting the $doc variables, the $services and other essential elements?
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...
I still prefer the automatic velocity API exposure from the actual java class, using annotations and uberspectors.
participants (7)
-
Anca Paula Luca -
Artem Melentyev -
Jerome Velociter -
Marius Dumitru Florea -
Sergiu Dumitriu -
Thomas Mortagne -
Vincent Massol