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]

