소스 검색

Change declarative support to use new converters

Change-Id: I3bb2c106a4c4d8556f6f752867da1917e0d3c9a3
tags/8.0.0.alpha1
Artur Signell 7 년 전
부모
커밋
2713507192

+ 4
- 3
server/src/main/java/com/vaadin/ui/declarative/DesignAttributeHandler.java 파일 보기

@@ -36,10 +36,10 @@ import org.jsoup.nodes.Attributes;
import org.jsoup.nodes.Element;
import org.jsoup.nodes.Node;

import com.vaadin.data.util.converter.Converter;
import com.vaadin.shared.ui.AlignmentInfo;
import com.vaadin.shared.util.SharedUtil;
import com.vaadin.ui.Alignment;
import com.vaadin.v7.data.util.converter.Converter;

/**
* Default attribute handler implementation used when parsing designs to
@@ -379,10 +379,11 @@ public class DesignAttributeHandler implements Serializable {
// value is not null. How to represent null value in attributes?
return "";
}
Converter<String, Object> converter = getFormatter()
@SuppressWarnings("unchecked")
Converter<String, Object> converter = (Converter<String, Object>) getFormatter()
.findConverterFor(sourceType);
if (converter != null) {
return converter.convertToPresentation(value, String.class, null);
return converter.convertToPresentation(value, null);
} else {
return value.toString();
}

+ 27
- 67
server/src/main/java/com/vaadin/ui/declarative/DesignFormatter.java 파일 보기

@@ -30,6 +30,11 @@ import java.util.concurrent.ConcurrentHashMap;

import org.jsoup.parser.Parser;

import com.vaadin.data.Result;
import com.vaadin.data.util.converter.Converter;
import com.vaadin.data.util.converter.StringToBigDecimalConverter;
import com.vaadin.data.util.converter.StringToDoubleConverter;
import com.vaadin.data.util.converter.StringToFloatConverter;
import com.vaadin.event.ShortcutAction;
import com.vaadin.server.Resource;
import com.vaadin.ui.declarative.converters.DesignDateConverter;
@@ -39,10 +44,6 @@ import com.vaadin.ui.declarative.converters.DesignResourceConverter;
import com.vaadin.ui.declarative.converters.DesignShortcutActionConverter;
import com.vaadin.ui.declarative.converters.DesignTimeZoneConverter;
import com.vaadin.ui.declarative.converters.DesignToStringConverter;
import com.vaadin.v7.data.util.converter.Converter;
import com.vaadin.v7.data.util.converter.StringToBigDecimalConverter;
import com.vaadin.v7.data.util.converter.StringToDoubleConverter;
import com.vaadin.v7.data.util.converter.StringToFloatConverter;

/**
* Class focused on flexible and consistent formatting and parsing of different
@@ -55,7 +56,6 @@ import com.vaadin.v7.data.util.converter.StringToFloatConverter;
public class DesignFormatter implements Serializable {

private final Map<Class<?>, Converter<String, ?>> converterMap = new ConcurrentHashMap<Class<?>, Converter<String, ?>>();
private final Converter<String, Enum> stringEnumConverter = new DesignEnumConverter();
private final Converter<String, Object> stringObjectConverter = new DesignObjectConverter();

/**
@@ -86,16 +86,12 @@ public class DesignFormatter implements Serializable {
Converter<String, Boolean> booleanConverter = new Converter<String, Boolean>() {

@Override
public Boolean convertToModel(String value,
Class<? extends Boolean> targetType, Locale locale)
throws Converter.ConversionException {
return !value.equalsIgnoreCase("false");
public Result<Boolean> convertToModel(String value, Locale locale) {
return Result.ok(!value.equalsIgnoreCase("false"));
}

@Override
public String convertToPresentation(Boolean value,
Class<? extends String> targetType, Locale locale)
throws Converter.ConversionException {
public String convertToPresentation(Boolean value, Locale locale) {
if (value.booleanValue()) {
return "";
} else {
@@ -103,16 +99,6 @@ public class DesignFormatter implements Serializable {
}
}

@Override
public Class<Boolean> getModelType() {
return Boolean.class;
}

@Override
public Class<String> getPresentationType() {
return String.class;
}

};
converterMap.put(Boolean.class, booleanConverter);
converterMap.put(boolean.class, booleanConverter);
@@ -144,41 +130,26 @@ public class DesignFormatter implements Serializable {
final DecimalFormat bigDecimalFmt = new DecimalFormat("0.###", symbols);
bigDecimalFmt.setGroupingUsed(false);
bigDecimalFmt.setParseBigDecimal(true);
converterMap.put(BigDecimal.class,
new StringToBigDecimalConverter() {
@Override
protected NumberFormat getFormat(Locale locale) {
return bigDecimalFmt;
};
});
converterMap.put(BigDecimal.class, new StringToBigDecimalConverter() {
@Override
protected NumberFormat getFormat(Locale locale) {
return bigDecimalFmt;
};
});

// strings do nothing
converterMap.put(String.class, new Converter<String, String>() {

@Override
public String convertToModel(String value,
Class<? extends String> targetType, Locale locale)
throws Converter.ConversionException {
return value;
public Result<String> convertToModel(String value, Locale locale) {
return Result.ok(value);
}

@Override
public String convertToPresentation(String value,
Class<? extends String> targetType, Locale locale)
throws Converter.ConversionException {
public String convertToPresentation(String value, Locale locale) {
return value;
}

@Override
public Class<String> getModelType() {
return String.class;
}

@Override
public Class<String> getPresentationType() {
return String.class;
}

});

// char takes the first character from the string
@@ -186,10 +157,9 @@ public class DesignFormatter implements Serializable {
Character.class) {

@Override
public Character convertToModel(String value,
Class<? extends Character> targetType, Locale locale)
throws Converter.ConversionException {
return value.charAt(0);
public Result<Character> convertToModel(String value,
Locale locale) {
return Result.ok(value.charAt(0));
}

};
@@ -203,16 +173,6 @@ public class DesignFormatter implements Serializable {
converterMap.put(TimeZone.class, new DesignTimeZoneConverter());
}

/**
* Adds a converter for a new type.
*
* @param converter
* Converter to add.
*/
protected <T> void addConverter(Converter<String, T> converter) {
converterMap.put(converter.getModelType(), converter);
}

