source: branches/supervisor/src/main/java/omq/server/RemoteObject.java @ 105

Last change on this file since 105 was 105, checked in by stoda, 11 years ago

UID changed to reference
TODO: add UID

File size: 5.8 KB
Line 
1package omq.server;
2
3import java.io.IOException;
4import java.lang.reflect.Method;
5import java.util.ArrayList;
6import java.util.HashMap;
7import java.util.List;
8import java.util.Map;
9import java.util.Properties;
10
11import omq.Remote;
12import omq.common.broker.Broker;
13import omq.common.util.ParameterQueue;
14
15import org.apache.log4j.Logger;
16
17/**
18 * A RemoteObject when it's started will be waiting for requests and will invoke
19 * them. When a RemoteObject is started it listens two queues, the first one has
20 * the same name as its reference and the second one is its multiqueue -this
21 * name can be set using a property, be aware to use a name not used by another
22 * object!!!-.
23 *
24 * @author Sergi Toda <sergi.toda@estudiants.urv.cat>
25 *
26 */
27public abstract class RemoteObject implements Remote {
28
29        private static final long serialVersionUID = -1778953938739846450L;
30        private static final Logger logger = Logger.getLogger(RemoteObject.class.getName());
31
32        private String reference;
33        private Properties env;
34        private transient Broker broker;
35        private transient RemoteThreadPool pool;
36        private transient Map<String, List<Class<?>>> params;
37
38        private static final Map<String, Class<?>> primitiveClasses = new HashMap<String, Class<?>>();
39
40        static {
41                primitiveClasses.put("byte", Byte.class);
42                primitiveClasses.put("short", Short.class);
43                primitiveClasses.put("char", Character.class);
44                primitiveClasses.put("int", Integer.class);
45                primitiveClasses.put("long", Long.class);
46                primitiveClasses.put("float", Float.class);
47                primitiveClasses.put("double", Double.class);
48        }
49
50        /**
51         * This method starts a remoteObject.
52         *
53         * @param reference
54         *            - broker's binding referece
55         * @param broker
56         *            - broker that binds this remoteObject
57         * @param env
58         *            - properties of this remoteObject
59         * @throws Exception
60         */
61        public void startRemoteObject(String reference, Broker broker, Properties env) throws Exception {
62                this.broker = broker;
63                this.reference = reference;
64                this.env = env;
65
66                this.params = new HashMap<String, List<Class<?>>>();
67                for (Method m : this.getClass().getMethods()) {
68                        List<Class<?>> list = new ArrayList<Class<?>>();
69                        for (Class<?> clazz : m.getParameterTypes()) {
70                                list.add(clazz);
71                        }
72                        this.params.put(m.getName(), list);
73                }
74
75                // Get pool information
76                int minPoolThreads = Integer.parseInt(env.getProperty(ParameterQueue.MIN_POOL_THREADS, "1"));
77                int maxPoolThreads = Integer.parseInt(env.getProperty(ParameterQueue.MAX_POOL_THREADS, "1"));
78                long refresh = Long.parseLong(env.getProperty(ParameterQueue.POOL_REFRESH_TIME, "60000"));
79                long keepAliveTime = Long.parseLong(env.getProperty(ParameterQueue.KEEP_ALIVE_TIME, "30000"));
80                int maxMessagesPerThread = Integer.parseInt(env.getProperty(ParameterQueue.MAX_MESSAGES_PER_THREAD, "5"));
81
82                // Create the pool & start it
83                pool = new RemoteThreadPool(minPoolThreads, maxPoolThreads, refresh, keepAliveTime, maxMessagesPerThread, this, broker);
84                pool.start();
85        }
86
87        @Override
88        public String getRef() {
89                return reference;
90        }
91
92        /**
93         * This method kills all the threads waiting for requests
94         *
95         * @throws IOException
96         *             - If an operation failed.
97         */
98        public void kill() throws IOException {
99                logger.info("Killing objectmq: " + this.getRef());
100                pool.kill();
101        }
102
103        /**
104         * This method invokes the method specified by methodName and arguments
105         *
106         * @param methodName
107         * @param arguments
108         * @return result
109         * @throws Exception
110         */
111        public Object invokeMethod(String methodName, Object[] arguments) throws Exception {
112
113                // Get the specific method identified by methodName and its arguments
114                Method method = loadMethod(methodName, arguments);
115
116                return method.invoke(this, arguments);
117        }
118
119        /**
120         * This method loads the method specified by methodName and args
121         *
122         * @param methodName
123         * @param args
124         * @return method
125         * @throws NoSuchMethodException
126         *             - If the method cannot be found
127         */
128        private Method loadMethod(String methodName, Object[] args) throws NoSuchMethodException {
129                Method m = null;
130
131                // Obtain the class reference
132                Class<?> clazz = this.getClass();
133                Class<?>[] argArray = null;
134
135                if (args != null) {
136                        argArray = new Class<?>[args.length];
137                        for (int i = 0; i < args.length; i++) {
138                                argArray[i] = args[i].getClass();
139                        }
140                }
141
142                try {
143                        m = clazz.getMethod(methodName, argArray);
144                } catch (NoSuchMethodException nsm) {
145                        m = loadMethodWithPrimitives(methodName, argArray);
146                }
147                return m;
148        }
149
150        /**
151         * This method loads a method which uses primitives as arguments
152         *
153         * @param methodName
154         *            - name of the method wanted to invoke
155         * @param argArray
156         *            - arguments
157         * @return method
158         * @throws NoSuchMethodException
159         *             - If the method cannot be found
160         */
161        private Method loadMethodWithPrimitives(String methodName, Class<?>[] argArray) throws NoSuchMethodException {
162                if (argArray != null) {
163                        Method[] methods = this.getClass().getMethods();
164                        int length = argArray.length;
165
166                        for (Method method : methods) {
167                                String name = method.getName();
168                                int argsLength = method.getParameterTypes().length;
169
170                                if (name.equals(methodName) && length == argsLength) {
171                                        // This array can have primitive types inside
172                                        Class<?>[] params = method.getParameterTypes();
173
174                                        boolean found = true;
175
176                                        for (int i = 0; i < length; i++) {
177                                                if (params[i].isPrimitive()) {
178                                                        Class<?> paramWrapper = primitiveClasses.get(params[i].getName());
179
180                                                        if (!paramWrapper.equals(argArray[i])) {
181                                                                found = false;
182                                                                break;
183                                                        }
184                                                }
185                                        }
186                                        if (found) {
187                                                return method;
188                                        }
189                                }
190                        }
191                }
192                throw new NoSuchMethodException(methodName);
193        }
194
195        public List<Class<?>> getParams(String methodName) {
196                return params.get(methodName);
197        }
198
199        public Broker getBroker() {
200                return broker;
201        }
202
203        public RemoteThreadPool getPool() {
204                return pool;
205        }
206
207        public Properties getEnv() {
208                return env;
209        }
210
211}
Note: See TracBrowser for help on using the repository browser.