1 /*
2 * Copyright 2002-2007 Sun Microsystems, Inc. All Rights Reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25
26 package javax.management.remote.rmi;
27
28 import java.io.IOException;
29 import java.rmi.NoSuchObjectException;
30 import java.rmi.Remote;
31 import java.rmi.RemoteException;
32 import java.rmi.server.RMIClientSocketFactory;
33 import java.rmi.server.RMIServerSocketFactory;
34 import java.rmi.server.UnicastRemoteObject;
35 import java.rmi.server.RemoteObject;
36 import java.util.Map;
37 import java.util.Collections;
38 import javax.security.auth.Subject;
39
40 import com.sun.jmx.remote.internal.RMIExporter;
41
42 /**
43 * <p>An {@link RMIServer} object that is exported through JRMP and that
44 * creates client connections as RMI objects exported through JRMP.
45 * User code does not usually reference this class directly.</p>
46 *
47 * @see RMIServerImpl
48 *
49 * @since 1.5
50 */
51 public class RMIJRMPServerImpl extends RMIServerImpl {
52 /**
53 * <p>Creates a new {@link RMIServer} object that will be exported
54 * on the given port using the given socket factories.</p>
55 *
56 * @param port the port on which this object and the {@link
57 * RMIConnectionImpl} objects it creates will be exported. Can be
58 * zero, to indicate any available port.
59 *
60 * @param csf the client socket factory for the created RMI
61 * objects. Can be null.
62 *
63 * @param ssf the server socket factory for the created RMI
64 * objects. Can be null.
65 *
66 * @param env the environment map. Can be null.
67 *
68 * @exception IOException if the {@link RMIServer} object
69 * cannot be created.
70 *
71 * @exception IllegalArgumentException if <code>port</code> is
72 * negative.
73 */
74 public RMIJRMPServerImpl(int port,
75 RMIClientSocketFactory csf,
76 RMIServerSocketFactory ssf,
77 Map<String,?> env)
78 throws IOException {
79
80 super(env);
81
82 if (port < 0)
83 throw new IllegalArgumentException("Negative port: " + port);
84
85 this.port = port;
86 this.csf = csf;
87 this.ssf = ssf;
88 this.env = (env == null) ? Collections.<String, Object>emptyMap() : env;
89 }
90
91 protected void export() throws IOException {
92 export(this);
93 }
94
95 private void export(Remote obj) throws RemoteException {
96 RMIExporter exporter =
97 (RMIExporter) env.get(RMIExporter.EXPORTER_ATTRIBUTE);
98 if (exporter == null)
99 UnicastRemoteObject.exportObject(obj, port, csf, ssf);
100 else
101 exporter.exportObject(obj, port, csf, ssf);
102 }
103
104 private void unexport(Remote obj, boolean force)
105 throws NoSuchObjectException {
106 RMIExporter exporter =
107 (RMIExporter) env.get(RMIExporter.EXPORTER_ATTRIBUTE);
108 if (exporter == null)
109 UnicastRemoteObject.unexportObject(obj, force);
110 else
111 exporter.unexportObject(obj, force);
112 }
113
114 protected String getProtocol() {
115 return "rmi";
116 }
117
118 /**
119 * <p>Returns a serializable stub for this {@link RMIServer} object.</p>
120 *
121 * @return a serializable stub.
122 *
123 * @exception IOException if the stub cannot be obtained - e.g the
124 * RMIJRMPServerImpl has not been exported yet.
125 */
126 public Remote toStub() throws IOException {
127 return RemoteObject.toStub(this);
128 }
129
130 /**
131 * <p>Creates a new client connection as an RMI object exported
132 * through JRMP. The port and socket factories for the new
133 * {@link RMIConnection} object are the ones supplied
134 * to the <code>RMIJRMPServerImpl</code> constructor.</p>
135 *
136 * @param connectionId the ID of the new connection. Every
137 * connection opened by this connector server will have a
138 * different id. The behavior is unspecified if this parameter is
139 * null.
140 *
141 * @param subject the authenticated subject. Can be null.
142 *
143 * @return the newly-created <code>RMIConnection</code>.
144 *
145 * @exception IOException if the new {@link RMIConnection}
146 * object cannot be created or exported.
147 */
148 protected RMIConnection makeClient(String connectionId, Subject subject)
149 throws IOException {
150
151 if (connectionId == null)
152 throw new NullPointerException("Null connectionId");
153
154 RMIConnection client =
155 new RMIConnectionImpl(this, connectionId, getDefaultClassLoader(),
156 subject, env);
157 export(client);
158 return client;
159 }
160
161 protected void closeClient(RMIConnection client) throws IOException {
162 unexport(client, true);
163 }
164
165 /**
166 * <p>Called by {@link #close()} to close the connector server by
167 * unexporting this object. After returning from this method, the
168 * connector server must not accept any new connections.</p>
169 *
170 * @exception IOException if the attempt to close the connector
171 * server failed.
172 */
173 protected void closeServer() throws IOException {
174 unexport(this, true);
175 }
176
177 private final int port;
178 private final RMIClientSocketFactory csf;
179 private final RMIServerSocketFactory ssf;
180 private final Map<String, ?> env;
181 }