001/* 002 * The contents of this file are subject to the terms of the Common Development and 003 * Distribution License (the License). You may not use this file except in compliance with the 004 * License. 005 * 006 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the 007 * specific language governing permission and limitations under the License. 008 * 009 * When distributing Covered Software, include this CDDL Header Notice in each file and include 010 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL 011 * Header, with the fields enclosed by brackets [] replaced by your own identifying 012 * information: "Portions Copyright [year] [name of copyright owner]". 013 * 014 * Copyright 2009 Sun Microsystems Inc. 015 * Portions Copyright 2010-2011 ApexIdentity Inc. 016 * Portions Copyright 2011-2015 ForgeRock AS. 017 */ 018 019package org.forgerock.openig.util; 020 021import java.io.BufferedReader; 022import java.io.IOException; 023import java.io.InputStream; 024import java.io.InputStreamReader; 025import java.nio.charset.Charset; 026import java.text.Normalizer; 027import java.util.Arrays; 028import java.util.Iterator; 029 030/** 031 * Miscellaneous string utility methods. 032 */ 033public final class StringUtil { 034 035 /** Platform specific end of line character. */ 036 private static final String EOL = System.getProperty("line.separator"); 037 038 /** 039 * Static methods only. 040 */ 041 private StringUtil() { } 042 043 /** 044 * Joins a collection of elements into a single string value, with a specified separator. 045 * 046 * @param separator the separator to place between joined elements. 047 * @param elements the collection of strings to be joined. 048 * @return the string containing the joined elements. 049 */ 050 public static String join(String separator, Iterable<?> elements) { 051 StringBuilder sb = new StringBuilder(); 052 for (Iterator<?> i = elements.iterator(); i.hasNext();) { 053 sb.append(i.next()); 054 if (i.hasNext() && separator != null) { 055 sb.append(separator); 056 } 057 } 058 return sb.toString(); 059 } 060 061 /** 062 * Joins an array of strings into a single string value, with a specified separator. 063 * 064 * @param separator the separator to place between joined elements. 065 * @param elements the array of strings to be joined. 066 * @return the string containing the joined string array. 067 */ 068 public static String join(String separator, Object... elements) { 069 return join(separator, Arrays.asList(elements)); 070 } 071 072 /** 073 * Reads the provided input stream as a string and then closes the stream. 074 * 075 * @param is 076 * the input stream to be read. 077 * @param charset 078 * the character set encoding of the input stream. 079 * @return the content of the stream. 080 * @throws IOException 081 * If an I/O error occurs. 082 */ 083 public static String asString(final InputStream is, Charset charset) throws IOException { 084 try (BufferedReader reader = new BufferedReader(new InputStreamReader(is, charset))) { 085 final String firstLine = reader.readLine(); 086 if (firstLine == null) { 087 return ""; 088 } 089 final StringBuilder builder = new StringBuilder(firstLine); 090 for (String line = reader.readLine(); line != null; line = reader.readLine()) { 091 builder.append(EOL); 092 builder.append(line); 093 } 094 return builder.toString(); 095 } 096 } 097 098 /** 099 * Appends a final slash on a given value. 100 * 101 * @param value 102 * The given string. 103 * @return A string ending with a slash. 104 */ 105 public static String trailingSlash(String value) { 106 if (value == null 107 || (value != null && value.endsWith("/"))) { 108 return value; 109 } 110 return value.concat("/"); 111 } 112 113 /** 114 * Transform the input String value into a slug: a simpler adaptation that is compatible for usage inside an URI 115 * (without requiring URL encoding). 116 * 117 * <p>Examples: 118 * <pre> 119 * {@code slug("A sentence with blanks, commas and extra punctuation ! ") 120 * .equals("a-sentence-with-blanks-commas-and-extra-punctuation"); 121 * slug("{ClientHandler}/heap/2").equals(clienthandler-heap-2); 122 * } 123 * </pre> 124 * 125 * @param value 126 * value to be transformed 127 * @return A slug version of the input 128 */ 129 public static String slug(String value) { 130 if (value == null) { 131 return null; 132 } 133 // 1. Decompose unicode characters 134 // 2. Remove all combining diacritical marks and also everything that isn't a word, a whitespace character, a 135 // dash or a slash 136 // 3. Replace all occurrences of whitespaces or dashes or slashes with one single whitespace 137 // 4. Trim 138 // 5. Replace all (middle) blanks with a dash 139 return Normalizer.normalize(value.toLowerCase(), Normalizer.Form.NFD) 140 .replaceAll("\\p{InCombiningDiacriticalMarks}|[^\\w\\s\\-/]", "") 141 .replaceAll("[\\s\\-/]+", " ") 142 .trim() 143 .replaceAll("\\s", "-"); 144 } 145 146}