001    /*
002      Copyright (C) 2002-2003 Laurent Martelli <laurent@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
015      License along with this program; if not, write to the Free Software
016      Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
017      USA */
018    
019    package org.objectweb.jac.core;
020    
021    import java.lang.reflect.AccessibleObject;
022    import java.lang.reflect.Constructor;
023    import java.lang.reflect.Method;
024    import java.util.Arrays;
025    import org.aopalliance.intercept.ConstructorInvocation;
026    import org.aopalliance.intercept.Interceptor;
027    import org.aopalliance.intercept.Invocation;
028    import org.aopalliance.intercept.MethodInvocation;
029    import org.apache.log4j.Logger;
030    import org.objectweb.jac.core.rtti.AbstractMethodItem;
031    import org.objectweb.jac.core.rtti.ClassItem;
032    import org.objectweb.jac.core.rtti.ClassRepository;
033    import org.objectweb.jac.core.rtti.ConstructorItem;
034    import org.objectweb.jac.core.rtti.MethodItem;
035    import org.objectweb.jac.util.ExtArrays;
036    import org.objectweb.jac.util.Strings;
037    
038    
039    public class Interaction implements MethodInvocation, ConstructorInvocation {
040        static final Logger logger = Logger.getLogger("interaction");
041    
042        public final Wrappee wrappee;
043        public final AbstractMethodItem method;
044        public final Object[] args;
045        public int rank;
046        public String cur_AC;
047        public Interceptor[] wrappingChain;
048    
049        public Interaction(WrappingChain wrappingChain, Wrappee wrappee, 
050                           AbstractMethodItem method, Object[] args) 
051        {
052            logger.debug("new Interaction(wrappee="+wrappee+", method="+method+Strings.hash(method)+
053                         ", wrappingChain="+wrappingChain+
054                         (wrappingChain!=null ? Strings.hash(wrappingChain) : "")+
055                         ")");
056            this.wrappingChain = 
057                wrappingChain==null ? ExtArrays.emptyInterceptorArray : wrappingChain.chain;
058            this.wrappee = wrappee;
059            this.method = method;
060            this.args = args;
061            this.rank = 0;
062        }
063    
064        public final Object proceed() {
065            rank += 1;
066            return Wrapping.nextWrapper(this);
067        }
068    
069        public final Object invoke(Object substance) {
070            return method.invoke(substance,args);
071        }
072    
073        public final Class getActualClass() {
074            if (wrappee!=null)
075                return wrappee.getClass();
076            else
077                return method.getClassItem().getActualClass();
078        }
079    
080        ClassItem cli;
081        public final ClassItem getClassItem() {
082            if (cli==null) {
083                if (wrappee!=null) {
084                    cli = ClassRepository.get().getClass(wrappee);
085                } else {
086                    cli = method.getClassItem();
087                }
088            }
089            return cli;
090        }
091    
092        public String toString() {
093            return wrappee+"."+method+(args!=null?("("+Arrays.asList(args)+")"):"")+" rank="+rank;
094        }
095    
096    
097            // AOP Alliance interfaces implementations
098        public Constructor getConstructor() {
099            return ((ConstructorItem)method).getActualConstructor();
100        }
101            
102    
103        public Method getMethod() {
104            return ((MethodItem)method).getActualMethod();
105        }
106    
107        // TODO implement these methods?
108        public Object getArgument(int index) {
109            return args[index];
110        }
111    
112        public void setArgument(int index, Object argument) {
113            args[index]=argument;
114        }
115    
116        public int getArgumentCount() {
117            return args.length;
118        }
119    
120        public Object[] getArguments() {
121            return args;
122        }
123    
124        public Object getThis() {
125            return wrappee;
126        }
127    
128        public AccessibleObject getStaticPart() {
129            if(method instanceof ConstructorItem) {
130                return getConstructor();
131            } else {
132                return getMethod();
133            }
134        }
135    }