Commits

sk89q authored 0d2adc57075
Add more detail error messages when parsing regions file.
No tags

src/main/java/com/sk89q/worldguard/protection/databases/YAMLDatabase.java

Modified
12 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 14 * GNU General Public License for more details.
15 15 *
16 16 * You should have received a copy of the GNU General Public License
17 17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 18 */
19 19
20 20 package com.sk89q.worldguard.protection.databases;
21 21
22 -import java.io.File;
23 -import java.io.IOException;
24 -import java.io.FileNotFoundException;
25 -import java.util.ArrayList;
26 -import java.util.HashMap;
27 -import java.util.LinkedHashMap;
28 -import java.util.List;
29 -import java.util.Map;
30 -import java.util.Set;
31 -import java.util.logging.Logger;
32 -
33 22 import com.sk89q.util.yaml.YAMLFormat;
34 23 import com.sk89q.util.yaml.YAMLNode;
35 24 import com.sk89q.util.yaml.YAMLProcessor;
36 25 import com.sk89q.worldedit.BlockVector;
37 26 import com.sk89q.worldedit.BlockVector2D;
38 27 import com.sk89q.worldedit.Vector;
39 28 import com.sk89q.worldguard.domains.DefaultDomain;
40 29 import com.sk89q.worldguard.protection.flags.DefaultFlag;
41 30 import com.sk89q.worldguard.protection.flags.Flag;
42 31 import com.sk89q.worldguard.protection.regions.GlobalProtectedRegion;
43 32 import com.sk89q.worldguard.protection.regions.ProtectedCuboidRegion;
44 33 import com.sk89q.worldguard.protection.regions.ProtectedPolygonalRegion;
45 34 import com.sk89q.worldguard.protection.regions.ProtectedRegion;
46 35 import com.sk89q.worldguard.protection.regions.ProtectedRegion.CircularInheritanceException;
36 +import org.yaml.snakeyaml.DumperOptions;
37 +import org.yaml.snakeyaml.DumperOptions.FlowStyle;
38 +import org.yaml.snakeyaml.Yaml;
39 +import org.yaml.snakeyaml.constructor.SafeConstructor;
40 +import org.yaml.snakeyaml.representer.Representer;
41 +
42 +import java.io.File;
43 +import java.io.FileNotFoundException;
44 +import java.io.IOException;
45 +import java.util.ArrayList;
46 +import java.util.HashMap;
47 +import java.util.LinkedHashMap;
48 +import java.util.List;
49 +import java.util.Map;
50 +import java.util.Set;
51 +import java.util.logging.Level;
52 +import java.util.logging.Logger;
47 53
48 54 public class YAMLDatabase extends AbstractProtectionDatabase {
49 -
55 +
56 + /**
57 + * Used to dump YAML when an error occurs
58 + */
59 + private static Yaml yaml;
60 +
50 61 private YAMLProcessor config;
51 62 private Map<String, ProtectedRegion> regions;
52 63 private final Logger logger;
53 64
54 65 public YAMLDatabase(File file, Logger logger) throws ProtectionDatabaseException, FileNotFoundException {
55 66 this.logger = logger;
56 67 if (!file.exists()) { // shouldn't be necessary, but check anyways
57 68 try {
58 69 file.createNewFile();
59 70 } catch (IOException e) {
71 82 }
72 83
73 84 Map<String, YAMLNode> regionData = config.getNodes("regions");
74 85
75 86 // No regions are even configured
76 87 if (regionData == null) {
77 88 this.regions = new HashMap<String, ProtectedRegion>();
78 89 return;
79 90 }
80 91
81 - Map<String,ProtectedRegion> regions =
82 - new HashMap<String,ProtectedRegion>();
83 - Map<ProtectedRegion,String> parentSets =
84 - new LinkedHashMap<ProtectedRegion, String>();
92 + Map<String,ProtectedRegion> regions = new HashMap<String,ProtectedRegion>();
93 + Map<ProtectedRegion,String> parentSets = new LinkedHashMap<ProtectedRegion, String>();
85 94
86 95 for (Map.Entry<String, YAMLNode> entry : regionData.entrySet()) {
87 96 String id = entry.getKey().toLowerCase().replace(".", "");
88 97 YAMLNode node = entry.getValue();
89 -
98 +
90 99 String type = node.getString("type");
91 100 ProtectedRegion region;
92 101
93 102 try {
94 103 if (type == null) {
95 - logger.warning("Undefined region type for region '" + id + '"');
104 + logger.warning("Undefined region type for region '" + id + "'!\n" +
105 + "Here is what the region data looks like:\n\n" + dumpAsYaml(entry.getValue().getMap()) + "\n");
96 106 continue;
97 107 } else if (type.equals("cuboid")) {
98 108 Vector pt1 = checkNonNull(node.getVector("min"));
99 109 Vector pt2 = checkNonNull(node.getVector("max"));
100 110 BlockVector min = Vector.getMinimum(pt1, pt2).toBlockVector();
101 111 BlockVector max = Vector.getMaximum(pt1, pt2).toBlockVector();
102 112 region = new ProtectedCuboidRegion(id, min, max);
103 113 } else if (type.equals("poly2d")) {
104 114 Integer minY = checkNonNull(node.getInt("min-y"));
105 115 Integer maxY = checkNonNull(node.getInt("max-y"));
106 116 List<BlockVector2D> points = node.getBlockVector2dList("points", null);
107 117 region = new ProtectedPolygonalRegion(id, points, minY, maxY);
108 118 } else if (type.equals("global")) {
109 119 region = new GlobalProtectedRegion(id);
110 120 } else {
111 - logger.warning("Unknown region type for region '" + id + '"');
121 + logger.warning("Unknown region type for region '" + id + "'!\n" +
122 + "Here is what the region data looks like:\n\n" + dumpAsYaml(entry.getValue().getMap()) + "\n");
112 123 continue;
113 124 }
114 125
115 126 Integer priority = checkNonNull(node.getInt("priority"));
116 127 region.setPriority(priority);
117 128 setFlags(region, node.getNode("flags"));
118 129 region.setOwners(parseDomain(node.getNode("owners")));
119 130 region.setMembers(parseDomain(node.getNode("members")));
120 131 regions.put(id, region);
121 132
122 133 String parentId = node.getString("parent");
123 134 if (parentId != null) {
124 135 parentSets.put(region, parentId);
125 136 }
126 137 } catch (NullPointerException e) {
127 - logger.warning("Missing data for region '" + id + '"');
138 + logger.log(Level.WARNING,
139 + "Unexpected NullPointerException encountered during parsing for the region '" + id + "'!\n" +
140 + "Here is what the region data looks like:\n\n" + dumpAsYaml(entry.getValue().getMap()) +
141 + "\n\nNote: This region will disappear as a result!", e);
128 142 }
129 143 }
130 144
131 145 // Relink parents
132 146 for (Map.Entry<ProtectedRegion, String> entry : parentSets.entrySet()) {
133 147 ProtectedRegion parent = regions.get(entry.getValue());
134 148 if (parent != null) {
135 149 try {
136 150 entry.getKey().setParent(parent);
137 151 } catch (CircularInheritanceException e) {
138 - logger.warning("Circular inheritance detect with '"
139 - + entry.getValue() + "' detected as a parent");
152 + logger.warning("Circular inheritance detect with '" + entry.getValue() + "' detected as a parent");
140 153 }
141 154 } else {
142 155 logger.warning("Unknown region parent: " + entry.getValue());
143 156 }
144 157 }
145 158
146 159 this.regions = regions;
147 160 }
148 161
149 162 private <V> V checkNonNull(V val) throws NullPointerException {
304 317 domainData.put(key, list);
305 318 }
306 319
307 320 public Map<String, ProtectedRegion> getRegions() {
308 321 return regions;
309 322 }
310 323
311 324 public void setRegions(Map<String, ProtectedRegion> regions) {
312 325 this.regions = regions;
313 326 }
327 +
328 + /**
329 + * Dump the given object as YAML for debugging purposes.
330 + *
331 + * @param object the object
332 + * @return the YAML string or an error string if dumping fals
333 + */
334 + private static String dumpAsYaml(Object object) {
335 + if (yaml == null) {
336 + DumperOptions options = new DumperOptions();
337 + options.setIndent(4);
338 + options.setDefaultFlowStyle(FlowStyle.AUTO);
339 +
340 + yaml = new Yaml(new SafeConstructor(), new Representer(), options);
341 + }
342 +
343 + try {
344 + return yaml.dump(object).replaceAll("(?m)^", "\t");
345 + } catch (Throwable t) {
346 + return "<error while dumping object>";
347 + }
348 + }
314 349
315 350 }

Everything looks good. We'll let you know here if there's anything you should know about.

Add shortcut