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 */ 017package org.apache.commons.configuration2.convert; 018 019import java.util.Collection; 020import java.util.List; 021 022/** 023 * <p> 024 * Definition of an interface that controls the handling of list delimiters in 025 * configuration properties. 026 * </p> 027 * <p> 028 * {@link org.apache.commons.configuration2.AbstractConfiguration 029 * AbstractConfiguration} supports list delimiters in property values. If such a 030 * delimiter is found, the value actually contains multiple values and has to be 031 * split. This is useful for instance for 032 * {@link org.apache.commons.configuration2.PropertiesConfiguration 033 * PropertiesConfiguration}: properties files that have to be compatible with 034 * the {@code java.util.Properties} class cannot have multiple occurrences of a 035 * single property key, therefore a different storage scheme for multi-valued 036 * properties is needed. A possible storage scheme could look as follows: 037 * </p> 038 * 039 * <pre> 040 * myProperty=value1,value2,value3 041 * </pre> 042 * 043 * <p> 044 * Here a comma is used as list delimiter. When parsing this property (and using 045 * a corresponding {@code ListDelimiterHandler} implementation) the string value 046 * is split, and three values are added for the property key. 047 * </p> 048 * <p> 049 * A {@code ListDelimiterHandler} knows how to parse and to escape property 050 * values. It is called by concrete {@code Configuration} implementations when 051 * they have to deal with properties with multiple values. 052 * </p> 053 * 054 * @version $Id: ListDelimiterHandler.java 1679782 2015-05-16 17:45:33Z oheger $ 055 * @since 2.0 056 */ 057public interface ListDelimiterHandler 058{ 059 /** 060 * A specialized {@code ValueTransformer} implementation which does no 061 * transformation. The {@code transformValue()} method just returns the 062 * passed in object without changes. This instance can be used by 063 * configurations which do not require additional encoding. 064 */ 065 ValueTransformer NOOP_TRANSFORMER = new ValueTransformer() 066 { 067 @Override 068 public Object transformValue(Object value) 069 { 070 return value; 071 } 072 }; 073 074 /** 075 * Parses the specified value for list delimiters and splits it if 076 * necessary. The passed in object can be either a single value or a complex 077 * one, e.g. a collection, an array, or an {@code Iterable}. It is the 078 * responsibility of this method to return an {@code Iterable} which 079 * contains all extracted values. 080 * 081 * @param value the value to be parsed 082 * @return an {@code Iterable} allowing access to all extracted values 083 */ 084 Iterable<?> parse(Object value); 085 086 /** 087 * Splits the specified string at the list delimiter and returns a 088 * collection with all extracted components. A concrete implementation also 089 * has to deal with escape characters which might mask a list delimiter 090 * character at certain positions. The boolean {@code trim} flag determines 091 * whether each extracted component should be trimmed. This typically makes 092 * sense as the list delimiter may be surrounded by whitespace. However, 093 * there may be specific use cases in which automatic trimming is not 094 * desired. 095 * 096 * @param s the string to be split 097 * @param trim a flag whether each component of the string is to be trimmed 098 * @return a collection with all components extracted from the string 099 */ 100 Collection<String> split(String s, boolean trim); 101 102 /** 103 * Escapes the specified single value object. This method is called for 104 * properties containing only a single value. So this method can rely on the 105 * fact that the passed in object is not a list. An implementation has to 106 * check whether the value contains list delimiter characters and - if so - 107 * escape them accordingly. 108 * 109 * @param value the value to be escaped 110 * @param transformer a {@code ValueTransformer} for an additional encoding 111 * (must not be <b>null</b>) 112 * @return the escaped value 113 */ 114 Object escape(Object value, ValueTransformer transformer); 115 116 /** 117 * Escapes all values in the given list and concatenates them to a single 118 * string. This operation is required by configurations that have to 119 * represent properties with multiple values in a single line in their 120 * external configuration representation. This may require an advanced 121 * escaping in some cases. 122 * 123 * @param values the list with all the values to be converted to a single 124 * value 125 * @param transformer a {@code ValueTransformer} for an additional encoding 126 * (must not be <b>null</b>) 127 * @return the resulting escaped value 128 */ 129 Object escapeList(List<?> values, ValueTransformer transformer); 130}