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] > >

