/* * RHQ Management Platform * Copyright (C) 2005-2011 Red Hat, Inc. * All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.rhq.bindings.util; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.Map; import org.rhq.core.domain.configuration.definition.ConfigurationDefinition; import org.rhq.core.domain.configuration.definition.PropertyDefinition; import org.rhq.core.domain.configuration.definition.PropertyDefinitionList; import org.rhq.core.domain.configuration.definition.PropertyDefinitionMap; import org.rhq.core.domain.configuration.definition.PropertyDefinitionSimple; import org.rhq.core.domain.content.PackageType; import org.rhq.core.domain.measurement.MeasurementDefinition; import org.rhq.core.domain.operation.OperationDefinition; import org.rhq.core.domain.resource.ResourceType; import org.rhq.core.util.MessageDigestGenerator; /** * This type is used as an identification of a resource type not based * on its id but rather on its structure. * * @author Lukas Krejci */ public class ResourceTypeFingerprint { private String digest; private static final Comparator<MeasurementDefinition> MEASUREMENT_DEFINITION_COMPARATOR = new Comparator<MeasurementDefinition>() { @Override public int compare(MeasurementDefinition o1, MeasurementDefinition o2) { return o1.getName().compareTo(o2.getName()); } }; private static final Comparator<OperationDefinition> OPERATION_DEFINITION_COMPARATOR = new Comparator<OperationDefinition>() { @Override public int compare(OperationDefinition o1, OperationDefinition o2) { return o1.getName().compareTo(o2.getName()); } }; private static final Comparator<PackageType> PACKAGE_TYPE_COMPARATOR = new Comparator<PackageType>() { @Override public int compare(PackageType o1, PackageType o2) { return o1.getName().compareTo(o2.getName()); } }; private static final Comparator<PropertyDefinition> PROPERTY_DEFINITION_COMPARATOR = new Comparator<PropertyDefinition>() { @Override public int compare(PropertyDefinition o1, PropertyDefinition o2) { return o1.getName().compareTo(o2.getName()); } }; public ResourceTypeFingerprint(ResourceType rt, Collection<MeasurementDefinition> measurements, Collection<OperationDefinition> operations, Collection<PackageType> packageTypes, ConfigurationDefinition pluginConfigurationDefinition, ConfigurationDefinition resourceConfigurationDefinition) { digest = computeDigest(rt, measurements, operations, packageTypes, pluginConfigurationDefinition, resourceConfigurationDefinition); } @Override public int hashCode() { return digest.hashCode(); } @Override public boolean equals(Object other) { if (this == other) { return true; } if (!(other instanceof ResourceTypeFingerprint)) { return false; } ResourceTypeFingerprint o = (ResourceTypeFingerprint) other; return digest.equals(o.digest); } @Override public String toString() { return digest; } private static String computeDigest(ResourceType rt, Collection<MeasurementDefinition> measurements, Collection<OperationDefinition> operations, Collection<PackageType> packageTypes, ConfigurationDefinition pluginConfigurationDefinition, ConfigurationDefinition resourceConfigurationDefinition) { StringBuilder representation = new StringBuilder(); addResourceTypeRepresentation(rt, representation); addMeasurementDefinitionsRepresentations(measurements, representation); addOperationDefinitionsRepresentations(operations, representation); addPackageTypesRepresentations(packageTypes, representation); addRepresentation(pluginConfigurationDefinition, representation); addRepresentation(resourceConfigurationDefinition, representation); return new MessageDigestGenerator(MessageDigestGenerator.SHA_256).calcDigestString(representation.toString()); } private static void addResourceTypeRepresentation(ResourceType rt, StringBuilder bld) { bld.append(rt.getName()).append(rt.getPlugin()); } private static void addMeasurementDefinitionsRepresentations(Collection<MeasurementDefinition> defs, StringBuilder bld) { if (defs == null) { bld.append("null"); } else { List<MeasurementDefinition> adefs = new ArrayList<MeasurementDefinition>(defs); Collections.sort(adefs, MEASUREMENT_DEFINITION_COMPARATOR); for (MeasurementDefinition d : adefs) { addRepresentation(d, bld); } } } private static void addOperationDefinitionsRepresentations(Collection<OperationDefinition> defs, StringBuilder bld) { if (defs == null) { bld.append("null"); } else { List<OperationDefinition> odefs = new ArrayList<OperationDefinition>(defs); Collections.sort(odefs, OPERATION_DEFINITION_COMPARATOR); for (OperationDefinition d : odefs) { addRepresentation(d, bld); } } } private static void addPackageTypesRepresentations(Collection<PackageType> defs, StringBuilder bld) { if (defs == null) { bld.append("null"); } else { List<PackageType> pdefs = new ArrayList<PackageType>(defs); Collections.sort(pdefs, PACKAGE_TYPE_COMPARATOR); for (PackageType d : pdefs) { addRepresentation(d, bld); } } } private static void addRepresentation(MeasurementDefinition md, StringBuilder bld) { bld.append(md.getName()); } private static void addRepresentation(OperationDefinition od, StringBuilder bld) { bld.append(od.getName()); addRepresentation(od.getResultsConfigurationDefinition(), bld); addRepresentation(od.getParametersConfigurationDefinition(), bld); } private static void addRepresentation(PackageType pt, StringBuilder bld) { bld.append(pt.getName()); } private static void addRepresentation(ConfigurationDefinition cd, StringBuilder bld) { if (cd == null) { bld.append("null"); } else { addRepresentation(cd.getPropertyDefinitions(), bld); } } private static void addRepresentation(Map<String, PropertyDefinition> defs, StringBuilder bld) { List<PropertyDefinition> pdefs = new ArrayList<PropertyDefinition>(defs.values()); Collections.sort(pdefs, PROPERTY_DEFINITION_COMPARATOR); for (PropertyDefinition def : pdefs) { addRepresentation(def, bld); } } private static void addRepresentation(PropertyDefinition def, StringBuilder bld) { if (def instanceof PropertyDefinitionSimple) { addRepresentation((PropertyDefinitionSimple) def, bld); } else if (def instanceof PropertyDefinitionMap) { addRepresentation((PropertyDefinitionMap) def, bld); } else if (def instanceof PropertyDefinitionList) { addRepresentation((PropertyDefinitionList) def, bld); } } private static void addRepresentation(PropertyDefinitionSimple p, StringBuilder bld) { bld.append(p.getName()).append(p.getType().name()); } private static void addRepresentation(PropertyDefinitionMap pm, StringBuilder bld) { bld.append(pm.getName()); addRepresentation(pm.getMap(), bld); } private static void addRepresentation(PropertyDefinitionList pl, StringBuilder bld) { bld.append(pl.getName()); addRepresentation(pl.getMemberDefinition(), bld); } }