View Javadoc
1   /*
2    * This program is free software; you can redistribute it and/or
3    * modify it under the terms of the GNU General Public License
4    * as published by the Free Software Foundation; either version 2
5    * of the License, or (at your option) any later version.
6    *
7    * This program is distributed in the hope that it will be useful,
8    * but WITHOUT ANY WARRANTY; without even the implied warranty of
9    * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10   * GNU General Public License for more details.
11   * 
12   * Full GNU GPL license terms : http://www.fsf.org/licenses/gpl.txt
13   * 
14   * Created on Apr 25, 2004
15   */
16  package net.mchaplin.ioc.rmi;
17  
18  import java.rmi.AccessException;
19  import java.rmi.RemoteException;
20  import java.rmi.registry.LocateRegistry;
21  import java.rmi.registry.Registry;
22  import java.util.Iterator;
23  import java.util.List;
24  
25  import net.mchaplin.commons.StackTraceUtils;
26  import net.mchaplin.ioc.ContainerI;
27  import net.mchaplin.ioc.DefaultContainer;
28  import net.mchaplin.ioc.component.DefaultComponent;
29  
30  
31  /***
32   * Bind & manage RmiServices into the RMI Registry
33   * RmiServices instances are registered in a DefaultContainer
34   * instance
35   * 
36   * @author mchaplin@users.sourceforge.net
37   *
38   */
39  public class RmiServer extends DefaultComponent {
40      
41      private static final String RMI_SERVICE = "net.wmind.iky.service.rmi.RmiService";
42      public static final String RMI_SERVICE_CONTAINER = "rmi-service";
43      
44      private RmiServerConfiguration serverConfig = null;
45      private DefaultContainer serviceContainer = null;
46      private Registry registry = null;
47      
48      public RmiServer(RmiServerConfiguration config, ContainerI container) {
49          super();
50          serverConfig = config;
51          // instanciate the Container that will manage RMIImplementations instance
52          serviceContainer = new DefaultContainer(container, RMI_SERVICE_CONTAINER);
53          // Register to its parent, if any
54          serverConfig = config;
55          startServer();
56      }
57      
58      
59      
60      /***
61       * @param config
62       */
63      public void startServer() {
64          log.info("Starting Local RMI Registry");
65          setupRegistry(serverConfig);
66          //log.info("RMI Registry State : "+this.getRegistryState());
67          registerServices(); // instanciate Rmi Services
68          bindServices(); // Bind them into the registry
69          log.info(this.getRegistryState());
70      }
71  
72  
73  
74      /***
75       * @param config
76       */
77      private void setupRegistry(RmiServerConfiguration config) {
78          // TMP
79          config.setHostAddress("0.0.0.0");
80          if (config.getHostAddress() != null && !config.getHostAddress().equals("0.0.0.0") && config.getHostPort() != 0) {
81              try {
82                  registry = LocateRegistry.getRegistry(config.getHostAddress(), config.getHostPort());
83              } catch (RemoteException e) {
84                  log.error("Exception occured while connecting to RMI Registry at : "+config.getHostAddress()+":"+config.getHostPort());
85                  StackTraceUtils.printStackTrace(e);
86              }
87          } else {
88              int port = config.getHostPort() != 0 ? config.getHostPort() : 1099;
89              serverConfig.setHostPort(port);
90              try {
91                  registry = LocateRegistry.createRegistry(port);
92                  serverConfig.setHostAddress("127.0.01");
93              } catch (RemoteException e) {
94                  log.error("Exception occured while creating local RMI Registry on port : "+port);
95                  StackTraceUtils.printStackTrace(e);
96              }
97          }
98      }
99      
100     public String getRegistryState() {
101         StringBuffer state = new StringBuffer();
102         state.append("RMI Registry on host [").append(serverConfig.getHostAddress())
103               .append(":").append(serverConfig.getHostPort()).append("]\n");
104         String[] services = null;
105         if (registry != null) {
106             try {
107                 services = registry.list();
108             } catch (AccessException e) {
109                 e.printStackTrace();
110             } catch (RemoteException e) {
111                 e.printStackTrace();
112             }
113             
114             state.append("\t Bound Services in Registry : ").append("\n");
115             for (int i=0 ; i<services.length ; i++) {
116                 state.append("\t --> ").append(services[i]).append("\n");
117             }
118             
119         } else {
120             state.append("RMI Registry not started, unable to list bound services");
121         }
122               
123         return state.toString();
124     }
125 
126 
127 
128     public void reset() {
129         this.serverConfig = null;
130         // TODO optimize : set each Service to null
131         this.serviceContainer = null;
132     }
133     
134     /***
135      * Bind services in local container
136      * instance in the RMI Registry
137      */
138     private void bindServices() {
139         List li = serviceContainer.retrieveComponentInstances(RMI_SERVICE);
140         if (li != null) {
141             Iterator lit = li.iterator();
142             String name = null;
143             RmiService curService = null;
144             while (lit.hasNext()) {
145                 // Class cast exception
146                 curService = (RmiService) lit.next();
147                 name = curService.getClass().getName();
148                 // keep only classname
149                 name = name.substring(name.lastIndexOf(".")+1);
150                 if (registry != null) {
151                     try {
152                         registry.rebind(name, curService);
153                     } catch (RemoteException e) {
154                         log.error("Remote Exception occured while binding : ["+name.toString()+"] to registry !");
155                         StackTraceUtils.printStackTrace(e);
156                     }
157                     log.info("Service ["+name.toString()+"] bound in RMI Registry");    
158                 } else {
159                     log.error("RMI Registry not started, unable to bind services !");
160                 }
161                 
162             }    
163         } else {
164             log.warn("bindServices() -> No services to bind !");
165         }
166     }
167 
168     /***
169      * Instantiate & register services defined
170      * in RmiServerConfiguration in a local
171      * DefaultContainer instance
172      */
173     private void registerServices() {
174         Class curService = null;
175         // bind instances to rmi
176         if (serverConfig.getRmiServices() != null ) {
177             for (int i=0 ; i<serverConfig.getRmiServices().size() ; i++) {
178                 String className = (String) serverConfig.getRmiServices().get(i);
179                 log.debug("About to register : ["+className+"]");
180                 try {
181                     curService = Class.forName(className);
182                 } catch (ClassNotFoundException e) {
183                     log.error("Component : "+className+" is not in the classpath !");
184                     StackTraceUtils.printStackTrace(e);
185                 }
186                 serviceContainer.registerComponentImplementation(curService, RMI_SERVICE);
187             }    
188         } else {
189             log.error(" -> registerServices() : no services to register !");
190         }
191         
192     }
193     
194     
195     /***
196      * Bind an RmiService instance to RMI Registry
197      * 
198      * @param rmiService instance to bind
199      */
200     public void bindService(RmiService rmiService) {
201        // TODO Implement bindService(RmiService rmiService)
202     }
203 
204     /***
205      * @return Returns the serviceContainer.
206      */
207     public ContainerI getServiceContainer() {
208         return serviceContainer;
209     }
210     /***
211      * @param serviceContainer The serviceContainer to set.
212      */
213     public void setServiceContainer(DefaultContainer serviceContainer) {
214         this.serviceContainer = serviceContainer;
215     }
216     /***
217      * @return Returns the serverConfig.
218      */
219     public RmiServerConfiguration getServerConfig() {
220         return serverConfig;
221     }
222     /***
223      * @param serverConfig The serverConfig to set.
224      */
225     public void setServerConfig(RmiServerConfiguration serverConfig) {
226         this.serverConfig = serverConfig;
227     }
228 }