Browse Source

Simplified declarative converters

* Removed shortcut interface
* Moved TimeZone converter to a separate class
* Moved Enum converter to a separate class

Change-Id: I2b959e3a002e6319912212df4a62a3bd05677f80
tags/7.4.0.rc1
Artur Signell 9 years ago
parent
commit
0119eab3d7

+ 6
- 28
server/src/com/vaadin/ui/declarative/DesignFormatter.java View File

@@ -31,11 +31,12 @@ import com.vaadin.data.util.converter.Converter;
import com.vaadin.event.ShortcutAction;
import com.vaadin.server.Resource;
import com.vaadin.ui.declarative.converters.DesignDateConverter;
import com.vaadin.ui.declarative.converters.DesignEnumConverter;
import com.vaadin.ui.declarative.converters.DesignFormatConverter;
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.ui.declarative.converters.ShortcutKeyMapper;

/**
* Class focused on flexible and consistent formatting and parsing of different
@@ -48,6 +49,7 @@ import com.vaadin.ui.declarative.converters.ShortcutKeyMapper;
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();

/**
* Creates the formatter with default types already mapped.
@@ -162,25 +164,11 @@ public class DesignFormatter implements Serializable {
converterMap.put(Character.class, charConverter);
converterMap.put(Character.TYPE, charConverter);

// date conversion has its own class
converterMap.put(Date.class, new DesignDateConverter());

// as shortcut action and resource
converterMap.put(ShortcutAction.class,
new DesignShortcutActionConverter(ShortcutKeyMapper.DEFAULT));

new DesignShortcutActionConverter());
converterMap.put(Resource.class, new DesignResourceConverter());

// timezones use different static method and do not use toString()
converterMap.put(TimeZone.class, new DesignToStringConverter<TimeZone>(
TimeZone.class, "getTimeZone") {
@Override
public String convertToPresentation(TimeZone value,
Class<? extends String> targetType, Locale locale)
throws Converter.ConversionException {
return value.getID();
}
});
converterMap.put(TimeZone.class, new DesignTimeZoneConverter());
}

/**
@@ -307,17 +295,7 @@ public class DesignFormatter implements Serializable {
protected <T> Converter<String, T> findConverterFor(
Class<? extends T> sourceType, boolean strict) {
if (sourceType.isEnum()) {
// enums can be read in lowercase
return new DesignToStringConverter<T>(sourceType) {

@Override
public T convertToModel(String value,
Class<? extends T> targetType, Locale locale)
throws Converter.ConversionException {
return super.convertToModel(value.toUpperCase(),
targetType, locale);
}
};
return (Converter<String, T>) stringEnumConverter;
} else if (converterMap.containsKey(sourceType)) {
return ((Converter<String, T>) converterMap.get(sourceType));
} else if (!strict) {

+ 63
- 0
server/src/com/vaadin/ui/declarative/converters/DesignEnumConverter.java View File

@@ -0,0 +1,63 @@
/*
* Copyright 2000-2014 Vaadin Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.vaadin.ui.declarative.converters;

import java.util.Locale;

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

/**
* An converter for Enum to/from String for {@link DesignAttributeHandler} to
* use internally.
*
* @since 7.4
* @author Vaadin Ltd
*/
public class DesignEnumConverter implements Converter<String, Enum> {

@Override
public Enum convertToModel(String value, Class<? extends Enum> targetType,
Locale locale)
throws com.vaadin.data.util.converter.Converter.ConversionException {
if (value == null || value.trim().equals("")) {
return null;
}
return Enum.valueOf(targetType, value.toUpperCase(Locale.ENGLISH));
}

@Override
public String convertToPresentation(Enum value,
Class<? extends String> targetType, Locale locale)
throws com.vaadin.data.util.converter.Converter.ConversionException {
if (value == null) {
return null;
}

return value.name().toLowerCase(Locale.ENGLISH);
}

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

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

}

+ 99
- 25
server/src/com/vaadin/ui/declarative/converters/DesignShortcutActionConverter.java View File

