001package fr.aumgn.bukkitutils.gson; 002 003import java.io.BufferedWriter; 004import java.io.File; 005import java.io.FileInputStream; 006import java.io.FileOutputStream; 007import java.io.IOException; 008import java.io.InputStreamReader; 009import java.io.OutputStreamWriter; 010import java.lang.reflect.Type; 011 012import org.bukkit.plugin.Plugin; 013 014import com.google.common.base.Charsets; 015import com.google.gson.Gson; 016import com.google.gson.reflect.TypeToken; 017import com.google.gson.stream.JsonReader; 018 019/** 020 * Class which handle loading of .json resources 021 * for a given plugin using {@link Gson}. 022 */ 023public class GsonLoader { 024 025 private final Gson gson; 026 private final Plugin plugin; 027 028 public GsonLoader(Gson gson, Plugin plugin) { 029 this.gson = gson; 030 this.plugin = plugin; 031 } 032 033 private File getFile(String filename) 034 throws GsonLoadException { 035 File file = new File(plugin.getDataFolder(), filename); 036 File folder = file.getParentFile(); 037 if (!file.exists() && !folder.exists() && !folder.mkdirs()) { 038 throw new GsonLoadException("Unable to create directory : " 039 + plugin.getDataFolder().getPath()); 040 } 041 042 return file; 043 } 044 045 /** 046 * Loads if exists or creates the given resource. 047 */ 048 public <T> T loadOrCreate(String filename, Class<T> klass) 049 throws GsonLoadException { 050 return loadOrCreate(filename, klass, klass); 051 } 052 053 /** 054 * Loads if exists or creates the given resource. 055 */ 056 @SuppressWarnings("unchecked") 057 public <T> T loadOrCreate(String filename, TypeToken<T> typeToken) 058 throws GsonLoadException { 059 return (T) loadOrCreate(filename, typeToken.getType(), 060 typeToken.getRawType()); 061 } 062 063 private <T> T loadOrCreate(String filename, Type type, Class<T> klass) 064 throws GsonLoadException { 065 try { 066 File file = getFile(filename); 067 T instance; 068 if (file.createNewFile()) { 069 instance = klass.newInstance(); 070 } else { 071 instance = unsafeLoad(file, type); 072 } 073 074 // This ensures user file is updated with newer fields. 075 write(file, instance); 076 077 return instance; 078 } catch (IOException exc) { 079 throw new GsonLoadException(exc); 080 } catch (InstantiationException exc) { 081 throw new GsonLoadException(exc); 082 } catch (IllegalAccessException exc) { 083 throw new GsonLoadException(exc); 084 } 085 } 086 087 /** 088 * Loads the given resource. 089 */ 090 public <T> T load(File file, Type klass) throws GsonLoadException { 091 try { 092 return unsafeLoad(file, klass); 093 } catch (IOException exc) { 094 throw new GsonLoadException(exc); 095 } 096 } 097 098 /** 099 * Loads the given resource. 100 */ 101 public <T> T load(File file, TypeToken<T> typeToken) 102 throws GsonLoadException { 103 try { 104 return unsafeLoad(file, typeToken.getRawType()); 105 } catch (IOException exc) { 106 throw new GsonLoadException(exc); 107 } 108 } 109 110 private <T> T unsafeLoad(File file, Type klass) throws IOException { 111 InputStreamReader isr = new InputStreamReader( 112 new FileInputStream(file), Charsets.UTF_8); 113 JsonReader reader = new JsonReader(isr); 114 115 try { 116 return gson.fromJson(reader, klass); 117 } finally { 118 reader.close(); 119 } 120 } 121 122 /** 123 * Writes the given resource. 124 */ 125 public void write(String filename, Object instance) 126 throws GsonLoadException { 127 try { 128 write(getFile(filename), instance); 129 } catch (IOException exc) { 130 throw new GsonLoadException(exc); 131 } 132 } 133 134 private void write(File file, Object instance) throws IOException { 135 OutputStreamWriter osw = new OutputStreamWriter( 136 new FileOutputStream(file), Charsets.UTF_8); 137 BufferedWriter writer = new BufferedWriter(osw); 138 139 try { 140 writer.write(gson.toJson(instance)); 141 } finally { 142 writer.close(); 143 } 144 } 145}