source: java/installer2/src/net/oni2/aeinstaller/backend/packages/Package.java@ 1202

Last change on this file since 1202 was 1202, checked in by alloc, 17 hours ago

AEI 2.31: Fixes for reading offline package cache

File size: 10.4 KB
Line 
1package net.oni2.aeinstaller.backend.packages;
2
3import java.io.BufferedReader;
4import java.io.File;
5import java.io.FileInputStream;
6import java.io.FileNotFoundException;
7import java.io.FilenameFilter;
8import java.io.IOException;
9import java.io.InputStreamReader;
10import java.net.URI;
11import java.net.URISyntaxException;
12import java.util.HashSet;
13
14import net.oni2.aeinstaller.backend.CaseInsensitiveFile;
15import net.oni2.aeinstaller.backend.Paths;
16import net.oni2.aeinstaller.backend.oni.management.tools.ToolInstallationList;
17import net.oni2.moddepot.DepotConfig;
18import net.oni2.moddepot.ECompatiblePlatform;
19import net.oni2.moddepot.model.NodeMod;
20import net.oni2.platformtools.PlatformInformation;
21import net.oni2.platformtools.PlatformInformation.Platform;
22import net.oni2.platformtools.applicationinvoker.EExeType;
23
24import org.apache.commons.io.FileUtils;
25
26/**
27 * @author Christian Illy
28 */
29public class Package implements Comparable<Package> {
30 private String name = "";
31 private int packageNumber = 0;
32
33 private HashSet<Type> types = new HashSet<Type>();
34 private boolean tool = false;
35 private ECompatiblePlatform platform = null;
36 private String version = "";
37 private String submitter = "";
38 private String creator = "";
39 private transient EBSLInstallType bslInstallType = EBSLInstallType.NORMAL;
40 private String description = "";
41 private transient double aeVersion = 0;
42 private int zipSize = 0;
43
44 private URI nodeUrl = null;
45 private String fileUrl = null;
46
47 private long createdMillis = -1;
48 private long updatedMillis = -1;
49
50 private transient File exeFile = null;
51 private transient EExeType exeType = EExeType.OSBINARY;
52 private transient File iconFile = null;
53 private transient String workingDir = "Base";
54
55 private transient HashSet<Integer> incompatibilities = new HashSet<Integer>();
56 private transient HashSet<Integer> dependencies = new HashSet<Integer>();
57 private transient HashSet<Integer> unlockLevel = new HashSet<Integer>();
58
59 private transient long localTimestamp = 0;
60
61 /**
62 * Create a new Package entry from a given Mod-Node
63 *
64 * @param nm
65 * Mod-Node
66 */
67 public Package(NodeMod nm) {
68 name = nm.getTitle();
69 packageNumber = nm.getPackageNumber();
70 platform = nm.getPlatform();
71 tool = nm.isTool();
72 for (String nType : nm.getTypes()) {
73 Type t = PackageManager.getInstance().getTypeByName(nType);
74 types.add(t);
75 if (!tool && !isCorePackage() && isValidOnPlatform())
76 t.addEntry(this);
77 }
78
79 createdMillis = nm.getCreated();
80 updatedMillis = nm.getUploads().firstElement().getTimestamp();
81
82 try {
83 nodeUrl = new URI(nm.getPath());
84 } catch (URISyntaxException e) {
85 e.printStackTrace();
86 }
87
88 fileUrl = nm.getUploads().firstElement().getUri_full();
89 zipSize = nm.getUploads().firstElement().getFilesize();
90
91 version = nm.getVersion();
92 submitter = nm.getName();
93 creator = nm.getCreator();
94 if (nm.getBody() != null) {
95 description = nm.getBody().getSafe_value();
96 if (!description.toLowerCase().startsWith("<p>"))
97 description = "<p>" + description + "</p>";
98 }
99
100 if (isLocalAvailable())
101 updateLocalData();
102 }
103
104 /**
105 * XML deserialization constructor
106 */
107 public Package () {}
108
109 private void clearLocalOnlyInfo() {
110 aeVersion = 0;
111 bslInstallType = EBSLInstallType.NORMAL;
112
113 dependencies = new HashSet<Integer>();
114 incompatibilities = new HashSet<Integer>();
115 unlockLevel = new HashSet<Integer>();
116
117 exeFile = null;
118 workingDir = null;
119 iconFile = null;
120 }
121
122 /**
123 * Update information for local package existence
124 */
125 public void updateLocalData() {
126 File config = CaseInsensitiveFile.getCaseInsensitiveFile(
127 getLocalPath(), "Mod_Info.cfg");
128 File aeicfg = new File(getLocalPath(), "aei.cfg");
129// File plain = CaseInsensitiveFile.getCaseInsensitiveFile(getLocalPath(),
130// "plain");
131 if (config.exists()) {
132 Mod_Info mi = new Mod_Info(config, packageNumber);
133
134 aeVersion = mi.getAeVersion();
135 bslInstallType = mi.getBslInstallType();
136 if (isLocalOnly()) {
137 name = mi.getName();
138 creator = mi.getCreator();
139 version = mi.getVersion();
140 description = mi.getDescription();
141 }
142
143 dependencies = mi.getDependencies();
144 incompatibilities = mi.getIncompatibilities();
145 unlockLevel = mi.getUnlockLevel();
146
147 exeFile = mi.getExeFile();
148 exeType = mi.getExeType();
149 workingDir = mi.getWorkingDir();
150 iconFile = mi.getIconFile();
151 } else {
152 clearLocalOnlyInfo();
153// System.err.println("No config found for mod folder: "
154// + getLocalPath().getPath());
155 }
156 if (aeicfg.exists()) {
157 try {
158 FileInputStream fstream = new FileInputStream(aeicfg);
159 InputStreamReader isr = new InputStreamReader(fstream);
160 BufferedReader br = new BufferedReader(isr);
161 String strLine;
162 while ((strLine = br.readLine()) != null) {
163 if (strLine.indexOf("->") < 1)
164 continue;
165 if (strLine.indexOf("//") >= 0)
166 strLine = strLine.substring(0, strLine.indexOf("//"));
167 String[] split = strLine.split("->", 2);
168 String sName = split[0].trim();
169 String sVal = split[1].trim();
170 if (sName.equalsIgnoreCase("Timestamp")) {
171 localTimestamp = Long.parseLong(sVal);
172 }
173 }
174 isr.close();
175 } catch (FileNotFoundException e) {
176 } catch (IOException e) {
177 e.printStackTrace();
178 }
179 }
180 if (isLocalOnly()) {
181 tool = packageNumber < 10000;
182 }
183 }
184
185 /**
186 * Create a new Mod entry from the given local mod folder
187 *
188 * @param folder
189 * Mod folder with Mod_Info.cfg
190 */
191 public Package(File folder) {
192 packageNumber = Integer.parseInt(folder.getName().substring(0, 5));
193 updateLocalData();
194
195 platform = ECompatiblePlatform.BOTH;
196 }
197
198 /**
199 * @return has separate paths for win/mac/common or not
200 */
201 public boolean hasSeparatePlatformDirs() {
202 return aeVersion >= 2;
203 }
204
205 private String getSanitizedPathName() {
206 return name.replaceAll("[^a-zA-Z0-9_.-]", "_");
207 }
208
209 /**
210 * @return Path to local mod folder
211 */
212 public File getLocalPath() {
213 final String folderStart = String.format("%05d", packageNumber);
214
215 if (Paths.getModsPath().exists()) {
216 for (File f : Paths.getModsPath().listFiles(new FilenameFilter() {
217 @Override
218 public boolean accept(File d, String fn) {
219 return fn.startsWith(folderStart);
220 }
221 })) {
222 return f;
223 }
224 }
225
226 return new File(Paths.getModsPath(), folderStart
227 + getSanitizedPathName());
228 }
229
230 /**
231 * @return Is there a newer version on the depot?
232 */
233 public boolean isNewerAvailable() {
234 if (!isLocalOnly())
235 return updatedMillis > localTimestamp;
236 else
237 return false;
238 }
239
240 /**
241 * @return Mod exists within mods folder
242 */
243 public boolean isLocalAvailable() {
244 return getLocalPath().exists();
245 }
246
247 /**
248 * @return If this mod is only locally available (not on Depot)
249 */
250 public boolean isLocalOnly() {
251 return nodeUrl == null;
252 }
253
254 /**
255 * @return Is mod installed?
256 */
257 public boolean isInstalled() {
258 if (tool)
259 return ToolInstallationList.getInstance()
260 .isInstalled(packageNumber);
261 else
262 return PackageManager.getInstance().isModInstalled(this);
263 }
264
265 /**
266 * @return Name of mod
267 */
268 public String getName() {
269 return name;
270 }
271
272 /**
273 * @return the package number
274 */
275 public int getPackageNumber() {
276 return packageNumber;
277 }
278
279 /**
280 * @return the package number as 5 digit string
281 */
282 public String getPackageNumberString() {
283 return String.format("%05d", packageNumber);
284 }
285
286 /**
287 * @return Types of mod
288 */
289 public HashSet<Type> getTypes() {
290 return types;
291 }
292
293 /**
294 * @return Is this mod actually a tool?
295 */
296 public boolean isTool() {
297 return tool;
298 }
299
300 /**
301 * @return Compatible platforms
302 */
303 public ECompatiblePlatform getPlatform() {
304 return platform;
305 }
306
307 /**
308 * @return Version of mod
309 */
310 public String getVersion() {
311 return version;
312 }
313
314 /**
315 * @return Submitter of mod
316 */
317 public String getSubmitter() {
318 return submitter;
319 }
320
321 /**
322 * @return Creator of mod
323 */
324 public String getCreator() {
325 return creator;
326 }
327
328 /**
329 * @return Installation type of BSL files
330 */
331 public EBSLInstallType getBSLInstallType() {
332 return bslInstallType;
333 }
334
335 /**
336 * @return Description of mod
337 */
338 public String getDescription() {
339 return description;
340 }
341
342 /**
343 * @return Size of Zip file on Depot
344 */
345 public int getZipSize() {
346 return zipSize;
347 }
348
349 /**
350 * @return the createdMillis
351 */
352 public long getCreatedMillis() {
353 return createdMillis;
354 }
355
356 /**
357 * @return the updatedMillis
358 */
359 public long getUpdatedMillis() {
360 return updatedMillis;
361 }
362
363 /**
364 * @return the fileUrl
365 */
366 public String getFileUrl() {
367 return fileUrl;
368 }
369
370 /**
371 * @return Is a package that is always installed?
372 */
373 public boolean isCorePackage() {
374 return packageNumber < DepotConfig.corePackageNumberLimit;
375 }
376
377 /**
378 * @return Depot page URI
379 */
380 public URI getUrl() {
381 return nodeUrl;
382 }
383
384 @Override
385 public String toString() {
386 return name;
387 }
388
389 /**
390 * @return the incompabitilities
391 */
392 public HashSet<Integer> getIncompabitilities() {
393 return incompatibilities;
394 }
395
396 /**
397 * @return the dependencies
398 */
399 public HashSet<Integer> getDependencies() {
400 return dependencies;
401 }
402
403 /**
404 * @return the levels this mod will unlock
405 */
406 public HashSet<Integer> getUnlockLevels() {
407 return unlockLevel;
408 }
409
410 /**
411 * @return Executable name of this tool
412 */
413 public File getExeFile() {
414 return exeFile;
415 }
416
417 /**
418 * @return Executable type of this tool
419 */
420 public EExeType getExeType() {
421 return exeType;
422 }
423
424 /**
425 * @return Icon file of this tool
426 */
427 public File getIconFile() {
428 return iconFile;
429 }
430
431 /**
432 * @return Working directory of this tool
433 */
434 public File getWorkingDir() {
435 if (workingDir.equalsIgnoreCase("Exe")) {
436 if (exeFile != null)
437 return exeFile.getParentFile();
438 else
439 return Paths.getEditionGDF();
440 } else if (workingDir.equalsIgnoreCase("GDF"))
441 return Paths.getEditionGDF();
442 else
443 return Paths.getEditionBasePath();
444 }
445
446 /**
447 * @return Is this mod valid on the running platform?
448 */
449 public boolean isValidOnPlatform() {
450 switch (platform) {
451 case BOTH:
452 return true;
453 case MACOS:
454 return (PlatformInformation.getPlatform() == Platform.MACOS);
455 case WIN:
456 return (PlatformInformation.getPlatform() == Platform.WIN)
457 || (PlatformInformation.getPlatform() == Platform.LINUX);
458 }
459 return false;
460 }
461
462 /**
463 * Delete the local package folder
464 */
465 public void deleteLocalPackage() {
466 if (getLocalPath().exists()) {
467 try {
468 FileUtils.deleteDirectory(getLocalPath());
469 updateLocalData();
470 } catch (IOException e) {
471 e.printStackTrace();
472 }
473 }
474 }
475
476 @Override
477 public int compareTo(Package o) {
478 return getPackageNumber() - o.getPackageNumber();
479 }
480
481}
Note: See TracBrowser for help on using the repository browser.