* Removed shortcut interface * Moved TimeZone converter to a separate class * Moved Enum converter to a separate class Change-Id: I2b959e3a002e6319912212df4a62a3bd05677f80tags/7.4.0.rc1
@@ -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) { |
@@ -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; | |||
} | |||
} |
@@ -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); | |||
} | |||
} |
@@ -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; | |||
} | |||
} |
@@ -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")); | |||
} | |||