import java.io.IOException;
import java.util.ArrayList;
import java.util.Calendar;
+import java.util.Date;
+import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
+import java.util.Map;
import org.apache.log4j.Logger;
+import org.splat.common.properties.MessageKeyEnum;
import org.splat.dal.bo.kernel.Relation;
import org.splat.dal.bo.kernel.User;
import org.splat.dal.bo.som.ConvertsRelation;
+import org.splat.dal.bo.som.Document;
+import org.splat.dal.bo.som.DocumentType;
import org.splat.dal.bo.som.File;
import org.splat.dal.bo.som.KnowledgeElement;
import org.splat.dal.bo.som.KnowledgeElementType;
+import org.splat.dal.bo.som.ProgressState;
import org.splat.dal.bo.som.Publication;
import org.splat.dal.bo.som.Scenario;
import org.splat.dal.bo.som.SimulationContext;
import org.splat.dal.bo.som.Study;
+import org.splat.dal.bo.som.UsesRelation;
import org.splat.dal.dao.kernel.UserDAO;
import org.splat.dal.dao.som.KnowledgeElementDAO;
import org.splat.dal.dao.som.KnowledgeElementTypeDAO;
import org.splat.dal.dao.som.ScenarioDAO;
import org.splat.dal.dao.som.StudyDAO;
import org.splat.kernel.InvalidPropertyException;
+import org.splat.kernel.MismatchException;
import org.splat.kernel.MissedPropertyException;
import org.splat.kernel.MultiplyDefinedException;
+import org.splat.kernel.NotApplicableException;
import org.splat.service.dto.DocumentDTO;
+import org.splat.service.dto.FileDTO;
import org.splat.service.dto.StepDTO;
import org.splat.service.technical.IndexService;
import org.splat.service.technical.ProjectSettingsService;
*/
private ProjectSettingsService _projectSettings;
+ /**
+ * Injected document type service.
+ */
+ private DocumentTypeService _documentTypeService;
+
/**
* Get the projectElementService.
*
*
* @see org.splat.service.ScenarioService#getScenarioInfo(long)
*/
- @Transactional
+ @Transactional(readOnly = true)
public List<StepDTO> getScenarioInfo(final long scenarioId) {
List<StepDTO> res = new ArrayList<StepDTO>();
// Get the scenario from the database by id
*
* @see org.splat.service.ScenarioService#checkin(long, long, java.util.List)
*/
+ @Transactional
public void checkin(final long scenId, final long userId,
- final List<StepDTO> scInfo) {
+ final List<StepDTO> scInfo) throws InvalidPropertyException,
+ MissedPropertyException, MultiplyDefinedException,
+ MismatchException, IOException, NotApplicableException {
+ // Get the scenario from the database by id
+ Scenario aScenario = getScenarioDAO().get(scenId);
+ // Get the user who perform this check-in operation
+ User aUser = getUserService().selectUser(userId);
+ // Get activities of the scenario
+ Step[] steps = getProjectElementService().getSteps(aScenario);
+ // Find result document types
+ List<DocumentType> resTypes = getDocumentTypeService()
+ .selectResultTypes();
+
+ // For each processed existing document keep its new version
+ Map<Document, Document> newVersion = new HashMap<Document, Document>();
+ // For each processed existing document keep its previous version
+ Map<Publication, Document> prevVersion = new HashMap<Publication, Document>();
+ // Keep newly created documents to create uses relations to results of a previous step.
+ List<Publication> newVers = new ArrayList<Publication>();
+ List<Publication> newDocs = new ArrayList<Publication>();
+ // For each step DTO
+ DocumentType resType;
+ java.io.File updir;
+ Document.Properties dprop = new Document.Properties();
+ Date aDate = new Date();
+ for (StepDTO stepDTO : scInfo) {
+ // Find a result document type of the step
+ int i = 0;
+ resType = null;
+ do {
+ if (resTypes.get(i).isResultOf(
+ getProjectSettings().getStep(stepDTO.getNumber()))) {
+ resType = resTypes.get(i);
+ }
+ i++;
+ } while ((resType == null) && (i < resTypes.size()));
+
+ // Find the appropriate scenario step
+ Step step = findStep(stepDTO, steps);
+
+ // Process documents of the step
+ for (DocumentDTO doc : stepDTO.getDocs()) {
+ if (doc.getFiles().size() > 0) {
+ // NOTE: Process only the first attached file for each document
+ FileDTO file = doc.getFiles().get(0);
+
+ // Get document title as the file name
+ java.io.File upfile = new java.io.File(file.getPath());
+ String fileFormat = upfile.getName().substring(
+ upfile.getName().lastIndexOf('.') + 1);
+ String docname = upfile.getName().substring(0,
+ upfile.getName().lastIndexOf('.'));
+
+ // Create a new document or a new version of the document
+ dprop.clear();
+ dprop.setAuthor(aUser).setDate(aDate);
+ Publication pub, newPub;
+
+ if (doc.getId() > 0) {
+ // If the document already exists then create a new version of it
+ // Find the document publication
+ pub = step.getDocument(doc.getId());
+ if (pub == null) {
+ throw new InvalidPropertyException(
+ MessageKeyEnum.SCN_000002.toString(), doc
+ .getId());
+ }
+ newPub = getStepService().versionDocument(step, pub,
+ dprop);
+ // Remeber the link from the old document to the new document version
+ newVersion.put(pub.value(), newPub.value());
+ // Remember the new version publication
+ newVers.add(newPub);
+ // Remember the previouse document version for the new publication
+ prevVersion.put(newPub, pub.value());
+ } else {
+
+ // Otherwise create a new document of the result type
+ // If result type is not found try to get type by file extension
+ if (resType == null) {
+ dprop.setType(getProjectSettings()
+ .getDefaultDocumentType(step.getStep(),
+ fileFormat));
+ } else {
+ dprop.setType(resType);
+ }
+ dprop.setDescription("Checked in").setName(docname)
+ .setFormat(fileFormat);
+ newPub = getStepService().createDocument(step, dprop);
+
+ // Remeber the new document
+ newDocs.add(newPub);
+ }
+
+ // Attach the file to the created document
+ updir = newPub.getSourceFile().asFile();
+ if (LOG.isInfoEnabled()) {
+ LOG.info("Moving \"" + upfile.getName() + "\" to \""
+ + updir.getPath() + "\".");
+ }
+ if (upfile.renameTo(updir)) {
+ // Save the new publication in the scenario.
+ // The old publication is removed from the scenario here.
+ getPublicationService().saveAs(newPub,
+ ProgressState.inWORK); // May throw FileNotFound if rename was not done
+ }
+ }
+ }
+ }
+
+ // Set uses/used relations
+
+ // For each new version copy uses relations from the previous version.
+ for (Publication newVer : newVers) {
+ // For each Uses relation of the previous version
+ for (Relation rel : prevVersion.get(newVer).getRelations(
+ UsesRelation.class)) {
+ // If used document has been also versioned then refer to its new version.
+ Document usedDoc = ((UsesRelation) rel).getTo();
+ if (newVersion.containsKey(usedDoc)) {
+ usedDoc = newVersion.get(usedDoc);
+ }
+ // Build the appropriate relation for the new version.
+ newVer.addDependency(usedDoc);
+ }
+ // TODO: Outdate documents which depend from the previous version and were not checked in during this operation.
+
+ }
+
+ // For each new document create uses relation to the last versions of
+ // results of the previous step.
+ for (Publication newDoc : newDocs) {
+ // Find used document type according to the configuration.
+ // Find documents of used type in the previous study step.
+
+ // Create uses relation from the new document
+ // to the found document in the previous step.
+ //newDoc.addDependency(to);
+ }
+ // Mark the scenario as checked in
+ checkin(aScenario);
+ }
+
+ /**
+ * Find appropriate step in the array of scenario steps according to the given step DTO.
+ *
+ * @param stepDTO
+ * the stepDTO
+ * @param steps
+ * scenario steps
+ * @return appropriate scenario step
+ * @throws InvalidPropertyException
+ * if appropriate step is not found
+ */
+ private Step findStep(final StepDTO stepDTO, final Step[] steps)
+ throws InvalidPropertyException {
+ int i = 0;
+ Step step = null;
+ do {
+ if (steps[i].getNumber() == stepDTO.getNumber()) {
+ step = steps[i];
+ }
+ i++;
+ } while ((step == null) && (i < steps.length));
+
+ if (step == null) {
+ throw new InvalidPropertyException(MessageKeyEnum.SCN_000001
+ .toString(), stepDTO.getNumber());
+ }
+ return step;
}
/**
_projectSettings = projectSettingsService;
}
+ /**
+ * Get the documentTypeService.
+ *
+ * @return the documentTypeService
+ */
+ public DocumentTypeService getDocumentTypeService() {
+ return _documentTypeService;
+ }
+
+ /**
+ * Set the documentTypeService.
+ *
+ * @param documentTypeService
+ * the documentTypeService to set
+ */
+ public void setDocumentTypeService(
+ final DocumentTypeService documentTypeService) {
+ _documentTypeService = documentTypeService;
+ }
+
}