• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2009-2010 jMonkeyEngine
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are
7  * met:
8  *
9  * * Redistributions of source code must retain the above copyright
10  *   notice, this list of conditions and the following disclaimer.
11  *
12  * * Redistributions in binary form must reproduce the above copyright
13  *   notice, this list of conditions and the following disclaimer in the
14  *   documentation and/or other materials provided with the distribution.
15  *
16  * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
17  *   may be used to endorse or promote products derived from this software
18  *   without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32 
33 package com.jme3.network.rmi;
34 
35 import com.jme3.network.HostedConnection;
36 import java.lang.reflect.InvocationHandler;
37 import java.lang.reflect.Method;
38 import java.util.ArrayList;
39 import java.util.HashMap;
40 
41 /**
42  * Contains various meta-data about an RMI interface.
43  *
44  * @author Kirill Vainer
45  */
46 public class RemoteObject implements InvocationHandler {
47 
48     /**
49      * Object ID
50      */
51     short objectId;
52 
53     /**
54      * Contains {@link MethodDef method definitions} for all exposed
55      * RMI methods in the remote RMI interface.
56      */
57     MethodDef[] methodDefs;
58 
59     /**
60      * Maps from methods locally retrieved from the RMI interface to
61      * a method ID.
62      */
63     HashMap<Method, Integer> methodMap = new HashMap<Method, Integer>();
64 
65     /**
66      * The {@link ObjectStore} which stores this RMI interface.
67      */
68     ObjectStore store;
69 
70     /**
71      * The client who exposed the RMI interface, or null if the server
72      * exposed it.
73      */
74     HostedConnection client;
75 
RemoteObject(ObjectStore store, HostedConnection client)76     public RemoteObject(ObjectStore store, HostedConnection client){
77         this.store = store;
78         this.client = client;
79     }
80 
methodEquals(MethodDef methodDef, Method method)81     private boolean methodEquals(MethodDef methodDef, Method method){
82         Class<?>[] interfaceTypes = method.getParameterTypes();
83         Class<?>[] defTypes       = methodDef.paramTypes;
84 
85         if (interfaceTypes.length == defTypes.length){
86             for (int i = 0; i < interfaceTypes.length; i++){
87                 if (!defTypes[i].isAssignableFrom(interfaceTypes[i])){
88                     return false;
89                 }
90             }
91             return true;
92         }
93         return false;
94     }
95 
96     /**
97      * Generates mappings from the given interface into the remote RMI
98      * interface's implementation.
99      *
100      * @param interfaceClass The interface class to use.
101      */
loadMethods(Class<?> interfaceClass)102     public void loadMethods(Class<?> interfaceClass){
103         HashMap<String, ArrayList<Method>> nameToMethods
104                 = new HashMap<String, ArrayList<Method>>();
105 
106         for (Method method : interfaceClass.getDeclaredMethods()){
107             ArrayList<Method> list = nameToMethods.get(method.getName());
108             if (list == null){
109                 list = new ArrayList<Method>();
110                 nameToMethods.put(method.getName(), list);
111             }
112             list.add(method);
113         }
114 
115         mapping_search: for (int i = 0; i < methodDefs.length; i++){
116             MethodDef methodDef = methodDefs[i];
117             ArrayList<Method> methods = nameToMethods.get(methodDef.name);
118             if (methods == null)
119                 continue;
120 
121             for (Method method : methods){
122                 if (methodEquals(methodDef, method)){
123                     methodMap.put(method, i);
124                     continue mapping_search;
125                 }
126             }
127         }
128     }
129 
130     /**
131      * Callback from InvocationHandler.
132      */
invoke(Object proxy, Method method, Object[] args)133     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
134         return store.invokeRemoteMethod(this, method, args);
135     }
136 
137 }
138