1 package net.sf.crispy.impl.rmi;
2
3 import java.net.BindException;
4 import java.rmi.Remote;
5 import java.rmi.RemoteException;
6 import java.rmi.registry.LocateRegistry;
7 import java.rmi.registry.Registry;
8 import java.rmi.server.ExportException;
9 import java.util.Hashtable;
10 import java.util.Iterator;
11 import java.util.Map;
12
13 import net.sf.crispy.InvocationException;
14 import net.sf.crispy.impl.MiniServer;
15 import net.sf.crispy.impl.RmiExecutor;
16 import net.sf.crispy.impl.ServiceManager;
17 import net.sf.crispy.server.InterceptorHandlerCreator;
18 import net.sf.crispy.server.ServiceEndpoint;
19 import net.sf.crispy.server.SingleServiceContainer;
20 import net.sf.crispy.util.Util;
21
22 import org.apache.commons.logging.Log;
23 import org.apache.commons.logging.LogFactory;
24
25 /**
26 * MiniRmiServer has the function to simulate a RMI Server. This is useful for test the RMI Client.
27 * Do not use this Server in production.
28 *
29 * @author Linke
30 *
31 */
32 public class MiniRmiServer implements MiniServer {
33
34 public static final int PORT = 1098;
35 protected static final Log log = LogFactory.getLog (MiniRmiServer.class);
36
37 private static MiniRmiServer lastStartedRmiServer = null;
38
39 private String urlAndPort = null;
40 private int port = PORT;
41 private Map lookUpMap = new Hashtable();
42 private RmiInvocationHandler rmiInvocationHandler = null;
43
44
45 public MiniRmiServer() { this (PORT); }
46 public MiniRmiServer(int pvPort, RmiInvocationHandler pvRmiInvocationHandler) {
47 this (pvPort);
48 setRmiInvocationHandler(pvRmiInvocationHandler);
49 }
50 public MiniRmiServer(int pvPort) {
51 setPort(pvPort);
52 }
53
54 public final int getPort() { return port; }
55 private void setPort(int pvPort) {
56 if (isStarted() == false) {
57 port = pvPort;
58 } else {
59 log.warn("A RMI-Server is already started on port: " + getPort());
60 }
61 }
62
63 public static boolean isStarted() { return (lastStartedRmiServer != null); }
64 private static void setStartedTrue(MiniRmiServer pvMiniRmiServer) {
65 lastStartedRmiServer = pvMiniRmiServer;
66 }
67 private static void setStartedFalse() {
68 lastStartedRmiServer = null;
69 }
70
71 public static MiniRmiServer getLastStartedRmiServer() {
72 return lastStartedRmiServer;
73 }
74
75 public void setUrlAndPort(String pvUrlAndPort) { urlAndPort = pvUrlAndPort; }
76 public String getUrlAndPort() { return (urlAndPort == null ? RmiExecutor.DEFAULT_URL_AND_PORT : urlAndPort); }
77
78 private void setRmiInvocationHandler(RmiInvocationHandler pvRmiInvocationHandler) {
79 rmiInvocationHandler = pvRmiInvocationHandler;
80 }
81 public RmiInvocationHandler getRmiInvocationHandler() {
82 if (rmiInvocationHandler == null) {
83 rmiInvocationHandler = getDefaultRmiInvocationHandler();
84 }
85 return rmiInvocationHandler;
86 }
87
88 public RmiInvocationHandler getDefaultRmiInvocationHandler() {
89 try {
90 return new RmiInvocationHandlerImpl();
91 } catch (RemoteException e) {
92 if (ServiceManager.DEBUG_MODE_ON) {
93 e.printStackTrace();
94 }
95 }
96 return null;
97 }
98
99 public void setInterceptorHandlerCreator(InterceptorHandlerCreator pvCreator) {
100 if (getRmiInvocationHandler() instanceof ServiceEndpoint) {
101 ((ServiceEndpoint) getRmiInvocationHandler()).setInterceptorHandlerCreator(pvCreator);
102 } else {
103 log.warn("The RmiInvocationHandler is not a instance of ServiceEndpoint. Can't set the InterceptorHandlerCreator: " + pvCreator);
104 }
105 }
106 public InterceptorHandlerCreator getInterceptorHandlerCreator() {
107 if (getRmiInvocationHandler() instanceof ServiceEndpoint) {
108 return ((ServiceEndpoint) getRmiInvocationHandler()).getInterceptorHandlerCreator();
109 } else {
110 log.warn("The RmiInvocationHandler is not a instance of ServiceEndpoint.");
111 return null;
112 }
113 }
114
115
116 public void addService (String pvServiceInterface, String pvServiceObject) {
117 try {
118 Object lvServiceObject = Util.createObject(pvServiceObject);
119 if (lvServiceObject instanceof Remote) {
120 addService(pvServiceInterface, (Remote) lvServiceObject);
121 } else {
122 addService(pvServiceInterface, lvServiceObject);
123 }
124 } catch (Exception e) {
125 if (ServiceManager.DEBUG_MODE_ON) {
126 e.printStackTrace();
127 }
128 }
129 }
130
131 public void addService (String pvLookName, Object pvServiceObject) {
132 RmiInvocationHandler lvHandler = getRmiInvocationHandler();
133 if (lvHandler instanceof SingleServiceContainer) {
134 ((SingleServiceContainer) lvHandler).addService(pvLookName, pvServiceObject);
135 } else {
136 throw new InvocationException("Can't add service: " + pvLookName +
137 ". The RmiInvocationHandler isen't a implementation from the SingleServiceContainer instance.");
138 }
139 }
140
141 public void addService (String pvLookName, Remote pvServiceObject) {
142 lookUpMap.put(pvLookName, pvServiceObject);
143 }
144
145 public void removeService (String pvLookName) {
146 lookUpMap.remove(pvLookName);
147 Registry registry = getRegistry(getPort());
148 try {
149 registry.unbind(pvLookName);
150 } catch (Exception e) {
151 if (log.isDebugEnabled()) {
152 log.debug("Can't remove service: " + pvLookName + " from MiniRmiServer: " + e, e);
153 }
154 }
155 }
156
157 public static Registry getRegistry(int pvPort) {
158 Registry registry = null;
159 try {
160 registry = LocateRegistry.getRegistry(pvPort);
161 registry.list();
162 return registry;
163 } catch (Exception t) {
164 try {
165 return LocateRegistry.createRegistry(pvPort);
166 } catch (ExportException e) {
167 if(e.getCause() != null && e.getCause() instanceof BindException) {
168 log.error("With the port: " + pvPort + " is a RMI-server already started (other JVM).");
169 }
170 if (ServiceManager.DEBUG_MODE_ON) {
171 e.printStackTrace();
172 }
173 } catch (RemoteException e) {
174 e.printStackTrace();
175 }
176 }
177 return registry;
178 }
179
180 public void start() {
181
182
183
184
185
186 if (isStarted() == false) {
187 try {
188 Registry registry = getRegistry(getPort());
189
190
191
192 registry.rebind(RmiExecutor.LOOKUP_NAME, getRmiInvocationHandler());
193
194 Iterator it = lookUpMap.keySet().iterator();
195 while (it.hasNext()) {
196 String lvKey = (String) it.next();
197 Object lvValue = lookUpMap.get(lvKey);
198 registry.rebind(lvKey, (Remote) lvValue);
199 }
200
201 setStartedTrue(this);
202 if (log.isDebugEnabled()) {
203 log.debug("MiniRmiServer is waiting for requests ...");
204 }
205 } catch (Exception e) {
206 e.printStackTrace();
207 }
208 } else {
209 if (log.isWarnEnabled()) {
210 log.warn("A RMI-server is already started on port: " + lastStartedRmiServer.getPort() + ". Only one RMI-server-instance per JVM is supported.");
211 }
212 }
213
214
215 }
216
217
218 public void stop() {
219 try {
220
221 Registry registry = getRegistry(getPort());
222
223 Iterator it = lookUpMap.keySet().iterator();
224 String lvKey = null;
225 Object lvValue = null;
226 while (it.hasNext()) {
227 try {
228 lvKey = (String) it.next();
229 lvValue = lookUpMap.get(lvKey);
230 registry.unbind(lvKey);
231
232 } catch (Exception e) {
233 log.debug("Problem by unbind service: " + lvKey + " --> " + lvValue);
234 }
235 }
236 if (registry != null) {
237 registry.unbind(RmiExecutor.LOOKUP_NAME);
238 }
239
240 registry = null;
241 } catch (Exception e) {
242 if (ServiceManager.DEBUG_MODE_ON) {
243 e.printStackTrace();
244 }
245 }
246 finally {
247 setStartedFalse();
248 }
249
250 }
251
252 public static void main(String[] args) {
253 Util.initJdkLogger();
254 MiniServer lvMiniServer = new MiniRmiServer();
255
256 lvMiniServer.addService("test.crispy.example.service.Echo", "test.crispy.example.service.EchoImpl");
257 lvMiniServer.addService("test.crispy.example.service.Calculator", "test.crispy.example.service.CalculatorImpl");
258
259 lvMiniServer.start();
260 }
261 }