SimpleJavaEngine/src/main/java/speiger/src/coreengine/assets/impl/ZipAssetPackage.java

112 lines
2.3 KiB
Java

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<String> getDomains()
{
try
{
List<String> result = new ArrayList<String>();
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;
}
}