001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *     http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017
018package org.apache.commons.configuration2;
019
020import java.util.Iterator;
021import java.util.List;
022import java.util.Map;
023import java.util.Properties;
024
025import org.apache.commons.configuration2.convert.ListDelimiterHandler;
026import org.apache.commons.lang3.StringUtils;
027
028/**
029 * Configuration converter. Helper class to convert between Configuration, ExtendedProperties and standard Properties.
030 */
031public final class ConfigurationConverter {
032    /** Constant for the default separator for properties with multiple values. */
033    private static final char DEFAULT_SEPARATOR = ',';
034
035    /**
036     * Convert a standard Properties class into a configuration class.
037     *
038     * @param props properties object to convert
039     * @return Configuration configuration created from the Properties
040     */
041    public static Configuration getConfiguration(final Properties props) {
042        return new MapConfiguration(props);
043    }
044
045    /**
046     * Convert a Configuration class into a Map class.
047     *
048     * @param config Configuration object to convert
049     * @return Map created from the Configuration
050     */
051    public static Map<Object, Object> getMap(final Configuration config) {
052        return new ConfigurationMap(config);
053    }
054
055    /**
056     * Convert a Configuration class into a Properties class. List properties are joined into a string using either the list
057     * delimiter handler of the configuration (if it extends AbstractConfiguration) or with a comma as delimiter otherwise.
058     * This version of the method exists only for backwards compatibility reason.
059     *
060     * @param config Configuration object to convert
061     * @return Properties created from the Configuration
062     */
063    public static Properties getProperties(final Configuration config) {
064        return getProperties((ImmutableConfiguration) config);
065    }
066
067    /**
068     * Convert a Configuration class into a Properties class. List properties are joined into a string using either the list
069     * delimiter handler of the configuration (if it extends AbstractConfiguration) or with a comma as delimiter otherwise.
070     *
071     * @param config ImmutableConfiguration object to convert
072     * @return Properties created from the Configuration
073     * @since 2.2
074     */
075    public static Properties getProperties(final ImmutableConfiguration config) {
076        final Properties props = new Properties();
077        final ListDelimiterHandler listHandler;
078        boolean useDelimiterHandler;
079
080        if (config instanceof AbstractConfiguration) {
081            listHandler = ((AbstractConfiguration) config).getListDelimiterHandler();
082            useDelimiterHandler = true;
083        } else {
084            listHandler = null;
085            useDelimiterHandler = false;
086        }
087
088        for (final Iterator<String> keys = config.getKeys(); keys.hasNext();) {
089            final String key = keys.next();
090            final List<Object> list = config.getList(key);
091
092            String propValue;
093            if (useDelimiterHandler) {
094                try {
095                    propValue = String.valueOf(listHandler.escapeList(list, ListDelimiterHandler.NOOP_TRANSFORMER));
096                } catch (final Exception ex) {
097                    // obviously, the list handler does not support splitting
098                    useDelimiterHandler = false;
099                    propValue = listToString(list);
100                }
101            } else {
102                propValue = listToString(list);
103            }
104
105            props.setProperty(key, propValue);
106        }
107
108        return props;
109    }
110
111    /**
112     * Helper method for joining all elements of a list to a string using the default value separator.
113     *
114     * @param list the list
115     * @return the resulting string
116     */
117    private static String listToString(final List<?> list) {
118        return StringUtils.join(list, DEFAULT_SEPARATOR);
119    }
120
121    /**
122     * Private constructor prevents instances from being created.
123     */
124    private ConfigurationConverter() {
125        // to prevent instantiation
126    }
127}