On 3 déc. 2013, at 19:23, Bengt Rodehav <[email protected]> wrote: > 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.
Then calling mDependencyModel.invalidateSelectedServices() should make it work. I will check why it’s not called. Regards, Clement > > /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] >> >> --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]

