1 package org.apache.onami.spi.core;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import static java.lang.String.format;
23
24 import java.util.Iterator;
25 import java.util.NoSuchElementException;
26
27 import com.google.inject.ProvisionException;
28
29
30
31
32
33
34 abstract class AbstractServiceClassIterator<S>
35 implements Iterator<Class<? extends S>>
36 {
37
38
39
40
41 private final Class<S> service;
42
43
44
45
46 private final ClassLoader classLoader;
47
48
49
50
51 private Iterator<String> pending = null;
52
53
54
55
56 private String nextName = null;
57
58
59
60
61
62
63
64 public AbstractServiceClassIterator( Class<S> service, ClassLoader classLoader )
65 {
66 this.service = service;
67 this.classLoader = classLoader;
68 }
69
70
71
72
73 public final boolean hasNext()
74 {
75 if ( nextName != null )
76 {
77 return true;
78 }
79
80 while ( ( pending == null ) || !pending.hasNext() )
81 {
82 if ( !hasMorePendingNames() )
83 {
84 return false;
85 }
86 pending = getPendingNames();
87 }
88
89 nextName = pending.next();
90 return true;
91 }
92
93
94
95
96
97
98 protected abstract boolean hasMorePendingNames();
99
100
101
102
103
104
105 protected abstract Iterator<String> getPendingNames();
106
107
108
109
110 public final Class<? extends S> next()
111 {
112 if ( !hasNext() )
113 {
114 throw new NoSuchElementException();
115 }
116 String className = nextName;
117 nextName = null;
118 try
119 {
120 Class<?> clazz = classLoader.loadClass( className );
121 if ( !service.isAssignableFrom( clazz ) )
122 {
123 throw new ProvisionException( format( "Provider '%s' is not assignable to Service '%s'",
124 className, service.getName() ) );
125 }
126 return clazz.asSubclass( service );
127 }
128 catch ( ClassNotFoundException e )
129 {
130 throw new ProvisionException( format( "Provider '%s' not found: %s", className, e.getMessage() ) );
131 }
132 catch ( ClassCastException e )
133 {
134 throw new ProvisionException( format( "Provider '%s' is not assignable to Service '%s'",
135 className, service.getName() ) );
136 }
137 }
138
139
140
141
142 public final void remove()
143 {
144 throw new UnsupportedOperationException();
145 }
146
147 }