001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: *
015: * See the License for the specific language governing permissions and
016: * limitations under the License.
017: */
018:
019: /**
020: * @author Mikhail A. Markov
021: * @version $Revision: 1.1.2.3 $
022: */package org.apache.harmony.rmi.registry;
023:
024: import java.net.UnknownHostException;
025: import java.util.Enumeration;
026: import java.util.Hashtable;
027: import java.rmi.Remote;
028: import java.rmi.RemoteException;
029: import java.rmi.RMISecurityManager;
030: import java.rmi.server.ObjID;
031: import java.rmi.server.RemoteServer;
032: import java.rmi.server.RMIClientSocketFactory;
033: import java.rmi.server.RMIServerSocketFactory;
034: import java.rmi.AlreadyBoundException;
035: import java.rmi.NotBoundException;
036: import java.rmi.AccessException;
037: import java.rmi.registry.Registry;
038:
039: import org.apache.harmony.rmi.common.RMIUtil;
040: import org.apache.harmony.rmi.internal.nls.Messages;
041: import org.apache.harmony.rmi.remoteref.UnicastServerRef;
042: import org.apache.harmony.rmi.remoteref.UnicastServerRef2;
043: import org.apache.harmony.rmi.server.ExportManager;
044: import org.apache.harmony.rmi.server.ServerConnectionManager;
045:
046: /**
047: * Transient Registry interface implementation.
048: * It does not extend UnicastRemoteObject because all constructors of
049: * UnicastRemoteObject export itself, but we need a special export for
050: * objects with well-known ObjID numbers.
051: *
052: * @author Mikhail A. Markov
053: * @version $Revision: 1.1.2.3 $
054: */
055: public class RegistryImpl extends RemoteServer implements Registry {
056:
057: private static final long serialVersionUID = 2202752560834503694L;
058:
059: /** Registry Object ID. */
060: public static final ObjID regId = new ObjID(ObjID.REGISTRY_ID);
061:
062: /* Bindings table. */
063: private transient Hashtable table = new Hashtable();
064:
065: /**
066: * Starts rmiregistry on the specified port. If no port specified then
067: * registry will be started on default port. This method ends with a
068: * blocking construction to not let the VM exit.
069: *
070: * @param args arguments which can contain port number
071: */
072: public static void main(String[] args) throws Exception {
073: String usage = "Usage: java org.apache.harmony.rmi.registry.RegistryImpl <port>"; //$NON-NLS-1$
074: int port = REGISTRY_PORT;
075:
076: if (args.length > 1) {
077: System.err.println(usage);
078: System.exit(-1);
079: } else if (args.length == 1) {
080: try {
081: port = Integer.parseInt(args[0]);
082: } catch (NumberFormatException nfe) {
083: // rmi.console.1B=Invalid port number {0}
084: System.out.println(Messages.getString(
085: "rmi.console.1B", args[0])); //$NON-NLS-1$
086: System.out.println(usage);
087: System.exit(-1);
088: }
089: }
090:
091: if (System.getSecurityManager() == null) {
092: System.setSecurityManager(new RMISecurityManager());
093: }
094: Registry reg = new RegistryImpl(port, null, null);
095:
096: // do not let VM exit
097: Object obj = new Object(); //$NON-LOCK-1$
098:
099: synchronized (obj) {
100: obj.wait();
101: }
102: }
103:
104: /**
105: * Constructs registry listening on default port and using default client
106: * and server socket factories for RMI calls.
107: *
108: * @throws RemoteException if the registry could not be exported
109: */
110: public RegistryImpl() throws RemoteException {
111: this (REGISTRY_PORT, null, null);
112: }
113:
114: /**
115: * Constructs registry listening on the specified port and using specified
116: * client and server socket factories for RMI calls.
117: *
118: * @param port port to accept connections
119: * @param csf client-side socket factory
120: * @param ssf server-side socket factory
121: *
122: * @throws RemoteException if the registry could not be exported
123: */
124: public RegistryImpl(int port, RMIClientSocketFactory csf,
125: RMIServerSocketFactory ssf) throws RemoteException {
126: UnicastServerRef sref;
127:
128: if (csf != null || ssf != null) {
129: sref = new UnicastServerRef2(port, csf, ssf, regId);
130: } else {
131: sref = new UnicastServerRef(port, csf, ssf, regId);
132: }
133: ExportManager.exportObject(this , sref, false, true, true);
134: }
135:
136: /**
137: * @see Registry.rebind(String, Remote)
138: */
139: public void rebind(String name, Remote obj) throws RemoteException,
140: AccessException {
141: if (name == null) {
142: // rmi.5D=name could not be null.
143: throw new NullPointerException(Messages.getString("rmi.5D")); //$NON-NLS-1$
144: }
145:
146: if (obj == null) {
147: // rmi.5C=obj could not be null.
148: throw new NullPointerException(Messages.getString("rmi.5C")); //$NON-NLS-1$
149: }
150: checkAccess("RegistryImpl.rebind"); //$NON-NLS-1$
151: table.put(name, obj);
152: }
153:
154: /**
155: * @see Registry.bind(String, Remote)
156: */
157: public void bind(String name, Remote obj) throws RemoteException,
158: AlreadyBoundException, AccessException {
159: if (name == null) {
160: // rmi.5D=name could not be null.
161: throw new NullPointerException(Messages.getString("rmi.5D")); //$NON-NLS-1$
162: }
163:
164: if (obj == null) {
165: // rmi.5C=obj could not be null.
166: throw new NullPointerException(Messages.getString("rmi.5C")); //$NON-NLS-1$
167: }
168:
169: if (table.containsKey(name)) {
170: // rmi.5E=There is already binding to the name {0}.
171: throw new AlreadyBoundException(Messages.getString(
172: "rmi.5E", name)); //$NON-NLS-1$
173: }
174: checkAccess("RegistryImpl.bind"); //$NON-NLS-1$
175: table.put(name, obj);
176: }
177:
178: /**
179: * @see Registry.lookup(String)
180: */
181: public Remote lookup(String name) throws RemoteException,
182: NotBoundException, AccessException {
183: if (name == null) {
184: // rmi.5D=name could not be null.
185: throw new NullPointerException(Messages.getString("rmi.5D")); //$NON-NLS-1$
186: }
187: Remote ref = (Remote) table.get(name);
188:
189: if (ref == null) {
190: // rmi.5F=Name {0} is not associated with any remote reference.
191: throw new NotBoundException(Messages.getString(
192: "rmi.5F", name)); //$NON-NLS-1$
193:
194: }
195: return ref;
196: }
197:
198: /**
199: * @see Registry.unbind(String)
200: */
201: public void unbind(String name) throws RemoteException,
202: NotBoundException, AccessException {
203: if (name == null) {
204: // rmi.5D=name could not be null.
205: throw new NullPointerException(Messages.getString("rmi.5D")); //$NON-NLS-1$
206: }
207: checkAccess("RegistryImpl.unbind"); //$NON-NLS-1$
208:
209: if (table.remove(name) == null) {
210: // rmi.5F=Name {0} is not associated with any remote reference.
211: throw new NotBoundException(Messages.getString(
212: "rmi.5F", name)); //$NON-NLS-1$
213: }
214: }
215:
216: /**
217: * @see Registry.list()
218: */
219: public String[] list() throws RemoteException, AccessException {
220: String[] names = new String[table.size()];
221: Enumeration e = table.keys();
222:
223: for (int i = names.length - 1; i >= 0; --i) {
224: names[i] = (String) e.nextElement();
225: }
226: return names;
227: }
228:
229: /*
230: * Checks if request came from local host. In this case the method will
231: * successfully return. If request came from non-local host then
232: * AccessException will be returned.
233: *
234: * @param registryMethod method requested access check
235: *
236: * @throws AccessException if request came from non-local host
237: */
238: private static void checkAccess(String registryMethod)
239: throws AccessException {
240: String hostName = ServerConnectionManager.getClientHost();
241:
242: try {
243: if (!RMIUtil.isLocalHost(hostName)) {
244: // rmi.60={0} from non-local host {1} is not allowed
245: throw new AccessException(Messages.getString(
246: "rmi.60", registryMethod, hostName)); //$NON-NLS-1$
247: }
248: } catch (UnknownHostException uhe) {
249: // rmi.61={0} from unknown host is not allowed
250: throw new AccessException(Messages.getString(
251: "rmi.61", registryMethod), uhe); //$NON-NLS-1$
252: }
253: }
254: }
|