Yes, I think I'm getting close now but it's been a bit more complicated than I expected. I learn a lot about iPojo though.
About triggering a re-compute... In my case The set of accepted services will not change. But my propety "extenders" has changed so The services must still be recomputed. I need to force it. /Bengt Den 3 dec 2013 17:32 skrev "Clement Escoffier" <[email protected] >: > Hi, > > It looks you are making great progresses. > > On 3 déc. 2013, at 17:13, Bengt Rodehav <[email protected]> wrote: > > > Thanks Clement, > > > > When I started using the bundle context retrieved using: > > > > BundleContext bc = model.getComponentInstance().getContext(); > > > > then it started to work even without using the "getWrappedReference()". > Not > > sure why but it does work. > > Yes, the bundle context retrieved this way is an ‘iPOJO-aware’ bundle > context, aware of the transformation aspect. > > > > > I've now added a configuration listener in the open() method that I > remove > > in the close() method. The notifications seem to work as well. > > > > In my listener I try to trigger a recomputing of the service > dependencies > > (that I currently now do in the "getServiceReferences()" method as > follows: > > > > mDependencyModel.invalidateMatchingServices(); > > mDependencyModel.invalidateSelectedServices(); > > > > This seems to trigger a new call to accept() but no call to > > getServiceReferences(). How can I accomplish that? > > First, I think that the first call would be enough. If the set of accepted > services change, then the getServiceReferences should be called. > > Clement > > > > > /Bengt > > > > > > 2013/12/3 Clement Escoffier <[email protected]> > > > >> Hi, > >> > >> The error is ‘expected’ as interceptors are dealing with transformed > >> service references and not (genuine) service references. Try to use > >> `transformed.getWrappedReference()` to retrieve the original reference. > >> > >> Regards, > >> > >> Clement > >> > >> On 3 déc. 2013, at 10:57, Bengt Rodehav <[email protected]> wrote: > >> > >>> I've tried something like this: > >>> > >>> BundleContext bundleContext = > >>> FrameworkUtil.getBundle(IRouteExtender.class).getBundleContext(); > >>> > >>> for (ServiceReference ref : theMatchingRefs) { > >>> IRouteExtender extender = (IRouteExtender) > >> bundleContext.getService(ref); > >>> // Causes exception > >>> System.out.println("Found extender with id: " + > >> extender.getExtenderId()); > >>> } > >>> > >>> But I get the following exception: > >>> > >>> ERROR: Bundle se.digia.connect.services.generic.service [164] > >>> EventDispatcher: Error during dispatch. (java.lang.ClassCastException: > >>> org.apache.felix.ipojo.dependency.impl.TransformedServiceReferenceImpl > >>> cannot be cast to > >>> > org.apache.felix.framework.ServiceRegistrationImpl$ServiceReferenceImpl) > >>> java.lang.ClassCastException: > >>> org.apache.felix.ipojo.dependency.impl.TransformedServiceReferenceImpl > >>> cannot be cast to > >>> org.apache.felix.framework.ServiceRegistrationImpl$ServiceReferenceImpl > >>> at > >>> > >> > org.apache.felix.framework.ServiceRegistry.getService(ServiceRegistry.java:250) > >>> at org.apache.felix.framework.Felix.getService(Felix.java:3420) > >>> at > >>> > >> > org.apache.felix.framework.BundleContextImpl.getService(BundleContextImpl.java:468) > >>> at > >>> > >> > se.digia.connect.service.generic.service.ExtenderInterceptor.__M_calculateExtenders(ExtenderInterceptor.java:104) > >>> at > >>> > >> > se.digia.connect.service.generic.service.ExtenderInterceptor.calculateExtenders(ExtenderInterceptor.java) > >>> at > >>> > >> > se.digia.connect.service.generic.service.ExtenderInterceptor.__M_getServiceReferences(ExtenderInterceptor.java:84) > >>> at > >>> > >> > se.digia.connect.service.generic.service.ExtenderInterceptor.getServiceReferences(ExtenderInterceptor.java) > >>> at > >>> > >> > org.apache.felix.ipojo.dependency.interceptors.DefaultServiceRankingInterceptor.onServiceArrival(DefaultServiceRankingInterceptor.java:61) > >>> at > >>> > >> > org.apache.felix.ipojo.dependency.impl.ServiceReferenceManager.applyRankingOnArrival(ServiceReferenceManager.java:559) > >>> at > >>> > >> > org.apache.felix.ipojo.dependency.impl.ServiceReferenceManager.onNewMatchingService(ServiceReferenceManager.java:510) > >>> at > >>> > >> > org.apache.felix.ipojo.dependency.impl.ServiceReferenceManager.addedService(ServiceReferenceManager.java:496) > >>> at > >>> > org.apache.felix.ipojo.util.Tracker$Tracked.trackAdding(Tracker.java:711) > >>> at > >>> org.apache.felix.ipojo.util.Tracker$Tracked.track(Tracker.java:672) > >>> at > >>> > >> > org.apache.felix.ipojo.util.Tracker$Tracked.serviceChanged(Tracker.java:633) > >>> at > >>> > >> > org.apache.felix.framework.util.EventDispatcher.invokeServiceListenerCallback(EventDispatcher.java:932) > >>> at > >>> > >> > org.apache.felix.framework.util.EventDispatcher.fireEventImmediately(EventDispatcher.java:793) > >>> at > >>> > >> > org.apache.felix.framework.util.EventDispatcher.fireServiceEvent(EventDispatcher.java:543) > >>> at > >>> org.apache.felix.framework.Felix.fireServiceEvent(Felix.java:4260) > >>> at > >> org.apache.felix.framework.Felix.registerService(Felix.java:3275) > >>> at > >>> > >> > org.apache.felix.framework.BundleContextImpl.registerService(BundleContextImpl.java:346) > >>> at > >>> > >> > org.apache.felix.ipojo.IPojoContext.registerService(IPojoContext.java:395) > >>> at > >>> > >> > org.apache.felix.ipojo.handlers.providedservice.ProvidedService.registerService(ProvidedService.java:338) > >>> at > >>> > >> > org.apache.felix.ipojo.handlers.providedservice.ProvidedServiceHandler.__M_stateChanged(ProvidedServiceHandler.java:484) > >>> at > >>> > >> > org.apache.felix.ipojo.handlers.providedservice.ProvidedServiceHandler.stateChanged(ProvidedServiceHandler.java) > >>> at > >>> > org.apache.felix.ipojo.InstanceManager.setState(InstanceManager.java:536) > >>> at > >>> org.apache.felix.ipojo.InstanceManager.start(InstanceManager.java:418) > >>> at > >>> > >> > org.apache.felix.ipojo.ComponentFactory.createInstance(ComponentFactory.java:179) > >>> at > >>> > >> > org.apache.felix.ipojo.IPojoFactory.createComponentInstance(IPojoFactory.java:319) > >>> at > >>> > >> > org.apache.felix.ipojo.IPojoFactory.createComponentInstance(IPojoFactory.java:240) > >>> at > >>> org.apache.felix.ipojo.IPojoFactory.updated(IPojoFactory.java:737) > >>> at > >>> > >> > org.apache.felix.ipojo.ConfigurationTracker.registerFactory(ConfigurationTracker.java:100) > >>> at > >>> > >> > org.apache.felix.ipojo.IPojoFactory.computeFactoryState(IPojoFactory.java:846) > >>> at > >>> > >> > org.apache.felix.ipojo.ComponentFactory.addedService(ComponentFactory.java:400) > >>> at > >>> > org.apache.felix.ipojo.util.Tracker$Tracked.trackAdding(Tracker.java:711) > >>> at > >>> > >> > org.apache.felix.ipojo.util.Tracker$Tracked.trackInitialServices(Tracker.java:596) > >>> at org.apache.felix.ipojo.util.Tracker.open(Tracker.java:210) > >>> at > >>> > >> > org.apache.felix.ipojo.ComponentFactory.starting(ComponentFactory.java:249) > >>> at > >> org.apache.felix.ipojo.IPojoFactory.start(IPojoFactory.java:671) > >>> at > >>> > >> > org.apache.felix.ipojo.extender.internal.linker.ManagedType$ExtensionSupport$1.call(ManagedType.java:229) > >>> at > >>> > >> > org.apache.felix.ipojo.extender.internal.linker.ManagedType$ExtensionSupport$1.call(ManagedType.java:216) > >>> at > >>> > >> > org.apache.felix.ipojo.extender.internal.queue.JobInfoCallable.call(JobInfoCallable.java:114) > >>> at > >>> java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303) > >>> at java.util.concurrent.FutureTask.run(FutureTask.java:138) > >>> at > >>> > >> > java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) > >>> at > >>> > >> > java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) > >>> at java.lang.Thread.run(Thread.java:662) > >>> > >>> Any ideas? > >>> > >>> BTW, the exception is only logged in the console - not in any log > files. > >>> > >>> /Bengt > >>> > >>> > >>> > >>> > >>> 2013/12/3 Bengt Rodehav <[email protected]> > >>> > >>>> I've now tested against trunk and I've come a lot further. Another > >>>> question for you... > >>>> > >>>> I need access to my service object in the getServiceReferences() > method. > >>>> It is possible if I have the BundleContext. In the accept() method I > get > >>>> the BundleContext passed as a parameter but not in the > >>>> getServiceReferences(). Why is that? > >>>> > >>>> How can I access the service object from the ServiceReference in the > >>>> getServiceReferences() method? Perhaps the signature of the > >>>> getServiceReferences() method should be changed to take a > BundleContext > >> as > >>>> well? > >>>> > >>>> /Bengt > >>>> > >>>> > >>>> 2013/11/29 Bengt Rodehav <[email protected]> > >>>> > >>>>> Thanks Clement. I'll check out trunk and see how far I'll get. > >>>>> > >>>>> /Bengt > >>>>> > >>>>> > >>>>> 2013/11/29 Clement Escoffier <[email protected]> > >>>>> > >>>>>> Hi, > >>>>>> On 29 nov. 2013, at 16:21, Bengt Rodehav <[email protected]> wrote: > >>>>>> > >>>>>>> Thanks Clement! > >>>>>>> > >>>>>>> I compared our code it turns out I had a type: I had specified the > >>>>>> handler > >>>>>>> to "org.apache.felix.ipojo.properties" instead of > >>>>>>> "org.apache.felix.ipojo:properties".. I had a period instead of a > >>>>>> colon. > >>>>>>> That explains my NPE. > >>>>>> > >>>>>> I probably did a mistake while explaining. The syntax is > >>>>>> namespace:handlername. > >>>>>> > >>>>>>> > >>>>>>> Now I can also retrieve the property. I can also call the > getValue() > >>>>>> method > >>>>>>> that returns the value in "toString" format. Can't get the > >>>>>> getObjectValue() > >>>>>>> to work though. Looking forward to the new getCurrentValue() > method. > >>>>>> > >>>>>> Unfortunately the getObjectValue only work for immutable properties. > >>>>>> > >>>>>>> > >>>>>>> Is it just the org.apache.felix.ipojo artifact I need to check out > >> and > >>>>>>> build on trunk? > >>>>>> > >>>>>> The following version contains the new method: > >>>>>> > >>>>>> > >> > https://repository.apache.org/content/repositories/snapshots/org/apache/felix/org.apache.felix.ipojo/1.11.1-SNAPSHOT/org.apache.felix.ipojo-1.11.1-20131129.182110-3.jar > >>>>>> > >>>>>> Clement > >>>>>> > >>>>>>> > >>>>>>> /Bengt > >>>>>>> > >>>>>>> > >>>>>>> > >>>>>>> > >>>>>>> 2013/11/29 Clement Escoffier <[email protected]> > >>>>>>> > >>>>>>>> Hi, > >>>>>>>> > >>>>>>>> I’ve done some testing: > >>>>>>>> > >>>>>>>> 1) I’m able to retrieve the properties > >>>>>>>> 2) I’m not able to retrieve the value > >>>>>>>> > >>>>>>>> Here is my accept method: > >>>>>>>> > >>>>>>>> @Override > >>>>>>>> public <S> TransformedServiceReference<S> accept(DependencyModel > >>>>>>>> dependency, BundleContext context, TransformedServiceReference<S> > >>>>>> ref) { > >>>>>>>> ConfigurationHandlerDescription h = > >>>>>>>> (ConfigurationHandlerDescription) > >>>>>>>> dependency.getComponentInstance().getInstanceDescription() > >>>>>>>> > >>>>>>>> .getHandlerDescription("org.apache.felix.ipojo:properties"); > >>>>>>>> > >>>>>>>> if (h == null) { > >>>>>>>> return null; > >>>>>>>> } > >>>>>>>> > >>>>>>>> PropertyDescription description = > >>>>>> h.getPropertyByName(“extenders"); > >>>>>>>> if (description == null) { > >>>>>>>> return null; > >>>>>>>> } > >>>>>>>> > >>>>>>>> System.out.println(description.getValue() + " / " + > >>>>>>>> Arrays.toString( > >>>>>>>> (String[]) description.getCurrentValue())); > >>>>>>>> > >>>>>>>> return ref; > >>>>>>>> } > >>>>>>>> > >>>>>>>> I’ve added the getCurrentValue() to PropertyDescription to > retrieve > >>>>>> the > >>>>>>>> current property value (gonna commit this ASAP). > >>>>>>>> (full code here: https://gist.github.com/cescoffier/7705901) > >>>>>>>> > >>>>>>>> Clement > >>>>>>>> > >>>>>>>> On 28 nov. 2013, at 15:06, Bengt Rodehav <[email protected]> > wrote: > >>>>>>>> > >>>>>>>>> Thanks! > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> 2013/11/28 Clement Escoffier <[email protected]> > >>>>>>>>> > >>>>>>>>>> > >>>>>>>>>> On 28 nov. 2013, at 14:36, Bengt Rodehav <[email protected]> > >> wrote: > >>>>>>>>>> > >>>>>>>>>>> Hello Clement, > >>>>>>>>>>> > >>>>>>>>>>> I changed to the following line: > >>>>>>>>>>> > >>>>>>>>>>> PropertyDescription[] propDescs = > >>>>>>>>>>> configHandlerDescription.getProperties(); > >>>>>>>>>>> > >>>>>>>>>>> But I still get an NPE. Have you tried to call these methods > from > >>>>>>>> within > >>>>>>>>>> an > >>>>>>>>>>> interceptor? > >>>>>>>>>> > >>>>>>>>>> Not this method, but I did something pretty similar. Will > >>>>>> investigate to > >>>>>>>>>> see why you get an NPE. > >>>>>>>>>> > >>>>>>>>>> Clement > >>>>>>>>>> > >>>>>>>>>>> > >>>>>>>>>>> /Bengt > >>>>>>>>>>> > >>>>>>>>>>> > >>>>>>>>>>> 2013/11/28 Clement Escoffier <[email protected]> > >>>>>>>>>>> > >>>>>>>>>>>> > >>>>>>>>>>>> On 28 nov. 2013, at 12:17, Bengt Rodehav <[email protected]> > >>>>>> wrote: > >>>>>>>>>>>> > >>>>>>>>>>>>> Hello again Clement! > >>>>>>>>>>>>> > >>>>>>>>>>>>> I was away on business yesterday which is why I'm late > >> replying. > >>>>>>>>>>>>> > >>>>>>>>>>>>> I've come a bit further now but still have problems accessing > >> my > >>>>>>>>>>>>> component's "extenders" property. Here is what my code looks > >> like > >>>>>>>> now: > >>>>>>>>>>>>> > >>>>>>>>>>>>> * public List<ServiceReference> > >>>>>> getServiceReferences(DependencyModel > >>>>>>>>>>>>> theDependencyModel,* > >>>>>>>>>>>>> * List<ServiceReference> theMatching) {* > >>>>>>>>>>>>> > >>>>>>>>>>>>> * ComponentInstance instance = > >>>>>>>>>>>>> theDependencyModel.getComponentInstance();* > >>>>>>>>>>>>> * InstanceDescription instanceDescription = > >>>>>>>>>>>>> instance.getInstanceDescription();* > >>>>>>>>>>>>> * ComponentTypeDescription componentTypeDescription = > >>>>>>>>>>>>> instanceDescription.getComponentDescription();* > >>>>>>>>>>>>> * String factoryName = > >>>>>>>>>>>>> componentTypeDescription.getFactory().getFactoryName();* > >>>>>>>>>>>>> > >>>>>>>>>>>>> * if (FACTORY_NAME.equals(factoryName)) {* > >>>>>>>>>>>>> * System.out.println("Found a GenericService2");* > >>>>>>>>>>>>> * ConfigurationHandlerDescription > >> configHandlerDescription = > >>>>>>>>>>>>> (ConfigurationHandlerDescription) instanceDescription* > >>>>>>>>>>>>> * > >>>>>>>>>> .getHandlerDescription("org.apache.felix.ipojo.properties");* > >>>>>>>>>>>>> * int state = instanceDescription.getState();* > >>>>>>>>>>>>> * System.out.println("State: " + state);* > >>>>>>>>>>>>> * if(ComponentInstance.VALID == > >>>>>> instanceDescription.getState()) > >>>>>>>> {* > >>>>>>>>>>>>> * PropertyDescription propDesc = > >>>>>>>>>>>>> configHandlerDescription.getPropertyByName("extenders"); // > >> NPE* > >>>>>>>>>>>>> * if(propDesc != null) {* > >>>>>>>>>>>>> * String extenders = propDesc.getValue();* > >>>>>>>>>>>>> * System.out.println("Extenders: " + extenders);* > >>>>>>>>>>>>> * }* > >>>>>>>>>>>>> * else {* > >>>>>>>>>>>>> * System.out.println("Extenders is null");* > >>>>>>>>>>>>> * }* > >>>>>>>>>>>>> * }* > >>>>>>>>>>>>> * }* > >>>>>>>>>>>>> > >>>>>>>>>>>>> I check the factory name to determine if this is a component > >>>>>> that I > >>>>>>>>>>>> should > >>>>>>>>>>>>> intercept. Presently I wait until the component is valid but > >> I'm > >>>>>> not > >>>>>>>>>> sure > >>>>>>>>>>>>> if I can wait since my interceptor has to kick in before > that. > >>>>>>>>>> Presently > >>>>>>>>>>>> I > >>>>>>>>>>>>> get a null pointer exception when I try to retrieve my > >> property. > >>>>>> Do > >>>>>>>> you > >>>>>>>>>>>>> have any idea why? It doesn't seem possible to retrieve > >>>>>> properties at > >>>>>>>>>>>> this > >>>>>>>>>>>>> pont. > >>>>>>>>>>>> > >>>>>>>>>>>> Did you try to inter ate over the set of properties and see > what > >>>>>> are > >>>>>>>>>> they ? > >>>>>>>>>>>> > >>>>>>>>>>>>> > >>>>>>>>>>>>> I also noticed that the method PropertyDescription.getValue() > >>>>>> always > >>>>>>>>>>>>> returns a String. In my case the underlying object is an > array > >> of > >>>>>>>>>> String > >>>>>>>>>>>>> (String[]). Is it possible to get the value in the correct > >> type? > >>>>>>>>>>>> > >>>>>>>>>>>> Yes, there is a getObjectValue(BundleContext context) method, > >> but > >>>>>> you > >>>>>>>>>> need > >>>>>>>>>>>> to give a bundle context object used if it needs to load > >> classes. > >>>>>>>>>>>> > >>>>>>>>>>>> Clement > >>>>>>>>>>>> > >>>>>>>>>>>>> > >>>>>>>>>>>>> /Bengt > >>>>>>>>>>>>> > >>>>>>>>>>>>> > >>>>>>>>>>>>> > >>>>>>>>>>>>> > >>>>>>>>>>>>> > >>>>>>>>>>>>> > >>>>>>>>>>>>> > >>>>>>>>>>>>> > >>>>>>>>>>>>> > >>>>>>>>>>>>> > >>>>>>>>>>>>> > >>>>>>>>>>>>> > >>>>>>>>>>>>> > >>>>>>>>>>>>> > >>>>>>>>>>>>> > >>>>>>>>>>>>> > >>>>>>>>>>>>> > >>>>>>>>>>>>> > >>>>>>>>>>>>> > >>>>>>>>>>>>> > >>>>>>>>>>>>> > >>>>>>>>>>>>> > >>>>>>>>>>>>> > >>>>>>>>>>>>> > >>>>>>>>>>>>> > >>>>>>>>>>>>> 2013/11/27 Clement Escoffier <[email protected]> > >>>>>>>>>>>>> > >>>>>>>>>>>>>> Hi, > >>>>>>>>>>>>>> > >>>>>>>>>>>>>> On 26 nov. 2013, at 16:00, Bengt Rodehav <[email protected] > > > >>>>>> wrote: > >>>>>>>>>>>>>> > >>>>>>>>>>>>>>> I'm getting a bit closer regarding the interceptors. Still > >> two > >>>>>>>>>> problems > >>>>>>>>>>>>>> for > >>>>>>>>>>>>>>> me: > >>>>>>>>>>>>>>> > >>>>>>>>>>>>>>> a) I still don't understand how to get hold of my > intercepted > >>>>>>>>>> instance > >>>>>>>>>>>>>> from > >>>>>>>>>>>>>>> within my interceptor. I get a reference to a > DependencyModel > >>>>>> from > >>>>>>>>>>>> which > >>>>>>>>>>>>>> I > >>>>>>>>>>>>>>> can get a ComponentInstance. But how do I go from there to > my > >>>>>>>>>>>> ComponentA > >>>>>>>>>>>>>>> class. I need to access the property "extenders" in order > for > >>>>>> my > >>>>>>>>>>>>>>> interceptor to do its job. > >>>>>>>>>>>>>>> > >>>>>>>>>>>>>> > >>>>>>>>>>>>>> It depends how how is managed the extender property, let’s > >>>>>> imagine > >>>>>>>>>> it’s > >>>>>>>>>>>> a > >>>>>>>>>>>>>> @Property. In this case, from the Dependency Model, you can > >>>>>> retrieve > >>>>>>>>>> the > >>>>>>>>>>>>>> component instance. From the instance, you have access to > the > >>>>>>>>>>>> introspection > >>>>>>>>>>>>>> layer (getInstanceDescription()), which let you analyze the > >>>>>> iPOJO > >>>>>>>>>>>> container. > >>>>>>>>>>>>>> > >>>>>>>>>>>>>> To be a bit more clear, let’s see some code: > >>>>>>>>>>>>>> > >>>>>>>>>>>>>> //First retrieve the configuration handler description from > >> the > >>>>>>>>>> instance > >>>>>>>>>>>>>> container: > >>>>>>>>>>>>>> ConfigurationHandlerDescription description = > >>>>>>>>>>>>>> (ConfigurationHandlerDescription) > >>>>>>>>>>>>>> > >>>>>>>>>>>> > >>>>>>>>>> > >>>>>>>> > >>>>>> > >> > model.getComponentInstance().getInstanceDescription().getHandlerDescription("org.apache.felix.ipojo.properties”); > >>>>>>>>>>>>>> // Find the extenders property > >>>>>>>>>>>>>> String extenders = > >>>>>>>>>>>> description.getPropertyByName("extenders").getValue(); > >>>>>>>>>>>>>> // You have your value ! > >>>>>>>>>>>>>> > >>>>>>>>>>>>>>> b) Also, when the property "extenders" is changed, I need > to > >>>>>> force > >>>>>>>>>> the > >>>>>>>>>>>>>>> interceptor to recalculate the dependencies. How can I > >>>>>> accomplish > >>>>>>>>>> that? > >>>>>>>>>>>>>> > >>>>>>>>>>>>>> It also depends on how this reconfiguration happen. Let’s > say > >>>>>> that > >>>>>>>> the > >>>>>>>>>>>>>> instance is reconfigured from the configuration admin or > iPOJO > >>>>>>>>>>>>>> reconfiguration abilities. In these case being notified is > >> quite > >>>>>>>>>>>> simple, as > >>>>>>>>>>>>>> you can register a ConfigurationListener on the > >>>>>>>>>>>>>> ConfigurationHandlerDescription object: > >>>>>>>>>>>>>> > >>>>>>>>>>>>>> description.addListener(new ConfigurationListener() { > >>>>>>>>>>>>>> public void configurationChanged(ComponentInstance > >>>>>>>> instance, > >>>>>>>>>>>>>> Map<String, Object> configuration) { > >>>>>>>>>>>>>> // The extender property may have been modified > >>>>>>>>>>>>>> } > >>>>>>>>>>>>>> }); > >>>>>>>>>>>>>> > >>>>>>>>>>>>>> Don’t forget to unregister the listener when the interceptor > >> is > >>>>>>>>>>>> unplugged > >>>>>>>>>>>>>> from the instance. > >>>>>>>>>>>>>> > >>>>>>>>>>>>>>> > >>>>>>>>>>>>>>> Getting deeper into iPojo than I've been before… > >>>>>>>>>>>>>> > >>>>>>>>>>>>>> It’s just the beginning…. (contributions are welcome if you > >> see > >>>>>> some > >>>>>>>>>>>>>> dark(er) area) > >>>>>>>>>>>>>> > >>>>>>>>>>>>>>> > >>>>>>>>>>>>>>> /Bengt > >>>>>>>>>>>>>>> > >>>>>>>>>>>>>>> > >>>>>>>>>>>>>>> 2013/11/26 Bengt Rodehav <[email protected]> > >>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>> Thanks Clement! > >>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>> 2013/11/26 Clement Escoffier <[email protected] > > > >>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>> Hi, > >>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>> On 25 nov. 2013, at 20:19, Bengt Rodehav < > >> [email protected]> > >>>>>>>>>> wrote: > >>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>>> Hello Clement and as always thanks for your detailed > >> answer! > >>>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>> You’re welcome. > >>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>>> It does seem a bit complicated to "require" an > >> interceptor. > >>>>>>>>>> Perhaps > >>>>>>>>>>>> an > >>>>>>>>>>>>>>>>>> easier way of doing this might be possible in the > future. > >>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>> I think it would be a good addition. Thinking about it. > >>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>>> Anyway, I'm not > >>>>>>>>>>>>>>>>>> exactly sure that I understood what you meant. Just to > >>>>>> clarify: > >>>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>>> My Component A (the component to be intercepted) has the > >>>>>>>> following > >>>>>>>>>>>>>> code: > >>>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>>> @Property(name = "extenders", mandatory = false) > >>>>>>>>>>>>>>>>>> private String[] mExtenderIds; > >>>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>>> @Requires(optional = true, id = "extenders") > >>>>>>>>>>>>>>>>>> private IExtender[] mExtenders; > >>>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>>> Do you mean that I should put a filter on the @Requires > >> with > >>>>>>>>>>>>>>>>> id="extenders" > >>>>>>>>>>>>>>>>>> (the intercepted = true) so that it can only be > satisfied > >>>>>> if my > >>>>>>>>>>>>>>>>> interceptor > >>>>>>>>>>>>>>>>>> has added that property? > >>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>> Exactly. > >>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>>> But how do I then handle the situation where my > Component > >> A > >>>>>> does > >>>>>>>>>> not > >>>>>>>>>>>>>>>>>> require any extenders? In that case I was planning on > >>>>>> setting > >>>>>>>> the > >>>>>>>>>>>>>>>>>> dependency to optional to make my instance valid without > >> any > >>>>>>>>>>>>>> extenders. > >>>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>>> Or, perhaps I could first set the @Requires to mandatory > >>>>>> (with > >>>>>>>> the > >>>>>>>>>>>>>>>>> filter): > >>>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>>> @Requires(optional = false, id = "extenders", > >>>>>>>>>>>>>>>>> filter="(intercepted=true)") > >>>>>>>>>>>>>>>>>> private IExtender[] mExtenders; > >>>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>>> Then, if my interceptor sees that the instance does not > >>>>>> require > >>>>>>>>>> any > >>>>>>>>>>>>>>>>>> extenders it can set the dependency to become optional. > >> This > >>>>>>>> way I > >>>>>>>>>>>>>> both > >>>>>>>>>>>>>>>>>> require the interceptor (via the filter) and I ensure > that > >>>>>> the > >>>>>>>>>> only > >>>>>>>>>>>>>> way > >>>>>>>>>>>>>>>>> to > >>>>>>>>>>>>>>>>>> allow the instance to be valid without the dependency is > >> if > >>>>>> the > >>>>>>>>>>>>>>>>> interceptor > >>>>>>>>>>>>>>>>>> has explicitly set the dependency to optional. > >>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>> That would work. You can change the optionality status of > >> the > >>>>>>>>>>>>>> dependency > >>>>>>>>>>>>>>>>> from the dependency model you get in the interceptor. > >>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>> Regards, > >>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>> Clement > >>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>>> /Bengt > >>>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>>> 2013/11/25 Clement Escoffier < > [email protected] > >>> > >>>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>>>> Hi, > >>>>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>>>> On 25 nov. 2013, at 11:04, Bengt Rodehav < > >>>>>> [email protected]> > >>>>>>>>>>>> wrote: > >>>>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>>>>> I've started to investigate using iPojo interceptors. > >> I'm > >>>>>>>> using > >>>>>>>>>>>>>> iPojo > >>>>>>>>>>>>>>>>>>>> version 1.11.0. I want to accomplish the following: > >>>>>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>>>>> Component A can be "extended" by specifying a list of > >>>>>>>> (required) > >>>>>>>>>>>>>>>>>>>> "extenders" (actually their id's), like this: > >>>>>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>>>>> @Property(name = "extenders", mandatory = false) > >>>>>>>>>>>>>>>>>>>> private String[] mExtenderIds; > >>>>>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>>>>> @Requires(optional = true, id = "extenders") > >>>>>>>>>>>>>>>>>>>> private IExtender[] mExtenders; > >>>>>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>>>>> The property is optional but if any extenderId's are > >>>>>> listed > >>>>>>>> then > >>>>>>>>>>>> the > >>>>>>>>>>>>>>>>>>>> @Requires should require that IExtender's with the > >>>>>>>> corresponding > >>>>>>>>>>>>>>>>>>> extenderId > >>>>>>>>>>>>>>>>>>>> is started. > >>>>>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>>>>> The IExtender interface contains the following method: > >>>>>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>>>>> public String getExtenderId(); > >>>>>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>>>>> Thus, every extender has an extenderId and if that id > is > >>>>>>>> listed > >>>>>>>>>>>> in a > >>>>>>>>>>>>>>>>>>>> components "extender" property then the corresponding > >>>>>> service > >>>>>>>>>>>> should > >>>>>>>>>>>>>>>>> be > >>>>>>>>>>>>>>>>>>>> required, otherwise not. > >>>>>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>>>>> My idea (actually Clement's idea from a previous > >>>>>> conversation > >>>>>>>> on > >>>>>>>>>>>>>> this > >>>>>>>>>>>>>>>>>>>> list). is to use a RankingInterceptor that returns an > >>>>>> empty > >>>>>>>>>> array > >>>>>>>>>>>>>>>>> until > >>>>>>>>>>>>>>>>>>> all > >>>>>>>>>>>>>>>>>>>> required services are present. > >>>>>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>>>>> I think this is doable but in order for my > >>>>>> RankingInterceptor > >>>>>>>> to > >>>>>>>>>>>>>>>>> work, it > >>>>>>>>>>>>>>>>>>>> must have access to the component's "extenders" > >> property. > >>>>>> It > >>>>>>>>>> would > >>>>>>>>>>>>>>>>> then > >>>>>>>>>>>>>>>>>>> go > >>>>>>>>>>>>>>>>>>>> through all the services implementing the IExtender > >>>>>> interface > >>>>>>>>>> and > >>>>>>>>>>>> if > >>>>>>>>>>>>>>>>>>> there > >>>>>>>>>>>>>>>>>>>> are extenders corresponding to the required > extenderId's > >>>>>> it > >>>>>>>>>> would > >>>>>>>>>>>>>>>>> return > >>>>>>>>>>>>>>>>>>>> all of those, otherwise it would return an empty list. > >>>>>> Also, > >>>>>>>> if > >>>>>>>>>> a > >>>>>>>>>>>>>>>>> list of > >>>>>>>>>>>>>>>>>>>> extenderId's was specified, then the service > dependency > >>>>>> is set > >>>>>>>>>> to > >>>>>>>>>>>>>>>>>>>> mandatory, otherwise to optional. > >>>>>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>>>>> My problem is how to gain access to the configuration > >>>>>> property > >>>>>>>>>>>> (the > >>>>>>>>>>>>>>>>>>>> "extenders" property) of my component from the > >>>>>> interceptor. > >>>>>>>> How > >>>>>>>>>>>> can > >>>>>>>>>>>>>> I > >>>>>>>>>>>>>>>>> do > >>>>>>>>>>>>>>>>>>>> this? > >>>>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>>>> When the interceptor is hooked to a dependency, it > >>>>>> receives the > >>>>>>>>>>>>>>>>> dependency > >>>>>>>>>>>>>>>>>>> model object. From this object you can retrieve the > >>>>>> component > >>>>>>>>>>>>>> instance > >>>>>>>>>>>>>>>>> and > >>>>>>>>>>>>>>>>>>> get the introspection metadata. > >>>>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>>>>> Another question I have is how to make sure that the > >>>>>>>> interceptor > >>>>>>>>>>>> is > >>>>>>>>>>>>>>>>>>> active. > >>>>>>>>>>>>>>>>>>>> If the interceptor is not active then my component > could > >>>>>>>> become > >>>>>>>>>>>>>>>>>>> erroneously > >>>>>>>>>>>>>>>>>>>> valid. Would it be feasible to have a mandatory > >>>>>> dependency on > >>>>>>>>>> the > >>>>>>>>>>>>>>>>>>>> interceptor? > >>>>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>>>> Unfortunately not, at least not easily. What you can do > >> is > >>>>>> a > >>>>>>>>>>>>>>>>> combination > >>>>>>>>>>>>>>>>>>> between a filter and two interceptors: the ranking > >>>>>> interceptors > >>>>>>>>>> as > >>>>>>>>>>>>>> you > >>>>>>>>>>>>>>>>> did, > >>>>>>>>>>>>>>>>>>> and a tracking interceptor. Let me explain: > >>>>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>>>> Let’s imagine your consumer with your service > dependency. > >>>>>> Add a > >>>>>>>>>>>>>> filter > >>>>>>>>>>>>>>>>>>> that will be resolved only if your interceptor is > there, > >>>>>>>>>> something > >>>>>>>>>>>>>>>>> like: > >>>>>>>>>>>>>>>>>>> (intercepted=true). > >>>>>>>>>>>>>>>>>>> Your interceptor implement both tracking and ranking > >>>>>>>>>> interceptors. > >>>>>>>>>>>>>> When > >>>>>>>>>>>>>>>>>>> the accept method is called on your interceptor, it > can > >>>>>>>>>>>> ‘transform’ > >>>>>>>>>>>>>>>>> the > >>>>>>>>>>>>>>>>>>> original service reference to add the ‘intercepted’ > >>>>>> property > >>>>>>>>>>>>>>>>>>> (ref.addProperty(“intercepted”, true);) This modified > >>>>>> service > >>>>>>>>>>>>>> reference > >>>>>>>>>>>>>>>>>>> matches your filter. Then, do your ranking policy are > we > >>>>>>>>>> discussed. > >>>>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>>>> This solution ensure that your dependency can only be > >>>>>> resolved > >>>>>>>> if > >>>>>>>>>>>>>> your > >>>>>>>>>>>>>>>>>>> interceptor is there. Indeed without the interceptor, > the > >>>>>>>> filter > >>>>>>>>>>>> does > >>>>>>>>>>>>>>>>> not > >>>>>>>>>>>>>>>>>>> match. > >>>>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>>>> Regards, > >>>>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>>>> Clement > >>>>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>>>>> /Bengt > >>>>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>>>> > >>>>>>>>>>>> > >>>>>> > --------------------------------------------------------------------- > >>>>>>>>>>>>>>>>>>> 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] > >>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>>> > >>>>>>>>>>>>>>>> > >>>>>>>>>>>>>> > >>>>>>>>>>>>>> > >>>>>>>>>>>>>> > >>>>>>>> > >> --------------------------------------------------------------------- > >>>>>>>>>>>>>> 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] > >>>>>>>>>>>> > >>>>>>>>>>>> > >>>>>>>>>> > >>>>>>>>>> > >>>>>>>>>> > >>>>>> > --------------------------------------------------------------------- > >>>>>>>>>> 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] > >>>>>> > >>>>>> > >>>>> > >>>> > >> > >> > >> --------------------------------------------------------------------- > >> 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] > >