/**
* Adds a converter for a given type.
*
@@ -248,7 +208,7 @@ public class DesignFormatter implements Serializable {
}

/**
* Parses a given string as a value of given type
* Parses a given string as a value of given type.
*
* @param value
* String value to convert.
@@ -260,7 +220,8 @@ public class DesignFormatter implements Serializable {
public <T> T parse(String value, Class<? extends T> type) {
Converter<String, T> converter = findConverterFor(type);
if (converter != null) {
return converter.convertToModel(value, type, null);
Result<T> result = converter.convertToModel(value, null);
return result.getOrThrow(msg -> new IllegalArgumentException(msg));
} else {
return null;
}
@@ -295,7 +256,7 @@ public class DesignFormatter implements Serializable {
} else {
Converter<String, Object> converter = findConverterFor(
object.getClass());
return converter.convertToPresentation(object, String.class, null);
return converter.convertToPresentation(object, null);
}
}

@@ -325,7 +286,7 @@ public class DesignFormatter implements Serializable {
* @return A valid converter for a given type or its supertype, <b>null</b>
* if it was not found.
*/
@SuppressWarnings("unchecked")
@SuppressWarnings({ "unchecked", "rawtypes" })
protected <T> Converter<String, T> findConverterFor(
Class<? extends T> sourceType, boolean strict) {
if (sourceType == Object.class) {
@@ -340,14 +301,13 @@ public class DesignFormatter implements Serializable {
} else if (!strict) {
for (Class<?> supported : converterMap.keySet()) {
if (supported.isAssignableFrom(sourceType)) {
return ((Converter<String, T>) converterMap
.get(supported));
return ((Converter<String, T>) converterMap.get(supported));
}
}
}

if (sourceType.isEnum()) {
return (Converter<String, T>) stringEnumConverter;
return new DesignEnumConverter(sourceType);
}
return null;
}

+ 6
- 18
server/src/main/java/com/vaadin/ui/declarative/converters/DesignDateConverter.java 파일 보기

@@ -20,8 +20,9 @@ import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;

import com.vaadin.data.Result;
import com.vaadin.data.util.converter.Converter;
import com.vaadin.ui.declarative.DesignAttributeHandler;
import com.vaadin.v7.data.util.converter.Converter;

/**
* A date converter to be used by {@link DesignAttributeHandler}. Provides
@@ -33,35 +34,22 @@ import com.vaadin.v7.data.util.converter.Converter;
public class DesignDateConverter implements Converter<String, Date> {

@Override
public Date convertToModel(String value, Class<? extends Date> targetType,
Locale locale) throws Converter.ConversionException {
public Result<Date> convertToModel(String value, Locale locale) {
for (String pattern : new String[] { "yyyy-MM-dd HH:mm:ssZ",
"yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM-dd HH",
"yyyy-MM-dd", "yyyy-MM", "yyyy" }) {
try {
return new SimpleDateFormat(pattern).parse(value);
return Result.ok(new SimpleDateFormat(pattern).parse(value));
} catch (ParseException e) {
// not parseable, ignore and try another format
}
}
return null;
return Result.error("Could not parse date value: " + value);
}

@Override
public String convertToPresentation(Date value,
Class<? extends String> targetType, Locale locale)
throws Converter.ConversionException {
public String convertToPresentation(Date value, Locale locale) {
return new SimpleDateFormat("yyyy-MM-dd HH:mm:ssZ").format(value);
}

@Override
public Class<Date> getModelType() {
return Date.class;
}

@Override
public Class<String> getPresentationType() {
return String.class;
}

}

+ 28
- 20
server/src/main/java/com/vaadin/ui/declarative/converters/DesignEnumConverter.java 파일 보기

@@ -17,8 +17,9 @@ package com.vaadin.ui.declarative.converters;

import java.util.Locale;

import com.vaadin.data.Result;
import com.vaadin.data.util.converter.Converter;
import com.vaadin.ui.declarative.DesignAttributeHandler;
import com.vaadin.v7.data.util.converter.Converter;

/**
* An converter for Enum to/from String for {@link DesignAttributeHandler} to
@@ -27,22 +28,39 @@ import com.vaadin.v7.data.util.converter.Converter;
* @since 7.4
* @author Vaadin Ltd
*/
public class DesignEnumConverter implements Converter<String, Enum> {
@SuppressWarnings("rawtypes")
public class DesignEnumConverter<T extends Enum>
implements Converter<String, T> {

private Class<T> type;

/**
* Creates a converter for the given enum type.
*
* @param type
* the enum type to convert to/from
*/
public DesignEnumConverter(Class<T> type) {
this.type = type;
}

@SuppressWarnings("unchecked")
@Override
public Enum convertToModel(String value, Class<? extends Enum> targetType,
Locale locale)
throws com.vaadin.v7.data.util.converter.Converter.ConversionException {
public Result<T> convertToModel(String value, Locale locale) {
if (value == null || value.trim().equals("")) {
return null;
return Result.ok(null);
}
try {
T result = (T) Enum.valueOf(type,
value.toUpperCase(Locale.ENGLISH));
return Result.ok(result);
} catch (Exception e) {
return Result.error(e.getMessage());
}
return Enum.valueOf(targetType, value.toUpperCase(Locale.ENGLISH));
}

@Override
public String convertToPresentation(Enum value,
Class<? extends String> targetType, Locale locale)
throws com.vaadin.v7.data.util.converter.Converter.ConversionException {
public String convertToPresentation(T value, Locale locale) {
if (value == null) {
return null;
}
@@ -50,14 +68,4 @@ public class DesignEnumConverter implements Converter<String, Enum> {
return value.name().toLowerCase(Locale.ENGLISH);
}

@Override
public Class<Enum> getModelType() {
return Enum.class;
}

@Override
public Class<String> getPresentationType() {
return String.class;
}

}

+ 5
- 18
server/src/main/java/com/vaadin/ui/declarative/converters/DesignObjectConverter.java 파일 보기

@@ -17,8 +17,9 @@ package com.vaadin.ui.declarative.converters;

import java.util.Locale;

import com.vaadin.data.Result;
import com.vaadin.data.util.converter.Converter;
import com.vaadin.ui.declarative.DesignAttributeHandler;
import com.vaadin.v7.data.util.converter.Converter;

/**
* An converter for Object to/from String for {@link DesignAttributeHandler} to
@@ -30,16 +31,12 @@ import com.vaadin.v7.data.util.converter.Converter;
public class DesignObjectConverter implements Converter<String, Object> {

@Override
public Object convertToModel(String value,
Class<? extends Object> targetType, Locale locale)
throws com.vaadin.v7.data.util.converter.Converter.ConversionException {
return value;
public Result<Object> convertToModel(String value, Locale locale) {
return Result.ok(value);
}

@Override
public String convertToPresentation(Object value,
Class<? extends String> targetType, Locale locale)
throws com.vaadin.v7.data.util.converter.Converter.ConversionException {
public String convertToPresentation(Object value, Locale locale) {
if (value == null) {
return null;
}
@@ -47,14 +44,4 @@ public class DesignObjectConverter implements Converter<String, Object> {
return value.toString();
}

@Override
public Class<Object> getModelType() {
return Object.class;
}

@Override
public Class<String> getPresentationType() {
return String.class;
}

}

+ 14
- 33
server/src/main/java/com/vaadin/ui/declarative/converters/DesignResourceConverter.java 파일 보기

@@ -21,6 +21,8 @@ import java.util.HashMap;
import java.util.Locale;
import java.util.Map;

import com.vaadin.data.Result;
import com.vaadin.data.util.converter.Converter;
import com.vaadin.server.ExternalResource;
import com.vaadin.server.FileResource;
import com.vaadin.server.FontAwesome;
@@ -30,7 +32,7 @@ import com.vaadin.server.Resource;
import com.vaadin.server.ResourceReference;
import com.vaadin.server.ThemeResource;
import com.vaadin.ui.declarative.DesignAttributeHandler;
import com.vaadin.v7.data.util.converter.Converter;
import com.vaadin.v7.data.util.converter.Converter.ConversionException;

/**
* A converter for {@link Resource} implementations supported by
@@ -40,13 +42,10 @@ import com.vaadin.v7.data.util.converter.Converter;
* @author Vaadin Ltd
*/
@SuppressWarnings("serial")
public class DesignResourceConverter
implements Converter<String, Resource> {
public class DesignResourceConverter implements Converter<String, Resource> {

@Override
public Resource convertToModel(String value,
Class<? extends Resource> targetType, Locale locale)
throws Converter.ConversionException {
public Result<Resource> convertToModel(String value, Locale locale) {
if (!value.contains("://")) {
// assume it'is "file://" protocol, one that is used to access a
// file on a given path on the server, this will later be striped
@@ -58,37 +57,24 @@ public class DesignResourceConverter
try {
ResourceConverterByProtocol converter = ResourceConverterByProtocol
.valueOf(protocol.toUpperCase(Locale.ENGLISH));
return converter.parse(value);
return Result.ok(converter.parse(value));
} catch (IllegalArgumentException iae) {
throw new ConversionException("Unrecognized protocol: " + protocol,
iae);
return Result.error("Unrecognized protocol: " + protocol);
}
}

@Override
public String convertToPresentation(Resource value,
Class<? extends String> targetType, Locale locale)
throws Converter.ConversionException {
public String convertToPresentation(Resource value, Locale locale) {
ResourceConverterByProtocol byType = ResourceConverterByProtocol
.byType(value.getClass());
if (byType != null) {
return byType.format(value);
} else {
throw new Converter.ConversionException(
throw new IllegalArgumentException(
"unknown Resource type - " + value.getClass().getName());
}
}

@Override
public Class<Resource> getModelType() {
return Resource.class;
}

@Override
public Class<String> getPresentationType() {
return String.class;
}

private static interface ProtocolResourceConverter extends Serializable {
public String format(Resource value);

@@ -108,8 +94,7 @@ public class DesignResourceConverter
}

@Override
public String format(Resource value)
throws Converter.ConversionException {
public String format(Resource value) {
return new ResourceReference(value, null, null).getURL();
}
},
@@ -138,8 +123,7 @@ public class DesignResourceConverter
}

@Override
public String format(Resource value)
throws Converter.ConversionException {
public String format(Resource value) {
FontIcon icon = (FontIcon) value;
return new ResourceReference(icon, null, null).getURL();

@@ -162,8 +146,7 @@ public class DesignResourceConverter
}

@Override
public String format(Resource value)
throws Converter.ConversionException {
public String format(Resource value) {
throw new UnsupportedOperationException(
"Use " + ResourceConverterByProtocol.FONTICON.toString()
+ " instead");
@@ -176,8 +159,7 @@ public class DesignResourceConverter
}

@Override
public String format(Resource value)
throws Converter.ConversionException {
public String format(Resource value) {
String path = ((FileResource) value).getSourceFile().getPath();
if (File.separatorChar != '/') {
// make sure we use '/' as file separator in templates
@@ -196,8 +178,7 @@ public class DesignResourceConverter
}

@Override
public String format(Resource value)
throws Converter.ConversionException {
public String format(Resource value) {
// default behavior for HTTP, HTTPS, FTP and FTPS
return ((ExternalResource) value).getURL();
}

+ 8
- 22
server/src/main/java/com/vaadin/ui/declarative/converters/DesignShortcutActionConverter.java 파일 보기

@@ -21,10 +21,11 @@ import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;

import com.vaadin.data.Result;
import com.vaadin.data.util.converter.Converter;
import com.vaadin.event.ShortcutAction;
import com.vaadin.event.ShortcutAction.KeyCode;
import com.vaadin.event.ShortcutAction.ModifierKey;
import com.vaadin.v7.data.util.converter.Converter;

/**
* Converter for {@link ShortcutActions}.
@@ -120,11 +121,9 @@ public class DesignShortcutActionConverter
}

@Override
public ShortcutAction convertToModel(String value,
Class<? extends ShortcutAction> targetType, Locale locale)
throws Converter.ConversionException {
public Result<ShortcutAction> convertToModel(String value, Locale locale) {
if (value.length() == 0) {
return null;
return Result.ok(null);
}

String[] data = value.split(" ", 2);
@@ -152,18 +151,15 @@ public class DesignShortcutActionConverter
"Invalid modifier '" + parts[i] + "'");
}
}
return new ShortcutAction(data.length == 2 ? data[1] : null,
keyCode, modifiers);
return Result.ok(new ShortcutAction(
data.length == 2 ? data[1] : null, keyCode, modifiers));
} catch (Exception e) {
throw new ConversionException("Invalid shortcut '" + value + "'",
e);
return Result.error("Invalid shortcut '" + value + "'");
}
}

@Override
public String convertToPresentation(ShortcutAction value,
Class<? extends String> targetType, Locale locale)
throws Converter.ConversionException {
public String convertToPresentation(ShortcutAction value, Locale locale) {
StringBuilder sb = new StringBuilder();
// handle modifiers
if (value.getModifiers() != null) {
@@ -179,16 +175,6 @@ public class DesignShortcutActionConverter
return sb.toString();
}

@Override
public Class<ShortcutAction> getModelType() {
return ShortcutAction.class;
}

@Override
public Class<String> getPresentationType() {
return String.class;
}

public int getKeycodeForString(String attributePresentation) {
Integer code = presentationMap.get(attributePresentation);
return code != null ? code.intValue() : -1;

+ 7
- 21
server/src/main/java/com/vaadin/ui/declarative/converters/DesignTimeZoneConverter.java 파일 보기

@@ -18,8 +18,9 @@ package com.vaadin.ui.declarative.converters;
import java.util.Locale;
import java.util.TimeZone;

import com.vaadin.data.Result;
import com.vaadin.data.util.converter.Converter;
import com.vaadin.ui.declarative.DesignAttributeHandler;
import com.vaadin.v7.data.util.converter.Converter;

/**
* Utility class for {@link DesignAttributeHandler} that deals with converting
@@ -28,24 +29,19 @@ import com.vaadin.v7.data.util.converter.Converter;
* @since 7.4
* @author Vaadin Ltd
*/
public class DesignTimeZoneConverter
implements Converter<String, TimeZone> {
public class DesignTimeZoneConverter implements Converter<String, TimeZone> {

@Override
public TimeZone convertToModel(String value,
Class<? extends TimeZone> targetTimeZone, Locale locale)
throws Converter.ConversionException {
public Result<TimeZone> convertToModel(String value, Locale locale) {
if (value == null || value.isEmpty()) {
return null;
return Result.ok(null);
}

return TimeZone.getTimeZone(value);
return Result.ok(TimeZone.getTimeZone(value));
}

@Override
public String convertToPresentation(TimeZone value,
Class<? extends String> targetTimeZone, Locale locale)
throws Converter.ConversionException {
public String convertToPresentation(TimeZone value, Locale locale) {
if (value == null) {
return "";
} else {
@@ -53,14 +49,4 @@ public class DesignTimeZoneConverter
}
}

@Override
public Class<TimeZone> getModelType() {
return TimeZone.class;
}

@Override
public Class<String> getPresentationType() {
return String.class;
}

}

+ 11
- 31
server/src/main/java/com/vaadin/ui/declarative/converters/DesignToStringConverter.java 파일 보기

@@ -18,8 +18,9 @@ package com.vaadin.ui.declarative.converters;
import java.lang.reflect.InvocationTargetException;
import java.util.Locale;

import com.vaadin.data.Result;
import com.vaadin.data.util.converter.Converter;
import com.vaadin.ui.declarative.DesignAttributeHandler;
import com.vaadin.v7.data.util.converter.Converter;

/**
* Utility class for {@link DesignAttributeHandler} that deals with converting
@@ -30,8 +31,7 @@ import com.vaadin.v7.data.util.converter.Converter;
* @param <TYPE>
* Type of the data being converted.
*/
public class DesignToStringConverter<TYPE>
implements Converter<String, TYPE> {
public class DesignToStringConverter<TYPE> implements Converter<String, TYPE> {

private final Class<? extends TYPE> type;

@@ -72,30 +72,20 @@ public class DesignToStringConverter<TYPE>
}

@Override
public TYPE convertToModel(String value, Class<? extends TYPE> targetType,
Locale locale) throws Converter.ConversionException {
public Result<TYPE> convertToModel(String value, Locale locale) {
try {
return type.cast(type.getMethod(this.staticMethodName, String.class)
.invoke(null, value));
} catch (IllegalAccessException e) {
throw new Converter.ConversionException(e);
} catch (IllegalArgumentException e) {
throw new Converter.ConversionException(e);
return Result.ok(type
.cast(type.getMethod(this.staticMethodName, String.class)
.invoke(null, value)));
} catch (InvocationTargetException e) {
throw new Converter.ConversionException(e.getCause());
} catch (NoSuchMethodException e) {
throw new Converter.ConversionException(e);
} catch (SecurityException e) {
throw new Converter.ConversionException(e);
} catch (RuntimeException e) {
throw new Converter.ConversionException(e);
return Result.error(e.getCause().getMessage());
} catch (Exception e) {
return Result.error(e.getMessage());
}
}

@Override
public String convertToPresentation(TYPE value,
Class<? extends String> targetType, Locale locale)
throws Converter.ConversionException {
public String convertToPresentation(TYPE value, Locale locale) {
if (value == null) {
return NULL_VALUE_REPRESENTATION;
} else {
@@ -103,14 +93,4 @@ public class DesignToStringConverter<TYPE>
}
}

@Override
public Class<TYPE> getModelType() {
return (Class<TYPE>) this.type;
}

@Override
public Class<String> getPresentationType() {
return String.class;
}

}

+ 3
- 4
server/src/test/java/com/vaadin/tests/design/DesignFormatterTest.java 파일 보기

@@ -42,7 +42,6 @@ import com.vaadin.server.ThemeResource;
import com.vaadin.shared.ApplicationConstants;
import com.vaadin.shared.util.SharedUtil;
import com.vaadin.ui.declarative.DesignFormatter;
import com.vaadin.v7.data.util.converter.Converter.ConversionException;

/**
* Various tests related to formatter.
@@ -238,7 +237,7 @@ public class DesignFormatterTest {
try {
formatter.parse(shortcut, ShortcutAction.class);
Assert.fail("Invalid shortcut '" + shortcut + "' should throw");
} catch (ConversionException e) {
} catch (IllegalArgumentException e) {
// expected
}
}
@@ -298,13 +297,13 @@ public class DesignFormatterTest {
formatter.format(new FileResource(new File(fileSystemPath))));
}

@Test(expected = ConversionException.class)
@Test(expected = IllegalArgumentException.class)
public void testResourceParseException() {
String someRandomResourceUrl = "random://url";
formatter.parse(someRandomResourceUrl, Resource.class);
}

@Test(expected = ConversionException.class)
@Test(expected = IllegalArgumentException.class)
public void testResourceFormatException() {
formatter.format(new Resource() { // must use unknown resource type
@Override

Loading…
취소
저장