Skip to content

Commit 78a4273

Browse files
committed
Improve module errors, and add ModuleReporter
1 parent a06b69a commit 78a4273

File tree

13 files changed

+351
-162
lines changed

13 files changed

+351
-162
lines changed

build.gradle

+2
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ dependencies {
3737
compile 'ee.ellytr.command:EllyCommand:2.0.4'
3838
compile 'ee.ellytr.chat:EllyChat:1.2.6'
3939
compile 'org.jdom:jdom2:2.0.6'
40+
compile 'org.jdom:jdom2-contrib:2.0.5'
4041
compile 'org.ow2.asm:asm-all:5.0.4'
4142

4243
testCompile('junit:junit:4.12')
@@ -57,6 +58,7 @@ shadowJar {
5758
append('LICENSE')
5859
dependencies {
5960
include(dependency('org.jdom:jdom2:2.0.6'))
61+
include(dependency('org.jdom:jdom2-contrib:2.0.5'))
6062
relocate 'org.jdom2', 'in.twizmwaz.cardinal.libs.jdom2'
6163
include(dependency('org.ow2.asm:asm-all:5.0.4'))
6264
relocate 'org.objectweb.asm', 'in.twizmwaz.cardinal.libs.asm'

gradle/wrapper/gradle-wrapper.properties

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#Tue Apr 26 23:37:45 EDT 2016
1+
#Thu Sep 22 02:07:06 CEST 2016
22
distributionBase=GRADLE_USER_HOME
33
distributionPath=wrapper/dists
44
zipStoreBase=GRADLE_USER_HOME

src/main/java/in/twizmwaz/cardinal/module/ModuleError.java

+32
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,46 @@
2626
package in.twizmwaz.cardinal.module;
2727

2828
import in.twizmwaz.cardinal.module.repository.LoadedMap;
29+
import lombok.AllArgsConstructor;
2930
import lombok.Data;
31+
import org.jdom2.Attribute;
32+
import org.jdom2.Element;
33+
import org.jdom2.contrib.input.LineNumberElement;
3034

3135
@Data
36+
@AllArgsConstructor
3237
public final class ModuleError {
3338

3439
private final Module module;
3540
private final LoadedMap map;
3641
private final String[] message;
3742
private final boolean critical;
3843

44+
public ModuleError(Module module, LoadedMap map, boolean critical, String... message) {
45+
this(module, map, message, critical);
46+
}
47+
48+
public ModuleError(Module module, LoadedMap map, Element element, String message, boolean critical) {
49+
this(module, map, critical, getErrorLocation(element), message);
50+
}
51+
52+
public ModuleError(Module module, LoadedMap map, Attribute attr, String message, boolean critical) {
53+
this(module, map, critical, getErrorLocation(attr), message);
54+
}
55+
56+
private static String getErrorLocation(Element element) {
57+
String result = "'" + element.getName() + "' element";
58+
if (element instanceof LineNumberElement) {
59+
LineNumberElement lineElement = (LineNumberElement) element;
60+
result += lineElement.getStartLine() == lineElement.getEndLine()
61+
? " on line " + lineElement.getStartLine()
62+
: " from line " + lineElement.getStartLine() + " to " + lineElement.getEndLine();
63+
}
64+
return result;
65+
}
66+
67+
private static String getErrorLocation(Attribute attribute) {
68+
return "'" + attribute.getName() + "' attribute in " + getErrorLocation(attribute.getParent());
69+
}
70+
3971
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
package in.twizmwaz.cardinal.module;
2+
3+
import in.twizmwaz.cardinal.match.Match;
4+
import in.twizmwaz.cardinal.module.id.IdModule;
5+
import in.twizmwaz.cardinal.module.repository.LoadedMap;
6+
import in.twizmwaz.cardinal.util.ParseUtil;
7+
import in.twizmwaz.cardinal.util.document.XML;
8+
import lombok.Getter;
9+
import lombok.NonNull;
10+
import lombok.RequiredArgsConstructor;
11+
import org.jdom2.Attribute;
12+
import org.jdom2.Element;
13+
14+
@RequiredArgsConstructor
15+
public class ModuleReporter {
16+
17+
private final Module module;
18+
private final LoadedMap map;
19+
@Getter
20+
private final Match match;
21+
22+
public ModuleReporter(Module module, Match match) {
23+
this(module, match.getMap(), match);
24+
}
25+
26+
@Getter
27+
private boolean canLoad = false;
28+
29+
public void reset() {
30+
canLoad = true;
31+
}
32+
33+
/**
34+
* Gets an attribute value from an element. If it fails to get a value, en error will be thrown.
35+
* @param element The element to get the attribute from.
36+
* @param attr The attribute to get.
37+
* @param type The class of the type to convert the attribute to.
38+
* @param <T> The type to convert the attribute value to.
39+
* @return An object of the correct type, or null if argument is missing or invalid.
40+
*/
41+
public <T> T getAttr(Element element, String attr, Class<T> type) {
42+
return getAttr(element, attr, type, null, true);
43+
}
44+
45+
/**
46+
* Gets an attribute value from an element. Defaults to fallback if not found.
47+
* @param element The element to get the attribute from.
48+
* @param attr The attribute to get.
49+
* @param type The class of the type to convert the attribute to.
50+
* @param fallback The fallback in case it's null or an error is thrown, null can be used as fallback.
51+
* @param <T> The type to convert the attribute value to.
52+
* @return An object of the correct type, or null if argument is missing or invalid.
53+
*/
54+
public <T> T getAttr(Element element, String attr, Class<T> type, T fallback) {
55+
return getAttr(element, attr, type, fallback, false);
56+
}
57+
58+
private <T> T getAttr(Element element, String attr, Class<T> type, T fallback, boolean required) {
59+
Attribute attribute = element.getAttribute(attr);
60+
if (required && attribute == null) {
61+
module.getErrors().add(new ModuleError(module, map, element, "Missing required attribute:'" + attr + "'", false));
62+
return null;
63+
}
64+
T result = getAttribute(attribute, type);
65+
if (required && result == null) {
66+
canLoad = false;
67+
}
68+
return result != null ? result : fallback;
69+
}
70+
71+
private <T> T getAttribute(Attribute attr, Class<T> type) {
72+
try {
73+
return XML.getAttribute(attr, type);
74+
} catch (Exception e) {
75+
module.getErrors().add(new ModuleError(module, map, attr, e.getMessage(), false));
76+
}
77+
return null;
78+
}
79+
80+
/**
81+
* Gets an attribute value from an element. If it fails to get a value, en error will be thrown.
82+
* @param element The element to get the object from.
83+
* @param type The class of the type to convert the element to.
84+
* @param <T> The type to convert the attribute value to.
85+
* @return An object of the correct type, or null if argument is missing or invalid.
86+
*/
87+
public <T> T getEl(Element element, Class<T> type) {
88+
return getEl(element, type, null, true);
89+
}
90+
91+
/**
92+
* Gets an attribute value from an element.
93+
* @param element The element to get the object from.
94+
* @param type The class of the type to convert the element to.
95+
* @param fallback The fallback in case it's null or an error is thrown, null can be used as fallback.
96+
* @param <T> The type to convert the attribute value to.
97+
* @return An object of the correct type, or null if argument is missing or invalid.
98+
*/
99+
public <T> T getEl(@NonNull Element element, Class<T> type, T fallback) {
100+
return getEl(element, type, fallback, false);
101+
}
102+
103+
private <T> T getEl(@NonNull Element element, Class<T> type, T fallback, boolean required) {
104+
T result = getElement(element, type);
105+
if (required && result == null) {
106+
canLoad = false;
107+
}
108+
return result != null ? result : fallback;
109+
}
110+
111+
private <T> T getElement(Element el, Class<T> type) {
112+
try {
113+
return XML.getElementObject(el, type);
114+
} catch (Exception e) {
115+
module.getErrors().add(new ModuleError(module, map, el, e.getMessage(), false));
116+
}
117+
return null;
118+
}
119+
120+
/**
121+
* Gets a property value from an element. It will try to get the object from the attribute,
122+
* if null, from child element.
123+
* @param element The element to get the property from.
124+
* @param prop The property to get.
125+
* @param type The class of the type to convert the property to.
126+
* @param <T> The type to convert the attribute value to.
127+
* @return An object of the correct type, or null if argument is missing or invalid.
128+
*/
129+
public <T> T getProp(Element element, String prop, Class<T> type) {
130+
return getProp(element, prop, type, null, true);
131+
}
132+
133+
/**
134+
* Gets a property value from an element. It will try to get the object from the attribute,
135+
* if missing, from child element.
136+
* @param element The element to get the property from.
137+
* @param prop The property to get.
138+
* @param type The class of the type to convert the property to.
139+
* @param fallback The fallback in case it's null or an error is thrown, null can be used as fallback.
140+
* @param <T> The type to convert the attribute value to.
141+
* @return An object of the correct type, or null if argument is missing or invalid.
142+
*/
143+
public <T> T getProp(Element element, String prop, Class<T> type, T fallback) {
144+
return getProp(element, prop, type, fallback, false);
145+
}
146+
147+
private <T> T getProp(Element element, String prop, Class<T> type, T fallback, boolean required) {
148+
T result;
149+
Attribute attribute = element.getAttribute(prop);
150+
Element child = element.getChild(prop);
151+
if (attribute == null && child == null && required) {
152+
module.getErrors().add(new ModuleError(module, map, element, "Missing required property:'" + prop + "'", false));
153+
return null;
154+
}
155+
if (attribute != null) {
156+
result = getAttribute(attribute, type);
157+
} else {
158+
result = getElement(element, type);
159+
}
160+
if (required && result == null) {
161+
canLoad = false;
162+
}
163+
return result != null ? result : fallback;
164+
}
165+
166+
public void checkId(Attribute attribute, String id) {
167+
if (!IdModule.get().canAdd(match, id)) {
168+
module.getErrors().add(new ModuleError(module, map, attribute, "Invalid or duplicated ID specified", false));
169+
canLoad = false;
170+
}
171+
}
172+
173+
}

src/main/java/in/twizmwaz/cardinal/module/id/IdModule.java

+10
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,16 @@ public boolean add(Match match, String id, Object object, boolean force) {
9696
return false;
9797
}
9898

99+
/**
100+
* Checks if the id could be added to the match
101+
* @param match The match to try the object to.
102+
* @param id The id to check.
103+
* @return if the object isn't null and isn't duplicated.
104+
*/
105+
public boolean canAdd(Match match, String id) {
106+
return id != null && !ids.get(match).containsKey(id);
107+
}
108+
99109
/**
100110
* Get an object with the given id.
101111
* @param match The match the object belongs to.

src/main/java/in/twizmwaz/cardinal/module/objective/Objective.java

-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ public abstract class Objective {
3838

3939
@NonNull
4040
protected final Match match;
41-
private final String id;
4241
private final boolean required;
4342
protected final boolean show;
4443

src/main/java/in/twizmwaz/cardinal/module/objective/core/Core.java

+2-3
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,6 @@ public class Core extends Objective implements OwnedObjective, EntryUpdater {
8383

8484
/**
8585
* @param match The match the core is part of.
86-
* @param id The core's ID, for usage in code and XML.
8786
* @param name The core's name, for usage by the user.
8887
* @param required Determines if this objective is required to win the match.
8988
* @param region The region that contains this core.
@@ -96,10 +95,10 @@ public class Core extends Objective implements OwnedObjective, EntryUpdater {
9695
* @param proximityHorizontal Determines if only horizontal distance is considered when
9796
* calculating proximity.
9897
*/
99-
public Core(Match match, String id, String name, boolean required, Region region, int leak,
98+
public Core(Match match, String name, boolean required, Region region, int leak,
10099
MaterialPattern material, Team owner, boolean modeChanges,
101100
boolean show, ProximityMetric proximityMetric, boolean proximityHorizontal) {
102-
super(match, id, required, show);
101+
super(match, required, show);
103102
this.name = name;
104103
this.leak = leak;
105104
this.material = material;

src/main/java/in/twizmwaz/cardinal/module/objective/core/CoreModule.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ public boolean loadMatch(Match match) {
170170
boolean proximityHorizontal = proximityHorizontalValue != null
171171
&& Numbers.parseBoolean(proximityHorizontalValue);
172172

173-
Core core = new Core(match, id, name, required, region, leak, material, team, modeChanges, show,
173+
Core core = new Core(match, name, required, region, leak, material, team, modeChanges, show,
174174
proximityMetric, proximityHorizontal);
175175
if (!IdModule.get().add(match, id, core)) {
176176
errors.add(new ModuleError(this, match.getMap(),

src/main/java/in/twizmwaz/cardinal/module/objective/destroyable/Destroyable.java

+2-3
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,6 @@ public class Destroyable extends Objective implements OwnedObjective, EntryUpdat
103103

104104
/**
105105
* @param match The match the destroyable belongs to.
106-
* @param id This destroyable's ID.
107106
* @param name This destroyable's name.
108107
* @param required Determines if this objective is required to win the match.
109108
* @param region The region that contains this destroyable.
@@ -119,12 +118,12 @@ public class Destroyable extends Objective implements OwnedObjective, EntryUpdat
119118
* @param proximityHorizontal Determines if only horizontal distance is considered when
120119
* calculating proximity.
121120
*/
122-
public Destroyable(Match match, String id, String name, boolean required, Region region,
121+
public Destroyable(Match match, String name, boolean required, Region region,
123122
MaterialPattern materials, Team owner,
124123
double completion, boolean modeChanges, boolean showProgress,
125124
boolean repairable, boolean sparks, boolean show,
126125
ProximityMetric proximityMetric, boolean proximityHorizontal) {
127-
super(match, id, required, show);
126+
super(match, required, show);
128127
this.name = name;
129128
this.materials = materials;
130129
this.owner = owner;

src/main/java/in/twizmwaz/cardinal/module/objective/destroyable/DestroyableModule.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ public boolean loadMatch(Match match) {
164164
boolean proximityHorizontal = proximityHorizontalValue != null
165165
&& Numbers.parseBoolean(proximityHorizontalValue);
166166

167-
Destroyable destroyable = new Destroyable(match, id, name, required, region, materials, owner,
167+
Destroyable destroyable = new Destroyable(match, name, required, region, materials, owner,
168168
completion, modeChanges, showProgress, repairable, sparks, show, proximityMetric, proximityHorizontal);
169169
if (!IdModule.get().add(match, id, destroyable)) {
170170
errors.add(new ModuleError(this, match.getMap(),

src/main/java/in/twizmwaz/cardinal/module/objective/wool/Wool.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -83,9 +83,9 @@ public class Wool extends Objective implements Listener, EntryUpdater {
8383
* @param monumentProximityRule The proximity rule that determines how to calculate proximity
8484
* after picking up the wool.
8585
*/
86-
public Wool(Match match, String id, boolean required, Team team, DyeColor color, Region monument, boolean craftable,
86+
public Wool(Match match, boolean required, Team team, DyeColor color, Region monument, boolean craftable,
8787
boolean show, Vector location, ProximityRule woolProximityRule, ProximityRule monumentProximityRule) {
88-
super(match, id, required, show);
88+
super(match, required, show);
8989
this.team = team;
9090
this.color = color;
9191
this.monument = monument;

0 commit comments

Comments
 (0)