View Javadoc

1   /*
2    * Copyright (c) 1998-2003 The Jgroup Team.
3    *
4    * This program is free software; you can redistribute it and/or modify
5    * it under the terms of the GNU Lesser General Public License version 2 as
6    * published by the Free Software Foundation.
7    *
8    * This program is distributed in the hope that it will be useful,
9    * but WITHOUT ANY WARRANTY; without even the implied warranty of
10   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11   * GNU Lesser General Public License for more details.
12   *
13   * You should have received a copy of the GNU Lesser General Public License
14   * along with this program; if not, write to the Free Software
15   * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
16   *
17   */
18  package jgroup.relacs.gmi;
19  
20  import java.io.Externalizable;
21  import java.io.IOException;
22  import java.io.ObjectInput;
23  import java.io.ObjectOutput;
24  import java.lang.reflect.InvocationTargetException;
25  import java.lang.reflect.Method;
26  import java.rmi.RemoteException;
27  
28  import org.apache.log4j.Logger;
29  
30  import jgroup.core.View;
31  
32  /**
33   * Encapsulates invocation results and the server-side view identifier
34   * at the time of result generation.
35   * 
36   * @author Tor Arve Stangeland
37   * @author Hein Meling
38   */
39  public final class InvocationResult
40    implements Externalizable
41  {
42  
43    ////////////////////////////////////////////////////////////////////////////////////////////
44    // Logger
45    ////////////////////////////////////////////////////////////////////////////////////////////
46  
47    /** Obtain logger for this class */
48    private static final Logger log = Logger.getLogger(InvocationResult.class);
49  
50  
51    ////////////////////////////////////////////////////////////////////////////////////////////
52    // Constants
53    ////////////////////////////////////////////////////////////////////////////////////////////
54  
55    private static final long serialVersionUID = -416389148892987660L;
56  
57  
58    ////////////////////////////////////////////////////////////////////////////////////////////
59    // RequestHandler return codes
60    ////////////////////////////////////////////////////////////////////////////////////////////
61  
62    /** Indicates that the invocation completed, and a result will follow. */
63    public static final int INVOCATION_COMPLETED         = 0x00;
64  
65    /** Indicates that the invocation completed, and a result will follow. */
66    public static final int INVOCATION_BLOCKED           = 0x01;
67  
68    /** Indicates that the invocation failed with the attached exception. */
69    public static final int INVOCATION_FAILED            = 0x02;
70  
71    /**
72     * Indicates that the invocation could not be performed since it
73     * had an unknown invocation semantics for the given request.
74     */
75    public static final int UNKNOWN_INVOCATION_SEMANTICS = 0x03;
76  
77  
78    ////////////////////////////////////////////////////////////////////////////////////////////
79    // Fields
80    ////////////////////////////////////////////////////////////////////////////////////////////
81  
82    /** The result of the invocation; it may be an exception. */
83    private Object result;
84  
85    /** Indicates if the results contains an exception. */
86    private boolean isException = false;
87  
88    /**
89     * The server-side view identifier of the group being invoked
90     * (always transmitted)
91     */
92    private long serverViewId;
93  
94    /**
95     * The server-side view of the group being invoked
96     * (only transmitted when a change has been detected).
97     */
98    private View serverView = null;
99  
100 
101   ////////////////////////////////////////////////////////////////////////////////////////////
102   // Constructors
103   ////////////////////////////////////////////////////////////////////////////////////////////
104 
105   /**
106    * Empty constructor for externalizable
107    */
108   public InvocationResult() {} 
109 
110   /**
111    * Invokes method <code>m</code> on object <code>o</code> with the
112    * provided arguments.  The method may return a result which is stored
113    * in the <code>result</code> field of this object, or it may return an
114    * exception.  The latter is also stored in the <code>result</code>
115    * field, but in addition the boolean field <code>isException</code> is
116    * set to true.
117    * 
118    * @param m Method to invoke
119    * @param args Arguments to method <code>m</code>
120    * @param o Object to invoke method on
121    * @param serverView The server-side view in which the method was invoked
122    * @param clientViewId The client-side view in which this method was invoked
123    */
124   public InvocationResult(Method m, Object[] args, Object o,
125                           View serverView, long clientViewId)
126     throws IllegalArgumentException, IllegalAccessException
127   {
128     this.serverViewId = serverView.getVid();
129     this.serverView = (clientViewId != serverViewId) ? serverView : null;
130     try {
131       result = m.invoke(o, args);
132     } catch (InvocationTargetException itex) {
133       // The method threw an exception
134       isException = true;
135       result = itex.getCause();
136       log.error("Invocation threw an exception", itex.getCause());
137     }
138   }
139 
140   public InvocationResult(RemoteException e)
141   {
142     isException = true;
143     result = e;
144     log.error("Invocation returned with a remote exception", e);
145   }
146 
147 
148   ////////////////////////////////////////////////////////////////////////////////////////////
149   // Client-side access methods (GroupInvocationHandler)
150   ////////////////////////////////////////////////////////////////////////////////////////////
151 
152   /**
153    * Returns the result of the invocation.
154    * If the invoked object threw an exception this exception is thrown.
155    */
156   Object getResult()
157     throws Exception
158   {
159     if (isException)
160       throw (Exception) result;
161     return result;
162   }
163 
164   /**
165    * Returns the server-side view identifier attached with this
166    * <code>InvocationResult</code> message.
167    */
168   long getServerViewId()
169   {
170     return serverViewId;
171   }
172 
173   /**
174    * Returns the server-side view attached with this
175    * <code>InvocationResult</code> message.
176    */
177   View getServerView()
178   {
179     return serverView;
180   }
181 
182 
183   ////////////////////////////////////////////////////////////////////////////////////////////
184   // Methods from Externalizable
185   ////////////////////////////////////////////////////////////////////////////////////////////
186 
187   /* (non-javadoc)
188    * @see java.io.Externalizable#readExternal(ObjectInput)
189    */
190   public void readExternal(ObjectInput in)
191     throws IOException, ClassNotFoundException
192   {
193     result = in.readObject();
194     isException = in.readBoolean();
195     serverViewId = in.readLong();
196     boolean containsView = in.readBoolean();
197     if (containsView)
198       serverView = (View) in.readObject();
199   }
200 
201   /* (non-javadoc)
202    * @see java.io.Externalizable#writeExternal(ObjectOutput)
203    */
204   public void writeExternal(ObjectOutput out)
205     throws IOException
206   {
207     out.writeObject(result);
208     out.writeBoolean(isException);
209     out.writeLong(serverViewId);
210     out.writeBoolean(serverView != null);
211     if (serverView != null)
212       out.writeObject(serverView);
213   }
214 
215 
216   ////////////////////////////////////////////////////////////////////////////////////////////
217   // Methods from Object
218   ////////////////////////////////////////////////////////////////////////////////////////////
219 
220   public String toString()
221   {
222     StringBuilder buf = new StringBuilder("InvocationResult[");
223     if (isException)
224       buf.append("Result is an exception, ");
225     buf.append("serverViewId=");
226     buf.append(serverViewId);
227     buf.append(", result=");
228     buf.append(result == null ? "null" : result.toString());
229     buf.append("]");
230     return buf.toString();
231   }
232 
233 } // END InvocationResult