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]

Reply via email to