001    /*
002      Copyright (C) 2001 Renaud Pawlak <renaud@aopsys.com>
003    
004      This program is free software; you can redistribute it and/or modify
005      it under the terms of the GNU Lesser General Public License as
006      published by the Free Software Foundation; either version 2 of the
007      License, or (at your option) any later version.
008    
009      This program is distributed in the hope that it will be useful,
010      but WITHOUT ANY WARRANTY; without even the implied warranty of
011      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
012      GNU Lesser General Public License for more details.
013    
014      You should have received a copy of the GNU Lesser General Public License
015      along with this program; if not, write to the Free Software
016      Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
017    
018    package org.objectweb.jac.wrappers;
019    
020    import org.aopalliance.intercept.ConstructorInvocation;
021    import org.aopalliance.intercept.MethodInvocation;
022    import org.objectweb.jac.core.AspectComponent;
023    import org.objectweb.jac.core.Interaction;
024    import org.objectweb.jac.core.Wrapper;
025    
026    import java.lang.reflect.InvocationTargetException;
027    import java.lang.reflect.Method;
028    
029    /**
030     * This wrapper forwards the method calls that arrive on the wrappee
031     * to another object.  The wrapped methods should be supported both by
032     * the wrappee and the forwardee. Otherwise, an exception is raised.
033     *
034     * @author <a href="http://cedric.cnam.fr/~pawlak/index-english.html">Renaud Pawlak</a>
035     *
036     * @see ForwardingException */
037    
038    public class ForwardingWrapper extends Wrapper {
039    
040            /**
041             * Construct a new forwarding wrapper.
042             *
043             * @param forwardee the object that receives the forwarded calls */
044    
045            public ForwardingWrapper(AspectComponent ac, Object forwardee) {
046                    super(ac);
047                    this.forwardee = forwardee;
048            }
049    
050            /** The forwardee. */
051            protected Object forwardee;
052    
053            /**
054             * The getter method for the forwardee.
055             *
056             * @return the object to which the calls are forwarded
057             *
058             * @see #forward(Interaction)
059             */
060    
061            public Object getForwardee() {
062                    return forwardee;
063            }
064    
065            /**
066             * Forwards all the incoming calls to the forwardee.
067             *
068             * <p>The forwardee class must support the wrapped method
069             * prototype. Otherwise, an exception is raised.
070             *
071             * @return the result of the forwarded method call
072             */
073    
074            public Object forward(Interaction interaction) throws ForwardingException {
075    
076                    Object ret = null;
077    
078                    //      System.out.println( "Forwarding " + method() + " to " + forwardee );
079                    Method[] methods = forwardee.getClass().getMethods();
080                    boolean ok = false;
081                    for (int i = 0; i < methods.length; i++) {
082                            //System.out.println ( "---> trying " + methods[i].getName() + method_args );
083                            if (methods[i].getName().equals(interaction.method)) {
084                                    try {
085                                            ok = false;
086                                            //System.out.println ( "Try to call " + method_name );
087                                            ret = methods[i].invoke(forwardee, interaction.args);
088                                            ok = true;
089                                    } catch (IllegalArgumentException e) {
090                                    } catch (InvocationTargetException e) {
091                                            Throwable t = e.getTargetException();
092                                            if (t instanceof RuntimeException) {
093                                                    throw (RuntimeException) t;
094                                            }
095                                            e.printStackTrace();
096                                            System.exit(1);
097                                    } catch (IllegalAccessException e) {
098                                            e.printStackTrace();
099                                            System.exit(1);
100                                    }
101                                    if (ok)
102                                            break;
103                            }
104                    }
105                    if (!ok) {
106                            throw new ForwardingException(
107                                    "The forwardee '"
108                                            + forwardee
109                                            + "' does not support '"
110                                            + interaction.method
111                                            + "' to forward from '"
112                                            + interaction.wrappee
113                                            + "'.");
114                    }
115    
116                    return ret;
117            }
118    
119            public Object invoke(MethodInvocation invocation) throws Throwable {
120                    return forward((Interaction) invocation);
121            }
122    
123            public Object construct(ConstructorInvocation invocation)
124                    throws Throwable {
125                    throw new Exception("Wrapper "+this+" does not support construction interception.");
126            }
127    }