Commit | Line | Data |
---|---|---|
01e70f63 FT |
1 | package dolda.jglob; |
2 | ||
3 | import java.util.*; | |
4 | import java.io.*; | |
5 | import java.net.*; | |
6 | import java.lang.annotation.*; | |
7 | ||
8 | public class Loader { | |
9 | private final Class<? extends Annotation> an; | |
10 | private final ClassLoader cl; | |
11 | private final Map<Class<?>, Object> instances = new HashMap<Class<?>, Object>(); | |
12 | ||
13 | private Loader(Class<? extends Annotation> annotation, ClassLoader loader) { | |
14 | this.an = annotation; | |
15 | this.cl = loader; | |
16 | } | |
17 | ||
18 | public Iterable<String> names() { | |
19 | return(new Iterable<String>() { | |
20 | public Iterator<String> iterator() { | |
21 | return(new Iterator<String>() { | |
22 | private Enumeration<URL> rls; | |
23 | private Iterator<String> cur = null; | |
24 | ||
25 | private Iterator<String> parse(URL url) { | |
26 | try { | |
27 | List<String> buf = new LinkedList<String>(); | |
28 | InputStream in = url.openStream(); | |
29 | try { | |
30 | BufferedReader r = new BufferedReader(new InputStreamReader(in, "utf-8")); | |
31 | String ln; | |
32 | while((ln = r.readLine()) != null) { | |
33 | ln = ln.trim(); | |
34 | if(ln.length() < 1) | |
35 | continue; | |
36 | buf.add(ln); | |
37 | } | |
38 | return(buf.iterator()); | |
39 | } finally { | |
40 | in.close(); | |
41 | } | |
42 | } catch(IOException e) { | |
43 | throw(new GlobAccessException(e)); | |
44 | } | |
45 | } | |
46 | ||
47 | public boolean hasNext() { | |
48 | if((cur == null) || !cur.hasNext()) { | |
49 | if(rls == null) { | |
50 | try { | |
51 | rls = cl.getResources("META-INF/glob/" + an.getName()); | |
52 | } catch(IOException e) { | |
53 | throw(new GlobAccessException(e)); | |
54 | } | |
55 | } | |
56 | if(!rls.hasMoreElements()) | |
57 | return(false); | |
58 | URL u = rls.nextElement(); | |
59 | cur = parse(u); | |
60 | } | |
61 | return(true); | |
62 | } | |
63 | ||
64 | public String next() { | |
65 | if(!hasNext()) | |
66 | throw(new NoSuchElementException()); | |
67 | String ret = cur.next(); | |
68 | return(ret); | |
69 | } | |
70 | ||
71 | public void remove() {throw(new UnsupportedOperationException());} | |
72 | }); | |
73 | } | |
74 | }); | |
75 | } | |
76 | ||
77 | public Iterable<Class<?>> classes() { | |
78 | return(new Iterable<Class<?>>() { | |
79 | public Iterator<Class<?>> iterator() { | |
80 | return(new Iterator<Class<?>>() { | |
81 | private final Iterator<String> names = names().iterator(); | |
82 | private Class<?> n = null; | |
83 | ||
84 | public boolean hasNext() { | |
85 | while(n == null) { | |
86 | if(!names.hasNext()) | |
87 | return(false); | |
88 | String nm = names.next(); | |
89 | Class<?> c; | |
90 | try { | |
91 | c = cl.loadClass(nm); | |
92 | } catch(ClassNotFoundException e) { | |
93 | continue; | |
94 | } | |
95 | if(c.getAnnotation(an) == null) | |
96 | continue; | |
97 | n = c; | |
98 | } | |
99 | return(true); | |
100 | } | |
101 | ||
102 | public Class<?> next() { | |
103 | if(!hasNext()) | |
104 | throw(new NoSuchElementException()); | |
105 | Class<?> r = n; | |
106 | n = null; | |
107 | return(r); | |
108 | } | |
109 | ||
110 | public void remove() {throw(new UnsupportedOperationException());} | |
111 | }); | |
112 | } | |
113 | }); | |
114 | } | |
115 | ||
116 | public Iterable<?> instances() { | |
117 | return(new Iterable<Object>() { | |
118 | public Iterator<Object> iterator() { | |
119 | return(new Iterator<Object>() { | |
120 | private final Iterator<Class<?>> classes = classes().iterator(); | |
121 | private Object n = null; | |
122 | ||
123 | public boolean hasNext() { | |
124 | while(n == null) { | |
125 | if(!classes.hasNext()) | |
126 | return(false); | |
127 | Class<?> cl = classes.next(); | |
128 | Object inst; | |
129 | try { | |
130 | inst = cl.newInstance(); | |
131 | } catch(InstantiationException e) { | |
132 | throw(new GlobInstantiationException(e)); | |
133 | } catch(IllegalAccessException e) { | |
134 | throw(new GlobInstantiationException(e)); | |
135 | } | |
136 | n = inst; | |
137 | } | |
138 | return(true); | |
139 | } | |
140 | ||
141 | public Object next() { | |
142 | if(!hasNext()) | |
143 | throw(new NoSuchElementException()); | |
144 | Object r = n; | |
145 | n = null; | |
146 | return(r); | |
147 | } | |
148 | ||
149 | public void remove() {throw(new UnsupportedOperationException());} | |
150 | }); | |
151 | } | |
152 | }); | |
153 | } | |
154 | ||
155 | public static Loader get(Class<? extends Annotation> annotation, ClassLoader loader) { | |
156 | return(new Loader(annotation, loader)); | |
157 | } | |
158 | ||
159 | public static Loader get(Class<? extends Annotation> annotation) { | |
160 | return(get(annotation, annotation.getClassLoader())); | |
161 | } | |
162 | } |