/** * AnalyzerBeans * Copyright (C) 2014 Neopost - Customer Information Management * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU * Lesser General Public License, as published by the Free Software Foundation. * * This program 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 distribution; if not, write to: * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ package org.eobjects.analyzer.job; import java.io.Serializable; import java.util.Collection; import java.util.HashMap; import java.util.Map; import java.util.Set; import org.apache.metamodel.util.EqualsBuilder; import org.eobjects.analyzer.descriptors.ConfiguredPropertyDescriptor; import org.eobjects.analyzer.descriptors.PropertyDescriptor; import com.google.common.collect.ImmutableMap; /** * Default (immutable) implementation of {@link BeanConfiguration}. */ public final class ImmutableBeanConfiguration implements BeanConfiguration { private static final long serialVersionUID = 1L; private final Map<PropertyDescriptor, Object> _properties; private final transient Map<PropertyDescriptor, Object> _transientProperties; public ImmutableBeanConfiguration(Map<? extends PropertyDescriptor, Object> properties) { if (properties == null) { _properties = ImmutableMap.of(); _transientProperties = null; } else { // separate transient and serializable properties to make sure we // can serialize later on final Map<PropertyDescriptor, Object> serializableProperties = new HashMap<>(); final Map<PropertyDescriptor, Object> transientProperties = new HashMap<>(); // validate contents for (final Map.Entry<? extends PropertyDescriptor, Object> entry : properties.entrySet()) { final PropertyDescriptor key = entry.getKey(); final Object value = entry.getValue(); if (value instanceof Collection) { throw new IllegalArgumentException( "Collection values are not allowed in BeanConfigurations. Violating entry: " + key + " -> " + value); } if (value instanceof Serializable) { serializableProperties.put(key, value); } else { transientProperties.put(key, value); } } _properties = ImmutableMap.copyOf(serializableProperties); _transientProperties = ImmutableMap.copyOf(transientProperties); } } @Override public Object getProperty(ConfiguredPropertyDescriptor propertyDescriptor) { final Object result = _properties.get(propertyDescriptor); if (result == null && _transientProperties != null) { return _transientProperties.get(propertyDescriptor); } return result; } @Override public String toString() { return "ImmutableBeanConfiguration[" + _properties + "]"; } @Override public int hashCode() { final int prime = 31; return prime + _properties.size() + _properties.keySet().hashCode(); } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } final ImmutableBeanConfiguration other = (ImmutableBeanConfiguration) obj; // since map comparison does not use deep equals for arrays, we need to // do this ourselves! final Map<PropertyDescriptor, Object> otherProperties = other._properties; final Set<PropertyDescriptor> configredProperties = _properties.keySet(); if (!configredProperties.equals(otherProperties.keySet())) { return false; } for (final PropertyDescriptor propertyDescriptor : configredProperties) { final Object value1 = _properties.get(propertyDescriptor); final Object value2 = otherProperties.get(propertyDescriptor); final boolean equals = EqualsBuilder.equals(value1, value2); if (!equals) { return false; } } return true; } }