Initial commit.
[jglob.git] / src / dolda / jglob / Loader.java
CommitLineData
01e70f63
FT
1package dolda.jglob;
2
3import java.util.*;
4import java.io.*;
5import java.net.*;
6import java.lang.annotation.*;
7
8public 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}