1 /*
2 * JBoss, Home of Professional Open Source
3 * Copyright 2005, JBoss Inc., and individual contributors as indicated
4 * by the @authors tag. See the copyright.txt in the distribution for a
5 * full listing of individual contributors.
6 *
7 * This is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU Lesser General Public License as
9 * published by the Free Software Foundation; either version 2.1 of
10 * the License, or (at your option) any later version.
11 *
12 * This software is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this software; if not, write to the Free
19 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21 */
22 package org.jboss.proxy;
23
24 import java.io.Externalizable;
25
26 import java.io.IOException;
27 import java.io.ObjectInput;
28 import java.io.ObjectOutput;
29
30 import java.lang.reflect.Method;
31 import java.lang.reflect.InvocationHandler;
32 import java.util.ArrayList;
33
34 import org.jboss.invocation.Invocation;
35 import org.jboss.invocation.InvocationContext;
36 import org.jboss.invocation.InvocationKey;
37 import org.jboss.invocation.PayloadKey;
38
39 /**
40 * An invocation handler whichs sets up the client invocation and
41 * starts the invocation interceptor call chain.
42 *
43 * @author <a href="mailto:marc.fleury@jboss.org">Marc Fleury</a>
44 * @author Scott.Stark@jboss.org
45 * @version $Revision: 37459 $
46 */
47 public class ClientContainer
48 implements Externalizable, InvocationHandler
49 {
50 /** The serialVersionUID. @since 1.5 */
51 private static final long serialVersionUID = -4061374432170701306L;
52
53 /** An empty method parameter list. */
54 protected static final Object[] EMPTY_ARGS = {};
55
56 /**
57 * The <em>static</em> information that gets attached to every invocation.
58 */
59 public InvocationContext context;
60
61 /** The first interceptor in the chain. */
62 public Interceptor next;
63
64 /**
65 * Exposed for externalization.
66 */
67 public ClientContainer()
68 {
69 super();
70 }
71
72 public ClientContainer(final InvocationContext context)
73 {
74 this.context = context;
75 }
76
77 public Object invoke(final Object proxy,
78 final Method m,
79 Object[] args)
80 throws Throwable
81 {
82 // Normalize args to always be an array
83 // Isn't this a bug in the proxy call??
84 if (args == null)
85 args = EMPTY_ARGS;
86
87 // Create the invocation object
88 Invocation invocation = new Invocation();
89
90 // Contextual information for the interceptors
91 invocation.setInvocationContext(context);
92 invocation.setId(context.getCacheId());
93 invocation.setObjectName(context.getObjectName());
94 invocation.setMethod(m);
95 invocation.setArguments(args);
96 invocation.setValue(InvocationKey.INVOKER_PROXY_BINDING,
97 context.getInvokerProxyBinding(),
98 PayloadKey.AS_IS);
99
100 // send the invocation down the client interceptor chain
101 Object obj = next.invoke(invocation);
102 return obj;
103 }
104
105 public InvocationContext getInvocationContext()
106 {
107 return this.context;
108 }
109 public ArrayList getInterceptors()
110 {
111 ArrayList tmp = new ArrayList();
112 Interceptor inext = next;
113 while( inext != null )
114 {
115 tmp.add(inext);
116 inext = inext.nextInterceptor;
117 }
118 return tmp;
119 }
120 public void setInterceptors(ArrayList interceptors)
121 {
122 if( interceptors.size() == 0 )
123 return;
124 next = (Interceptor) interceptors.get(0);
125 Interceptor i = next;
126 for(int n = 1; n < interceptors.size(); n ++)
127 {
128 Interceptor inext = (Interceptor) interceptors.get(n);
129 i.setNext(inext);
130 i = inext;
131 }
132 }
133
134 public Interceptor setNext(Interceptor interceptor)
135 {
136 next = interceptor;
137
138 return interceptor;
139 }
140
141 /**
142 * Externalization support.
143 */
144 public void writeExternal(final ObjectOutput out)
145 throws IOException
146 {
147 out.writeObject(next);
148 out.writeObject(context);
149 }
150
151 /**
152 * Externalization support.
153 */
154 public void readExternal(final ObjectInput in)
155 throws IOException, ClassNotFoundException
156 {
157 next = (Interceptor) in.readObject();
158 context = (InvocationContext) in.readObject();
159 }
160 }
161