package cz.cuni.mff.d3s.been.core.task;
import static cz.cuni.mff.d3s.been.core.jaxb.Factory.TASK;
import java.io.StringWriter;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import javax.xml.bind.JAXBException;
import org.xml.sax.SAXException;
import cz.cuni.mff.d3s.been.core.jaxb.BindingComposer;
import cz.cuni.mff.d3s.been.core.jaxb.XSD;
/**
* Convenient functions for TaskEntry.
*
* Use these instead of directly manipulating a TaskEntry.
*
* @author Martin Sixta
*/
public class TaskEntries {
private TaskEntries() {
// prevents initialization
}
/**
* Creates a new {@link TaskEntry} from given {@link TaskDescriptor}. Entry is
* created with state {@link TaskState#CREATED}, with random UUID and default
* owner and runtime id.
*
* @param taskDescriptor
* for which the new entry is created
* @param taskContextId
* requested context id
* @return initialized entry
*/
public static TaskEntry create(TaskDescriptor taskDescriptor, String taskContextId) {
if (taskContextId == null) {
throw new NullPointerException("Task context ID cannot be null.");
}
if (taskDescriptor == null) {
throw new NullPointerException("Task descriptor cannot be null.");
}
TaskEntry entry = TASK.createTaskEntry();
entry.setState(TaskState.CREATED);
entry.setId(UUID.randomUUID().toString());
entry.setTaskContextId(taskContextId);
entry.setTaskDescriptor(taskDescriptor);
// do not set runtimeId
return entry;
}
/**
*
* Returns XML string of an entry.
*
* @param entry
* an entry to serialize
* @return XML serialization of the entry
* @throws IllegalArgumentException
* if entry cannot be serialized
*/
public static String toXml(TaskEntry entry) throws IllegalArgumentException {
BindingComposer<TaskEntry> composer;
StringWriter writer;
try {
composer = XSD.TASKENTRY.createComposer(TaskEntry.class);
writer = new StringWriter();
composer.compose(entry, writer);
} catch (SAXException | JAXBException e) {
throw new IllegalArgumentException("TaskEntry can't be converted to XML", e);
}
return writer.toString();
}
/**
*
* Sets a new state of a {@link TaskEntry}.
*
* @param entry
* entry to change
* @param newState
* state to change to
* @param reasonFormat
* format string with explanation why the change has been made
* @param reasonArgs
* arguments for the format string
* @throws IllegalStateException
* if the transition to a new state is illegal.
*/
public static
void
setState(TaskEntry entry, TaskState newState, String reasonFormat, Object... reasonArgs) throws IllegalStateException {
TaskState oldState = entry.getState();
if (oldState == null || !oldState.canChangeTo(newState)) {
throw new IllegalStateException("Cannot change state from " + oldState + " to " + newState);
}
StateChangeEntry logEntry = createStateChangeEntry(newState, String.format(reasonFormat, reasonArgs));
getStateChangeEntries(entry).add(logEntry);
entry.setState(newState);
}
/**
*
* Returns collection of transition taken by a {@link TaskEntry}.
*
* @param entry
* the entry to operate on
* @return mutable list of transitions
*/
public static List<StateChangeEntry> getStateChangeEntries(TaskEntry entry) {
if (!entry.isSetStateChangeLog()) {
entry.setStateChangeLog(TASK.createStateChangeLog());
}
return entry.getStateChangeLog().getLogEntries();
}
/**
* Creates StateChangeEntry.
*
* @param state
* requested state
* @param reasonFormat
* reason format
* @param reasonArgs
* reason format arguments
* @return StateChangeEntry
*/
private static StateChangeEntry createStateChangeEntry(TaskState state, String reasonFormat, Object... reasonArgs) {
StateChangeEntry logEntry = TASK.createStateChangeEntry();
logEntry.setState(state);
logEntry.setReason(String.format(reasonFormat, reasonArgs));
logEntry.setTimestamp(new Date().getTime());
return logEntry;
}
}