This is an automated email from the ASF dual-hosted git repository. davsclaus pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/camel.git
commit 071fdb31c0de3674f7b17bf9e6737429ae75a41d Author: Claus Ibsen <claus.ib...@gmail.com> AuthorDate: Sun Jun 16 09:27:11 2019 +0200 CAMEL-13650: Properties component - loadProperties to return properties in order --- .../properties/DefaultPropertiesResolver.java | 12 +-- .../component/properties/OrderedProperties.java | 95 ++++++++++++++++++++++ .../component/properties/PropertiesComponent.java | 6 +- .../PropertiesComponentLoadPropertiesTest.java | 18 ++++ 4 files changed, 122 insertions(+), 9 deletions(-) diff --git a/components/camel-properties/src/main/java/org/apache/camel/component/properties/DefaultPropertiesResolver.java b/components/camel-properties/src/main/java/org/apache/camel/component/properties/DefaultPropertiesResolver.java index 7ac047f..f110cab 100644 --- a/components/camel-properties/src/main/java/org/apache/camel/component/properties/DefaultPropertiesResolver.java +++ b/components/camel-properties/src/main/java/org/apache/camel/component/properties/DefaultPropertiesResolver.java @@ -47,7 +47,7 @@ public class DefaultPropertiesResolver implements PropertiesResolver { } public Properties resolveProperties(CamelContext context, boolean ignoreMissingLocation, List<PropertiesLocation> locations) { - Properties answer = new Properties(); + Properties answer = new OrderedProperties(); Properties prop; for (PropertiesLocation location : locations) { @@ -76,7 +76,7 @@ public class DefaultPropertiesResolver implements PropertiesResolver { } protected Properties loadPropertiesFromFilePath(CamelContext context, boolean ignoreMissingLocation, PropertiesLocation location) { - Properties answer = new Properties(); + Properties answer = new OrderedProperties(); String path = location.getPath(); InputStream is = null; @@ -103,7 +103,7 @@ public class DefaultPropertiesResolver implements PropertiesResolver { } protected Properties loadPropertiesFromClasspath(CamelContext context, boolean ignoreMissingLocation, PropertiesLocation location) { - Properties answer = new Properties(); + Properties answer = new OrderedProperties(); String path = location.getPath(); InputStream is = context.getClassResolver().loadResourceAsStream(path); @@ -138,13 +138,13 @@ public class DefaultPropertiesResolver implements PropertiesResolver { } catch (Exception ex) { // just look up the Map as a fault back Map map = context.getRegistry().lookupByNameAndType(path, Map.class); - answer = new Properties(); + answer = new OrderedProperties(); answer.putAll(map); } if (answer == null && (!ignoreMissingLocation && !location.isOptional())) { throw RuntimeCamelException.wrapRuntimeCamelException(new FileNotFoundException("Properties " + path + " not found in registry")); } - return answer != null ? answer : new Properties(); + return answer != null ? answer : new OrderedProperties(); } /** @@ -158,7 +158,7 @@ public class DefaultPropertiesResolver implements PropertiesResolver { * @return the prepared properties */ protected Properties prepareLoadedProperties(Properties properties) { - Properties answer = new Properties(); + Properties answer = new OrderedProperties(); for (Map.Entry<Object, Object> entry : properties.entrySet()) { Object key = entry.getKey(); Object value = entry.getValue(); diff --git a/components/camel-properties/src/main/java/org/apache/camel/component/properties/OrderedProperties.java b/components/camel-properties/src/main/java/org/apache/camel/component/properties/OrderedProperties.java new file mode 100644 index 0000000..5356084 --- /dev/null +++ b/components/camel-properties/src/main/java/org/apache/camel/component/properties/OrderedProperties.java @@ -0,0 +1,95 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.camel.component.properties; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Enumeration; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.Map; +import java.util.Properties; +import java.util.Set; +import java.util.Vector; + +/** + * This class is an ordered {@link Properties} where the key/values are stored in the order they are added or loaded. + * <p/> + * Note: This implementation is only intended as implementation detail for the Camel properties component, and has only + * been designed to provide the needed functionality. + */ +public final class OrderedProperties extends Properties { + + // TODO: Move to camel-util + + private final Map<String, String> map = new LinkedHashMap<>(); + + public OrderedProperties() { + } + + @Override + public synchronized Object put(Object key, Object value) { + return map.put(key.toString(), value.toString()); + } + + @Override + public String getProperty(String key) { + return map.get(key); + } + + @Override + public String getProperty(String key, String defaultValue) { + return map.getOrDefault(key, defaultValue); + } + + @Override + public synchronized Enumeration<Object> keys() { + return new Vector<Object>(map.keySet()).elements(); + } + + @Override + public Set<Object> keySet() { + return new LinkedHashSet<>(map.keySet()); + } + + @Override + @SuppressWarnings("unchecked") + public Set<Map.Entry<Object, Object>> entrySet() { + Set entrySet = map.entrySet(); + return (Set<Map.Entry<Object, Object>>) entrySet; + } + + @Override + public synchronized int size() { + return map.size(); + } + + @Override + public Set<String> stringPropertyNames() { + return map.keySet(); + } + + @Override + public Collection<Object> values() { + return new ArrayList<>(map.values()); + } + + @Override + public synchronized String toString() { + return map.toString(); + } +} diff --git a/components/camel-properties/src/main/java/org/apache/camel/component/properties/PropertiesComponent.java b/components/camel-properties/src/main/java/org/apache/camel/component/properties/PropertiesComponent.java index cda1377..61a7716 100644 --- a/components/camel-properties/src/main/java/org/apache/camel/component/properties/PropertiesComponent.java +++ b/components/camel-properties/src/main/java/org/apache/camel/component/properties/PropertiesComponent.java @@ -192,11 +192,11 @@ public class PropertiesComponent extends DefaultComponent implements org.apache. if (locations != null) { return doLoadProperties(Arrays.stream(locations).map(PropertiesLocation::new).collect(Collectors.toList())); } - return new Properties(); + return new OrderedProperties(); } protected Properties doLoadProperties(List<PropertiesLocation> paths) { - Properties prop = new Properties(); + Properties prop = new OrderedProperties(); // use initial properties if (initialProperties != null) { @@ -224,7 +224,7 @@ public class PropertiesComponent extends DefaultComponent implements org.apache. // use override properties if (overrideProperties != null) { // make a copy to avoid affecting the original properties - Properties override = new Properties(); + Properties override = new OrderedProperties(); override.putAll(prop); override.putAll(overrideProperties); prop = override; diff --git a/core/camel-core/src/test/java/org/apache/camel/component/properties/PropertiesComponentLoadPropertiesTest.java b/core/camel-core/src/test/java/org/apache/camel/component/properties/PropertiesComponentLoadPropertiesTest.java index e9ddf40..c1d8c13 100644 --- a/core/camel-core/src/test/java/org/apache/camel/component/properties/PropertiesComponentLoadPropertiesTest.java +++ b/core/camel-core/src/test/java/org/apache/camel/component/properties/PropertiesComponentLoadPropertiesTest.java @@ -16,7 +16,9 @@ */ package org.apache.camel.component.properties; +import java.util.Iterator; import java.util.Properties; +import java.util.Set; import org.apache.camel.CamelContext; import org.apache.camel.ContextTestSupport; @@ -55,6 +57,22 @@ public class PropertiesComponentLoadPropertiesTest extends ContextTestSupport { assertEquals("World", prop.getProperty("hello")); assertEquals("2000", prop.getProperty("millisecs")); + + // should be ordered keys + Iterator it = prop.keySet().iterator(); + assertEquals("hello", it.next()); + assertEquals("camel.component.seda.concurrent-consumers", it.next()); + assertEquals("camel.component.seda.queueSize", it.next()); + assertEquals("camel.component.direct.timeout", it.next()); + assertEquals("millisecs", it.next()); + + // should be ordered values + it = prop.values().iterator(); + assertEquals("World", it.next()); + assertEquals("2", it.next()); + assertEquals("500", it.next()); + assertEquals("1234", it.next()); + assertEquals("2000", it.next()); } @Override