1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package com.gridsystems.innergrid.api;
18
19 import java.io.InputStream;
20 import java.io.Serializable;
21 import java.lang.reflect.Constructor;
22 import java.net.URL;
23 import java.rmi.Remote;
24 import java.util.Comparator;
25 import java.util.Enumeration;
26 import java.util.Map;
27 import java.util.Properties;
28 import java.util.TreeMap;
29
30 import com.gridsystems.innergrid.kernel.KernelException;
31
32
33
34
35
36
37
38 public final class ApiFactory {
39
40
41
42
43 private static final int DUMMY_DEFAULT_PORT = 1;
44
45
46
47
48 private static Map<Class, Api> apis = new TreeMap<Class, Api>(new ClassComparator());
49
50
51
52
53 private static Map<Class, Class> interfaces
54 = new TreeMap<Class, Class>(new ClassComparator());
55
56
57
58
59 private ApiFactory() { }
60
61
62
63
64
65
66 static {
67 String apiname = "com/gridsystems/innergrid/api/api.providers";
68
69
70
71 Enumeration enumeration = null;
72 try {
73 ClassLoader cl = Thread.currentThread().getContextClassLoader();
74 enumeration = cl.getResources(apiname);
75 } catch (Exception ex) {
76 System.err.println("ApiFactory::static() -> Error loading API.");
77 enumeration = null;
78 }
79
80 Connection conn = null;
81 try {
82 Credentials cred = new UsernameTokenCredentials("", "");
83 conn = new DirectConnection("localhost", DUMMY_DEFAULT_PORT, true, cred);
84 } catch (Exception e) { }
85
86 while (enumeration.hasMoreElements()) {
87 URL resource = (URL)enumeration.nextElement();
88 parseResource(resource, conn);
89 }
90 };
91
92
93
94
95
96
97
98 private static void parseResource(URL resource, Connection c) {
99 try {
100 InputStream is = resource.openStream();
101
102 Properties props = new Properties();
103 props.load(is);
104
105 Enumeration e = props.keys();
106
107 while (e.hasMoreElements()) {
108 String key = (String)e.nextElement();
109 String value = props.getProperty(key);
110 parseResourceKeyValue(key, value, c);
111 }
112 } catch (Exception ex) { }
113 }
114
115
116
117
118
119
120
121
122
123 private static void parseResourceKeyValue(String key, String value, Connection c) {
124 String implName = key;
125 String ifaceName = value;
126 boolean isRemote = true;
127
128 int pos = value.indexOf(",");
129 if (pos != -1) {
130 ifaceName = value.substring(0, pos);
131 isRemote = value.substring(pos + 1, value.length()).trim().equals("remote");
132 }
133
134
135 Class< ? > impl;
136 try {
137 impl = Class.forName(implName);
138 Constructor cons = impl.getConstructor(new Class[] {Connection.class});
139 cons.newInstance(new Object[] {c});
140 } catch (ClassNotFoundException ex) {
141 System.err.println("Cannot find " + implName + " implementation class");
142 return;
143 } catch (Exception e) {
144 System.err.println("Cannot find constructor with Connection "
145 + "parameter in " + implName + " class");
146 return;
147 }
148
149
150 Class iface;
151 try {
152 iface = Class.forName(ifaceName);
153 } catch (Exception ex) {
154 System.err.println("Cannot find " + ifaceName + " interface");
155 return;
156 }
157
158
159 try {
160 addApi(iface, impl, isRemote);
161 } catch (Exception ex) {
162 System.err.println("Cannot add api to internal list");
163 }
164 }
165
166
167
168
169
170
171
172 private static class ClassComparator implements Comparator<Class>, Serializable {
173
174
175
176
177 private static final long serialVersionUID = 1234523452345L;
178
179
180
181
182 public ClassComparator() { }
183
184
185
186
187 public int compare(Class c1, Class c2) {
188 String s1 = c1 == null ? "null" : c1.getName();
189 String s2 = c2 == null ? "null" : c2.getName();
190
191 return s1.compareToIgnoreCase(s2);
192 }
193 }
194
195
196
197
198 private static class Api {
199
200
201
202
203 public Class iface = null;
204
205
206
207
208 public Class impl = null;
209
210
211
212
213 public boolean isRemote = true;
214
215
216
217
218
219
220
221
222
223 public Api(Class iface, Class impl, boolean isRemote) {
224 this.iface = iface;
225 this.impl = impl;
226 this.isRemote = isRemote;
227 }
228 }
229
230
231
232
233
234
235
236
237
238 private static void addApi(Class interf, Class impl, boolean isremote) {
239 if (interf == null || impl == null) {
240 return;
241 }
242
243 Api newapi = new Api(interf, impl, isremote);
244 apis.put(impl, newapi);
245
246 Class oldimpl = (Class)interfaces.get(interf);
247 if (oldimpl != null) {
248 Api oldapi = (Api)apis.get(oldimpl);
249 if (oldapi.isRemote && !isremote) {
250 return;
251 }
252 }
253 interfaces.put(interf, impl);
254 }
255
256
257
258
259
260
261 public static Api[] getAllApis() {
262 return (Api[])apis.values().toArray(new Api[0]);
263 }
264
265
266
267
268
269
270
271
272
273
274
275
276
277 @SuppressWarnings("unchecked")
278 public static <T extends Remote> T newApi(Class<T> iface, Connection con)
279 throws KernelException {
280
281 if (con == null) {
282 throw new CKernelException("CLT011");
283 }
284 if (iface == null) {
285 throw new CKernelException("CLT015", new String[] { "null" });
286 }
287 Class impl = (Class)interfaces.get(iface);
288 if (impl == null) {
289 throw new CKernelException("CLT015", new String[] { iface.getName() });
290 }
291 T instance;
292 try {
293 Constructor cons = impl.getConstructor(new Class[] { Connection.class });
294 instance = (T)cons.newInstance(new Object[] { con });
295 } catch (Exception ex) {
296 throw new CKernelException("CLT015", new String[] { iface.getName() });
297 }
298 return instance;
299 }
300
301 }