/*
* Copyright 2014 JBoss Inc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.artificer.repository.hibernate.audit;
import org.artificer.common.audit.AuditEntryTypes;
import org.artificer.common.audit.AuditItemTypes;
import org.artificer.repository.audit.ArtifactDiff;
import org.artificer.repository.hibernate.HibernateEntityFactory;
import org.artificer.repository.hibernate.entity.ArtificerArtifact;
import org.jboss.downloads.artificer._2013.auditing.AuditEntry;
import org.jboss.downloads.artificer._2013.auditing.AuditItemType;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
/**
* A class that is able to compare an artifact and output
* the differences in properties, relationships, and classifiers. This class
* is used by the auditing code to record changes made to a node.
*
* @author Brett Meyer.
*/
public class HibernateAuditor {
private final Map<String, String> oldProperties = new HashMap<>();
private final List<String> oldClassifiers = new ArrayList<>();
/**
* Constructor. Creates an initial snapshot of information found in the
* included artifact. The information will be used for a later comparison.
*/
public HibernateAuditor(ArtificerArtifact oldArtifact) {
// Note: Do not directly use the ArtificerArtifact collections, as they are going to change before #diff is called!
oldProperties.putAll(oldArtifact.snapshotProperties());
oldClassifiers.addAll(oldArtifact.getClassifiers());
}
/**
* Called to compare the initial snapshot information with the current state
* of the artifact node.
*
* @param newArtifact
*/
public ArtificerAuditEntry diff(ArtificerArtifact newArtifact) {
ArtifactDiff diff = new ArtifactDiff();
Map<String, String> newProperties = newArtifact.snapshotProperties();
List<String> newClassifiers = newArtifact.getClassifiers();
for (String name : newProperties.keySet()) {
String newValue = newProperties.get(name);
newValue = newValue == null ? "" : newValue;
if (oldProperties.containsKey(name)) {
String oldValue = oldProperties.get(name);
oldValue = oldValue == null ? "" : oldValue;
if (!oldValue.equals(newValue)) {
diff.getUpdatedProperties().put(name, newValue);
}
// Remove it so that, at the end of this, the map of properties contains all
// properties that were removed.
oldProperties.remove(name);
} else {
diff.getAddedProperties().put(name, newValue);
}
}
for (String newClassifier : newClassifiers) {
if (!oldClassifiers.contains(newClassifier)) {
diff.getAddedClassifiers().add(newClassifier);
}
// Remove it so that, at the end of this, the classifier set contains only
// classifiers that were removed.
oldClassifiers.remove(newClassifier);
}
// Process property deletes
for (Map.Entry<String, String> entry : oldProperties.entrySet()) {
String name = entry.getKey();
diff.getDeletedProperties().add(name);
}
// Process classifier deletes
for (String classifier : oldClassifiers) {
diff.getDeletedClassifiers().add(classifier);
}
ArtificerAuditEntry artificerAuditEntry = new ArtificerAuditEntry();
artificerAuditEntry.setUuid(UUID.randomUUID().toString());
artificerAuditEntry.setModifiedBy(HibernateEntityFactory.user());
artificerAuditEntry.setType(AuditEntryTypes.ARTIFACT_UPDATE);
createAuditItem(artificerAuditEntry, AuditItemTypes.PROPERTY_ADDED, diff.getAddedProperties());
createAuditItem(artificerAuditEntry, AuditItemTypes.PROPERTY_CHANGED, diff.getUpdatedProperties());
Map<String, String> deletedProperties = new HashMap<>();
for (String deletedProperty : diff.getDeletedProperties()) {
deletedProperties.put(deletedProperty, "");
}
createAuditItem(artificerAuditEntry, AuditItemTypes.PROPERTY_REMOVED, deletedProperties);
Map<String, String> addedClassifiers = new HashMap<>();
int idx = 0;
for (String addedClassifier : diff.getAddedClassifiers()) {
addedClassifiers.put("classifier-" + idx++, addedClassifier);
}
createAuditItem(artificerAuditEntry, AuditItemTypes.CLASSIFIERS_ADDED, addedClassifiers);
Map<String, String> deletedClassifiers = new HashMap<>();
idx = 0;
for (String deletedClassifier : diff.getDeletedClassifiers()) {
deletedClassifiers.put("classifier-" + idx++, deletedClassifier);
}
createAuditItem(artificerAuditEntry, AuditItemTypes.CLASSIFIERS_REMOVED, deletedClassifiers);
artificerAuditEntry.setArtifact(newArtifact);
newArtifact.getAuditEntries().add(artificerAuditEntry);
return artificerAuditEntry;
}
public static ArtificerAuditEntry createAddEntry(ArtificerArtifact artifact) {
ArtificerAuditEntry artificerAuditEntry = new ArtificerAuditEntry();
artificerAuditEntry.setUuid(UUID.randomUUID().toString());
artificerAuditEntry.setModifiedBy(HibernateEntityFactory.user());
artificerAuditEntry.setType(AuditEntryTypes.ARTIFACT_ADD);
createAuditItem(artificerAuditEntry, AuditItemTypes.PROPERTY_ADDED, artifact.snapshotProperties());
Map<String, String> addedClassifiers = new HashMap<>();
int idx = 0;
for (String addedClassifier : artifact.getClassifiers()) {
addedClassifiers.put("classifier-" + idx++, addedClassifier);
}
createAuditItem(artificerAuditEntry, AuditItemTypes.CLASSIFIERS_ADDED, addedClassifiers);
artificerAuditEntry.setArtifact(artifact);
artifact.getAuditEntries().add(artificerAuditEntry);
return artificerAuditEntry;
}
public static ArtificerAuditEntry createDeleteEntry(ArtificerArtifact artifact) {
ArtificerAuditEntry artificerAuditEntry = new ArtificerAuditEntry();
artificerAuditEntry.setUuid(UUID.randomUUID().toString());
artificerAuditEntry.setModifiedBy(HibernateEntityFactory.user());
artificerAuditEntry.setType(AuditEntryTypes.ARTIFACT_DELETE);
artificerAuditEntry.setArtifact(artifact);
artifact.getAuditEntries().add(artificerAuditEntry);
return artificerAuditEntry;
}
private static void createAuditItem(ArtificerAuditEntry artificerAuditEntry,
String type, Map<String, String> properties) {
if (!properties.isEmpty()) {
ArtificerAuditItem artificerAuditItem = new ArtificerAuditItem();
artificerAuditItem.setType(type);
artificerAuditItem.getProperties().putAll(properties);
artificerAuditItem.setAuditEntry(artificerAuditEntry);
artificerAuditEntry.getItems().add(artificerAuditItem);
}
}
public static List<AuditEntry> auditEntries(List<ArtificerAuditEntry> artificerAuditEntries) {
List<AuditEntry> auditEntries = new ArrayList<>();
for (ArtificerAuditEntry artificerAuditEntry : artificerAuditEntries) {
auditEntries.add(auditEntry(artificerAuditEntry));
}
return auditEntries;
}
public static AuditEntry auditEntry(ArtificerAuditEntry artificerAuditEntry) {
AuditEntry auditEntry = new AuditEntry();
auditEntry.setWhen(HibernateEntityFactory.calendar(artificerAuditEntry.getModifiedBy().getLastActionTime()));
auditEntry.setWho(artificerAuditEntry.getModifiedBy().getUsername());
auditEntry.setUuid(artificerAuditEntry.getUuid());
auditEntry.setType(artificerAuditEntry.getType());
for (ArtificerAuditItem artificerAuditItem : artificerAuditEntry.getItems()) {
AuditItemType auditItem = new AuditItemType();
auditItem.setType(artificerAuditItem.getType());
for (String key : artificerAuditItem.getProperties().keySet()) {
String value = artificerAuditItem.getProperties().get(key);
AuditItemType.Property property = new AuditItemType.Property();
property.setName(key);
property.setValue(value);
auditItem.getProperty().add(property);
}
auditEntry.getAuditItem().add(auditItem);
}
return auditEntry;
}
public static ArtificerAuditEntry auditEntry(AuditEntry srampAuditEntry, ArtificerArtifact artifact) {
ArtificerAuditEntry auditEntry = new ArtificerAuditEntry();
auditEntry.setModifiedBy(HibernateEntityFactory.user());
auditEntry.setUuid(srampAuditEntry.getUuid());
auditEntry.setType(srampAuditEntry.getType());
for (AuditItemType srampAuditItem : srampAuditEntry.getAuditItem()) {
ArtificerAuditItem auditItem = new ArtificerAuditItem();
auditItem.setType(srampAuditItem.getType());
for (AuditItemType.Property srampProperty : srampAuditItem.getProperty()) {
auditItem.getProperties().put(srampProperty.getName(), srampProperty.getValue());
}
auditEntry.getItems().add(auditItem);
auditItem.setAuditEntry(auditEntry);
}
auditEntry.setArtifact(artifact);
artifact.getAuditEntries().add(auditEntry);
return auditEntry;
}
}