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