001    package biweekly.util;
002    
003    import java.util.Collection;
004    import java.util.Map;
005    
006    /*
007     Copyright (c) 2013, Michael Angstadt
008     All rights reserved.
009    
010     Redistribution and use in source and binary forms, with or without
011     modification, are permitted provided that the following conditions are met: 
012    
013     1. Redistributions of source code must retain the above copyright notice, this
014     list of conditions and the following disclaimer. 
015     2. Redistributions in binary form must reproduce the above copyright notice,
016     this list of conditions and the following disclaimer in the documentation
017     and/or other materials provided with the distribution. 
018    
019     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
020     ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
021     WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
022     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
023     ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
024     (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
025     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
026     ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
027     (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
028     SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
029     */
030    
031    /**
032     * Contains miscellaneous string utilities.
033     * @author Michael Angstadt
034     */
035    public class StringUtils {
036            /**
037             * Joins a collection of strings into a delimited list.
038             * @param collection the collection of strings
039             * @param delimiter the delimiter (e.g. ",")
040             * @return the final string
041             */
042            public static String join(Collection<String> collection, String delimiter) {
043                    return join(collection, delimiter, new JoinCallback<String>() {
044                            public void handle(StringBuilder sb, String string) {
045                                    sb.append(string);
046                            }
047                    });
048            }
049    
050            /**
051             * Joins a collection of values into a delimited list.
052             * @param collection the collection of values
053             * @param delimiter the delimiter (e.g. ",")
054             * @param join callback function to call on every element in the collection
055             * @return the final string
056             */
057            public static <T> String join(Collection<T> collection, String delimiter, JoinCallback<T> join) {
058                    StringBuilder sb = new StringBuilder();
059    
060                    boolean first = true;
061                    for (T element : collection) {
062                            if (first) {
063                                    first = false;
064                            } else {
065                                    sb.append(delimiter);
066                            }
067                            join.handle(sb, element);
068                    }
069    
070                    return sb.toString();
071            }
072    
073            /**
074             * Joins a map into a delimited list.
075             * @param map the map
076             * @param delimiter the delimiter (e.g. ",")
077             * @param join callback function to call on every element in the collection
078             * @return the final string
079             */
080            public static <K, V> String join(Map<K, V> map, String delimiter, final JoinMapCallback<K, V> join) {
081                    return join(map.entrySet(), delimiter, new JoinCallback<Map.Entry<K, V>>() {
082                            public void handle(StringBuilder sb, Map.Entry<K, V> entry) {
083                                    join.handle(sb, entry.getKey(), entry.getValue());
084                            }
085                    });
086            }
087    
088            /**
089             * Callback interface used with the
090             * {@link StringUtils#join(Collection, String, JoinCallback)} method.
091             * @author Michael Angstadt
092             * @param <T> the value type
093             */
094            public static interface JoinCallback<T> {
095                    void handle(StringBuilder sb, T value);
096            }
097    
098            /**
099             * Callback interface used with the
100             * {@link StringUtils#join(Map, String, JoinMapCallback)} method.
101             * @author Michael Angstadt
102             * @param <K> the key class
103             * @param <V> the value class
104             */
105            public static interface JoinMapCallback<K, V> {
106                    void handle(StringBuilder sb, K key, V value);
107            }
108    }