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.
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. Is it just the org.apache.felix.ipojo artifact I need to check out and build on trunk? /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] > >> > >> > >

