package speiger.src.coreengine.assets.impl; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.concurrent.atomic.AtomicInteger; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; import speiger.src.coreengine.assets.AssetLocation; import speiger.src.coreengine.assets.IAsset; import speiger.src.coreengine.assets.IAssetPackage; import speiger.src.coreengine.utils.collections.iterators.IterableWrapper; public class ZipAssetPackage implements IAssetPackage { public static final int ASSET_OFFSET = "assets/".length(); File file; ZipFile cache = null; AtomicInteger usedReferences = new AtomicInteger(); public ZipAssetPackage(File file) { this.file = file; } protected ZipFile getReference() throws IOException { usedReferences.getAndIncrement(); if(cache == null) cache = new ZipFile(file); return cache; } protected void onReferenceClosed() { int left = usedReferences.decrementAndGet(); if(left == 0 && cache != null) { try { cache.close(); } catch(Exception e) {e.printStackTrace();} cache = null; } else if(left < 0) { usedReferences.set(0); } } @Override public List getDomains() { try { List result = new ArrayList(); ZipFile zip = new ZipFile(file); for(ZipEntry entry : IterableWrapper.wrap(zip.entries())) { String name = entry.getName(); if(isPathValid(name)) { result.add(name.substring(ASSET_OFFSET, name.length() - 1)); } } zip.close(); return result; } catch(IOException e) { e.printStackTrace(); return Collections.emptyList(); } } private boolean isPathValid(String input) { if(input.startsWith("assets/")) { int index = input.indexOf("/", ASSET_OFFSET); if(index != -1 && input.length() - index <= 1) { return true; } } return false; } @Override public IAsset getAsset(AssetLocation location) { try { ZipFile zip = getReference(); ZipEntry entry = zip.getEntry(location.getActualLocation()); if(entry != null) { return new ZipAsset(zip, entry, location, this::onReferenceClosed); } } catch(Exception e) { e.printStackTrace(); } onReferenceClosed(); return null; } }