001: /*
002: * Copyright 1990-2006 Sun Microsystems, Inc. All Rights Reserved.
003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
004: *
005: * This program is free software; you can redistribute it and/or
006: * modify it under the terms of the GNU General Public License version
007: * 2 only, as published by the Free Software Foundation.
008: *
009: * This program is distributed in the hope that it will be useful, but
010: * WITHOUT ANY WARRANTY; without even the implied warranty of
011: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012: * General Public License version 2 for more details (a copy is
013: * included at /legal/license.txt).
014: *
015: * You should have received a copy of the GNU General Public License
016: * version 2 along with this work; if not, write to the Free Software
017: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
018: * 02110-1301 USA
019: *
020: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
021: * Clara, CA 95054 or visit www.sun.com if you need additional
022: * information or have any questions.
023: */
024:
025: package com.sun.jumpimpl.ixc;
026:
027: import java.awt.Container;
028: import java.rmi.*;
029: import java.rmi.registry.Registry;
030: import java.lang.reflect.Method;
031: import java.security.AccessController;
032: import java.security.AccessControlContext;
033: import java.util.HashMap;
034: import java.util.Arrays;
035: import java.util.ArrayList;
036: import java.util.List;
037: import javax.microedition.xlet.XletContext;
038: import javax.microedition.xlet.UnavailableContainerException;
039: import javax.microedition.xlet.ixc.*;
040:
041: public class JUMPIxcRegistryImpl extends IxcRegistry {
042:
043: // <XletContext, JUMPIxcRegistryImpl>
044: static HashMap ixcRegistries = new HashMap();
045:
046: // This IxcRegistry's XletContext
047: private XletContext context;
048:
049: // The 'name' Strings binded by this IxcRegistry
050: private ArrayList exportedNames;
051:
052: // The stub for the Executive's IxcRegistry
053: JUMPExecIxcRegistryStub amHandler;
054:
055: // This Xlet's AccessControlContext snapshot
056: private AccessControlContext acc;
057:
058: /**
059: * Returns the Inter-Xlet Communication registry.
060: */
061: public static IxcRegistry getIxcRegistryImpl(XletContext context) {
062:
063: synchronized (ixcRegistries) {
064: IxcRegistry regis = (IxcRegistry) ixcRegistries
065: .get(context);
066: if (regis != null)
067: return regis;
068:
069: regis = new JUMPIxcRegistryImpl(context);
070:
071: if (regis != null)
072: ixcRegistries.put(context, regis);
073:
074: return regis;
075: }
076: }
077:
078: public static boolean isExecutiveVM() {
079: return (Utils.getMtaskServerID() == Utils.getMtaskClientID() && Utils
080: .getMtaskServerID() != -1);
081:
082: }
083:
084: protected JUMPIxcRegistryImpl(XletContext context) {
085: super ();
086: this .context = context;
087: this .amHandler = new JUMPExecIxcRegistryStub(context);
088: this .exportedNames = new ArrayList();
089:
090: this .acc = AccessController.getContext();
091: }
092:
093: public Remote lookup(String name) throws StubException,
094: NotBoundException {
095:
096: SecurityManager sm = System.getSecurityManager();
097: if (sm != null)
098: sm.checkPermission(new IxcPermission(name, "lookup"));
099:
100: try {
101: return amHandler.lookupWithXletID(name, Utils
102: .getMtaskClientID());
103: } catch (RemoteException re) {
104: System.out.println("@@@Error with lookup()");
105:
106: if (re instanceof StubException)
107: throw (StubException) re;
108:
109: Throwable e = re.getCause();
110: throw new StubException("lookup() problem", e);
111: }
112: }
113:
114: public void bind(String name, Remote obj) throws StubException,
115: AlreadyBoundException {
116:
117: SecurityManager sm = System.getSecurityManager();
118: if (sm != null)
119: sm.checkPermission(new IxcPermission(name, "bind"));
120:
121: if (name == null || obj == null)
122: throw new NullPointerException("name and obj can't be null");
123:
124: // Basic check, if this xlet already bound the given name.
125: if (exportedNames.contains(name))
126: throw new AlreadyBoundException(name);
127:
128: try {
129:
130: amHandler.bind(name, obj);
131:
132: } catch (RemoteException re) {
133:
134: if (re instanceof StubException)
135: throw (StubException) re;
136:
137: Throwable e = re.getCause();
138: //if (e instanceof AlreadyBoundException)
139: // throw (AlreadyBoundException) e;
140:
141: throw new StubException("Bind() problem", e);
142: }
143:
144: // The object is successfully registered.
145: // Record the name to the local list.
146: synchronized (exportedNames) {
147: exportedNames.add(name);
148: }
149: }
150:
151: public void unbind(String name) throws NotBoundException,
152: AccessException {
153:
154: if (!exportedNames.contains(name)) {
155:
156: // First, a security check.
157: SecurityManager sm = System.getSecurityManager();
158: if (sm != null) {
159: sm.checkPermission(new IxcPermission(name, "bind"));
160: }
161:
162: try {
163: // This is inefficient, but we need to check for
164: // NotBoundException first.
165: List list = Arrays.asList(amHandler.list());
166: if (!list.contains(name))
167: throw new NotBoundException("Name " + name
168: + " not bound");
169: } catch (RemoteException re) {
170: }
171:
172: // At this point, just throw AccessException
173: throw new AccessException(
174: "Cannot unbind objects bound by other xlets");
175: }
176:
177: try {
178: amHandler.unbind(name);
179: } catch (RemoteException e) {
180: throw new RuntimeException(e.getCause());
181: }
182:
183: // Successfully unbinded, remove the name
184: // from the local list as well.
185: synchronized (exportedNames) {
186: exportedNames.remove(name);
187: }
188: }
189:
190: public void rebind(String name, Remote obj) throws StubException,
191: AccessException {
192:
193: SecurityManager sm = System.getSecurityManager();
194: if (sm != null)
195: sm.checkPermission(new IxcPermission(name, "bind"));
196:
197: if (name == null || obj == null)
198: throw new NullPointerException("name and obj can't be null");
199:
200: if (!exportedNames.contains(name)) {
201:
202: // If we know from the local list that this xlet
203: // never exported an obj under a given name before,
204: // then do bind(). If AlreadyBoundException is caught,
205: // then throw it back as AccessException, as another
206: // xlet must have bound an object under the same name.
207: try {
208: bind(name, obj);
209: } catch (AlreadyBoundException e) {
210: throw new AccessException("Name already bound");
211: } // let other exception fall through
212:
213: } else {
214: try {
215: amHandler.rebind(name, obj);
216: } catch (RemoteException re) {
217:
218: // StubException is locally thrown if the obj
219: // implements malformed Remote interface
220: if (re instanceof StubException)
221: throw (StubException) re;
222:
223: // Else inspect what happened in the
224: // Executive VM
225: Throwable e = re.getCause();
226:
227: if (e instanceof StubException)
228: throw (StubException) e;
229:
230: else
231: throw new RuntimeException(e);
232: }
233: }
234:
235: // Successfully rebinded, record this name
236: // just in case the name was never bound.
237: synchronized (exportedNames) {
238: if (!exportedNames.contains(name))
239: exportedNames.add(name);
240: }
241: }
242:
243: public String[] list() {
244: String[] names;
245:
246: try {
247: names = amHandler.list();
248: } catch (RemoteException re) {
249: System.err.println("Unexpected exception during list()");
250: re.printStackTrace();
251: // At least return the names that are known locally...
252: names = (String[]) exportedNames.toArray(new String[] {});
253: }
254:
255: SecurityManager sm = System.getSecurityManager();
256: if (sm != null) {
257: ArrayList list = new ArrayList();
258: for (int i = 0; i < names.length; i++) {
259: try {
260: sm.checkPermission(new IxcPermission(names[i],
261: "lookup"));
262: list.add(names[i]);
263: } catch (SecurityException e) {
264: }
265: }
266: names = (String[]) list.toArray(new String[] {});
267: }
268:
269: return names;
270: }
271:
272: public void unbindAll() {
273:
274: String[] names = (String[]) exportedNames
275: .toArray(new String[] {});
276:
277: for (int i = 0; i < names.length; i++) {
278: try {
279: amHandler.unbind(names[i]);
280: } catch (NotBoundException nbe) {
281: // Just ignore it.
282: } catch (RemoteException re) {
283: System.err
284: .println("Unexpected exception during unbindAll()");
285: throw new RuntimeException(re.getCause());
286: }
287: }
288:
289: // Successfully cleared, remove all names from the local list.
290: synchronized (exportedNames) {
291: exportedNames.clear();
292: }
293: }
294:
295: AccessControlContext getACC() {
296: return acc;
297: }
298: }
|