Created
October 23, 2012 22:59
-
-
Save Xyene/3942326 to your computer and use it in GitHub Desktop.
Even easier config files, with comments!
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* A class for saving/loading lazy configuration classes/files. | |
* Based on codename_B's non static config 'offering' :) | |
* Inspired by md_5's easy config | |
* | |
* Node commenting by Xiaomao, fixed by Icyene | |
* Integer limiting by Icynene | |
*/ | |
public class ReflectConfiguration { | |
private final Plugin plugin; | |
private final String name; | |
private final String prefix; | |
private final String header; | |
/** | |
* Creates a ReflectConfiguration file based on given name | |
* | |
* @param plugin The plugin | |
* @param name The name of the file to write to | |
*/ | |
public ReflectConfiguration(Plugin plugin, String name) { | |
this.plugin = plugin; | |
this.name = name; | |
this.prefix = plugin.getName(); | |
this.header = prefix + " configuration file: '" + name + "'.\nGenerated for " + prefix + " version " + plugin.getDescription().getVersion() + "."; | |
} | |
/** | |
* Loads the object. | |
*/ | |
public void load() { | |
try { | |
synchronized (this) { | |
plugin.getLogger().log(Level.INFO, "Loading configuration file: " + name); | |
onLoad(plugin); | |
} | |
} catch (Exception e) { | |
ErrorLogger.generateErrorLog(e); | |
} | |
} | |
private void onLoad(Plugin plugin) throws Exception { | |
synchronized (this) { | |
File worldFolder = new File(plugin.getDataFolder() + File.separator + "worlds"); | |
if (!worldFolder.exists()) { | |
if (!worldFolder.mkdir()) { | |
ErrorLogger.generateErrorLog(new RuntimeException("Failed to create configuration directory!")); | |
} | |
} | |
File worldFile = new File(worldFolder.getAbsoluteFile(), File.separator + name + ".yml"); | |
YamlConfiguration worlds = YamlConfiguration.loadConfiguration(worldFile); | |
((FileConfiguration) worlds).options().header(header); | |
for (Field field : getClass().getDeclaredFields()) { | |
if (doSkip(field)) | |
continue; | |
String path = prefix + "." + field.getName().replaceAll("__", " ").replaceAll("_", "."); | |
if (worlds.isSet(path)) { | |
LimitInteger lim; | |
if ((lim = field.getAnnotation(LimitInteger.class)) != null) { | |
int limit = lim.limit(); | |
boolean doCorrect = false; | |
try { | |
if (worlds.getInt(path) > limit) { | |
doCorrect = true; | |
} | |
} catch (Exception e) { | |
doCorrect = true; | |
} | |
if (doCorrect) { | |
plugin.getLogger().log(Level.SEVERE, lim.warning().replace("%node", "'" + path.substring(6) + "'").replace("%limit", limit + "")); | |
if (lim.correct()) | |
worlds.set(path, lim.limit()); | |
} | |
} | |
field.set(this, worlds.get(path)); | |
} else | |
worlds.set(path, field.get(this)); | |
} | |
worlds.save(worldFile); | |
Files.write(StringUtils.join(addComments(Files.toString(worldFile, Charset.defaultCharset()).split("\n")), "\n"), worldFile, Charset.defaultCharset()); | |
} | |
} | |
Collection<String> addComments(String[] lines) { | |
int prevlevel = 0; | |
final int indent = 2; | |
LinkedList<String> outlines = new LinkedList<String>(); | |
Stack<String> hierarchy = new Stack<String>(); | |
for (String line : lines) { | |
String content = StringUtils.stripStart(line, " "); | |
int spaces = line.length() - content.length(), | |
level = spaces / indent + 1; | |
String[] tokens = content.split(":", 2); | |
String name = tokens[0]; | |
if (level <= prevlevel) { | |
for (int i = 0; i <= prevlevel - level; ++i) { | |
hierarchy.pop(); | |
} | |
} | |
hierarchy.push(name); | |
prevlevel = level; | |
String id = StringUtils.join(hierarchy, "_").replaceAll(" ", "__"); | |
Comment comment = null; | |
try { | |
comment = getClass().getDeclaredField(id.replaceAll(prefix + ".", "")).getAnnotation(Comment.class); | |
} catch (NoSuchFieldException ignored) { | |
} | |
if (comment == null) { | |
outlines.add(line); | |
continue; | |
} | |
String indentPrefix = StringUtils.repeat(" ", spaces); | |
if (comment.location() == Comment.CommentLocation.TOP) | |
for (String data : comment._()) | |
outlines.add(indentPrefix + "# " + data); | |
if (comment.location() == Comment.CommentLocation.INLINE) { | |
String[] comments = comment._(); | |
outlines.add(line + " # " + comments[0]); | |
for (int i = 1; i < comments.length; ++i) | |
outlines.add(StringUtils.repeat(" ", line.length() + 1) + "# " + comments[i]); | |
} else | |
outlines.add(line); | |
if (comment.location() == Comment.CommentLocation.BOTTOM) | |
for (String data : comment._()) | |
outlines.add(indentPrefix + "# " + data); | |
} | |
return outlines; | |
} | |
public boolean doSkip(Field field) { | |
int mod = field.getModifiers(); | |
return Modifier.isFinal(mod) || Modifier.isTransient(mod) || Modifier.isVolatile(mod); | |
} | |
@Target(ElementType.FIELD) | |
@Retention(RetentionPolicy.RUNTIME) | |
public @interface LimitInteger { | |
int limit() default 100; | |
String warning() default "%node cannot be over %limit! Defaulted to value of %limit."; | |
boolean correct() default true; | |
} | |
@Target(ElementType.FIELD) | |
@Retention(RetentionPolicy.RUNTIME) | |
public @interface Comment { | |
String[] _(); | |
CommentLocation location() default CommentLocation.INLINE; | |
public enum CommentLocation { | |
INLINE(1), | |
TOP(2), | |
BOTTOM(3); | |
CommentLocation(int location) { | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment