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]

