import java.util.Map;
import java.util.Set;
+import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Order;
+import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
+import org.hibernate.transform.Transformers;
import org.splat.common.properties.MessageKeyEnum;
import org.splat.dal.bo.kernel.Relation;
import org.splat.dal.bo.kernel.Role;
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.ProjectElement;
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.UsedByRelation;
import org.splat.dal.bo.som.UsesRelation;
+import org.splat.dal.bo.som.ValidationCycle;
import org.splat.dal.bo.som.Document.Properties;
import org.splat.dal.dao.kernel.RoleDAO;
import org.splat.dal.dao.kernel.UserDAO;
import org.splat.dal.dao.som.KnowledgeElementTypeDAO;
import org.splat.dal.dao.som.ScenarioDAO;
import org.splat.dal.dao.som.StudyDAO;
+import org.splat.dal.dao.som.ValidationCycleDAO;
+import org.splat.exception.InvalidParameterException;
import org.splat.i18n.I18nUtils;
import org.splat.kernel.InvalidPropertyException;
import org.splat.kernel.MismatchException;
import org.splat.log.AppLogger;
import org.splat.service.dto.DocumentDTO;
import org.splat.service.dto.FileDTO;
+import org.splat.service.dto.ScenarioDTO;
import org.splat.service.dto.StepDTO;
import org.splat.service.technical.IndexService;
import org.splat.service.technical.ProjectSettingsService;
+import org.splat.service.technical.RepositoryService;
+import org.splat.service.technical.StepsConfigService;
import org.splat.som.Step;
import org.splat.util.BeanHelper;
+import org.splat.util.IOUtils;
import org.springframework.transaction.annotation.Transactional;
/**
public final static AppLogger LOG = AppLogger
.getLogger(ScenarioServiceImpl.class);
+ /**
+ * " to " literal.
+ */
+ private static final String TO = " to ";
/**
* Injected index service.
*/
*/
private DocumentTypeService _documentTypeService;
+ /**
+ * Injected validation cycle DAO.
+ */
+ private ValidationCycleDAO _validationCycleDAO;
+
+ /**
+ * Injected project settings service.
+ */
+ private StepsConfigService _stepsConfigService;
+
+ /**
+ * Injected repository service.
+ */
+ private RepositoryService _repositoryService;
+
/**
* Get the projectElementService.
*
_stepService = stepService;
}
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.splat.service.ScenarioService#getStudyScenarios(java.lang.Long)
+ */
+ @Override
+ @Transactional(readOnly = true)
+ public List<ScenarioDTO> getStudyScenarios(final Long studyId) {
+ DetachedCriteria query = DetachedCriteria
+ .forClass(Scenario.class, "scen")
+ .add(Restrictions.eq("owner.rid", studyId))
+ .setProjection(
+ Projections.projectionList().add(
+ Projections.property("scen.title"), "title")
+ .add(Projections.property("scen.rid"), "index"))
+ .setResultTransformer(
+ Transformers.aliasToBean(ScenarioDTO.class));
+ return getScenarioDAO().getFilteredDTOList(query);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.splat.service.ScenarioService#copyStudyContent(long, long, int, long)
+ */
+ @Override
+ @Transactional
+ public void copyStudyContent(final long fromStudyId, final long fromScenId,
+ final int finalStepNum, final long toStudyId)
+ throws InvalidParameterException, MissedPropertyException,
+ InvalidPropertyException, MultiplyDefinedException,
+ NotApplicableException, IOException {
+ Study fromStudy = getStudyService().selectStudy(fromStudyId);
+ if (fromStudy == null) {
+ throw new InvalidParameterException(MessageKeyEnum.STD_000002
+ .toString(), String.valueOf(fromStudyId));
+ }
+ Scenario fromScen = null;
+ for (Scenario scen : fromStudy.getScenariiList()) {
+ if (scen.getIndex() == fromScenId) {
+ fromScen = scen;
+ break;
+ }
+ }
+
+ Study toStudy = getStudyService().selectStudy(toStudyId);
+ if (toStudy == null) {
+ throw new InvalidParameterException(MessageKeyEnum.STD_000002
+ .toString(), String.valueOf(toStudy));
+ }
+
+ // Check if the step is applied to a scenario and scenario is defined
+ if (fromScen == null
+ && getStepsConfigService().stepInvolves(finalStepNum,
+ Scenario.class)) {
+ throw new InvalidParameterException(MessageKeyEnum.SCN_000006
+ .toString(), String.valueOf(fromScenId));
+ }
+
+ // Copy validation cycles
+ copyValidationCycles(fromStudy, toStudy);
+
+ // Copy content of the study up to the given step
+ Map<Publication, Publication> oldToNewPub = new HashMap<Publication, Publication>();
+ copyDocs(fromStudy, toStudy, finalStepNum, oldToNewPub);
+ if (fromScen != null) {
+ copyDocs(fromScen, toStudy.getScenariiList().get(0), finalStepNum,
+ oldToNewPub);
+ }
+ copyDependencies(fromStudy, finalStepNum, oldToNewPub);
+ if (fromScen != null) {
+ copyDependencies(fromScen, finalStepNum, oldToNewPub);
+ }
+ }
+
+ /**
+ * Copy validation cycles from study to study.
+ *
+ * @param fromStudy
+ * the source study
+ * @param toStudy
+ * the destination study
+ */
+ private void copyValidationCycles(final Study fromStudy, final Study toStudy) {
+ for (ValidationCycle fromCycle : fromStudy.getValidationCycles()
+ .values()) {
+ if (fromCycle.isAssigned()) {
+ ValidationCycle cycle = fromCycle.clone(toStudy);
+ getValidationCycleDAO().create(cycle);
+ toStudy.addRelation(cycle.getContext());
+ toStudy.getValidationCycles().put(
+ cycle.getDocumentType().getName(), cycle); // Replaces the cycle if exists as default,
+ }
+ }
+ }
+
+ /**
+ * Copy dependencies between documents from the given project element up to <BR>
+ * the given step according to the given map of old publications to new publications.
+ *
+ * @param from
+ * the source project element
+ * @param finalStepNum
+ * the final step for copy processing
+ * @param oldToNewPub
+ * the old to new publications map
+ */
+ private void copyDependencies(final ProjectElement from,
+ final int finalStepNum,
+ final Map<Publication, Publication> oldToNewPub) {
+ // Copy dependencies between copied documents
+ for (Publication pub : from.getDocums()) {
+ // If the document in the step before the final one
+ if (pub.value().getStep() <= finalStepNum) {
+ Publication newPub = oldToNewPub.get(pub);
+ for (Publication used : pub.getRelations(UsesRelation.class)) {
+ newPub.addDependency(oldToNewPub.get(used));
+ }
+ }
+ }
+ }
+
+ /**
+ * Copy documents with dependencies up to the given step.
+ *
+ * @param from
+ * the source project element
+ * @param to
+ * the destination project element
+ * @param finalStepNum
+ * the final step for copy process
+ * @param oldToNewPub2
+ * @throws MissedPropertyException
+ * if document creation is failed
+ * @throws InvalidPropertyException
+ * if document creation is failed
+ * @throws MultiplyDefinedException
+ * if document creation is failed
+ * @throws IOException
+ * if document file creation is failed
+ * @throws NotApplicableException
+ * if document state is not applicable
+ * @param oldToNewPub
+ * the old to new publications map
+ *
+ */
+ private void copyDocs(final ProjectElement from, final ProjectElement to,
+ final int finalStepNum,
+ final Map<Publication, Publication> oldToNewPub)
+ throws MissedPropertyException, InvalidPropertyException,
+ MultiplyDefinedException, NotApplicableException, IOException {
+ Map<Integer, Step> steps = getProjectElementService().getStepsMap(to);
+ // Copy publications without old versions and relations to not copied steps documents
+ for (Publication pub : from.getDocums()) {
+ // If the document in the step before the final one
+ if (pub.value().getStep() <= finalStepNum) {
+ // Copy the document
+ oldToNewPub.put(pub, createDoc(pub.value(), steps.get(pub
+ .value().getStep())));
+ }
+ }
+ }
+
+ /**
+ * Create a copy of the given document and publish it in the given step.
+ *
+ * @param fromDoc
+ * the source document
+ * @param step
+ * the destination step
+ * @return the created publication
+ * @throws MissedPropertyException
+ * if document creation is failed
+ * @throws InvalidPropertyException
+ * if document creation is failed
+ * @throws MultiplyDefinedException
+ * if document creation is failed
+ * @throws IOException
+ * if document file creation is failed
+ * @throws NotApplicableException
+ * if document state is not applicable
+ */
+ private Publication createDoc(final Document fromDoc, final Step step)
+ throws MissedPropertyException, InvalidPropertyException,
+ MultiplyDefinedException, IOException, NotApplicableException {
+
+ java.io.File srcFile = fromDoc.getSourceFile().asFile();
+ // Creation of the document
+ Document.Properties dprop = new Document.Properties().setName(
+ fromDoc.getTitle()).setType(fromDoc.getType()).setFormat(
+ fromDoc.getFormat()).setAuthor(fromDoc.getAuthor());
+
+ java.io.File tmpDir = getRepositoryService().getDownloadDirectory(
+ step.getOwnerStudy().getAuthor());
+
+ // Remove local file index prefix to get original filename.
+ java.io.File upfile = new java.io.File(tmpDir.getPath()
+ + "/"
+ + srcFile.getName().substring(
+ srcFile.getName().indexOf('_') + 1));
+ // Copy the source file into the temporary folder with original filename.
+ copyFile(srcFile, upfile);
+
+ dprop.setLocalPath(upfile.getPath());
+ Publication addoc = getStepService().createDocument(step, dprop);
+
+ // Move the temporary file into the repository
+ moveFile(upfile, addoc.getSourceFile().asFile());
+
+ getPublicationService().saveAs(addoc, fromDoc.getProgressState());
+
+ // Copy attached files
+ for (Relation rel : fromDoc.getRelations(ConvertsRelation.class)) {
+ File attach = ((ConvertsRelation) rel).getTo();
+ ConvertsRelation export = getPublicationService().attach(addoc,
+ attach.getFormat());
+ // Copy the source document attachment file to the new study vault
+ copyFile(attach.asFile(), export.getTo().asFile());
+ }
+ return addoc;
+ }
+
+ /**
+ * Copy a file. Print info message.
+ *
+ * @param upfile
+ * the source file.
+ * @param file
+ * the target file
+ * @throws IOException
+ * if failed
+ */
+ private void copyFile(final java.io.File upfile, final java.io.File file)
+ throws IOException {
+ if (LOG.isInfoEnabled()) {
+ LOG.info("Copy " + upfile.getAbsolutePath() + TO + file.getPath());
+ }
+ IOUtils.copy(upfile, file);
+ }
+
+ /**
+ * Copy a file. Print info message.
+ *
+ * @param upfile
+ * the source file.
+ * @param file
+ * the target file
+ * @return true if renamed otherwise return false
+ */
+ private boolean moveFile(final java.io.File upfile, final java.io.File file) {
+ if (LOG.isInfoEnabled()) {
+ LOG.info("Move " + upfile.getAbsolutePath() + TO + file.getPath());
+ }
+ return upfile.renameTo(file);
+ }
+
/**
* {@inheritDoc}
*
return study;
}
- /**
+ /**
* {@inheritDoc}
+ *
* @see org.splat.service.ScenarioService#assignStudyContext(java.lang.Long, java.lang.String, java.lang.String)
*/
@Transactional
return kelm;
}
- /**
- * Update the scenario in the database.
- *
- * @param aScenario
- * the scenario to update
- * @return true if updating succeeded
- */
- @Transactional
- private boolean update(final Scenario aScenario) {
- boolean isOk = false;
- try {
- getScenarioDAO().update(aScenario); // Update of relational base
- isOk = true;
- } catch (Exception error) {
- LOG.error("Unable to re-index the knowledge element '"
- + aScenario.getIndex() + "', reason:", error);
- }
- return isOk;
- }
-
/**
* {@inheritDoc}
*
// Attach the file via ConvertsRelation, create a new document or
// create a new version of the document
dprop.setAuthor(aUser).setDate(aDate).setFormat(fileFormat);
+ String authorName = I18nUtils.getMessageLocaleDefault(aUser
+ .getDisplayName());
+ String summary = I18nUtils.getMessageLocaleDefault(
+ MessageKeyEnum.DCT_000005.toString(), authorName);
+ dprop.setDescription(summary);
if (doc.getId() > 0) {
checkinExistingDoc(step, doc, dprop, fileFormat, upfile,
}
docname += "_" + i; // The generated new document title
- dprop.setDescription("Checked in").setName(docname);
+ dprop.setName(docname);
Publication newPub = getStepService().createDocument(step,
dprop);
- // Remeber the new document
+ // Remember the new document
newDocs.add(newPub);
saveFile(newPub, step, upfile);
// If there is no attachment with this extension then attach the new one
ConvertsRelation export = getPublicationService().attach(pub,
fileFormat);
- if (LOG.isDebugEnabled()) {
- LOG.debug("Moving " + upfile.getName() + " to "
- + export.getTo().asFile().getPath());
- }
- upfile.renameTo(export.getTo().asFile());
+ moveFile(upfile, export.getTo().asFile());
} else {
// If an attachment with this extension already exists then
// replace it by the new one
- upfile.renameTo(attach.asFile());
+ moveFile(upfile, attach.asFile());
// Update attached file modification date
attach.setDate(new Date());
}
NotApplicableException {
// Attach the file to the created document
java.io.File updir = newPub.getSourceFile().asFile();
- if (LOG.isDebugEnabled()) {
- LOG.debug("Moving \"" + upfile.getName() + "\" to \""
- + updir.getPath() + "\".");
- }
if (updir.exists()) {
if (updir.delete()) {
LOG.info(MessageKeyEnum.SCN_000003.toString(), updir
} else {
throw new IOException(
"Can't delete the existing destination file to move file from "
- + upfile.getAbsolutePath() + " to "
+ + upfile.getAbsolutePath() + TO
+ updir.getAbsolutePath());
}
}
- if (upfile.renameTo(updir)) {
+ if (moveFile(upfile, 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
} else {
throw new IOException("Can't move file from "
- + upfile.getAbsolutePath() + " to "
- + updir.getAbsolutePath());
+ + upfile.getAbsolutePath() + TO + updir.getAbsolutePath());
}
}
_simulationContextTypeService = simulationContextTypeService;
}
+ /**
+ * Get the validationCycleDAO.
+ *
+ * @return the validationCycleDAO
+ */
+ public ValidationCycleDAO getValidationCycleDAO() {
+ return _validationCycleDAO;
+ }
+
+ /**
+ * Set the validationCycleDAO.
+ *
+ * @param validationCycleDAO
+ * the validationCycleDAO to set
+ */
+ public void setValidationCycleDAO(
+ final ValidationCycleDAO validationCycleDAO) {
+ _validationCycleDAO = validationCycleDAO;
+ }
+
+ /**
+ * Get steps config.
+ *
+ * @return steps config service
+ */
+ private StepsConfigService getStepsConfigService() {
+ return _stepsConfigService;
+ }
+
+ /**
+ * Set steps config service.
+ *
+ * @param stepsConfigService
+ * steps config service
+ */
+ public void setStepsConfigService(
+ final StepsConfigService stepsConfigService) {
+ _stepsConfigService = stepsConfigService;
+ }
+
+ /**
+ * Get the repositoryService.
+ *
+ * @return the repositoryService
+ */
+ public RepositoryService getRepositoryService() {
+ return _repositoryService;
+ }
+
+ /**
+ * Set the repositoryService.
+ *
+ * @param repositoryService
+ * the repositoryService to set
+ */
+ public void setRepositoryService(final RepositoryService repositoryService) {
+ _repositoryService = repositoryService;
+ }
+
}