/* * RHQ Management Platform * Copyright (C) 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.core.domain.drift; import java.util.Comparator; import java.util.List; /** * Compares two {@link DriftDefinition} objects. The comparison can either * compare basedir/includes-excludes filters or ignore them. Will also compare * name, interval, enabled flag. * * @author John Mazzitelli */ public class DriftDefinitionComparator implements Comparator<DriftDefinition> { public enum CompareMode { /** * The comparator will only check the base information: name, description, enabled, * interval, driftHandlingMode, pinned, and pinnedVersion. The basedir/includes-excludes * filters will be ignored. */ ONLY_BASE_INFO, /** * The comparator will only check the basedir/includes-excludes filters. * The base information will be ignored (see {@link #ONLY_BASE_INFO} for what those are). */ ONLY_DIRECTORY_SPECIFICATIONS, /** * The comparator will check both the basedir/includes-excludes filters and * the base information (see {@link #ONLY_BASE_INFO} for what those are). */ BOTH_BASE_INFO_AND_DIRECTORY_SPECIFICATIONS; }; private final CompareMode compareMode; public DriftDefinitionComparator(CompareMode mode) { this.compareMode = mode; } @Override public int compare(DriftDefinition dc1, DriftDefinition dc2) { if (compareMode != CompareMode.ONLY_DIRECTORY_SPECIFICATIONS) { if (dc1.getName() != null) { if (dc2.getName() != null) { int results = dc1.getName().compareTo(dc2.getName()); if (results != 0) { return results; } } else { return 1; // dc1's name is not null, but dc2's name is null, not equal! } } else if (dc2.getName() != null) { return -1; // dc1's name is null, but dc2's name is not null, not equal! } if (dc1.getDescription() != null) { if (dc2.getDescription() != null) { int results = dc1.getDescription().compareTo(dc2.getDescription()); if (results != 0) { return results; } } else { return 1; // dc1's description is not null, but dc2's description is null } } else if (dc2.getDescription() != null) { return -1; // dc2's description is not null, but dc1's description is null } if (dc1.getInterval() != dc2.getInterval()) { return dc1.getInterval() < dc2.getInterval() ? -1 : 1; } if (dc1.getDriftHandlingMode() != dc2.getDriftHandlingMode()) { return dc1.getDriftHandlingMode().ordinal() < dc2.getDriftHandlingMode().ordinal() ? -1 : 1; } if (dc1.isEnabled() != dc2.isEnabled()) { return dc1.isEnabled() ? 1 : -1; // so false sorts before true, seems logical to me } if (dc1.isAttached() != dc2.isAttached()) { return dc1.isAttached() ? 1 : -1; } if (dc1.isPinned() != dc2.isPinned()) { return dc1.isPinned() ? 1 : -1; } } if (compareMode != CompareMode.ONLY_BASE_INFO) { if (dc1.getBasedir() != null) { if (!dc1.getBasedir().equals(dc2.getBasedir())) { int hash1 = dc1.getBasedir().hashCode(); int hash2 = (dc2.getBasedir() != null) ? dc2.getBasedir().hashCode() : 0; return hash1 < hash2 ? -1 : 1; } } else if (dc2.getBasedir() != null) { return -1; // dc1's basedir is null, but dc2's basedir is not null, not equal! } List<Filter> filters1 = dc1.getIncludes(); List<Filter> filters2 = dc2.getIncludes(); int results = compareFilters(filters1, filters2); if (results != 0) { return results; } filters1 = dc1.getExcludes(); filters2 = dc2.getExcludes(); results = compareFilters(filters1, filters2); if (results != 0) { return results; } } return 0; } private int compareFilters(List<Filter> filters1, List<Filter> filters2) { if (filters1 == null) { return (filters2 == null) ? 0 : -1; } else if (filters2 == null) { return 1; } // at this point, we know both filters1 and filters2 are non-null // let's do the next easiest check - size. If the lists are different sizes, then clearly they are different if (filters1.size() != filters2.size()) { return (filters1.size() < filters2.size()) ? -1 : 1; } // they are the same size, let's see if they have the same items. We only need to see if one contains // all of the other; because they are the same size, if filters1 contains all the filters2 items, // then clearly the other way is true too (filters2 contains all of filters1 items). if (!filters1.containsAll(filters2)) { return -1; // unsure if we need to do further anaylsis to determine if -1 or 1 should be returned; for now, don't worry about it } return 0; } }