*/
public class ScenarioServiceImpl implements ScenarioService {
- /**
- * The logger for the service.
- */
- public final static AppLogger LOG = AppLogger
- .getLogger(ScenarioServiceImpl.class);
-
- /**
- * " to " literal.
- */
- private static final String TO = " to ";
- /**
- * Injected index service.
- */
- private IndexService _indexService;
- /**
- * Injected step service.
- */
- private StepService _stepService;
- /**
- * Injected study service.
- */
- private StudyService _studyService;
- /**
- * Injected publication service.
- */
- private PublicationService _publicationService;
- /**
- * Injected project element service.
- */
- private ProjectElementService _projectElementService;
- /**
- * Injected knowledge element DAO.
- */
- private KnowledgeElementDAO _knowledgeElementDAO;
- /**
- * Injected scenario DAO.
- */
- private ScenarioDAO _scenarioDAO;
-
- /**
- * Injected study DAO.
- */
- private StudyDAO _studyDAO;
-
- /**
- * Injected knowledge element service.
- */
- private KnowledgeElementTypeService _knowledgeElementTypeService;
-
- /**
- * Injected user service.
- */
- private UserService _userService;
-
- /**
- * Injected user DAO.
- */
- private UserDAO _userDAO;
-
- /**
- * Injected role DAO.
- */
- private RoleDAO _roleDAO;
-
- /**
- * Injected knowledge element type DAO.
- */
- private KnowledgeElementTypeDAO _knowledgeElementTypeDAO;
-
- /**
- * Injected document DAO.
- */
- private DocumentDAO _documentDAO;
-
- /**
- * Injected simulation context service.
- */
- private SimulationContextService _simulationContextService;
-
- /**
- * Injected simulation context type service.
- */
- private SimulationContextTypeService _simulationContextTypeService;
-
- /**
- * Injected project service.
- */
- private ProjectSettingsService _projectSettings;
-
- /**
- * Injected document type 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.
- *
- * @return the projectElementService
- */
- public ProjectElementService getProjectElementService() {
- return _projectElementService;
- }
-
- /**
- * Set the projectElementService.
- *
- * @param projectElementService
- * the projectElementService to set
- */
- public void setProjectElementService(
- final ProjectElementService projectElementService) {
- _projectElementService = projectElementService;
- }
-
- /**
- * Get the publicationService.
- *
- * @return the publicationService
- */
- public PublicationService getPublicationService() {
- return _publicationService;
- }
-
- /**
- * Set the publicationService.
- *
- * @param publicationService
- * the publicationService to set
- */
- public void setPublicationService(
- final PublicationService publicationService) {
- _publicationService = publicationService;
- }
-
- /**
- * Get the stepService.
- *
- * @return the stepService
- */
- public StepService getStepService() {
- return _stepService;
- }
-
- /**
- * Set the stepService.
- *
- * @param stepService
- * the stepService to set
- */
- public void setStepService(final StepService stepService) {
- _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());
- }
- file.delete(); // necessary on some platforms if the file exists.
- return upfile.renameTo(file);
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.splat.service.ScenarioService#getScenarioInfo(long)
- */
- @Transactional(readOnly = true)
- public List<StepDTO> getScenarioInfo(final long scenarioId) {
- List<StepDTO> res = new ArrayList<StepDTO>();
- // Get the scenario from the database by id
- Scenario scen = getScenarioDAO().get(scenarioId);
- if (LOG.isDebugEnabled()) {
- LOG.debug("Scenario[" + scenarioId + "]: Number of publications: "
- + scen.getDocums().size());
- }
- // Get activities of the scenario
- Step[] steps = getProjectElementService().getSteps(scen);
- StepDTO stepDTO;
- DocumentDTO docDTO;
- String docType, fileFormat;
- String processing;
- boolean doImport;
- // For each activity create a step DTO and add it to the result list
- for (Step step : steps) {
- stepDTO = BeanHelper.copyBean(step.getStep(), StepDTO.class);
- res.add(stepDTO);
- if (LOG.isDebugEnabled()) {
- LOG.debug("Step[" + stepDTO.getNumber()
- + "]: Number of documents: "
- + step.getDocuments().size());
- }
- // For each publication of the activity create a document DTO.
- // Each file is considered as a source file.
- for (Publication tag : step.getDocuments()) {
- docDTO = stepDTO.addDoc(tag.value().getIndex(), tag.value()
- .getTitle());
- char aState = tag.getIsnew();
- docType = tag.value().getType().getName();
- // For each file of the document create a file DTO
- // Process source file of the document
- fileFormat = tag.value().getFile().getFormat();
- doImport = getProjectSettings().doImport(docType, fileFormat);
- if (doImport && (!tag.isOutdated())) {
- processing = "file-import";
- } else {
- processing = "file-download";
- }
- File aFile = tag.value().getFile();
- docDTO.addFile(aFile.getIndex(), aFile.getRelativePath(),
- aState, processing, false);
- // Process all exported files
- for (Relation rel : tag.value().getRelations(
- ConvertsRelation.class)) {
- aFile = ((ConvertsRelation) rel).getTo();
- fileFormat = aFile.getFormat();
- doImport = getProjectSettings().doImport(docType,
- fileFormat);
- if (doImport && (!tag.isOutdated())) {
- processing = "file-import";
- } else {
- processing = "file-download";
- }
- docDTO.addFile(aFile.getIndex(), aFile.getRelativePath(),
- aState, processing, false);
- }
- }
- }
- return res;
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.splat.service.ScenarioService#createStudy(java.lang.String, java.lang.String, java.lang.String, java.lang.String)
- */
- @Transactional
- public long createStudy(final String username, final String title,
- final String productName, final String description)
- throws InvalidPropertyException, MissedPropertyException,
- MultiplyDefinedException {
- long id = 0;
-
- // Find the author
- User author = getUserService().selectUser(username);
- if (author == null) {
- // User is not found
- throw new InvalidPropertyException(MessageKeyEnum.USR_000001
- .toString(), username);
- }
-
- // Set the study properties
- Study.Properties sprop = new Study.Properties();
- sprop.setTitle(title).setManager(author);
- sprop.setDescription(description);
-
- // Find the product simulation context
- SimulationContextType productContextType = getSimulationContextService()
- .selectType("product");
- SimulationContext.Properties cprop = new SimulationContext.Properties();
- cprop.setType(productContextType).setValue(productName);
- SimulationContext productCtx = getSimulationContextService()
- .selectSimulationContext(productContextType, productName);
- if (productCtx != null) {
- cprop.setIndex(productCtx.getIndex());
- }
-
- // Set a first scenario properties
- Scenario.Properties oprop = new Scenario.Properties();
- oprop.setTitle(I18nUtils.getMessageLocaleDefault("label.scenario")
- + " 1");
-
- Study study = createStudy(sprop, oprop, cprop);
- id = study.getIndex();
-
- return id;
- }
-
- /**
- * Create a new study with one scenario and "product" simulation context.
- *
- * @param sprop
- * the study properties
- * @param oprop
- * the scenario properties
- * @param cprop
- * the "product" simulation context properties
- * @return the created study
- * @throws MissedPropertyException
- * if a mandatory property is missed
- * @throws InvalidPropertyException
- * if a property is invalid
- * @throws MultiplyDefinedException
- * if some property occurs several times
- */
- @Transactional
- public Study createStudy(final Study.Properties sprop,
- final Scenario.Properties oprop,
- final SimulationContext.Properties cprop)
- throws MissedPropertyException, InvalidPropertyException,
- MultiplyDefinedException {
- Study study = getStudyService().createStudy(sprop);
- addScenario(study, oprop);
- if (cprop.getIndex() == 0) { // Input of new project context
- cprop.setType(getSimulationContextService().selectType("product"))
- .setValue(cprop.getValue());
- getStudyService().addProjectContext(study, cprop);
- } else { // Selection of existing project context
- SimulationContext context = getSimulationContextService()
- .selectSimulationContext(cprop.getIndex());
- getStudyService().addProjectContext(study, context);
- }
- return study;
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.splat.service.ScenarioService#assignStudyContext(java.lang.Long, java.lang.String, java.lang.String)
- */
- @Transactional
- public void assignStudyContext(final Long studyId, final String ctxType,
- final String ctxValue) throws MissedPropertyException,
- InvalidPropertyException, MultiplyDefinedException {
- // Find the study by the given id
- Study study = getStudyDAO().get(studyId);
- if (study == null) {
- throw new InvalidPropertyException(MessageKeyEnum.STD_000002
- .toString(), studyId);
- }
- // Find the context type by its name
- SimulationContextType celt = getSimulationContextService().selectType(
- ctxType);
- if (celt == null) {
- // Creation of a new context type
- celt = getSimulationContextTypeService().createType(ctxType,
- getProjectElementService().getFirstStep(study).getStep());
- }
- // Find the given context value of the given type
- SimulationContext context = getSimulationContextService()
- .selectSimulationContext(celt, ctxValue);
- if (context == null) { // Input of a new project context
- SimulationContext.Properties cprop = new SimulationContext.Properties();
- cprop.setType(celt).setValue(ctxValue);
- getStudyService().addProjectContext(study, cprop);
- } else { // Selection of existing project context
- getStudyService().addProjectContext(study, context);
- }
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.splat.service.ScenarioService#addKnowledgeElement(org.splat.dal.bo.som.Scenario,
- * org.splat.dal.bo.som.KnowledgeElement.Properties)
- */
- @Transactional
- public KnowledgeElement addKnowledgeElement(final Scenario aScenarioDTO,
- final KnowledgeElement.Properties kprop)
- throws MissedPropertyException, InvalidPropertyException,
- MultiplyDefinedException {
- KnowledgeElement kelm = null;
- // try {
- long aScenarioId = aScenarioDTO.getIndex();
- if (LOG.isDebugEnabled()) {
- LOG
- .debug("Add a knowledge element to the scenario #"
- + aScenarioId);
- }
- // Get the persistent scenario.
- Scenario aScenario = getScenarioDAO().get(aScenarioId);
- // Get persistent objects for creating a new knowledge.
- // TODO: Actions must use DTO instead of persistent objects.
- getUserDAO().merge(kprop.getAuthor());
- getKnowledgeElementTypeDAO().merge(kprop.getType());
- // Create a transient knowledge element related to the given scenario.
- kelm = new KnowledgeElement(kprop.setOwnerScenario(aScenario));
- // Save the new knowledge in the database.
- getKnowledgeElementDAO().create(kelm);
- // Update scenario transient data.
- if (kelm.getType().equals("usecase")) {
- aScenarioDTO.setUcase(kelm);
- } else if (aScenarioDTO.getKnowledgeElementsList() != null) { // If null, knowl will be initialized when needed
- aScenarioDTO.getKnowledgeElementsList().add(kelm);
- }
-
- // Load the workflow for the parent study to take into account
- // all study actors durng reindexing.
- getStudyService().loadWorkflow(aScenario.getOwnerStudy());
-
- // // Update the lucene index of knowledge elements.
- // getIndexService().add(kelm);
- if (LOG.isDebugEnabled()) {
- LOG.debug("A knowledge element #" + kelm.getIndex()
- + " is added to the scenario #" + aScenario.getIndex());
- }
- // } catch (IOException error) {
- // LOG.error("Unable to index the knowedge element '"
- // + kelm.getIndex() + "', reason:", error);
- // kelm = null;
- // }
-
- return kelm;
- }
-
- /**
- * {@inheritDoc}
- *
- * @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) 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();
-
- // Keep newly created documents to create uses relations to results of a previous step.
- // For each processed existing document keep its new version
- Map<Document, Document> newVersion = new HashMap<Document, Document>();
- // Created publications of new created versions of existing documents
- List<Publication> newVers = new ArrayList<Publication>();
- // The list of publications of new created documents not existing before the checkin
- List<Publication> newDocs = new ArrayList<Publication>();
- // For each step DTO
- DocumentType resType;
- Date aDate = new Date(); // The timestamp of the checkin operation
- for (StepDTO stepDTO : scInfo) {
- if (LOG.isDebugEnabled()) {
- LOG.debug("Checkin the step:\n" + stepDTO);
- }
- if (stepDTO.getDocs().size() == 0) {
- break;
- }
- // 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);
-
- List<FileDTO> filesToBeAttached = new ArrayList<FileDTO>();
- FileDTO fileToAttachTo = null; //all the rest documents will be attached to it
-
- //The id is the same for all DocumentDTOs of a step
- Long currentDocId = stepDTO.getDocs().get(0).getId();
- if(currentDocId != null && currentDocId > 0) { //there is a result document in the step
- String currentFormat = step.getDocument(currentDocId).value().getFormat();
-
- // Process each document of the step
- for (DocumentDTO doc : stepDTO.getDocs()) {
- for (FileDTO fileDTO : doc.getFiles()) {
-
- String path = fileDTO.getPath();
- String format = path.substring(path.lastIndexOf('.') + 1);
-
- // If it has the same format as current doc (there can be just one such file)
- // then this doc will be DocToAttachTo.
- if (format != null && format.equals(currentFormat)) {
- fileToAttachTo = fileDTO;
- } else {
- // Else, put it in the list of docs that will be attached to DocToAttachTo
- filesToBeAttached.add(fileDTO);
- }
- }
- }
- } else {
- // Process each document of the step
- for (DocumentDTO doc : stepDTO.getDocs()) {
- for (FileDTO fileDTO : doc.getFiles()) {
- String path = doc.getFiles().get(0).getPath();
- String format = path.substring(path.lastIndexOf('.') + 1);
-
- ProjectSettingsService.Step stepType = step.getStep();
- // If the default type for its format in the current step is the result type,
- // then this doc will be DocToAttachTo.
- DocumentType defaultDocType = _projectSettings.getDefaultDocumentType(stepType, format);
- if (defaultDocType != null && defaultDocType.isResultOf(stepType)) {
- //It is possible that there is not just one such doc
- if(fileToAttachTo != null){
- filesToBeAttached.add(fileToAttachTo);
- }
- fileToAttachTo = fileDTO;
- } else {
- // Else, put it in the list of docs that will be attached to DocToAttachTo
- filesToBeAttached.add(fileDTO);
- }
- }
- }
-
- //could not find any file with appropriate format
- if (fileToAttachTo == null && !filesToBeAttached.isEmpty()) {
- //All the rest documents will be attached to the first in the list
- fileToAttachTo = filesToBeAttached.get(0);
- filesToBeAttached.remove(0);
- }
- }
-
- if (fileToAttachTo != null) { // true if the DocumentDTO list is not empty
-
- //Process docToAttachTo
- Publication pub = checkinDoc(step, fileToAttachTo, currentDocId,
- aUser, resType, aDate,
- newVersion, newVers, newDocs);
- currentDocId = pub.value().getIndex();
- }
-
- //Process rest docs
- for (FileDTO file : filesToBeAttached) {
- checkinDoc(step, file, currentDocId, aUser, resType, aDate, newVersion,
- newVers, newDocs);
- }
- }
-
- // Set uses/used relations
- updateRelationsAfterCheckin(aScenario, newVersion, newVers, newDocs);
-
- // Mark the scenario as checked in
- checkin(aScenario);
- }
-
- /**
- * Updated uses/used relations after checkin operation:<BR>
- * <ul>
- * <li>For each new version copy uses relations from the previous version.</li>
- * <li>Outdate documents which depend from the previous version and were not checked in during this operation.</li>
- * <li>For each new document create uses relation to the last versions of results of the previous step.</li>
- * </ul>
- *
- * @param aScenario
- * the checked in scenario
- * @param newVersion
- * the mapping of documents existed before the checkin to their new created versions
- * @param newVers
- * the list of publications of new created versions of documents existed before the checkin
- * @param newDocs
- * the list of publications of new created documents not existed before the checkin
- */
- private void updateRelationsAfterCheckin(final Scenario aScenario,
- final Map<Document, Document> newVersion,
- final List<Publication> newVers, final List<Publication> newDocs) {
- // For each new version copy uses relations from the previous version.
- for (Publication newVer : newVers) {
- // For each Uses relation of the previous version
- Document prevDoc = newVer.value().getPreviousVersion();// prevVersion.get(newVer);
- if (LOG.isDebugEnabled()) {
- LOG.debug("Previous version for publication #"
- + newVer.getIndex() + " is found: " + prevDoc);
- }
- List<Relation> usesRelations = prevDoc
- .getRelations(UsesRelation.class);
- for (Relation rel : usesRelations) {
- // 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);
- }
- // Outdate documents which depend from the previous version and
- // were not checked in during this operation.
- // 1. Get all usedBy relations of the previous document version
- for (Relation rel : prevDoc.getRelations(UsedByRelation.class)) {
- Document using = ((UsedByRelation) rel).getTo();
- // Check that not checked in dependent documents became outdated
- Publication usingPub = aScenario.getPublication(using);
- if (usingPub != null) { // if the document using the old version is still published
- usingPub.setIsnew('O');
- }
- }
- }
-
- // For each new document create uses relation to the last versions of
- // results of the previous step.
- for (Publication newPub : newDocs) {
- // Find used document type according to the configuration.
- Set<DocumentType> usedTypes = newPub.value().getType()
- .getDefaultUses();
- // Find documents of used type in the previous study step.
- for (Publication pub : aScenario.getDocums()) {
- if ((pub.getStep().getNumber() <= newPub.getStep().getNumber())
- && (!pub.isOutdated())
- && usedTypes.contains(pub.value().getType())
- && !newPub.equals(pub)) {
- // Create uses relation from the new document
- // to the found document in the previous step.
- newPub.addDependency(pub);
- }
- }
- }
- }
-
- /**
- * Pure checkin of the document without creation of uses/usedBy relations. For an existing document a new version is created. New
- * documents become published in the given step of the appropriate scenario. The appropriate uploaded file is attached to the created
- * document and the document is published in the scenario. The publication of the old version is removed from the scenario.
- *
- * @param step
- * the destination scenario step
- * @param file
- * the FilDTO to checkin
- * @param docId
- * target document id
- * @param aUser
- * the user who performs checkin
- * @param resType
- * the result document type of the given step
- * @param aDate
- * timestamp of the checkin operation
- * @param newVersion
- * the mapping of existing documents to their new created versions
- * @param newVers
- * the list of publications of new created versions of existing documents
- * @param newDocs
- * the list of publications of new created documents not existing before the checkin
- * @return
- * the newly created publication, if exists (the document has been created or versioned),
- * null otherwise (the doc has been attached to the old one)
- * @throws InvalidPropertyException
- * if the scenario hasn't some of given steps or documents
- * @throws IOException
- * if a file can't be moved into the vault
- * @throws MismatchException
- * if version creation in some of steps is failed
- * @throws MissedPropertyException
- * if some mandatory property is missed when new document or new document version is created
- * @throws MultiplyDefinedException
- * if some property is defined several times when new document or new document version is created
- * @throws NotApplicableException
- * if failed saving of a new publication with a given state
- */
- private Publication checkinDoc(final Step step, final FileDTO file,
- final long docId, final User aUser, final DocumentType resType,
- final Date aDate, final Map<Document, Document> newVersion,
- final List<Publication> newVers, final List<Publication> newDocs)
- throws InvalidPropertyException, MismatchException,
- MissedPropertyException, MultiplyDefinedException, IOException,
- NotApplicableException {
- Publication newPub = null;
- if (file != null) {
- Document.Properties dprop = new Document.Properties();
- // NOTE: Process only the first attached file for each document
- dprop.setLocalPath(file.getPath());
-
- // 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);
-
- // 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 (docId > 0) {
- newPub = checkinExistingDoc(step, docId, dprop, fileFormat, upfile,
- newVersion, newVers);
- } 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);
- }
- // New document title generation as <document type name>_N
- String docname = dprop.getType().getName();
- int i = 1;
- for (Publication scenPub : step.getOwner().getDocums()) {
- if (scenPub.value().getTitle().startsWith(docname)) {
- i++;
- }
- }
- docname += "_" + i; // The generated new document title
-
- dprop.setName(docname);
- newPub = getStepService().createDocument(step,
- dprop);
-
- // Remember the new document
- newDocs.add(newPub);
-
- saveFile(newPub, step, upfile);
- }
- }
- return newPub;
- }
-
- /**
- * Check in existing document.
- *
- * @param step
- * study step to check in
- * @param docId
- * target document id
- * @param dprop
- * document properties
- * @param fileFormat
- * checked in file format
- * @param upfile
- * the file to check in
- * @param newVersion
- * the map of created versions during this check in
- * @param newVers
- * the list of new versions created during this check in
- * @return
- * the newly created publication, if exists (the document has been versioned),
- * null otherwise (the doc has been attached to the old one)
- * @throws InvalidPropertyException
- * if publication of the document is not found in the step
- * @throws MismatchException
- * if the found publication does not point to a document
- * @throws IOException
- * if can not move the file into the vault
- * @throws MultiplyDefinedException
- * thrown by versionDocument
- * @throws MissedPropertyException
- * thrown by versionDocument
- * @throws NotApplicableException
- * if failed saving of a new publication with a given state
- */
- private Publication checkinExistingDoc(final Step step, final long docId,
- final Properties dprop, final String fileFormat,
- final java.io.File upfile,
- final Map<Document, Document> newVersion,
- final List<Publication> newVers) throws InvalidPropertyException,
- MismatchException, MissedPropertyException,
- MultiplyDefinedException, IOException, NotApplicableException {
- // If the document already exists then
- // Attach the file via ConvertsRelation if the extension of the
- // new file differs from the old one.
- // If file format (i.e. extension) is the same then create a new
- // version of the document.
- // Find the document publication
- //Publication pub = step.getDocument(doc.getId());
- Publication pub = step.getDocument(docId);
- Publication newPub = null;
- if (pub == null) {
- throw new InvalidPropertyException(MessageKeyEnum.SCN_000002
- .toString(), docId);
- }
- if (pub.value() == null) {
- throw new MismatchException(MessageKeyEnum.SCN_000002.toString(),
- docId);
- }
- if (LOG.isDebugEnabled()) {
- LOG.debug("Old format: " + pub.value().getFormat()
- + " => New format: " + fileFormat);
- }
- // If formats are same then create a new document version
- if (pub.value().getFormat() != null
- && pub.value().getFormat().equals(fileFormat)) {
- newPub = getStepService().versionDocument(step, pub,
- dprop);
- if (LOG.isDebugEnabled()) {
- LOG.debug("Created document type: "
- + newPub.value().getType().getName() + ", format: "
- + newPub.value().getFormat());
- }
- // 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);
-
- saveFile(newPub, step, upfile);
-
- } else { // If formats are different then attach the new file via ConvertsRelation
- File attach = pub.value().getAttachedFile(fileFormat);
- if (attach == null) {
- // If there is no attachment with this extension then attach the new one
- ConvertsRelation export = getPublicationService().attach(pub,
- fileFormat);
- moveFile(upfile, export.getTo().asFile());
- } else {
- // If an attachment with this extension already exists then
- // replace it by the new one
- moveFile(upfile, attach.asFile());
- // Update attached file modification date
- attach.setDate(new Date());
- }
- }
- return newPub;
- }
-
- /**
- * Save the file in the vault and create its publication in the step.
- *
- * @param newPub
- * the new publication to save
- * @param step
- * the study step to publish the document
- * @param upfile
- * the downloaded file
- * @throws IOException
- * if a file can't be moved into the vault
- * @throws NotApplicableException
- * if failed saving of a new publication with a given state
- */
- private void saveFile(final Publication newPub, final Step step,
- final java.io.File upfile) throws IOException,
- NotApplicableException {
- // Attach the file to the created document
- java.io.File updir = newPub.getSourceFile().asFile();
- if (updir.exists()) {
- if (updir.delete()) {
- LOG.info(MessageKeyEnum.SCN_000003.toString(), updir
- .getAbsoluteFile(), step.getOwner().getIndex());
- } else {
- throw new IOException(
- "Can't delete the existing destination file to move file from "
- + upfile.getAbsolutePath() + TO
- + updir.getAbsolutePath());
- }
- }
- 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());
- }
- }
-
- /**
- * 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;
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.splat.service.ScenarioService#checkin(long)
- */
- @Transactional
- public void checkin(final long scenarioId) throws InvalidPropertyException {
- Scenario aScenario = getScenarioDAO().get(scenarioId);
- if (aScenario == null) {
- // Scenario not found
- throw new InvalidPropertyException(MessageKeyEnum.SCN_000006
- .toString(), scenarioId);
- }
- checkin(aScenario);
- }
-
- /**
- * Mark the scenario as checked in.
- *
- * @param aScenario
- * the scenario to check in.
- */
- private void checkin(final Scenario aScenario) {
- aScenario.setUser(null);
- aScenario.setLastModificationDate(Calendar.getInstance().getTime());
- // getScenarioDAO().update(aScenario);
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.splat.service.ScenarioService#checkout(org.splat.dal.bo.som.Scenario, org.splat.dal.bo.kernel.User)
- */
- public boolean checkout(final Scenario aScenario, final User user) {
- boolean res = getStudyService().isStaffedBy(aScenario.getOwnerStudy(),
- user);
- if (res) {
- aScenario.setUser(user);
- aScenario.setLastModificationDate(Calendar.getInstance().getTime());
- // RKV: getScenarioDAO().update(aScenario);
- }
- return res;
- }
-
- /**
- * Mark the given scenario as checked out by the given user.
- *
- * @param scenarioId
- * the scenario id
- * @param userId
- * the id of the user performing the check out
- * @throws InvalidPropertyException
- * if the user or the scenario is not found in the database
- * @throws NotApplicableException
- * if the given user can not check out the scenario
- */
- @Transactional
- public void checkout(final long scenarioId, final long userId)
- throws InvalidPropertyException, NotApplicableException {
- User aUser = getUserService().selectUser(userId);
- if (aUser == null) {
- // User not found
- throw new InvalidPropertyException(MessageKeyEnum.USR_000001
- .toString(), userId);
- }
- Scenario aScenario = getScenarioDAO().get(scenarioId);
- if (aScenario == null) {
- // Scenario not found
- throw new InvalidPropertyException(MessageKeyEnum.SCN_000006
- .toString(), scenarioId);
- }
- boolean res = getStudyService().isStaffedBy(aScenario.getOwnerStudy(),
- aUser);
- if (res) {
- if (aScenario.isCheckedout()
- && (!aScenario.getUser().getUsername().equals(
- aUser.getUsername()))) {
- throw new NotApplicableException(MessageKeyEnum.SCN_000008
- .toString(), scenarioId, aScenario.getUser()
- .getUsername());
- }
- aScenario.setUser(aUser);
- aScenario.setLastModificationDate(Calendar.getInstance().getTime());
- } else {
- // User doesn't participate in the scenario
- throw new NotApplicableException(MessageKeyEnum.SCN_000007
- .toString(), aUser.getUsername(), scenarioId);
- }
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.splat.service.ScenarioService#copyContentsUpTo(org.splat.dal.bo.som.Scenario, org.splat.som.Step)
- */
- public void copyContentsUpTo(final Scenario scenario, final Step lastep) {
- Scenario base = (Scenario) lastep.getOwner();
- Step[] from = getProjectElementService().getSteps(base);
- Step[] to = getProjectElementService().getSteps(scenario);
- for (int i = 0; i < from.length; i++) {
- Step step = from[i];
- if (step.getNumber() > lastep.getNumber()) {
- break;
- }
-
- List<Publication> docs = step.getAllDocuments();
- for (Iterator<Publication> j = docs.iterator(); j.hasNext();) {
- Publication doc = getPublicationService().copy(j.next(),
- scenario); // Creation of a new reference to the document
- // Database.getSession().save(doc); Publications MUST be saved later through cascading when saving the scenario
- getStepService().add(to[i], doc);
- }
- List<SimulationContext> ctex = step.getAllSimulationContexts();
- for (Iterator<SimulationContext> j = ctex.iterator(); j.hasNext();) {
- getStepService().addSimulationContext(to[i], j.next());
- }
- }
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.splat.service.ScenarioService#isEmpty(org.splat.dal.bo.som.Scenario)
- */
- public boolean isEmpty(final Scenario scenario) {
- Step[] mystep = getProjectElementService().getSteps(scenario);
- boolean isEmp = true;
- for (int i = 0; i < mystep.length; i++) {
- if (mystep[i].isStarted()) {
- isEmp = false;
- break;
- }
- }
- return isEmp;
- }
-
- /**
- * @param scenario
- * @return
- */
- public boolean isFinished(final Scenario scenario) {
- Step[] mystep = getProjectElementService().getSteps(scenario);
- boolean notempty = false; // If this is empty, this is not finished
- for (int i = 0; i < mystep.length; i++) {
- if (!mystep[i].isStarted()) {
- continue;
- }
- if (!mystep[i].isFinished()) {
- return false;
- }
- notempty = true;
- }
- return notempty;
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.splat.service.StudyService#addScenario(org.splat.dal.bo.som.Study, org.splat.dal.bo.som.Scenario.Properties)
- */
- @Transactional
- public Scenario addScenario(final Study aStudy,
- final Scenario.Properties sprop) throws MissedPropertyException,
- InvalidPropertyException, MultiplyDefinedException {
- if (sprop.getManager() == null) {
- sprop.setManager(aStudy.getAuthor());
- }
-
- Scenario scenario = new Scenario(sprop.setOwnerStudy(aStudy));
- if (sprop.getBaseStep() != null) {
- copyContentsUpTo(scenario, sprop.getBaseStep());
- }
- Scenario previous = sprop.getInsertAfter();
-
- if (previous == null) {
- aStudy.getScenariiList().add(scenario);
- } else {
- aStudy.getScenariiList().add(
- aStudy.getScenariiList().indexOf(previous) + 1, scenario);
- }
- getStudyDAO().update(aStudy); // No need to update the Lucene index
- getScenarioDAO().create(scenario); // Must be done after updating this study because of the back reference to the study
- if (sprop.getBaseStep() != null) {
- // No need to update the Knowledge Element index as Knowledge Elements are not copied
- getProjectElementService().refresh(scenario); // Because saving the scenario changes the hashcode of copied Publications
- }
- KnowledgeElementType ucase = getKnowledgeElementTypeService()
- .selectType("usecase");
- KnowledgeElement.Properties kprop = new KnowledgeElement.Properties();
- // TODO: Get appropriate user by its role: UserService.getAdmin();
- // User admin = getUserService().selectUser(1); // First user created when creating the database
- Role adminRole = getRoleDAO().getFilteredList(
- Restrictions.like("role", "%sysadmin%")).get(0);
- User admin = getUserDAO().getFilteredList(
- Restrictions.eq("role", adminRole), Order.asc("rid")).get(0); // First sysadmin in the database
-
- kprop.setType(ucase).setTitle(aStudy.getTitle()).setValue(
- scenario.getTitle()).setAuthor(admin); // Internal Knowledge Element required by the validation process of
- // knowledges
- addKnowledgeElement(scenario, kprop);
- return scenario;
- }
-
- /**
- * Remove a knowledge element from a scenario.
- *
- * @param scenario
- * the scenario
- * @param kelm
- * the knowledge element to remove
- * @return true if removal succeeded
- */
- @Transactional
- public boolean removeKnowledgeElement(final Scenario scenario,
- final KnowledgeElement kelm) {
- KnowledgeElement torem = scenario.getKnowledgeElement(kelm.getIndex());
- boolean isOk = (torem != null);
- if (isOk) {
- isOk = scenario.getKnowledgeElements().remove(torem);
- if (isOk) {
- getScenarioDAO().merge(scenario);
- // Update of my transient data
- // RKV: These transient data are not used indeed.
- // RKV: List<KnowledgeElement> kelms = scenario.getKnowledgeByType().get(
- // RKV: kelm.getType().getIndex());
- // RKV: kelms.remove(torem);
- if (scenario.getKnowledgeElementsList() != null) {
- scenario.getKnowledgeElementsList().remove(torem);
- }
- // TODO: If the owner study is not private, remove the knowledge from the Lucene index
- }
- }
- return isOk;
- }
-
- /**
- *
- * {@inheritDoc}
- *
- * @see org.splat.service.ScenarioService#renameScenario(java.lang.String)
- */
- @Transactional
- public void renameScenario(final Scenario scenario) {
- getScenarioDAO().merge(scenario);
- }
-
- /**
- * {@inheritDoc}
- * @see org.splat.service.ScenarioService#removeScenario(long)
- */
- @Transactional
- public void removeScenario(final long scenarioId) {
- Scenario scenario = getScenarioDAO().get(scenarioId);
- Study study = scenario.getOwnerStudy();
-
- if (scenario != null && study != null) {
- getScenarioDAO().delete(scenario);
-
- // Collect all documents which are published in another scenario
- // or are previous versions of documents published in another scenario
- Set<Document> untouched = new HashSet<Document>();
-
- List<Scenario> otherScenarios = study.getScenariiList();
- otherScenarios.remove(scenario);
-
- for (Scenario otherScenario : otherScenarios) {
- for (Publication publication : otherScenario.getDocums()) {
- for (Document document = publication.value(); document != null;
- document = document.getPreviousVersion()) {
- untouched.add(document);
- }
- }
- }
-
- // Collect all documents which are published in this scenario
- // or are previous versions of documents published in this scenario
- Set<Document> toRemove = new HashSet<Document>();
- for (Publication publication : scenario.getDocums()) {
- for (Document document = publication.value(); document != null;
- document = document.getPreviousVersion()) {
- toRemove.add(document);
- }
- }
-
- toRemove.removeAll(untouched);
-
- // Delete all necessary documents
- for (Document document : toRemove) {
- _documentDAO.delete(document);
- }
- }
- }
-
- /**
- * Get the knowledgeElementDAO.
- *
- * @return the knowledgeElementDAO
- */
- public KnowledgeElementDAO getKnowledgeElementDAO() {
- return _knowledgeElementDAO;
- }
-
- /**
- * Set the knowledgeElementDAO.
- *
- * @param knowledgeElementDAO
- * the knowledgeElementDAO to set
- */
- public void setKnowledgeElementDAO(
- final KnowledgeElementDAO knowledgeElementDAO) {
- _knowledgeElementDAO = knowledgeElementDAO;
- }
-
- /**
- * Get the indexService.
- *
- * @return the indexService
- */
- public IndexService getIndexService() {
- return _indexService;
- }
-
- /**
- * Set the indexService.
- *
- * @param indexService
- * the indexService to set
- */
- public void setIndexService(final IndexService indexService) {
- _indexService = indexService;
- }
-
- /**
- * Get the scenarioDAO.
- *
- * @return the scenarioDAO
- */
- public ScenarioDAO getScenarioDAO() {
- return _scenarioDAO;
- }
-
- /**
- * Set the scenarioDAO.
- *
- * @param scenarioDAO
- * the scenarioDAO to set
- */
- public void setScenarioDAO(final ScenarioDAO scenarioDAO) {
- _scenarioDAO = scenarioDAO;
- }
-
- /**
- * Get the studyDAO.
- *
- * @return the studyDAO
- */
- public StudyDAO getStudyDAO() {
- return _studyDAO;
- }
-
- /**
- * Set the studyDAO.
- *
- * @param studyDAO
- * the studyDAO to set
- */
- public void setStudyDAO(final StudyDAO studyDAO) {
- _studyDAO = studyDAO;
- }
-
- /**
- * Get the knowledgeElementTypeService.
- *
- * @return the knowledgeElementTypeService
- */
- public KnowledgeElementTypeService getKnowledgeElementTypeService() {
- return _knowledgeElementTypeService;
- }
-
- /**
- * Set the knowledgeElementTypeService.
- *
- * @param knowledgeElementTypeService
- * the knowledgeElementTypeService to set
- */
- public void setKnowledgeElementTypeService(
- final KnowledgeElementTypeService knowledgeElementTypeService) {
- _knowledgeElementTypeService = knowledgeElementTypeService;
- }
-
- /**
- * Get the studyService.
- *
- * @return the studyService
- */
- public StudyService getStudyService() {
- return _studyService;
- }
-
- /**
- * Set the studyService.
- *
- * @param studyService
- * the studyService to set
- */
- public void setStudyService(final StudyService studyService) {
- _studyService = studyService;
- }
-
- /**
- * Get the userService.
- *
- * @return the userService
- */
- public UserService getUserService() {
- return _userService;
- }
-
- /**
- * Set the userService.
- *
- * @param userService
- * the userService to set
- */
- public void setUserService(final UserService userService) {
- _userService = userService;
- }
-
- /**
- * Get the userDAO.
- *
- * @return the userDAO
- */
- public UserDAO getUserDAO() {
- return _userDAO;
- }
-
- /**
- * Set the userDAO.
- *
- * @param userDAO
- * the userDAO to set
- */
- public void setUserDAO(final UserDAO userDAO) {
- _userDAO = userDAO;
- }
-
- /**
- * Get the knowledgeElementTypeDAO.
- *
- * @return the knowledgeElementTypeDAO
- */
- public KnowledgeElementTypeDAO getKnowledgeElementTypeDAO() {
- return _knowledgeElementTypeDAO;
- }
-
- /**
- * Set the knowledgeElementTypeDAO.
- *
- * @param knowledgeElementTypeDAO
- * the knowledgeElementTypeDAO to set
- */
- public void setKnowledgeElementTypeDAO(
- final KnowledgeElementTypeDAO knowledgeElementTypeDAO) {
- _knowledgeElementTypeDAO = knowledgeElementTypeDAO;
- }
-
- /**
- * Get the documentDAO.
- * @return the documentDAO
- */
- public DocumentDAO getDocumentDAO() {
- return _documentDAO;
- }
-
- /**
- * Set the documentDAO.
- * @param documentDAO the documentDAO to set
- */
- public void setDocumentDAO(final DocumentDAO documentDAO) {
- _documentDAO = documentDAO;
- }
-
- /**
- * Get the simulationContextService.
- *
- * @return the simulationContextService
- */
- public SimulationContextService getSimulationContextService() {
- return _simulationContextService;
- }
-
- /**
- * Set the simulationContextService.
- *
- * @param simulationContextService
- * the simulationContextService to set
- */
- public void setSimulationContextService(
- final SimulationContextService simulationContextService) {
- _simulationContextService = simulationContextService;
- }
-
- /**
- * Get project settings.
- *
- * @return Project settings service
- */
- private ProjectSettingsService getProjectSettings() {
- return _projectSettings;
- }
-
- /**
- * Set project settings service.
- *
- * @param projectSettingsService
- * project settings service
- */
- public void setProjectSettings(
- final ProjectSettingsService projectSettingsService) {
- _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;
- }
-
- /**
- * Get the roleDAO.
- *
- * @return the roleDAO
- */
- public RoleDAO getRoleDAO() {
- return _roleDAO;
- }
-
- /**
- * Set the roleDAO.
- *
- * @param roleDAO
- * the roleDAO to set
- */
- public void setRoleDAO(final RoleDAO roleDAO) {
- _roleDAO = roleDAO;
- }
-
- /**
- * Get the simulationContextTypeService.
- *
- * @return the simulationContextTypeService
- */
- public SimulationContextTypeService getSimulationContextTypeService() {
- return _simulationContextTypeService;
- }
-
- /**
- * Set the simulationContextTypeService.
- *
- * @param simulationContextTypeService
- * the simulationContextTypeService to set
- */
- public void setSimulationContextTypeService(
- final SimulationContextTypeService simulationContextTypeService) {
- _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;
- }
-
+ /**
+ * The logger for the service.
+ */
+ public final static AppLogger LOG = AppLogger
+ .getLogger(ScenarioServiceImpl.class);
+
+ /**
+ * " to " literal.
+ */
+ private static final String TO = " to ";
+ /**
+ * Injected index service.
+ */
+ private IndexService _indexService;
+ /**
+ * Injected step service.
+ */
+ private StepService _stepService;
+ /**
+ * Injected study service.
+ */
+ private StudyService _studyService;
+ /**
+ * Injected publication service.
+ */
+ private PublicationService _publicationService;
+ /**
+ * Injected project element service.
+ */
+ private ProjectElementService _projectElementService;
+ /**
+ * Injected knowledge element DAO.
+ */
+ private KnowledgeElementDAO _knowledgeElementDAO;
+ /**
+ * Injected scenario DAO.
+ */
+ private ScenarioDAO _scenarioDAO;
+
+ /**
+ * Injected study DAO.
+ */
+ private StudyDAO _studyDAO;
+
+ /**
+ * Injected knowledge element service.
+ */
+ private KnowledgeElementTypeService _knowledgeElementTypeService;
+
+ /**
+ * Injected user service.
+ */
+ private UserService _userService;
+
+ /**
+ * Injected user DAO.
+ */
+ private UserDAO _userDAO;
+
+ /**
+ * Injected role DAO.
+ */
+ private RoleDAO _roleDAO;
+
+ /**
+ * Injected knowledge element type DAO.
+ */
+ private KnowledgeElementTypeDAO _knowledgeElementTypeDAO;
+
+ /**
+ * Injected document DAO.
+ */
+ private DocumentDAO _documentDAO;
+
+ /**
+ * Injected simulation context service.
+ */
+ private SimulationContextService _simulationContextService;
+
+ /**
+ * Injected simulation context type service.
+ */
+ private SimulationContextTypeService _simulationContextTypeService;
+
+ /**
+ * Injected project service.
+ */
+ private ProjectSettingsService _projectSettings;
+
+ /**
+ * Injected document type 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 a new id to document arriver after check-out.
+ * Return two several values: -1 or ID of the existing document.
+ *
+ * @param scenId
+ * the scenario id
+ * @param activityNumber
+ * the number of activity
+ * @param docId
+ * the document id
+ * @param fileExt
+ * the file extension
+ * @return new document id or -1 if same document do nor exist.
+ * @throws InvalidPropertyException if activityNumber is incorrect.
+ */
+
+ @Override
+ public final long getNewDocumentId(final long scenId,
+ final int activityNumber, final Long docId,
+ final String fileExt) throws InvalidPropertyException {
+
+ Scenario aScenario = getScenarioDAO().get(scenId);
+ Step[] steps = getProjectElementService().getSteps(aScenario);
+ Step currentStep = null;
+ for (Step step : steps) {
+ if (step.getNumber() == activityNumber) {
+ currentStep = step;
+ break;
+ }
+ }
+ if (currentStep == null) {
+ throw new InvalidPropertyException(
+ MessageKeyEnum.SCN_000001.toString(), activityNumber);
+ }
+
+ long resId = -1;
+ if (docId > 0) {
+ ProjectSettingsService.Step stepType = currentStep.getStep();
+ DocumentType documentType = _projectSettings
+ .getDefaultDocumentType(stepType, fileExt);
+ if (currentStep.getDocument(docId).value().getType()
+ .equals(documentType)) {
+ resId = docId;
+ } else {
+ List<Publication> allDocs = currentStep.getAllDocuments();
+ for (Publication publication : allDocs) {
+ if (publication.value().getType().equals(documentType)
+ && publication.value().getIndex() > resId) {
+ resId = publication.value().getIndex();
+ }
+ }
+ }
+ }
+ return resId;
+ }
+
+ /**
+ * Get the projectElementService.
+ *
+ * @return the projectElementService
+ */
+ public ProjectElementService getProjectElementService() {
+ return _projectElementService;
+ }
+
+ /**
+ * Set the projectElementService.
+ *
+ * @param projectElementService
+ * the projectElementService to set
+ */
+ public void setProjectElementService(
+ final ProjectElementService projectElementService) {
+ _projectElementService = projectElementService;
+ }
+
+ /**
+ * Get the publicationService.
+ *
+ * @return the publicationService
+ */
+ public PublicationService getPublicationService() {
+ return _publicationService;
+ }
+
+ /**
+ * Set the publicationService.
+ *
+ * @param publicationService
+ * the publicationService to set
+ */
+ public void setPublicationService(
+ final PublicationService publicationService) {
+ _publicationService = publicationService;
+ }
+
+ /**
+ * Get the stepService.
+ *
+ * @return the stepService
+ */
+ public StepService getStepService() {
+ return _stepService;
+ }
+
+ /**
+ * Set the stepService.
+ *
+ * @param stepService
+ * the stepService to set
+ */
+ public void setStepService(final StepService stepService) {
+ _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());
+ }
+ file.delete(); // necessary on some platforms if the file exists.
+ return upfile.renameTo(file);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.splat.service.ScenarioService#getScenarioInfo(long)
+ */
+ @Transactional(readOnly = true)
+ public List<StepDTO> getScenarioInfo(final long scenarioId) {
+ List<StepDTO> res = new ArrayList<StepDTO>();
+ // Get the scenario from the database by id
+ Scenario scen = getScenarioDAO().get(scenarioId);
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Scenario[" + scenarioId + "]: Number of publications: "
+ + scen.getDocums().size());
+ }
+ // Get activities of the scenario
+ Step[] steps = getProjectElementService().getSteps(scen);
+ StepDTO stepDTO;
+ DocumentDTO docDTO;
+ String docType, fileFormat;
+ String processing;
+ boolean doImport;
+ // For each activity create a step DTO and add it to the result list
+ for (Step step : steps) {
+ stepDTO = BeanHelper.copyBean(step.getStep(), StepDTO.class);
+ res.add(stepDTO);
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Step[" + stepDTO.getNumber()
+ + "]: Number of documents: "
+ + step.getDocuments().size());
+ }
+ // For each publication of the activity create a document DTO.
+ // Each file is considered as a source file.
+ for (Publication tag : step.getDocuments()) {
+ docDTO = stepDTO.addDoc(tag.value().getIndex(), tag.value()
+ .getTitle());
+ char aState = tag.getIsnew();
+ docType = tag.value().getType().getName();
+ // For each file of the document create a file DTO
+ // Process source file of the document
+ fileFormat = tag.value().getFile().getFormat();
+ doImport = getProjectSettings().doImport(docType, fileFormat);
+ if (doImport && (!tag.isOutdated())) {
+ processing = "file-import";
+ } else {
+ processing = "file-download";
+ }
+ File aFile = tag.value().getFile();
+ docDTO.addFile(aFile.getIndex(), aFile.getRelativePath(),
+ aState, processing, false);
+ // Process all exported files
+ for (Relation rel : tag.value().getRelations(
+ ConvertsRelation.class)) {
+ aFile = ((ConvertsRelation) rel).getTo();
+ fileFormat = aFile.getFormat();
+ doImport = getProjectSettings().doImport(docType,
+ fileFormat);
+ if (doImport && (!tag.isOutdated())) {
+ processing = "file-import";
+ } else {
+ processing = "file-download";
+ }
+ docDTO.addFile(aFile.getIndex(), aFile.getRelativePath(),
+ aState, processing, false);
+ }
+ }
+ }
+ return res;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.splat.service.ScenarioService#createStudy(java.lang.String,
+ * java.lang.String, java.lang.String, java.lang.String)
+ */
+ @Transactional
+ public long createStudy(final String username, final String title,
+ final String productName, final String description)
+ throws InvalidPropertyException, MissedPropertyException,
+ MultiplyDefinedException {
+ long id = 0;
+
+ // Find the author
+ User author = getUserService().selectUser(username);
+ if (author == null) {
+ // User is not found
+ throw new InvalidPropertyException(
+ MessageKeyEnum.USR_000001.toString(), username);
+ }
+
+ // Set the study properties
+ Study.Properties sprop = new Study.Properties();
+ sprop.setTitle(title).setManager(author);
+ sprop.setDescription(description);
+
+ // Find the product simulation context
+ SimulationContextType productContextType = getSimulationContextService()
+ .selectType("product");
+ SimulationContext.Properties cprop = new SimulationContext.Properties();
+ cprop.setType(productContextType).setValue(productName);
+ SimulationContext productCtx = getSimulationContextService()
+ .selectSimulationContext(productContextType, productName);
+ if (productCtx != null) {
+ cprop.setIndex(productCtx.getIndex());
+ }
+
+ // Set a first scenario properties
+ Scenario.Properties oprop = new Scenario.Properties();
+ oprop.setTitle(I18nUtils.getMessageLocaleDefault("label.scenario")
+ + " 1");
+
+ Study study = createStudy(sprop, oprop, cprop);
+ id = study.getIndex();
+
+ return id;
+ }
+
+ /**
+ * Create a new study with one scenario and "product" simulation context.
+ *
+ * @param sprop
+ * the study properties
+ * @param oprop
+ * the scenario properties
+ * @param cprop
+ * the "product" simulation context properties
+ * @return the created study
+ * @throws MissedPropertyException
+ * if a mandatory property is missed
+ * @throws InvalidPropertyException
+ * if a property is invalid
+ * @throws MultiplyDefinedException
+ * if some property occurs several times
+ */
+ @Transactional
+ public Study createStudy(final Study.Properties sprop,
+ final Scenario.Properties oprop,
+ final SimulationContext.Properties cprop)
+ throws MissedPropertyException, InvalidPropertyException,
+ MultiplyDefinedException {
+ Study study = getStudyService().createStudy(sprop);
+ addScenario(study, oprop);
+ if (cprop.getIndex() == 0) { // Input of new project context
+ cprop.setType(getSimulationContextService().selectType("product"))
+ .setValue(cprop.getValue());
+ getStudyService().addProjectContext(study, cprop);
+ } else { // Selection of existing project context
+ SimulationContext context = getSimulationContextService()
+ .selectSimulationContext(cprop.getIndex());
+ getStudyService().addProjectContext(study, context);
+ }
+ return study;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.splat.service.ScenarioService#assignStudyContext(java.lang.Long,
+ * java.lang.String, java.lang.String)
+ */
+ @Transactional
+ public void assignStudyContext(final Long studyId, final String ctxType,
+ final String ctxValue) throws MissedPropertyException,
+ InvalidPropertyException, MultiplyDefinedException {
+ // Find the study by the given id
+ Study study = getStudyDAO().get(studyId);
+ if (study == null) {
+ throw new InvalidPropertyException(
+ MessageKeyEnum.STD_000002.toString(), studyId);
+ }
+ // Find the context type by its name
+ SimulationContextType celt = getSimulationContextService().selectType(
+ ctxType);
+ if (celt == null) {
+ // Creation of a new context type
+ celt = getSimulationContextTypeService().createType(ctxType,
+ getProjectElementService().getFirstStep(study).getStep());
+ }
+ // Find the given context value of the given type
+ SimulationContext context = getSimulationContextService()
+ .selectSimulationContext(celt, ctxValue);
+ if (context == null) { // Input of a new project context
+ SimulationContext.Properties cprop = new SimulationContext.Properties();
+ cprop.setType(celt).setValue(ctxValue);
+ getStudyService().addProjectContext(study, cprop);
+ } else { // Selection of existing project context
+ getStudyService().addProjectContext(study, context);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.splat.service.ScenarioService#addKnowledgeElement(org.splat.dal.bo.som.Scenario,
+ * org.splat.dal.bo.som.KnowledgeElement.Properties)
+ */
+ @Transactional
+ public KnowledgeElement addKnowledgeElement(final Scenario aScenarioDTO,
+ final KnowledgeElement.Properties kprop)
+ throws MissedPropertyException, InvalidPropertyException,
+ MultiplyDefinedException {
+ KnowledgeElement kelm = null;
+ // try {
+ long aScenarioId = aScenarioDTO.getIndex();
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Add a knowledge element to the scenario #" + aScenarioId);
+ }
+ // Get the persistent scenario.
+ Scenario aScenario = getScenarioDAO().get(aScenarioId);
+ // Get persistent objects for creating a new knowledge.
+ // TODO: Actions must use DTO instead of persistent objects.
+ getUserDAO().merge(kprop.getAuthor());
+ getKnowledgeElementTypeDAO().merge(kprop.getType());
+ // Create a transient knowledge element related to the given scenario.
+ kelm = new KnowledgeElement(kprop.setOwnerScenario(aScenario));
+ // Save the new knowledge in the database.
+ getKnowledgeElementDAO().create(kelm);
+ // Update scenario transient data.
+ if (kelm.getType().equals("usecase")) {
+ aScenarioDTO.setUcase(kelm);
+ } else if (aScenarioDTO.getKnowledgeElementsList() != null) { // If
+ // null,
+ // knowl
+ // will be
+ // initialized
+ // when
+ // needed
+ aScenarioDTO.getKnowledgeElementsList().add(kelm);
+ }
+
+ // Load the workflow for the parent study to take into account
+ // all study actors durng reindexing.
+ getStudyService().loadWorkflow(aScenario.getOwnerStudy());
+
+ // // Update the lucene index of knowledge elements.
+ // getIndexService().add(kelm);
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("A knowledge element #" + kelm.getIndex()
+ + " is added to the scenario #" + aScenario.getIndex());
+ }
+ // } catch (IOException error) {
+ // LOG.error("Unable to index the knowedge element '"
+ // + kelm.getIndex() + "', reason:", error);
+ // kelm = null;
+ // }
+
+ return kelm;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @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) 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();
+
+ // Keep newly created documents to create uses relations to results of a
+ // previous step.
+ // For each processed existing document keep its new version
+ Map<Document, Document> newVersion = new HashMap<Document, Document>();
+ // Created publications of new created versions of existing documents
+ List<Publication> newVers = new ArrayList<Publication>();
+ // The list of publications of new created documents not existing before
+ // the checkin
+ List<Publication> newDocs = new ArrayList<Publication>();
+ // For each step DTO
+ DocumentType resType;
+ Date aDate = new Date(); // The timestamp of the checkin operation
+ for (StepDTO stepDTO : scInfo) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Checkin the step:\n" + stepDTO);
+ }
+ if (stepDTO.getDocs().size() == 0) {
+ break;
+ }
+ // 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);
+
+ List<FileDTO> filesToBeAttached = new ArrayList<FileDTO>();
+ FileDTO fileToAttachTo = null; // all the rest documents will be
+ // attached to it
+
+ // The id is the same for all DocumentDTOs of a step
+ Long currentDocId = stepDTO.getDocs().get(0).getId();
+ if (currentDocId != null && currentDocId > 0) { // there is a result
+ // document in the
+ // step
+ String currentFormat = step.getDocument(currentDocId).value()
+ .getFormat();
+
+ // Process each document of the step
+ for (DocumentDTO doc : stepDTO.getDocs()) {
+ for (FileDTO fileDTO : doc.getFiles()) {
+
+ String path = fileDTO.getPath();
+ String format = path
+ .substring(path.lastIndexOf('.') + 1);
+
+ // If it has the same format as current doc (there can
+ // be just one such file)
+ // then this doc will be DocToAttachTo.
+ if (format != null && format.equals(currentFormat)) {
+ fileToAttachTo = fileDTO;
+ } else {
+ // Else, put it in the list of docs that will be
+ // attached to DocToAttachTo
+ filesToBeAttached.add(fileDTO);
+ }
+ }
+ }
+ } else {
+ // Process each document of the step
+ for (DocumentDTO doc : stepDTO.getDocs()) {
+ for (FileDTO fileDTO : doc.getFiles()) {
+ String path = doc.getFiles().get(0).getPath();
+ String format = path
+ .substring(path.lastIndexOf('.') + 1);
+
+ ProjectSettingsService.Step stepType = step.getStep();
+ // If the default type for its format in the current
+ // step is the result type,
+ // then this doc will be DocToAttachTo.
+ DocumentType defaultDocType = _projectSettings
+ .getDefaultDocumentType(stepType, format);
+ if (defaultDocType != null
+ && defaultDocType.isResultOf(stepType)) {
+ // It is possible that there is not just one such
+ // doc
+ if (fileToAttachTo != null) {
+ filesToBeAttached.add(fileToAttachTo);
+ }
+ fileToAttachTo = fileDTO;
+ } else {
+ // Else, put it in the list of docs that will be
+ // attached to DocToAttachTo
+ filesToBeAttached.add(fileDTO);
+ }
+ }
+ }
+
+ // could not find any file with appropriate format
+ if (fileToAttachTo == null && !filesToBeAttached.isEmpty()) {
+ // All the rest documents will be attached to the first in
+ // the list
+ fileToAttachTo = filesToBeAttached.get(0);
+ filesToBeAttached.remove(0);
+ }
+ }
+
+ if (fileToAttachTo != null) { // true if the DocumentDTO list is not
+ // empty
+
+ // Process docToAttachTo
+ Publication pub = checkinDoc(step, fileToAttachTo,
+ currentDocId, aUser, resType, aDate, newVersion,
+ newVers, newDocs);
+ currentDocId = pub.value().getIndex();
+ }
+
+ // Process rest docs
+ for (FileDTO file : filesToBeAttached) {
+ checkinDoc(step, file, currentDocId, aUser, resType, aDate,
+ newVersion, newVers, newDocs);
+ }
+ }
+
+ // Set uses/used relations
+ updateRelationsAfterCheckin(aScenario, newVersion, newVers, newDocs);
+
+ // Mark the scenario as checked in
+ checkin(aScenario);
+ }
+
+ /**
+ * Updated uses/used relations after checkin operation:<BR>
+ * <ul>
+ * <li>For each new version copy uses relations from the previous version.</li>
+ * <li>Outdate documents which depend from the previous version and were not
+ * checked in during this operation.</li>
+ * <li>For each new document create uses relation to the last versions of
+ * results of the previous step.</li>
+ * </ul>
+ *
+ * @param aScenario
+ * the checked in scenario
+ * @param newVersion
+ * the mapping of documents existed before the checkin to their
+ * new created versions
+ * @param newVers
+ * the list of publications of new created versions of documents
+ * existed before the checkin
+ * @param newDocs
+ * the list of publications of new created documents not existed
+ * before the checkin
+ */
+ private void updateRelationsAfterCheckin(final Scenario aScenario,
+ final Map<Document, Document> newVersion,
+ final List<Publication> newVers, final List<Publication> newDocs) {
+ // For each new version copy uses relations from the previous version.
+ for (Publication newVer : newVers) {
+ // For each Uses relation of the previous version
+ Document prevDoc = newVer.value().getPreviousVersion();// prevVersion.get(newVer);
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Previous version for publication #"
+ + newVer.getIndex() + " is found: " + prevDoc);
+ }
+ List<Relation> usesRelations = prevDoc
+ .getRelations(UsesRelation.class);
+ for (Relation rel : usesRelations) {
+ // 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);
+ }
+ // Outdate documents which depend from the previous version and
+ // were not checked in during this operation.
+ // 1. Get all usedBy relations of the previous document version
+ for (Relation rel : prevDoc.getRelations(UsedByRelation.class)) {
+ Document using = ((UsedByRelation) rel).getTo();
+ // Check that not checked in dependent documents became outdated
+ Publication usingPub = aScenario.getPublication(using);
+ if (usingPub != null) { // if the document using the old version
+ // is still published
+ usingPub.setIsnew('O');
+ }
+ }
+ }
+
+ // For each new document create uses relation to the last versions of
+ // results of the previous step.
+ for (Publication newPub : newDocs) {
+ // Find used document type according to the configuration.
+ Set<DocumentType> usedTypes = newPub.value().getType()
+ .getDefaultUses();
+ // Find documents of used type in the previous study step.
+ for (Publication pub : aScenario.getDocums()) {
+ if ((pub.getStep().getNumber() <= newPub.getStep().getNumber())
+ && (!pub.isOutdated())
+ && usedTypes.contains(pub.value().getType())
+ && !newPub.equals(pub)) {
+ // Create uses relation from the new document
+ // to the found document in the previous step.
+ newPub.addDependency(pub);
+ }
+ }
+ }
+ }
+
+ /**
+ * Pure checkin of the document without creation of uses/usedBy relations.
+ * For an existing document a new version is created. New documents become
+ * published in the given step of the appropriate scenario. The appropriate
+ * uploaded file is attached to the created document and the document is
+ * published in the scenario. The publication of the old version is removed
+ * from the scenario.
+ *
+ * @param step
+ * the destination scenario step
+ * @param file
+ * the FilDTO to checkin
+ * @param docId
+ * target document id
+ * @param aUser
+ * the user who performs checkin
+ * @param resType
+ * the result document type of the given step
+ * @param aDate
+ * timestamp of the checkin operation
+ * @param newVersion
+ * the mapping of existing documents to their new created
+ * versions
+ * @param newVers
+ * the list of publications of new created versions of existing
+ * documents
+ * @param newDocs
+ * the list of publications of new created documents not existing
+ * before the checkin
+ * @return the newly created publication, if exists (the document has been
+ * created or versioned), null otherwise (the doc has been attached
+ * to the old one)
+ * @throws InvalidPropertyException
+ * if the scenario hasn't some of given steps or documents
+ * @throws IOException
+ * if a file can't be moved into the vault
+ * @throws MismatchException
+ * if version creation in some of steps is failed
+ * @throws MissedPropertyException
+ * if some mandatory property is missed when new document or new
+ * document version is created
+ * @throws MultiplyDefinedException
+ * if some property is defined several times when new document
+ * or new document version is created
+ * @throws NotApplicableException
+ * if failed saving of a new publication with a given state
+ */
+ private Publication checkinDoc(final Step step, final FileDTO file,
+ final long docId, final User aUser, final DocumentType resType,
+ final Date aDate, final Map<Document, Document> newVersion,
+ final List<Publication> newVers, final List<Publication> newDocs)
+ throws InvalidPropertyException, MismatchException,
+ MissedPropertyException, MultiplyDefinedException, IOException,
+ NotApplicableException {
+ Publication newPub = null;
+ if (file != null) {
+ Document.Properties dprop = new Document.Properties();
+ // NOTE: Process only the first attached file for each document
+ dprop.setLocalPath(file.getPath());
+
+ // 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);
+
+ // 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 (docId > 0) {
+ newPub = checkinExistingDoc(step, docId, dprop, fileFormat,
+ upfile, newVersion, newVers);
+ } 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);
+ }
+ // New document title generation as <document type name>_N
+ String docname = dprop.getType().getName();
+ int i = 1;
+ for (Publication scenPub : step.getOwner().getDocums()) {
+ if (scenPub.value().getTitle().startsWith(docname)) {
+ i++;
+ }
+ }
+ docname += "_" + i; // The generated new document title
+
+ dprop.setName(docname);
+ newPub = getStepService().createDocument(step, dprop);
+
+ // Remember the new document
+ newDocs.add(newPub);
+
+ saveFile(newPub, step, upfile);
+ }
+ }
+ return newPub;
+ }
+
+ /**
+ * Check in existing document.
+ *
+ * @param step
+ * study step to check in
+ * @param docId
+ * target document id
+ * @param dprop
+ * document properties
+ * @param fileFormat
+ * checked in file format
+ * @param upfile
+ * the file to check in
+ * @param newVersion
+ * the map of created versions during this check in
+ * @param newVers
+ * the list of new versions created during this check in
+ * @return the newly created publication, if exists (the document has been
+ * versioned), null otherwise (the doc has been attached to the old
+ * one)
+ * @throws InvalidPropertyException
+ * if publication of the document is not found in the step
+ * @throws MismatchException
+ * if the found publication does not point to a document
+ * @throws IOException
+ * if can not move the file into the vault
+ * @throws MultiplyDefinedException
+ * thrown by versionDocument
+ * @throws MissedPropertyException
+ * thrown by versionDocument
+ * @throws NotApplicableException
+ * if failed saving of a new publication with a given state
+ */
+ private Publication checkinExistingDoc(final Step step, final long docId,
+ final Properties dprop, final String fileFormat,
+ final java.io.File upfile,
+ final Map<Document, Document> newVersion,
+ final List<Publication> newVers) throws InvalidPropertyException,
+ MismatchException, MissedPropertyException,
+ MultiplyDefinedException, IOException, NotApplicableException {
+ // If the document already exists then
+ // Attach the file via ConvertsRelation if the extension of the
+ // new file differs from the old one.
+ // If file format (i.e. extension) is the same then create a new
+ // version of the document.
+ // Find the document publication
+ // Publication pub = step.getDocument(doc.getId());
+ Publication pub = step.getDocument(docId);
+ Publication newPub = null;
+ if (pub == null) {
+ throw new InvalidPropertyException(
+ MessageKeyEnum.SCN_000002.toString(), docId);
+ }
+ if (pub.value() == null) {
+ throw new MismatchException(MessageKeyEnum.SCN_000002.toString(),
+ docId);
+ }
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Old format: " + pub.value().getFormat()
+ + " => New format: " + fileFormat);
+ }
+ // If formats are same then create a new document version
+ if (pub.value().getFormat() != null
+ && pub.value().getFormat().equals(fileFormat)) {
+ newPub = getStepService().versionDocument(step, pub, dprop);
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Created document type: "
+ + newPub.value().getType().getName() + ", format: "
+ + newPub.value().getFormat());
+ }
+ // 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);
+
+ saveFile(newPub, step, upfile);
+
+ } else { // If formats are different then attach the new file via
+ // ConvertsRelation
+ File attach = pub.value().getAttachedFile(fileFormat);
+ if (attach == null) {
+ // If there is no attachment with this extension then attach the
+ // new one
+ ConvertsRelation export = getPublicationService().attach(pub,
+ fileFormat);
+ moveFile(upfile, export.getTo().asFile());
+ } else {
+ // If an attachment with this extension already exists then
+ // replace it by the new one
+ moveFile(upfile, attach.asFile());
+ // Update attached file modification date
+ attach.setDate(new Date());
+ }
+ }
+ return newPub;
+ }
+
+ /**
+ * Save the file in the vault and create its publication in the step.
+ *
+ * @param newPub
+ * the new publication to save
+ * @param step
+ * the study step to publish the document
+ * @param upfile
+ * the downloaded file
+ * @throws IOException
+ * if a file can't be moved into the vault
+ * @throws NotApplicableException
+ * if failed saving of a new publication with a given state
+ */
+ private void saveFile(final Publication newPub, final Step step,
+ final java.io.File upfile) throws IOException,
+ NotApplicableException {
+ // Attach the file to the created document
+ java.io.File updir = newPub.getSourceFile().asFile();
+ if (updir.exists()) {
+ if (updir.delete()) {
+ LOG.info(MessageKeyEnum.SCN_000003.toString(),
+ updir.getAbsoluteFile(), step.getOwner().getIndex());
+ } else {
+ throw new IOException(
+ "Can't delete the existing destination file to move file from "
+ + upfile.getAbsolutePath() + TO
+ + updir.getAbsolutePath());
+ }
+ }
+ 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());
+ }
+ }
+
+ /**
+ * 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;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.splat.service.ScenarioService#checkin(long)
+ */
+ @Transactional
+ public void checkin(final long scenarioId) throws InvalidPropertyException {
+ Scenario aScenario = getScenarioDAO().get(scenarioId);
+ if (aScenario == null) {
+ // Scenario not found
+ throw new InvalidPropertyException(
+ MessageKeyEnum.SCN_000006.toString(), scenarioId);
+ }
+ checkin(aScenario);
+ }
+
+ /**
+ * Mark the scenario as checked in.
+ *
+ * @param aScenario
+ * the scenario to check in.
+ */
+ private void checkin(final Scenario aScenario) {
+ aScenario.setUser(null);
+ aScenario.setLastModificationDate(Calendar.getInstance().getTime());
+ // getScenarioDAO().update(aScenario);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.splat.service.ScenarioService#checkout(org.splat.dal.bo.som.Scenario,
+ * org.splat.dal.bo.kernel.User)
+ */
+ public boolean checkout(final Scenario aScenario, final User user) {
+ boolean res = getStudyService().isStaffedBy(aScenario.getOwnerStudy(),
+ user);
+ if (res) {
+ aScenario.setUser(user);
+ aScenario.setLastModificationDate(Calendar.getInstance().getTime());
+ // RKV: getScenarioDAO().update(aScenario);
+ }
+ return res;
+ }
+
+ /**
+ * Mark the given scenario as checked out by the given user.
+ *
+ * @param scenarioId
+ * the scenario id
+ * @param userId
+ * the id of the user performing the check out
+ * @throws InvalidPropertyException
+ * if the user or the scenario is not found in the database
+ * @throws NotApplicableException
+ * if the given user can not check out the scenario
+ */
+ @Transactional
+ public void checkout(final long scenarioId, final long userId)
+ throws InvalidPropertyException, NotApplicableException {
+ User aUser = getUserService().selectUser(userId);
+ if (aUser == null) {
+ // User not found
+ throw new InvalidPropertyException(
+ MessageKeyEnum.USR_000001.toString(), userId);
+ }
+ Scenario aScenario = getScenarioDAO().get(scenarioId);
+ if (aScenario == null) {
+ // Scenario not found
+ throw new InvalidPropertyException(
+ MessageKeyEnum.SCN_000006.toString(), scenarioId);
+ }
+ boolean res = getStudyService().isStaffedBy(aScenario.getOwnerStudy(),
+ aUser);
+ if (res) {
+ if (aScenario.isCheckedout()
+ && (!aScenario.getUser().getUsername()
+ .equals(aUser.getUsername()))) {
+ throw new NotApplicableException(
+ MessageKeyEnum.SCN_000008.toString(), scenarioId,
+ aScenario.getUser().getUsername());
+ }
+ aScenario.setUser(aUser);
+ aScenario.setLastModificationDate(Calendar.getInstance().getTime());
+ } else {
+ // User doesn't participate in the scenario
+ throw new NotApplicableException(
+ MessageKeyEnum.SCN_000007.toString(), aUser.getUsername(),
+ scenarioId);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.splat.service.ScenarioService#copyContentsUpTo(org.splat.dal.bo.som.Scenario,
+ * org.splat.som.Step)
+ */
+ public void copyContentsUpTo(final Scenario scenario, final Step lastep) {
+ Scenario base = (Scenario) lastep.getOwner();
+ Step[] from = getProjectElementService().getSteps(base);
+ Step[] to = getProjectElementService().getSteps(scenario);
+ for (int i = 0; i < from.length; i++) {
+ Step step = from[i];
+ if (step.getNumber() > lastep.getNumber()) {
+ break;
+ }
+
+ List<Publication> docs = step.getAllDocuments();
+ for (Iterator<Publication> j = docs.iterator(); j.hasNext();) {
+ Publication doc = getPublicationService().copy(j.next(),
+ scenario); // Creation of a new reference to the
+ // document
+ // Database.getSession().save(doc); Publications MUST be saved
+ // later through cascading when saving the scenario
+ getStepService().add(to[i], doc);
+ }
+ List<SimulationContext> ctex = step.getAllSimulationContexts();
+ for (Iterator<SimulationContext> j = ctex.iterator(); j.hasNext();) {
+ getStepService().addSimulationContext(to[i], j.next());
+ }
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.splat.service.ScenarioService#isEmpty(org.splat.dal.bo.som.Scenario)
+ */
+ public boolean isEmpty(final Scenario scenario) {
+ Step[] mystep = getProjectElementService().getSteps(scenario);
+ boolean isEmp = true;
+ for (int i = 0; i < mystep.length; i++) {
+ if (mystep[i].isStarted()) {
+ isEmp = false;
+ break;
+ }
+ }
+ return isEmp;
+ }
+
+ /**
+ * @param scenario
+ * @return
+ */
+ public boolean isFinished(final Scenario scenario) {
+ Step[] mystep = getProjectElementService().getSteps(scenario);
+ boolean notempty = false; // If this is empty, this is not finished
+ for (int i = 0; i < mystep.length; i++) {
+ if (!mystep[i].isStarted()) {
+ continue;
+ }
+ if (!mystep[i].isFinished()) {
+ return false;
+ }
+ notempty = true;
+ }
+ return notempty;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.splat.service.StudyService#addScenario(org.splat.dal.bo.som.Study,
+ * org.splat.dal.bo.som.Scenario.Properties)
+ */
+ @Transactional
+ public Scenario addScenario(final Study aStudy,
+ final Scenario.Properties sprop) throws MissedPropertyException,
+ InvalidPropertyException, MultiplyDefinedException {
+ if (sprop.getManager() == null) {
+ sprop.setManager(aStudy.getAuthor());
+ }
+
+ Scenario scenario = new Scenario(sprop.setOwnerStudy(aStudy));
+ if (sprop.getBaseStep() != null) {
+ copyContentsUpTo(scenario, sprop.getBaseStep());
+ }
+ Scenario previous = sprop.getInsertAfter();
+
+ if (previous == null) {
+ aStudy.getScenariiList().add(scenario);
+ } else {
+ aStudy.getScenariiList().add(
+ aStudy.getScenariiList().indexOf(previous) + 1, scenario);
+ }
+ getStudyDAO().update(aStudy); // No need to update the Lucene index
+ getScenarioDAO().create(scenario); // Must be done after updating this
+ // study because of the back
+ // reference to the study
+ if (sprop.getBaseStep() != null) {
+ // No need to update the Knowledge Element index as Knowledge
+ // Elements are not copied
+ getProjectElementService().refresh(scenario); // Because saving the
+ // scenario changes
+ // the hashcode of
+ // copied Publications
+ }
+ KnowledgeElementType ucase = getKnowledgeElementTypeService()
+ .selectType("usecase");
+ KnowledgeElement.Properties kprop = new KnowledgeElement.Properties();
+ // TODO: Get appropriate user by its role: UserService.getAdmin();
+ // User admin = getUserService().selectUser(1); // First user created
+ // when creating the database
+ Role adminRole = getRoleDAO().getFilteredList(
+ Restrictions.like("role", "%sysadmin%")).get(0);
+ User admin = getUserDAO().getFilteredList(
+ Restrictions.eq("role", adminRole), Order.asc("rid")).get(0); // First
+ // sysadmin
+ // in
+ // the
+ // database
+
+ kprop.setType(ucase).setTitle(aStudy.getTitle())
+ .setValue(scenario.getTitle()).setAuthor(admin); // Internal
+ // Knowledge
+ // Element
+ // required by
+ // the
+ // validation
+ // process of
+ // knowledges
+ addKnowledgeElement(scenario, kprop);
+ return scenario;
+ }
+
+ /**
+ * Remove a knowledge element from a scenario.
+ *
+ * @param scenario
+ * the scenario
+ * @param kelm
+ * the knowledge element to remove
+ * @return true if removal succeeded
+ */
+ @Transactional
+ public boolean removeKnowledgeElement(final Scenario scenario,
+ final KnowledgeElement kelm) {
+ KnowledgeElement torem = scenario.getKnowledgeElement(kelm.getIndex());
+ boolean isOk = (torem != null);
+ if (isOk) {
+ isOk = scenario.getKnowledgeElements().remove(torem);
+ if (isOk) {
+ getScenarioDAO().merge(scenario);
+ // Update of my transient data
+ // RKV: These transient data are not used indeed.
+ // RKV: List<KnowledgeElement> kelms =
+ // scenario.getKnowledgeByType().get(
+ // RKV: kelm.getType().getIndex());
+ // RKV: kelms.remove(torem);
+ if (scenario.getKnowledgeElementsList() != null) {
+ scenario.getKnowledgeElementsList().remove(torem);
+ }
+ // TODO: If the owner study is not private, remove the knowledge
+ // from the Lucene index
+ }
+ }
+ return isOk;
+ }
+
+ /**
+ *
+ * {@inheritDoc}
+ *
+ * @see org.splat.service.ScenarioService#renameScenario(java.lang.String)
+ */
+ @Transactional
+ public void renameScenario(final Scenario scenario) {
+ getScenarioDAO().merge(scenario);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.splat.service.ScenarioService#removeScenario(long)
+ */
+ @Transactional
+ public void removeScenario(final long scenarioId) {
+ Scenario scenario = getScenarioDAO().get(scenarioId);
+ Study study = scenario.getOwnerStudy();
+
+ if (scenario != null && study != null) {
+ getScenarioDAO().delete(scenario);
+
+ // Collect all documents which are published in another scenario
+ // or are previous versions of documents published in another
+ // scenario
+ Set<Document> untouched = new HashSet<Document>();
+
+ List<Scenario> otherScenarios = study.getScenariiList();
+ otherScenarios.remove(scenario);
+
+ for (Scenario otherScenario : otherScenarios) {
+ for (Publication publication : otherScenario.getDocums()) {
+ for (Document document = publication.value(); document != null; document = document
+ .getPreviousVersion()) {
+ untouched.add(document);
+ }
+ }
+ }
+
+ // Collect all documents which are published in this scenario
+ // or are previous versions of documents published in this scenario
+ Set<Document> toRemove = new HashSet<Document>();
+ for (Publication publication : scenario.getDocums()) {
+ for (Document document = publication.value(); document != null; document = document
+ .getPreviousVersion()) {
+ toRemove.add(document);
+ }
+ }
+
+ toRemove.removeAll(untouched);
+
+ // Delete all necessary documents
+ for (Document document : toRemove) {
+ _documentDAO.delete(document);
+ }
+ }
+ }
+
+ /**
+ * Get the knowledgeElementDAO.
+ *
+ * @return the knowledgeElementDAO
+ */
+ public KnowledgeElementDAO getKnowledgeElementDAO() {
+ return _knowledgeElementDAO;
+ }
+
+ /**
+ * Set the knowledgeElementDAO.
+ *
+ * @param knowledgeElementDAO
+ * the knowledgeElementDAO to set
+ */
+ public void setKnowledgeElementDAO(
+ final KnowledgeElementDAO knowledgeElementDAO) {
+ _knowledgeElementDAO = knowledgeElementDAO;
+ }
+
+ /**
+ * Get the indexService.
+ *
+ * @return the indexService
+ */
+ public IndexService getIndexService() {
+ return _indexService;
+ }
+
+ /**
+ * Set the indexService.
+ *
+ * @param indexService
+ * the indexService to set
+ */
+ public void setIndexService(final IndexService indexService) {
+ _indexService = indexService;
+ }
+
+ /**
+ * Get the scenarioDAO.
+ *
+ * @return the scenarioDAO
+ */
+ public ScenarioDAO getScenarioDAO() {
+ return _scenarioDAO;
+ }
+
+ /**
+ * Set the scenarioDAO.
+ *
+ * @param scenarioDAO
+ * the scenarioDAO to set
+ */
+ public void setScenarioDAO(final ScenarioDAO scenarioDAO) {
+ _scenarioDAO = scenarioDAO;
+ }
+
+ /**
+ * Get the studyDAO.
+ *
+ * @return the studyDAO
+ */
+ public StudyDAO getStudyDAO() {
+ return _studyDAO;
+ }
+
+ /**
+ * Set the studyDAO.
+ *
+ * @param studyDAO
+ * the studyDAO to set
+ */
+ public void setStudyDAO(final StudyDAO studyDAO) {
+ _studyDAO = studyDAO;
+ }
+
+ /**
+ * Get the knowledgeElementTypeService.
+ *
+ * @return the knowledgeElementTypeService
+ */
+ public KnowledgeElementTypeService getKnowledgeElementTypeService() {
+ return _knowledgeElementTypeService;
+ }
+
+ /**
+ * Set the knowledgeElementTypeService.
+ *
+ * @param knowledgeElementTypeService
+ * the knowledgeElementTypeService to set
+ */
+ public void setKnowledgeElementTypeService(
+ final KnowledgeElementTypeService knowledgeElementTypeService) {
+ _knowledgeElementTypeService = knowledgeElementTypeService;
+ }
+
+ /**
+ * Get the studyService.
+ *
+ * @return the studyService
+ */
+ public StudyService getStudyService() {
+ return _studyService;
+ }
+
+ /**
+ * Set the studyService.
+ *
+ * @param studyService
+ * the studyService to set
+ */
+ public void setStudyService(final StudyService studyService) {
+ _studyService = studyService;
+ }
+
+ /**
+ * Get the userService.
+ *
+ * @return the userService
+ */
+ public UserService getUserService() {
+ return _userService;
+ }
+
+ /**
+ * Set the userService.
+ *
+ * @param userService
+ * the userService to set
+ */
+ public void setUserService(final UserService userService) {
+ _userService = userService;
+ }
+
+ /**
+ * Get the userDAO.
+ *
+ * @return the userDAO
+ */
+ public UserDAO getUserDAO() {
+ return _userDAO;
+ }
+
+ /**
+ * Set the userDAO.
+ *
+ * @param userDAO
+ * the userDAO to set
+ */
+ public void setUserDAO(final UserDAO userDAO) {
+ _userDAO = userDAO;
+ }
+
+ /**
+ * Get the knowledgeElementTypeDAO.
+ *
+ * @return the knowledgeElementTypeDAO
+ */
+ public KnowledgeElementTypeDAO getKnowledgeElementTypeDAO() {
+ return _knowledgeElementTypeDAO;
+ }
+
+ /**
+ * Set the knowledgeElementTypeDAO.
+ *
+ * @param knowledgeElementTypeDAO
+ * the knowledgeElementTypeDAO to set
+ */
+ public void setKnowledgeElementTypeDAO(
+ final KnowledgeElementTypeDAO knowledgeElementTypeDAO) {
+ _knowledgeElementTypeDAO = knowledgeElementTypeDAO;
+ }
+
+ /**
+ * Get the documentDAO.
+ *
+ * @return the documentDAO
+ */
+ public DocumentDAO getDocumentDAO() {
+ return _documentDAO;
+ }
+
+ /**
+ * Set the documentDAO.
+ *
+ * @param documentDAO
+ * the documentDAO to set
+ */
+ public void setDocumentDAO(final DocumentDAO documentDAO) {
+ _documentDAO = documentDAO;
+ }
+
+ /**
+ * Get the simulationContextService.
+ *
+ * @return the simulationContextService
+ */
+ public SimulationContextService getSimulationContextService() {
+ return _simulationContextService;
+ }
+
+ /**
+ * Set the simulationContextService.
+ *
+ * @param simulationContextService
+ * the simulationContextService to set
+ */
+ public void setSimulationContextService(
+ final SimulationContextService simulationContextService) {
+ _simulationContextService = simulationContextService;
+ }
+
+ /**
+ * Get project settings.
+ *
+ * @return Project settings service
+ */
+ private ProjectSettingsService getProjectSettings() {
+ return _projectSettings;
+ }
+
+ /**
+ * Set project settings service.
+ *
+ * @param projectSettingsService
+ * project settings service
+ */
+ public void setProjectSettings(
+ final ProjectSettingsService projectSettingsService) {
+ _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;
+ }
+
+ /**
+ * Get the roleDAO.
+ *
+ * @return the roleDAO
+ */
+ public RoleDAO getRoleDAO() {
+ return _roleDAO;
+ }
+
+ /**
+ * Set the roleDAO.
+ *
+ * @param roleDAO
+ * the roleDAO to set
+ */
+ public void setRoleDAO(final RoleDAO roleDAO) {
+ _roleDAO = roleDAO;
+ }
+
+ /**
+ * Get the simulationContextTypeService.
+ *
+ * @return the simulationContextTypeService
+ */
+ public SimulationContextTypeService getSimulationContextTypeService() {
+ return _simulationContextTypeService;
+ }
+
+ /**
+ * Set the simulationContextTypeService.
+ *
+ * @param simulationContextTypeService
+ * the simulationContextTypeService to set
+ */
+ public void setSimulationContextTypeService(
+ final SimulationContextTypeService simulationContextTypeService) {
+ _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;
+ }
}
*/
public class TestScenarioService extends BaseTest {
- /**
- * Logger for the class.
- */
- private static final AppLogger LOG = AppLogger
- .getLogger(TestScenarioService.class);
-
- /**
- * The tested ScenarioService. Later injected by Spring.
- */
- @Autowired
- @Qualifier("scenarioService")
- private transient ScenarioService _scenarioService;
-
- /**
- * The RepositoryService. Later injected by Spring.
- */
- @Autowired
- @Qualifier("repositoryService")
- private transient RepositoryService _repositoryService;
-
- /**
- * The Scenario DAO. Later injected by Spring.
- */
- @Autowired
- @Qualifier("scenarioDAO")
- private transient ScenarioDAO _scenarioDAO;
-
- /**
- * The PublicationService. Later injected by Spring.
- */
- @Autowired
- @Qualifier("publicationService")
- private transient PublicationService _publicationService;
-
- /**
- * The StepService. Later injected by Spring.
- */
- @Autowired
- @Qualifier("stepService")
- private transient StepService _stepService;
-
- /**
- * The SimulationContextService. Later injected by Spring.
- */
- @Autowired
- @Qualifier("simulationContextService")
- private transient SimulationContextService _simulationContextService;
-
- /**
- * The ProjectSettingsService. Later injected by Spring.
- */
- @Autowired
- @Qualifier("projectSettings")
- private transient ProjectSettingsService _projectSettings;
-
- /**
- * The StepsConfigService. Later injected by Spring.
- */
- @Autowired
- @Qualifier("stepsConfigService")
- private transient StepsConfigService _stepsConfigService;
-
- /**
- * The DocumentTypeService. Later injected by Spring.
- */
- @Autowired
- @Qualifier("documentTypeService")
- private transient DocumentTypeService _documentTypeService;
-
- /**
- * The KnowledgeElementTypeService. Later injected by Spring.
- */
- @Autowired
- @Qualifier("knowledgeElementTypeService")
- private transient KnowledgeElementTypeService _knowledgeElementTypeService;
-
- /**
- * The UserDAO. Later injected by Spring.
- */
- @Autowired
- @Qualifier("userDAO")
- private transient UserDAO _userDAO;
-
- /**
- * The StudyService. Later injected by Spring.
- */
- @Autowired
- @Qualifier("studyService")
- private transient StudyService _studyService;
-
- /**
- * The StudyDAO. Later injected by Spring.
- */
- @Autowired
- @Qualifier("studyDAO")
- private transient StudyDAO _studyDAO;
-
- /**
- * The ValidationCycleDAO. Later injected by Spring.
- */
- @Autowired
- @Qualifier("validationCycleDAO")
- private transient ValidationCycleDAO _validationCycleDAO;
-
- /**
- * The ProjectElementService. Later injected by Spring.
- */
- @Autowired
- @Qualifier("projectElementService")
- private transient ProjectElementService _projectElementService;
-
- /**
- * Test of getting a scenario content for building siman-salome.conf.<BR>
- * <B>Description :</B> <BR>
- * <i>Create a scenario and try to get an info for it.</i><BR>
- * <B>Action : </B><BR>
- * <i>1. call the method for an existing scenario id.</i><BR>
- * <i>2. call the method for a not existing scenario id.</i><BR>
- * <B>Test data : </B><BR>
- * <i>no input parameters</i><BR>
- * <i>no input parameters</i><BR>
- *
- * <B>Outcome results:</B><BR>
- * <i>
- * <ul>
- * <li>result DTO must contain list of all documents and files<BR>
- * </li>
- * <li>Exception is thrown<BR>
- * </li>
- * </ul>
- * </i>
- *
- * @throws InvalidPropertyException
- * if an invalid property is used when creating objects
- * @throws MultiplyDefinedException
- * when trying to create an object with already existing id
- * @throws MissedPropertyException
- * if a mandatory property is not defined for an object to be created
- * @throws IOException
- * if scenario creation is failed
- * @throws SQLException
- * if scenario creation is failed
- */
- @Test(groups = { "checkout", "sevice", "functional", "business" })
- public void testGetScenarioInfo() throws InvalidPropertyException,
- MissedPropertyException, MultiplyDefinedException, IOException,
- SQLException {
- LOG.debug(">>>>> BEGIN testGetScenarioInfo()");
- startNestedTransaction();
-
- long scenarioId = createScenario();
- // Call DAO's create method for a good transient knowledge element.
- List<StepDTO> steps = _scenarioService.getScenarioInfo(scenarioId);
- Assert.assertNotNull(steps, "List of steps must not be null.");
- Assert.assertTrue(steps.size() > 0, "No steps are read.");
-
- List<Step> projSteps = _stepsConfigService.getStepsOf(Scenario.class);
- Assert.assertEquals(steps.size(), projSteps.size(),
- "Not all steps are listed.");
- int docIndex = 0;
- for (StepDTO step : steps) {
- LOG.debug("check the step " + step.getNumber() + ":\n" + step);
- Assert.assertNotNull(step, "Step DTO must not be null.");
- Assert.assertNotNull(step.getKey(), "Step name must not be null.");
- Assert.assertFalse(step.getKey().isEmpty(),
- "Step name must not empty.");
- Assert.assertTrue(step.getNumber() > 0,
- "Step number must be positive integer.");
- Assert.assertNotNull(step.getDocs(),
- "Step documents list must not be null.");
-
- Step aProjStep = null;
- for (Step projStep : projSteps) {
- if (projStep.getNumber() == step.getNumber()) {
- aProjStep = projStep;
- break;
- }
- }
-
- List<DocumentType> dtypes = _documentTypeService
- .selectTypesOf(aProjStep);
- for (DocumentType dtype : dtypes) {
- Assert.assertTrue(step.getDocs().size() > 0,
- "Step documents list must not be empty.");
- String docName = "document" + docIndex;
- for (DocumentDTO doc : step.getDocs()) {
- if (docName.equals(doc.getTitle())) {
- Assert.assertTrue(doc.getId() > 0,
- "Document id must be positive integer.");
- Assert.assertEquals(doc.getTitle(), docName);
- Assert.assertNotNull(doc.getFiles(),
- "Document files list must not be null.");
- Assert
- .assertTrue(doc.getFiles().size() > 1,
- "Document must have more then 1 attached file.");
-
- for (FileDTO file : doc.getFiles()) {
- Assert.assertNotNull(file.getPath(),
- "File path must not be null.");
- Assert.assertFalse(file.getPath().isEmpty(),
- "File path must not be empty.");
- /*
- * <mappings> <document type="geometry"> <import format="brep"/> <!-- Result Shape --> </document> <document
- * type="model"> <import format="med"/> <!-- Result mesh without input parameters --> </document> <document
- * type="loads"> <import format="c3m"/> <!-- Input data created interactively --> </document> <document
- * type="results"> <import format="med"/> <!-- Calculation results source file --> </document> </mappings>
- */
- // Check state and processing instruction
- String fileFormat = file.getPath().substring(
- file.getPath().lastIndexOf('.') + 1);
- /*
- * if (_projectSettings.doImport(dtype.getName(), fileFormat)) { Assert.assertTrue(file.isResult(), "The file
- * must be a result file."); } else { Assert.assertFalse(file.isResult(), "The file must be a source file."); }
- */if ((docIndex % 2) == 0) { // New
- Assert.assertEquals(file.getState(), 'Y',
- "File state must be actual ('Y').");
- if (_projectSettings.doImport(dtype.getName(),
- fileFormat)) {
- Assert.assertEquals(file.getProcessing(),
- "file-import",
- "File must be imported.");
- } else {
- Assert.assertEquals(file.getProcessing(),
- "file-download",
- "File must be downloaded.");
- }
- } else { // Outdated
- Assert.assertEquals(file.getState(), 'O',
- "File state must be outdated ('O').");
- Assert
- .assertEquals(file.getProcessing(),
- "file-download",
- "Outdated document should not be imported but downloaded.");
- }
- }
- }
- }
- docIndex++;
- }
- }
-
- // Call DAO's get method for a not existing id.
- try {
- steps = _scenarioService.getScenarioInfo(-1L);
- // getHibernateTemplate().flush();
- Assert
- .fail("Getting an object with not existing id must be failed.");
- } catch (Exception e) {
- LOG.debug("Expected exception is thrown: "
- + e.getClass().getSimpleName() + ": " + e.getMessage());
- }
- rollbackNestedTransaction();
- LOG.debug(">>>>> END testGetScenarioInfo()");
- }
-
- /**
- * Test check-in scenario operation to be performed after SALOME session.<BR>
- * <B>Description :</B> <BR>
- * <i>Create a scenario and try to check-in it with some simulated SALOME results data.<BR>
- * After check-in verify following points:
- * <ul>
- * <li>scenario is no more marked as checked out</li>
- * <li>new document versions are created for checked in documents</li>
- * <li>presentation of the previous version is removed</li>
- * <li>uses relations are copied correctly</li>
- * <li>files are moved correctly</li>
- * <li>formats of files are new if they are according to the document's type on the study step</li>
- * <li>new documents are created for new data</li>
- * <li>new documents have correctly generated names</li>
- * <li>uses relations are created correctly</li>
- * <li>files are moved correctly</li>
- * </ul>
- * </i><BR>
- * <B>Action : </B><BR>
- * <i>1. call the method for an existing scenario id.</i><BR>
- * <i>2. call the method for a not existing scenario id.</i><BR>
- * <B>Test data : </B><BR>
- * <i>no input parameters</i><BR>
- * <i>no input parameters</i><BR>
- *
- * <B>Outcome results:</B><BR>
- * <i>
- * <ul>
- * <li>New version of existing documents must be created and new documents must be imported for documents with zero id. Correct
- * relations must be created.<BR>
- * </li>
- * <li>Exception is thrown<BR>
- * </li>
- * </ul>
- * </i>
- *
- * @throws InvalidPropertyException
- * if an invalid property is used when creating objects
- * @throws MultiplyDefinedException
- * when trying to create an object with already existing id
- * @throws MissedPropertyException
- * if a mandatory property is not defined for an object to be created
- * @throws IOException
- * if scenario creation is failed
- * @throws SQLException
- * if scenario creation is failed
- * @throws NotApplicableException
- * if checkin failed
- * @throws MismatchException
- * if checkin failed
- */
- @Test(groups = { "checkin", "sevice", "functional", "business" })
- public void testCheckin() throws InvalidPropertyException,
- MissedPropertyException, MultiplyDefinedException, IOException,
- SQLException, MismatchException, NotApplicableException {
- LOG.debug(">>>>> BEGIN testCheckin()");
- startNestedTransaction();
-
- _projectSettings.getAllSteps().clear(); // Clear config to be able to load it again
- _projectSettings.configure("classpath:test/som.xml");
- getHibernateTemplate().flush();
- long scenarioId = createScenario();
- Scenario aScen = _scenarioDAO.get(scenarioId);
- User user = aScen.getAuthor();
- long userId = user.getIndex();
-
- // ////////////////////////////////////////////////////////
- // Call checkin method for empty list of modules.
-
- // Simulate checkout
- _scenarioService.checkout(aScen, user);
- _scenarioDAO.flush();
- // Check that scenario is no more marked as checked out
- aScen = _scenarioDAO.get(scenarioId);
- Assert.assertTrue(aScen.isCheckedout(),
- "Scenario is not marked as checked out after checkout.");
-
- // Prepare test data for checkin
- // Checkin only two first steps (geom and mesh)
- List<StepDTO> stepsToCheckin = new ArrayList<StepDTO>();
- // Do test checkin
- _scenarioService.checkin(scenarioId, userId, stepsToCheckin);
-
- _scenarioDAO.flush();
- // Check that scenario is no more marked as checked out
- aScen = _scenarioDAO.get(scenarioId);
- Assert.assertFalse(aScen.isCheckedout(),
- "Scenario is still marked as checked out after checkin.");
-
- // ///////////////////////////////////////////////////////////
- // Different test cases
-
- //Fancy but compact way to iterate over all possible combinations without missing any of them.
- List<Boolean> trueFalse = new ArrayList<Boolean>();
- trueFalse.add(false);
- trueFalse.add(true);
- long testCaseNumber = 1; //To provide some uniqueness to files content.
-
- for (boolean hasSource : trueFalse) {
- for (boolean hasAttachments : trueFalse) {
- for (boolean checkinSource : trueFalse) {
- for (boolean checkinAttachments : trueFalse) {
- if (hasAttachments && !hasSource) { // Impossible test cases
- continue;
- }
- if (!checkinAttachments && !checkinSource) { // Unnecessary test cases
- continue;
- }
-
- //startNestedTransaction();
- Set<String> res = testCheckinTestcase(testCaseNumber++,
- scenarioId, userId,
- hasSource, hasAttachments,
- checkinSource, checkinAttachments);
- //rollbackNestedTransaction();
-
- // These combinations are dictated by assertCheckinValidity logic
- Assert.assertEquals(!hasSource && (checkinSource || checkinAttachments),
- res.contains("aNewSourceCreated"));
- Assert.assertEquals(hasSource && checkinSource,
- res.contains("oldSourceVersioned"));
- Assert.assertEquals(checkinAttachments && hasSource && checkinSource,
- res.contains("fileAttachedToAVersionedDoc"));
- Assert.assertEquals(checkinAttachments && hasSource && !checkinSource,
- res.contains("fileAttachedToAnOldDoc"));
- Assert.assertEquals(checkinAttachments && !hasSource,
- res.contains("fileAttachedToANewDoc"));
-
- }
- }
- }
- }
-
- // ///////////////////////////////////////////////////////////
- // Call checkin method for a not existing id.
- try {
- _scenarioService.checkin(-1, userId, stepsToCheckin);
- Assert
- .fail("Check in for scenario with not existing id must be failed.");
- } catch (Exception e) {
- LOG.debug("Expected exception is thrown: "
- + e.getClass().getSimpleName() + ": " + e.getMessage());
- }
-
- // Test checkin with empty list of steps
- stepsToCheckin.clear();
- _scenarioService.checkin(scenarioId, userId, stepsToCheckin);
-
- rollbackNestedTransaction();
- LOG.debug(">>>>> END testCheckin()");
- }
-
-
- /**
- * Performs necessary checks after checkin.
- * @param testCaseNumber
- * the test case number
- * @param stepsToCheckin
- * stepDTOs which has been checked in
- * @param aScen
- * the scenario
- * @param dates
- * modification dates
- * @return
- * set of strings indicating which cases has occurred
- * @throws IOException
- * if something is wrong
- */
- private Set<String> assertCheckinValidity(final long testCaseNumber,
- final List<StepDTO> stepsToCheckin, final Scenario aScen,
- final Map<Long, Date> dates) throws IOException{
- Set<String> result = new HashSet<String>();
- Assert.assertFalse(aScen.isCheckedout(),
- "Scenario is still marked as checked out after checkin.");
- // Check that new document versions are created for checked in documents
- for (StepDTO step : stepsToCheckin) {
- for (DocumentDTO docDTO : step.getDocs()) {
- for (FileDTO fileDTO : docDTO.getFiles()) {
-
- if ((docDTO.getId() != 0) && (docDTO.getId() != null)) {
- boolean prevVersFound = false;
- boolean versionedWithThisFile = false;
- Document prevDoc = null;
- Document curDoc = null;
- Publication newPub = null;
-
- // If previous version is found then the format must be the same
- String newFormat = fileDTO.getPath()
- .substring(fileDTO.getPath().lastIndexOf('.') + 1);
- for (Publication pub : aScen.getDocums()) {
- prevDoc = pub.value().getPreviousVersion();
- if (prevDoc != null) {
- prevVersFound = (prevDoc.getIndex() == docDTO.getId());
- if (prevVersFound) { // Found next published version of the checked in document
- newPub = pub;
- if(pub.value().getFormat().equals(newFormat)) {
- versionedWithThisFile = true;
- }
- break;
- }
- }
- if (pub.value().getIndex() == docDTO.getId()) {
- // Document version was not changed, old document is still published
- curDoc = pub.value();
- break;
- }
- }
- Assert.assertTrue(prevVersFound || (curDoc != null),
- "New version or new attached file of the existing checked in document \""
- + docDTO.getTitle() + "\" (id="
- + docDTO.getId()
- + ") is not found in the scenario.");
-
- if (prevVersFound && versionedWithThisFile) {
- result.add("oldSourceVersioned");
- Assert.assertFalse(aScen.publishes(prevDoc));
- // Check that presentation of the previous version is removed
- checkFiles(docDTO, newPub);
-
- // Formats of files are new if they are according to the document's type on the study step
- Assert.assertEquals(newPub.getSourceFile()
- .getFormat(), newFormat);
- Assert.assertEquals(newPub.getSourceFile()
- .getRelativePath().substring(
- newPub.getSourceFile()
- .getRelativePath()
- .lastIndexOf('.') + 1),
- newFormat);
-
- // Check that uses relations are copied correctly
-
- // 1. Get all uses relations of the previous document version
- for (Relation rel : prevDoc
- .getRelations(UsesRelation.class)) {
- Document used = ((UsesRelation) rel).getTo();
- // 2.1. Get the latest version of the document published in this scenario
- Publication toBeUsed = aScen.getPublication(used);
- if (toBeUsed == null) {
- // Find the latest published version
- for (Publication lastPub : aScen.getDocums()) {
- if ((lastPub.value().getPreviousVersion() != null)
- && (lastPub.value()
- .getPreviousVersion()
- .getIndex() == used
- .getIndex())) {
- toBeUsed = lastPub;
- break;
- }
- }
- }
- if ((toBeUsed != null) && (!toBeUsed.isOutdated())) {
- // 2.2. For each used document check that its latest not outdated version
- // is used by the new checked in document version.
- checkUsesRelation(newPub, toBeUsed);
- }
- }
- // 1. Get all usedBy relations of the previous document version
- for (Relation rel : prevDoc
- .getRelations(UsedByRelation.class)) {
- Document using = ((UsedByRelation) rel).getTo();
- // Check that not checked in dependent documents became outdated
- Publication usingPub = aScen.getPublication(using);
- if (usingPub != null) { // if the document using the old version is still published
- Assert.assertTrue(usingPub.isOutdated(),
- "Not checked in dependent document "
- + using.getTitle() + " ("
- + using.getType().getName()
- + ") must become outdated.");
- }
- }
-
- // Check that a correct comment is generated for VersionsRelation
- VersionsRelation versRel = (VersionsRelation) newPub
- .value().getFirstRelation(
- VersionsRelation.class);
- Assert.assertNotNull(versRel,
- "VersionsRelation must be created.");
- Assert
- .assertNotNull(versRel.getDescription(),
- "VersionsRelation description was not generated.");
- int descrLen = versRel.getDescription().length();
- Assert.assertTrue(descrLen > 0,
- "VersionsRelation description is empty.");
- LOG.debug("Version description: "
- + versRel.getDescription());
- } else {
- // Otherwise the file is attached to some other document,
- // which has been or has not been versioned during checkin
- Document targetDoc = null;
- if(prevVersFound) { // if the document has been versioned
- Assert.assertEquals(Long.valueOf(prevDoc.getIndex()),
- docDTO.getId());
- targetDoc = newPub.value();
- result.add("fileAttachedToAVersionedDoc");
- } else {
- targetDoc = curDoc;
- result.add("fileAttachedToAnOldDoc");
- }
- Assert.assertFalse(newFormat.equals(targetDoc.getFormat()));
-
- // Check file content
- Assert.assertTrue(Files.readFile(targetDoc.getAttachedFile(newFormat).asFile())
- .contains(new File(fileDTO.getPath()).getName()));
-
- // Otherwise the new file format must differ from the previous one
- // and the new file must be attached to the same document
- org.splat.dal.bo.som.File attFile = targetDoc
- .getAttachedFile(newFormat);
- Assert.assertNotNull(attFile, "File "
- + fileDTO.getPath()
- + " must be attached to the document "
- + docDTO.getTitle() + "#" + docDTO.getId());
- Assert.assertTrue(attFile.asFile().exists(), "File "
- + fileDTO.getPath()
- + " attached to the document "
- + docDTO.getTitle() + "#" + docDTO.getId()
- + " doesn't exist");
- LOG.debug("Source format: " + targetDoc.getFormat()
- + ", new format: " + newFormat);
- // Check that attachment with the same format is not duplicated.
- int attachNb = 0;
- for (Relation conv : targetDoc
- .getRelations(ConvertsRelation.class)) {
- if (newFormat.equals(((ConvertsRelation) conv)
- .getTo().getFormat())) {
- attachNb++;
- }
- }
- Assert
- .assertEquals(attachNb, 1,
- "Attachment with the same format must be only one.");
-
- // Check that the attached file date is updated
- if (dates.containsKey(attFile.getIndex())) {
- Assert
- .assertTrue(attFile.getDate().compareTo(
- dates.get(attFile.getIndex())) > 0,
- "Attachment modification date is not updated.");
- result.add("modifDatesChecked");
- }
- }
-
- } else {
- // here file may be attached to a newly created one,
- // or it may be a source of new doc itself.
-
- // Check that new documents are created for new data
- boolean foundAsSource = false;
- boolean foundAsAttachment = false;
- Publication newPub = null;
- for (Publication pub : aScen.getDocums()) {
- if (pub.value().getPreviousVersion() == null) {
- // TODO: is it correct? type name here?
- foundAsSource = (pub.value().getTitle().startsWith(pub
- .value().getType().getName()));
- if (foundAsSource) { // Found next published version of the checked in document
- String fcontent = Files.readFile(pub
- .getSourceFile().asFile());
- foundAsSource = fcontent.contains(
- new File(fileDTO.getPath()).getName());
- if (foundAsSource) {
- LOG
- .debug("Found new document with generated title: "
- + pub.value().getTitle());
- newPub = pub;
- break;
- }
- }
-
- String format = fileDTO.getPath().substring(
- fileDTO.getPath().lastIndexOf('.') + 1);
- org.splat.dal.bo.som.File attachment = pub.value().getAttachedFile(format);
- if (attachment != null) {
- String fcontent = Files.readFile(attachment.asFile());
- if (fcontent.contains(new File(fileDTO.getPath()).getName())) {
- foundAsAttachment = true;
- Assert.assertFalse(new File(fileDTO.getPath()).exists(), "File"
- + fileDTO.getPath()
- + " was not removed from downloads directory.");
- result.add("fileAttachedToANewDoc");
- break;
- }
- }
- }
- }
- Assert.assertTrue(foundAsSource || foundAsAttachment,
- "New document or attachment is not created for checked in document \""
- + docDTO.getTitle() + "\".");
-
- if (foundAsSource) {
-
- // TODO: check that all the conditions for this file to be chosen
- // as fileToAttachTo are present.
- //probably, drop some unimportant
-
- // Check file content
- Assert.assertTrue(Files.readFile(newPub.getSourceFile().asFile())
- .contains(new File(fileDTO.getPath()).getName()));
-
- result.add("aNewSourceCreated");
- // Check that uses relations are created correctly
- Assert.assertTrue(newPub.value().getTitle().startsWith(
- newPub.value().getType().getName() + "_"),
- "Document title newPub.value().getTitle() must start with "
- + newPub.value().getType().getName() + "_");
-
- // 1. Find the document type used by this document type
- Set<DocumentType> usedTypes = newPub.value().getType()
- .getDefaultUses();
- // 2. Find documents of used types in the current study step and previous study steps
- for (Publication pub : aScen.getDocums()) {
- if ((pub.getStep().getNumber() <= step.getNumber())
- && (!pub.isOutdated())
- && usedTypes.contains(pub.value().getType())
- && !newPub.equals(pub)) {
- // 3. Check that there is uses relation to the found document
- // if it is not outdated.
- checkUsesRelation(newPub, pub);
- }
- }
-
- // Check that files are moved correctly
- checkFiles(docDTO, newPub);
- }
- }
- }
- }
- }
- return result;
- }
-
- /**
- * Check if there is uses relation from the newPub to pub.
- *
- * @param newPub
- * the new publication
- * @param pub
- * the publication to be used
- */
- private void checkUsesRelation(final Publication newPub,
- final Publication pub) {
- boolean uses = false;
- boolean usesExist = false;
- for (Publication usesPub : newPub.getRelations(UsesRelation.class)) {
- usesExist = true;
- uses = (usesPub.equals(pub));
- if (uses) {
- break;
- }
- }
- Assert.assertTrue(usesExist && uses, "The created document "
- + newPub.value().getTitle() + "("
- + newPub.value().getType().getName() + ")"
- + " has no uses relation to the document "
- + pub.value().getTitle() + "("
- + pub.value().getType().getName() + ")");
- }
-
- /**
- * Check that files are moved correctly.
- *
- * @param docDTO
- * checked in document DTO
- * @param newPub
- * the created document publication
- */
- private void checkFiles(final DocumentDTO docDTO, final Publication newPub) {
- // Check that original files are deleted
- for (int j = 0; j < docDTO.getFiles().size(); j++) {
- FileDTO fileDTO = docDTO.getFiles().get(j);
- Assert.assertFalse(new File(fileDTO.getPath()).exists(), "File"
- + fileDTO.getPath()
- + " was not removed from downloads directory.");
- String format = fileDTO.getPath().substring(
- fileDTO.getPath().lastIndexOf('.') + 1);
- }
- // TODO: Check file by its internal content
- Assert.assertTrue(newPub.getSourceFile().exists(), "File "
- + newPub.getSourceFile().asFile().getAbsolutePath()
- + " for the document " + docDTO.getTitle()
- + " was not created.");
- }
-
- /**
- * Prepare a document with a file for check-in.
- *
- * @param stepTo
- * step DTO with data for check-in
- * @param module
- * SALOME module name
- * @param format
- * file extension
- * @param userId
- * download directory
- * @param stepFrom
- * checked out stepDTO
- * @param stepsToCheckin
- * DTO for check-in
- * @throws IOException
- * if file creation failed
- * @return step DTO with data prepared for check-in (stepTo or new if stepTo is null)
- */
- private StepDTO createDocDTOForModule(final StepDTO stepTo,
- final String module, final String format, final long userId,
- final StepDTO stepFrom, final List<StepDTO> stepsToCheckin)
- throws IOException {
- StepDTO stepToCheckin = stepTo;
- if (stepToCheckin == null) {
- stepToCheckin = new StepDTO();
- }
- if (module.equals(stepFrom.getModule())) {
- stepsToCheckin.add(stepToCheckin);
- stepToCheckin.setNumber(stepFrom.getNumber());
- for (DocumentDTO doc : stepFrom.getDocs()) {
- if (doc.getFiles().get(0).getState() != 'O') {
- DocumentDTO docToCheckin = stepToCheckin.addDoc(
- doc.getId(), doc.getTitle());
- for (FileDTO file : doc.getFiles()) {
- if (file.getPath().endsWith(format)
- || (file.getPath().endsWith("py") && (format
- .equals("brep") || format.equals("med")))) {
- // Create a file in the download directory
- if ("GEOM".equals(module)) {
- // New version case
- docToCheckin.addFile(createDownloadedFile(
- userId, doc.getTitle() + "_newvers",
- "py"));
- } else {
- // Attached generated result case
- docToCheckin.addFile(createDownloadedFile(
- userId, doc.getTitle() + "_result",
- format));
- }
- }
- }
- }
- }
- // Prepare new data
- stepToCheckin.addDoc(0, "newdoc" + stepFrom.getNumber()).addFile(
- createDownloadedFile(userId, "newdoc"
- + stepFrom.getNumber(), "brep"));
- }
- return stepToCheckin;
- }
-
- /**
- * Tests a checkin testcase.
- * @param testCaseNumber
- * the test case number
- * @param scenarioId
- * the scenrio id
- * @param userId
- * the user id
- * @param hasSource
- * whether the scenario is supposed to have a source file in this test case befor checkin
- * @param hasAttachments
- * whether the scenario is supposed to have files attached to the source
- * in this test case befor checkin
- * @param checkinSource
- * whether the "comm" file should be checked in
- * @param checkinAttachment
- * whether the "resu" and "mess" files should be checked in
- * @return
- * set of strings indicating which cases has occurred
- * @throws IOException
- * if something is wrong
- * @throws InvalidPropertyException
- * if something is wrong
- * @throws MultiplyDefinedException
- * if something is wrong
- * @throws MissedPropertyException
- * if something is wrong
- * @throws SQLException
- * if something is wrong
- * @throws NotApplicableException
- * if something is wrong
- * @throws MismatchException
- * if something is wrong
- */
- private Set<String> testCheckinTestcase(final long testCaseNumber,
- final long scenarioId, final long userId,
- final boolean hasSource, final boolean hasAttachments,
- final boolean checkinSource, final boolean checkinAttachment)
- throws IOException, InvalidPropertyException, MultiplyDefinedException,
- MissedPropertyException, SQLException, NotApplicableException, MismatchException{
-
- Scenario aScen = _scenarioDAO.get(scenarioId);
- User user = _userDAO.get(userId);
-
- List<StepDTO> steps = _scenarioService.getScenarioInfo(scenarioId);
-
- // ////////////////////////////////////////////////////////
- // Call checkin method for good prepared transient data.
-
- // Simulate checkout
- steps = _scenarioService.getScenarioInfo(scenarioId);
- _scenarioService.checkout(aScen, user);
-
- // Remember modification dates of all attached files
- Map<Long, Date> dates = new HashMap<Long, Date>();
- for (Publication p : aScen.getDocums()) {
- for (Relation r : p.value().getRelations(ConvertsRelation.class)) {
- org.splat.dal.bo.som.File attach = ((ConvertsRelation) r)
- .getTo();
- dates.put(attach.getIndex(), attach.getDate());
- }
- }
-
- long targetDocId =
- addMecaDocsToScenario(testCaseNumber, aScen, user, hasAttachments, hasSource);
-
- List<StepDTO> stepsToCheckin = new ArrayList<StepDTO>();
- for(StepDTO step : steps) {
- createDocDTOForMeca(testCaseNumber, targetDocId, null, userId, step, stepsToCheckin,
- checkinSource, checkinAttachment);
- }
-
- // /////////////////////////////////////////////////////////////////
- // Do test checkin
- _scenarioService.checkin(scenarioId, userId, stepsToCheckin);
-
- // Check that scenario is no more marked as checked out
- aScen = _scenarioDAO.get(scenarioId);
- return assertCheckinValidity(testCaseNumber, stepsToCheckin, aScen, dates);
- }
-
- /**
- * It will delete any "comm" publications in the scenario, and then create a new one,
- * with attachments if specified.
- * @param testCaseNumber
- * the test case number
- * @param aScen
- * the scenario
- * @param user
- * user who will be used as an author for the added documents
- * @param hasAttachments
- * whether to add the "comm" doc to the scenario
- * @param hasSource
- * whether to add "resu" and "mess" docs to the scenario
- * @return
- * the source document id, if exists, 0 otherwise.
- * @throws IOException
- * if something is wrong
- * @throws InvalidPropertyException
- * if something is wrong
- * @throws MissedPropertyException
- * if something is wrong
- * @throws MultiplyDefinedException
- * if something is wrong
- */
- private long addMecaDocsToScenario(final long testCaseNumber,
- final Scenario aScen, final User user,
- final boolean hasAttachments, final boolean hasSource)
- throws IOException, InvalidPropertyException, MissedPropertyException,
- MultiplyDefinedException {
-
- long res = 0;
- org.splat.som.Step mecaStep = null;
- for (org.splat.som.Step step : _projectElementService.getSteps(aScen)) {
- if ("SALOME_MECA".equals(step.getStep().getModule())) {
- mecaStep = step;
- }
- }
-
- //remove comm documents
- List<Publication> toRemove = new ArrayList<Publication>();
- for (Publication pub : mecaStep.getDocuments()) {
- if ("comm".equals(pub.value().getFormat())) {
- toRemove.add(pub);
- }
- }
- for (Publication pub : toRemove) {
- // remove relations so the publication can be removed correctly
- List<Relation> relations = new ArrayList<Relation>();
- relations.addAll(pub.value().getAllRelations());
- for (Relation rel : relations) {
- pub.value().removeRelation(UsesRelation.class, rel.getTo());
- }
- aScen.remove(pub);
- }
-
- if (hasSource) {
- // Select result document type for Meca step
- List<DocumentType> dtypes = _documentTypeService
- .selectTypesOf(mecaStep.getStep());
- DocumentType resultType = null;
- for (DocumentType doctype : dtypes) {
- if(doctype.isResultOf(mecaStep.getStep())) {
- resultType = doctype;
- break;
- }
- }
-
- Document.Properties dprop = new Document.Properties();
- File directory = _repositoryService.getDownloadDirectory(user);
- directory.mkdirs();
- dprop.setName("commDoc" + testCaseNumber)
- .setFormat("comm")
- .setAuthor(user)
- .setDate(new Date())
- .setType(resultType)
- .setLocalPath(dprop.getName() + "." + dprop.getFormat());
-
- Publication commPub = createDoc(aScen, mecaStep, dprop, "", false);
- // The following is necessary because createDoc does not do all required work
- // (and PublicationServiceImpl.createDoc() is complicated so it's harder to make it work)
- commPub.setStep(mecaStep);
- aScen.getDocums().add(commPub);
- mecaStep.getDocuments().add(commPub);
-
- res = commPub.value().getIndex();
-
- // add attachments
- if (hasAttachments) {
- // Create new "resu" file
- FileDTO resuFileDTO = createDownloadedFile(user.getIndex(), "resuFile", "resu");
- ConvertsRelation export = _publicationService.attach(commPub, "resu");
- File resuFile = new File(resuFileDTO.getPath());
- File dest = export.getTo().asFile();
- dest.delete();
- Assert.assertTrue(resuFile.renameTo(dest));
-
- // Create new "mess" file
- FileDTO messFileDTO = createDownloadedFile(user.getIndex(), "messFile", "mess");
- export = _publicationService.attach(commPub, "mess");
- File messFile = new File(messFileDTO.getPath());
- dest = export.getTo().asFile();
- dest.delete();
- Assert.assertTrue(messFile.renameTo(dest));
- }
- }
-
- return res;
- }
-
- /**
- * Prepare a document with a file for check-in.
- *
- * @param stepTo
- * step DTO with data for check-in
- * @param userId
- * download directory
- * @param stepFrom
- * checked out stepDTO
- * @param stepsToCheckin
- * DTO for check-in
- * @param createSource
- * whether to add the COMM file to the DTO
- * @param createAttachment
- * whether to add the RESU and MESS files to the DTO
- * @throws IOException
- * if file creation failed
- * @return step DTO with data prepared for check-in (stepTo or new if stepTo is null)
- */
- private StepDTO createDocDTOForMeca(final long testCaseNumber,
- final long targetDocId, final StepDTO stepTo,
- final long userId, final StepDTO stepFrom, final List<StepDTO> stepsToCheckin,
- final boolean createSource, final boolean createAttachment)
- throws IOException {
- StepDTO stepToCheckin = stepTo;
- if (stepToCheckin == null) {
- stepToCheckin = new StepDTO();
- }
- if ("SALOME_MECA".equals(stepFrom.getModule())) {
-
- stepsToCheckin.add(stepToCheckin);
- stepToCheckin.setNumber(stepFrom.getNumber());
-
- DocumentDTO docToCheckin = stepToCheckin.addDoc(
- targetDocId, "newCommDoc");
-
- if(createSource) {
- docToCheckin.addFile(createDownloadedFile(
- userId, "newCommDoc" + testCaseNumber + "_result",
- "comm"));
- }
- if(createAttachment) {
- docToCheckin.addFile(createDownloadedFile(
- userId, "newResuDoc" + testCaseNumber + "_result",
- "resu"));
- docToCheckin.addFile(createDownloadedFile(
- userId, "newMessDoc" + testCaseNumber + "_result",
- "mess"));
- }
- }
- return stepToCheckin;
- }
-
- /**
- * Create a file in the user's repository downloads directory.
- *
- * @param userId
- * user id
- * @param name
- * file name
- * @param format
- * file extension
- * @return created file DTO
- * @throws IOException
- * if file creation failed
- */
- private FileDTO createDownloadedFile(final long userId, final String name,
- final String format) throws IOException {
- // Create a file in the download directory
- return createDownloadedFile(userId, name + "." + format);
- }
-
- /**
- * Create a file in the user's repository downloads directory.
- *
- * @param userId
- * user id
- * @param fname
- * file name
- * @return created file DTO
- * @throws IOException
- * if file creation failed
- */
- private FileDTO createDownloadedFile(final long userId, final String fname)
- throws IOException {
- // Create a file in the download directory
- String filePath = getDownloadPath(userId) + fname;
- FileWriter fw = new FileWriter(filePath);
- fw.write("Simulation of " + fname + " file for checkin at "
- + new Date());
- fw.close();
- return new FileDTO(filePath);
- }
-
- /**
- * Create a persistent scenario for tests.
- *
- * @return a persistent scenario
- * @throws InvalidPropertyException
- * if an invalid property is used when creating objects
- * @throws MultiplyDefinedException
- * when trying to create an object with already existing id
- * @throws MissedPropertyException
- * if a mandatory property is not defined for an object to be created
- * @throws IOException
- * if document creation is failed
- * @throws SQLException
- * if project settings loading is failed
- */
- private long createScenario() throws InvalidPropertyException,
- MissedPropertyException, MultiplyDefinedException, IOException,
- SQLException {
- // Create a scenario for tests
- HibernateTemplate ht = getHibernateTemplate();
-
- Database.getInstance().reset();
- _projectSettings.getAllSteps().clear(); // Clear config to be able to load it again
- // Load workflow customization
- try {
- _projectSettings.configure("classpath:test/som.xml");
- } catch (FileNotFoundException e) {
- Assert.fail("Can't find som.xml: ", e);
- }
- List<Step> steps = _stepsConfigService.getStepsOf(Scenario.class);
- Assert.assertTrue(steps.size() > 0, "No steps are created.");
-
- // Create a test user
- User.Properties uprop = new User.Properties();
- uprop.setUsername("TST_Username").setName("TST_SimanUnitTestsUser")
- .setFirstName("TST_FirstName").setDisplayName("TST_test.user")
- .addRole("TST_user").setMailAddress(
- "noreply@salome-platform.org");
- uprop.disableCheck();
- User anAuthor = new User(uprop);
- ht.saveOrUpdate(anAuthor);
-
- // Create a test study
- Study.Properties stprops = new Study.Properties().setReference(
- "TST_SID_01").setTitle("TST_Study").setManager(anAuthor);
- Study aStudy = new Study(stprops);
- ht.saveOrUpdate(aStudy);
-
- // Create a test scenario
- Scenario.Properties sprops = new Scenario.Properties().setTitle(
- "TST_Scenario").setManager(anAuthor).setOwnerStudy(aStudy);
- Scenario aScenario = new Scenario(sprops);
- aStudy.getScenariiList().add(aScenario);
- ht.saveOrUpdate(anAuthor);
- ht.saveOrUpdate(aStudy);
- ht.saveOrUpdate(aScenario);
-
- // Create documents for each scenario step
- Document.Properties dprop = new Document.Properties().setAuthor(
- anAuthor).setDate(new Date());
- int i = 0;
- Publication usedPub = null;
- Map<Long, Long> usedMap = new HashMap<Long, Long>();
- for (Step step : steps) {
- LOG.debug("Create scenario step: " + i);
-
- org.splat.som.Step aScStep = new org.splat.som.Step(step, aScenario);
- List<DocumentType> dtypes = _documentTypeService
- .selectTypesOf(step);
- for (DocumentType dtype : dtypes) {
- // Create a document published in the scenario
- // document<i>: document type[0] - first type used on the step
- // <source-file>.brep
- // <attached-file>.med
- dprop.setName("document" + i++).setType(dtype);
- /*
- * if (step.getNumber() > 3) { dprop.setFormat("med"); } else {
- */dprop.setFormat("py");
- // }
- dprop.setLocalPath(dprop.getName() + "." + dprop.getFormat());
- Publication pub = createDoc(aScenario, aScStep, dprop, "med",
- false);
- if (usedPub != null) {
- pub.addDependency(usedPub);
- ht.saveOrUpdate(pub.value());
-
- usedMap.put(pub.getIndex(), usedPub.getIndex());
- }
- usedPub = pub;
-
- // Create another document with outdated publication
- dprop.setName("document" + i++).setType(dtype).setFormat("py");
- dprop.setLocalPath(dprop.getName() + "." + dprop.getFormat());
- createDoc(aScenario, aScStep, dprop, "med", true);
-
- }
- if (dtypes.size() <= 0) {
- LOG.debug("No document types are found for scenario step " + i);
- }
- }
-
- // Check that the scenario and its documents have been created correctly.
-
- Assert.assertNotNull(ht.find("from Document"),
- "No documents in the database.");
- Assert.assertTrue(ht.find("from Document").size() > 0,
- "No documents in the database.");
-
- Assert.assertNotNull(ht.find("from Publication where owner="
- + aScenario.getIndex()), "No publications in the database.");
- Assert.assertTrue(
- ht.find("from Publication where owner=" + aScenario.getIndex())
- .size() > 0, "No publications in the database.");
-
- for (Publication p : (List<Publication>) ht
- .find("from Publication where owner=" + aScenario.getIndex())) {
- LOG.debug("Publication found: [id=" + p.getIndex() + ", owner="
- + p.getOwner().getIndex() + ", doc=" + p.value().getIndex()
- + "]");
- Assert.assertEquals(p.getOwner().getIndex(), aScenario.getIndex(),
- "The publication was not attached to the scenario.");
- }
-
- // Remove the scenario from the current hibernate session.
- ht.evict(aScenario);
- // Check that the scenario is created in the database.
- Scenario aScen = ht.load(Scenario.class, aScenario.getIndex());
- Assert.assertNotNull(aScen, "Scenario was not saved in the database.");
- Assert.assertTrue(aScen.getDocums().size() > 0,
- "No publications in the scenario.");
-
- Assert.assertTrue(i > 0,
- "More then one document must be in the database");
-
- // Check created uses relations
- Assert
- .assertTrue(usedMap.size() > 0,
- "Uses relations must be created.");
- boolean foundAny = false;
- for (Long usingId : usedMap.keySet()) {
- for (Publication pub : aScen.getDocums()) {
- if (pub.getIndex() == usingId) {
- boolean found = false;
- for (Publication used : aScen.getDocums()) {
- found = (used.getIndex() == usedMap.get(usingId));
- if (found) {
- break;
- }
- }
- Assert.assertTrue(found,
- "Uses relation was not created in the database.");
- foundAny = foundAny || found;
- }
- }
- }
- Assert.assertTrue(foundAny,
- "No Uses relation was created in the database.");
-
- return aScenario.getIndex();
- }
-
- /**
- * Create a document published in the scenario. <BR>
- * document:<BR>
- * document type[0] - first type used on the step <BR>
- * <source-file>.brep <BR>
- * <attached-file>.med
- *
- * @param aScenario
- * the scenario to add the document to
- * @param aScStep
- * scenario step where the document to be published
- * @param dprop
- * document properties
- * @param attachedFileExt
- * extension of the secon attached (exported) file
- * @param isOutdated
- * outdated document flag
- * @return the publication of the created document
- * @throws IOException
- * @throws MultiplyDefinedException
- * @throws InvalidPropertyException
- * @throws MissedPropertyException
- */
- private Publication createDoc(final Scenario aScenario,
- final org.splat.som.Step aScStep, final Properties dprop,
- final String attachedFileExt, final boolean isOutdated)
- throws MissedPropertyException, InvalidPropertyException,
- MultiplyDefinedException, IOException {
- // Create a document published in the scenario
- // document<i>: document type[0] - first type used on the step
- // <source-file>.brep
- // <attached-file>.med
- createDownloadedFile(aScenario.getAuthor().getIndex(), dprop
- .getLocalPath());
- Publication pub = _stepService.createDocument(aScStep, dprop);
- Assert.assertNotNull(pub.getOwner(),
- "The publication must be attached to the scenario.");
- Assert.assertEquals(pub.getOwner().getIndex(), aScenario.getIndex(),
- "The publication was not attached to the scenario.");
-
- if (isOutdated) {
- pub.setIsnew('O');
- }
- aScenario.add(pub);
- HibernateTemplate ht = getHibernateTemplate();
- ht.saveOrUpdate(pub);
-
- // Attach a file
- createDownloadedFile(aScenario.getAuthor().getIndex(), dprop
- .getLocalPath().substring(0,
- dprop.getLocalPath().lastIndexOf(".") - 1),
- attachedFileExt);
- ht.save(pub.value());
- ht.saveOrUpdate(_publicationService.attach(pub, attachedFileExt));
-
- return pub;
- }
-
- /**
- * Test study creation.<BR>
- * <B>Description :</B> <BR>
- * <i>Create a study.</i><BR>
- * <B>Action : </B><BR>
- * <i>1. call the method for a not existing product.</i><BR>
- * <i>2. call the method for an existing username and an existing product.</i><BR>
- * <i>3. call the method for a not existing username expecting an exception.</i><BR>
- * <B>Test data : </B><BR>
- * <i>no input parameters</i><BR>
- *
- * <B>Outcome results:</B><BR>
- * <i>
- * <ul>
- * <li>1: The new study must be created. The new product simulation context must be created.</li>
- * <li>2: The new study must be created.</li>
- * <li>3: The new study must not be created. Exception must be thrown.</li>
- * </ul>
- * </i>
- *
- * @throws IOException
- * if application configuration loading is failed
- * @throws SQLException
- * if application configuration loading is failed
- * @throws BusinessException
- * if test data creation is failed
- */
- @Test(groups = { "study", "sevice", "functional", "business" })
- public void testCreateStudy() throws BusinessException, IOException,
- SQLException {
- LOG.debug(">>>>> BEGIN testCreateStudy()");
- startNestedTransaction();
-
- Database.getInstance().reset();
- _projectSettings.getAllSteps().clear(); // Clear config to be able to load it again
- _projectSettings.configure("classpath:test/som.xml");
-
- // Create a test user
- User.Properties uprop = new User.Properties();
- uprop.setUsername("TST_Username").setName("TST_SimanUnitTestsUser")
- .setFirstName("TST_FirstName").setDisplayName("TST_test.user")
- .addRole("TST_user").setMailAddress(
- "noreply@salome-platform.org");
- uprop.disableCheck();
- User anAuthor = new User(uprop);
-
- getHibernateTemplate().saveOrUpdate(anAuthor);
- KnowledgeElementType ucase = _knowledgeElementTypeService
- .selectType("usecase");
- Assert.assertNotNull(ucase,
- "Knowledge type 'usecase' must be created in the database.");
- SimulationContextType prodtype = _simulationContextService
- .selectType("product");
- Assert
- .assertNotNull(prodtype,
- "Simulation context type 'product' must be created in the database.");
-
- // Create admin
- uprop.clear();
- uprop.setUsername("TST_Admin").setName("TST_SimanUnitTestsAdmin")
- .setFirstName("TST_AdminFirstName").setDisplayName(
- "TST_test.admin").addRole("TST_user,sysadmin")
- .setMailAddress("noreply@salome-platform.org");
- uprop.disableCheck();
-
- getHibernateTemplate().saveOrUpdate(new User(uprop));
- getHibernateTemplate().flush();
-
- Study.Properties sprop = new Study.Properties();
- sprop.setTitle("Test study creation").setManager(anAuthor);
- Scenario.Properties oprop = new Scenario.Properties();
- oprop.setTitle("Test scenario for the created study");
-
- // Addition of the entered project context
- SimulationContext.Properties cprop = new SimulationContext.Properties();
- // Input of new project context
- cprop.setType(_simulationContextService.selectType("product"))
- .setValue("Test Simulation Context: Product");
- Study study = _scenarioService.createStudy(sprop, oprop, cprop);
-
- Assert.assertNotNull(study);
- Assert.assertTrue(study.getIndex() > 0);
-
- rollbackNestedTransaction();
- LOG.debug(">>>>> END testCreateStudy()");
- }
-
- /**
- * Test study creation.<BR>
- * <B>Description :</B> <BR>
- * <i>Create a study.</i><BR>
- * <B>Action : </B><BR>
- * <i>1. call the method for a not existing product.</i><BR>
- * <i>2. call the method for an existing username and an existing product.</i><BR>
- * <i>3. call the method for a not existing username expecting an exception.</i><BR>
- * <B>Test data : </B><BR>
- * <i>no input parameters</i><BR>
- *
- * <B>Outcome results:</B><BR>
- * <i>
- * <ul>
- * <li>1: The new study must be created. The new product simulation context must be created.</li>
- * <li>2: The new study must be created.</li>
- * <li>3: The new study must not be created. Exception must be thrown.</li>
- * </ul>
- * </i>
- *
- * @throws IOException
- * if application configuration loading is failed
- * @throws SQLException
- * if application configuration loading is failed
- * @throws BusinessException
- * if test data creation is failed
- */
- @Test(groups = { "study", "sevice", "functional", "business" })
- public void testCreateStudyFromPython() throws IOException, SQLException,
- BusinessException {
- LOG.debug(">>>>> BEGIN testCreateStudyFromPython()");
- startNestedTransaction();
-
- HibernateTemplate ht = getHibernateTemplate();
-
- Database.getInstance().reset();
- _projectSettings.getAllSteps().clear(); // Clear config to be able to load it again
- _projectSettings.configure("classpath:test/som.xml");
-
- // Create a test user
- User goodUser = TestEntitiesGenerator.getTestUser("goodUser");
- _userDAO.create(goodUser);
- SimulationContextType prodtype = _simulationContextService
- .selectType("product");
- Assert
- .assertNotNull(prodtype,
- "Simulation context type 'product' must be created in the database.");
-
- String productName = "New Test Product " + new Date().toString();
-
- ht.flush();
- ht.clear();
- long studyId1 = _scenarioService.createStudy("goodUser",
- "Test Study 1", productName, "Test description");
- Assert.assertTrue(studyId1 > 0);
-
- ht.flush();
- ht.clear();
- try {
- _scenarioService.createStudy("badbadUser", "Test Study 2",
- productName, "Test description");
- Assert.fail("Study must not be created for not existing user.");
- } catch (InvalidPropertyException ipe) {
- LOG.debug("Expected exception: " + ipe.getMessage());
- }
-
- ht.flush();
- ht.clear();
- long studyId3 = _scenarioService.createStudy("goodUser",
- "Test Study 3", productName, "Test description");
- Assert.assertTrue(studyId3 > 0);
-
- // Check that the simulation context is the same
- Study study1 = _studyService.selectStudy(studyId1);
- Study study3 = _studyService.selectStudy(studyId3);
- Assert.assertEquals(study1.SimulationContextIterator().next(), study3
- .SimulationContextIterator().next());
-
- // Check the title of the created scenario
- String scTitle = study1.getScenarii()[0].getTitle();
- Assert.assertEquals(scTitle, I18nUtils
- .getMessageLocaleDefault("label.scenario")
- + " 1");
- Assert.assertFalse(scTitle.equals("label.scenario 1"));
-
- rollbackNestedTransaction();
- LOG.debug(">>>>> END testCreateStudyFromPython()");
- }
-
- /**
- * Test study content copy.<BR>
- * <B>Description :</B> <BR>
- * <i>Create a study.</i><BR>
- * <B>Action : </B><BR>
- * <i>1. call the method for a not existing source study.</i><BR>
- * <i>2. call the method for a not existing source scenario with not evolving step.</i><BR>
- * <i>3. call the method for a not existing source scenario with evolving step.</i><BR>
- * <i>4. call the method for an existing source scenario with evolving step.</i><BR>
- * <B>Test data : </B><BR>
- * <i>no input parameters</i><BR>
- *
- * <B>Outcome results:</B><BR>
- * <i>
- * <ul>
- * <li>1: Exception must be thrown.</li>
- * <li>2: The study content must be copied.</li>
- * <li>3: Exception must be thrown.</li>
- * <li>4: The study content must be copied.</li>
- * </ul>
- * </i>
- *
- * @throws IOException
- * if application configuration loading is failed
- * @throws SQLException
- * if application configuration loading is failed
- * @throws BusinessException
- * if test data creation is failed
- */
- @Test(groups = { "study", "sevice", "functional", "business" })
- public void testCopyStudyContent() throws IOException, SQLException,
- BusinessException {
- LOG.debug(">>>>> BEGIN testCopyStudyContent()");
- startNestedTransaction();
-
- HibernateTemplate ht = getHibernateTemplate();
-
- Database.getInstance().reset();
- _projectSettings.getAllSteps().clear(); // Clear config to be able to load it again
- _projectSettings.configure("classpath:test/som.xml");
-
- User goodUser = TestEntitiesGenerator.getTestUser("GoodUser");
- _userDAO.create(goodUser);
- User otherUser = TestEntitiesGenerator.getTestUser("otherUser");
- _userDAO.create(otherUser);
-
- // Create private study
- Study aStudy = TestEntitiesGenerator.getTestStudy(goodUser);
- aStudy.setTitle("0.This is private study");
- Long studyId = _studyDAO.create(aStudy);
-
- // Add a scenario to the study
- Scenario scen = TestEntitiesGenerator.getTestScenario(aStudy);
- _scenarioDAO.create(scen);
- ht.flush();
- // Add a second scenario to the study
- scen = TestEntitiesGenerator.getTestScenario(aStudy);
- Long aScenId = _scenarioDAO.create(scen);
- ht.flush();
-
- // Add a validation cycle with otherUser as a reviewer
- ValidationCycle.Properties vprop = new ValidationCycle.Properties();
- DocumentType dtype = _documentTypeService.selectType("minutes");
- vprop.setDocumentType(dtype);
- vprop.setActor(ValidationStep.REVIEW, otherUser);
- ValidationCycle cycle = new ValidationCycle(aStudy, vprop);
- _validationCycleDAO.create(cycle);
- ValidationCycleRelation link = cycle.getContext();
- aStudy.addRelation(link);
- ht.flush();
-
- // Add documents to the first study activity
- // Add a converts relations
- Map<Integer, org.splat.som.Step> stSteps = _projectElementService
- .getStepsMap(aStudy);
- org.splat.som.Step aStep = stSteps.get(1);
- Publication pub1 = addDoc(aStudy, aStep, "document1", dtype);
- Publication pub2 = addDoc(aStudy, aStep, "document2", dtype);
- Publication pub3 = addDoc(aStudy, aStep, "document3", dtype);
- ht.flush();
-
- LOG.debug("pub1 version doc: " + pub1.value().getTitle() + " ["
- + pub1.value().getReference() + "]" + " ["
- + pub1.value().getRid() + "]");
- LOG.debug("pub2 version doc: " + pub2.value().getTitle() + " ["
- + pub2.value().getReference() + "]" + " ["
- + pub2.value().getRid() + "]");
- LOG.debug("pub3 version doc: " + pub3.value().getTitle() + " ["
- + pub3.value().getReference() + "]" + " ["
- + pub3.value().getRid() + "]");
-
- ht.update(aStudy);
-
- ht.flush();
- LOG.debug("Before versioning:");
- for (Publication doc : _projectElementService.getFirstStep(aStudy)
- .getAllDocuments()) {
- LOG.debug("Study doc: " + doc.value().getTitle() + " ["
- + doc.value().getReference() + "]" + " ["
- + doc.value().getRid() + "]");
- }
- // Add a version relations
- Publication pub31 = version(pub3);
- ht.flush();
- //
- // LOG.debug("pub31 version doc: " + pub31.value().getTitle() + " ["
- // + pub31.value().getReference() + "]" + " ["
- // + pub31.value().getRid() + "]");
- // ht.saveOrUpdate(aStudy);
-
- // LOG.debug("After versioning:");
- // for (Publication doc : aStudy.getDocums()) {
- // LOG.debug("Study doc: " + doc.value().getTitle() + " ["
- // + doc.value().getReference() + "]" + " ["
- // + doc.value().getRid() + "]");
- // }
-
- // Add documents to the first scenario activity
- Map<Integer, org.splat.som.Step> scSteps = _projectElementService
- .getStepsMap(scen);
- aStep = scSteps.get(2);
- Publication spub1 = addDoc(scen, aStep, "sdocument1", dtype);
- Publication spub2 = addDoc(scen, aStep, "sdocument2", dtype);
- Publication spub3 = addDoc(scen, aStep, "sdocument3", dtype);
- LOG.debug("spub1 version doc: " + spub1.value().getTitle() + " ["
- + spub1.value().getReference() + "]" + " ["
- + spub1.value().getRid() + "]");
- LOG.debug("spub2 version doc: " + spub2.value().getTitle() + " ["
- + spub2.value().getReference() + "]" + " ["
- + spub2.value().getRid() + "]");
- LOG.debug("spub3 version doc: " + spub3.value().getTitle() + " ["
- + spub3.value().getReference() + "]" + " ["
- + spub3.value().getRid() + "]");
- ht.flush();
-
- // Create a scenario document version
- Publication spub31 = version(spub3);
- // LOG.debug("spub31 version doc: " + spub31.value().getTitle() + " ["
- // + spub31.value().getReference() + "]" + " ["
- // + spub31.value().getRid() + "]");
- ht.flush();
-
- // Add uses relations
- pub2.addDependency(pub1);
- ht.saveOrUpdate(pub2.value());
- pub3.addDependency(pub2);
- ht.saveOrUpdate(pub3.value());
-
- spub2.addDependency(pub1);
- spub2.addDependency(spub1);
- spub2.addDependency(pub2);
- spub2.addDependency(pub3);
- ht.saveOrUpdate(spub2.value());
- spub3.addDependency(spub2);
- ht.saveOrUpdate(spub3.value());
- spub31.addDependency(pub31);
- ht.saveOrUpdate(spub31.value());
- ht.flush();
-
- // Create target study1
- Study aStudy1 = TestEntitiesGenerator.getTestStudy(goodUser);
- aStudy1.setTitle("1.This is a target study1");
- aStudy1.setReference("tst1");
- Long studyId1 = _studyDAO.create(aStudy1);
-
- // Add a scenario to the study
- Scenario scen1 = TestEntitiesGenerator.getTestScenario(aStudy1);
- _scenarioDAO.create(scen1);
- ht.flush();
-
- // Create target study2
- Study aStudy2 = TestEntitiesGenerator.getTestStudy(goodUser);
- aStudy2.setTitle("2.This is a target study2");
- aStudy2.setReference("tst2");
- Long studyId2 = _studyDAO.create(aStudy2);
-
- // Add a scenario to the study
- Scenario scen2 = TestEntitiesGenerator.getTestScenario(aStudy2);
- _scenarioDAO.create(scen2);
- ht.flush();
- ht.clear();
-
- // //////////////////// TEST CALL /////////////////////////////////////
- // 1. call the method for a not existing source study.
- try {
- _scenarioService.copyStudyContent(-1, -1, -1, -1);
- Assert.fail("Exception must be thrown for not existing study id.");
- } catch (InvalidParameterException e) {
- LOG.debug("Expected exception: " + e.getClass().getSimpleName()
- + ": " + e.getMessage());
- }
-
- ht.flush();
- ht.clear();
-
- // 2. call the method for a not existing source scenario with not evolving step.
- _scenarioService.copyStudyContent(studyId, -1, 1, studyId1);
-
- ht.flush();
- ht.clear();
-
- aStudy = _studyService.selectStudy(studyId);
- aStudy1 = _studyService.selectStudy(studyId1);
- for (Publication pub : aStudy.getDocums()) {
- // Find the same document in the created copy of the study
- Publication found = null;
- for (Publication newPub : aStudy1.getDocums()) {
- if (pub.value().getTitle().equals(newPub.value().getTitle())
- && pub.value().getType().equals(
- newPub.value().getType())) {
- found = newPub;
- break;
- }
- }
- Assert.assertNotNull(found, "The document "
- + pub.value().getTitle() + "is not copied");
- // Check that all files are copied (source and attached)
- }
-
- // 3. call the method for a not existing source scenario with evolving step.
- try {
- _scenarioService.copyStudyContent(studyId, -1, 2, studyId2);
- Assert
- .fail("Exception must be thrown for not existing scenario id and evolving step.");
- } catch (InvalidParameterException e) {
- LOG.debug("Expected exception: " + e.getClass().getSimpleName()
- + ": " + e.getMessage());
- }
-
- ht.flush();
- ht.clear();
-
- // 4. call the method for an existing source scenario with evolving step.
- _scenarioService.copyStudyContent(studyId, aScenId, 9, studyId2);
- ht.flush();
-
- rollbackNestedTransaction();
- LOG.debug(">>>>> END testCopyStudyContent()");
- }
-
- /**
- * Test assigning a simulation context to a study.<BR>
- * <B>Description :</B> <BR>
- * <i>Create a study and assign a simulation context to it.</i><BR>
- * <B>Action : </B><BR>
- * <i>1. call the method for not existing study id.</i><BR>
- * <i>2. call the method for not existing context type and context value.</i><BR>
- * <i>3. call the method for existing context type and context value.</i><BR>
- * <i>4. call the method for existing context type and not existing context value.</i><BR>
- * <i>5. call the method for empty context type.</i><BR>
- * <i>6. call the method for empty context value.</i><BR>
- * <B>Test data : </B><BR>
- * <i>no input parameters</i><BR>
- *
- * <B>Outcome results:</B><BR>
- * <i>
- * <ul>
- * <li>1: Exception must be thrown.</li>
- * <li>2: The new context type and value must be created. The new context must be assigned to the study first step.</li>
- * <li>3: The existing context must be assigned to the study first step.</li>
- * <li>4: The new context value must be created. The new context must be assigned to the study first step.</li>
- * <li>5: Exception must be thrown.</li>
- * <li>6: Exception must be thrown.</li>
- * </ul>
- * </i>
- *
- * @throws IOException
- * if application configuration loading is failed
- * @throws SQLException
- * if application configuration loading is failed
- * @throws BusinessException
- * if test data creation is failed
- */
- @Test(groups = { "study", "sevice", "functional", "business" })
- public void testAssignStudyContextFromPython() throws IOException,
- SQLException, BusinessException {
- LOG.debug(">>>>> BEGIN testAssignStudyContextFromPython()");
- startNestedTransaction();
-
- HibernateTemplate ht = getHibernateTemplate();
-
- Database.getInstance().reset();
- _projectSettings.getAllSteps().clear(); // Clear config to be able to load it again
- _projectSettings.configure("classpath:test/som.xml");
-
- // Create a test user
- User goodUser = TestEntitiesGenerator.getTestUser("goodUser");
- _userDAO.create(goodUser);
- SimulationContextType prodtype = _simulationContextService
- .selectType("product");
- Assert
- .assertNotNull(prodtype,
- "Simulation context type 'product' must be created in the database.");
-
- String productName = "New Test Product " + new Date().toString();
-
- ht.flush();
- ht.clear();
- long studyId1 = _scenarioService.createStudy("goodUser",
- "Test Study 1", productName, "Test description");
- Assert.assertTrue(studyId1 > 0);
-
- ht.flush();
- ht.clear();
-
- // //////// START OF TESTS
- // 1. call the method for not existing study id.</i><BR>
- try {
- _scenarioService.assignStudyContext(-1L, "new context type",
- "new context value");
- Assert.fail("Not existing study must not be found.");
- } catch (InvalidPropertyException ipe) {
- LOG.debug("Expected exception: " + ipe.getMessage());
- }
-
- // 2. call the method for not existing context type and context value.</i><BR>
- _scenarioService.assignStudyContext(studyId1, "new context type",
- "new context value");
-
- ht.flush();
- ht.clear();
-
- // Check the assigned simulation context
- checkCtx(studyId1, "new context type", "new context value");
-
- // 3. call the method for existing context type and context value.</i><BR>
- _scenarioService.assignStudyContext(studyId1, "new context type",
- "new context value");
-
- ht.flush();
- ht.clear();
-
- // Check the assigned simulation context
- checkCtx(studyId1, "new context type", "new context value");
-
- // 4. call the method for existing context type and not existing context value.</i><BR>
- _scenarioService.assignStudyContext(studyId1, "new context type",
- "new context value1");
-
- ht.flush();
- ht.clear();
-
- // Check the assigned simulation context
- checkCtx(studyId1, "new context type", "new context value1");
-
- // 5. call the method for empty context type.</i><BR>
- try {
- _scenarioService.assignStudyContext(studyId1, "",
- "new context value");
- Assert.fail("Empty context type name must be forbidden.");
- } catch (InvalidPropertyException ipe) {
- LOG.debug("Expected exception: " + ipe.getMessage());
- }
- // 6. call the method for empty context value.</i><BR>
- try {
- _scenarioService.assignStudyContext(studyId1, "new context type",
- "");
- Assert.fail("Empty context value must be forbidden.");
- } catch (InvalidPropertyException ipe) {
- LOG.debug("Expected exception: " + ipe.getMessage());
- }
-
- rollbackNestedTransaction();
- LOG.debug(">>>>> END testAssignStudyContextFromPython()");
- }
-
- /**
- * Test getting a study scenarios DTO list.<BR>
- * <B>Description :</B> <BR>
- * <i>Create a study and get its scenarios DTO list.</i><BR>
- * <B>Action : </B><BR>
- * <i>1. call the method for not existing study id.</i><BR>
- * <i>2. call the method for a study with one scenario.</i><BR>
- * <i>3. call the method for a study with several scenarios.</i><BR>
- * <B>Test data : </B><BR>
- * <i>no input parameters</i><BR>
- *
- * <B>Outcome results:</B><BR>
- * <i>
- * <ul>
- * <li>1: The returned list of DTO must be empty.</li>
- * <li>2: The returned list of DTO must contain one scenario DTO.</li>
- * <li>3: The returned list of DTO must contain several scenario DTOs.</li>
- * </ul>
- * </i>
- *
- * @throws IOException
- * if application configuration loading is failed
- * @throws SQLException
- * if application configuration loading is failed
- * @throws BusinessException
- * if test data creation is failed
- */
- @Test(groups = { "study", "sevice", "functional", "business" })
- public void testGetStudyScenarios() throws IOException, SQLException,
- BusinessException {
- LOG.debug(">>>>> BEGIN testGetStudyScenarios()");
- startNestedTransaction();
-
- HibernateTemplate ht = getHibernateTemplate();
-
- Database.getInstance().reset();
- _projectSettings.getAllSteps().clear(); // Clear config to be able to load it again
- _projectSettings.configure("classpath:test/som.xml");
-
- // Create a test user
- User goodUser = TestEntitiesGenerator.getTestUser("goodUser");
- _userDAO.create(goodUser);
- Study study = TestEntitiesGenerator.getTestStudy(goodUser);
- long studyId1 = _studyDAO.create(study);
- ht.flush();
- Scenario scen = TestEntitiesGenerator.getTestScenario(study,
- "test scen11");
- long id11 = _scenarioDAO.create(scen);
- ht.flush();
- study = TestEntitiesGenerator.getTestStudy(goodUser);
- long studyId2 = _studyDAO.create(study);
- ht.flush();
- scen = TestEntitiesGenerator.getTestScenario(study, "test scen21");
- long id21 = _scenarioDAO.create(scen);
- ht.flush();
- scen = TestEntitiesGenerator.getTestScenario(study, "test scen22");
- long id22 = _scenarioDAO.create(scen);
- ht.flush();
- scen = TestEntitiesGenerator.getTestScenario(study, "test scen23");
- long id23 = _scenarioDAO.create(scen);
- ht.flush();
- ht.clear();
-
- // //////// START OF TESTS
- // 1. call the method for not existing study id.
- List<ScenarioDTO> scens = _scenarioService.getStudyScenarios(-1L);
-
- Assert.assertNotNull(scens);
- Assert.assertTrue(scens.isEmpty());
-
- // 2. call the method for a study with one scenario.
- scens = _scenarioService.getStudyScenarios(studyId1);
-
- ht.flush();
- ht.clear();
- Assert.assertNotNull(scens);
- Assert.assertEquals(scens.size(), 1);
- Assert.assertEquals(scens.get(0).getIndex().longValue(), id11);
- Assert.assertEquals(scens.get(0).getTitle(), "test scen11");
-
- // 3. call the method for a study with several scenarios.
- scens = _scenarioService.getStudyScenarios(studyId2);
- Assert.assertEquals(scens.size(), 3);
- Assert.assertEquals(scens.get(0).getIndex().longValue(), id21);
- Assert.assertEquals(scens.get(0).getTitle(), "test scen21");
- Assert.assertEquals(scens.get(1).getIndex().longValue(), id22);
- Assert.assertEquals(scens.get(1).getTitle(), "test scen22");
- Assert.assertEquals(scens.get(2).getIndex().longValue(), id23);
- Assert.assertEquals(scens.get(2).getTitle(), "test scen23");
-
- ht.flush();
- ht.clear();
-
- rollbackNestedTransaction();
- LOG.debug(">>>>> END testGetStudyScenarios()");
- }
-
- /**
- * Check if the context is assigned to the study.
- *
- * @param studyId1
- * the study id
- * @param ctxType
- * the context type name
- * @param ctxValue
- * the context value
- */
- private void checkCtx(final long studyId1, final String ctxType,
- final String ctxValue) {
- // Check the assigned simulation context
- Study study1 = _studyService.selectStudy(studyId1);
- Iterator<SimulationContext> it = study1.SimulationContextIterator();
- SimulationContext ctx;
- boolean isFound = false;
- while ((!isFound) && it.hasNext()) {
- ctx = it.next();
- isFound = ctx.getType().getName().equals(ctxType)
- && ctx.getValue().equals(ctxValue);
- }
- Assert.assertTrue(isFound, "Context must be assigned to the study.");
- }
+ /**
+ * Logger for the class.
+ */
+ private static final AppLogger LOG = AppLogger
+ .getLogger(TestScenarioService.class);
+
+ /**
+ * The tested ScenarioService. Later injected by Spring.
+ */
+ @Autowired
+ @Qualifier("scenarioService")
+ private transient ScenarioService _scenarioService;
+
+ /**
+ * The RepositoryService. Later injected by Spring.
+ */
+ @Autowired
+ @Qualifier("repositoryService")
+ private transient RepositoryService _repositoryService;
+
+ /**
+ * The Scenario DAO. Later injected by Spring.
+ */
+ @Autowired
+ @Qualifier("scenarioDAO")
+ private transient ScenarioDAO _scenarioDAO;
+
+ /**
+ * The PublicationService. Later injected by Spring.
+ */
+ @Autowired
+ @Qualifier("publicationService")
+ private transient PublicationService _publicationService;
+
+ /**
+ * The StepService. Later injected by Spring.
+ */
+ @Autowired
+ @Qualifier("stepService")
+ private transient StepService _stepService;
+
+ /**
+ * The SimulationContextService. Later injected by Spring.
+ */
+ @Autowired
+ @Qualifier("simulationContextService")
+ private transient SimulationContextService _simulationContextService;
+
+ /**
+ * The ProjectSettingsService. Later injected by Spring.
+ */
+ @Autowired
+ @Qualifier("projectSettings")
+ private transient ProjectSettingsService _projectSettings;
+
+ /**
+ * The StepsConfigService. Later injected by Spring.
+ */
+ @Autowired
+ @Qualifier("stepsConfigService")
+ private transient StepsConfigService _stepsConfigService;
+
+ /**
+ * The DocumentTypeService. Later injected by Spring.
+ */
+ @Autowired
+ @Qualifier("documentTypeService")
+ private transient DocumentTypeService _documentTypeService;
+
+ /**
+ * The KnowledgeElementTypeService. Later injected by Spring.
+ */
+ @Autowired
+ @Qualifier("knowledgeElementTypeService")
+ private transient KnowledgeElementTypeService _knowledgeElementTypeService;
+
+ /**
+ * The UserDAO. Later injected by Spring.
+ */
+ @Autowired
+ @Qualifier("userDAO")
+ private transient UserDAO _userDAO;
+
+ /**
+ * The StudyService. Later injected by Spring.
+ */
+ @Autowired
+ @Qualifier("studyService")
+ private transient StudyService _studyService;
+
+ /**
+ * The StudyDAO. Later injected by Spring.
+ */
+ @Autowired
+ @Qualifier("studyDAO")
+ private transient StudyDAO _studyDAO;
+
+ /**
+ * The ValidationCycleDAO. Later injected by Spring.
+ */
+ @Autowired
+ @Qualifier("validationCycleDAO")
+ private transient ValidationCycleDAO _validationCycleDAO;
+
+ /**
+ * The ProjectElementService. Later injected by Spring.
+ */
+ @Autowired
+ @Qualifier("projectElementService")
+ private transient ProjectElementService _projectElementService;
+
+
+ /**
+ * Test of getting a new id of document arrived during checkin.<BR>
+ * <B>Description :</B> <BR>
+ * <i>Create a study, scenario, documents and list extension of documents arrived after checkin.<BR>
+ * Try get new id for every new document</i><BR>
+ * <B>Action : </B><BR>
+ * <i>
+ * <ol>
+ * <li>call the method for activityNumber = -1</li>
+ * <li>call the method for first test case, when before check in existed
+ * D1.comm and after checkin arrived three documents file1.comm, file2.resu, file3.mess</li>
+ * <li>call the method for second test case, when before check in not existed
+ * docs and after checkin arrived three documents file1.comm, file2.resu, file3.mess</li>
+ * <li>call the method for third test case, when before check in existed D1.comm,
+ * D2.resu(id of D1 > id of D2) and after checkin arrived three documents file1.comm, file2.resu, file3.mess</li>
+ * <li>call the method for fourth test case, when before check in existed D1.comm,
+ * D2.resu (id of D1 < id of D2) and after checkin arrived three documents file1.comm, file2.resu, file3.mess</li>
+ * </ol>
+ * </i>
+
+ * <B>Test data : </B><BR>
+ * <i>no input parameters</i><BR>
+ * <BR>
+ * <B>Outcome results:</B><BR>
+ * <i>The returned id is -1 if there is no appropriate document in the step or max id of existing document with appropriate type<BR>
+ * <ol>
+ * <li>If activityNumber = -1 then throw InvalidPropertyException.</li>
+ * <li>comm: id of D1.comm document; resu and mess: -1</li>
+ * <li>comm: -1; resu and mess: -1</li>
+ * <li>comm: id of D1.comm document; resu and mess: id of D2.resu document;</li>
+ * <li>comm: id of D1.comm document; resu and mess: id of D2.resu document;</li>
+ * </ol>
+ * </i>
+ * @throws BusinessException
+ * if documents creation is failed
+ * @throws IOException
+ * if scenario creation is failed
+ * @throws SQLException
+ * if scenario creation is failed
+ */
+
+ @Test(groups = {"checkin", "sevice", "functional", "business" })
+ public void testGetNewDocumentId() throws IOException, SQLException,
+ BusinessException {
+ LOG.debug(">>>>> BEGIN testGetNewDocumentId()");
+ int numOfMecaStep = 5;
+ long maxId = -1;
+
+ startNestedTransaction();
+
+ HibernateTemplate ht = getHibernateTemplate();
+
+ Database.getInstance().reset();
+ _projectSettings.getAllSteps().clear();
+ _projectSettings.configure("classpath:test/som-generated-copy.xml");
+
+ List<String> docAfterCheckin = new ArrayList<String>();
+
+ docAfterCheckin.add("comm");
+ docAfterCheckin.add("resu");
+ docAfterCheckin.add("mess");
+
+ // Create a test user
+ User goodUser = TestEntitiesGenerator.getTestUser("goodUser");
+ _userDAO.create(goodUser);
+ Study study = TestEntitiesGenerator.getTestStudy(goodUser);
+
+
+ // Create a test study
+ _studyDAO.create(study);
+ ht.flush();
+
+ //Create a test scenario
+ Scenario scen1 = TestEntitiesGenerator.getTestScenario(study,
+ "test scen 1");
+ long id1 = _scenarioDAO.create(scen1);
+ Map<Integer, org.splat.som.Step> stSteps = _projectElementService
+ .getStepsMap(scen1);
+
+ org.splat.som.Step aStep = stSteps.get(numOfMecaStep);
+
+ Publication pub1 = createDoc("D1", "loads", "comm", aStep,
+ goodUser, scen1, ht);
+ ht.flush();
+
+ // test valid number of step
+ try {
+ _scenarioService.getNewDocumentId(id1, -1, pub1.value().getIndex(),
+ docAfterCheckin.get(0));
+ Assert.fail("Document must not be found with an invalid step number");
+ } catch (InvalidPropertyException e) {
+ LOG.debug("Expected exception: " + e.getMessage());
+ }
+
+ // first test case
+
+ Assert.assertTrue(_scenarioService.getNewDocumentId(id1, numOfMecaStep,
+ pub1.value().getIndex(), docAfterCheckin.get(0))
+ == pub1.value().getIndex());
+ Assert.assertTrue(_scenarioService.getNewDocumentId(id1, numOfMecaStep,
+ pub1.value().getIndex(), docAfterCheckin.get(1))
+ == -1);
+ Assert.assertTrue(_scenarioService.getNewDocumentId(id1, numOfMecaStep,
+ pub1.value().getIndex(), docAfterCheckin.get(2))
+ == -1);
+
+
+ scen1 = TestEntitiesGenerator.getTestScenario(study, "test scen 1");
+ id1 = _scenarioDAO.create(scen1);
+ stSteps = _projectElementService
+ .getStepsMap(scen1);
+ aStep = stSteps.get(numOfMecaStep);
+ ht.flush();
+
+ //second test case
+
+ Assert.assertTrue(_scenarioService.getNewDocumentId(id1, numOfMecaStep,
+ maxId, docAfterCheckin.get(0)) == -1);
+ Assert.assertTrue(_scenarioService.getNewDocumentId(id1, numOfMecaStep,
+ maxId, docAfterCheckin.get(1)) == -1);
+ Assert.assertTrue(_scenarioService.getNewDocumentId(id1, numOfMecaStep,
+ maxId, docAfterCheckin.get(2)) == -1);
+
+ scen1 = TestEntitiesGenerator.getTestScenario(study, "test scen 1");
+ id1 = _scenarioDAO.create(scen1);
+ stSteps = _projectElementService.getStepsMap(scen1);
+ aStep = stSteps.get(numOfMecaStep);
+
+ pub1 = createDoc("D1", "loads", "comm", aStep, goodUser, scen1, ht);
+ Publication pub2 = createDoc("D2", "resultsMeca", "resu", aStep,
+ goodUser, scen1, ht);
+
+ ht.flush();
+
+ //third test case
+
+ if (pub1.value().getIndex() > pub2.value().getIndex()) {
+ maxId = pub1.value().getIndex();
+ } else {
+ maxId = pub2.value().getIndex();
+ }
+
+ Assert.assertTrue(_scenarioService.getNewDocumentId(id1, numOfMecaStep,
+ maxId, docAfterCheckin.get(0))
+ == pub1.value().getIndex());
+ Assert.assertTrue(_scenarioService.getNewDocumentId(id1, numOfMecaStep,
+ maxId, docAfterCheckin.get(1))
+ == pub2.value().getIndex());
+ Assert.assertTrue(_scenarioService.getNewDocumentId(id1, numOfMecaStep,
+ maxId, docAfterCheckin.get(2))
+ == pub2.value().getIndex());
+
+ scen1 = TestEntitiesGenerator.getTestScenario(study, "test scen 1");
+ id1 = _scenarioDAO.create(scen1);
+ stSteps = _projectElementService.getStepsMap(scen1);
+ aStep = stSteps.get(numOfMecaStep);
+
+ pub1 = createDoc("D2", "resultsMeca", "resu", aStep,
+ goodUser, scen1, ht);
+ pub2 = createDoc("D1", "loads", "comm", aStep, goodUser, scen1, ht);
+
+ ht.flush();
+
+ // fourth test case
+
+ if (pub1.value().getIndex() > pub2.value().getIndex()) {
+ maxId = pub1.value().getIndex();
+ } else {
+ maxId = pub2.value().getIndex();
+ }
+
+ Assert.assertTrue(_scenarioService.getNewDocumentId(id1, numOfMecaStep,
+ maxId, docAfterCheckin.get(0)) == pub2.value().getIndex());
+ Assert.assertTrue(_scenarioService.getNewDocumentId(id1, numOfMecaStep,
+ maxId, docAfterCheckin.get(1)) == pub1.value().getIndex());
+ Assert.assertTrue(_scenarioService.getNewDocumentId(id1, numOfMecaStep,
+ maxId, docAfterCheckin.get(2)) == pub1.value().getIndex());
+
+ rollbackNestedTransaction();
+ LOG.debug(">>>>> END testGetNewDocId()");
+ }
+
+ /**
+ * Create a document published in the scenario. <BR>
+ *
+ * @param name
+ * name of the document
+ * @param docType
+ * type of the document
+ * @param format
+ * document extension
+ * @param step
+ * scenario step where the document to be published
+ * @param user
+ * User of document
+ * @param scen
+ * the scenario to add the document to
+ * @param ht
+ * hinernate session
+ *
+ *
+ * @return the publication of the created document
+ * @throws IOException
+ * @throws SQLException
+ * @throws BusinessException
+ */
+
+ protected final Publication createDoc(final String name,
+ final String docType, final String format,
+ final org.splat.som.Step step, final User user,
+ final Scenario scen,
+ final HibernateTemplate ht)throws
+ IOException, SQLException, BusinessException {
+ DocumentType dtype = _documentTypeService.selectType(docType);
+
+ Document.Properties dprop = new Document.Properties().setAuthor(
+ user).setDate(new Date()).setName(name)
+ .setType(dtype).setFormat(format);
+
+ dprop.setStep(step.getStep());
+ Publication pub = _stepService.createDocument(step, dprop);
+
+ pub.setStep(step);
+ scen.add(pub);
+
+ step.getDocuments().add(pub);
+
+ ht.saveOrUpdate(pub);
+ ht.save(pub.value());
+
+ return pub;
+ }
+
+ /**
+ * Test of getting a scenario content for building siman-salome.conf.<BR>
+ * <B>Description :</B> <BR>
+ * <i>Create a scenario and try to get an info for it.</i><BR>
+ * <B>Action : </B><BR>
+ * <i>1. call the method for an existing scenario id.</i><BR>
+ * <i>2. call the method for a not existing scenario id.</i><BR>
+ * <B>Test data : </B><BR>
+ * <i>no input parameters</i><BR>
+ * <i>no input parameters</i><BR>
+ *
+ * <B>Outcome results:</B><BR>
+ * <i>
+ * <ul>
+ * <li>result DTO must contain list of all documents and files<BR>
+ * </li>
+ * <li>Exception is thrown<BR>
+ * </li>
+ * </ul>
+ * </i>
+ *
+ * @throws InvalidPropertyException
+ * if an invalid property is used when creating objects
+ * @throws MultiplyDefinedException
+ * when trying to create an object with already existing id
+ * @throws MissedPropertyException
+ * if a mandatory property is not defined for an object to be
+ * created
+ * @throws IOException
+ * if scenario creation is failed
+ * @throws SQLException
+ * if scenario creation is failed
+ */
+ @Test(groups = { "checkout", "sevice", "functional", "business" })
+ public void testGetScenarioInfo() throws InvalidPropertyException,
+ MissedPropertyException, MultiplyDefinedException, IOException,
+ SQLException {
+ LOG.debug(">>>>> BEGIN testGetScenarioInfo()");
+ startNestedTransaction();
+
+ long scenarioId = createScenario();
+ // Call DAO's create method for a good transient knowledge element.
+ List<StepDTO> steps = _scenarioService.getScenarioInfo(scenarioId);
+ Assert.assertNotNull(steps, "List of steps must not be null.");
+ Assert.assertTrue(steps.size() > 0, "No steps are read.");
+
+ List<Step> projSteps = _stepsConfigService.getStepsOf(Scenario.class);
+ Assert.assertEquals(steps.size(), projSteps.size(),
+ "Not all steps are listed.");
+ int docIndex = 0;
+ for (StepDTO step : steps) {
+ LOG.debug("check the step " + step.getNumber() + ":\n" + step);
+ Assert.assertNotNull(step, "Step DTO must not be null.");
+ Assert.assertNotNull(step.getKey(), "Step name must not be null.");
+ Assert.assertFalse(step.getKey().isEmpty(),
+ "Step name must not empty.");
+ Assert.assertTrue(step.getNumber() > 0,
+ "Step number must be positive integer.");
+ Assert.assertNotNull(step.getDocs(),
+ "Step documents list must not be null.");
+
+ Step aProjStep = null;
+ for (Step projStep : projSteps) {
+ if (projStep.getNumber() == step.getNumber()) {
+ aProjStep = projStep;
+ break;
+ }
+ }
+
+ List<DocumentType> dtypes = _documentTypeService
+ .selectTypesOf(aProjStep);
+ for (DocumentType dtype : dtypes) {
+ Assert.assertTrue(step.getDocs().size() > 0,
+ "Step documents list must not be empty.");
+ String docName = "document" + docIndex;
+ for (DocumentDTO doc : step.getDocs()) {
+ if (docName.equals(doc.getTitle())) {
+ Assert.assertTrue(doc.getId() > 0,
+ "Document id must be positive integer.");
+ Assert.assertEquals(doc.getTitle(), docName);
+ Assert.assertNotNull(doc.getFiles(),
+ "Document files list must not be null.");
+ Assert.assertTrue(doc.getFiles().size() > 1,
+ "Document must have more then 1 attached file.");
+
+ for (FileDTO file : doc.getFiles()) {
+ Assert.assertNotNull(file.getPath(),
+ "File path must not be null.");
+ Assert.assertFalse(file.getPath().isEmpty(),
+ "File path must not be empty.");
+ /*
+ * <mappings> <document type="geometry"> <import
+ * format="brep"/> <!-- Result Shape --> </document>
+ * <document type="model"> <import format="med"/>
+ * <!-- Result mesh without input parameters -->
+ * </document> <document type="loads"> <import
+ * format="c3m"/> <!-- Input data created
+ * interactively --> </document> <document
+ * type="results"> <import format="med"/> <!--
+ * Calculation results source file --> </document>
+ * </mappings>
+ */
+ // Check state and processing instruction
+ String fileFormat = file.getPath().substring(
+ file.getPath().lastIndexOf('.') + 1);
+ /*
+ * if (_projectSettings.doImport(dtype.getName(),
+ * fileFormat)) { Assert.assertTrue(file.isResult(),
+ * "The file must be a result file.
+ * "); } else { Assert.assertFalse(file.isResult(), "
+ * The file must be a source file."); }
+ */if ((docIndex % 2) == 0) { // New
+ Assert.assertEquals(file.getState(), 'Y',
+ "File state must be actual ('Y').");
+ if (_projectSettings.doImport(dtype.getName(),
+ fileFormat)) {
+ Assert.assertEquals(file.getProcessing(),
+ "file-import",
+ "File must be imported.");
+ } else {
+ Assert.assertEquals(file.getProcessing(),
+ "file-download",
+ "File must be downloaded.");
+ }
+ } else { // Outdated
+ Assert.assertEquals(file.getState(), 'O',
+ "File state must be outdated ('O').");
+ Assert.assertEquals(file.getProcessing(),
+ "file-download",
+ "Outdated document should not be imported but downloaded.");
+ }
+ }
+ }
+ }
+ docIndex++;
+ }
+ }
+
+ // Call DAO's get method for a not existing id.
+ try {
+ steps = _scenarioService.getScenarioInfo(-1L);
+ // getHibernateTemplate().flush();
+ Assert.fail("Getting an object with not existing id must be failed.");
+ } catch (Exception e) {
+ LOG.debug("Expected exception is thrown: "
+ + e.getClass().getSimpleName() + ": " + e.getMessage());
+ }
+ rollbackNestedTransaction();
+ LOG.debug(">>>>> END testGetScenarioInfo()");
+ }
+
+ /**
+ * Test check-in scenario operation to be performed after SALOME session.<BR>
+ * <B>Description :</B> <BR>
+ * <i>Create a scenario and try to check-in it with some simulated SALOME
+ * results data.<BR>
+ * After check-in verify following points:
+ * <ul>
+ * <li>scenario is no more marked as checked out</li>
+ * <li>new document versions are created for checked in documents</li>
+ * <li>presentation of the previous version is removed</li>
+ * <li>uses relations are copied correctly</li>
+ * <li>files are moved correctly</li>
+ * <li>formats of files are new if they are according to the document's type
+ * on the study step</li>
+ * <li>new documents are created for new data</li>
+ * <li>new documents have correctly generated names</li>
+ * <li>uses relations are created correctly</li>
+ * <li>files are moved correctly</li>
+ * </ul>
+ * </i><BR>
+ * <B>Action : </B><BR>
+ * <i>1. call the method for an existing scenario id.</i><BR>
+ * <i>2. call the method for a not existing scenario id.</i><BR>
+ * <B>Test data : </B><BR>
+ * <i>no input parameters</i><BR>
+ * <i>no input parameters</i><BR>
+ *
+ * <B>Outcome results:</B><BR>
+ * <i>
+ * <ul>
+ * <li>New version of existing documents must be created and new documents
+ * must be imported for documents with zero id. Correct relations must be
+ * created.<BR>
+ * </li>
+ * <li>Exception is thrown<BR>
+ * </li>
+ * </ul>
+ * </i>
+ *
+ * @throws InvalidPropertyException
+ * if an invalid property is used when creating objects
+ * @throws MultiplyDefinedException
+ * when trying to create an object with already existing id
+ * @throws MissedPropertyException
+ * if a mandatory property is not defined for an object to be
+ * created
+ * @throws IOException
+ * if scenario creation is failed
+ * @throws SQLException
+ * if scenario creation is failed
+ * @throws NotApplicableException
+ * if checkin failed
+ * @throws MismatchException
+ * if checkin failed
+ */
+ @Test(groups = { "checkin", "sevice", "functional", "business" })
+ public void testCheckin() throws InvalidPropertyException,
+ MissedPropertyException, MultiplyDefinedException, IOException,
+ SQLException, MismatchException, NotApplicableException {
+ LOG.debug(">>>>> BEGIN testCheckin()");
+ startNestedTransaction();
+
+ _projectSettings.getAllSteps().clear(); // Clear config to be able to
+ // load it again
+ _projectSettings.configure("classpath:test/som.xml");
+ getHibernateTemplate().flush();
+ long scenarioId = createScenario();
+ Scenario aScen = _scenarioDAO.get(scenarioId);
+ User user = aScen.getAuthor();
+ long userId = user.getIndex();
+
+ // ////////////////////////////////////////////////////////
+ // Call checkin method for empty list of modules.
+
+ // Simulate checkout
+ _scenarioService.checkout(aScen, user);
+ _scenarioDAO.flush();
+ // Check that scenario is no more marked as checked out
+ aScen = _scenarioDAO.get(scenarioId);
+ Assert.assertTrue(aScen.isCheckedout(),
+ "Scenario is not marked as checked out after checkout.");
+
+ // Prepare test data for checkin
+ // Checkin only two first steps (geom and mesh)
+ List<StepDTO> stepsToCheckin = new ArrayList<StepDTO>();
+ // Do test checkin
+ _scenarioService.checkin(scenarioId, userId, stepsToCheckin);
+
+ _scenarioDAO.flush();
+ // Check that scenario is no more marked as checked out
+ aScen = _scenarioDAO.get(scenarioId);
+ Assert.assertFalse(aScen.isCheckedout(),
+ "Scenario is still marked as checked out after checkin.");
+
+ // ///////////////////////////////////////////////////////////
+ // Different test cases
+
+ // Fancy but compact way to iterate over all possible combinations
+ // without missing any of them.
+ List<Boolean> trueFalse = new ArrayList<Boolean>();
+ trueFalse.add(false);
+ trueFalse.add(true);
+ long testCaseNumber = 1; // To provide some uniqueness to files content.
+
+ for (boolean hasSource : trueFalse) {
+ for (boolean hasAttachments : trueFalse) {
+ for (boolean checkinSource : trueFalse) {
+ for (boolean checkinAttachments : trueFalse) {
+ if (hasAttachments && !hasSource) { // Impossible test
+ // cases
+ continue;
+ }
+ if (!checkinAttachments && !checkinSource) { // Unnecessary
+ // test
+ // cases
+ continue;
+ }
+
+ // startNestedTransaction();
+ Set<String> res = testCheckinTestcase(testCaseNumber++,
+ scenarioId, userId, hasSource, hasAttachments,
+ checkinSource, checkinAttachments);
+ // rollbackNestedTransaction();
+
+ // These combinations are dictated by
+ // assertCheckinValidity logic
+ Assert.assertEquals(!hasSource
+ && (checkinSource || checkinAttachments),
+ res.contains("aNewSourceCreated"));
+ Assert.assertEquals(hasSource && checkinSource,
+ res.contains("oldSourceVersioned"));
+ Assert.assertEquals(checkinAttachments && hasSource
+ && checkinSource,
+ res.contains("fileAttachedToAVersionedDoc"));
+ Assert.assertEquals(checkinAttachments && hasSource
+ && !checkinSource,
+ res.contains("fileAttachedToAnOldDoc"));
+ Assert.assertEquals(checkinAttachments && !hasSource,
+ res.contains("fileAttachedToANewDoc"));
+
+ }
+ }
+ }
+ }
+
+ // ///////////////////////////////////////////////////////////
+ // Call checkin method for a not existing id.
+ try {
+ _scenarioService.checkin(-1, userId, stepsToCheckin);
+ Assert.fail("Check in for scenario with not existing id must be failed.");
+ } catch (Exception e) {
+ LOG.debug("Expected exception is thrown: "
+ + e.getClass().getSimpleName() + ": " + e.getMessage());
+ }
+
+ // Test checkin with empty list of steps
+ stepsToCheckin.clear();
+ _scenarioService.checkin(scenarioId, userId, stepsToCheckin);
+
+ rollbackNestedTransaction();
+ LOG.debug(">>>>> END testCheckin()");
+ }
+
+ /**
+ * Performs necessary checks after checkin.
+ *
+ * @param testCaseNumber
+ * the test case number
+ * @param stepsToCheckin
+ * stepDTOs which has been checked in
+ * @param aScen
+ * the scenario
+ * @param dates
+ * modification dates
+ * @return set of strings indicating which cases has occurred
+ * @throws IOException
+ * if something is wrong
+ */
+ private Set<String> assertCheckinValidity(final long testCaseNumber,
+ final List<StepDTO> stepsToCheckin, final Scenario aScen,
+ final Map<Long, Date> dates) throws IOException {
+ Set<String> result = new HashSet<String>();
+ Assert.assertFalse(aScen.isCheckedout(),
+ "Scenario is still marked as checked out after checkin.");
+ // Check that new document versions are created for checked in documents
+ for (StepDTO step : stepsToCheckin) {
+ for (DocumentDTO docDTO : step.getDocs()) {
+ for (FileDTO fileDTO : docDTO.getFiles()) {
+
+ if ((docDTO.getId() != 0) && (docDTO.getId() != null)) {
+ boolean prevVersFound = false;
+ boolean versionedWithThisFile = false;
+ Document prevDoc = null;
+ Document curDoc = null;
+ Publication newPub = null;
+
+ // If previous version is found then the format must be
+ // the same
+ String newFormat = fileDTO.getPath().substring(
+ fileDTO.getPath().lastIndexOf('.') + 1);
+ for (Publication pub : aScen.getDocums()) {
+ prevDoc = pub.value().getPreviousVersion();
+ if (prevDoc != null) {
+ prevVersFound = (prevDoc.getIndex() == docDTO
+ .getId());
+ if (prevVersFound) { // Found next published
+ // version of the checked
+ // in document
+ newPub = pub;
+ if (pub.value().getFormat()
+ .equals(newFormat)) {
+ versionedWithThisFile = true;
+ }
+ break;
+ }
+ }
+ if (pub.value().getIndex() == docDTO.getId()) {
+ // Document version was not changed, old
+ // document is still published
+ curDoc = pub.value();
+ break;
+ }
+ }
+ Assert.assertTrue(prevVersFound || (curDoc != null),
+ "New version or new attached file of the existing checked in document \""
+ + docDTO.getTitle() + "\" (id="
+ + docDTO.getId()
+ + ") is not found in the scenario.");
+
+ if (prevVersFound && versionedWithThisFile) {
+ result.add("oldSourceVersioned");
+ Assert.assertFalse(aScen.publishes(prevDoc));
+ // Check that presentation of the previous version
+ // is removed
+ checkFiles(docDTO, newPub);
+
+ // Formats of files are new if they are according to
+ // the document's type on the study step
+ Assert.assertEquals(newPub.getSourceFile()
+ .getFormat(), newFormat);
+ Assert.assertEquals(
+ newPub.getSourceFile()
+ .getRelativePath()
+ .substring(
+ newPub.getSourceFile()
+ .getRelativePath()
+ .lastIndexOf('.') + 1),
+ newFormat);
+
+ // Check that uses relations are copied correctly
+
+ // 1. Get all uses relations of the previous
+ // document version
+ for (Relation rel : prevDoc
+ .getRelations(UsesRelation.class)) {
+ Document used = ((UsesRelation) rel).getTo();
+ // 2.1. Get the latest version of the document
+ // published in this scenario
+ Publication toBeUsed = aScen
+ .getPublication(used);
+ if (toBeUsed == null) {
+ // Find the latest published version
+ for (Publication lastPub : aScen
+ .getDocums()) {
+ if ((lastPub.value()
+ .getPreviousVersion() != null)
+ && (lastPub.value()
+ .getPreviousVersion()
+ .getIndex() == used
+ .getIndex())) {
+ toBeUsed = lastPub;
+ break;
+ }
+ }
+ }
+ if ((toBeUsed != null)
+ && (!toBeUsed.isOutdated())) {
+ // 2.2. For each used document check that
+ // its latest not outdated version
+ // is used by the new checked in document
+ // version.
+ checkUsesRelation(newPub, toBeUsed);
+ }
+ }
+ // 1. Get all usedBy relations of the previous
+ // document version
+ for (Relation rel : prevDoc
+ .getRelations(UsedByRelation.class)) {
+ Document using = ((UsedByRelation) rel).getTo();
+ // Check that not checked in dependent documents
+ // became outdated
+ Publication usingPub = aScen
+ .getPublication(using);
+ if (usingPub != null) { // if the document using
+ // the old version is
+ // still published
+ Assert.assertTrue(usingPub.isOutdated(),
+ "Not checked in dependent document "
+ + using.getTitle() + " ("
+ + using.getType().getName()
+ + ") must become outdated.");
+ }
+ }
+
+ // Check that a correct comment is generated for
+ // VersionsRelation
+ VersionsRelation versRel = (VersionsRelation) newPub
+ .value().getFirstRelation(
+ VersionsRelation.class);
+ Assert.assertNotNull(versRel,
+ "VersionsRelation must be created.");
+ Assert.assertNotNull(versRel.getDescription(),
+ "VersionsRelation description was not generated.");
+ int descrLen = versRel.getDescription().length();
+ Assert.assertTrue(descrLen > 0,
+ "VersionsRelation description is empty.");
+ LOG.debug("Version description: "
+ + versRel.getDescription());
+ } else {
+ // Otherwise the file is attached to some other
+ // document,
+ // which has been or has not been versioned during
+ // checkin
+ Document targetDoc = null;
+ if (prevVersFound) { // if the document has been
+ // versioned
+ Assert.assertEquals(
+ Long.valueOf(prevDoc.getIndex()),
+ docDTO.getId());
+ targetDoc = newPub.value();
+ result.add("fileAttachedToAVersionedDoc");
+ } else {
+ targetDoc = curDoc;
+ result.add("fileAttachedToAnOldDoc");
+ }
+ Assert.assertFalse(newFormat.equals(targetDoc
+ .getFormat()));
+
+ // Check file content
+ Assert.assertTrue(Files.readFile(
+ targetDoc.getAttachedFile(newFormat)
+ .asFile()).contains(
+ new File(fileDTO.getPath()).getName()));
+
+ // Otherwise the new file format must differ from
+ // the previous one
+ // and the new file must be attached to the same
+ // document
+ org.splat.dal.bo.som.File attFile = targetDoc
+ .getAttachedFile(newFormat);
+ Assert.assertNotNull(
+ attFile,
+ "File "
+ + fileDTO.getPath()
+ + " must be attached to the document "
+ + docDTO.getTitle() + "#"
+ + docDTO.getId());
+ Assert.assertTrue(
+ attFile.asFile().exists(),
+ "File " + fileDTO.getPath()
+ + " attached to the document "
+ + docDTO.getTitle() + "#"
+ + docDTO.getId() + " doesn't exist");
+ LOG.debug("Source format: " + targetDoc.getFormat()
+ + ", new format: " + newFormat);
+ // Check that attachment with the same format is not
+ // duplicated.
+ int attachNb = 0;
+ for (Relation conv : targetDoc
+ .getRelations(ConvertsRelation.class)) {
+ if (newFormat.equals(((ConvertsRelation) conv)
+ .getTo().getFormat())) {
+ attachNb++;
+ }
+ }
+ Assert.assertEquals(attachNb, 1,
+ "Attachment with the same format must be only one.");
+
+ // Check that the attached file date is updated
+ if (dates.containsKey(attFile.getIndex())) {
+ Assert.assertTrue(
+ attFile.getDate().compareTo(
+ dates.get(attFile.getIndex())) > 0,
+ "Attachment modification date is not updated.");
+ result.add("modifDatesChecked");
+ }
+ }
+
+ } else {
+ // here file may be attached to a newly created one,
+ // or it may be a source of new doc itself.
+
+ // Check that new documents are created for new data
+ boolean foundAsSource = false;
+ boolean foundAsAttachment = false;
+ Publication newPub = null;
+ for (Publication pub : aScen.getDocums()) {
+ if (pub.value().getPreviousVersion() == null) {
+ // TODO: is it correct? type name here?
+ foundAsSource = (pub.value().getTitle()
+ .startsWith(pub.value().getType()
+ .getName()));
+ if (foundAsSource) { // Found next published
+ // version of the checked
+ // in document
+ String fcontent = Files.readFile(pub
+ .getSourceFile().asFile());
+ foundAsSource = fcontent.contains(new File(
+ fileDTO.getPath()).getName());
+ if (foundAsSource) {
+ LOG.debug("Found new document with generated title: "
+ + pub.value().getTitle());
+ newPub = pub;
+ break;
+ }
+ }
+
+ String format = fileDTO.getPath().substring(
+ fileDTO.getPath().lastIndexOf('.') + 1);
+ org.splat.dal.bo.som.File attachment = pub
+ .value().getAttachedFile(format);
+ if (attachment != null) {
+ String fcontent = Files.readFile(attachment
+ .asFile());
+ if (fcontent.contains(new File(fileDTO
+ .getPath()).getName())) {
+ foundAsAttachment = true;
+ Assert.assertFalse(
+ new File(fileDTO.getPath())
+ .exists(),
+ "File"
+ + fileDTO.getPath()
+ + " was not removed from downloads directory.");
+ result.add("fileAttachedToANewDoc");
+ break;
+ }
+ }
+ }
+ }
+ Assert.assertTrue(foundAsSource || foundAsAttachment,
+ "New document or attachment is not created for checked in document \""
+ + docDTO.getTitle() + "\".");
+
+ if (foundAsSource) {
+
+ // TODO: check that all the conditions for this file
+ // to be chosen
+ // as fileToAttachTo are present.
+ // probably, drop some unimportant
+
+ // Check file content
+ Assert.assertTrue(Files.readFile(
+ newPub.getSourceFile().asFile()).contains(
+ new File(fileDTO.getPath()).getName()));
+
+ result.add("aNewSourceCreated");
+ // Check that uses relations are created correctly
+ Assert.assertTrue(
+ newPub.value()
+ .getTitle()
+ .startsWith(
+ newPub.value().getType()
+ .getName()
+ + "_"),
+ "Document title newPub.value().getTitle() must start with "
+ + newPub.value().getType()
+ .getName() + "_");
+
+ // 1. Find the document type used by this document
+ // type
+ Set<DocumentType> usedTypes = newPub.value()
+ .getType().getDefaultUses();
+ // 2. Find documents of used types in the current
+ // study step and previous study steps
+ for (Publication pub : aScen.getDocums()) {
+ if ((pub.getStep().getNumber() <= step
+ .getNumber())
+ && (!pub.isOutdated())
+ && usedTypes.contains(pub.value()
+ .getType())
+ && !newPub.equals(pub)) {
+ // 3. Check that there is uses relation to
+ // the found document
+ // if it is not outdated.
+ checkUsesRelation(newPub, pub);
+ }
+ }
+
+ // Check that files are moved correctly
+ checkFiles(docDTO, newPub);
+ }
+ }
+ }
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Check if there is uses relation from the newPub to pub.
+ *
+ * @param newPub
+ * the new publication
+ * @param pub
+ * the publication to be used
+ */
+ private void checkUsesRelation(final Publication newPub,
+ final Publication pub) {
+ boolean uses = false;
+ boolean usesExist = false;
+ for (Publication usesPub : newPub.getRelations(UsesRelation.class)) {
+ usesExist = true;
+ uses = (usesPub.equals(pub));
+ if (uses) {
+ break;
+ }
+ }
+ Assert.assertTrue(usesExist && uses, "The created document "
+ + newPub.value().getTitle() + "("
+ + newPub.value().getType().getName() + ")"
+ + " has no uses relation to the document "
+ + pub.value().getTitle() + "("
+ + pub.value().getType().getName() + ")");
+ }
+
+ /**
+ * Check that files are moved correctly.
+ *
+ * @param docDTO
+ * checked in document DTO
+ * @param newPub
+ * the created document publication
+ */
+ private void checkFiles(final DocumentDTO docDTO, final Publication newPub) {
+ // Check that original files are deleted
+ for (int j = 0; j < docDTO.getFiles().size(); j++) {
+ FileDTO fileDTO = docDTO.getFiles().get(j);
+ Assert.assertFalse(new File(fileDTO.getPath()).exists(), "File"
+ + fileDTO.getPath()
+ + " was not removed from downloads directory.");
+ String format = fileDTO.getPath().substring(
+ fileDTO.getPath().lastIndexOf('.') + 1);
+ }
+ // TODO: Check file by its internal content
+ Assert.assertTrue(newPub.getSourceFile().exists(), "File "
+ + newPub.getSourceFile().asFile().getAbsolutePath()
+ + " for the document " + docDTO.getTitle()
+ + " was not created.");
+ }
+
+ /**
+ * Prepare a document with a file for check-in.
+ *
+ * @param stepTo
+ * step DTO with data for check-in
+ * @param module
+ * SALOME module name
+ * @param format
+ * file extension
+ * @param userId
+ * download directory
+ * @param stepFrom
+ * checked out stepDTO
+ * @param stepsToCheckin
+ * DTO for check-in
+ * @throws IOException
+ * if file creation failed
+ * @return step DTO with data prepared for check-in (stepTo or new if stepTo
+ * is null)
+ */
+ private StepDTO createDocDTOForModule(final StepDTO stepTo,
+ final String module, final String format, final long userId,
+ final StepDTO stepFrom, final List<StepDTO> stepsToCheckin)
+ throws IOException {
+ StepDTO stepToCheckin = stepTo;
+ if (stepToCheckin == null) {
+ stepToCheckin = new StepDTO();
+ }
+ if (module.equals(stepFrom.getModule())) {
+ stepsToCheckin.add(stepToCheckin);
+ stepToCheckin.setNumber(stepFrom.getNumber());
+ for (DocumentDTO doc : stepFrom.getDocs()) {
+ if (doc.getFiles().get(0).getState() != 'O') {
+ DocumentDTO docToCheckin = stepToCheckin.addDoc(
+ doc.getId(), doc.getTitle());
+ for (FileDTO file : doc.getFiles()) {
+ if (file.getPath().endsWith(format)
+ || (file.getPath().endsWith("py") && (format
+ .equals("brep") || format.equals("med")))) {
+ // Create a file in the download directory
+ if ("GEOM".equals(module)) {
+ // New version case
+ docToCheckin.addFile(createDownloadedFile(
+ userId, doc.getTitle() + "_newvers",
+ "py"));
+ } else {
+ // Attached generated result case
+ docToCheckin.addFile(createDownloadedFile(
+ userId, doc.getTitle() + "_result",
+ format));
+ }
+ }
+ }
+ }
+ }
+ // Prepare new data
+ stepToCheckin.addDoc(0, "newdoc" + stepFrom.getNumber()).addFile(
+ createDownloadedFile(userId,
+ "newdoc" + stepFrom.getNumber(), "brep"));
+ }
+ return stepToCheckin;
+ }
+
+ /**
+ * Tests a checkin testcase.
+ *
+ * @param testCaseNumber
+ * the test case number
+ * @param scenarioId
+ * the scenrio id
+ * @param userId
+ * the user id
+ * @param hasSource
+ * whether the scenario is supposed to have a source file in this
+ * test case befor checkin
+ * @param hasAttachments
+ * whether the scenario is supposed to have files attached to the
+ * source in this test case befor checkin
+ * @param checkinSource
+ * whether the "comm" file should be checked in
+ * @param checkinAttachment
+ * whether the "resu" and "mess" files should be checked in
+ * @return set of strings indicating which cases has occurred
+ * @throws IOException
+ * if something is wrong
+ * @throws InvalidPropertyException
+ * if something is wrong
+ * @throws MultiplyDefinedException
+ * if something is wrong
+ * @throws MissedPropertyException
+ * if something is wrong
+ * @throws SQLException
+ * if something is wrong
+ * @throws NotApplicableException
+ * if something is wrong
+ * @throws MismatchException
+ * if something is wrong
+ */
+ private Set<String> testCheckinTestcase(final long testCaseNumber,
+ final long scenarioId, final long userId, final boolean hasSource,
+ final boolean hasAttachments, final boolean checkinSource,
+ final boolean checkinAttachment) throws IOException,
+ InvalidPropertyException, MultiplyDefinedException,
+ MissedPropertyException, SQLException, NotApplicableException,
+ MismatchException {
+
+ Scenario aScen = _scenarioDAO.get(scenarioId);
+ User user = _userDAO.get(userId);
+
+ List<StepDTO> steps = _scenarioService.getScenarioInfo(scenarioId);
+
+ // ////////////////////////////////////////////////////////
+ // Call checkin method for good prepared transient data.
+
+ // Simulate checkout
+ steps = _scenarioService.getScenarioInfo(scenarioId);
+ _scenarioService.checkout(aScen, user);
+
+ // Remember modification dates of all attached files
+ Map<Long, Date> dates = new HashMap<Long, Date>();
+ for (Publication p : aScen.getDocums()) {
+ for (Relation r : p.value().getRelations(ConvertsRelation.class)) {
+ org.splat.dal.bo.som.File attach = ((ConvertsRelation) r)
+ .getTo();
+ dates.put(attach.getIndex(), attach.getDate());
+ }
+ }
+
+ long targetDocId = addMecaDocsToScenario(testCaseNumber, aScen, user,
+ hasAttachments, hasSource);
+
+ List<StepDTO> stepsToCheckin = new ArrayList<StepDTO>();
+ for (StepDTO step : steps) {
+ createDocDTOForMeca(testCaseNumber, targetDocId, null, userId,
+ step, stepsToCheckin, checkinSource, checkinAttachment);
+ }
+
+ // /////////////////////////////////////////////////////////////////
+ // Do test checkin
+ _scenarioService.checkin(scenarioId, userId, stepsToCheckin);
+
+ // Check that scenario is no more marked as checked out
+ aScen = _scenarioDAO.get(scenarioId);
+ return assertCheckinValidity(testCaseNumber, stepsToCheckin, aScen,
+ dates);
+ }
+
+ /**
+ * It will delete any "comm" publications in the scenario, and then create a
+ * new one, with attachments if specified.
+ *
+ * @param testCaseNumber
+ * the test case number
+ * @param aScen
+ * the scenario
+ * @param user
+ * user who will be used as an author for the added documents
+ * @param hasAttachments
+ * whether to add the "comm" doc to the scenario
+ * @param hasSource
+ * whether to add "resu" and "mess" docs to the scenario
+ * @return the source document id, if exists, 0 otherwise.
+ * @throws IOException
+ * if something is wrong
+ * @throws InvalidPropertyException
+ * if something is wrong
+ * @throws MissedPropertyException
+ * if something is wrong
+ * @throws MultiplyDefinedException
+ * if something is wrong
+ */
+ private long addMecaDocsToScenario(final long testCaseNumber,
+ final Scenario aScen, final User user,
+ final boolean hasAttachments, final boolean hasSource)
+ throws IOException, InvalidPropertyException,
+ MissedPropertyException, MultiplyDefinedException {
+
+ long res = 0;
+ org.splat.som.Step mecaStep = null;
+ for (org.splat.som.Step step : _projectElementService.getSteps(aScen)) {
+ if ("SALOME_MECA".equals(step.getStep().getModule())) {
+ mecaStep = step;
+ }
+ }
+
+ // remove comm documents
+ List<Publication> toRemove = new ArrayList<Publication>();
+ for (Publication pub : mecaStep.getDocuments()) {
+ if ("comm".equals(pub.value().getFormat())) {
+ toRemove.add(pub);
+ }
+ }
+ for (Publication pub : toRemove) {
+ // remove relations so the publication can be removed correctly
+ List<Relation> relations = new ArrayList<Relation>();
+ relations.addAll(pub.value().getAllRelations());
+ for (Relation rel : relations) {
+ pub.value().removeRelation(UsesRelation.class, rel.getTo());
+ }
+ aScen.remove(pub);
+ }
+
+ if (hasSource) {
+ // Select result document type for Meca step
+ List<DocumentType> dtypes = _documentTypeService
+ .selectTypesOf(mecaStep.getStep());
+ DocumentType resultType = null;
+ for (DocumentType doctype : dtypes) {
+ if (doctype.isResultOf(mecaStep.getStep())) {
+ resultType = doctype;
+ break;
+ }
+ }
+
+ Document.Properties dprop = new Document.Properties();
+ File directory = _repositoryService.getDownloadDirectory(user);
+ directory.mkdirs();
+ dprop.setName("commDoc" + testCaseNumber).setFormat("comm")
+ .setAuthor(user).setDate(new Date()).setType(resultType)
+ .setLocalPath(dprop.getName() + "." + dprop.getFormat());
+
+ Publication commPub = createDoc(aScen, mecaStep, dprop, "", false);
+ // The following is necessary because createDoc does not do all
+ // required work
+ // (and PublicationServiceImpl.createDoc() is complicated so it's
+ // harder to make it work)
+ commPub.setStep(mecaStep);
+ aScen.getDocums().add(commPub);
+ mecaStep.getDocuments().add(commPub);
+
+ res = commPub.value().getIndex();
+
+ // add attachments
+ if (hasAttachments) {
+ // Create new "resu" file
+ FileDTO resuFileDTO = createDownloadedFile(user.getIndex(),
+ "resuFile", "resu");
+ ConvertsRelation export = _publicationService.attach(commPub,
+ "resu");
+ File resuFile = new File(resuFileDTO.getPath());
+ File dest = export.getTo().asFile();
+ dest.delete();
+ Assert.assertTrue(resuFile.renameTo(dest));
+
+ // Create new "mess" file
+ FileDTO messFileDTO = createDownloadedFile(user.getIndex(),
+ "messFile", "mess");
+ export = _publicationService.attach(commPub, "mess");
+ File messFile = new File(messFileDTO.getPath());
+ dest = export.getTo().asFile();
+ dest.delete();
+ Assert.assertTrue(messFile.renameTo(dest));
+ }
+ }
+
+ return res;
+ }
+
+ /**
+ * Prepare a document with a file for check-in.
+ *
+ * @param stepTo
+ * step DTO with data for check-in
+ * @param userId
+ * download directory
+ * @param stepFrom
+ * checked out stepDTO
+ * @param stepsToCheckin
+ * DTO for check-in
+ * @param createSource
+ * whether to add the COMM file to the DTO
+ * @param createAttachment
+ * whether to add the RESU and MESS files to the DTO
+ * @throws IOException
+ * if file creation failed
+ * @return step DTO with data prepared for check-in (stepTo or new if stepTo
+ * is null)
+ */
+ private StepDTO createDocDTOForMeca(final long testCaseNumber,
+ final long targetDocId, final StepDTO stepTo, final long userId,
+ final StepDTO stepFrom, final List<StepDTO> stepsToCheckin,
+ final boolean createSource, final boolean createAttachment)
+ throws IOException {
+ StepDTO stepToCheckin = stepTo;
+ if (stepToCheckin == null) {
+ stepToCheckin = new StepDTO();
+ }
+ if ("SALOME_MECA".equals(stepFrom.getModule())) {
+
+ stepsToCheckin.add(stepToCheckin);
+ stepToCheckin.setNumber(stepFrom.getNumber());
+
+ DocumentDTO docToCheckin = stepToCheckin.addDoc(targetDocId,
+ "newCommDoc");
+
+ if (createSource) {
+ docToCheckin.addFile(createDownloadedFile(userId, "newCommDoc"
+ + testCaseNumber + "_result", "comm"));
+ }
+ if (createAttachment) {
+ docToCheckin.addFile(createDownloadedFile(userId, "newResuDoc"
+ + testCaseNumber + "_result", "resu"));
+ docToCheckin.addFile(createDownloadedFile(userId, "newMessDoc"
+ + testCaseNumber + "_result", "mess"));
+ }
+ }
+ return stepToCheckin;
+ }
+
+ /**
+ * Create a file in the user's repository downloads directory.
+ *
+ * @param userId
+ * user id
+ * @param name
+ * file name
+ * @param format
+ * file extension
+ * @return created file DTO
+ * @throws IOException
+ * if file creation failed
+ */
+ private FileDTO createDownloadedFile(final long userId, final String name,
+ final String format) throws IOException {
+ // Create a file in the download directory
+ return createDownloadedFile(userId, name + "." + format);
+ }
+
+ /**
+ * Create a file in the user's repository downloads directory.
+ *
+ * @param userId
+ * user id
+ * @param fname
+ * file name
+ * @return created file DTO
+ * @throws IOException
+ * if file creation failed
+ */
+ private FileDTO createDownloadedFile(final long userId, final String fname)
+ throws IOException {
+ // Create a file in the download directory
+ String filePath = getDownloadPath(userId) + fname;
+ FileWriter fw = new FileWriter(filePath);
+ fw.write("Simulation of " + fname + " file for checkin at "
+ + new Date());
+ fw.close();
+ return new FileDTO(filePath);
+ }
+
+ /**
+ * Create a persistent scenario for tests.
+ *
+ * @return a persistent scenario
+ * @throws InvalidPropertyException
+ * if an invalid property is used when creating objects
+ * @throws MultiplyDefinedException
+ * when trying to create an object with already existing id
+ * @throws MissedPropertyException
+ * if a mandatory property is not defined for an object to be
+ * created
+ * @throws IOException
+ * if document creation is failed
+ * @throws SQLException
+ * if project settings loading is failed
+ */
+ private long createScenario() throws InvalidPropertyException,
+ MissedPropertyException, MultiplyDefinedException, IOException,
+ SQLException {
+ // Create a scenario for tests
+ HibernateTemplate ht = getHibernateTemplate();
+
+ Database.getInstance().reset();
+ _projectSettings.getAllSteps().clear(); // Clear config to be able to
+ // load it again
+ // Load workflow customization
+ try {
+ _projectSettings.configure("classpath:test/som.xml");
+ } catch (FileNotFoundException e) {
+ Assert.fail("Can't find som.xml: ", e);
+ }
+ List<Step> steps = _stepsConfigService.getStepsOf(Scenario.class);
+ Assert.assertTrue(steps.size() > 0, "No steps are created.");
+
+ // Create a test user
+ User.Properties uprop = new User.Properties();
+ uprop.setUsername("TST_Username").setName("TST_SimanUnitTestsUser")
+ .setFirstName("TST_FirstName").setDisplayName("TST_test.user")
+ .addRole("TST_user")
+ .setMailAddress("noreply@salome-platform.org");
+ uprop.disableCheck();
+ User anAuthor = new User(uprop);
+ ht.saveOrUpdate(anAuthor);
+
+ // Create a test study
+ Study.Properties stprops = new Study.Properties()
+ .setReference("TST_SID_01").setTitle("TST_Study")
+ .setManager(anAuthor);
+ Study aStudy = new Study(stprops);
+ ht.saveOrUpdate(aStudy);
+
+ // Create a test scenario
+ Scenario.Properties sprops = new Scenario.Properties()
+ .setTitle("TST_Scenario").setManager(anAuthor)
+ .setOwnerStudy(aStudy);
+ Scenario aScenario = new Scenario(sprops);
+ aStudy.getScenariiList().add(aScenario);
+ ht.saveOrUpdate(anAuthor);
+ ht.saveOrUpdate(aStudy);
+ ht.saveOrUpdate(aScenario);
+
+ // Create documents for each scenario step
+ Document.Properties dprop = new Document.Properties().setAuthor(
+ anAuthor).setDate(new Date());
+ int i = 0;
+ Publication usedPub = null;
+ Map<Long, Long> usedMap = new HashMap<Long, Long>();
+ for (Step step : steps) {
+ LOG.debug("Create scenario step: " + i);
+
+ org.splat.som.Step aScStep = new org.splat.som.Step(step, aScenario);
+ List<DocumentType> dtypes = _documentTypeService
+ .selectTypesOf(step);
+ for (DocumentType dtype : dtypes) {
+ // Create a document published in the scenario
+ // document<i>: document type[0] - first type used on the step
+ // <source-file>.brep
+ // <attached-file>.med
+ dprop.setName("document" + i++).setType(dtype);
+ /*
+ * if (step.getNumber() > 3) { dprop.setFormat("med"); } else {
+ */dprop.setFormat("py");
+ // }
+ dprop.setLocalPath(dprop.getName() + "." + dprop.getFormat());
+ Publication pub = createDoc(aScenario, aScStep, dprop, "med",
+ false);
+ if (usedPub != null) {
+ pub.addDependency(usedPub);
+ ht.saveOrUpdate(pub.value());
+
+ usedMap.put(pub.getIndex(), usedPub.getIndex());
+ }
+ usedPub = pub;
+
+ // Create another document with outdated publication
+ dprop.setName("document" + i++).setType(dtype).setFormat("py");
+ dprop.setLocalPath(dprop.getName() + "." + dprop.getFormat());
+ createDoc(aScenario, aScStep, dprop, "med", true);
+
+ }
+ if (dtypes.size() <= 0) {
+ LOG.debug("No document types are found for scenario step " + i);
+ }
+ }
+
+ // Check that the scenario and its documents have been created
+ // correctly.
+
+ Assert.assertNotNull(ht.find("from Document"),
+ "No documents in the database.");
+ Assert.assertTrue(ht.find("from Document").size() > 0,
+ "No documents in the database.");
+
+ Assert.assertNotNull(
+ ht.find("from Publication where owner=" + aScenario.getIndex()),
+ "No publications in the database.");
+ Assert.assertTrue(
+ ht.find("from Publication where owner=" + aScenario.getIndex())
+ .size() > 0, "No publications in the database.");
+
+ for (Publication p : (List<Publication>) ht
+ .find("from Publication where owner=" + aScenario.getIndex())) {
+ LOG.debug("Publication found: [id=" + p.getIndex() + ", owner="
+ + p.getOwner().getIndex() + ", doc=" + p.value().getIndex()
+ + "]");
+ Assert.assertEquals(p.getOwner().getIndex(), aScenario.getIndex(),
+ "The publication was not attached to the scenario.");
+ }
+
+ // Remove the scenario from the current hibernate session.
+ ht.evict(aScenario);
+ // Check that the scenario is created in the database.
+ Scenario aScen = ht.load(Scenario.class, aScenario.getIndex());
+ Assert.assertNotNull(aScen, "Scenario was not saved in the database.");
+ Assert.assertTrue(aScen.getDocums().size() > 0,
+ "No publications in the scenario.");
+
+ Assert.assertTrue(i > 0,
+ "More then one document must be in the database");
+
+ // Check created uses relations
+ Assert.assertTrue(usedMap.size() > 0, "Uses relations must be created.");
+ boolean foundAny = false;
+ for (Long usingId : usedMap.keySet()) {
+ for (Publication pub : aScen.getDocums()) {
+ if (pub.getIndex() == usingId) {
+ boolean found = false;
+ for (Publication used : aScen.getDocums()) {
+ found = (used.getIndex() == usedMap.get(usingId));
+ if (found) {
+ break;
+ }
+ }
+ Assert.assertTrue(found,
+ "Uses relation was not created in the database.");
+ foundAny = foundAny || found;
+ }
+ }
+ }
+ Assert.assertTrue(foundAny,
+ "No Uses relation was created in the database.");
+
+ return aScenario.getIndex();
+ }
+
+ /**
+ * Create a document published in the scenario. <BR>
+ * document:<BR>
+ * document type[0] - first type used on the step <BR>
+ * <source-file>.brep <BR>
+ * <attached-file>.med
+ *
+ * @param aScenario
+ * v
+ * @param aScStep
+ * scenario step where the document to be published
+ * @param dprop
+ * document properties
+ * @param attachedFileExt
+ * extension of the secon attached (exported) file
+ * @param isOutdated
+ * outdated document flag
+ * @return the publication of the created document
+ * @throws IOException
+ * @throws MultiplyDefinedException
+ * @throws InvalidPropertyException
+ * @throws MissedPropertyException
+ */
+ private Publication createDoc(final Scenario aScenario,
+ final org.splat.som.Step aScStep, final Properties dprop,
+ final String attachedFileExt, final boolean isOutdated)
+ throws MissedPropertyException, InvalidPropertyException,
+ MultiplyDefinedException, IOException {
+ // Create a document published in the scenario
+ // document<i>: document type[0] - first type used on the step
+ // <source-file>.brep
+ // <attached-file>.med
+ createDownloadedFile(aScenario.getAuthor().getIndex(),
+ dprop.getLocalPath());
+ Publication pub = _stepService.createDocument(aScStep, dprop);
+ Assert.assertNotNull(pub.getOwner(),
+ "The publication must be attached to the scenario.");
+ Assert.assertEquals(pub.getOwner().getIndex(), aScenario.getIndex(),
+ "The publication was not attached to the scenario.");
+
+ if (isOutdated) {
+ pub.setIsnew('O');
+ }
+ aScenario.add(pub);
+ HibernateTemplate ht = getHibernateTemplate();
+ ht.saveOrUpdate(pub);
+
+ // Attach a file
+ createDownloadedFile(
+ aScenario.getAuthor().getIndex(),
+ dprop.getLocalPath().substring(0,
+ dprop.getLocalPath().lastIndexOf(".") - 1),
+ attachedFileExt);
+ ht.save(pub.value());
+ ht.saveOrUpdate(_publicationService.attach(pub, attachedFileExt));
+
+ return pub;
+ }
+
+ /**
+ * Test study creation.<BR>
+ * <B>Description :</B> <BR>
+ * <i>Create a study.</i><BR>
+ * <B>Action : </B><BR>
+ * <i>1. call the method for a not existing product.</i><BR>
+ * <i>2. call the method for an existing username and an existing
+ * product.</i><BR>
+ * <i>3. call the method for a not existing username expecting an
+ * exception.</i><BR>
+ * <B>Test data : </B><BR>
+ * <i>no input parameters</i><BR>
+ *
+ * <B>Outcome results:</B><BR>
+ * <i>
+ * <ul>
+ * <li>1: The new study must be created. The new product simulation context
+ * must be created.</li>
+ * <li>2: The new study must be created.</li>
+ * <li>3: The new study must not be created. Exception must be thrown.</li>
+ * </ul>
+ * </i>
+ *
+ * @throws IOException
+ * if application configuration loading is failed
+ * @throws SQLException
+ * if application configuration loading is failed
+ * @throws BusinessException
+ * if test data creation is failed
+ */
+ @Test(groups = { "study", "sevice", "functional", "business" })
+ public void testCreateStudy() throws BusinessException, IOException,
+ SQLException {
+ LOG.debug(">>>>> BEGIN testCreateStudy()");
+ startNestedTransaction();
+
+ Database.getInstance().reset();
+ _projectSettings.getAllSteps().clear(); // Clear config to be able to
+ // load it again
+ _projectSettings.configure("classpath:test/som.xml");
+
+ // Create a test user
+ User.Properties uprop = new User.Properties();
+ uprop.setUsername("TST_Username").setName("TST_SimanUnitTestsUser")
+ .setFirstName("TST_FirstName").setDisplayName("TST_test.user")
+ .addRole("TST_user")
+ .setMailAddress("noreply@salome-platform.org");
+ uprop.disableCheck();
+ User anAuthor = new User(uprop);
+
+ getHibernateTemplate().saveOrUpdate(anAuthor);
+ KnowledgeElementType ucase = _knowledgeElementTypeService
+ .selectType("usecase");
+ Assert.assertNotNull(ucase,
+ "Knowledge type 'usecase' must be created in the database.");
+ SimulationContextType prodtype = _simulationContextService
+ .selectType("product");
+ Assert.assertNotNull(prodtype,
+ "Simulation context type 'product' must be created in the database.");
+
+ // Create admin
+ uprop.clear();
+ uprop.setUsername("TST_Admin").setName("TST_SimanUnitTestsAdmin")
+ .setFirstName("TST_AdminFirstName")
+ .setDisplayName("TST_test.admin").addRole("TST_user,sysadmin")
+ .setMailAddress("noreply@salome-platform.org");
+ uprop.disableCheck();
+
+ getHibernateTemplate().saveOrUpdate(new User(uprop));
+ getHibernateTemplate().flush();
+
+ Study.Properties sprop = new Study.Properties();
+ sprop.setTitle("Test study creation").setManager(anAuthor);
+ Scenario.Properties oprop = new Scenario.Properties();
+ oprop.setTitle("Test scenario for the created study");
+
+ // Addition of the entered project context
+ SimulationContext.Properties cprop = new SimulationContext.Properties();
+ // Input of new project context
+ cprop.setType(_simulationContextService.selectType("product"))
+ .setValue("Test Simulation Context: Product");
+ Study study = _scenarioService.createStudy(sprop, oprop, cprop);
+
+ Assert.assertNotNull(study);
+ Assert.assertTrue(study.getIndex() > 0);
+
+ rollbackNestedTransaction();
+ LOG.debug(">>>>> END testCreateStudy()");
+ }
+
+ /**
+ * Test study creation.<BR>
+ * <B>Description :</B> <BR>
+ * <i>Create a study.</i><BR>
+ * <B>Action : </B><BR>
+ * <i>1. call the method for a not existing product.</i><BR>
+ * <i>2. call the method for an existing username and an existing
+ * product.</i><BR>
+ * <i>3. call the method for a not existing username expecting an
+ * exception.</i><BR>
+ * <B>Test data : </B><BR>
+ * <i>no input parameters</i><BR>
+ *
+ * <B>Outcome results:</B><BR>
+ * <i>
+ * <ul>
+ * <li>1: The new study must be created. The new product simulation context
+ * must be created.</li>
+ * <li>2: The new study must be created.</li>
+ * <li>3: The new study must not be created. Exception must be thrown.</li>
+ * </ul>
+ * </i>
+ *
+ * @throws IOException
+ * if application configuration loading is failed
+ * @throws SQLException
+ * if application configuration loading is failed
+ * @throws BusinessException
+ * if test data creation is failed
+ */
+ @Test(groups = { "study", "sevice", "functional", "business" })
+ public void testCreateStudyFromPython() throws IOException, SQLException,
+ BusinessException {
+ LOG.debug(">>>>> BEGIN testCreateStudyFromPython()");
+ startNestedTransaction();
+
+ HibernateTemplate ht = getHibernateTemplate();
+
+ Database.getInstance().reset();
+ _projectSettings.getAllSteps().clear(); // Clear config to be able to
+ // load it again
+ _projectSettings.configure("classpath:test/som.xml");
+
+ // Create a test user
+ User goodUser = TestEntitiesGenerator.getTestUser("goodUser");
+ _userDAO.create(goodUser);
+ SimulationContextType prodtype = _simulationContextService
+ .selectType("product");
+ Assert.assertNotNull(prodtype,
+ "Simulation context type 'product' must be created in the database.");
+
+ String productName = "New Test Product " + new Date().toString();
+
+ ht.flush();
+ ht.clear();
+ long studyId1 = _scenarioService.createStudy("goodUser",
+ "Test Study 1", productName, "Test description");
+ Assert.assertTrue(studyId1 > 0);
+
+ ht.flush();
+ ht.clear();
+ try {
+ _scenarioService.createStudy("badbadUser", "Test Study 2",
+ productName, "Test description");
+ Assert.fail("Study must not be created for not existing user.");
+ } catch (InvalidPropertyException ipe) {
+ LOG.debug("Expected exception: " + ipe.getMessage());
+ }
+
+ ht.flush();
+ ht.clear();
+ long studyId3 = _scenarioService.createStudy("goodUser",
+ "Test Study 3", productName, "Test description");
+ Assert.assertTrue(studyId3 > 0);
+
+ // Check that the simulation context is the same
+ Study study1 = _studyService.selectStudy(studyId1);
+ Study study3 = _studyService.selectStudy(studyId3);
+ Assert.assertEquals(study1.SimulationContextIterator().next(), study3
+ .SimulationContextIterator().next());
+
+ // Check the title of the created scenario
+ String scTitle = study1.getScenarii()[0].getTitle();
+ Assert.assertEquals(scTitle,
+ I18nUtils.getMessageLocaleDefault("label.scenario") + " 1");
+ Assert.assertFalse(scTitle.equals("label.scenario 1"));
+
+ rollbackNestedTransaction();
+ LOG.debug(">>>>> END testCreateStudyFromPython()");
+ }
+
+ /**
+ * Test study content copy.<BR>
+ * <B>Description :</B> <BR>
+ * <i>Create a study.</i><BR>
+ * <B>Action : </B><BR>
+ * <i>1. call the method for a not existing source study.</i><BR>
+ * <i>2. call the method for a not existing source scenario with not
+ * evolving step.</i><BR>
+ * <i>3. call the method for a not existing source scenario with evolving
+ * step.</i><BR>
+ * <i>4. call the method for an existing source scenario with evolving
+ * step.</i><BR>
+ * <B>Test data : </B><BR>
+ * <i>no input parameters</i><BR>
+ *
+ * <B>Outcome results:</B><BR>
+ * <i>
+ * <ul>
+ * <li>1: Exception must be thrown.</li>
+ * <li>2: The study content must be copied.</li>
+ * <li>3: Exception must be thrown.</li>
+ * <li>4: The study content must be copied.</li>
+ * </ul>
+ * </i>
+ *
+ * @throws IOException
+ * if application configuration loading is failed
+ * @throws SQLException
+ * if application configuration loading is failed
+ * @throws BusinessException
+ * if test data creation is failed
+ */
+ @Test(groups = { "study", "sevice", "functional", "business" })
+ public void testCopyStudyContent() throws IOException, SQLException,
+ BusinessException {
+ LOG.debug(">>>>> BEGIN testCopyStudyContent()");
+ startNestedTransaction();
+
+ HibernateTemplate ht = getHibernateTemplate();
+
+ Database.getInstance().reset();
+ _projectSettings.getAllSteps().clear(); // Clear config to be able to
+ // load it again
+ _projectSettings.configure("classpath:test/som.xml");
+
+ User goodUser = TestEntitiesGenerator.getTestUser("GoodUser");
+ _userDAO.create(goodUser);
+ User otherUser = TestEntitiesGenerator.getTestUser("otherUser");
+ _userDAO.create(otherUser);
+
+ // Create private study
+ Study aStudy = TestEntitiesGenerator.getTestStudy(goodUser);
+ aStudy.setTitle("0.This is private study");
+ Long studyId = _studyDAO.create(aStudy);
+
+ // Add a scenario to the study
+ Scenario scen = TestEntitiesGenerator.getTestScenario(aStudy);
+ _scenarioDAO.create(scen);
+ ht.flush();
+ // Add a second scenario to the study
+ scen = TestEntitiesGenerator.getTestScenario(aStudy);
+ Long aScenId = _scenarioDAO.create(scen);
+ ht.flush();
+
+ // Add a validation cycle with otherUser as a reviewer
+ ValidationCycle.Properties vprop = new ValidationCycle.Properties();
+ DocumentType dtype = _documentTypeService.selectType("minutes");
+ vprop.setDocumentType(dtype);
+ vprop.setActor(ValidationStep.REVIEW, otherUser);
+ ValidationCycle cycle = new ValidationCycle(aStudy, vprop);
+ _validationCycleDAO.create(cycle);
+ ValidationCycleRelation link = cycle.getContext();
+ aStudy.addRelation(link);
+ ht.flush();
+
+ // Add documents to the first study activity
+ // Add a converts relations
+ Map<Integer, org.splat.som.Step> stSteps = _projectElementService
+ .getStepsMap(aStudy);
+ org.splat.som.Step aStep = stSteps.get(1);
+ Publication pub1 = addDoc(aStudy, aStep, "document1", dtype);
+ Publication pub2 = addDoc(aStudy, aStep, "document2", dtype);
+ Publication pub3 = addDoc(aStudy, aStep, "document3", dtype);
+ ht.flush();
+
+ LOG.debug("pub1 version doc: " + pub1.value().getTitle() + " ["
+ + pub1.value().getReference() + "]" + " ["
+ + pub1.value().getRid() + "]");
+ LOG.debug("pub2 version doc: " + pub2.value().getTitle() + " ["
+ + pub2.value().getReference() + "]" + " ["
+ + pub2.value().getRid() + "]");
+ LOG.debug("pub3 version doc: " + pub3.value().getTitle() + " ["
+ + pub3.value().getReference() + "]" + " ["
+ + pub3.value().getRid() + "]");
+
+ ht.update(aStudy);
+
+ ht.flush();
+ LOG.debug("Before versioning:");
+ for (Publication doc : _projectElementService.getFirstStep(aStudy)
+ .getAllDocuments()) {
+ LOG.debug("Study doc: " + doc.value().getTitle() + " ["
+ + doc.value().getReference() + "]" + " ["
+ + doc.value().getRid() + "]");
+ }
+ // Add a version relations
+ Publication pub31 = version(pub3);
+ ht.flush();
+ //
+ // LOG.debug("pub31 version doc: " + pub31.value().getTitle() + " ["
+ // + pub31.value().getReference() + "]" + " ["
+ // + pub31.value().getRid() + "]");
+ // ht.saveOrUpdate(aStudy);
+
+ // LOG.debug("After versioning:");
+ // for (Publication doc : aStudy.getDocums()) {
+ // LOG.debug("Study doc: " + doc.value().getTitle() + " ["
+ // + doc.value().getReference() + "]" + " ["
+ // + doc.value().getRid() + "]");
+ // }
+
+ // Add documents to the first scenario activity
+ Map<Integer, org.splat.som.Step> scSteps = _projectElementService
+ .getStepsMap(scen);
+ aStep = scSteps.get(2);
+ Publication spub1 = addDoc(scen, aStep, "sdocument1", dtype);
+ Publication spub2 = addDoc(scen, aStep, "sdocument2", dtype);
+ Publication spub3 = addDoc(scen, aStep, "sdocument3", dtype);
+ LOG.debug("spub1 version doc: " + spub1.value().getTitle() + " ["
+ + spub1.value().getReference() + "]" + " ["
+ + spub1.value().getRid() + "]");
+ LOG.debug("spub2 version doc: " + spub2.value().getTitle() + " ["
+ + spub2.value().getReference() + "]" + " ["
+ + spub2.value().getRid() + "]");
+ LOG.debug("spub3 version doc: " + spub3.value().getTitle() + " ["
+ + spub3.value().getReference() + "]" + " ["
+ + spub3.value().getRid() + "]");
+ ht.flush();
+
+ // Create a scenario document version
+ Publication spub31 = version(spub3);
+ // LOG.debug("spub31 version doc: " + spub31.value().getTitle() + " ["
+ // + spub31.value().getReference() + "]" + " ["
+ // + spub31.value().getRid() + "]");
+ ht.flush();
+
+ // Add uses relations
+ pub2.addDependency(pub1);
+ ht.saveOrUpdate(pub2.value());
+ pub3.addDependency(pub2);
+ ht.saveOrUpdate(pub3.value());
+
+ spub2.addDependency(pub1);
+ spub2.addDependency(spub1);
+ spub2.addDependency(pub2);
+ spub2.addDependency(pub3);
+ ht.saveOrUpdate(spub2.value());
+ spub3.addDependency(spub2);
+ ht.saveOrUpdate(spub3.value());
+ spub31.addDependency(pub31);
+ ht.saveOrUpdate(spub31.value());
+ ht.flush();
+
+ // Create target study1
+ Study aStudy1 = TestEntitiesGenerator.getTestStudy(goodUser);
+ aStudy1.setTitle("1.This is a target study1");
+ aStudy1.setReference("tst1");
+ Long studyId1 = _studyDAO.create(aStudy1);
+
+ // Add a scenario to the study
+ Scenario scen1 = TestEntitiesGenerator.getTestScenario(aStudy1);
+ _scenarioDAO.create(scen1);
+ ht.flush();
+
+ // Create target study2
+ Study aStudy2 = TestEntitiesGenerator.getTestStudy(goodUser);
+ aStudy2.setTitle("2.This is a target study2");
+ aStudy2.setReference("tst2");
+ Long studyId2 = _studyDAO.create(aStudy2);
+
+ // Add a scenario to the study
+ Scenario scen2 = TestEntitiesGenerator.getTestScenario(aStudy2);
+ _scenarioDAO.create(scen2);
+ ht.flush();
+ ht.clear();
+
+ // //////////////////// TEST CALL /////////////////////////////////////
+ // 1. call the method for a not existing source study.
+ try {
+ _scenarioService.copyStudyContent(-1, -1, -1, -1);
+ Assert.fail("Exception must be thrown for not existing study id.");
+ } catch (InvalidParameterException e) {
+ LOG.debug("Expected exception: " + e.getClass().getSimpleName()
+ + ": " + e.getMessage());
+ }
+
+ ht.flush();
+ ht.clear();
+
+ // 2. call the method for a not existing source scenario with not
+ // evolving step.
+ _scenarioService.copyStudyContent(studyId, -1, 1, studyId1);
+
+ ht.flush();
+ ht.clear();
+
+ aStudy = _studyService.selectStudy(studyId);
+ aStudy1 = _studyService.selectStudy(studyId1);
+ for (Publication pub : aStudy.getDocums()) {
+ // Find the same document in the created copy of the study
+ Publication found = null;
+ for (Publication newPub : aStudy1.getDocums()) {
+ if (pub.value().getTitle().equals(newPub.value().getTitle())
+ && pub.value().getType()
+ .equals(newPub.value().getType())) {
+ found = newPub;
+ break;
+ }
+ }
+ Assert.assertNotNull(found, "The document "
+ + pub.value().getTitle() + "is not copied");
+ // Check that all files are copied (source and attached)
+ }
+
+ // 3. call the method for a not existing source scenario with evolving
+ // step.
+ try {
+ _scenarioService.copyStudyContent(studyId, -1, 2, studyId2);
+ Assert.fail("Exception must be thrown for not existing scenario id and evolving step.");
+ } catch (InvalidParameterException e) {
+ LOG.debug("Expected exception: " + e.getClass().getSimpleName()
+ + ": " + e.getMessage());
+ }
+
+ ht.flush();
+ ht.clear();
+
+ // 4. call the method for an existing source scenario with evolving
+ // step.
+ _scenarioService.copyStudyContent(studyId, aScenId, 9, studyId2);
+ ht.flush();
+
+ rollbackNestedTransaction();
+ LOG.debug(">>>>> END testCopyStudyContent()");
+ }
+
+ /**
+ * Test assigning a simulation context to a study.<BR>
+ * <B>Description :</B> <BR>
+ * <i>Create a study and assign a simulation context to it.</i><BR>
+ * <B>Action : </B><BR>
+ * <i>1. call the method for not existing study id.</i><BR>
+ * <i>2. call the method for not existing context type and context
+ * value.</i><BR>
+ * <i>3. call the method for existing context type and context value.</i><BR>
+ * <i>4. call the method for existing context type and not existing context
+ * value.</i><BR>
+ * <i>5. call the method for empty context type.</i><BR>
+ * <i>6. call the method for empty context value.</i><BR>
+ * <B>Test data : </B><BR>
+ * <i>no input parameters</i><BR>
+ *
+ * <B>Outcome results:</B><BR>
+ * <i>
+ * <ul>
+ * <li>1: Exception must be thrown.</li>
+ * <li>2: The new context type and value must be created. The new context
+ * must be assigned to the study first step.</li>
+ * <li>3: The existing context must be assigned to the study first step.</li>
+ * <li>4: The new context value must be created. The new context must be
+ * assigned to the study first step.</li>
+ * <li>5: Exception must be thrown.</li>
+ * <li>6: Exception must be thrown.</li>
+ * </ul>
+ * </i>
+ *
+ * @throws IOException
+ * if application configuration loading is failed
+ * @throws SQLException
+ * if application configuration loading is failed
+ * @throws BusinessException
+ * if test data creation is failed
+ */
+ @Test(groups = { "study", "sevice", "functional", "business" })
+ public void testAssignStudyContextFromPython() throws IOException,
+ SQLException, BusinessException {
+ LOG.debug(">>>>> BEGIN testAssignStudyContextFromPython()");
+ startNestedTransaction();
+
+ HibernateTemplate ht = getHibernateTemplate();
+
+ Database.getInstance().reset();
+ _projectSettings.getAllSteps().clear(); // Clear config to be able to
+ // load it again
+ _projectSettings.configure("classpath:test/som.xml");
+
+ // Create a test user
+ User goodUser = TestEntitiesGenerator.getTestUser("goodUser");
+ _userDAO.create(goodUser);
+ SimulationContextType prodtype = _simulationContextService
+ .selectType("product");
+ Assert.assertNotNull(prodtype,
+ "Simulation context type 'product' must be created in the database.");
+
+ String productName = "New Test Product " + new Date().toString();
+
+ ht.flush();
+ ht.clear();
+ long studyId1 = _scenarioService.createStudy("goodUser",
+ "Test Study 1", productName, "Test description");
+ Assert.assertTrue(studyId1 > 0);
+
+ ht.flush();
+ ht.clear();
+
+ // //////// START OF TESTS
+ // 1. call the method for not existing study id.</i><BR>
+ try {
+ _scenarioService.assignStudyContext(-1L, "new context type",
+ "new context value");
+ Assert.fail("Not existing study must not be found.");
+ } catch (InvalidPropertyException ipe) {
+ LOG.debug("Expected exception: " + ipe.getMessage());
+ }
+
+ // 2. call the method for not existing context type and context
+ // value.</i><BR>
+ _scenarioService.assignStudyContext(studyId1, "new context type",
+ "new context value");
+
+ ht.flush();
+ ht.clear();
+
+ // Check the assigned simulation context
+ checkCtx(studyId1, "new context type", "new context value");
+
+ // 3. call the method for existing context type and context
+ // value.</i><BR>
+ _scenarioService.assignStudyContext(studyId1, "new context type",
+ "new context value");
+
+ ht.flush();
+ ht.clear();
+
+ // Check the assigned simulation context
+ checkCtx(studyId1, "new context type", "new context value");
+
+ // 4. call the method for existing context type and not existing context
+ // value.</i><BR>
+ _scenarioService.assignStudyContext(studyId1, "new context type",
+ "new context value1");
+
+ ht.flush();
+ ht.clear();
+
+ // Check the assigned simulation context
+ checkCtx(studyId1, "new context type", "new context value1");
+
+ // 5. call the method for empty context type.</i><BR>
+ try {
+ _scenarioService.assignStudyContext(studyId1, "",
+ "new context value");
+ Assert.fail("Empty context type name must be forbidden.");
+ } catch (InvalidPropertyException ipe) {
+ LOG.debug("Expected exception: " + ipe.getMessage());
+ }
+ // 6. call the method for empty context value.</i><BR>
+ try {
+ _scenarioService.assignStudyContext(studyId1, "new context type",
+ "");
+ Assert.fail("Empty context value must be forbidden.");
+ } catch (InvalidPropertyException ipe) {
+ LOG.debug("Expected exception: " + ipe.getMessage());
+ }
+
+ rollbackNestedTransaction();
+ LOG.debug(">>>>> END testAssignStudyContextFromPython()");
+ }
+
+ /**
+ * Test getting a study scenarios DTO list.<BR>
+ * <B>Description :</B> <BR>
+ * <i>Create a study and get its scenarios DTO list.</i><BR>
+ * <B>Action : </B><BR>
+ * <i>1. call the method for not existing study id.</i><BR>
+ * <i>2. call the method for a study with one scenario.</i><BR>
+ * <i>3. call the method for a study with several scenarios.</i><BR>
+ * <B>Test data : </B><BR>
+ * <i>no input parameters</i><BR>
+ *
+ * <B>Outcome results:</B><BR>
+ * <i>
+ * <ul>
+ * <li>1: The returned list of DTO must be empty.</li>
+ * <li>2: The returned list of DTO must contain one scenario DTO.</li>
+ * <li>3: The returned list of DTO must contain several scenario DTOs.</li>
+ * </ul>
+ * </i>
+ *
+ * @throws IOException
+ * if application configuration loading is failed
+ * @throws SQLException
+ * if application configuration loading is failed
+ * @throws BusinessException
+ * if test data creation is failed
+ */
+ @Test(groups = { "study", "sevice", "functional", "business" })
+ public void testGetStudyScenarios() throws IOException, SQLException,
+ BusinessException {
+ LOG.debug(">>>>> BEGIN testGetStudyScenarios()");
+ startNestedTransaction();
+
+ HibernateTemplate ht = getHibernateTemplate();
+
+ Database.getInstance().reset();
+ _projectSettings.getAllSteps().clear(); // Clear config to be able to
+ // load it again
+ _projectSettings.configure("classpath:test/som.xml");
+
+ // Create a test user
+ User goodUser = TestEntitiesGenerator.getTestUser("goodUser");
+ _userDAO.create(goodUser);
+ Study study = TestEntitiesGenerator.getTestStudy(goodUser);
+ long studyId1 = _studyDAO.create(study);
+ ht.flush();
+ Scenario scen = TestEntitiesGenerator.getTestScenario(study,
+ "test scen11");
+ long id11 = _scenarioDAO.create(scen);
+ ht.flush();
+ study = TestEntitiesGenerator.getTestStudy(goodUser);
+ long studyId2 = _studyDAO.create(study);
+ ht.flush();
+ scen = TestEntitiesGenerator.getTestScenario(study, "test scen21");
+ long id21 = _scenarioDAO.create(scen);
+ ht.flush();
+ scen = TestEntitiesGenerator.getTestScenario(study, "test scen22");
+ long id22 = _scenarioDAO.create(scen);
+ ht.flush();
+ scen = TestEntitiesGenerator.getTestScenario(study, "test scen23");
+ long id23 = _scenarioDAO.create(scen);
+ ht.flush();
+ ht.clear();
+
+ // //////// START OF TESTS
+ // 1. call the method for not existing study id.
+ List<ScenarioDTO> scens = _scenarioService.getStudyScenarios(-1L);
+
+ Assert.assertNotNull(scens);
+ Assert.assertTrue(scens.isEmpty());
+
+ // 2. call the method for a study with one scenario.
+ scens = _scenarioService.getStudyScenarios(studyId1);
+
+ ht.flush();
+ ht.clear();
+ Assert.assertNotNull(scens);
+ Assert.assertEquals(scens.size(), 1);
+ Assert.assertEquals(scens.get(0).getIndex().longValue(), id11);
+ Assert.assertEquals(scens.get(0).getTitle(), "test scen11");
+
+ // 3. call the method for a study with several scenarios.
+ scens = _scenarioService.getStudyScenarios(studyId2);
+ Assert.assertEquals(scens.size(), 3);
+ Assert.assertEquals(scens.get(0).getIndex().longValue(), id21);
+ Assert.assertEquals(scens.get(0).getTitle(), "test scen21");
+ Assert.assertEquals(scens.get(1).getIndex().longValue(), id22);
+ Assert.assertEquals(scens.get(1).getTitle(), "test scen22");
+ Assert.assertEquals(scens.get(2).getIndex().longValue(), id23);
+ Assert.assertEquals(scens.get(2).getTitle(), "test scen23");
+
+ ht.flush();
+ ht.clear();
+
+ rollbackNestedTransaction();
+ LOG.debug(">>>>> END testGetStudyScenarios()");
+ }
+
+ /**
+ * Check if the context is assigned to the study.
+ *
+ * @param studyId1
+ * the study id
+ * @param ctxType
+ * the context type name
+ * @param ctxValue
+ * the context value
+ */
+ private void checkCtx(final long studyId1, final String ctxType,
+ final String ctxValue) {
+ // Check the assigned simulation context
+ Study study1 = _studyService.selectStudy(studyId1);
+ Iterator<SimulationContext> it = study1.SimulationContextIterator();
+ SimulationContext ctx;
+ boolean isFound = false;
+ while ((!isFound) && it.hasNext()) {
+ ctx = it.next();
+ isFound = ctx.getType().getName().equals(ctxType)
+ && ctx.getValue().equals(ctxValue);
+ }
+ Assert.assertTrue(isFound, "Context must be assigned to the study.");
+ }
}