001 /* 002 * Sonar, open source software quality management tool. 003 * Copyright (C) 2009 SonarSource SA 004 * mailto:contact AT sonarsource DOT com 005 * 006 * Sonar is free software; you can redistribute it and/or 007 * modify it under the terms of the GNU Lesser General Public 008 * License as published by the Free Software Foundation; either 009 * version 3 of the License, or (at your option) any later version. 010 * 011 * Sonar is distributed in the hope that it will be useful, 012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 014 * Lesser General Public License for more details. 015 * 016 * You should have received a copy of the GNU Lesser General Public 017 * License along with Sonar; if not, write to the Free Software 018 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 019 */ 020 package org.sonar.api.utils; 021 022 import com.google.common.collect.Multiset; 023 import org.apache.commons.collections.Bag; 024 import org.apache.commons.lang.StringUtils; 025 import org.apache.commons.lang.math.NumberUtils; 026 027 import java.util.HashMap; 028 import java.util.Map; 029 030 /** 031 * Util class to format key/value data. Output is a string representation ready to be 032 * injected into the database 033 * 034 * @since 1.10 035 */ 036 public final class KeyValueFormat { 037 038 private KeyValueFormat() { 039 } 040 041 public static <KEY, VALUE> Map<KEY, VALUE> parse(String data, Transformer<KEY, VALUE> transformer) { 042 Map<String, String> rawData = parse(data); 043 Map<KEY, VALUE> map = new HashMap<KEY, VALUE>(); 044 for (Map.Entry<String, String> entry : rawData.entrySet()) { 045 KeyValue<KEY, VALUE> keyVal = transformer.transform(entry.getKey(), entry.getValue()); 046 if (keyVal != null) { 047 map.put(keyVal.getKey(), keyVal.getValue()); 048 } 049 } 050 return map; 051 } 052 053 public static Map<String, String> parse(String data) { 054 Map<String, String> map = new HashMap<String, String>(); 055 String[] pairs = StringUtils.split(data, ";"); 056 for (String pair : pairs) { 057 String[] keyValue = StringUtils.split(pair, "="); 058 String key = keyValue[0]; 059 String value = (keyValue.length == 2 ? keyValue[1] : ""); 060 map.put(key, value); 061 } 062 return map; 063 } 064 065 public static <KEY, VALUE> String format(Map<KEY, VALUE> map) { 066 StringBuilder sb = new StringBuilder(); 067 boolean first = true; 068 for (Map.Entry<?, ?> entry : map.entrySet()) { 069 if (!first) { 070 sb.append(";"); 071 } 072 sb.append(entry.getKey().toString()); 073 sb.append("="); 074 if (entry.getValue() != null) { 075 sb.append(entry.getValue()); 076 } 077 first = false; 078 } 079 080 return sb.toString(); 081 } 082 083 /** 084 * Please use Multiset from google collections instead of commons-collections bags. 085 */ 086 public static String format(Bag bag) { 087 return format(bag, 0); 088 } 089 090 /** 091 * Please use Multiset from google collections instead of commons-collections bags. 092 */ 093 public static String format(Bag bag, int var) { 094 StringBuilder sb = new StringBuilder(); 095 boolean first = true; 096 for (Object obj : bag.uniqueSet()) { 097 if (!first) { 098 sb.append(";"); 099 } 100 sb.append(obj.toString()); 101 sb.append("="); 102 sb.append(bag.getCount(obj) + var); 103 first = false; 104 } 105 106 return sb.toString(); 107 } 108 109 public static String format(Multiset<?> set) { 110 StringBuilder sb = new StringBuilder(); 111 boolean first = true; 112 for (Multiset.Entry<?> entry : set.entrySet()) { 113 if (!first) { 114 sb.append(";"); 115 } 116 sb.append(entry.getElement().toString()); 117 sb.append("="); 118 sb.append(entry.getCount()); 119 first = false; 120 } 121 return sb.toString(); 122 } 123 124 public static String format(Object... objects) { 125 StringBuilder sb = new StringBuilder(); 126 boolean first = true; 127 if (objects != null) { 128 for (int i = 0; i < objects.length; i++) { 129 if (!first) { 130 sb.append(";"); 131 } 132 sb.append(objects[i++].toString()); 133 sb.append("="); 134 sb.append(objects[i]); 135 first = false; 136 } 137 } 138 return sb.toString(); 139 } 140 141 public interface Transformer<KEY, VALUE> { 142 143 public KeyValue<KEY, VALUE> transform(String key, String value); 144 } 145 146 public static class StringNumberPairTransformer implements Transformer<String, Double> { 147 148 public KeyValue<String, Double> transform(String key, String value) { 149 return new KeyValue<String, Double>(key, toDouble(value)); 150 } 151 } 152 153 public static class DoubleNumbersPairTransformer implements Transformer<Double, Double> { 154 155 public KeyValue<Double, Double> transform(String key, String value) { 156 return new KeyValue<Double, Double>(toDouble(key), toDouble(value)); 157 } 158 } 159 160 public static class IntegerNumbersPairTransformer implements Transformer<Integer, Integer> { 161 162 public KeyValue<Integer, Integer> transform(String key, String value) { 163 return new KeyValue<Integer, Integer>(toInteger(key), toInteger(value)); 164 } 165 } 166 167 private static Double toDouble(String value) { 168 return StringUtils.isBlank(value) ? null : NumberUtils.toDouble(value); 169 } 170 171 private static Integer toInteger(String value) { 172 return StringUtils.isBlank(value) ? null : NumberUtils.toInt(value); 173 } 174 }