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 }