TAMAYA-274 Some minor additions. TAMAYA-353 Some minor additions.
Project: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/commit/19ba2a4c Tree: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/tree/19ba2a4c Diff: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/diff/19ba2a4c Branch: refs/heads/master Commit: 19ba2a4c43772b0af350e24f1145a94a855c23a4 Parents: 1fbe9a1 Author: Anatole Tresch <[email protected]> Authored: Mon Nov 5 00:16:15 2018 +0100 Committer: Anatole Tresch <[email protected]> Committed: Mon Nov 5 00:16:15 2018 +0100 ---------------------------------------------------------------------- .../tamaya/collections/CollectionConverter.java | 120 +++++++++++++------ .../tamaya/collections/ItemTokenizer.java | 10 +- 2 files changed, 91 insertions(+), 39 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/19ba2a4c/collections/src/main/java/org/apache/tamaya/collections/CollectionConverter.java ---------------------------------------------------------------------- diff --git a/collections/src/main/java/org/apache/tamaya/collections/CollectionConverter.java b/collections/src/main/java/org/apache/tamaya/collections/CollectionConverter.java index 215d128..2cadd6e 100644 --- a/collections/src/main/java/org/apache/tamaya/collections/CollectionConverter.java +++ b/collections/src/main/java/org/apache/tamaya/collections/CollectionConverter.java @@ -18,7 +18,6 @@ */ package org.apache.tamaya.collections; -import org.apache.tamaya.Configuration; import org.apache.tamaya.TypeLiteral; import org.apache.tamaya.spi.PropertyConverter; import org.apache.tamaya.spi.ConversionContext; @@ -35,6 +34,7 @@ import java.util.logging.Logger; public final class CollectionConverter implements PropertyConverter<Collection> { private static final Logger LOG = Logger.getLogger(CollectionConverter.class.getName()); + public static final String VALUE_MAPPING = "collection-mapping"; private enum MappingType{ /** The list values are identiified by parsing the node value(s) into items. @@ -48,7 +48,13 @@ public final class CollectionConverter implements PropertyConverter<Collection> node, /** The list values are identiified by using the node's child value(s) as items. Hereby * the items of all values are combined. */ - node_all + node_all, + /** This will guess the matching evaluation policy (value,bode) for each {@code PropertyValue} and + * combine the items of all values. */ + combine, + /** This will guess the matching evaluation policy (value,bode) on the most significant {@code PropertyValue} + * only. */ + override, } private MappingType mappingType = MappingType.value_all; @@ -56,13 +62,15 @@ public final class CollectionConverter implements PropertyConverter<Collection> public static <T extends Collection> T convertList(ConversionContext context, Supplier<T> collectionSupplier) { MappingType mappingType = MappingType.valueOf((String)context.getMeta() - .getOrDefault("mapping", "value_all")); + .getOrDefault(VALUE_MAPPING, MappingType.combine.toString())); TypeLiteral<?> targetType = context.getTargetType(); Type[] types = TypeLiteral.getTypeParameters(targetType.getType()); TypeLiteral<?> collectionTargetType; if(types.length>0) { collectionTargetType = TypeLiteral.of(types[0]); }else { + LOG.warning(String.format("No type information for Collection item type in '{0}', using String.", + context.getKey())); collectionTargetType = TypeLiteral.of(String.class); } T result = collectionSupplier.get(); @@ -76,13 +84,71 @@ public final class CollectionConverter implements PropertyConverter<Collection> case value: return convertListByValues(context.getValues(), context, collectionTargetType, result, false); - default: case value_all: return convertListByValues(context.getValues(), context, collectionTargetType, result, true); + case override: + return convertListWithBestGuess(context.getValues(), context, + collectionTargetType, result,false); + case combine: + default: + return convertListWithBestGuess(context.getValues(), context, + collectionTargetType, result,true); } } + private static <T extends Collection> T convertListWithBestGuess(List<PropertyValue> values, + ConversionContext context, + TypeLiteral<?> targetType, + T result, + boolean combine) { + if(!combine){ + values = Collections.singletonList(values.get(0)); + LOG.finest(String.format("Combine deactivated, only checking for collection values in {0}.", values.get(0))); + }else{ + LOG.finest(String.format("Combine activated, checking for collection values in {0}.", values)); + } + // First: try value based approach + for (PropertyValue val : values) { + int valuesFound = 0; + List<String> tokenList = ItemTokenizer.split(val.getValue(), context); + for (String token : tokenList) { + Object o = ItemTokenizer.convertValue(token, targetType, context); + if (o != null) { + valuesFound++; + result.add(o); + } + } + if(valuesFound==0) { + LOG.finest(() -> String.format("No values found in {0} using value evaluation, checking for child nodes...", val)); + for(PropertyValue itemNode:val) { + String textValue = itemNode.getValue(); + if(textValue!=null) { + if (targetType.equals(TypeLiteral.of(String.class))) { + valuesFound++; + result.add(textValue); + } else { + Object o = ItemTokenizer.convertValue(itemNode.getValue(), targetType, context); + if (o != null) { + valuesFound++; + result.add(o); + } + } + } + } + } + if(valuesFound==0){ + LOG.warning(String.format("Failed to convert key '{0}' to type: {1}: no values found.", + val.getKey(), targetType)); + }else{ + LOG.finest(String.format("Found {2} collection values for key '{0}' with type: {1}: no values found.", + val.getKey(), targetType, valuesFound)); + } + } + + return result; + } + private static <T extends Collection> T convertListByValues(List<PropertyValue> values, ConversionContext context, TypeLiteral<?> targetType, @@ -90,6 +156,9 @@ public final class CollectionConverter implements PropertyConverter<Collection> boolean combine) { if(!combine){ values = Collections.singletonList(values.get(0)); + LOG.finest(String.format("Combine deactivated, only checking for collection values in {0}.", values.get(0))); + }else{ + LOG.finest(String.format("Combine activated, checking for collection values in {0}.", values)); } for (PropertyValue val : values) { List<String> tokenList = ItemTokenizer.split(val.getValue(), context); @@ -140,6 +209,8 @@ public final class CollectionConverter implements PropertyConverter<Collection> if (types.length > 1) { collectionTargetType = TypeLiteral.of(types[1]); } else { + LOG.warning(String.format("No type information for Map parameter types in '{0}', using String.", + context.getKey())); collectionTargetType = TypeLiteral.of(String.class); } MappingType mappingType = MappingType.valueOf((String) context.getMeta() @@ -170,6 +241,9 @@ public final class CollectionConverter implements PropertyConverter<Collection> boolean combine) { if(!combine){ values = Collections.singletonList(values.get(0)); + LOG.finest(String.format("Combine deactivated, only checking for collection values in {0}.", values.get(0))); + }else{ + LOG.finest(String.format("Combine activated, checking for collection values in {0}.", values)); } for (PropertyValue val : values) { List<String> tokenList = ItemTokenizer.split(val.getValue(), context); @@ -194,6 +268,9 @@ public final class CollectionConverter implements PropertyConverter<Collection> boolean combine) { if(!combine){ values = Collections.singletonList(values.get(0)); + LOG.finest(String.format("Combine deactivated, only checking for collection values in {0}.", values.get(0))); + }else{ + LOG.finest(String.format("Combine activated, checking for collection values in {0}.", values)); } for (PropertyValue val : values) { for(PropertyValue itemNode:val) { @@ -210,40 +287,11 @@ public final class CollectionConverter implements PropertyConverter<Collection> } - public static ArrayList<String> convertSimpleList(String value, ConversionContext context) { - List<String> rawList = ItemTokenizer.split(value, context); - ArrayList<String> mlist = new ArrayList<>(); - for(String raw:rawList){ - String convValue = raw; - if (convValue != null) { - mlist.add(convValue); - } - } - return mlist; - } - - public static Map<String,String> convertSimpleMap(String value, ConversionContext context) { - List<String> rawList = ItemTokenizer.split(value, context); - HashMap<String,String> result = new HashMap(rawList.size()); - for(String raw:rawList){ - String[] items = ItemTokenizer.splitMapEntry(raw, context); - if(items.length==1){ - result.put(items[0], items[0]); - }else{ - result.put(items[0], items[1]); - } - } - return result; - } - @Override public Collection convert(String value, ConversionContext context) { - String collectionType = "List"; - if(context!=null) { - collectionType = (String)context.getMeta().getOrDefault("collection-type", "List"); - if (collectionType.startsWith("java.util.")) { - collectionType = collectionType.substring("java.util.".length()); - } + String collectionType = (String)context.getMeta().getOrDefault("collection-type", "List"); + if (collectionType.startsWith("java.util.")) { + collectionType = collectionType.substring("java.util.".length()); } Collection result = null; switch (collectionType) { http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/19ba2a4c/collections/src/main/java/org/apache/tamaya/collections/ItemTokenizer.java ---------------------------------------------------------------------- diff --git a/collections/src/main/java/org/apache/tamaya/collections/ItemTokenizer.java b/collections/src/main/java/org/apache/tamaya/collections/ItemTokenizer.java index 7cd043b..7b4b61e 100644 --- a/collections/src/main/java/org/apache/tamaya/collections/ItemTokenizer.java +++ b/collections/src/main/java/org/apache/tamaya/collections/ItemTokenizer.java @@ -34,6 +34,10 @@ final class ItemTokenizer { private static final Logger LOG = Logger.getLogger(ItemTokenizer.class.getName()); + public static final String ITEM_SEPARATOR = "item-separator"; + public static final String MAP_ENTRY_SEPARATOR = "map-entry-separator"; + public static final String ITEM_CONVERTER = "item-converter"; + /** * Private singleton. */ @@ -47,7 +51,7 @@ final class ItemTokenizer { * @return the tokenized createValue as createList, in order of occurrence. */ public static List<String> split(String value, ConversionContext ctx){ - String itemSeparator = (String)ctx.getMeta().getOrDefault("item-separator", ","); + String itemSeparator = (String)ctx.getMeta().getOrDefault(ITEM_SEPARATOR, ","); return split(value, itemSeparator); } @@ -84,7 +88,7 @@ final class ItemTokenizer { * @return an array of length 2, with the trimmed and parsed key/createValue pair. */ public static String[] splitMapEntry(String mapEntry, ConversionContext ctx){ - String entrySeparator = (String)ctx.getMeta().getOrDefault("map-entry-separator", "="); + String entrySeparator = (String)ctx.getMeta().getOrDefault(MAP_ENTRY_SEPARATOR, "="); return splitMapEntry(mapEntry, entrySeparator); } @@ -125,7 +129,7 @@ final class ItemTokenizer { * @return the parsed createValue, or null. */ public static <T> T convertValue(String value, TypeLiteral<T> targetType, ConversionContext context) { - String converterClass = context.getMeta().get("item-converter"); + String converterClass = context.getMeta().get(ITEM_CONVERTER); List<PropertyConverter<T>> valueConverters = new ArrayList<>(1); if (converterClass != null) { try {
