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]

