1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package org.microemu.microedition.io;
23
24 import java.io.IOException;
25 import java.lang.reflect.Proxy;
26 import java.security.AccessControlContext;
27 import java.security.AccessController;
28 import java.security.PrivilegedActionException;
29 import java.security.PrivilegedExceptionAction;
30 import java.util.Vector;
31
32 import javax.microedition.io.Connection;
33 import javax.microedition.io.ConnectionNotFoundException;
34
35 import org.microemu.cldc.ClosedConnection;
36 import org.microemu.log.Logger;
37
38 import com.sun.cdc.io.ConnectionBaseInterface;
39
40
41
42
43
44
45
46 public class ConnectorImpl extends ConnectorAdapter {
47
48
49 private AccessControlContext acc;
50
51
52 public static boolean debugConnectionInvocations = false;
53
54 private final boolean needPrivilegedCalls = isWebstart();
55
56 public ConnectorImpl() {
57 acc = AccessController.getContext();
58 }
59
60 private static boolean isWebstart() {
61 try {
62 return (System.getProperty("javawebstart.version") != null);
63 } catch (SecurityException e) {
64
65 return false;
66 }
67 }
68
69 public Connection open(final String name, final int mode, final boolean timeouts) throws IOException {
70 try {
71 return (Connection) AccessController.doPrivileged(new PrivilegedExceptionAction() {
72 public Object run() throws IOException {
73 if (debugConnectionInvocations || needPrivilegedCalls) {
74 return openSecureProxy(name, mode, timeouts, needPrivilegedCalls);
75 } else {
76 return openSecure(name, mode, timeouts);
77 }
78 }
79 }, acc);
80 } catch (PrivilegedActionException e) {
81 if (e.getCause() instanceof IOException) {
82 throw (IOException) e.getCause();
83 }
84 throw new IOException(e.toString());
85 }
86 }
87
88 private static Class[] getAllInterfaces(Class klass) {
89 Vector allInterfaces = new Vector();
90 Class parent = klass;
91 while (parent != null) {
92 Class[] interfaces = parent.getInterfaces();
93 for (int i = 0; i < interfaces.length; i++) {
94 allInterfaces.add(interfaces[i]);
95 }
96 parent = parent.getSuperclass();
97 }
98
99 return (Class[]) allInterfaces.toArray(new Class[allInterfaces.size()]);
100 }
101
102 private Connection openSecureProxy(String name, int mode, boolean timeouts, boolean needPrivilegedCalls)
103 throws IOException {
104 Connection origConnection = openSecure(name, mode, timeouts);
105 Class connectionClass = null;
106 Class[] interfaces = getAllInterfaces(origConnection.getClass());
107 for (int i = 0; i < interfaces.length; i++) {
108 if (Connection.class.isAssignableFrom(interfaces[i])) {
109 connectionClass = interfaces[i];
110 break;
111 } else if (interfaces[i].getClass().getName().equals(Connection.class.getName())) {
112 Logger.debugClassLoader("ME2 Connection.class", Connection.class);
113 Logger.debugClassLoader(name + " Connection.class", interfaces[i]);
114 Logger.error("Connection interface loaded by different ClassLoader");
115 }
116 }
117 if (connectionClass == null) {
118 throw new ClassCastException(origConnection.getClass().getName() + " Connection expected");
119 }
120 return (Connection) Proxy.newProxyInstance(ConnectorImpl.class.getClassLoader(), interfaces,
121 new ConnectionInvocationHandler(origConnection, needPrivilegedCalls));
122 }
123
124 private Connection openSecure(String name, int mode, boolean timeouts) throws IOException {
125 String className = null;
126 String protocol = null;
127 try {
128 try {
129 protocol = name.substring(0, name.indexOf(':'));
130 className = "org.microemu.cldc." + protocol + ".Connection";
131 Class cl = Class.forName(className);
132 Object inst = cl.newInstance();
133 if (inst instanceof ConnectionImplementation) {
134 return ((ConnectionImplementation) inst).openConnection(name, mode, timeouts);
135 } else {
136 return ((ClosedConnection) inst).open(name);
137 }
138 } catch (ClassNotFoundException e) {
139 try {
140 className = "com.sun.cdc.io.j2me." + protocol + ".Protocol";
141 Class cl = Class.forName(className);
142 ConnectionBaseInterface base = (ConnectionBaseInterface) cl.newInstance();
143 return base.openPrim(name.substring(name.indexOf(':') + 1), mode, timeouts);
144 } catch (ClassNotFoundException ex) {
145 Logger.debug("connection [" + protocol + "] class not found", e);
146 Logger.debug("connection [" + protocol + "] class not found", ex);
147 throw new ConnectionNotFoundException("connection [" + protocol + "] class not found");
148 }
149 }
150 } catch (InstantiationException e) {
151 Logger.error("Unable to create", className, e);
152 throw new ConnectionNotFoundException();
153 } catch (IllegalAccessException e) {
154 Logger.error("Unable to create", className, e);
155 throw new ConnectionNotFoundException();
156 }
157 }
158 }