1
20 package org.crosswire.jsword.book.install;
21
22 import java.io.IOException;
23 import java.net.URI;
24 import java.util.Collections;
25 import java.util.Iterator;
26 import java.util.LinkedHashMap;
27 import java.util.List;
28 import java.util.Map;
29 import java.util.Set;
30 import java.util.concurrent.CopyOnWriteArrayList;
31
32 import org.crosswire.common.util.CWProject;
33 import org.crosswire.common.util.FileUtil;
34 import org.crosswire.common.util.NetUtil;
35 import org.crosswire.common.util.PluginUtil;
36 import org.crosswire.common.util.PropertyMap;
37 import org.crosswire.common.util.Reporter;
38 import org.slf4j.Logger;
39 import org.slf4j.LoggerFactory;
40
41
48 public final class InstallManager {
49
52 public InstallManager() {
53 listeners = new CopyOnWriteArrayList<InstallerListener>();
54 installers = new LinkedHashMap<String, Installer>();
55
56 try {
57 PropertyMap sitemap = PluginUtil.getPlugin(getClass());
58 factories = PluginUtil.getImplementorsMap(InstallerFactory.class);
59 int i = 0;
60 for (String def = sitemap.get(PREFIX + ++i); def != null; def = sitemap.get(PREFIX + ++i)) {
61 try {
62 String[] parts = def.split(",", 3);
63 String type = parts[0];
64 String name = parts[1];
65 String rest = parts[2];
66
67 Class<InstallerFactory> clazz = factories.get(type);
68 if (clazz == null) {
69 log.warn("Unable to get class for {}", type);
70 } else {
71 InstallerFactory ifactory = clazz.newInstance();
72 Installer installer = ifactory.createInstaller(rest);
73
74 internalAdd(name, installer);
75 }
76 } catch (InstantiationException e) {
77 Reporter.informUser(this, e);
78 } catch (IllegalAccessException e) {
79 Reporter.informUser(this, e);
80 }
81 }
82 } catch (IOException ex) {
83 Reporter.informUser(this, ex);
84 }
85 }
86
87
91 public void save() {
92 PropertyMap props = new PropertyMap();
93 StringBuilder buf = new StringBuilder();
94 int i = 1;
95 for (String name : installers.keySet()) {
96 Installer installer = installers.get(name);
97 buf.delete(0, buf.length());
99 buf.append(installer.getType());
100 buf.append(',');
101 buf.append(name);
102 buf.append(',');
103 buf.append(installer.getInstallerDefinition());
104 props.put(PREFIX + i++, buf.toString());
105 }
106 URI outputURI = CWProject.instance().getWritableURI(getClass().getName(), FileUtil.EXTENSION_PLUGIN);
107 try {
108 NetUtil.storeProperties(props, outputURI, "Saved Installer Sites");
109 } catch (IOException e) {
110 log.error("Failed to save installers", e);
111 }
112 }
113
114
119 public Set<String> getInstallerFactoryNames() {
120 return Collections.unmodifiableSet(factories.keySet());
121 }
122
123
131 public String getFactoryNameForInstaller(Installer installer) {
132 Class<? extends Installer> match = installer.getClass();
133 for (String name : factories.keySet()) {
134 Class<InstallerFactory> factclazz = factories.get(name);
135 try {
136 InstallerFactory ifactory = factclazz.newInstance();
137 Class<? extends Installer> clazz = ifactory.createInstaller().getClass();
138 if (clazz == match) {
139 return name;
140 }
141 } catch (InstantiationException e) {
142 log.warn("Failed to instantiate installer factory: {}={}", name, factclazz.getName(), e);
143 } catch (IllegalAccessException e) {
144 log.warn("Failed to instantiate installer factory: {}={}", name, factclazz.getName(), e);
145 }
146 }
147
148 log.warn("Failed to find factory name for {} among the {} factories.", installer, Integer.toString(factories.size()));
149 return null;
150 }
151
152
160 public String getInstallerNameForInstaller(Installer installer) {
161 for (String name : installers.keySet()) {
162 Installer test = installers.get(name);
163 if (installer.equals(test)) {
164 return name;
165 }
166 }
167
168 log.warn("Failed to find installer name for {} among the {} installers.", installer, Integer.toString(installers.size()));
169 for (String name : installers.keySet()) {
170 Installer test = installers.get(name);
171 log.warn(" it isn't equal to {}", test.getInstallerDefinition());
172 }
173 return null;
174 }
175
176
183 public InstallerFactory getInstallerFactory(String name) {
184 Class<InstallerFactory> clazz = factories.get(name);
185 try {
186 return clazz.newInstance();
187 } catch (InstantiationException e) {
188 assert false : e;
189 } catch (IllegalAccessException e) {
190 assert false : e;
191 }
192 return null;
193 }
194
195
199 public Map<String, Installer> getInstallers() {
200 return Collections.unmodifiableMap(installers);
201 }
202
203
210 public Installer getInstaller(String name) {
211 return installers.get(name);
212 }
213
214
222 public void addInstaller(String name, Installer installer) {
223 assert installer != null;
224 assert name != null;
225
226 removeInstaller(name);
227
228 internalAdd(name, installer);
229 fireInstallersChanged(this, installer, true);
230 }
231
232
241 private void internalAdd(String name, Installer installer) {
242 Iterator<String> it = installers.keySet().iterator();
243 while (it.hasNext()) {
244 String tname = it.next();
245 Installer tinstaller = installers.get(tname);
246
247 if (tinstaller.equals(installer)) {
248 log.warn("duplicate installers: {}={}. removing {}", name, tname, tname);
250
251 it.remove();
253 fireInstallersChanged(this, tinstaller, false);
254 }
255 }
256
257 installers.put(name, installer);
258 }
259
260
266 public void removeInstaller(String name) {
267 if (installers.containsKey(name)) {
268 Installer old = installers.remove(name);
269 fireInstallersChanged(this, old, false);
270 }
271 }
272
273
279 public void addInstallerListener(InstallerListener li) {
280 listeners.add(li);
281 }
282
283
289 public void removeBooksListener(InstallerListener li) {
290 listeners.remove(li);
291 }
292
293
303 protected void fireInstallersChanged(Object source, Installer installer, boolean added) {
304 InstallerEvent ev = new InstallerEvent(source, installer, added);
305 for (InstallerListener listener : listeners) {
306 if (added) {
307 listener.installerAdded(ev);
308 } else {
309 listener.installerRemoved(ev);
310 }
311 }
312 }
313
314
317 private static final String PREFIX = "Installer.";
318
319
322 private Map<String, Class<InstallerFactory>> factories;
323
324
327 private Map<String, Installer> installers;
328
329
332 private List<InstallerListener> listeners;
333
334
337 private static final Logger log = LoggerFactory.getLogger(InstallManager.class);
338 }
339