@@ -15,10 +15,16 @@
*/
package com.vaadin.ui.declarative.converters;

import java.util.Collections;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;

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

/**
* Converter for {@link ShortcutActions}.
@@ -29,19 +35,88 @@ import com.vaadin.event.ShortcutAction;
public class DesignShortcutActionConverter implements
Converter<String, ShortcutAction> {

/**
* Default instance of the shortcut key mapper.
*/
private final ShortcutKeyMapper keyMapper;

/**
* Constructs the converter with given key mapper.
*
* @param mapper
* Key mapper to use.
*/
public DesignShortcutActionConverter(ShortcutKeyMapper mapper) {
keyMapper = mapper;
private final Map<Integer, String> keyCodeMap;
private final Map<String, Integer> presentationMap;

public DesignShortcutActionConverter() {
HashMap<Integer, String> codes = new HashMap<Integer, String>();
// map modifiers
codes.put(ModifierKey.ALT, "alt");
codes.put(ModifierKey.CTRL, "ctrl");
codes.put(ModifierKey.META, "meta");
codes.put(ModifierKey.SHIFT, "shift");
// map keys
codes.put(KeyCode.ENTER, "enter");
codes.put(KeyCode.ESCAPE, "escape");
codes.put(KeyCode.PAGE_UP, "pageup");
codes.put(KeyCode.PAGE_DOWN, "pagedown");
codes.put(KeyCode.TAB, "tab");
codes.put(KeyCode.ARROW_LEFT, "left");
codes.put(KeyCode.ARROW_UP, "up");
codes.put(KeyCode.ARROW_RIGHT, "right");
codes.put(KeyCode.ARROW_DOWN, "down");
codes.put(KeyCode.BACKSPACE, "backspace");
codes.put(KeyCode.DELETE, "delete");
codes.put(KeyCode.INSERT, "insert");
codes.put(KeyCode.END, "end");
codes.put(KeyCode.HOME, "home");
codes.put(KeyCode.F1, "f1");
codes.put(KeyCode.F2, "f2");
codes.put(KeyCode.F3, "f3");
codes.put(KeyCode.F4, "f4");
codes.put(KeyCode.F5, "f5");
codes.put(KeyCode.F6, "f6");
codes.put(KeyCode.F7, "f7");
codes.put(KeyCode.F8, "f8");
codes.put(KeyCode.F9, "f9");
codes.put(KeyCode.F10, "f10");
codes.put(KeyCode.F11, "f11");
codes.put(KeyCode.F12, "f12");
codes.put(KeyCode.NUM0, "0");
codes.put(KeyCode.NUM1, "1");
codes.put(KeyCode.NUM2, "2");
codes.put(KeyCode.NUM3, "3");
codes.put(KeyCode.NUM4, "4");
codes.put(KeyCode.NUM5, "5");
codes.put(KeyCode.NUM6, "6");
codes.put(KeyCode.NUM7, "7");
codes.put(KeyCode.NUM8, "8");
codes.put(KeyCode.NUM9, "9");
codes.put(KeyCode.SPACEBAR, "spacebar");
codes.put(KeyCode.A, "a");
codes.put(KeyCode.B, "b");
codes.put(KeyCode.C, "c");
codes.put(KeyCode.D, "d");
codes.put(KeyCode.E, "e");
codes.put(KeyCode.F, "f");
codes.put(KeyCode.G, "g");
codes.put(KeyCode.H, "h");
codes.put(KeyCode.I, "i");
codes.put(KeyCode.J, "j");
codes.put(KeyCode.K, "k");
codes.put(KeyCode.L, "l");
codes.put(KeyCode.M, "m");
codes.put(KeyCode.N, "n");
codes.put(KeyCode.O, "o");
codes.put(KeyCode.P, "p");
codes.put(KeyCode.Q, "q");
codes.put(KeyCode.R, "r");
codes.put(KeyCode.S, "s");
codes.put(KeyCode.T, "t");
codes.put(KeyCode.U, "u");
codes.put(KeyCode.V, "v");
codes.put(KeyCode.X, "x");
codes.put(KeyCode.Y, "y");
codes.put(KeyCode.Z, "z");

keyCodeMap = Collections.unmodifiableMap(codes);

HashMap<String, Integer> presentations = new HashMap<String, Integer>();
for (Entry<Integer, String> entry : keyCodeMap.entrySet()) {
presentations.put(entry.getValue(), entry.getKey());
}

presentationMap = Collections.unmodifiableMap(presentations);
}

@Override
@@ -56,7 +131,7 @@ public class DesignShortcutActionConverter implements
String[] parts = data[0].split("-");
// handle keycode
String keyCodePart = parts[parts.length - 1];
int keyCode = getKeyMapper().getKeycodeForString(keyCodePart);
int keyCode = getKeycodeForString(keyCodePart);
if (keyCode < 0) {
throw new IllegalArgumentException("Invalid shortcut definition "
+ value);
@@ -67,7 +142,7 @@ public class DesignShortcutActionConverter implements
modifiers = new int[parts.length - 1];
}
for (int i = 0; i < parts.length - 1; i++) {
int modifier = getKeyMapper().getKeycodeForString(parts[i]);
int modifier = getKeycodeForString(parts[i]);
if (modifier > 0) {
modifiers[i] = modifier;
} else {
@@ -87,12 +162,11 @@ public class DesignShortcutActionConverter implements
// handle modifiers
if (value.getModifiers() != null) {
for (int modifier : value.getModifiers()) {
sb.append(getKeyMapper().getStringForKeycode(modifier)).append(
"-");
sb.append(getStringForKeycode(modifier)).append("-");
}
}
// handle keycode
sb.append(getKeyMapper().getStringForKeycode(value.getKeyCode()));
sb.append(getStringForKeycode(value.getKeyCode()));
if (value.getCaption() != null) {
sb.append(" ").append(value.getCaption());
}
@@ -109,13 +183,13 @@ public class DesignShortcutActionConverter implements
return String.class;
}

/**
* Returns the currently used key mapper.
*
* @return Key mapper.
*/
public ShortcutKeyMapper getKeyMapper() {
return keyMapper;
public int getKeycodeForString(String attributePresentation) {
Integer code = presentationMap.get(attributePresentation);
return code != null ? code.intValue() : -1;
}
public String getStringForKeycode(int keyCode) {
return keyCodeMap.get(keyCode);
}

}

+ 65
- 0
server/src/com/vaadin/ui/declarative/converters/DesignTimeZoneConverter.java View File

@@ -0,0 +1,65 @@
/*
* Copyright 2000-2014 Vaadin Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.vaadin.ui.declarative.converters;

import java.util.Locale;
import java.util.TimeZone;

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

/**
* Utility class for {@link DesignAttributeHandler} that deals with converting
* various TimeZones to string.
*
* @since 7.4
* @author Vaadin Ltd
*/
public class DesignTimeZoneConverter implements Converter<String, TimeZone> {

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

return TimeZone.getTimeZone(value);
}

@Override
public String convertToPresentation(TimeZone value,
Class<? extends String> targetTimeZone, Locale locale)
throws Converter.ConversionException {
if (value == null) {
return "";
} else {
return value.getID();
}
}

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

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

}

+ 1
- 1
server/tests/src/com/vaadin/tests/server/component/abstracttextfield/WriteDesignTest.java View File

@@ -57,7 +57,7 @@ public class WriteDesignTest extends TestCase {
assertEquals("5", design.attr("maxlength"));
assertEquals("3", design.attr("columns"));
assertEquals("input", design.attr("input-prompt"));
assertEquals("EAGER", design.attr("text-change-event-mode"));
assertEquals("eager", design.attr("text-change-event-mode"));
assertEquals("100", design.attr("text-change-timeout"));
}


Loading…
Cancel
Save