package net.minecraftforkage.instsetup;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.Writer;
import java.lang.reflect.Type;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
public abstract class AbstractZipFile {
/**
* Returns a collection of the paths of files and directories in this zip file.
* Directory paths end in a slash ('/'). File paths do not.
*/
public abstract Iterable<String> getFileNames() throws IOException;
/**
* Checks whether the zip file contains an entry with the given path.
* To test for a directory, the path must end in a slash ('/').
*/
public abstract boolean doesPathExist(String path) throws IOException;
/**
* Returns an input stream reading from the ZIP entry with the specified path.
* Throws an IOException if the path does not exist or is a directory.
*/
public abstract InputStream read(String path) throws IOException;
/**
* Returns an output stream writing to the ZIP entry with the specified path.
* If an entry is simultaneously read and written to, the result is unspecified.
* Throws an IOException if the path is a directory path.
* Parent directories of the given path are automatically created
* (at an unspecified time before or during the closure of the returned stream).
*/
public abstract OutputStream write(String path) throws IOException;
/**
* Deletes the entry with the given path.
* To delete a directory, the path must end with a slash ('/').
* Throws IOException if the path does not exist.
*/
public abstract void delete(String path) throws IOException;
/**
* Creates a directory entry if it does not already exist.
* The path must end with a slash ('/').
* Parent directories, if any, are automatically created if they
* do not already exist.
*/
public abstract void createDirectory(String path) throws IOException;
/* ===== UTF-8 UTILITY METHODS ===== */
/**
* Similar to {@link #read(String)}, but returns a Reader.
* Characters are decoded as UTF-8.
*/
public Reader readUTF8(String path) throws IOException {
return new InputStreamReader(read(path), StandardCharsets.UTF_8);
}
/**
* Similar to {@link #write(String)}, but returns a Writer.
* Characters are encoded as UTF-8.
*/
public Writer writeUTF8(String path) throws IOException {
return new OutputStreamWriter(write(path), StandardCharsets.UTF_8);
}
/* ===== JSON UTILITY METHODS ===== */
private static final Gson DEFAULT_GSON = new GsonBuilder().serializeNulls().setPrettyPrinting().create();
/**
* Reads a JSON file into an object tree, using {@link Gson}
* with the default settings.
*/
public <T> T readGSON(String path, Class<T> classOfT) throws IOException {
return readGSON(path, classOfT, DEFAULT_GSON);
}
/**
* Reads a JSON file into an object tree, using {@link Gson}
* with the default settings.
*/
public <T> T readGSON(String path, Type typeOfT) throws IOException {
return readGSON(path, typeOfT, DEFAULT_GSON);
}
/**
* Reads a JSON file into an object tree, using a customized {@link Gson} instance.
*/
public <T> T readGSON(String path, Class<T> classOfT, Gson gsonInstance) throws IOException {
try (Reader in = readUTF8(path)) {
return gsonInstance.fromJson(in, classOfT);
}
}
/**
* Reads a JSON file into an object tree, using a customized {@link Gson} instance.
*/
public <T> T readGSON(String path, Type typeOfT, Gson gsonInstance) throws IOException {
try (Reader in = readUTF8(path)) {
return gsonInstance.fromJson(in, typeOfT);
}
}
/**
* Writes an object tree into a JSON file, using {@link Gson}
* with the default settings.
*/
public void writeGSON(String path, Object object) throws IOException {
writeGSON(path, object, DEFAULT_GSON);
}
/**
* Writes an object tree into a JSON file, using a customized {@link Gson} instance.
*/
public void writeGSON(String path, Object object, Gson gsonInstance) throws IOException {
try (Writer out = writeUTF8(path)) {
gsonInstance.toJson(object, out);
}
}
/**
* If the file does not exist, write the given list to it as a JSON array.
* If the file does exist, it must contain a JSON array. The elements in the given list
* will be appended to the array.
*/
public synchronized void appendGSONArray(String path, List<?> list) throws IOException {
List<Object> objects = new ArrayList<Object>();
if(doesPathExist(path))
for(JsonElement existingElement : readGSON(path, JsonArray.class))
objects.add(existingElement);
objects.addAll(list);
writeGSON(path, objects);
}
/* ===== PROPERTIES FILE UTILITY METHODS ===== */
@SuppressWarnings({ "unchecked", "rawtypes" })
public Map<String, String> readProperties(String path) throws IOException {
Properties p = new Properties();
try (InputStream in = read(path)) {
p.load(in);
}
return (Map<String, String>)(Map)p;
}
AbstractZipFile() {}
}