1 | |
package org.jtheque.core.managers.patch; |
2 | |
|
3 | |
|
4 | |
|
5 | |
|
6 | |
|
7 | |
|
8 | |
|
9 | |
|
10 | |
|
11 | |
|
12 | |
|
13 | |
|
14 | |
|
15 | |
|
16 | |
|
17 | |
|
18 | |
|
19 | |
import org.jtheque.core.managers.ManagerException; |
20 | |
import org.jtheque.core.managers.Managers; |
21 | |
import org.jtheque.core.managers.log.ILoggingManager; |
22 | |
import org.jtheque.core.managers.view.able.IViewManager; |
23 | |
import org.jtheque.core.utils.file.XMLException; |
24 | |
import org.jtheque.core.utils.file.XMLReader; |
25 | |
import org.jtheque.core.utils.file.XMLWriter; |
26 | |
import org.jtheque.utils.bean.IntDate; |
27 | |
import org.jtheque.utils.io.FileUtils; |
28 | |
|
29 | |
import java.io.File; |
30 | |
import java.util.ArrayList; |
31 | |
import java.util.Collection; |
32 | |
|
33 | |
|
34 | |
|
35 | |
|
36 | |
|
37 | |
|
38 | |
public final class PatchManager implements IPatchManager { |
39 | |
private final Collection<AppliedPatch> appliedPatches; |
40 | |
private final Collection<OnlinePatch> onlinePatches; |
41 | |
private final Collection<Patch> patches; |
42 | |
|
43 | |
private boolean updated; |
44 | 0 | private boolean xmlUpToDate = true; |
45 | |
|
46 | |
private static final int RESTART_CODE = 2; |
47 | |
|
48 | |
|
49 | |
|
50 | |
|
51 | |
public PatchManager() { |
52 | 0 | super(); |
53 | |
|
54 | 0 | patches = new ArrayList<Patch>(10); |
55 | 0 | appliedPatches = new ArrayList<AppliedPatch>(10); |
56 | 0 | onlinePatches = new ArrayList<OnlinePatch>(10); |
57 | 0 | } |
58 | |
|
59 | |
@Override |
60 | |
public boolean isApplied(String name) { |
61 | 0 | boolean applied = false; |
62 | |
|
63 | 0 | for (AppliedPatch patch : appliedPatches) { |
64 | 0 | if (patch.getName().equals(name)) { |
65 | 0 | applied = true; |
66 | |
} |
67 | |
} |
68 | |
|
69 | 0 | return applied; |
70 | |
} |
71 | |
|
72 | |
@Override |
73 | |
public void setUpdated(boolean updatedParameter) { |
74 | 0 | updated = updatedParameter; |
75 | 0 | xmlUpToDate = false; |
76 | 0 | } |
77 | |
|
78 | |
@Override |
79 | |
public void preInit() { |
80 | 0 | boolean restart = applyPatchesIfNeeded(); |
81 | |
|
82 | 0 | if (restart) { |
83 | 0 | Managers.getManager(IViewManager.class).getSplashManager().closeSplashScreen(); |
84 | |
|
85 | 0 | Managers.getCore().getLifeCycleManager().restart(); |
86 | |
} |
87 | 0 | } |
88 | |
|
89 | |
@Override |
90 | |
public void init() throws ManagerException { |
91 | 0 | File f = new File(Managers.getCore().getFolders().getApplicationFolder(), "/core/patchs.xml"); |
92 | |
|
93 | 0 | if (f.exists()) { |
94 | 0 | openConfiguration(f); |
95 | |
} else { |
96 | 0 | updated = true; |
97 | 0 | xmlUpToDate = false; |
98 | |
} |
99 | 0 | } |
100 | |
|
101 | |
|
102 | |
|
103 | |
|
104 | |
|
105 | |
|
106 | |
private void openConfiguration(File f) { |
107 | 0 | XMLReader reader = new XMLReader(); |
108 | |
|
109 | |
try { |
110 | 0 | reader.openFile(f); |
111 | |
|
112 | 0 | readUpdated(reader); |
113 | 0 | readAppliedPatches(reader); |
114 | 0 | readPatches(reader); |
115 | 0 | } catch (XMLException e) { |
116 | 0 | Managers.getManager(ILoggingManager.class).getLogger(getClass()).error(e); |
117 | |
} finally { |
118 | 0 | FileUtils.close(reader); |
119 | 0 | } |
120 | 0 | } |
121 | |
|
122 | |
|
123 | |
|
124 | |
|
125 | |
|
126 | |
|
127 | |
|
128 | |
private void readUpdated(XMLReader reader) throws XMLException { |
129 | 0 | String strUpdated = reader.readString("updated", reader.getRootElement()); |
130 | |
|
131 | 0 | if (strUpdated != null && "1".equals(strUpdated)) { |
132 | 0 | updated = true; |
133 | |
} |
134 | 0 | } |
135 | |
|
136 | |
|
137 | |
|
138 | |
|
139 | |
|
140 | |
|
141 | |
|
142 | |
private void readPatches(XMLReader reader) throws XMLException { |
143 | 0 | for (Object currentNode : reader.getNodes("patch/patch", reader.getRootElement())) { |
144 | 0 | String c = reader.readString("@class", currentNode); |
145 | |
|
146 | |
try { |
147 | 0 | Class<?> patchClass = Class.forName(c, true, getClass().getClassLoader()); |
148 | |
|
149 | 0 | if (Patch.class.isAssignableFrom(patchClass)) { |
150 | 0 | Class<Patch> castedClass = (Class<Patch>) patchClass; |
151 | |
|
152 | |
try { |
153 | 0 | patches.add(castedClass.newInstance()); |
154 | 0 | } catch (InstantiationException e) { |
155 | 0 | Managers.getManager(ILoggingManager.class).getLogger(getClass()).error(e); |
156 | 0 | } catch (IllegalAccessException e) { |
157 | 0 | Managers.getManager(ILoggingManager.class).getLogger(getClass()).error(e); |
158 | 0 | } |
159 | |
} |
160 | 0 | } catch (ClassNotFoundException e) { |
161 | 0 | Managers.getManager(ILoggingManager.class).getLogger(getClass()).error(e); |
162 | 0 | } |
163 | 0 | } |
164 | 0 | } |
165 | |
|
166 | |
|
167 | |
|
168 | |
|
169 | |
|
170 | |
|
171 | |
|
172 | |
private void readAppliedPatches(XMLReader reader) throws XMLException { |
173 | 0 | for (Object currentNode : reader.getNodes("applied/patch", reader.getRootElement())) { |
174 | 0 | AppliedPatch patch = new AppliedPatch(); |
175 | |
|
176 | 0 | patch.setDate(new IntDate(reader.readInt("date", currentNode))); |
177 | 0 | patch.setName(reader.readString("name", currentNode)); |
178 | |
|
179 | 0 | appliedPatches.add(patch); |
180 | 0 | } |
181 | 0 | } |
182 | |
|
183 | |
@Override |
184 | |
public void close() { |
185 | 0 | if (!xmlUpToDate) { |
186 | 0 | saveXML(); |
187 | |
} |
188 | 0 | } |
189 | |
|
190 | |
|
191 | |
|
192 | |
|
193 | |
private void saveXML() { |
194 | 0 | XMLWriter writer = new XMLWriter("config"); |
195 | |
|
196 | 0 | writer.setCurrent(writer.getRoot()); |
197 | |
|
198 | 0 | saveUpdated(writer); |
199 | 0 | saveAppliedPatches(writer); |
200 | 0 | savePatches(writer); |
201 | |
|
202 | 0 | writer.write(Managers.getCore().getFolders().getApplicationFolder().getAbsolutePath() + "/core/patchs.xml"); |
203 | 0 | } |
204 | |
|
205 | |
|
206 | |
|
207 | |
|
208 | |
|
209 | |
|
210 | |
private void savePatches(XMLWriter writer) { |
211 | 0 | writer.add("patchs"); |
212 | |
|
213 | 0 | for (OnlinePatch patch : onlinePatches) { |
214 | 0 | writer.add("patch"); |
215 | 0 | writer.addAttribute("class", patch.getClassName()); |
216 | 0 | writer.switchToParent(); |
217 | |
} |
218 | |
|
219 | 0 | writer.switchToParent(); |
220 | 0 | } |
221 | |
|
222 | |
|
223 | |
|
224 | |
|
225 | |
|
226 | |
|
227 | |
private void saveAppliedPatches(XMLWriter writer) { |
228 | 0 | writer.add("applied"); |
229 | |
|
230 | 0 | for (AppliedPatch patch : appliedPatches) { |
231 | 0 | writer.add("patch"); |
232 | |
|
233 | 0 | writer.addOnly("date", Integer.toString(patch.getDate().intValue())); |
234 | 0 | writer.addOnly("name", patch.getName()); |
235 | |
|
236 | 0 | writer.switchToParent(); |
237 | |
} |
238 | |
|
239 | 0 | writer.switchToParent(); |
240 | 0 | } |
241 | |
|
242 | |
|
243 | |
|
244 | |
|
245 | |
|
246 | |
|
247 | |
private void saveUpdated(XMLWriter writer) { |
248 | 0 | if (updated) { |
249 | 0 | writer.addOnly("updated", "1"); |
250 | |
} else { |
251 | 0 | writer.addOnly("updated", "0"); |
252 | |
} |
253 | 0 | } |
254 | |
|
255 | |
|
256 | |
|
257 | |
|
258 | |
|
259 | |
|
260 | |
private void addAppliedPatch(AppliedPatch patch) { |
261 | 0 | appliedPatches.add(patch); |
262 | 0 | xmlUpToDate = false; |
263 | 0 | } |
264 | |
|
265 | |
@Override |
266 | |
public void registerPatch(Patch p) { |
267 | 0 | patches.add(p); |
268 | 0 | } |
269 | |
|
270 | |
@Override |
271 | |
public boolean applyPatchesIfNeeded() { |
272 | 0 | boolean restart = false; |
273 | |
|
274 | 0 | if (updated) { |
275 | 0 | if (applyAllNeededPatches()) { |
276 | 0 | restart = true; |
277 | |
} else { |
278 | 0 | setUpdated(false); |
279 | 0 | restart = false; |
280 | |
} |
281 | |
} |
282 | |
|
283 | 0 | return restart; |
284 | |
} |
285 | |
|
286 | |
|
287 | |
|
288 | |
|
289 | |
|
290 | |
|
291 | |
private boolean applyAllNeededPatches() { |
292 | 0 | boolean restart = false; |
293 | |
|
294 | 0 | for (Patch patch : patches) { |
295 | 0 | if (!isApplied(patch.getName()) && patch.mustBeAppliedFor(Managers.getCore().getApplication().getVersion())) { |
296 | 0 | int code = patch.apply(); |
297 | |
|
298 | 0 | if (code < 0) { |
299 | 0 | registerAppliedPatch(patch); |
300 | |
} |
301 | |
|
302 | 0 | if (code == RESTART_CODE) { |
303 | 0 | restart = true; |
304 | 0 | break; |
305 | |
} |
306 | 0 | } |
307 | |
} |
308 | |
|
309 | 0 | return restart; |
310 | |
} |
311 | |
|
312 | |
|
313 | |
|
314 | |
|
315 | |
|
316 | |
|
317 | |
private void registerAppliedPatch(Patch patch) { |
318 | 0 | AppliedPatch applied = new AppliedPatch(); |
319 | 0 | applied.setDate(IntDate.today()); |
320 | 0 | applied.setName(patch.getName()); |
321 | |
|
322 | 0 | addAppliedPatch(applied); |
323 | 0 | } |
324 | |
|
325 | |
@Override |
326 | |
public void registerOnlinePatch(OnlinePatch patch) { |
327 | 0 | onlinePatches.add(patch); |
328 | 0 | } |
329 | |
} |