/* * 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 static org.rhq.core.domain.drift.DriftCategory.FILE_REMOVED; import java.io.Serializable; import java.util.Collection; import java.util.Map; import java.util.Set; import java.util.TreeMap; /** * A representation of an agent's drift file monitoring. * * @author John Sanda */ public class DriftSnapshot implements Serializable { private static final long serialVersionUID = 1L; /** The request that generated this snapshot */ private DriftSnapshotRequest request; /** * The version of this snapshot. It may differ from the requested version if the requested version * does not exist. -1 indicates that the definition does not yet have an initial snapshot. */ private int version = -1; /** Map of directory path to information about that directory. Includes only directories with drift instances */ private Map<String, DriftSnapshotDirectory> directoryMap; /** Map of path to Drift instance. */ private Map<String, Drift<?, ?>> driftMap; /** * This should not be used. It's to satisfy smartgwt. */ public DriftSnapshot() { } public DriftSnapshot(DriftSnapshotRequest request) { super(); this.request = request; if (this.request.isIncludeDriftDirectories()) { directoryMap = new TreeMap<String, DriftSnapshotDirectory>(); } if (this.request.isIncludeDriftInstances()) { driftMap = new TreeMap<String, Drift<?, ?>>(); } } public int getVersion() { return version; } public Collection<Drift<?, ?>> getDriftInstances() { if (null == driftMap) { return null; } return driftMap.values(); } public Collection<DriftSnapshotDirectory> getDriftDirectories() { if (null == directoryMap) { return null; } return directoryMap.values(); } /** * @param changeSet The drifts must be set for the changeSet * @return the snapshot */ public DriftSnapshot addChangeSet(DriftChangeSet<? extends Drift<?, ?>> changeSet) { String dirFilter = request.getDirectory(); Set<? extends Drift<?, ?>> drifts = changeSet.getDrifts(); for (Drift<?, ?> drift : drifts) { String path = drift.getPath(); if (request.isIncludeDriftDirectories()) { int i = path.lastIndexOf("/"); String key = (i != -1) ? path.substring(0, i) : ""; DriftSnapshotDirectory dir = directoryMap.get(key); if (null == dir) { dir = new DriftSnapshotDirectory(key); directoryMap.put(key, dir); } switch (drift.getCategory()) { case FILE_ADDED: dir.incrementAdded(); dir.incrementFiles(); break; case FILE_CHANGED: dir.incrementChanged(); break; case FILE_REMOVED: dir.incrementRemoved(); dir.decrementFiles(); break; default: throw new IllegalArgumentException("Unexpected drift category: " + drift.getCategory().name()); } } if (request.isIncludeDriftInstances()) { if ((null != dirFilter) && (!dirFilter.equals(drift.getDirectory()))) { continue; } if (drift.getCategory() == FILE_REMOVED) { driftMap.remove(path); } else { driftMap.put(drift.getPath(), drift); } } } version = changeSet.getVersion(); return this; } public DriftDiffReport<?> diff(DriftSnapshot right) { if (!(right.request.isIncludeDriftInstances() && this.request.isIncludeDriftInstances())) { throw new IllegalArgumentException("Cannot compare DriftSnapshots that do not contain drift instances"); } DriftSnapshot left = this; DriftDiffReport<Drift<?, ?>> diff = new DriftDiffReport<Drift<?, ?>>(); for (Map.Entry<String, Drift<?, ?>> entry : left.driftMap.entrySet()) { if (!right.driftMap.containsKey(entry.getKey())) { diff.elementNotInRight(entry.getValue()); } } for (Map.Entry<String, Drift<?, ?>> entry : right.driftMap.entrySet()) { if (!left.driftMap.containsKey(entry.getKey())) { diff.elementNotInLeft(entry.getValue()); } } for (Map.Entry<String, Drift<?, ?>> entry : left.driftMap.entrySet()) { Drift<?, ?> rightDrift = right.driftMap.get(entry.getKey()); if (rightDrift != null) { DriftFile leftFile = entry.getValue().getNewDriftFile(); DriftFile rightFile = rightDrift.getNewDriftFile(); if (!leftFile.getHashId().equals(rightFile.getHashId())) { diff.elementInConflict(entry.getValue()); } } } return diff; } public DriftSnapshotRequest getRequest() { return request; } public static class DriftSnapshotDirectory implements Serializable { private static final long serialVersionUID = 1L; private String directoryPath; private int files = 0; private int added = 0; private int changed = 0; private int removed = 0; /** for smartgwt, do not call */ public DriftSnapshotDirectory() { } public DriftSnapshotDirectory(String directoryPath) { this.directoryPath = directoryPath; } public String getDirectoryPath() { return directoryPath; } public int getFiles() { return files; } protected void decrementFiles() { if (this.files > 0) { --this.files; } } protected void incrementFiles() { ++this.files; } public int getAdded() { return added; } protected void incrementAdded() { ++this.added; } public int getChanged() { return changed; } protected void incrementChanged() { ++this.changed; } public int getRemoved() { return removed; } protected void incrementRemoved() { ++this.removed; } } }