cucumber.api.Transformer Maven / Gradle / Ivy
package cucumber.api;
import cucumber.deps.com.thoughtworks.xstream.converters.SingleValueConverter;
import cucumber.runtime.ParameterInfo;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Locale;
/**
*
* Allows transformation of a step definition argument to a custom type, giving you full control
* over how that type is instantiated.
*
*
* Consider the following Gherkin step:
*
* Given today's date is "10/03/1985"
*
* As an example, let's assume we want Cucumber to transform the substring "10/03/1985" into an instance of
* org.joda.time.LocalDate
class:
*
*
* @Given("today's date is \"(.*)\"")
* public void todays_date_is(LocalDate d) {
* }
*
*
* If the parameter's class has a constructor with a single String
or Object
argument, then
* Cucumber will instantiate it without any further ado. However, in this case that might not give you what you
* want. Depending on your Locale, the date may be Oct 3 or March 10!
*
*
*
* This is when you can use a custom transformer. You'll also have to do that if your parameter class doesn't
* have a constructor with a single String
or Object
argument. For the JODA Time
* example:
*
*
*
* @Given("today's date is \"(.*)\"")
* public void todays_date_is(@Transform(JodaTimeConverter.class) LocalDate d) {
* }
*
*
* And then a JodaTimeConverter
class:
*
* {@code
* public static class JodaTimeConverter extends Transformer {
* private static DateTimeFormatter FORMATTER = DateTimeFormat.forStyle("S-");
*
* @Override
* public LocalDate transform(String value) {
* return FORMATTER.withLocale(getLocale()).parseLocalDate(value);
* }
* }
* }
*
* An alternative to annotating parameters with {@link Transform} is to annotate your class with
* {@link cucumber.deps.com.thoughtworks.xstream.annotations.XStreamConverter}:
*
*
* @XStreamConverter(MyConverter.class)
* public class MyClass {
* }
*
*
* This will also enable a {@link DataTable} to be transformed to
* a List<MyClass;>
*
*
* @param the type to be instantiated
* @see Transform
*/
public abstract class Transformer implements SingleValueConverter {
private final Type type;
private Locale locale;
public Transformer() {
ParameterizedType ptype = (ParameterizedType) getClass().getGenericSuperclass();
this.type = ptype.getActualTypeArguments()[0];
}
@Override
public String toString(Object o) {
return o.toString();
}
@Override
public final Object fromString(String s) {
return transform(s);
}
@Override
public boolean canConvert(Class type) {
return type.equals(this.type);
}
public abstract T transform(String value);
public void setParameterInfoAndLocale(ParameterInfo parameterInfo, Locale locale) {
this.locale = locale;
}
/**
* @return the current locale
*/
protected Locale getLocale() {
return locale;
}
}