001/* 002 * Copyright (c) 2012, the Last.fm Java Project and Committers 003 * All rights reserved. 004 * 005 * Redistribution and use of this software in source and binary forms, with or without modification, are 006 * permitted provided that the following conditions are met: 007 * 008 * - Redistributions of source code must retain the above 009 * copyright notice, this list of conditions and the 010 * following disclaimer. 011 * 012 * - Redistributions in binary form must reproduce the above 013 * copyright notice, this list of conditions and the 014 * following disclaimer in the documentation and/or other 015 * materials provided with the distribution. 016 * 017 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED 018 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 019 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 020 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 021 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 022 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 023 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 024 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 025 */ 026package de.umass.util; 027 028import java.io.UnsupportedEncodingException; 029import java.net.URLDecoder; 030import java.net.URLEncoder; 031import java.security.MessageDigest; 032import java.security.NoSuchAlgorithmException; 033import java.util.HashMap; 034import java.util.Map; 035import java.util.regex.Pattern; 036 037/** 038 * Utilitiy class with methods to calculate an md5 hash and to encode URLs. 039 * 040 * @author Janni Kovacs 041 */ 042public final class StringUtilities { 043 044 private static MessageDigest digest; 045 private static Pattern MBID_PATTERN = Pattern 046 .compile("^[0-9a-f]{8}\\-[0-9a-f]{4}\\-[0-9a-f]{4}\\-[0-9a-f]{4}\\-[0-9a-f]{12}$", 047 Pattern.CASE_INSENSITIVE); 048 private static final Pattern MD5_PATTERN = Pattern.compile("[a-fA-F0-9]{32}"); 049 050 static { 051 try { 052 digest = MessageDigest.getInstance("MD5"); 053 } catch (NoSuchAlgorithmException e) { 054 // better never happens 055 } 056 } 057 058 /** 059 * Returns a 32 chararacter hexadecimal representation of an MD5 hash of the given String. 060 * 061 * @param s the String to hash 062 * @return the md5 hash 063 */ 064 public static String md5(String s) { 065 try { 066 byte[] bytes = digest.digest(s.getBytes("UTF-8")); 067 StringBuilder b = new StringBuilder(32); 068 for (byte aByte : bytes) { 069 String hex = Integer.toHexString((int) aByte & 0xFF); 070 if (hex.length() == 1) 071 b.append('0'); 072 b.append(hex); 073 } 074 return b.toString(); 075 } catch (UnsupportedEncodingException e) { 076 // utf-8 always available 077 } 078 return null; 079 } 080 081 /** 082 * URL Encodes the given String <code>s</code> using the UTF-8 character encoding. 083 * 084 * @param s a String 085 * @return url encoded string 086 */ 087 public static String encode(String s) { 088 if(s == null) 089 return null; 090 try { 091 return URLEncoder.encode(s, "UTF-8"); 092 } catch (UnsupportedEncodingException e) { 093 // utf-8 always available 094 } 095 return null; 096 } 097 098 /** 099 * Decodes an URL encoded String <code>s</code> using the UTF-8 character encoding. 100 * 101 * @param s an encoded String 102 * @return the decoded String 103 */ 104 public static String decode(String s) { 105 if(s == null) 106 return null; 107 try { 108 return URLDecoder.decode(s, "UTF-8"); 109 } catch (UnsupportedEncodingException e) { 110 // utf-8 always available 111 } 112 return null; 113 } 114 115 /** 116 * Checks if the supplied String <i>may</i> be a Musicbrainz ID. This method returns <code>true</code> for Strings that are 117 * exactly 36 characters long and match the MBID pattern <code>[0-9a-f]{8}\-[0-9a-f]{4}\-[0-9a-f]{4}\-[0-9a-f]{4}\-[0-9a-f]{12}</code>. 118 * 119 * @param nameOrMbid a possible MBID 120 * @return <code>true</code> if this String <i>may</i> be a MBID 121 */ 122 public static boolean isMbid(String nameOrMbid) { 123 // example: bfcc6d75-a6a5-4bc6-8282-47aec8531818 124 return nameOrMbid != null && nameOrMbid.length() == 36 && MBID_PATTERN.matcher(nameOrMbid).matches(); 125 } 126 127 /** 128 * Creates a Map out of an array with Strings. 129 * 130 * @param strings input strings, key-value alternating 131 * @return a parameter map 132 */ 133 public static Map<String, String> map(String... strings) { 134 if (strings.length % 2 != 0) 135 throw new IllegalArgumentException("strings.length % 2 != 0"); 136 Map<String, String> mp = new HashMap<String, String>(); 137 for (int i = 0; i < strings.length; i += 2) { 138 mp.put(strings[i], strings[i + 1]); 139 } 140 return mp; 141 } 142 143 /** 144 * Strips all characters from a String, that might be invalid to be used in file names. 145 * By default <tt>: / \ < > | ? " *</tt> are all replaced by <tt>-</tt>. 146 * Note that this is no guarantee that the returned name will be definately valid. 147 * 148 * @param s the String to clean up 149 * @return the cleaned up String 150 */ 151 public static String cleanUp(String s) { 152 return s.replaceAll("[*:/\\\\?|<>\"]", "-"); 153 } 154 155 /** 156 * Tests if the given string <i>might</i> already be a 32-char md5 string. 157 * 158 * @param s String to test 159 * @return <code>true</code> if the given String might be a md5 string 160 */ 161 public static boolean isMD5(String s) { 162 return s.length() == 32 && MD5_PATTERN.matcher(s).matches(); 163 } 164 165 /** 166 * Converts a Last.fm boolean result string to a boolean. 167 * 168 * @param resultString A Last.fm boolean result string. 169 * @return <code>true</code> if the given String represents a true, <code>false</code> otherwise. 170 */ 171 public static boolean convertToBoolean(String resultString) { 172 return "1".equals(resultString); 173 } 174 175 /** 176 * Converts from a boolean to a Last.fm boolean result string. 177 * 178 * @param value A boolean value. 179 * @return A string representing a Last.fm boolean. 180 */ 181 public static String convertFromBoolean(boolean value) { 182 if (value) { 183 return "1"; 184 } else { 185 return "0"; 186 } 187 } 188 189}