/* * Copyright (c) MuleSoft, Inc. All rights reserved. http://www.mulesoft.com * The software in this package is published under the terms of the CPAL v1.0 * license, a copy of which has been included with this distribution in the * LICENSE.txt file. */ package org.mule.runtime.config.spring.parsers.assembly.configuration; import org.mule.runtime.config.spring.parsers.AbstractMuleBeanDefinitionParser; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Properties; import java.util.Set; import org.springframework.util.StringUtils; /** * A direct implementation of {@link PropertyConfiguration} */ public class SimplePropertyConfiguration implements PropertyConfiguration { private List<String> references = new ArrayList<String>(); private Properties nameMappings = new Properties(); private Map<String, NamedValueMap> valueMappings = new HashMap<String, NamedValueMap>(); private Set<String> collections = new HashSet<String>(); private Map<String, Boolean> ignored = new HashMap<String, Boolean>(); private boolean ignoreAll = false; @Override public void addReference(String propertyName) { references.add(dropRef(propertyName)); } @Override public void addMapping(String propertyName, Map<String, Object> mappings) { valueMappings.put(propertyName, new NamedValueMap(propertyName, mappings)); } @Override public void addMapping(String propertyName, String mappings) { valueMappings.put(propertyName, new NamedValueMap(propertyName, mappings)); } @Override public void addMapping(String propertyName, ValueMap mappings) { valueMappings.put(propertyName, new NamedValueMap(propertyName, mappings)); } @Override public void addAlias(String alias, String propertyName) { nameMappings.put(alias, propertyName); } @Override public void addCollection(String propertyName) { collections.add(dropRef(propertyName)); } @Override public void addIgnored(String propertyName) { ignored.put(dropRef(propertyName), Boolean.TRUE); } @Override public void removeIgnored(String propertyName) { ignored.put(dropRef(propertyName), Boolean.FALSE); } @Override public void setIgnoredDefault(boolean ignoreAll) { this.ignoreAll = ignoreAll; } @Override public String getAttributeMapping(String alias) { return getAttributeMapping(alias, alias); } @Override public String getAttributeAlias(String name) { for (Iterator<?> iterator = nameMappings.entrySet().iterator(); iterator.hasNext();) { Map.Entry<?, ?> entry = (Map.Entry<?, ?>) iterator.next(); if (entry.getValue().equals(name)) { return entry.getKey().toString(); } } return name; } public String getAttributeMapping(String alias, String deflt) { return nameMappings.getProperty(alias, deflt); } @Override public boolean isCollection(String propertyName) { return collections.contains(dropRef(propertyName)); } @Override public boolean isIgnored(String propertyName) { String name = dropRef(propertyName); if (ignored.containsKey(name)) { return ignored.get(name).booleanValue(); } else { return ignoreAll; } } /** * A property can be explicitly registered as a bean reference via registerBeanReference() or it can simply use the "-ref" * suffix. * * @param attributeName true if the name appears to correspond to a reference */ @Override public boolean isReference(String attributeName) { return (references.contains(dropRef(attributeName)) || attributeName.endsWith(AbstractMuleBeanDefinitionParser.ATTRIBUTE_REF_SUFFIX) || attributeName.endsWith(AbstractMuleBeanDefinitionParser.ATTRIBUTE_REFS_SUFFIX) || attributeName.equals(AbstractMuleBeanDefinitionParser.ATTRIBUTE_REF)); } @Override public SingleProperty getSingleProperty(String name) { return new SinglePropertyWrapper(name, this); } /** * Extract a JavaBean property name from the supplied attribute name. * <p> * The default implementation uses the {@link org.springframework.core.Conventions#attributeNameToPropertyName(String)} method * to perform the extraction. * <p> * The name returned must obey the standard JavaBean property name conventions. For example for a class with a setter method * '<code>setBingoHallFavourite(String)</code>', the name returned had better be '<code>bingoHallFavourite</code>' (with that * exact casing). * * @param oldName the attribute name taken straight from the XML element being parsed; will never be <code>null</code> * @return the extracted JavaBean property name; must never be <code>null</code> */ @Override public String translateName(String oldName) { // Remove the bean reference suffix if any. String name = dropRef(oldName); // Map to the real property name if necessary. name = getAttributeMapping(name); // JavaBeans property convention. name = Conventions.attributeNameToPropertyName(name); if (!StringUtils.hasText(name)) { throw new IllegalStateException("Illegal property name for " + oldName + ": cannot be null or empty."); } return name; } protected String dropRef(String name) { return org.mule.runtime.core.util.StringUtils .chomp(org.mule.runtime.core.util.StringUtils.chomp(name, AbstractMuleBeanDefinitionParser.ATTRIBUTE_REF_SUFFIX), AbstractMuleBeanDefinitionParser.ATTRIBUTE_REFS_SUFFIX); } @Override public Object translateValue(String name, String value) { NamedValueMap vm = valueMappings.get(name); if (vm != null) { return vm.getValue(value); } else { return value; } } public static class NamedValueMap { private String propertyName; private ValueMap valueMap; public NamedValueMap(String propertyName, String mappingsString) { this.propertyName = propertyName; valueMap = new MapValueMap(mappingsString); } public NamedValueMap(String propertyName, Map<String, Object> valueMap) { this.propertyName = propertyName; this.valueMap = new MapValueMap(valueMap); } public NamedValueMap(String propertyName, ValueMap valueMap) { this.propertyName = propertyName; this.valueMap = valueMap; } public String getPropertyName() { return propertyName; } public Object getValue(String key) { return valueMap.rewrite(key); } } public static class MapValueMap implements ValueMap { protected Map<String, Object> map; public MapValueMap(Map<String, Object> map) { this.map = map; } public MapValueMap(String definition) { map = new HashMap<String, Object>(); String[] values = StringUtils.tokenizeToStringArray(definition, ","); for (int i = 0; i < values.length; i++) { String value = values[i]; int x = value.indexOf("="); if (x == -1) { throw new IllegalArgumentException("Mappings string not properly defined: " + definition); } map.put(value.substring(0, x), value.substring(x + 1)); } } @Override public Object rewrite(String value) { Object result = map.get(value); if (null == result) { return value; } else { return result.toString(); } } } public static class IndentityMapValueMap extends MapValueMap { public IndentityMapValueMap(Map<String, Object> map) { super(map); } @Override public Object rewrite(String value) { Object result = map.get(value); return result; } } }