Return-Path: X-Original-To: apmail-felix-users-archive@minotaur.apache.org Delivered-To: apmail-felix-users-archive@minotaur.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id B1CCD10EFD for ; Thu, 28 Nov 2013 11:18:36 +0000 (UTC) Received: (qmail 43523 invoked by uid 500); 28 Nov 2013 11:18:33 -0000 Delivered-To: apmail-felix-users-archive@felix.apache.org Received: (qmail 43434 invoked by uid 500); 28 Nov 2013 11:18:23 -0000 Mailing-List: contact users-help@felix.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: users@felix.apache.org Delivered-To: mailing list users@felix.apache.org Received: (qmail 43426 invoked by uid 99); 28 Nov 2013 11:18:20 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 28 Nov 2013 11:18:20 +0000 X-ASF-Spam-Status: No, hits=1.5 required=5.0 tests=HTML_MESSAGE,RCVD_IN_DNSWL_LOW,SPF_PASS X-Spam-Check-By: apache.org Received-SPF: pass (nike.apache.org: domain of bengt.rodehav@gmail.com designates 209.85.160.50 as permitted sender) Received: from [209.85.160.50] (HELO mail-pb0-f50.google.com) (209.85.160.50) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 28 Nov 2013 11:18:13 +0000 Received: by mail-pb0-f50.google.com with SMTP id rr13so12326017pbb.23 for ; Thu, 28 Nov 2013 03:17:52 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:sender:in-reply-to:references:date:message-id:subject :from:to:content-type; bh=5wuQtJknSki61Znd48e2E6yMpMb76d2wam9wdV4pVEY=; b=wYp3493kCkTpjm2rmc4DXv8RjYtMi82wd/5fm0Qe3uYbnt8TiOe3AnUI63RQbnjE8v Jwi9nMOzRDhF/9yPJ9I1oxtmlHRvJX30fDgbjd2fzFKjkG2ppi4YB/r3Mn5avdkCPxPv jU523ZT9xhGwmAFs+FtNYIaGgILlFkq+wZPgQndh5WupLSYizlEgZyUAUDTgLRjUMgKV UphS5WOIfI2z+DK+GJx7dvxfTRU8K0CrfoUKCHXMaWVUQK/QlJu+AcyhhOEDwuWgK/pj e7DgbmVETeDgKH/0k3zPiUP3zRl9iQJHAQNksVfrRSS9aA26MrM0xc99V7pE68m5V6AW cV9g== MIME-Version: 1.0 X-Received: by 10.68.204.193 with SMTP id la1mr10237976pbc.159.1385637472206; Thu, 28 Nov 2013 03:17:52 -0800 (PST) Sender: bengt.rodehav@gmail.com Received: by 10.70.55.196 with HTTP; Thu, 28 Nov 2013 03:17:52 -0800 (PST) In-Reply-To: References: <145F5DCA-6683-49A4-B414-619B09739577@gmail.com> <955C2A92-DBAF-4F0E-8B97-FDA83E25DAC0@gmail.com> Date: Thu, 28 Nov 2013 12:17:52 +0100 X-Google-Sender-Auth: vDM63rUFJfrk4O3KzSmUeQWxHA0 Message-ID: Subject: Re: Using iPojo interceptors From: Bengt Rodehav To: "users@felix.apache.org" Content-Type: multipart/alternative; boundary=e89a8ffbae9b51845904ec3addcf X-Virus-Checked: Checked by ClamAV on apache.org --e89a8ffbae9b51845904ec3addcf Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: quoted-printable 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 getServiceReferences(DependencyModel theDependencyModel,* * List theMatching) {* * ComponentInstance instance =3D theDependencyModel.getComponentInstance();* * InstanceDescription instanceDescription =3D instance.getInstanceDescription();* * ComponentTypeDescription componentTypeDescription =3D instanceDescription.getComponentDescription();* * String factoryName =3D componentTypeDescription.getFactory().getFactoryName();* * if (FACTORY_NAME.equals(factoryName)) {* * System.out.println("Found a GenericService2");* * ConfigurationHandlerDescription configHandlerDescription =3D (ConfigurationHandlerDescription) instanceDescription* * .getHandlerDescription("org.apache.felix.ipojo.properties");* * int state =3D instanceDescription.getState();* * System.out.println("State: " + state);* * if(ComponentInstance.VALID =3D=3D instanceDescription.getState()) {* * PropertyDescription propDesc =3D configHandlerDescription.getPropertyByName("extenders"); // NPE* * if(propDesc !=3D null) {* * String extenders =3D 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. 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? /Bengt 2013/11/27 Clement Escoffier > Hi, > > On 26 nov. 2013, at 16:00, Bengt Rodehav 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 whic= h > I > > can get a ComponentInstance. But how do I go from there to my Component= A > > 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=92s imagine it= =92s a > @Property. In this case, from the Dependency Model, you can retrieve the > component instance. From the instance, you have access to the introspecti= on > layer (getInstanceDescription()), which let you analyze the iPOJO contain= er. > > To be a bit more clear, let=92s see some code: > > //First retrieve the configuration handler description from the instance > container: > ConfigurationHandlerDescription description =3D > (ConfigurationHandlerDescription) > model.getComponentInstance().getInstanceDescription().getHandlerDescripti= on("org.apache.felix.ipojo.properties=94); > // Find the extenders property > String extenders =3D 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=92s 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 configuration) { > // The extender property may have been modified > } > }); > > Don=92t forget to unregister the listener when the interceptor is unplugg= ed > from the instance. > > > > > Getting deeper into iPojo than I've been before=85 > > It=92s just the beginning=85. (contributions are welcome if you see some > dark(er) area) > > > > > /Bengt > > > > > > 2013/11/26 Bengt Rodehav > > > >> Thanks Clement! > >> > >> > >> 2013/11/26 Clement Escoffier > >> > >>> Hi, > >>> > >>> On 25 nov. 2013, at 20:19, Bengt Rodehav wrote: > >>> > >>>> Hello Clement and as always thanks for your detailed answer! > >>>> > >>> > >>> You=92re 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 =3D "extenders", mandatory =3D false) > >>>> private String[] mExtenderIds; > >>>> > >>>> @Requires(optional =3D true, id =3D "extenders") > >>>> private IExtender[] mExtenders; > >>>> > >>>> Do you mean that I should put a filter on the @Requires with > >>> id=3D"extenders" > >>>> (the intercepted =3D 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 =3D false, id =3D "extenders", > >>> filter=3D"(intercepted=3Dtrue)") > >>>> 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 > >>>> > >>>>> Hi, > >>>>> > >>>>> > >>>>> On 25 nov. 2013, at 11:04, Bengt Rodehav 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 =3D "extenders", mandatory =3D false) > >>>>>> private String[] mExtenderIds; > >>>>>> > >>>>>> @Requires(optional =3D true, id =3D "extenders") > >>>>>> private IExtender[] mExtenders; > >>>>>> > >>>>>> > >>>>>> The property is optional but if any extenderId's are listed then t= he > >>>>>> @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 shou= ld > >>> 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 (th= e > >>>>>> "extenders" property) of my component from the interceptor. How ca= n > 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 i= s > >>>>> 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=92s imagine your consumer with your service dependency. Add a > filter > >>>>> that will be resolved only if your interceptor is there, something > >>> like: > >>>>> (intercepted=3Dtrue). > >>>>> Your interceptor implement both tracking and ranking interceptors. > When > >>>>> the accept method is called on your interceptor, it can =91transfo= rm=92 > >>> the > >>>>> original service reference to add the =91intercepted=92 property > >>>>> (ref.addProperty(=93intercepted=94, 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 do= es > >>> not > >>>>> match. > >>>>> > >>>>> Regards, > >>>>> > >>>>> Clement > >>>>> > >>>>>> > >>>>>> /Bengt > >>>>> > >>>>> > >>>>> -------------------------------------------------------------------= -- > >>>>> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org > >>>>> For additional commands, e-mail: users-help@felix.apache.org > >>>>> > >>>>> > >>> > >>> > >>> --------------------------------------------------------------------- > >>> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org > >>> For additional commands, e-mail: users-help@felix.apache.org > >>> > >>> > >> > > > --------------------------------------------------------------------- > To unsubscribe, e-mail: users-unsubscribe@felix.apache.org > For additional commands, e-mail: users-help@felix.apache.org > > --e89a8ffbae9b51845904ec3addcf--