001/**
002 * Copyright 2010-2014 The Kuali Foundation
003 *
004 * Licensed under the Educational Community License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.opensource.org/licenses/ecl2.php
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package org.kuali.common.util.base.string;
017
018import static com.google.common.base.Preconditions.checkArgument;
019import static com.google.common.collect.Sets.newHashSet;
020import static org.kuali.common.util.base.Precondition.checkNotBlank;
021import static org.kuali.common.util.base.Precondition.checkNotNull;
022
023import java.util.List;
024import java.util.Set;
025
026import com.google.common.base.Function;
027import com.google.common.base.Splitter;
028import com.google.common.collect.ImmutableSet;
029
030/**
031 * <p>
032 * Convert a set of delimited strings into an immutable set of individual elements.
033 * </p>
034 * 
035 * A set containing these two strings:
036 * 
037 * <pre>
038 * java.class.path
039 * java.class.version
040 * </pre>
041 * 
042 * Converts to a set containing these four strings:
043 * 
044 * <pre>
045 * java
046 * java.class
047 * java.class.path
048 * java.class.version
049 * </pre>
050 */
051public final class SplitterFunction implements Function<Set<String>, Set<String>> {
052
053        public SplitterFunction() {
054                this(".");
055        }
056
057        public SplitterFunction(String separator) {
058                this.separator = checkNotNull(separator, "separator");
059                this.splitter = Splitter.on(separator);
060        }
061
062        private final Splitter splitter;
063        private final String separator;
064
065        /**
066         * <p>
067         * Convert a set of delimited strings into an immutable set of individual elements.
068         * </p>
069         * 
070         * A set containing these two strings:
071         * 
072         * <pre>
073         * java.class.path
074         * java.class.version
075         * </pre>
076         * 
077         * Converts to a set containing these four strings:
078         * 
079         * <pre>
080         * java
081         * java.class
082         * java.class.path
083         * java.class.version
084         * </pre>
085         * 
086         * @throws IllegalArgumentException
087         *             If splitting the individual strings into elements produces blank tokens
088         * @throws NullPointerException
089         *             If strings is null or contains null elements
090         */
091        @Override
092        public Set<String> apply(Set<String> strings) {
093                checkNotNull(strings, "strings");
094                Set<String> set = newHashSet();
095                for (String string : strings) {
096                        set.addAll(apply(string));
097                }
098                return ImmutableSet.copyOf(set);
099        }
100
101        /**
102         * Convert a delimited string into a set of individual elements.
103         * 
104         * <pre>
105         * java.class.path -> java
106         *                    java.class
107         *                    java.class.path
108         * </pre>
109         * 
110         * @throws IllegalArgumentException
111         *             If splitting the string into elements produces blank tokens
112         */
113        protected Set<String> apply(String string) {
114                checkNotNull(string, "string");
115
116                // Split the key into tokens
117                List<String> tokens = splitter.splitToList(string);
118
119                // Setup some storage for the strings we are creating
120                Set<String> strings = newHashSet();
121
122                // Allocate a string builder
123                StringBuilder sb = new StringBuilder();
124
125                // Iterate over the tokens to create unique string elements
126                for (int i = 0; i < tokens.size(); i++) {
127
128                        // append the separator unless this is the first loop iteration
129                        sb = (i != 0) ? sb.append(separator) : sb;
130
131                        // Extract the token, checking to make sure it isn't blank
132                        String token = checkNotBlank(tokens.get(i), "token");
133
134                        // Append the current token to create a new element
135                        String element = sb.append(token).toString();
136
137                        // Make sure it was actually added
138                        // TODO Don't think checkArgument() here is necessary since checkNotBlank() prevents token from being the empty string
139                        checkArgument(strings.add(element), "%s is a duplicate token -> [%s]", element, string);
140                }
141
142                // Return what we've got
143                return strings;
144        }
145
146        public String getSeparator() {
147                return separator;
148        }
149
150        public Splitter getSplitter() {
151                return splitter;
152        }
153
154}