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}