You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tapestry.apache.org by Joshua Jackson <jo...@gmail.com> on 2007/07/08 16:52:59 UTC

T5 IoC: How to invoke a decorator method after the service method invoked

Hi all,

Sorry for the long subject :-D.

Ok straight to the point. I'm currently building a decorator for a
Service. But the problem I'm facing is, the method inside the
decorator is only invoked before the service method is invoked. What I
want is the decorator method to be invoked before and after the
service method is invoked. How do I get this? I saw the logging
decorator method is invoked before and after, but I just still can not
get the idea. Perhaps there should be a reference on building custom
decorator? :-D

Thanks in advance

-- 
Let's create a highly maintainable and efficient code

YM!: thejavafreak
Blog: http://www.nagasakti.or.id/roller/joshua/

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


Re: T5 IoC: How to invoke a decorator method after the service method invoked

Posted by Joshua Jackson <jo...@gmail.com>.
All right... This is so cool. Just the way I wanted it. Thank you so
much Davor. ;) You the man. I think this should be documented since I
believe many people wanted to create their own decorator.

On 7/11/07, Davor Hrg <hr...@gmail.com> wrote:
...
> interceptor is an implementation of the service interface,
> you then code manualy method implementations,
> choosing when and how to call the delegate service.

-- 
It's not just about coding, it's a matter of fulfilling you core being

YM!: thejavafreak
Blog: http://joshuajava.wordpress.com/

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


Re: T5 IoC: How to invoke a decorator method after the service method invoked

Posted by Davor Hrg <hr...@gmail.com>.
try this:

delete clases Delegate and delegateImpl


then change the interceptor:
public class Interceptor implements AnotherService{

    private final Service service;
    private final Log log;
    private final AnotherService delegate;

    public Interceptor(AnotherService delegate,Service service, Log log) {
        this.delegate = delegate;
        this.service = service;
        this.log = log;
    }

    public void run() {
        // Logic before delegate invocation here.
        log.info("<<< Before delegate >>>");
        service.execute();

        delegate.run();

        service.execute();
        // Logic after delegate invocation here.
        log.info("<<< After delegate >>>");
    }
 }

and change appmodule.decorateAnotherService

       public static AnotherService decorateAnotherService(
               Object delegate, Service service, Log log)
       {
               return new Interceptor((AnotherService)delegate, service, log
);
       }




interceptor is an implementation of the service interface,
you then code manualy method implementations,
choosing when and how to call the delegate service.


the code above outputed this to log:
11:28:28.390 INFO   [SocketListener0-1] services.Interceptor.run(
Interceptor.java:19) >52> <<< Before delegate >>>
11:28:28.390 INFO   [SocketListener0-1] services.ServiceImpl.execute(
ServiceImpl.java:14) >54> <-- Inside Service method -->
11:28:28.390 INFO   [SocketListener0-1] services.AnotherServiceImpl.run(
AnotherServiceImpl.java:13) >53> Inside another service
11:28:28.390 INFO   [SocketListener0-1] services.ServiceImpl.execute(
ServiceImpl.java:14) >54> <-- Inside Service method -->
11:28:28.390 INFO   [SocketListener0-1] services.Interceptor.run(
Interceptor.java:26) >52> <<< After delegate >>>

Davor Hrg

On 7/11/07, Joshua Jackson <jo...@gmail.com> wrote:
>
> I tried the hint you gave me but it seems to be not working. Perhaps I
> am missing something. Let me paste the code snippets so there won't be
> any confusion.
>
> This is the AppModule:
> public class AppModule {
>     public static void bind(ServiceBinder binder){
>         binder.bind(Decorator.class, DecoratorImpl.class);
>         binder.bind(Service.class, ServiceImpl.class);
>         binder.bind(AnotherService.class, AnotherServiceImpl.class);
>     }
>
>     public static Object decorateAnotherService(
>             Object delegate, Service service,
>
>             @InjectService("Decorator")
>             Decorator decorator)
>     {
>             return decorator.decorate( delegate, service );
>     }
> }
>
> Basically I binded everything to their interface. What I want is to
> decorate AnotherService with Service and I want the execute method in
> Service to be invoked before and after any method in AnotherService is
> invoked. Which means before and after the AnotherService's run method
> is invoked, the Service's execute method is invoked.
>
> This is the ServiceImpl:
> public class ServiceImpl implements Service {
>     public void execute() {
>         log.debug("<-- Inside Service method -->");
>     }
> }
>
> And this is the AnotherServiceImpl:
> public class AnotherServiceImpl implements AnotherService{
>     public void run(){
>         log.debug("Inside another service");
>     }
> }
>
> This is the DecoratorImpl:
> public class DecoratorImpl implements Decorator {
>     public Object decorate(Object delegate, Service service) {
>         log.debug("<<< Begin decorator >>>");
>
>         Interceptor interceptor= new Interceptor(service);
>         interceptor.execute();
>
>         log.debug("<<< End decorator >>>");
>
>         return service;
>     }
> }
>
> And this is the Interceptor:
> public class Interceptor {
>     private final Service service;
>
>     public Interceptor(Service service) {
>         this.service = service;
>     }
>
>     public void execute() {
>         // Logic before delegate invocation here.
>         log.debug("<<< Before delegate >>>");
>
>         service.execute();
>
>         // Logic after delegate invocation here.
>         log.debug("<<< After delegate >>>");
>
>     }
> }
>
> I already did what you said by creating the Interceptor inside the
> Decorator and then execute the service method inside the Interceptor.
> But that didn't work, because the Service.execute() is still executed
> only before the AnotherService.run().
>
> What have I gotten wrong here.
>
> Thanks in advance
>
> On 7/9/07, Howard Lewis Ship <hl...@gmail.com> wrote:
> > The decorator creates the interceptor.
> >
> > The interceptor has the same interface as the service.
> >
> > The decorator is passed the service, which it can then provide to the
> > interceptor.  It's called the "delegate" (because it may not be the
> > service, it may be another interceptor, but that's actually not
> > relevant).
>
> --
> It's not just about coding, it's a matter of fulfilling you core being
>
> YM!: thejavafreak
> Blog: http://joshuajava.wordpress.com/
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
> For additional commands, e-mail: users-help@tapestry.apache.org
>
>

