1 package org.codehaus.plexus.classworlds;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 import java.io.Closeable;
20 import java.io.IOException;
21 import java.util.ArrayList;
22 import java.util.Collection;
23 import java.util.Collections;
24 import java.util.LinkedHashMap;
25 import java.util.List;
26 import java.util.Map;
27 import java.util.function.Predicate;
28
29 import org.codehaus.plexus.classworlds.realm.ClassRealm;
30 import org.codehaus.plexus.classworlds.realm.DuplicateRealmException;
31 import org.codehaus.plexus.classworlds.realm.FilteredClassRealm;
32 import org.codehaus.plexus.classworlds.realm.NoSuchRealmException;
33
34
35
36
37
38
39 public class ClassWorld implements Closeable {
40 private final Map<String, ClassRealm> realms;
41
42 private final List<ClassWorldListener> listeners = new ArrayList<>();
43
44 public ClassWorld(String realmId, ClassLoader classLoader) {
45 this();
46
47 try {
48 newRealm(realmId, classLoader);
49 } catch (DuplicateRealmException e) {
50
51 }
52 }
53
54 public ClassWorld() {
55 this.realms = new LinkedHashMap<>();
56 }
57
58 public ClassRealm newRealm(String id) throws DuplicateRealmException {
59 return newRealm(id, getClass().getClassLoader());
60 }
61
62 public ClassRealm newRealm(String id, ClassLoader classLoader) throws DuplicateRealmException {
63 return newRealm(id, classLoader, null);
64 }
65
66
67
68
69
70
71
72
73
74
75
76
77
78 public synchronized ClassRealm newRealm(String id, ClassLoader classLoader, Predicate<String> filter)
79 throws DuplicateRealmException {
80 if (realms.containsKey(id)) {
81 throw new DuplicateRealmException(this, id);
82 }
83
84 ClassRealm realm;
85
86 if (filter == null) {
87 realm = new ClassRealm(this, id, classLoader);
88 } else {
89 realm = new FilteredClassRealm(filter, this, id, classLoader);
90 }
91 realms.put(id, realm);
92
93 for (ClassWorldListener listener : listeners) {
94 listener.realmCreated(realm);
95 }
96
97 return realm;
98 }
99
100
101
102
103
104 @SuppressWarnings("RedundantThrows")
105 @Override
106 public synchronized void close() throws IOException {
107 realms.values().forEach(this::disposeRealm);
108 realms.clear();
109 }
110
111 public synchronized void disposeRealm(String id) throws NoSuchRealmException {
112 ClassRealm realm = realms.remove(id);
113
114 if (realm != null) {
115 disposeRealm(realm);
116 } else {
117 throw new NoSuchRealmException(this, id);
118 }
119 }
120
121 private void disposeRealm(ClassRealm realm) {
122 try {
123 realm.close();
124 } catch (IOException ignore) {
125 }
126 for (ClassWorldListener listener : listeners) {
127 listener.realmDisposed(realm);
128 }
129 }
130
131 public synchronized ClassRealm getRealm(String id) throws NoSuchRealmException {
132 if (realms.containsKey(id)) {
133 return realms.get(id);
134 }
135
136 throw new NoSuchRealmException(this, id);
137 }
138
139 public synchronized Collection<ClassRealm> getRealms() {
140 return Collections.unmodifiableList(new ArrayList<>(realms.values()));
141 }
142
143
144 public synchronized ClassRealm getClassRealm(String id) {
145 if (realms.containsKey(id)) {
146 return realms.get(id);
147 }
148
149 return null;
150 }
151
152 public synchronized void addListener(ClassWorldListener listener) {
153
154 if (!listeners.contains(listener)) {
155 listeners.add(listener);
156 }
157 }
158
159 public synchronized void removeListener(ClassWorldListener listener) {
160 listeners.remove(listener);
161 }
162 }