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]

Reply via email to