Re: T5 IoC: How to invoke a decorator method after the service method invoked

Posted by Joshua Jackson <jo...@gmail.com>.
I tried the hint you gave me but it seems to be not working. Perhaps I
am missing something. Let me paste the code snippets so there won't be
any confusion.

This is the AppModule:
public class AppModule {
    public static void bind(ServiceBinder binder){
        binder.bind(Decorator.class, DecoratorImpl.class);
        binder.bind(Service.class, ServiceImpl.class);
        binder.bind(AnotherService.class, AnotherServiceImpl.class);
    }

    public static Object decorateAnotherService(
            Object delegate, Service service,

            @InjectService("Decorator")
            Decorator decorator)
    {
            return decorator.decorate( delegate, service );
    }
}

Basically I binded everything to their interface. What I want is to
decorate AnotherService with Service and I want the execute method in
Service to be invoked before and after any method in AnotherService is
invoked. Which means before and after the AnotherService's run method
is invoked, the Service's execute method is invoked.

This is the ServiceImpl:
public class ServiceImpl implements Service {
    public void execute() {
        log.debug("<-- Inside Service method -->");
    }
}

And this is the AnotherServiceImpl:
public class AnotherServiceImpl implements AnotherService{
    public void run(){
        log.debug("Inside another service");
    }
}

This is the DecoratorImpl:
public class DecoratorImpl implements Decorator {
    public Object decorate(Object delegate, Service service) {
        log.debug("<<< Begin decorator >>>");

        Interceptor interceptor= new Interceptor(service);
        interceptor.execute();

        log.debug("<<< End decorator >>>");

        return service;
    }
}

And this is the Interceptor:
public class Interceptor {
    private final Service service;

    public Interceptor(Service service) {
        this.service = service;
    }

    public void execute() {
        // Logic before delegate invocation here.
        log.debug("<<< Before delegate >>>");

        service.execute();

        // Logic after delegate invocation here.
        log.debug("<<< After delegate >>>");

    }
}

I already did what you said by creating the Interceptor inside the
Decorator and then execute the service method inside the Interceptor.
But that didn't work, because the Service.execute() is still executed
only before the AnotherService.run().

What have I gotten wrong here.

Thanks in advance

On 7/9/07, Howard Lewis Ship <hl...@gmail.com> wrote:
> The decorator creates the interceptor.
>
> The interceptor has the same interface as the service.
>
> The decorator is passed the service, which it can then provide to the
> interceptor.  It's called the "delegate" (because it may not be the
> service, it may be another interceptor, but that's actually not
> relevant).

-- 
It's not just about coding, it's a matter of fulfilling you core being

YM!: thejavafreak
Blog: http://joshuajava.wordpress.com/

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


Re: T5 IoC: How to invoke a decorator method after the service method invoked

Posted by Joshua Jackson <jo...@gmail.com>.
Thanks for the reply Howard. What I'm trying to achieve here is to
create a declarative transaction. So before the service method is
invoked, I want to begin a transaction, and commit when the service
method is finished.

I'm going to try out the explanation you have given me. But I think
I'm still far off from creating an interceptor with javassist.

Another question: Is the SampleInterceptor.foo invoked from the
decorator method?

PS: I think you need to add a reference regarding on creating custom
decorator here just to prevent others asking the same question like I
did. :-D

Regards,
joshua

