package ru.hflabs.rcd.task.performer; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; import com.google.common.collect.Maps; import javax.xml.bind.annotation.XmlTransient; import java.util.Collection; import java.util.LinkedHashMap; import java.util.Map; import java.util.Set; /** * Класс <class>ParameterHolder</class> реализует контейнер параметров * * @author Nazin Alexander */ public class ParametersHolder implements Map<String, Object> { /** Сервис конвертации объектов */ private static final transient ObjectMapper OBJECT_MAPPER = new ObjectMapper(); /** Настройка сервиса конвертации объектов */ static { OBJECT_MAPPER.configure(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT, true); } /** Репозиторий параметров */ private final Map<String, Object> delegate; public ParametersHolder() { this(new LinkedHashMap<String, Object>()); } public ParametersHolder(Map<String, Object> delegate) { this.delegate = delegate; } /** * Сохраняет параметр * * @param name название параметра * @param value значение параметра */ protected <T> void injectParameter(String name, T value) { delegate.put(name, value); } /** * Возвращает параметр по его имени или <code>NULL</code>, если параметр не установлен * * @param name название параметра * @param targetClass ожидаемый класс параметра * @return Возвращает найденный параметр или <code>NULL</code> * @throws ClassCastException исключение, если найденный параметр не соответствует ожидаемому классу */ protected <T> T retrieveParameter(String name, Class<T> targetClass) throws ClassCastException { return retrieveParameter(name, targetClass, null); } /** * Возвращает параметр по его имени * * @param name название параметра * @param targetClass ожидаемый класс параметра * @param defaultValue значение по умолчанию * @return Возвращает найденный параметр или <i>defaultValue</i>, если параметр не установлен * @throws ClassCastException исключение, если найденный параметр не соответствует ожидаемому классу */ protected <T> T retrieveParameter(String name, Class<T> targetClass, T defaultValue) throws ClassCastException { // Получаем значение по его имени Object value = delegate.get(name); // Выполняем преобразование значения в ожидаемый тип if (value != null) { if (targetClass.equals(value.getClass())) { return targetClass.cast(value); } else { try { return OBJECT_MAPPER.convertValue(value, targetClass); } catch (Exception ex) { return defaultValue; } } } else { return defaultValue; } } @Override public int size() { return delegate.size(); } @Override @XmlTransient public boolean isEmpty() { return delegate.isEmpty(); } @Override public boolean containsKey(Object key) { return delegate.containsKey(key); } @Override public boolean containsValue(Object value) { return delegate.containsValue(value); } @Override public Object get(Object key) { return delegate.get(key); } @Override public Object put(String key, Object value) { return delegate.put(key, value); } @Override public Object remove(Object key) { return delegate.remove(key); } @Override public void putAll(Map<? extends String, ?> m) { delegate.putAll(m); } @Override public void clear() { delegate.clear(); } @Override public Set<String> keySet() { return delegate.keySet(); } @Override public Collection<Object> values() { return delegate.values(); } @Override public Set<Entry<String, Object>> entrySet() { return delegate.entrySet(); } @Override public String toString() { if (OBJECT_MAPPER != null) { try { return OBJECT_MAPPER.writeValueAsString(delegate); } catch (JsonProcessingException ex) { return super.toString(); } } else { return super.toString(); } } @Override public int hashCode() { return delegate != null ? delegate.hashCode() : 0; } @Override public boolean equals(Object o) { if (this == o) { return true; } if (o == null || getClass() != o.getClass()) { return false; } ParametersHolder that = (ParametersHolder) o; if (delegate != null ? !Maps.difference(delegate, that.delegate).areEqual() : that.delegate != null) { return false; } return true; } }