1
21 package org.crosswire.jsword.book.install;
22
23 import java.io.IOException;
24 import java.net.URI;
25 import java.util.Collections;
26 import java.util.Iterator;
27 import java.util.LinkedHashMap;
28 import java.util.List;
29 import java.util.Map;
30 import java.util.Set;
31 import java.util.concurrent.CopyOnWriteArrayList;
32
33 import org.crosswire.common.util.CWProject;
34 import org.crosswire.common.util.FileUtil;
35 import org.crosswire.common.util.NetUtil;
36 import org.crosswire.common.util.PluginUtil;
37 import org.crosswire.common.util.PropertyMap;
38 import org.crosswire.common.util.Reporter;
39 import org.slf4j.Logger;
40 import org.slf4j.LoggerFactory;
41
42
50 public final class InstallManager {
51
54 public InstallManager() {
55 listeners = new CopyOnWriteArrayList<InstallerListener>();
56 installers = new LinkedHashMap<String, Installer>();
57
58 try {
59 PropertyMap sitemap = PluginUtil.getPlugin(getClass());
60 factories = PluginUtil.getImplementorsMap(InstallerFactory.class);
61 int i = 0;
62 for (String def = sitemap.get(PREFIX + ++i); def != null; def = sitemap.get(PREFIX + ++i)) {
63 try {
64 String[] parts = def.split(",", 3);
65 String type = parts[0];
66 String name = parts[1];
67 String rest = parts[2];
68
69 Class<InstallerFactory> clazz = factories.get(type);
70 if (clazz == null) {
71 log.warn("Unable to get class for {}", type);
72 } else {
73 InstallerFactory ifactory = clazz.newInstance();
74 Installer installer = ifactory.createInstaller(rest);
75
76 internalAdd(name, installer);
77 }
78 } catch (InstantiationException e) {
79 Reporter.informUser(this, e);
80 } catch (IllegalAccessException e) {
81 Reporter.informUser(this, e);
82 }
83 }
84 } catch (IOException ex) {
85 Reporter.informUser(this, ex);
86 }
87 }
88
89
93 public void save() {
94 PropertyMap props = new PropertyMap();
95 StringBuilder buf = new StringBuilder();
96 int i = 1;
97 for (String name : installers.keySet()) {
98 Installer installer = installers.get(name);
99 buf.delete(0, buf.length());
101 buf.append(installer.getType());
102 buf.append(',');
103 buf.append(name);
104 buf.append(',');
105 buf.append(installer.getInstallerDefinition());
106 props.put(PREFIX + i++, buf.toString());
107 }
108 URI outputURI = CWProject.instance().getWritableURI(getClass().getName(), FileUtil.EXTENSION_PLUGIN);
109 try {
110 NetUtil.storeProperties(props, outputURI, "Saved Installer Sites");
111 } catch (IOException e) {
112 log.error("Failed to save installers", e);
113 }
114 }
115
116
119 public Set<String> getInstallerFactoryNames() {
120 return Collections.unmodifiableSet(factories.keySet());
121 }
122
123
128 public String getFactoryNameForInstaller(Installer installer) {
129 Class<? extends Installer> match = installer.getClass();
130 for (String name : factories.keySet()) {
131 Class<InstallerFactory> factclazz = factories.get(name);
132 try {
133 InstallerFactory ifactory = factclazz.newInstance();
134 Class<? extends Installer> clazz = ifactory.createInstaller().getClass();
135 if (clazz == match) {
136 return name;
137 }
138 } catch (InstantiationException e) {
139 log.warn("Failed to instantiate installer factory: {}={}", name, factclazz.getName(), e);
140 } catch (IllegalAccessException e) {
141 log.warn("Failed to instantiate installer factory: {}={}", name, factclazz.getName(), e);
142 }
143 }
144
145 log.warn("Failed to find factory name for {} among the {} factories.", installer, Integer.toString(factories.size()));
146 return null;
147 }
148
149
154 public String getInstallerNameForInstaller(Installer installer) {
155 for (String name : installers.keySet()) {
156 Installer test = installers.get(name);
157 if (installer.equals(test)) {
158 return name;
159 }
160 }
161
162 log.warn("Failed to find installer name for {} among the {} installers.", installer, Integer.toString(installers.size()));
163 for (String name : installers.keySet()) {
164 Installer test = installers.get(name);
165 log.warn(" it isn't equal to {}", test.getInstallerDefinition());
166 }
167 return null;
168 }
169
170
177 public InstallerFactory getInstallerFactory(String name) {
178 Class<InstallerFactory> clazz = factories.get(name);
179 try {
180 return clazz.newInstance();
181 } catch (InstantiationException e) {
182 assert false : e;
183 } catch (IllegalAccessException e) {
184 assert false : e;
185 }
186 return null;
187 }
188
189
192 public Map<String, Installer> getInstallers() {
193 return Collections.unmodifiableMap(installers);
194 }
195
196
203 public Installer getInstaller(String name) {
204 return installers.get(name);
205 }
206
207
215 public void addInstaller(String name, Installer installer) {
216 assert installer != null;
217 assert name != null;
218
219 removeInstaller(name);
220
221 internalAdd(name, installer);
222 fireInstallersChanged(this, installer, true);
223 }
224
225
234 private void internalAdd(String name, Installer installer) {
235 Iterator<String> it = installers.keySet().iterator();
236 while (it.hasNext()) {
237 String tname = it.next();
238 Installer tinstaller = installers.get(tname);
239
240 if (tinstaller.equals(installer)) {
241 log.warn("duplicate installers: {}={}. removing {}", name, tname, tname);
243
244 it.remove();
246 fireInstallersChanged(this, tinstaller, false);
247 }
248 }
249
250 installers.put(name, installer);
251 }
252
253
259 public void removeInstaller(String name) {
260 if (installers.containsKey(name)) {
261 Installer old = installers.remove(name);
262 fireInstallersChanged(this, old, false);
263 }
264 }
265
266
272 public void addInstallerListener(InstallerListener li) {
273 listeners.add(li);
274 }
275
276
282 public void removeBooksListener(InstallerListener li) {
283 listeners.remove(li);
284 }
285
286
296 protected void fireInstallersChanged(Object source, Installer installer, boolean added) {
297 InstallerEvent ev = new InstallerEvent(source, installer, added);
298 for (InstallerListener listener : listeners) {
299 if (added) {
300 listener.installerAdded(ev);
301 } else {
302 listener.installerRemoved(ev);
303 }
304 }
305 }
306
307
310 private static final String PREFIX = "Installer.";
311
312
315 private Map<String, Class<InstallerFactory>> factories;
316
317
320 private Map<String, Installer> installers;
321
322
325 private List<InstallerListener> listeners;
326
327
330 private static final Logger log = LoggerFactory.getLogger(InstallManager.class);
331 }
332