/*
* Copyright 2013 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.overlord.dtgov.ui.server.services;
import java.util.List;
import javax.inject.Inject;
import org.jboss.downloads.overlord.sramp._2013.auditing.AuditEntry;
import org.jboss.downloads.overlord.sramp._2013.auditing.AuditItemType;
import org.jboss.downloads.overlord.sramp._2013.auditing.AuditItemType.Property;
import org.jboss.errai.bus.server.annotations.Service;
import org.oasis_open.docs.s_ramp.ns.s_ramp_v1.BaseArtifactType;
import org.overlord.dtgov.ui.client.shared.beans.ArtifactHistoryBean;
import org.overlord.dtgov.ui.client.shared.beans.HistoryEventBean;
import org.overlord.dtgov.ui.client.shared.beans.HistoryEventSummaryBean;
import org.overlord.dtgov.ui.client.shared.exceptions.DtgovUiException;
import org.overlord.dtgov.ui.client.shared.services.IHistoryService;
import org.overlord.dtgov.ui.server.i18n.Messages;
import org.overlord.dtgov.ui.server.services.sramp.SrampApiClientAccessor;
import org.overlord.sramp.atom.err.SrampAtomException;
import org.overlord.sramp.client.SrampClientException;
import org.overlord.sramp.client.audit.AuditEntrySummary;
import org.overlord.sramp.client.audit.AuditResultSet;
import org.overlord.sramp.common.ArtifactType;
import org.overlord.sramp.common.audit.AuditEntryTypes;
import org.overlord.sramp.common.audit.AuditItemTypes;
/**
* Concrete implementation of the task inbox service.
*
* @author eric.wittmann@redhat.com
*/
@Service
public class HistoryService implements IHistoryService {
@Inject
private SrampApiClientAccessor srampClientAccessor;
/**
* Constructor.
*/
public HistoryService() {
}
/**
* @see org.overlord.dtgov.ui.client.shared.services.IHistoryService#listEvents(java.lang.String)
*/
@Override
public ArtifactHistoryBean listEvents(String artifactUuid) throws DtgovUiException {
try {
// Get the artifact from s-ramp
BaseArtifactType artifact = srampClientAccessor.getClient().getArtifactMetaData(artifactUuid);
ArtifactType artifactType = ArtifactType.valueOf(artifact);
// Create the return bean with some artifact info
ArtifactHistoryBean bean = new ArtifactHistoryBean();
bean.setArtifactName(artifact.getName());
bean.setArtifactType(artifactType.getType());
bean.setArtifactUuid(artifactUuid);
bean.setArtifactVersion(artifact.getVersion());
// TODO this will stop at 100 audit entries - the UI should be updated to handle this limitation (bring in a page at a time and only fetch more as the user scrolls)
AuditResultSet auditTrail = srampClientAccessor.getClient().getAuditTrailForArtifact(artifactUuid);
for (AuditEntrySummary auditEntry : auditTrail) {
HistoryEventSummaryBean event = new HistoryEventSummaryBean();
event.setArtifactUuid(artifactUuid);
event.setId(auditEntry.getUuid());
event.setType(auditEntry.getType());
event.setSummary(generateEventSummary(auditEntry));
event.setWhen(auditEntry.getWhen());
event.setWho(auditEntry.getWho());
bean.getEvents().add(event);
}
return bean;
} catch (SrampClientException e) {
throw new DtgovUiException(e);
} catch (SrampAtomException e) {
throw new DtgovUiException(e);
}
}
/**
* Generates a human readable summary from the information in the audit entry summary. This basically
* means interpreting the 'type' of the entry and outputing something sensible for a person to read.
* @param event
*/
private String generateEventSummary(AuditEntrySummary entry) {
if (AuditEntryTypes.ARTIFACT_ADD.equals(entry.getType())) {
return Messages.i18n.format("HistoryService.AddedArtifactToRepo"); //$NON-NLS-1$
} else if (AuditEntryTypes.ARTIFACT_UPDATE.equals(entry.getType())) {
return Messages.i18n.format("HistoryService.UpdatedInfoOnArty"); //$NON-NLS-1$
} else if (AuditEntryTypes.ARTIFACT_DELETE.equals(entry.getType())) {
return Messages.i18n.format("HistoryService.DeletedArty"); //$NON-NLS-1$
}
return Messages.i18n.format("HistoryService.UnrecognizedAction", entry.getType()); //$NON-NLS-1$
}
/**
* @see org.overlord.dtgov.ui.client.shared.services.IHistoryService#getEventDetails(java.lang.String, java.lang.String)
*/
@Override
public HistoryEventBean getEventDetails(String artifactUuid, String eventId) throws DtgovUiException {
try {
AuditEntry auditEntry = srampClientAccessor.getClient().getAuditEntry(artifactUuid, eventId);
HistoryEventBean bean = new HistoryEventBean();
bean.setDetails(generateEventDetails(auditEntry));
return bean;
} catch (SrampClientException e) {
throw new DtgovUiException(e);
} catch (SrampAtomException e) {
throw new DtgovUiException(e);
}
}
/**
* Generates a human readable but detailed account of what this event is all about. This means
* analyzing the type and audit items in the entry and producing a bit of text explaining what
* they are and what they mean.
* @param auditEntry
*/
private String generateEventDetails(AuditEntry auditEntry) {
if (AuditEntryTypes.ARTIFACT_ADD.equals(auditEntry.getType()) || AuditEntryTypes.ARTIFACT_DELETE.equals(auditEntry.getType())) {
return Messages.i18n.format("HistoryService.NoAdditionalInfo"); //$NON-NLS-1$
} else if (AuditEntryTypes.ARTIFACT_UPDATE.equals(auditEntry.getType())) {
List<AuditItemType> auditItem = auditEntry.getAuditItem();
if (auditItem.isEmpty()) {
return Messages.i18n.format("HistoryService.NoAdditionalInfo"); //$NON-NLS-1$
}
StringBuilder buffer = new StringBuilder();
for (AuditItemType auditItemType : auditItem) {
generateAuditItemSummary(auditItemType, buffer);
}
if (buffer.length() == 0) {
return Messages.i18n.format("HistoryService.NoAdditionalInfo"); //$NON-NLS-1$
}
return buffer.toString();
}
return Messages.i18n.format("HistoryService.UnrecognizedAction", auditEntry.getType()); //$NON-NLS-1$
}
/**
* @param auditItemType
* @param buffer
*/
private void generateAuditItemSummary(AuditItemType auditItemType, StringBuilder buffer) {
// TODO lots of injection possible here!
// TODO this needs to be re-thought. should the server generate the HTML?
String type = auditItemType.getType();
if (AuditItemTypes.PROPERTY_ADDED.equals(type)) {
List<Property> properties = auditItemType.getProperty();
if (!properties.isEmpty()) {
buffer.append("<p>"); //$NON-NLS-1$
buffer.append(Messages.i18n.format("HistoryService.PropertiesWereAdded")); //$NON-NLS-1$
buffer.append(":</p>"); //$NON-NLS-1$
buffer.append("<ul>"); //$NON-NLS-1$
for (Property property : properties) {
buffer.append("<li>"); //$NON-NLS-1$
buffer.append(
Messages.i18n.format("HistoryService.PropertyWithValue", //$NON-NLS-1$
property.getName(), property.getValue()));
buffer.append("</li>"); //$NON-NLS-1$
}
buffer.append("</ul>"); //$NON-NLS-1$
}
} else if (AuditItemTypes.PROPERTY_CHANGED.equals(type)) {
List<Property> properties = auditItemType.getProperty();
if (!properties.isEmpty()) {
buffer.append("<p>"); //$NON-NLS-1$
buffer.append(Messages.i18n.format("HistoryService.PropertiesWereModified")); //$NON-NLS-1$
buffer.append(":</p>"); //$NON-NLS-1$
buffer.append("<ul>"); //$NON-NLS-1$
for (Property property : properties) {
buffer.append("<li>"); //$NON-NLS-1$
buffer.append(
Messages.i18n.format("HistoryService.PropertyWithNewValue", //$NON-NLS-1$
property.getName(), property.getValue()));
buffer.append("</li>"); //$NON-NLS-1$
}
buffer.append("</ul>"); //$NON-NLS-1$
}
} else if (AuditItemTypes.PROPERTY_REMOVED.equals(type)) {
List<Property> properties = auditItemType.getProperty();
if (!properties.isEmpty()) {
buffer.append("<p>"); //$NON-NLS-1$
buffer.append(Messages.i18n.format("HistoryService.PropertiesWereRemoved")); //$NON-NLS-1$
buffer.append(":</p>"); //$NON-NLS-1$
buffer.append("<ul>"); //$NON-NLS-1$
for (Property property : properties) {
buffer.append("<li>"); //$NON-NLS-1$
buffer.append(Messages.i18n.format("HistoryService.Property", property.getName())); //$NON-NLS-1$
buffer.append("</li>"); //$NON-NLS-1$
}
buffer.append("</ul>"); //$NON-NLS-1$
}
} else if (AuditItemTypes.CLASSIFIERS_ADDED.equals(type)) {
List<Property> properties = auditItemType.getProperty();
if (!properties.isEmpty()) {
buffer.append("<p>"); //$NON-NLS-1$
buffer.append(Messages.i18n.format("HistoryService.ClassifiersWereAdded")); //$NON-NLS-1$
buffer.append(":</p>"); //$NON-NLS-1$
buffer.append("<ul>"); //$NON-NLS-1$
for (Property property : properties) {
buffer.append("<li>"); //$NON-NLS-1$
buffer.append(Messages.i18n.format("HistoryService.Classifier", property.getValue())); //$NON-NLS-1$
buffer.append("</li>"); //$NON-NLS-1$
}
buffer.append("</ul>"); //$NON-NLS-1$
}
} else if (AuditItemTypes.CLASSIFIERS_REMOVED.equals(type)) {
List<Property> properties = auditItemType.getProperty();
if (!properties.isEmpty()) {
buffer.append("<p>"); //$NON-NLS-1$
buffer.append(Messages.i18n.format("HistoryService.ClassifiersWereRemoved")); //$NON-NLS-1$
buffer.append(":</p>"); //$NON-NLS-1$
buffer.append("<ul>"); //$NON-NLS-1$
for (Property property : properties) {
buffer.append("<li>"); //$NON-NLS-1$
buffer.append(Messages.i18n.format("HistoryService.Classifier", property.getValue())); //$NON-NLS-1$
buffer.append("</li>"); //$NON-NLS-1$
}
buffer.append("</ul>"); //$NON-NLS-1$
}
}
}
}