Did you have any chance to check this Clement?

/Bengt


2013/12/3 Clement Escoffier <[email protected]>

>
> On 3 déc. 2013, at 19:23, Bengt Rodehav <[email protected]> wrote:
>
> > Yes, I think I'm getting close now but it's been a bit more complicated
> > than I expected. I learn a lot about iPojo though.
> >
> > About triggering a re-compute...
> >
> > In my case The set of accepted services will not change. But my propety
> > "extenders" has changed so The services must still be recomputed. I need
> to
> > force it.
>
> Then calling mDependencyModel.invalidateSelectedServices() should make it
> work. I will check why it’s not called.
>
> Regards,
>
> Clement
>
> >
> > /Bengt
> > Den 3 dec 2013 17:32 skrev "Clement Escoffier" <
> [email protected]
> >> :
> >
> >> Hi,
> >>
> >> It looks you are making great progresses.
> >>
> >> On 3 déc. 2013, at 17:13, Bengt Rodehav <[email protected]> wrote:
> >>
> >>> Thanks Clement,
> >>>
> >>> When I started using the bundle context retrieved using:
> >>>
> >>> BundleContext bc = model.getComponentInstance().getContext();
> >>>
> >>> then it started to work even without using the "getWrappedReference()".
> >> Not
> >>> sure why but it does work.
> >>
> >> Yes, the bundle context retrieved this way is an ‘iPOJO-aware’ bundle
> >> context, aware of the transformation aspect.
> >>
> >>>
> >>> I've now added a configuration listener in the open() method that I
> >> remove
> >>> in the close() method. The notifications seem to work as well.
> >>>
> >>> In my  listener I try to trigger a recomputing of the service
> >> dependencies
> >>> (that I currently now do in the "getServiceReferences()" method as
> >> follows:
> >>>
> >>>       mDependencyModel.invalidateMatchingServices();
> >>>       mDependencyModel.invalidateSelectedServices();
> >>>
> >>> This seems to trigger a new call to accept() but no call to
> >>> getServiceReferences(). How can I accomplish that?
> >>
> >> First, I think that the first call would be enough. If the set of
> accepted
> >> services change, then the getServiceReferences should be called.
> >>
> >> Clement
> >>
> >>>
> >>> /Bengt
> >>>
> >>>
> >>> 2013/12/3 Clement Escoffier <[email protected]>
> >>>
> >>>> Hi,
> >>>>
> >>>> The error is ‘expected’ as interceptors are dealing with transformed
> >>>> service references and not (genuine) service references. Try to use
> >>>> `transformed.getWrappedReference()` to retrieve the original
> reference.
> >>>>
> >>>> Regards,
> >>>>
> >>>> Clement
> >>>>
> >>>> On 3 déc. 2013, at 10:57, Bengt Rodehav <[email protected]> wrote:
> >>>>
> >>>>> I've tried something like this:
> >>>>>
> >>>>> BundleContext bundleContext =
> >>>>> FrameworkUtil.getBundle(IRouteExtender.class).getBundleContext();
> >>>>>
> >>>>> for (ServiceReference ref : theMatchingRefs) {
> >>>>> IRouteExtender extender = (IRouteExtender)
> >>>> bundleContext.getService(ref);
> >>>>> // Causes exception
> >>>>> System.out.println("Found extender with id: " +
> >>>> extender.getExtenderId());
> >>>>> }
> >>>>>
> >>>>> But I get the following exception:
> >>>>>
> >>>>> ERROR: Bundle se.digia.connect.services.generic.service [164]
> >>>>> EventDispatcher: Error during dispatch.
> (java.lang.ClassCastException:
> >>>>>
> org.apache.felix.ipojo.dependency.impl.TransformedServiceReferenceImpl
> >>>>> cannot be cast to
> >>>>>
> >> org.apache.felix.framework.ServiceRegistrationImpl$ServiceReferenceImpl)
> >>>>> java.lang.ClassCastException:
> >>>>>
> org.apache.felix.ipojo.dependency.impl.TransformedServiceReferenceImpl
> >>>>> cannot be cast to
> >>>>>
> org.apache.felix.framework.ServiceRegistrationImpl$ServiceReferenceImpl
> >>>>>      at
> >>>>>
> >>>>
> >>
> org.apache.felix.framework.ServiceRegistry.getService(ServiceRegistry.java:250)
> >>>>>      at org.apache.felix.framework.Felix.getService(Felix.java:3420)
> >>>>>      at
> >>>>>
> >>>>
> >>
> org.apache.felix.framework.BundleContextImpl.getService(BundleContextImpl.java:468)
> >>>>>      at
> >>>>>
> >>>>
> >>
> se.digia.connect.service.generic.service.ExtenderInterceptor.__M_calculateExtenders(ExtenderInterceptor.java:104)
> >>>>>      at
> >>>>>
> >>>>
> >>
> se.digia.connect.service.generic.service.ExtenderInterceptor.calculateExtenders(ExtenderInterceptor.java)
> >>>>>      at
> >>>>>
> >>>>
> >>
> se.digia.connect.service.generic.service.ExtenderInterceptor.__M_getServiceReferences(ExtenderInterceptor.java:84)
> >>>>>      at
> >>>>>
> >>>>
> >>
> se.digia.connect.service.generic.service.ExtenderInterceptor.getServiceReferences(ExtenderInterceptor.java)
> >>>>>      at
> >>>>>
> >>>>
> >>
> org.apache.felix.ipojo.dependency.interceptors.DefaultServiceRankingInterceptor.onServiceArrival(DefaultServiceRankingInterceptor.java:61)
> >>>>>      at
> >>>>>
> >>>>
> >>
> org.apache.felix.ipojo.dependency.impl.ServiceReferenceManager.applyRankingOnArrival(ServiceReferenceManager.java:559)
> >>>>>      at
> >>>>>
> >>>>
> >>
> org.apache.felix.ipojo.dependency.impl.ServiceReferenceManager.onNewMatchingService(ServiceReferenceManager.java:510)
> >>>>>      at
> >>>>>
> >>>>
> >>
> org.apache.felix.ipojo.dependency.impl.ServiceReferenceManager.addedService(ServiceReferenceManager.java:496)
> >>>>>      at
> >>>>>
> >>
> org.apache.felix.ipojo.util.Tracker$Tracked.trackAdding(Tracker.java:711)
> >>>>>      at
> >>>>> org.apache.felix.ipojo.util.Tracker$Tracked.track(Tracker.java:672)
> >>>>>      at
> >>>>>
> >>>>
> >>
> org.apache.felix.ipojo.util.Tracker$Tracked.serviceChanged(Tracker.java:633)
> >>>>>      at
> >>>>>
> >>>>
> >>
> org.apache.felix.framework.util.EventDispatcher.invokeServiceListenerCallback(EventDispatcher.java:932)
> >>>>>      at
> >>>>>
> >>>>
> >>
> org.apache.felix.framework.util.EventDispatcher.fireEventImmediately(EventDispatcher.java:793)
> >>>>>      at
> >>>>>
> >>>>
> >>
> org.apache.felix.framework.util.EventDispatcher.fireServiceEvent(EventDispatcher.java:543)
> >>>>>      at
> >>>>> org.apache.felix.framework.Felix.fireServiceEvent(Felix.java:4260)
> >>>>>      at
> >>>> org.apache.felix.framework.Felix.registerService(Felix.java:3275)
> >>>>>      at
> >>>>>
> >>>>
> >>
> org.apache.felix.framework.BundleContextImpl.registerService(BundleContextImpl.java:346)
> >>>>>      at
> >>>>>
> >>>>
> >>
> org.apache.felix.ipojo.IPojoContext.registerService(IPojoContext.java:395)
> >>>>>      at
> >>>>>
> >>>>
> >>
> org.apache.felix.ipojo.handlers.providedservice.ProvidedService.registerService(ProvidedService.java:338)
> >>>>>      at
> >>>>>
> >>>>
> >>
> org.apache.felix.ipojo.handlers.providedservice.ProvidedServiceHandler.__M_stateChanged(ProvidedServiceHandler.java:484)
> >>>>>      at
> >>>>>
> >>>>
> >>
> org.apache.felix.ipojo.handlers.providedservice.ProvidedServiceHandler.stateChanged(ProvidedServiceHandler.java)
> >>>>>      at
> >>>>>
> >>
> org.apache.felix.ipojo.InstanceManager.setState(InstanceManager.java:536)
> >>>>>      at
> >>>>>
> org.apache.felix.ipojo.InstanceManager.start(InstanceManager.java:418)
> >>>>>      at
> >>>>>
> >>>>
> >>
> org.apache.felix.ipojo.ComponentFactory.createInstance(ComponentFactory.java:179)
> >>>>>      at
> >>>>>
> >>>>
> >>
> org.apache.felix.ipojo.IPojoFactory.createComponentInstance(IPojoFactory.java:319)
> >>>>>      at
> >>>>>
> >>>>
> >>
> org.apache.felix.ipojo.IPojoFactory.createComponentInstance(IPojoFactory.java:240)
> >>>>>      at
> >>>>> org.apache.felix.ipojo.IPojoFactory.updated(IPojoFactory.java:737)
> >>>>>      at
> >>>>>
> >>>>
> >>
> org.apache.felix.ipojo.ConfigurationTracker.registerFactory(ConfigurationTracker.java:100)
> >>>>>      at
> >>>>>
> >>>>
> >>
> org.apache.felix.ipojo.IPojoFactory.computeFactoryState(IPojoFactory.java:846)
> >>>>>      at
> >>>>>
> >>>>
> >>
> org.apache.felix.ipojo.ComponentFactory.addedService(ComponentFactory.java:400)
> >>>>>      at
> >>>>>
> >>
> org.apache.felix.ipojo.util.Tracker$Tracked.trackAdding(Tracker.java:711)
> >>>>>      at
> >>>>>
> >>>>
> >>
> org.apache.felix.ipojo.util.Tracker$Tracked.trackInitialServices(Tracker.java:596)
> >>>>>      at org.apache.felix.ipojo.util.Tracker.open(Tracker.java:210)
> >>>>>      at
> >>>>>
> >>>>
> >>
> org.apache.felix.ipojo.ComponentFactory.starting(ComponentFactory.java:249)
> >>>>>      at
> >>>> org.apache.felix.ipojo.IPojoFactory.start(IPojoFactory.java:671)
> >>>>>      at
> >>>>>
> >>>>
> >>
> org.apache.felix.ipojo.extender.internal.linker.ManagedType$ExtensionSupport$1.call(ManagedType.java:229)
> >>>>>      at
> >>>>>
> >>>>
> >>
> org.apache.felix.ipojo.extender.internal.linker.ManagedType$ExtensionSupport$1.call(ManagedType.java:216)
> >>>>>      at
> >>>>>
> >>>>
> >>
> org.apache.felix.ipojo.extender.internal.queue.JobInfoCallable.call(JobInfoCallable.java:114)
> >>>>>      at
> >>>>> java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
> >>>>>      at java.util.concurrent.FutureTask.run(FutureTask.java:138)
> >>>>>      at
> >>>>>
> >>>>
> >>
> java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
> >>>>>      at
> >>>>>
> >>>>
> >>
> java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
> >>>>>      at java.lang.Thread.run(Thread.java:662)
> >>>>>
> >>>>> Any ideas?
> >>>>>
> >>>>> BTW, the exception is only logged in the console - not in any log
> >> files.
> >>>>>
> >>>>> /Bengt
> >>>>>
> >>>>>
> >>>>>
> >>>>>
> >>>>> 2013/12/3 Bengt Rodehav <[email protected]>
> >>>>>
> >>>>>> I've now tested against trunk and I've come a lot further. Another
> >>>>>> question for you...
> >>>>>>
> >>>>>> I need access to my service object in the getServiceReferences()
> >> method.
> >>>>>> It is possible if I have the BundleContext. In the accept() method I
> >> get
> >>>>>> the BundleContext passed as a parameter but not in the
> >>>>>> getServiceReferences(). Why is that?
> >>>>>>
> >>>>>> How can I access the service object from the ServiceReference in the
> >>>>>> getServiceReferences() method? Perhaps the signature of the
> >>>>>> getServiceReferences() method should be changed to take a
> >> BundleContext
> >>>> as
> >>>>>> well?
> >>>>>>
> >>>>>> /Bengt
> >>>>>>
> >>>>>>
> >>>>>> 2013/11/29 Bengt Rodehav <[email protected]>
> >>>>>>
> >>>>>>> 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]
> >>>>>>>>
> >>>>>>>>
> >>>>>>>
> >>>>>>
> >>>>
> >>>>
> >>>> ---------------------------------------------------------------------
> >>>> 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