package com.github.rmannibucau.cdi.configuration.xml.handlers; import com.github.rmannibucau.cdi.configuration.factory.SetterFallback; import com.github.rmannibucau.cdi.configuration.model.ConfigBean; import org.xml.sax.Attributes; import java.util.ArrayList; import java.util.Comparator; import java.util.List; import java.util.Map; import java.util.TreeMap; import static com.github.rmannibucau.cdi.configuration.factory.Converter.convertTo; public abstract class CollectionHandler extends NamespaceHandlerSupport { protected static final String ITEM_PREFIX = "item-"; @Override public ConfigBean createBean(final String localName, final Attributes attributes) { final String type = parameterType(attributes.getValue("type")); final ConfigBean bean = new ConfigBean(localName, getRawBeanType(type), attributes.getValue("scope"), attributes.getValue("qualifier"), getFactory().getName(), "create", null, null, false); for (int i = 0; i < attributes.getLength(); i++) { bean.getDirectAttributes().put(attributes.getLocalName(i), attributes.getValue(i)); } bean.getDirectAttributes().put("type", type); // if default value force it to not be null and present addTypeParameters(bean, type); return bean; } protected void addTypeParameters(final ConfigBean bean, final String type) { bean.getTypeParameters().add(type); } protected String getRawBeanType(String componentType) { throw new UnsupportedOperationException(); } protected Class<?> getFactory() { throw new UnsupportedOperationException(); } protected static String parameterType(final String type) { if (type == null) { return String.class.getName(); } return type; } protected static class ItemComparator implements Comparator<String> { private final String prefix; public ItemComparator(final String prefix) { this.prefix = prefix; } public ItemComparator() { this(ITEM_PREFIX); } @Override public int compare(final String o1, final String o2) { int idx1 = Integer.parseInt(o1.substring(prefix.length())); int idx2 = Integer.parseInt(o2.substring(prefix.length())); return idx1 - idx2; } } protected static class ItemsFactory<T> implements SetterFallback { protected Class<T> type; protected final Map<String, String> listValues = new TreeMap<String, String>(new ItemComparator()); protected List<T> doCreate() { final List<T> list = new ArrayList<T>(); for (final String value : listValues.values()) { list.add(type.cast(convertTo(type, value))); } return list; } @Override public void set(final String key, final String value) { if (key.startsWith(ITEM_PREFIX)) { listValues.put(key, value); } else { throw new IllegalArgumentException("Key " + key + " unknown"); } } } }