Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.sonar.api.utils.KeyValueFormat Maven / Gradle / Ivy
/*
* SonarQube, open source software quality management tool.
* Copyright (C) 2008-2014 SonarSource
* mailto:contact AT sonarsource DOT com
*
* SonarQube is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* SonarQube is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package org.sonar.api.utils;
import com.google.common.collect.LinkedHashMultiset;
import com.google.common.collect.Maps;
import com.google.common.collect.Multimap;
import com.google.common.collect.Multiset;
import org.apache.commons.collections.Bag;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.math.NumberUtils;
import org.slf4j.LoggerFactory;
import org.sonar.api.rules.RulePriority;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
/**
* Formats and parses key/value pairs with the string representation : "key1=value1;key2=value2". Conversion
* of fields is supported and can be extended.
*
* This format can easily be parsed with Ruby code: hash=Hash[*(my_string.split(';').map { |elt| elt.split('=') }.flatten)]
*
* @since 1.10
*/
public final class KeyValueFormat {
public static final String PAIR_SEPARATOR = ";";
public static final String FIELD_SEPARATOR = "=";
private KeyValueFormat() {
// only static methods
}
public abstract static class Converter {
abstract String format(T type);
abstract T parse(String s);
}
public static final class StringConverter extends Converter {
private static final StringConverter INSTANCE = new StringConverter();
private StringConverter() {
}
@Override
String format(String s) {
return s;
}
@Override
String parse(String s) {
return s;
}
}
public static StringConverter newStringConverter() {
return StringConverter.INSTANCE;
}
public static final class ToStringConverter extends Converter {
private static final ToStringConverter INSTANCE = new ToStringConverter();
private ToStringConverter() {
}
@Override
String format(Object o) {
return o.toString();
}
@Override
String parse(String s) {
throw new IllegalStateException("Can not parse with ToStringConverter: " + s);
}
}
public static ToStringConverter newToStringConverter() {
return ToStringConverter.INSTANCE;
}
public static final class IntegerConverter extends Converter {
private static final IntegerConverter INSTANCE = new IntegerConverter();
private IntegerConverter() {
}
@Override
String format(Integer s) {
return s == null ? "" : String.valueOf(s);
}
@Override
Integer parse(String s) {
return StringUtils.isBlank(s) ? null : NumberUtils.toInt(s);
}
}
public static IntegerConverter newIntegerConverter() {
return IntegerConverter.INSTANCE;
}
public static final class PriorityConverter extends Converter {
private static final PriorityConverter INSTANCE = new PriorityConverter();
private PriorityConverter() {
}
@Override
String format(RulePriority s) {
return s == null ? "" : s.toString();
}
@Override
RulePriority parse(String s) {
return StringUtils.isBlank(s) ? null : RulePriority.valueOf(s);
}
}
public static PriorityConverter newPriorityConverter() {
return PriorityConverter.INSTANCE;
}
public static final class DoubleConverter extends Converter {
private static final DoubleConverter INSTANCE = new DoubleConverter();
private DoubleConverter() {
}
@Override
String format(Double d) {
return d == null ? "" : String.valueOf(d);
}
@Override
Double parse(String s) {
return StringUtils.isBlank(s) ? null : NumberUtils.toDouble(s);
}
}
public static DoubleConverter newDoubleConverter() {
return DoubleConverter.INSTANCE;
}
public static class DateConverter extends Converter {
private SimpleDateFormat dateFormat;
/**
* @deprecated in version 2.13. Replaced by {@link org.sonar.api.utils.KeyValueFormat#newDateConverter()}
*/
@Deprecated
public DateConverter() {
this(DateUtils.DATE_FORMAT);
}
private DateConverter(String format) {
this.dateFormat = new SimpleDateFormat(format);
}
@Override
String format(Date d) {
return d == null ? "" : dateFormat.format(d);
}
@Override
Date parse(String s) {
try {
return StringUtils.isBlank(s) ? null : dateFormat.parse(s);
} catch (ParseException e) {
throw new SonarException("Not a date with format: " + dateFormat.toPattern(), e);
}
}
}
public static DateConverter newDateConverter() {
return new DateConverter(DateUtils.DATE_FORMAT);
}
public static DateConverter newDateTimeConverter() {
return new DateConverter(DateUtils.DATETIME_FORMAT);
}
public static DateConverter newDateConverter(String format) {
return new DateConverter(format);
}
/**
* @deprecated in version 2.13. Replaced by {@link org.sonar.api.utils.KeyValueFormat#newDateTimeConverter()}
*/
@Deprecated
public static class DateTimeConverter extends DateConverter {
public DateTimeConverter() {
super(DateUtils.DATETIME_FORMAT);
}
}
public static Map parse(String data, Converter keyConverter, Converter valueConverter) {
Map map = Maps.newLinkedHashMap();
if (data != null) {
String[] pairs = StringUtils.split(data, PAIR_SEPARATOR);
for (String pair : pairs) {
String[] keyValue = StringUtils.split(pair, FIELD_SEPARATOR);
String key = keyValue[0];
String value = keyValue.length == 2 ? keyValue[1] : "";
map.put(keyConverter.parse(key), valueConverter.parse(value));
}
}
return map;
}
public static Map parse(String data) {
return parse(data, newStringConverter(), newStringConverter());
}
/**
* @since 2.7
*/
public static Map parseStringInt(String data) {
return parse(data, newStringConverter(), newIntegerConverter());
}
/**
* @since 2.7
*/
public static Map parseStringDouble(String data) {
return parse(data, newStringConverter(), newDoubleConverter());
}
/**
* @since 2.7
*/
public static Map parseIntString(String data) {
return parse(data, newIntegerConverter(), newStringConverter());
}
/**
* @since 2.7
*/
public static Map parseIntDouble(String data) {
return parse(data, newIntegerConverter(), newDoubleConverter());
}
/**
* @since 2.7
*/
public static Map parseIntDate(String data) {
return parse(data, newIntegerConverter(), newDateConverter());
}
/**
* @since 2.7
*/
public static Map parseIntInt(String data) {
return parse(data, newIntegerConverter(), newIntegerConverter());
}
/**
* @since 2.7
*/
public static Map parseIntDateTime(String data) {
return parse(data, newIntegerConverter(), newDateTimeConverter());
}
/**
* Value of pairs is the occurrences of the same single key. A multiset is sometimes called a bag.
* For example parsing "foo=2;bar=1" creates a multiset with 3 elements : foo, foo and bar.
*/
/**
* @since 2.7
*/
public static Multiset parseMultiset(String data, Converter keyConverter) {
// to keep the same order
Multiset multiset = LinkedHashMultiset.create();
if (data != null) {
String[] pairs = StringUtils.split(data, PAIR_SEPARATOR);
for (String pair : pairs) {
String[] keyValue = StringUtils.split(pair, FIELD_SEPARATOR);
String key = keyValue[0];
String value = keyValue.length == 2 ? keyValue[1] : "0";
multiset.add(keyConverter.parse(key), new IntegerConverter().parse(value));
}
}
return multiset;
}
/**
* @since 2.7
*/
public static Multiset parseIntegerMultiset(String data) {
return parseMultiset(data, newIntegerConverter());
}
/**
* @since 2.7
*/
public static Multiset parseMultiset(String data) {
return parseMultiset(data, newStringConverter());
}
/**
* Transforms a string with the following format: "key1=value1;key2=value2..."
* into a Map. Requires to implement the transform(key,value) method
*
* @param data the input string
* @param transformer the interface to implement
* @return a Map of
* @deprecated since 2.7
*/
@Deprecated
public static Map parse(String data, Transformer transformer) {
Map rawData = parse(data);
Map map = new HashMap();
for (Map.Entry entry : rawData.entrySet()) {
KeyValue keyVal = transformer.transform(entry.getKey(), entry.getValue());
if (keyVal != null) {
map.put(keyVal.getKey(), keyVal.getValue());
}
}
return map;
}
private static String formatEntries(Collection> entries, Converter keyConverter, Converter valueConverter) {
StringBuilder sb = new StringBuilder();
boolean first = true;
for (Map.Entry entry : entries) {
if (!first) {
sb.append(PAIR_SEPARATOR);
}
sb.append(keyConverter.format(entry.getKey()));
sb.append(FIELD_SEPARATOR);
if (entry.getValue() != null) {
sb.append(valueConverter.format(entry.getValue()));
}
first = false;
}
return sb.toString();
}
private static String formatEntries(Set> entries, Converter keyConverter) {
StringBuilder sb = new StringBuilder();
boolean first = true;
for (Multiset.Entry entry : entries) {
if (!first) {
sb.append(PAIR_SEPARATOR);
}
sb.append(keyConverter.format(entry.getElement()));
sb.append(FIELD_SEPARATOR);
sb.append(new IntegerConverter().format(entry.getCount()));
first = false;
}
return sb.toString();
}
/**
* @since 2.7
*/
public static String format(Map map, Converter keyConverter, Converter valueConverter) {
return formatEntries(map.entrySet(), keyConverter, valueConverter);
}
/**
* @since 2.7
*/
public static String format(Map map) {
return format(map, newToStringConverter(), newToStringConverter());
}
/**
* @since 2.7
*/
public static String formatIntString(Map map) {
return format(map, newIntegerConverter(), newStringConverter());
}
/**
* @since 2.7
*/
public static String formatIntDouble(Map map) {
return format(map, newIntegerConverter(), newDoubleConverter());
}
/**
* @since 2.7
*/
public static String formatIntDate(Map map) {
return format(map, newIntegerConverter(), newDateConverter());
}
/**
* @since 2.7
*/
public static String formatIntDateTime(Map map) {
return format(map, newIntegerConverter(), newDateTimeConverter());
}
/**
* @since 2.7
*/
public static String formatStringInt(Map map) {
return format(map, newStringConverter(), newIntegerConverter());
}
/**
* Limitation: there's currently no methods to parse into Multimap.
*
* @since 2.7
*/
public static String format(Multimap map, Converter keyConverter, Converter valueConverter) {
return formatEntries(map.entries(), keyConverter, valueConverter);
}
/**
* @since 2.7
*/
public static String format(Multiset multiset, Converter keyConverter) {
return formatEntries(multiset.entrySet(), keyConverter);
}
public static String format(Multiset multiset) {
return formatEntries(multiset.entrySet(), newToStringConverter());
}
/**
* @since 1.11
* @deprecated use Multiset from google collections instead of commons-collections bags
*/
@Deprecated
public static String format(Bag bag) {
return format(bag, 0);
}
/**
* @since 1.11
* @deprecated use Multiset from google collections instead of commons-collections bags
*/
@Deprecated
public static String format(Bag bag, int var) {
StringBuilder sb = new StringBuilder();
if (bag != null) {
boolean first = true;
for (Object obj : bag.uniqueSet()) {
if (!first) {
sb.append(PAIR_SEPARATOR);
}
sb.append(obj.toString());
sb.append(FIELD_SEPARATOR);
sb.append(bag.getCount(obj) + var);
first = false;
}
}
return sb.toString();
}
/**
* @deprecated since 2.7. Replaced by Converter
*/
@Deprecated
public interface Transformer {
KeyValue transform(String key, String value);
}
/**
* Implementation of Transformer
*
* @deprecated since 2.7 replaced by Converter
*/
@Deprecated
public static class StringNumberPairTransformer implements Transformer {
public KeyValue transform(String key, String value) {
return new KeyValue(key, toDouble(value));
}
}
/**
* Implementation of Transformer
*
* @deprecated since 2.7. Replaced by Converter
*/
@Deprecated
public static class DoubleNumbersPairTransformer implements Transformer {
public KeyValue transform(String key, String value) {
return new KeyValue(toDouble(key), toDouble(value));
}
}
/**
* Implementation of Transformer
*
* @deprecated since 2.7. Replaced by Converter
*/
@Deprecated
public static class IntegerNumbersPairTransformer implements Transformer {
public KeyValue transform(String key, String value) {
return new KeyValue(toInteger(key), toInteger(value));
}
}
/**
* Implementation of Transformer
*
* @deprecated since 2.7. Replaced by Converter
*/
@Deprecated
public static class RulePriorityNumbersPairTransformer implements Transformer {
public KeyValue transform(String key, String value) {
try {
if (StringUtils.isBlank(value)) {
value = "0";
}
return new KeyValue(RulePriority.valueOf(key.toUpperCase()), Integer.parseInt(value));
} catch (Exception e) {
LoggerFactory.getLogger(RulePriorityNumbersPairTransformer.class).warn("Property " + key + " has invalid value: " + value, e);
return null;
}
}
}
private static Double toDouble(String value) {
return StringUtils.isBlank(value) ? null : NumberUtils.toDouble(value);
}
private static Integer toInteger(String value) {
return StringUtils.isBlank(value) ? null : NumberUtils.toInt(value);
}
}