On 7/9/07, Howard Lewis Ship <hl...@gmail.com> wrote:
> The decorator creates the interceptor.
>
> The interceptor has the same interface as the service.
>
> The decorator is passed the service, which it can then provide to the
> interceptor.  It's called the "delegate" (because it may not be the
> service, it may be another interceptor, but that's actually not
> relevant).
>
> So, the interceptor has the same methods as the service, and a
> do-nothing interceptor would just re-invoke each method on the
> service.
>
> Example:
>
> public interface Sample() {
>  String foo(String bar);
> }
>
> A hand-assembled interceptor would look like:
>
> public class SampleInterceptor {
>  private final Sample _delegate;
>
>  public SampleInterceptor(Sample delegate) { _delegate = delegate; }
>
>  public String foo(String bar) {
>    // Logic before delegate invocation here.
>    String result =  _delegate.foo(bar);
>   // Logic after delegate invocation here.
>
>  return result;
>  }
> }
>
> Of course, we don't use hand-written interceptors often, we instead
> brew up the interceptors on the fly inside decorator methods, using
> JDK dynamic proxies, or Javassist (ClassFactory and friends).
>
> Notice the two comments; you see that you can add logic before
> delegating, even to the point of changing method parameters before
> re-invoking.  In theory you could even invoke a different method on
> delegate, or not invoke the method, or invoke a method on some other
> object.
>
> Likewise, you can have logic after invoking the method.  You could
> even but a try ... finally arround the call to _delegate and trap
> exceptions.
>
> On 7/8/07, Joshua Jackson <jo...@gmail.com> wrote:
> > Hi all,
> >
> > Sorry for the long subject :-D.
> >
> > Ok straight to the point. I'm currently building a decorator for a
> > Service. But the problem I'm facing is, the method inside the
> > decorator is only invoked before the service method is invoked. What I
> > want is the decorator method to be invoked before and after the
> > service method is invoked. How do I get this? I saw the logging
> > decorator method is invoked before and after, but I just still can not
> > get the idea. Perhaps there should be a reference on building custom
> > decorator? :-D
> >
> > Thanks in advance
> >
> > --
> > Let's create a highly maintainable and efficient code
> >
> > YM!: thejavafreak
> > Blog: http://www.nagasakti.or.id/roller/joshua/
> >
> > ---------------------------------------------------------------------
> > To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
> > For additional commands, e-mail: users-help@tapestry.apache.org
> >
> >
>
>
> --
> Howard M. Lewis Ship
> TWD Consulting, Inc.
> Independent J2EE / Open-Source Java Consultant
> Creator and PMC Chair, Apache Tapestry
> Creator, Apache HiveMind
>
> Professional Tapestry training, mentoring, support
> and project work.  http://howardlewisship.com
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
> For additional commands, e-mail: users-help@tapestry.apache.org
>
>


-- 
Let's create a highly maintainable and efficient code

YM!: thejavafreak
Blog: http://www.nagasakti.or.id/roller/joshua/

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


Re: T5 IoC: How to invoke a decorator method after the service method invoked

Posted by Howard Lewis Ship <hl...@gmail.com>.
The decorator creates the interceptor.

The interceptor has the same interface as the service.

The decorator is passed the service, which it can then provide to the
interceptor.  It's called the "delegate" (because it may not be the
service, it may be another interceptor, but that's actually not
relevant).

So, the interceptor has the same methods as the service, and a
do-nothing interceptor would just re-invoke each method on the
service.

Example:

public interface Sample() {
  String foo(String bar);
}

A hand-assembled interceptor would look like:

public class SampleInterceptor {
  private final Sample _delegate;

  public SampleInterceptor(Sample delegate) { _delegate = delegate; }

  public String foo(String bar) {
    // Logic before delegate invocation here.
    String result =  _delegate.foo(bar);
   // Logic after delegate invocation here.

  return result;
  }
}

Of course, we don't use hand-written interceptors often, we instead
brew up the interceptors on the fly inside decorator methods, using
JDK dynamic proxies, or Javassist (ClassFactory and friends).

Notice the two comments; you see that you can add logic before
delegating, even to the point of changing method parameters before
re-invoking.  In theory you could even invoke a different method on
delegate, or not invoke the method, or invoke a method on some other
object.

Likewise, you can have logic after invoking the method.  You could
even but a try ... finally arround the call to _delegate and trap
exceptions.

On 7/8/07, Joshua Jackson <jo...@gmail.com> wrote:
> Hi all,
>
> Sorry for the long subject :-D.
>
> Ok straight to the point. I'm currently building a decorator for a
> Service. But the problem I'm facing is, the method inside the
> decorator is only invoked before the service method is invoked. What I
> want is the decorator method to be invoked before and after the
> service method is invoked. How do I get this? I saw the logging
> decorator method is invoked before and after, but I just still can not
> get the idea. Perhaps there should be a reference on building custom
> decorator? :-D
>
> Thanks in advance
>
> --
> Let's create a highly maintainable and efficient code
>
> YM!: thejavafreak
> Blog: http://www.nagasakti.or.id/roller/joshua/
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
> For additional commands, e-mail: users-help@tapestry.apache.org
>
>


-- 
Howard M. Lewis Ship
TWD Consulting, Inc.
Independent J2EE / Open-Source Java Consultant
Creator and PMC Chair, Apache Tapestry
Creator, Apache HiveMind

Professional Tapestry training, mentoring, support
and project work.  http://howardlewisship.com

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org