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

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

ObjectMQ without RemoteWrapper? - one consumer per thread -

File size: 5.5 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 UID;
33        private Properties env;
34        private transient Broker broker;
35        private transient Map<String, List<Class<?>>> params;
36        private transient List<InvocationThread> invocationList;
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.UID = 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 num threads to use
76                int numThreads = Integer.parseInt(env.getProperty(ParameterQueue.NUM_THREADS, "1"));
77                invocationList = new ArrayList<InvocationThread>(numThreads);
78
79                // Start invocation threads
80                for (int i = 0; i < numThreads; i++) {
81                        InvocationThread iThread = new InvocationThread(this, broker);
82                        invocationList.add(iThread);
83                        iThread.start();
84                }
85
86        }
87
88        @Override
89        public String getRef() {
90                return UID;
91        }
92
93        /**
94         * This method kills all the threads waiting for requests
95         *
96         * @throws IOException
97         *             - If an operation failed.
98         */
99        public void kill() throws IOException {
100                logger.info("Killing objectmq: " + this.getRef());
101                for (InvocationThread iThread : invocationList) {
102                        iThread.kill();
103                }
104        }
105
106        /**
107         * This method invokes the method specified by methodName and arguments
108         *
109         * @param methodName
110         * @param arguments
111         * @return result
112         * @throws Exception
113         */
114        public Object invokeMethod(String methodName, Object[] arguments) throws Exception {
115
116                // Get the specific method identified by methodName and its arguments
117                Method method = loadMethod(methodName, arguments);
118
119                return method.invoke(this, arguments);
120        }
121
122        /**
123         * This method loads the method specified by methodName and args
124         *
125         * @param methodName
126         * @param args
127         * @return method
128         * @throws NoSuchMethodException
129         *             - If the method cannot be found
130         */
131        private Method loadMethod(String methodName, Object[] args) throws NoSuchMethodException {
132                Method m = null;
133
134                // Obtain the class reference
135                Class<?> clazz = this.getClass();
136                Class<?>[] argArray = null;
137
138                if (args != null) {
139                        argArray = new Class<?>[args.length];
140                        for (int i = 0; i < args.length; i++) {
141                                argArray[i] = args[i].getClass();
142                        }
143                }
144
145                try {
146                        m = clazz.getMethod(methodName, argArray);
147                } catch (NoSuchMethodException nsm) {
148                        m = loadMethodWithPrimitives(methodName, argArray);
149                }
150                return m;
151        }
152
153        /**
154         * This method loads a method which uses primitives as arguments
155         *
156         * @param methodName
157         *            - name of the method wanted to invoke
158         * @param argArray
159         *            - arguments
160         * @return method
161         * @throws NoSuchMethodException
162         *             - If the method cannot be found
163         */
164        private Method loadMethodWithPrimitives(String methodName, Class<?>[] argArray) throws NoSuchMethodException {
165                if (argArray != null) {
166                        Method[] methods = this.getClass().getMethods();
167                        int length = argArray.length;
168
169                        for (Method method : methods) {
170                                String name = method.getName();
171                                int argsLength = method.getParameterTypes().length;
172
173                                if (name.equals(methodName) && length == argsLength) {
174                                        // This array can have primitive types inside
175                                        Class<?>[] params = method.getParameterTypes();
176
177                                        boolean found = true;
178
179                                        for (int i = 0; i < length; i++) {
180                                                if (params[i].isPrimitive()) {
181                                                        Class<?> paramWrapper = primitiveClasses.get(params[i].getName());
182
183                                                        if (!paramWrapper.equals(argArray[i])) {
184                                                                found = false;
185                                                                break;
186                                                        }
187                                                }
188                                        }
189                                        if (found) {
190                                                return method;
191                                        }
192                                }
193                        }
194                }
195                throw new NoSuchMethodException(methodName);
196        }
197
198        public List<Class<?>> getParams(String methodName) {
199                return params.get(methodName);
200        }
201
202        public Broker getBroker() {
203                return broker;
204        }
205
206        public Properties getEnv() {
207                return env;
208        }
209
210}
Note: See TracBrowser for help on using the repository browser.