/* * RHQ Management Platform * Copyright (C) 2005-2010 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, version 2, as * published by the Free Software Foundation, and/or the GNU Lesser * General Public License, version 2.1, also 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 General Public License and the GNU Lesser General Public License * for more details. * * You should have received a copy of the GNU General Public License * and 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.rhq.enterprise.server.resource.disambiguation; import java.util.ArrayList; import java.util.Collections; import java.util.List; /** * This class partitions the reports inserted into it by chunking them up * into sublists containing mutually ambiguous reports. The ambiguity is determined using * a {@link DisambiguationPolicy}. * * @param <T> the type of the original instances the are being disambiguated. * * @author Lukas Krejci */ public class ReportPartitions<T> { private static final long serialVersionUID = 1L; private DisambiguationPolicy disambiguationPolicy; private List<List<MutableDisambiguationReport<T>>> uniquePartitions; private List<List<MutableDisambiguationReport<T>>> ambiguousPartitions; /** * Constructs a new instance with no partitions in it. * * @param disambiguationPolicy the policy that decides if reports are ambiguous. */ public ReportPartitions(DisambiguationPolicy disambiguationPolicy) { this.disambiguationPolicy = disambiguationPolicy; uniquePartitions = new ArrayList<List<MutableDisambiguationReport<T>>>(); ambiguousPartitions = new ArrayList<List<MutableDisambiguationReport<T>>>(); } public ReportPartitions(DisambiguationPolicy disambiguationPolicy, ReportPartitions<T> other) { this(disambiguationPolicy); putAll(other); } public ReportPartitions(DisambiguationPolicy disambiguationPolicy, List<List<MutableDisambiguationReport<T>>> partitions) { this(disambiguationPolicy); for(List<MutableDisambiguationReport<T>> partition : partitions) { putAll(partition); } } public DisambiguationPolicy getDisambiguationPolicy() { return disambiguationPolicy; } public List<List<MutableDisambiguationReport<T>>> getAmbiguousPartitions() { return Collections.unmodifiableList(ambiguousPartitions); } public List<List<MutableDisambiguationReport<T>>> getUniquePartitions() { return Collections.unmodifiableList(uniquePartitions); } public List<List<MutableDisambiguationReport<T>>> getAllPartitions() { List<List<MutableDisambiguationReport<T>>> ret = new ArrayList<List<MutableDisambiguationReport<T>>>(ambiguousPartitions); ret.addAll(uniquePartitions); return Collections.unmodifiableList(ret); } public void put(MutableDisambiguationReport<T> value) { put(value, true); } public void putAll(List<MutableDisambiguationReport<T>> values) { for (MutableDisambiguationReport<T> v : values) { put(v, false); } updatePolicy(); } public void putAll(ReportPartitions<T> other) { for (List<MutableDisambiguationReport<T>> partition : other.getAllPartitions()) { for (MutableDisambiguationReport<T> v : partition) { put(v, false); } } updatePolicy(); } public boolean isPartitionsUnique() { return ambiguousPartitions.size() == 0; } public String toString() { return "ReportPartitions[policy=" + disambiguationPolicy + ", uniquePartitions=" + uniquePartitions + ", ambiguousPartitions=" + ambiguousPartitions + "]"; } private void put(MutableDisambiguationReport<T> value, boolean updatePolicy) { if (insertIntoExisting(value, ambiguousPartitions) >= 0) { return; } else { int idx = insertIntoExisting(value, uniquePartitions); if (idx >= 0) { ambiguousPartitions.add(uniquePartitions.remove(idx)); } else { List<MutableDisambiguationReport<T>> newPartition = new ArrayList<MutableDisambiguationReport<T>>(); newPartition.add(value); uniquePartitions.add(newPartition); } } if (updatePolicy) { updatePolicy(); } } private void updatePolicy() { this.disambiguationPolicy.getCurrentLevel().setDeciding(uniquePartitions.size() > 0); } private int insertIntoExisting(MutableDisambiguationReport<T> value, List<List<MutableDisambiguationReport<T>>> partitions) { int idx = -1; boolean found = false; for (List<MutableDisambiguationReport<T>> partition : partitions) { for (MutableDisambiguationReport<T> partitionPrototype : partition) { if (disambiguationPolicy.areAmbiguous(partitionPrototype, value)) { found = true; break; } } idx++; if (found) { partition.add(value); break; } } return found ? idx : -1; } }