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]

