Thanks Clement. I'll check out trunk and see how far I'll get.

/Bengt


2013/11/29 Clement Escoffier <[email protected]>

> 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