Pierre, Marcel
Thank you guys for the detailed and fast response!
As far as I can see DM is more elegant way, however it requires modification
of legacy code that I would like to avoid.
I’ll try hook solution then. 
Will post the result.

Best Regards,
Vladimir



Marcel Offermans wrote:
> 
> Some comments inline...
> 
> On 15 Mar 2011, at 22:42 , Pierre De Rop wrote:
> 
>> Hi Vladimir,
>> 
>> I'm not sure to understand: when you are talking about "AspectService",
>> are
>> you talking about DependencyManager "AspectService" ?
>> if true, then I don't think it works in your case, because DM
>> AspectService
>> only work if you track  "MetadataProvider" with DependencyManager
>> "ServiceDependency".
>> in other words, I don't think it's possible to mix DM AspectService with
>> DeclarativeService, but may be Marcel have to confirm this ?
> 
> You're right. Aspects that "intercept" services are implemented as
> services with a higher ranking as the original.
> 
> If you have only one original, then a plain service tracker works just
> fine, as it will always return the highest ranked service if you are only
> looking for one service.
> 
> If you have multiple originals, you need to somehow distinguish between
> the N originals and N aspects on top of them. Like Pierre says, if you use
> the service dependencies that are available in the dependency manager,
> this is handled transparantly for you. If you track services yourself, you
> need to do some manual work:
> 
> Whenever a new service is added to the tracker, you need to check if it is
> an aspect on top of an original service or not. Each aspect has an extra
> service property to recognize it and to link it to the original service.
> So if an aspect comes in, you need to add it to your tracker AND hide the
> original service from the consumer of that tracker. Same thing (the other
> way round) if a service is removed.
> 
> The dependency manager actually has a modified ServiceTracker that you can
> use if you want to do that (but not want to use its ServiceDependency).
> 
>> So, coming back to your use case, if you don't want to use DM
>> ServiceDependency for tracking the MetadataProvider, but
>> DeclarativeService
>> (as it seems to be the case),  then may be you could take a look at
>> service
>> hooks ?
> 
> My personal opinion: service hooks are pretty much useless for
> *dynamically* adding an aspect on top of an existing service because the
> hooks *must* be in place before the rest of the framework starts. The
> hooks are not capable of "removing" any services that were already out
> there when an aspect is added. But if you know upfront you want to
> intercept something and you can install the hooks when the framework
> starts, they work just fine.
> 
>> 
>> The following tutorial explains how to intercept all service method
>> invocation using Event/Find Hooks:
>> 
>> http://java.dzone.com/articles/osgi-service-hook-log-all
>> 
>> and you can checkout the sample code from:
>> 
>> svn checkout http://osgiservicelogger.googlecode.com/svn/trunk/
>> 
>> If, however, you would like to consider using DependencyManager
>> ServiceDependency for tracking the MetadataProvider services, then you
>> could
>> implement the following thing:
>> 
>> import org.apache.felix.dm.annotation.api.Component;
>> 
>> @Component
>> public class MetadataProviderTracker {
>>     @ServiceDependency(required=false, removed="unbindMetadataProvider")
>>     protected void bindMetadataProvider(MetadataProvider mp) {
>>         providerMap.put(mp.getType(), mp);
>>     }
>> 
>>     protected void unbindMetadataProvider(MetadataProvider mp) {
>>        providerMap.remove(mp.getType());
>>    }
>> 
>>    // ...
>> }
>> 
>> 
>> and simply define your MetadataProvider interceptor, like this:
>> 
>> @AspectService(ranking = 10 /* the ranking of this Aspect service used to
>> chain aspects in the proper order */ )
>> public class MetadataProviderInterceptor implements MetadataProvider
>> {
>>   /**
>>     * This is the MetadataProvider this interceptor is applying to
>> (injected by reflection).
>>     */
>>    private volatile MetadataProvider originalMetadataProvider;
>> 
>>   public void callMethod() {
>>      // Intercept method call, and eventually invoke
>> this.originalMetadataProvider.callMehod() , if required
>>   }
>> }
>> 
>> 
>> Alternatively, you  can also use AspectService with a real DynamicProxy:
>> 
>> @AspectService(ranking = 10, service=MetadataProvider.class,
>> factoryMethod="create")
>> public class MetadataProviderInterceptor implements InvocationHandler {
>>       static Object create() {
>>            return
>> Proxy.newProxyInstance(MetadataProviderInterceptor.class.getClassLoader(),
>>                                      new Class[] {
>> MetadataProviderInterceptor.class },
>>                                      new MetadataProviderInterceptor());
>>       }
>> 
>>       // Injected by reflection
>>       private volatile MetadataProvider originalMetadataProvider;
>> 
>>      public Object invoke(Object proxy, Method method, Object[] args)
>> throws Throwable {
>>          if (method.getName().equals("callMethod")) {
>>              // Intercept "callMethod"
>>          } else {
>>              return method.invoke(this.originalMetadataProvider, args);
>>          }
>>      }
>> }
>> 
>> 
>> 
>> Dos this correspond to your actual needs ?
>> 
>> Kind Regards;
>> /pierre
>> 
>> 
>> 
>> 
>> 
>> On Mon, Mar 14, 2011 at 4:51 PM, TVladimir
>> <[email protected]>wrote:
>> 
>>> 
>>> Hello,
>>> Could you please suggest solution for the following issue:
>>> 
>>> Description:
>>> There are number of implementations of MetadataProvider interface, these
>>> implementations are collected into map as described below, and then used
>>> by
>>> application logic
>>> 
>>> @Reference(name = "metadataProvider", strategy =
>>> ReferenceStrategy.EVENT,
>>> policy = ReferencePolicy.DYNAMIC, referenceInterface =
>>> MetadataProvider.class, cardinality =
>>> ReferenceCardinality.OPTIONAL_MULTIPLE)
>>> 
>>> 
>>> protected void bindMetadataProvider(MetadataProvider mp) {
>>>  providerMap.put(mp.getType(), mp);
>>> }
>>> 
>>> protected void unbindMetadataProvider(MetadataProvider mp) {
>>>  providerMap.remove(mp.getType());
>>> }
>>> 
>>> 
>>> Task:
>>> I would like to decorate/intercept one of the implementation's method.
>>> If you do: providerMap.get(“type”).callMethod(), callMethod() should be
>>> intercepted.
>>> 
>>> Issue:
>>> AspectService approach doesn’t work here.  When I created  AspectService
>>> for
>>> MetadataProvider interface, “bind” registered all implementations +
>>> aspect
>>> services for all implementations.
>>> 
>>> Any ideas how to make it?
>>> 
>>> Thanks,
>>> Vladimir
>>> 
>>> --
>>> View this message in context:
>>> http://old.nabble.com/AspectService-for-dynamic-reference-tp31145479p31145479.html
>>> Sent from the Apache Felix - Users mailing list archive at Nabble.com.
>>> 
>>> 
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: [email protected]
>>> For additional commands, e-mail: [email protected]
>>> 
>>> 
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [email protected]
> For additional commands, e-mail: [email protected]
> 
> 
> 

-- 
View this message in context: 
http://old.nabble.com/AspectService-for-dynamic-reference-tp31145479p31163077.html
Sent from the Apache Felix - Users mailing list archive at Nabble.com.


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to