forked from Bukkit/Bukkit
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Refactor common metadata code into base class. Fixes BUKKIT-3624
Implementing the MetadataValue interface is significant work due to having to provide a large amount of conversion stub methods. This commit adds a new optional abstract base class to aid in implementation.
- Loading branch information
Showing
3 changed files
with
176 additions
and
59 deletions.
There are no files selected for viewing
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
77 changes: 77 additions & 0 deletions
77
src/main/java/org/bukkit/metadata/MetadataValueAdapter.java
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
package org.bukkit.metadata; | ||
|
||
import org.apache.commons.lang.Validate; | ||
import org.bukkit.plugin.Plugin; | ||
import org.bukkit.util.NumberConversions; | ||
|
||
/** | ||
* Optional base class for facilitating MetadataValue implementations. | ||
* | ||
* This provides all the conversion functions for MetadataValue | ||
* so that writing an implementation of MetadataValue is as simple | ||
* as implementing value() and invalidate(). | ||
* | ||
*/ | ||
public abstract class MetadataValueAdapter implements MetadataValue { | ||
protected final Plugin owningPlugin; | ||
|
||
protected MetadataValueAdapter(Plugin owningPlugin) { | ||
Validate.notNull(owningPlugin, "owningPlugin cannot be null"); | ||
this.owningPlugin = owningPlugin; | ||
} | ||
|
||
public Plugin getOwningPlugin() { | ||
return owningPlugin; | ||
} | ||
|
||
public int asInt() { | ||
return NumberConversions.toInt(value()); | ||
} | ||
|
||
public float asFloat() { | ||
return NumberConversions.toFloat(value()); | ||
} | ||
|
||
public double asDouble() { | ||
return NumberConversions.toDouble(value()); | ||
} | ||
|
||
public long asLong() { | ||
return NumberConversions.toLong(value()); | ||
} | ||
|
||
public short asShort() { | ||
return NumberConversions.toShort(value()); | ||
} | ||
|
||
public byte asByte() { | ||
return NumberConversions.toByte(value()); | ||
} | ||
|
||
public boolean asBoolean() { | ||
Object value = value(); | ||
if (value instanceof Boolean) { | ||
return (Boolean) value; | ||
} | ||
|
||
if (value instanceof Number) { | ||
return ((Number) value).intValue() != 0; | ||
} | ||
|
||
if (value instanceof String) { | ||
return Boolean.parseBoolean((String) value); | ||
} | ||
|
||
return value != null; | ||
} | ||
|
||
public String asString() { | ||
Object value = value(); | ||
|
||
if (value == null) { | ||
return ""; | ||
} | ||
return value.toString(); | ||
} | ||
|
||
} |
97 changes: 97 additions & 0 deletions
97
src/test/java/org/bukkit/metadata/MetadataValueAdapterTest.java
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
package org.bukkit.metadata; | ||
|
||
import static org.junit.Assert.assertEquals; | ||
|
||
import org.bukkit.plugin.Plugin; | ||
import org.bukkit.plugin.TestPlugin; | ||
import org.junit.Test; | ||
|
||
public class MetadataValueAdapterTest { | ||
private TestPlugin plugin = new TestPlugin("x"); | ||
|
||
@Test | ||
public void testAdapterBasics() { | ||
IncrementingMetaValue mv = new IncrementingMetaValue(plugin); | ||
// check getOwningPlugin | ||
assertEquals(mv.getOwningPlugin(), this.plugin); | ||
|
||
// Check value-getting and invalidation. | ||
assertEquals(new Integer(1), mv.value()); | ||
assertEquals(new Integer(2), mv.value()); | ||
mv.invalidate(); | ||
assertEquals(new Integer(1), mv.value()); | ||
} | ||
|
||
@Test | ||
public void testAdapterConversions() { | ||
IncrementingMetaValue mv = new IncrementingMetaValue(plugin); | ||
|
||
assertEquals(1, mv.asInt()); | ||
assertEquals(2L, mv.asLong()); | ||
assertEquals(3.0, mv.asFloat(), 0.001); | ||
assertEquals(4, mv.asByte()); | ||
assertEquals(5.0, mv.asDouble(), 0.001); | ||
assertEquals(6, mv.asShort()); | ||
assertEquals("7", mv.asString()); | ||
} | ||
|
||
/** Boolean conversion is non-trivial, we want to test it thoroughly. */ | ||
@Test | ||
public void testBooleanConversion() { | ||
// null is False. | ||
assertEquals(false, simpleValue(null).asBoolean()); | ||
|
||
// String to boolean. | ||
assertEquals(true, simpleValue("True").asBoolean()); | ||
assertEquals(true, simpleValue("TRUE").asBoolean()); | ||
assertEquals(false, simpleValue("false").asBoolean()); | ||
|
||
// Number to boolean. | ||
assertEquals(true, simpleValue(1).asBoolean()); | ||
assertEquals(true, simpleValue(5.0).asBoolean()); | ||
assertEquals(false, simpleValue(0).asBoolean()); | ||
assertEquals(false, simpleValue(0.1).asBoolean()); | ||
|
||
// Boolean as boolean, of course. | ||
assertEquals(true, simpleValue(Boolean.TRUE).asBoolean()); | ||
assertEquals(false, simpleValue(Boolean.FALSE).asBoolean()); | ||
|
||
// any object that is not null and not a Boolean, String, or Number is true. | ||
assertEquals(true, simpleValue(new Object()).asBoolean()); | ||
} | ||
|
||
/** Test String conversions return an empty string when given null. */ | ||
@Test | ||
public void testStringConversionNull() { | ||
assertEquals("", simpleValue(null).asString()); | ||
} | ||
|
||
/** Get a fixed value MetadataValue. */ | ||
private MetadataValue simpleValue(Object value) { | ||
return new FixedMetadataValue(plugin, value); | ||
} | ||
|
||
/** | ||
* A sample non-trivial MetadataValueAdapter implementation. | ||
* | ||
* The rationale for implementing an incrementing value is to have a value | ||
* which changes with every call to value(). This is important for testing | ||
* because we want to make sure all the tested conversions are calling the | ||
* value() method exactly once and no caching is going on. | ||
*/ | ||
class IncrementingMetaValue extends MetadataValueAdapter { | ||
private int internalValue = 0; | ||
|
||
protected IncrementingMetaValue(Plugin owningPlugin) { | ||
super(owningPlugin); | ||
} | ||
|
||
public Object value() { | ||
return ++internalValue; | ||
} | ||
|
||
public void invalidate() { | ||
internalValue = 0; | ||
} | ||
} | ||
} |