1
22 package org.crosswire.jsword.book.install;
23
24 import java.io.IOException;
25 import java.net.URI;
26 import java.util.Collections;
27 import java.util.Iterator;
28 import java.util.LinkedHashMap;
29 import java.util.Map;
30 import java.util.Set;
31
32 import org.crosswire.common.util.CWProject;
33 import org.crosswire.common.util.EventListenerList;
34 import org.crosswire.common.util.FileUtil;
35 import org.crosswire.common.util.Logger;
36 import org.crosswire.common.util.NetUtil;
37 import org.crosswire.common.util.PluginUtil;
38 import org.crosswire.common.util.PropertyMap;
39 import org.crosswire.common.util.Reporter;
40
41
49 public final class InstallManager {
50
53 public InstallManager() {
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("");
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
117 public Set<String> getInstallerFactoryNames() {
118 return Collections.unmodifiableSet(factories.keySet());
119 }
120
121
126 public String getFactoryNameForInstaller(Installer installer) {
127 Class<? extends Installer> match = installer.getClass();
128 for (String name : factories.keySet()) {
129 Class<InstallerFactory> factclazz = factories.get(name);
130 try {
131 InstallerFactory ifactory = factclazz.newInstance();
132 Class<? extends Installer> clazz = ifactory.createInstaller().getClass();
133 if (clazz == match) {
134 return name;
135 }
136 } catch (InstantiationException e) {
137 log.warn("Failed to instantiate installer factory: " + name + "=" + factclazz.getName(), e);
138 } catch (IllegalAccessException e) {
139 log.warn("Failed to instantiate installer factory: " + name + "=" + factclazz.getName(), e);
140 }
141 }
142
143 log.warn("Failed to find factory name for " + installer.toString() + " among the " + factories.size() + " factories.");
144 return null;
145 }
146
147
152 public String getInstallerNameForInstaller(Installer installer) {
153 for (String name : installers.keySet()) {
154 Installer test = installers.get(name);
155 if (installer.equals(test)) {
156 return name;
157 }
158 }
159
160 log.warn("Failed to find installer name for " + installer.toString() + " among the " + installers.size() + " installers.");
161 for (String name : installers.keySet()) {
162 Installer test = installers.get(name);
163 log.warn(" it isn't equal to " + test.getInstallerDefinition());
164 }
165 return null;
166 }
167
168
175 public InstallerFactory getInstallerFactory(String name) {
176 Class<InstallerFactory> clazz = factories.get(name);
177 try {
178 return clazz.newInstance();
179 } catch (InstantiationException e) {
180 assert false : e;
181 } catch (IllegalAccessException e) {
182 assert false : e;
183 }
184 return null;
185 }
186
187
190 public Map<String, Installer> getInstallers() {
191 return Collections.unmodifiableMap(installers);
192 }
193
194
201 public Installer getInstaller(String name) {
202 return installers.get(name);
203 }
204
205
213 public void addInstaller(String name, Installer installer) {
214 assert installer != null;
215 assert name != null;
216
217 removeInstaller(name);
218
219 internalAdd(name, installer);
220 fireInstallersChanged(this, installer, true);
221 }
222
223
232 private void internalAdd(String name, Installer installer) {
233 Iterator<String> it = installers.keySet().iterator();
234 while (it.hasNext()) {
235 String tname = it.next();
236 Installer tinstaller = installers.get(tname);
237
238 if (tinstaller.equals(installer)) {
239 log.warn("duplicate installers: " + name + "=" + tname + ". removing " + tname);
241
242 it.remove();
244 fireInstallersChanged(this, tinstaller, false);
245 }
246 }
247
248 installers.put(name, installer);
249 }
250
251
257 public void removeInstaller(String name) {
258 if (installers.containsKey(name)) {
259 Installer old = installers.remove(name);
260 fireInstallersChanged(this, old, false);
261 }
262 }
263
264
270 public synchronized void addInstallerListener(InstallerListener li) {
271 listeners.add(InstallerListener.class, li);
272 }
273
274
280 public synchronized void removeBooksListener(InstallerListener li) {
281 listeners.remove(InstallerListener.class, li);
282 }
283
284
294 protected synchronized void fireInstallersChanged(Object source, Installer installer, boolean added) {
295 Object[] contents = listeners.getListenerList();
297
298 InstallerEvent ev = null;
301 for (int i = contents.length - 2; i >= 0; i -= 2) {
302 if (contents[i] == InstallerListener.class) {
303 if (ev == null) {
304 ev = new InstallerEvent(source, installer, added);
305 }
306
307 if (added) {
308 ((InstallerListener) contents[i + 1]).installerAdded(ev);
309 } else {
310 ((InstallerListener) contents[i + 1]).installerRemoved(ev);
311 }
312 }
313 }
314 }
315
316
319 private static final String PREFIX = "Installer.";
320
321
324 private Map<String, Class<InstallerFactory>> factories;
325
326
329 private static final Logger log = Logger.getLogger(InstallManager.class);
330
331
334 private Map<String, Installer> installers;
335
336
339 private static EventListenerList listeners = new EventListenerList();
340 }
341