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, 16 hours ago

AEI 2.31: Fixes for reading offline package cache

File size: 10.4 KB
RevLine 
[648]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
[699]14import net.oni2.aeinstaller.backend.CaseInsensitiveFile;
[648]15import net.oni2.aeinstaller.backend.Paths;
[804]16import net.oni2.aeinstaller.backend.oni.management.tools.ToolInstallationList;
[749]17import net.oni2.moddepot.DepotConfig;
18import net.oni2.moddepot.ECompatiblePlatform;
19import net.oni2.moddepot.model.NodeMod;
[720]20import net.oni2.platformtools.PlatformInformation;
21import net.oni2.platformtools.PlatformInformation.Platform;
22import net.oni2.platformtools.applicationinvoker.EExeType;
[648]23
[720]24import org.apache.commons.io.FileUtils;
25
[648]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 = "";
[857]39 private transient EBSLInstallType bslInstallType = EBSLInstallType.NORMAL;
[648]40 private String description = "";
[857]41 private transient double aeVersion = 0;
[648]42 private int zipSize = 0;
43
[857]44 private URI nodeUrl = null;
45 private String fileUrl = null;
[648]46
[857]47 private long createdMillis = -1;
48 private long updatedMillis = -1;
[648]49
[857]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";
[648]54
[857]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
[648]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();
[749]72 for (String nType : nm.getTypes()) {
73 Type t = PackageManager.getInstance().getTypeByName(nType);
[648]74 types.add(t);
75 if (!tool && !isCorePackage() && isValidOnPlatform())
76 t.addEntry(this);
77 }
[857]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
[648]91 version = nm.getVersion();
92 submitter = nm.getName();
93 creator = nm.getCreator();
[670]94 if (nm.getBody() != null) {
[648]95 description = nm.getBody().getSafe_value();
[670]96 if (!description.toLowerCase().startsWith("<p>"))
97 description = "<p>" + description + "</p>";
98 }
[648]99
100 if (isLocalAvailable())
101 updateLocalData();
102 }
[1202]103
104 /**
105 * XML deserialization constructor
106 */
107 public Package () {}
[648]108
[657]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
[648]122 /**
123 * Update information for local package existence
124 */
125 public void updateLocalData() {
[749]126 File config = CaseInsensitiveFile.getCaseInsensitiveFile(
127 getLocalPath(), "Mod_Info.cfg");
[648]128 File aeicfg = new File(getLocalPath(), "aei.cfg");
[1020]129// File plain = CaseInsensitiveFile.getCaseInsensitiveFile(getLocalPath(),
130// "plain");
[648]131 if (config.exists()) {
132 Mod_Info mi = new Mod_Info(config, packageNumber);
133
134 aeVersion = mi.getAeVersion();
135 bslInstallType = mi.getBslInstallType();
[857]136 if (isLocalOnly()) {
[648]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();
[672]148 exeType = mi.getExeType();
[648]149 workingDir = mi.getWorkingDir();
150 iconFile = mi.getIconFile();
151 } else {
[657]152 clearLocalOnlyInfo();
[857]153// System.err.println("No config found for mod folder: "
154// + getLocalPath().getPath());
[648]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 }
[1020]180 if (isLocalOnly()) {
181 tool = packageNumber < 10000;
182 }
[648]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() {
[857]234 if (!isLocalOnly())
235 return updatedMillis > localTimestamp;
[648]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 /**
[857]248 * @return If this mod is only locally available (not on Depot)
249 */
250 public boolean isLocalOnly() {
251 return nodeUrl == null;
252 }
253
254 /**
[648]255 * @return Is mod installed?
256 */
257 public boolean isInstalled() {
258 if (tool)
[857]259 return ToolInstallationList.getInstance()
260 .isInstalled(packageNumber);
[648]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 /**
[857]350 * @return the createdMillis
[648]351 */
[857]352 public long getCreatedMillis() {
353 return createdMillis;
[648]354 }
355
356 /**
[857]357 * @return the updatedMillis
[648]358 */
[857]359 public long getUpdatedMillis() {
360 return updatedMillis;
[648]361 }
362
363 /**
[857]364 * @return the fileUrl
[657]365 */
[857]366 public String getFileUrl() {
367 return fileUrl;
[657]368 }
369
370 /**
[857]371 * @return Is a package that is always installed?
372 */
373 public boolean isCorePackage() {
374 return packageNumber < DepotConfig.corePackageNumberLimit;
375 }
376
377 /**
[648]378 * @return Depot page URI
379 */
380 public URI getUrl() {
[857]381 return nodeUrl;
[648]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 /**
[672]418 * @return Executable type of this tool
419 */
420 public EExeType getExeType() {
421 return exeType;
422 }
423
424 /**
[648]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:
[720]454 return (PlatformInformation.getPlatform() == Platform.MACOS);
[648]455 case WIN:
[720]456 return (PlatformInformation.getPlatform() == Platform.WIN)
457 || (PlatformInformation.getPlatform() == Platform.LINUX);
[648]458 }
459 return false;
460 }
461
[657]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
[648]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.