KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > thaiopensource > util > Service


1 package com.thaiopensource.util;
2
3 import java.util.Enumeration JavaDoc;
4 import java.util.NoSuchElementException JavaDoc;
5 import java.util.Vector JavaDoc;
6 import java.io.Reader JavaDoc;
7 import java.io.InputStream JavaDoc;
8 import java.io.InputStreamReader JavaDoc;
9 import java.io.BufferedReader JavaDoc;
10 import java.io.IOException JavaDoc;
11 import java.io.UnsupportedEncodingException JavaDoc;
12 import java.net.URL JavaDoc;
13
14 public class Service {
15   private final Class JavaDoc serviceClass;
16   private final Enumeration JavaDoc configFiles;
17   private Enumeration JavaDoc classNames = null;
18   private final Vector JavaDoc providers = new Vector JavaDoc();
19   private Loader loader;
20
21   private class ProviderEnumeration implements Enumeration JavaDoc {
22     private int nextIndex = 0;
23
24     public boolean hasMoreElements() {
25       return nextIndex < providers.size() || moreProviders();
26     }
27
28     public Object JavaDoc nextElement() {
29       try {
30     return providers.elementAt(nextIndex++);
31       }
32       catch (ArrayIndexOutOfBoundsException JavaDoc e) {
33     throw new NoSuchElementException JavaDoc();
34       }
35     }
36   }
37
38   private static class Singleton implements Enumeration JavaDoc {
39     private Object JavaDoc obj;
40     private Singleton(Object JavaDoc obj) {
41       this.obj = obj;
42     }
43
44     public boolean hasMoreElements() {
45       return obj != null;
46     }
47
48     public Object JavaDoc nextElement() {
49       if (obj == null)
50     throw new NoSuchElementException JavaDoc();
51       Object JavaDoc tem = obj;
52       obj = null;
53       return tem;
54     }
55   }
56
57   // JDK 1.1
58
private static class Loader {
59     Enumeration JavaDoc getResources(String JavaDoc resName) {
60       ClassLoader JavaDoc cl = Loader.class.getClassLoader();
61       URL JavaDoc url;
62       if (cl == null)
63     url = ClassLoader.getSystemResource(resName);
64       else
65     url = cl.getResource(resName);
66       return new Singleton(url);
67     }
68
69     Class JavaDoc loadClass(String JavaDoc name) throws ClassNotFoundException JavaDoc {
70       return Class.forName(name);
71     }
72   }
73
74   // JDK 1.2+
75
private static class Loader2 extends Loader {
76     private ClassLoader JavaDoc cl;
77
78     Loader2() {
79       cl = Loader2.class.getClassLoader();
80       // If the thread context class loader has the class loader
81
// of this class as an ancestor, use the thread context class
82
// loader. Otherwise, the thread context class loader
83
// probably hasn't been set up properly, so don't use it.
84
ClassLoader JavaDoc clt = Thread.currentThread().getContextClassLoader();
85       for (ClassLoader JavaDoc tem = clt; tem != null; tem = tem.getParent())
86     if (tem == cl) {
87       cl = clt;
88       break;
89     }
90     }
91
92     Enumeration JavaDoc getResources(String JavaDoc resName) {
93       try {
94         Enumeration JavaDoc resources = cl.getResources(resName);
95         if (resources.hasMoreElements())
96       return resources;
97         // Some application servers apparently do not implement findResources
98
// in their class loaders, so fall back to getResource.
99
return new Singleton(cl.getResource(resName));
100       }
101       catch (IOException JavaDoc e) {
102     return new Singleton(null);
103       }
104     }
105
106     Class JavaDoc loadClass(String JavaDoc name) throws ClassNotFoundException JavaDoc {
107       return Class.forName(name, true, cl);
108     }
109   }
110
111   public Service(Class JavaDoc cls) {
112     try {
113       loader = new Loader2();
114     }
115     catch (NoSuchMethodError JavaDoc e) {
116       loader = new Loader();
117     }
118     serviceClass = cls;
119     String JavaDoc resName = "META-INF/services/" + serviceClass.getName();
120     configFiles = loader.getResources(resName);
121   }
122
123   public Enumeration JavaDoc getProviders() {
124     return new ProviderEnumeration();
125   }
126
127   synchronized private boolean moreProviders() {
128     for (;;) {
129       while (classNames == null) {
130     if (!configFiles.hasMoreElements())
131       return false;
132     classNames = parseConfigFile((URL JavaDoc)configFiles.nextElement());
133       }
134       while (classNames.hasMoreElements()) {
135     String JavaDoc className = (String JavaDoc)classNames.nextElement();
136     try {
137       Class JavaDoc cls = loader.loadClass(className);
138       Object JavaDoc obj = cls.newInstance();
139       if (serviceClass.isInstance(obj)) {
140         providers.addElement(obj);
141         return true;
142       }
143     }
144     catch (ClassNotFoundException JavaDoc e) { }
145     catch (InstantiationException JavaDoc e) { }
146     catch (IllegalAccessException JavaDoc e) { }
147     catch (LinkageError JavaDoc e) { }
148       }
149       classNames = null;
150     }
151   }
152
153   private static final int START = 0;
154   private static final int IN_NAME = 1;
155   private static final int IN_COMMENT = 2;
156
157   private static Enumeration JavaDoc parseConfigFile(URL JavaDoc url) {
158     try {
159       InputStream JavaDoc in = url.openStream();
160       Reader JavaDoc r;
161       try {
162     r = new InputStreamReader JavaDoc(in, "UTF-8");
163       }
164       catch (UnsupportedEncodingException JavaDoc e) {
165     r = new InputStreamReader JavaDoc(in, "UTF8");
166       }
167       r = new BufferedReader JavaDoc(r);
168       Vector JavaDoc tokens = new Vector JavaDoc();
169       StringBuffer JavaDoc tokenBuf = new StringBuffer JavaDoc();
170       int state = START;
171       for (;;) {
172     int n = r.read();
173     if (n < 0)
174       break;
175     char c = (char)n;
176     switch (c) {
177     case '\r':
178     case '\n':
179       state = START;
180       break;
181     case ' ':
182     case '\t':
183       break;
184     case '#':
185       state = IN_COMMENT;
186       break;
187     default:
188       if (state != IN_COMMENT) {
189         state = IN_NAME;
190         tokenBuf.append(c);
191       }
192       break;
193     }
194     if (tokenBuf.length() != 0 && state != IN_NAME) {
195       tokens.addElement(tokenBuf.toString());
196       tokenBuf.setLength(0);
197     }
198       }
199       if (tokenBuf.length() != 0)
200     tokens.addElement(tokenBuf.toString());
201       return tokens.elements();
202     }
203     catch (IOException JavaDoc e) {
204       return null;
205     }
206   }
207
208   public static void main(String JavaDoc[] args) throws ClassNotFoundException JavaDoc {
209     Service svc = new Service(Class.forName(args[0]));
210     for (Enumeration JavaDoc e = svc.getProviders(); e.hasMoreElements();)
211       System.out.println(e.nextElement().getClass().getName());
212   }
213 }
214
Popular Tags