package org.sakaiproject.citation.impl.openurl; import java.io.UnsupportedEncodingException; import java.net.URLDecoder; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; /** * Supporting static utilities for the OpenURL code. * @author buckett * */ public class Utils { /** * Just gets the first value for the key out of the map. * @param params * @param key * @return The value or <code>null</code> if it isn't found or is null. */ public static String getValue(Map<String, String[]> params, String key) { String[] values = params.get(key); if (values != null) { if (values.length > 0) { if (values.length > 1) { // Too many values, dropping one. } return values[0]; } } return null; } /** * This splits the source string up into a map. Similar to the servlet request * parsing but we don't decode it yet, until we know the encoding we should use. * @return Always returns a Map of the values. */ public static Map<String, String[]>split(String source) { Map<String, String[]> values = new HashMap<String,String[]>(); if (source != null) { String[] parts = source.split("&"); for(String part: parts) { String kv[] = part.split("="); if ((kv.length == 2 || kv.length == 1) && kv[0].length() > 1 ) { String key = kv[0]; String value = (kv.length > 1)?kv[1]:null; if (values.containsKey(key)) { // Not very efficient, but not may params have multiple values. List<String> valuesList = new ArrayList<String>(Arrays.asList(values.get(key))); valuesList.add(value); values.put(key, valuesList.toArray(new String[]{})); } else { values.put(key, new String[]{value}); } } } } return values; } /** * Decode all the keys and values based on the encoding. */ public static Map<String, String[]> decode(Map<String, String[]> source, String encoding) { try { Map <String, String[]> decoded = new HashMap<String, String[]>(); for(Map.Entry<String, String[]> entry: source.entrySet()) { String key = URLDecoder.decode(entry.getKey(), encoding); String[] values = new String[entry.getValue().length]; for(int i = 0; i< entry.getValue().length; i++) { values[i] = (entry.getValue()[i] == null)?null:URLDecoder.decode(entry.getValue()[i], encoding); } decoded.put(key, values); } return decoded; } catch (UnsupportedEncodingException uee) { throw new IllegalArgumentException("Unsupported encoding: "+encoding); } } /** * Attempts to extract the author from the multiple fields in an OpenURL and return an author string. * @return Author string, such as John Smith. */ public static String lookForAuthor(Map<String, List<String>> values) { // If we don't have a surname don't event bother StringBuilder author = new StringBuilder(); if (appendFirst(author, values.get("aulast"), null)) { // Check for author in other fields. if (values.containsKey("au")) { for (String otherAuthor: values.get("au")) { if (otherAuthor != null && otherAuthor.toLowerCase().contains(author.toString().toLowerCase())) { // Surname already exist in other au field, assume we don't need this one. return null; } } } // Try to build as much of a name as possible without duplicating parts. if (!appendFirst(author, values.get("aufirst"), ", ")) { if (!appendFirst(author, values.get("auinit"), ", ")) { if (appendFirst(author, values.get("auinit1"), ", ")) { appendFirst(author, values.get("auinitm"), " "); } } } return author.toString(); } return null; } /** * Simple utility function for adding the first value of the list of strings to the buffer. * @param buffer * @param values * @param seperator */ public static boolean appendFirst(StringBuilder buffer, List<String> values, String seperator) { if (values != null && !values.isEmpty()) { String value = values.get(0); if (value != null) { if (seperator != null) { buffer.append(seperator); } buffer.append(value); return true; } } return false; } }