/*
* Copyright (C) 2006-2016 DLR, Germany
*
* All rights reserved
*
* http://www.rcenvironment.de/
*/
package de.rcenvironment.core.component.datamanagement.internal;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import de.rcenvironment.core.communication.common.CommunicationException;
import de.rcenvironment.core.component.datamanagement.api.ComponentDataManagementService;
import de.rcenvironment.core.component.datamanagement.api.ComponentDataManagementUtil;
import de.rcenvironment.core.component.datamanagement.api.ComponentHistoryDataItem;
import de.rcenvironment.core.component.datamanagement.history.HistoryMetaDataKeys;
import de.rcenvironment.core.component.execution.api.ComponentContext;
import de.rcenvironment.core.datamanagement.FileDataService;
import de.rcenvironment.core.datamanagement.commons.MetaData;
import de.rcenvironment.core.datamanagement.commons.MetaDataSet;
import de.rcenvironment.core.datamodel.api.TypedDatumSerializer;
/**
* Implements history-related methods.
*
* TODO merge with {@link ComponentDataManagementService}?
*
* @author Robert Mischke
* @author Doreen Seider
*/
public class WorkflowHistoryServiceImpl {
private static final MetaData METADATA_CLASS_NAME = new MetaData(
HistoryMetaDataKeys.HISTORY_HISTORY_DATA_ITEM_IDENTIFIER, true, true);
private static final MetaData METADATA_USER_INFO_TEXT = new MetaData(
HistoryMetaDataKeys.HISTORY_USER_INFO_TEXT, true, true);
private static final MetaData METADATA_HISTORY_TIMESTAMP = new MetaData(
HistoryMetaDataKeys.HISTORY_TIMESTAMP, true, true);
private TypedDatumSerializer typedDatumSerializer;
/**
* FileDataService for storing/loading resources to the data management.
*/
private FileDataService fileDataService;
/**
* Default constructor that tries to acquire all data management services automatically.
*
* @param user the certificate to acquire the data management services with
*/
public WorkflowHistoryServiceImpl(TypedDatumSerializer typedDatumSerializer, FileDataService fileDataService) {
this.typedDatumSerializer = typedDatumSerializer;
this.fileDataService = fileDataService;
}
/**
* Creates a history data point.
*
* TODO better doc; merge with {@link ComponentDataManagementService}?
*
* @param historyData the history data to store
* @param userInfoText the user information text to associate; usually used as display title
* @param componentContext the {@link ComponentContext} to read metadata from
* @param timestamp timestamp of the history data creation
* @throws IOException on a data management or I/O error
*/
public void addHistoryDataPoint(Serializable historyData, String userInfoText, ComponentContext componentContext,
long timestamp) throws IOException {
MetaDataSet mds = new MetaDataSet();
ComponentDataManagementUtil.setComponentMetaData(mds, componentContext);
setHistoryMetaData(mds, historyData, userInfoText, timestamp);
InputStream historyDataInputStream = getHistoryDataPointAsInputStreamInputStream(historyData);
// create reference
try {
fileDataService.newReferenceFromStream(historyDataInputStream, mds, componentContext.getDefaultStorageNodeId());
} catch (InterruptedException | CommunicationException e) {
// reduce exception types
throw new IOException(e);
}
}
private static void setHistoryMetaData(MetaDataSet mds, Serializable historyData, String userInfoText, long timestamp) {
if (historyData instanceof ComponentHistoryDataItem) {
mds.setValue(METADATA_CLASS_NAME, ((ComponentHistoryDataItem) historyData).getIdentifier());
} else {
mds.setValue(METADATA_CLASS_NAME, historyData.getClass().getCanonicalName());
}
mds.setValue(METADATA_USER_INFO_TEXT, userInfoText);
mds.setValue(METADATA_HISTORY_TIMESTAMP, Long.toString(timestamp));
}
private InputStream getHistoryDataPointAsInputStreamInputStream(Serializable historyData) throws IOException {
if (historyData instanceof ComponentHistoryDataItem) {
historyData = ((ComponentHistoryDataItem) historyData).serialize(typedDatumSerializer);
}
// convert Serializable -> InputStream;
// as all streams are memory-only, cleanup is left to GC
ByteArrayOutputStream baOutputStream = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baOutputStream);
oos.writeObject(historyData);
return new ByteArrayInputStream(baOutputStream.toByteArray());
}
}