001: /*
002: * Copyright (c) 1998-2003 Caucho Technology -- all rights reserved
003: *
004: * This file is part of Resin(R) Open Source
005: *
006: * Each copy or derived work must preserve the copyright notice and this
007: * notice unmodified.
008: *
009: * Resin Open Source is free software; you can redistribute it and/or modify
010: * it under the terms of the GNU General Public License as published by
011: * the Free Software Foundation; either version 2 of the License, or
012: * (at your option) any later version.
013: *
014: * Resin Open Source is distributed in the hope that it will be useful,
015: * but WITHOUT ANY WARRANTY; without even the implied warranty of
016: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
017: * of NON-INFRINGEMENT. See the GNU General Public License for more
018: * details.
019: *
020: * You should have received a copy of the GNU General Public License
021: * along with Resin Open Source; if not, write to the
022: * Free SoftwareFoundation, Inc.
023: * 59 Temple Place, Suite 330
024: * Boston, MA 02111-1307 USA
025: *
026: * @author Sam
027: */
028:
029: package com.caucho.resources.rmi;
030:
031: import com.caucho.config.ConfigException;
032: import com.caucho.jca.AbstractResourceAdapter;
033: import com.caucho.log.Log;
034: import com.caucho.util.L10N;
035:
036: import javax.resource.spi.BootstrapContext;
037: import javax.resource.spi.ResourceAdapterInternalException;
038: import java.rmi.registry.LocateRegistry;
039: import java.rmi.registry.Registry;
040: import java.util.Iterator;
041: import java.util.LinkedList;
042: import java.util.logging.Level;
043: import java.util.logging.Logger;
044:
045: /**
046: * An RMI registry and its services. This resource is used to register
047: * services with an RMI Registry. The Registry is either on localhost, in
048: * which case it is created in the local JVM unless it already exists, or the
049: * Registry is on a remote server, in which case it is assumed that the
050: * Registry has already been started.
051: */
052:
053: public class RmiRegistry extends AbstractResourceAdapter {
054: static protected final Logger log = Log.open(RmiRegistry.class);
055: static final L10N L = new L10N(RmiRegistry.class);
056:
057: private String _server = "localhost";
058: private int _port = 1099;
059:
060: private LinkedList<RmiService> _services = new LinkedList<RmiService>();
061:
062: private String _namePrefix;
063:
064: /**
065: * The server that runs the RMI registry. If this is `localhost' (the
066: * default), then the Registry is created on the localhost if it does not
067: * already exist. If the server is not localhost, then it is assumed that
068: * the remote Registry already exists.
069: */
070: public void setServer(String server) {
071: _server = server;
072: }
073:
074: public String getServer() {
075: return _server;
076: }
077:
078: /**
079: * The port for the Registry, default is 1099.
080: */
081: public void setPort(int port) {
082: _port = port;
083: }
084:
085: /**
086: * The port for the Registry.
087: */
088: public int getPort() {
089: return _port;
090: }
091:
092: /**
093: * Add an RMI service to register with this Registry.
094: */
095: public void addRmiService(RmiService service)
096: throws ConfigException {
097: _services.add(service);
098:
099: }
100:
101: @javax.annotation.PostConstruct
102: public void init() throws ConfigException {
103: if (System.getSecurityManager() == null)
104: throw new ConfigException(
105: "RMI requires a SecurityManager - add a <security-manager/> element to <resin>");
106:
107: _namePrefix = ("//" + _server + ':' + _port + '/');
108: }
109:
110: public void start(BootstrapContext ctx)
111: throws ResourceAdapterInternalException {
112: if (_server.equals("localhost"))
113: startRegistry();
114: else {
115: log.config(L.l("using remote RMI Registry `{0}:{1}'",
116: _server, String.valueOf(_port)));
117: }
118:
119: // start (export and bind) all services
120: for (Iterator<RmiService> i = _services.iterator(); i.hasNext();) {
121: RmiService s = i.next();
122:
123: s.start();
124: }
125: }
126:
127: /**
128: * Make a full name for a service with this registry and
129: * the given serviceName.
130: */
131: String makeFullName(String serviceName) {
132: return _namePrefix + serviceName;
133: }
134:
135: /**
136: * Start the RMI registry in the local JVM, if it has not been started
137: * already.
138: */
139: private void startRegistry()
140: throws ResourceAdapterInternalException {
141: /**
142: * Some tricks are required here, the RMI Registry needs to be
143: * started from the system classloader.
144: */
145: Thread thread = Thread.currentThread();
146: ClassLoader oldLoader = thread.getContextClassLoader();
147:
148: try {
149: thread.setContextClassLoader(ClassLoader
150: .getSystemClassLoader());
151:
152: try {
153: Registry reg = LocateRegistry.getRegistry(_port);
154: reg.list(); // Verify it's alive and well
155: if (log.isLoggable(Level.CONFIG))
156: log.config(L.l("found RMI Registry on port `{0}'",
157: _port));
158: } catch (Exception e) {
159: // couldn't find a valid registry so create one
160: if (log.isLoggable(Level.CONFIG))
161: log.config(L.l(
162: "creating RMI Registry on port `{0}'",
163: _port));
164:
165: LocateRegistry.createRegistry(_port);
166: }
167: } catch (Exception ex) {
168: throw new ResourceAdapterInternalException(ex);
169: } finally {
170: thread.setContextClassLoader(oldLoader);
171: }
172: }
173:
174: /**
175: * stop (unbind and unexport) all services
176: */
177: public void stop() throws ResourceAdapterInternalException {
178: // unbind and unexport all services
179: for (Iterator<RmiService> i = _services.iterator(); i.hasNext();) {
180: RmiService s = i.next();
181: s.stop();
182: }
183: }
184: }
|