001 package net.minecraftforge.common; 002 003 import java.io.BufferedWriter; 004 import java.io.IOException; 005 import java.util.ArrayList; 006 import java.util.Collection; 007 import java.util.Map; 008 import java.util.Set; 009 import java.util.TreeMap; 010 011 import com.google.common.base.Splitter; 012 013 import static net.minecraftforge.common.Configuration.*; 014 015 public class ConfigCategory implements Map<String, Property> 016 { 017 private String name; 018 private String comment; 019 private ArrayList<ConfigCategory> children = new ArrayList<ConfigCategory>(); 020 private Map<String, Property> properties = new TreeMap<String, Property>(); 021 public final ConfigCategory parent; 022 023 public ConfigCategory(String name) 024 { 025 this(name, null); 026 } 027 028 public ConfigCategory(String name, ConfigCategory parent) 029 { 030 this.name = name; 031 this.parent = parent; 032 if (parent != null) 033 { 034 parent.children.add(this); 035 } 036 } 037 038 public boolean equals(Object obj) 039 { 040 if (obj instanceof ConfigCategory) 041 { 042 ConfigCategory cat = (ConfigCategory)obj; 043 return name.equals(cat.name) && children.equals(cat.children); 044 } 045 046 return false; 047 } 048 049 public String getQualifiedName() 050 { 051 return getQualifiedName(name, parent); 052 } 053 054 public static String getQualifiedName(String name, ConfigCategory parent) 055 { 056 return (parent == null ? name : parent.getQualifiedName() + Configuration.CATEGORY_SPLITTER + name); 057 } 058 059 public ConfigCategory getFirstParent() 060 { 061 return (parent == null ? this : parent.getFirstParent()); 062 } 063 064 public boolean isChild() 065 { 066 return parent != null; 067 } 068 069 public Map<String, Property> getValues() 070 { 071 return properties; 072 } 073 074 public void setComment(String comment) 075 { 076 this.comment = comment; 077 } 078 079 public boolean containsKey(String key) 080 { 081 return properties.containsKey(key); 082 } 083 084 public Property get(String key) 085 { 086 return properties.get(key); 087 } 088 089 public void set(String key, Property value) 090 { 091 properties.put(key, value); 092 } 093 094 public void write(BufferedWriter out, int indent) throws IOException 095 { 096 String pad = getIndent(indent); 097 098 out.write(pad + "####################" + NEW_LINE); 099 out.write(pad + "# " + name + NEW_LINE); 100 101 if (comment != null) 102 { 103 out.write(pad + "#===================" + NEW_LINE); 104 Splitter splitter = Splitter.onPattern("\r?\n"); 105 106 for (String line : splitter.split(comment)) 107 { 108 out.write(pad + "# " + line + NEW_LINE); 109 } 110 } 111 112 out.write(pad + "####################" + NEW_LINE + NEW_LINE); 113 114 if (!allowedProperties.matchesAllOf(name)) 115 { 116 name = '"' + name + '"'; 117 } 118 119 out.write(pad + name + " {" + NEW_LINE); 120 121 pad = getIndent(indent + 1); 122 123 Property[] props = properties.values().toArray(new Property[properties.size()]); 124 125 for (int x = 0; x < props.length; x++) 126 { 127 Property prop = props[x]; 128 129 if (prop.comment != null) 130 { 131 if (x != 0) 132 { 133 out.newLine(); 134 } 135 136 Splitter splitter = Splitter.onPattern("\r?\n"); 137 for (String commentLine : splitter.split(prop.comment)) 138 { 139 out.write(pad + "# " + commentLine + NEW_LINE); 140 } 141 } 142 143 String propName = prop.getName(); 144 145 if (!allowedProperties.matchesAllOf(propName)) 146 { 147 propName = '"' + propName + '"'; 148 } 149 150 if (prop.isList()) 151 { 152 out.write(String.format(pad + "%s:%s <" + NEW_LINE, prop.getType().getID(), propName)); 153 pad = getIndent(indent + 2); 154 155 for (String line : prop.valueList) 156 { 157 out.write(pad + line + NEW_LINE); 158 } 159 160 out.write(getIndent(indent + 1) + " >" + NEW_LINE); 161 } 162 else if (prop.getType() == null) 163 { 164 out.write(String.format(pad + "%s=%s" + NEW_LINE, propName, prop.value)); 165 } 166 else 167 { 168 out.write(String.format(pad + "%s:%s=%s" + NEW_LINE, prop.getType().getID(), propName, prop.value)); 169 } 170 } 171 172 for (ConfigCategory child : children) 173 { 174 child.write(out, indent + 1); 175 } 176 177 out.write(getIndent(indent) + "}" + NEW_LINE + NEW_LINE); 178 } 179 180 private String getIndent(int indent) 181 { 182 StringBuilder buf = new StringBuilder(""); 183 for (int x = 0; x < indent; x++) 184 { 185 buf.append(" "); 186 } 187 return buf.toString(); 188 } 189 190 191 //Map bouncer functions for compatibility with older mods, to be removed once all mods stop using it. 192 @Override public int size(){ return properties.size(); } 193 @Override public boolean isEmpty() { return properties.isEmpty(); } 194 @Override public boolean containsKey(Object key) { return properties.containsKey(key); } 195 @Override public boolean containsValue(Object value){ return properties.containsValue(value); } 196 @Override public Property get(Object key) { return properties.get(key); } 197 @Override public Property put(String key, Property value) { return properties.put(key, value); } 198 @Override public Property remove(Object key) { return properties.remove(key); } 199 @Override public void putAll(Map<? extends String, ? extends Property> m) { properties.putAll(m); } 200 @Override public void clear() { properties.clear(); } 201 @Override public Set<String> keySet() { return properties.keySet(); } 202 @Override public Collection<Property> values() { return properties.values(); } 203 @Override public Set<java.util.Map.Entry<String, Property>> entrySet() { return properties.entrySet(); } 204 205 }