X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=Workspace%2FSiman-Common%2Fsrc%2Forg%2Fsplat%2Fservice%2FStudyServiceImpl.java;h=86863e9829f107c5e9f56ea976c906ceb4ff4cac;hb=eb90d68aafe1fbc1307dd1121500a97ffd940d21;hp=14145e9ae96b3772110318dd20d277d534cefbc6;hpb=f114fa58fe391ec054072b249d1d629bbb27b786;p=tools%2Fsiman.git diff --git a/Workspace/Siman-Common/src/org/splat/service/StudyServiceImpl.java b/Workspace/Siman-Common/src/org/splat/service/StudyServiceImpl.java index 14145e9..86863e9 100644 --- a/Workspace/Siman-Common/src/org/splat/service/StudyServiceImpl.java +++ b/Workspace/Siman-Common/src/org/splat/service/StudyServiceImpl.java @@ -33,6 +33,7 @@ import org.apache.lucene.store.FSDirectory; import org.hibernate.Criteria; import org.hibernate.Hibernate; import org.hibernate.criterion.DetachedCriteria; +import org.hibernate.criterion.Order; import org.hibernate.criterion.Restrictions; import org.hibernate.proxy.HibernateProxy; import org.jfree.chart.ChartFactory; @@ -48,26 +49,30 @@ import org.splat.dal.bo.som.ContributorRelation; import org.splat.dal.bo.som.DescriptionAttribute; import org.splat.dal.bo.som.DocumentType; import org.splat.dal.bo.som.IDBuilder; +import org.splat.dal.bo.som.KnowledgeElement; import org.splat.dal.bo.som.ProgressState; import org.splat.dal.bo.som.ProjectElement; import org.splat.dal.bo.som.Publication; +import org.splat.dal.bo.som.ReaderRelation; import org.splat.dal.bo.som.Scenario; import org.splat.dal.bo.som.SimulationContext; import org.splat.dal.bo.som.Study; -import org.splat.dal.bo.som.Study.Properties; import org.splat.dal.bo.som.ValidationCycle; -import org.splat.dal.bo.som.ValidationCycle.Actor; import org.splat.dal.bo.som.ValidationCycleRelation; import org.splat.dal.bo.som.ValidationStep; import org.splat.dal.bo.som.Visibility; +import org.splat.dal.bo.som.Study.Properties; +import org.splat.dal.bo.som.ValidationCycle.Actor; import org.splat.dal.dao.som.DescriptionAttributeDAO; import org.splat.dal.dao.som.DocumentDAO; +import org.splat.dal.dao.som.DocumentTypeDAO; import org.splat.dal.dao.som.IDBuilderDAO; import org.splat.dal.dao.som.PublicationDAO; import org.splat.dal.dao.som.ScenarioDAO; import org.splat.dal.dao.som.StudyDAO; import org.splat.dal.dao.som.UsedByRelationDAO; import org.splat.dal.dao.som.ValidationCycleDAO; +import org.splat.exception.BusinessException; import org.splat.exception.IncompatibleDataException; import org.splat.exception.InvalidParameterException; import org.splat.kernel.InvalidPropertyException; @@ -78,12 +83,14 @@ import org.splat.log.AppLogger; import org.splat.service.dto.DocToCompareDTO; import org.splat.service.dto.DocumentDTO; import org.splat.service.dto.StudyFacadeDTO; +import org.splat.service.dto.UserDTO; import org.splat.service.technical.IndexService; import org.splat.service.technical.ProjectSettingsService; -import org.splat.service.technical.ProjectSettingsService.Step; import org.splat.service.technical.ProjectSettingsServiceImpl; import org.splat.service.technical.RepositoryService; +import org.splat.service.technical.ProjectSettingsService.Step; import org.splat.som.Revision; +import org.splat.util.BeanHelper; import org.springframework.transaction.annotation.Transactional; import com.lowagie.text.Document; @@ -186,6 +193,10 @@ public class StudyServiceImpl implements StudyService { * Injected description attribute DAO. */ private DescriptionAttributeDAO _descriptionAttributeDAO; + /** + * Injected document type DAO. + */ + private DocumentTypeDAO _documentTypeDAO; /** * {@inheritDoc} @@ -195,7 +206,9 @@ public class StudyServiceImpl implements StudyService { @Transactional public Study selectStudy(final long index) { Study result = getStudyDAO().get(index); - loadWorkflow(result); + if (result != null) { + loadWorkflow(result); + } return result; } @@ -240,14 +253,16 @@ public class StudyServiceImpl implements StudyService { // Remove all relations of study documents for (org.splat.dal.bo.som.Document doc : docums) { - LOG.debug("Found doc: " + doc.getTitle() + " [" + doc.getReference() + "]" + " [" + doc.getRid() + "]"); + LOG.debug("Found doc: " + doc.getTitle() + " [" + + doc.getReference() + "]" + " [" + doc.getRid() + "]"); doc.getAllRelations().clear(); } getDocumentDAO().flush(); // Remove all documents of the study for (org.splat.dal.bo.som.Document doc : docums) { - LOG.debug("Remove doc: " + doc.getTitle() + " [" + doc.getReference() + "]" + " [" + doc.getRid() + "]"); + LOG.debug("Remove doc: " + doc.getTitle() + " [" + + doc.getReference() + "]" + " [" + doc.getRid() + "]"); getDocumentDAO().delete(doc); } } @@ -330,13 +345,25 @@ public class StudyServiceImpl implements StudyService { */ @Transactional public boolean addContributor(final Study aStudy, final User user) { - List contributor = getModifiableContributors(aStudy); // Initializes contributor - for (Iterator i = contributor.iterator(); i.hasNext();) { - User present = i.next(); - if (present.equals(user)) { - return false; + List contributors = getModifiableContributors(aStudy); // Initializes contributor + + if (contributors.contains(user)) { + return false; + } + + // Remove user from readers + try { + List readers = getReaders(aStudy.getIndex()); + for (UserDTO reader : readers) { + if (reader.getIndex() == user.getIndex()) { + // user must be the actual user in the relationship object in the aStudy object for this to work + aStudy.removeRelation(ReaderRelation.class, user); + } } + } catch (InvalidParameterException e) { + LOG.error(e.getMessage(), e); } + boolean absent = getModifiableActors(aStudy).add(user); // User may already be a reviewer or an approver aStudy.addRelation(new ContributorRelation(aStudy, user)); @@ -346,37 +373,12 @@ public class StudyServiceImpl implements StudyService { return true; } - /** - * Moves this study from the Public to the Reference area of the repository. For being moved to the Reference area, the study must - * previously be approved. - * - * @param aStudy - * the study to move - * @return true if the move succeeded. - * @see #moveToPublic() - * @see #isPublic() - * @see Publication#approve(Date) - */ - public boolean moveToReference(final Study aStudy) { - if (aStudy.getProgressState() != ProgressState.APPROVED) { - return false; - } - if (aStudy.getVisibility() != Visibility.PUBLIC) { - return false; - } - - aStudy.setVisibility(Visibility.REFERENCE); - if (update(aStudy)) { - return updateKnowledgeElementsIndex(aStudy); // If fails, the database roll-back is under responsibility of the caller - } - return false; - } - /** * {@inheritDoc} * * @see org.splat.service.StudyService#update(org.splat.dal.bo.som.Study, org.splat.dal.bo.som.Study.Properties) */ + @Transactional public boolean update(final Study aStudy, final Properties sprop) throws InvalidPropertyException { if (sprop.getTitle() != null) { @@ -399,17 +401,9 @@ public class StudyServiceImpl implements StudyService { * the document * @return true if the document is published in the study */ -/* private boolean publishes(final Study aStudy, final Document doc) { - if (!aStudy.publishes(doc)) { - Scenario[] scene = aStudy.getScenarii(); - for (int i = 0; i < scene.length; i++) { - if (scene[i].publishes(doc)) { - return true; - } - } - } - return false; - } + /* + * private boolean publishes(final Study aStudy, final Document doc) { if (!aStudy.publishes(doc)) { Scenario[] scene = + * aStudy.getScenarii(); for (int i = 0; i < scene.length; i++) { if (scene[i].publishes(doc)) { return true; } } } return false; } */ /** * {@inheritDoc} @@ -418,20 +412,13 @@ public class StudyServiceImpl implements StudyService { */ @Transactional public boolean removeContributor(final Study aStudy, final User... users) { - List contributor = getModifiableContributors(aStudy); // Initializes contributor + List contributors = getModifiableContributors(aStudy); // Initializes contributor Boolean done = false; - for (int i = 0; i < users.length; i++) { - User user = users[i]; - for (Iterator j = contributor.iterator(); j.hasNext();) { - User present = j.next(); - if (!present.equals(user)) { - continue; - } - + for (User user : users) { + if (contributors.contains(user)) { aStudy.removeRelation(ContributorRelation.class, user); - j.remove(); // Updates the contributor shortcut + contributors.remove(user); done = true; - break; } } if (done) { @@ -445,6 +432,7 @@ public class StudyServiceImpl implements StudyService { * * @see org.splat.service.StudyService#removeProjectContext(org.splat.dal.bo.som.Study, org.splat.dal.bo.som.SimulationContext) */ + @Transactional public boolean removeProjectContext(final Study aStudy, final SimulationContext context) { boolean done = getStepService().removeSimulationContext( @@ -483,12 +471,12 @@ public class StudyServiceImpl implements StudyService { ValidationCycleRelation link = cycle.getContext(); aStudy.addRelation(link); + getValidationCycleDAO().flush(); aStudyDTO.getAllRelations().add(link); // RKV validactor.put(cname, link.getTo()); // Replaces the cycle if exists as default, - } catch (Exception error) { - LOG.error("Unable to re-index Knowledge Elements, reason:", - error); + } catch (BusinessException error) { + LOG.error("Unable to create validation cycle, reason:", error); return; } } @@ -496,25 +484,6 @@ public class StudyServiceImpl implements StudyService { update(aStudy); // Re-index the study, just in case } - /** - * Demotes this study from In-Check to In-Draft then In-Work states. This function is called internally when demoting the final result - * document of the study. - * - * @param aStudy - * a study to demote - * @return true if the demotion succeeded. - */ - public boolean demote(final Study aStudy) { - if (aStudy.getProgressState() == ProgressState.inCHECK) { - aStudy.setProgressState(ProgressState.inDRAFT); - } else if (aStudy.getProgressState() == ProgressState.inDRAFT) { - aStudy.setProgressState(ProgressState.inWORK); - } else { - return false; - } - return update(aStudy); - } - /** * {@inheritDoc} * @@ -527,31 +496,60 @@ public class StudyServiceImpl implements StudyService { } /** - * Promotes this study from In-Work to In-Draft then In-Check and APPROVED states. This function is called internally when promoting the - * final result document of the study. + * Promotes this study from In-Work to In-Draft then In-Check and APPROVED
+ * states. This function takes into account statuses of final result
+ * documents of the study. * * @param aStudy * a study to promote - * @return true if the demotion succeeded. + * @return true if the promotion succeeded. */ @Transactional public boolean promote(final Study aStudy) { - if (aStudy.getProgressState() == ProgressState.inWORK) { + boolean res = true; + if (aStudy.getProgressState() == ProgressState.inWORK + && canBePromoted(aStudy)) { aStudy.setProgressState(ProgressState.inDRAFT); - } else if (aStudy.getProgressState() == ProgressState.inDRAFT) { + } else if (aStudy.getProgressState() == ProgressState.inDRAFT + && canBeReviewed(aStudy)) { aStudy.setProgressState(ProgressState.inCHECK); Revision myvers = new Revision(aStudy.getVersion()); if (myvers.isMinor()) { aStudy.setVersion(myvers.incrementAs(aStudy.getProgressState()) .toString()); } - } else if (aStudy.getProgressState() == ProgressState.inCHECK) { + } else if (aStudy.getProgressState() == ProgressState.inCHECK + && canBeApproved(aStudy)) { aStudy.setProgressState(ProgressState.APPROVED); + updateKnowledgeElementsState(aStudy); } else { - return false; + res = false; + } + if (res) { + res = update(aStudy); } - return update(aStudy); + return res; + } + + /** + * Demotes this study from In-Check or In-Draft to In-Work states. + * + * @param aStudy + * a study to demote + * @return true if the demotion succeeded. + */ + @Transactional + public boolean demote(final Study aStudy) { + boolean res; + if (aStudy.getProgressState() == ProgressState.inCHECK + || aStudy.getProgressState() == ProgressState.inDRAFT) { + aStudy.setProgressState(ProgressState.inWORK); + res = update(aStudy); + } else { + res = false; + } + return res; } /** @@ -568,7 +566,7 @@ public class StudyServiceImpl implements StudyService { if (aStudy.getVisibility() == Visibility.PRIVATE) { aStudy.setVisibility(Visibility.PUBLIC); if (update(aStudy)) { - isOk = updateKnowledgeElementsIndex(aStudy); // If fails, the database roll-back is under responsibility of the caller + isOk = updateKnowledgeElementsState(aStudy); // If fails, the database roll-back is under responsibility of the caller } } return isOk; @@ -587,7 +585,7 @@ public class StudyServiceImpl implements StudyService { if (aStudy.getVisibility() == Visibility.PUBLIC) { aStudy.setVisibility(Visibility.PRIVATE); if (update(aStudy)) { - isOk = updateKnowledgeElementsIndex(aStudy); // If fails, the database roll-back is under responsibility of the caller + isOk = updateKnowledgeElementsState(aStudy); // If fails, the database roll-back is under responsibility of the caller } } return isOk; @@ -600,7 +598,6 @@ public class StudyServiceImpl implements StudyService { * the study to update * @return true if the study is updated successfully */ - @Transactional private boolean update(final Study aStudy) { boolean isOk = false; try { @@ -747,32 +744,18 @@ public class StudyServiceImpl implements StudyService { } /** - * Update lucene index for the study knowledge elements. + * Update knowledge elements states. * * @param aStudy * the study - * @return true if reindexing succeeded + * @return true if succeeded */ - private boolean updateKnowledgeElementsIndex(final Study aStudy) { - // boolean isOk = false; - // try { - // IndexService lucin = getIndex(); - // - // for (Iterator i = aStudy.getScenariiList().iterator(); i - // .hasNext();) { - // Scenario scene = i.next(); - // for (Iterator j = scene - // .getAllKnowledgeElements().iterator(); j.hasNext();) { - // KnowledgeElement kelm = j.next(); - // lucin.update(kelm); - // } - // } - // isOk = true; - // } catch (Exception error) { - // LOG.error("Unable to re-index Knowledge Elements, reason:", - // error); - // } - // return isOk; + private boolean updateKnowledgeElementsState(final Study aStudy) { + for (Scenario scenario : aStudy.getScenariiList()) { + for (KnowledgeElement element : scenario.getAllKnowledgeElements()) { + element.setProgressState(aStudy.getProgressState()); + } + } return true; } @@ -994,14 +977,18 @@ public class StudyServiceImpl implements StudyService { */ public ValidationCycle getValidationCycleOf(final Study aStudy, final DocumentType type) { - if (aStudy.getValidationCycles() == null - || aStudy.getValidationCycles().isEmpty()) { - setShortCuts(aStudy); + ValidationCycle result = null; + if (aStudy != null) { + if (aStudy.getValidationCycles() == null + || aStudy.getValidationCycles().isEmpty()) { + setShortCuts(aStudy); + } + if (type != null) { + result = aStudy.getValidationCycles().get(type.getName()); + } } - ValidationCycle result = aStudy.getValidationCycles().get( - type.getName()); - if (result == null) { - if (type.isStepResult()) { + if ((result == null) && (aStudy != null)) { + if ((type == null) || type.isStepResult()) { result = aStudy.getValidationCycles().get("default"); // "default" validation cycle defined in the configuration, if exist } if (result == null) { @@ -1138,13 +1125,16 @@ public class StudyServiceImpl implements StudyService { * * @see org.splat.service.StudyService#markStudyAsReference(org.splat.dal.bo.som.Study) */ - @Override @Transactional - public void markStudyAsReference(final Study aStudy) { - - aStudy.setMarkreference(1); - aStudy.setProgressState(ProgressState.TEMPLATE); - getStudyDAO().merge(aStudy); + public boolean markStudyAsReference(final Study aStudy) { + boolean res = false; + if (aStudy.getProgressState() == ProgressState.APPROVED) { + aStudy.setMarkreference(1); + aStudy.setProgressState(ProgressState.TEMPLATE); + res = updateKnowledgeElementsState(aStudy); + getStudyDAO().merge(aStudy); + } + return res; } /** @@ -1153,12 +1143,11 @@ public class StudyServiceImpl implements StudyService { * * @see org.splat.service.StudyService#removeStudyAsReference(org.splat.dal.bo.som.Study) */ - @Override @Transactional public void removeStudyAsReference(final Study aStudy) { - aStudy.setMarkreference(0); aStudy.setProgressState(ProgressState.APPROVED); + updateKnowledgeElementsState(aStudy); getStudyDAO().merge(aStudy); } @@ -1176,7 +1165,8 @@ public class StudyServiceImpl implements StudyService { } Study study = _studyDAO.get(studyId); if (study == null) { - throw new InvalidParameterException(PARAM_STUDY_ID, studyId.toString()); + throw new InvalidParameterException(PARAM_STUDY_ID, studyId + .toString()); } return study.getDescription(); } @@ -1186,7 +1176,6 @@ public class StudyServiceImpl implements StudyService { * * @see org.splat.service.StudyService#setDescription(java.lang.Long, java.lang.String) */ - @Override @Transactional public void setDescription(final Long studyId, final String descriptionText) throws InvalidParameterException { @@ -1195,7 +1184,8 @@ public class StudyServiceImpl implements StudyService { } Study study = _studyDAO.get(studyId); if (study == null) { - throw new InvalidParameterException(PARAM_STUDY_ID, studyId.toString()); + throw new InvalidParameterException(PARAM_STUDY_ID, studyId + .toString()); } study.setAttribute(new DescriptionAttribute(study, descriptionText)); } @@ -1205,7 +1195,6 @@ public class StudyServiceImpl implements StudyService { * * @see org.splat.service.StudyService#removeStudyDescription(java.lang.Long) */ - @Override @Transactional public boolean removeDescription(final Long studyId) throws InvalidParameterException { @@ -1251,17 +1240,19 @@ public class StudyServiceImpl implements StudyService { + "downloads" + File.separator + userName + File.separator + "ComparisonResult.pdf"; - XYSeries series = new XYSeries("Study: " + docDTO.getStudyTitle() + " Scenario: " + docDTO.getScenarioTitle() + " Document: " + docDTO.getDocumentTitle()); + XYSeries series = new XYSeries("Study: " + docDTO.getStudyTitle() + + " Scenario: " + docDTO.getScenarioTitle() + " Document: " + + docDTO.getDocumentTitle()); // read the file and get points information. try { Scanner input = new Scanner(compDocFile); - //get the title of the chart. + // get the title of the chart. if (input.hasNext()) { chartTitle = input.nextLine(); } - + // get the name of the axis. if (input.hasNext()) { String[] tokens = input.nextLine().split(","); @@ -1304,15 +1295,11 @@ public class StudyServiceImpl implements StudyService { dataset.addSeries(series); } catch (FileNotFoundException e) { - if (LOG.isDebugEnabled()) { - LOG.debug("Sorry, the file is not found."); - } - return "ERROR"; + LOG.error("Sorry, the file is not found.", e); } } // for - JFreeChart chart = ChartFactory.createXYLineChart( - chartTitle, // Title + JFreeChart chart = ChartFactory.createXYLineChart(chartTitle, // Title axis1Name, // x-axis Label axis2Name, // y-axis Label dataset, // Dataset @@ -1346,18 +1333,88 @@ public class StudyServiceImpl implements StudyService { document.close(); } catch (FileNotFoundException e) { - if (LOG.isDebugEnabled()) { - LOG.debug("Sorry, the file is not found."); - } + LOG.error("Sorry, the file is not found.", e); } catch (DocumentException e) { - if (LOG.isDebugEnabled()) { - LOG.debug("Sorry, the DocumentException is thrown."); - } + LOG.error("Sorry, the DocumentException is thrown.", e); } return resultPath; } + /** + * {@inheritDoc} + * + * @see org.splat.service.StudyService#getReaders(long) + */ + @Transactional(readOnly = true) + public List getReaders(final long studyId) + throws InvalidParameterException { + Study aStudy = selectStudy(studyId); + if (aStudy == null) { + throw new InvalidParameterException(PARAM_STUDY_ID, String + .valueOf(studyId)); + } + List relations = aStudy.getRelations(ReaderRelation.class); + List result = new ArrayList(); + for (Relation relation : relations) { + result.add(BeanHelper.copyBean(relation.getTo(), UserDTO.class)); + } + return Collections.unmodifiableList(result); + } + + /** + * {@inheritDoc} + * + * @see org.splat.service.StudyService#addReader(long, long) + */ + @Transactional + public boolean addReader(final long studyId, final long userId) + throws InvalidParameterException { + Study aStudy = selectStudy(studyId); + if (aStudy == null) { + throw new InvalidParameterException(PARAM_STUDY_ID, String + .valueOf(studyId)); + } + User user = _userService.selectUser(userId); + if (user == null) { + throw new InvalidParameterException("userId", String + .valueOf(userId)); + } + + for (Relation relation : aStudy.getRelations(ReaderRelation.class)) { + if (user.equals(relation.getTo())) { + return false; + } + } + aStudy.addRelation(new ReaderRelation(aStudy, user)); + update(aStudy); + return true; + } + + /** + * {@inheritDoc} + * + * @see org.splat.service.StudyService#removeReader(long, long) + */ + @Transactional + public boolean removeReader(final long studyId, final long userId) + throws InvalidParameterException { + Study aStudy = selectStudy(studyId); + if (aStudy == null) { + throw new InvalidParameterException(PARAM_STUDY_ID, String + .valueOf(studyId)); + } + User user = _userService.selectUser(userId); + if (user == null) { + throw new InvalidParameterException("userId", String + .valueOf(userId)); + } + + Relation relation = aStudy.removeRelation(ReaderRelation.class, user); + update(aStudy); + return relation != null; + } + /** * Get project settings. * @@ -1558,98 +1615,102 @@ public class StudyServiceImpl implements StudyService { * @see org.splat.service.StudyService#getComparableStudies() */ @Transactional(readOnly = true) - public List getComparableStudies(final long userId) throws MismatchException { - //retrieve the number of the "Analyze the results" step + public List getComparableStudies(final long userId) + throws MismatchException { + // retrieve the number of the "Analyze the results" step List allSteps = _projectSettings.getAllSteps(); Step theAnalyzeStep = null; - for(Step step : allSteps) { - if(step.getKey().equals("postprocessing")) { + for (Step step : allSteps) { + if (step.getKey().equals("postprocessing")) { theAnalyzeStep = step; } } - if(theAnalyzeStep == null) { //TODO: throw some other exception - throw new MismatchException("no step with key 'postprocessing' found." + - "Probably, customization settings have been changed."); + if (theAnalyzeStep == null) { // TODO: throw some other exception + throw new MismatchException( + "no step with key 'postprocessing' found." + + "Probably, customization settings have been changed."); } - List publications = _publicationDAO.getFilteredList("mydoc", - Restrictions.eq("step", Integer.valueOf(theAnalyzeStep.getNumber()))); + List publications = _publicationDAO.getFilteredList( + "mydoc", Restrictions.eq("step", Integer.valueOf(theAnalyzeStep + .getNumber()))); - //split retrieved publications into groups by studies and scenarios + // split retrieved publications into groups by studies and scenarios Map> studyMap = new HashMap>(); - Map> scenarioMap = - new HashMap>(); - - for(Publication publication : publications) { - //filter out publications corresponding to a document of given step which is not a _result_ document - if(!publication.value().getType().isResultOf(theAnalyzeStep) + Map> scenarioMap = new HashMap>(); + + for (Publication publication : publications) { + // filter out publications corresponding to a document of given step which is not a _result_ document + if (!publication.value().getType().isResultOf(theAnalyzeStep) || !"srd".equals(publication.getSourceFile().getFormat())) { continue; } - - //check the study visibility to the user - if(!isStaffedBy(publication.getOwnerStudy(), _userService.selectUser(userId)) - && Visibility.PUBLIC.equals(publication.getOwnerStudy().getVisibility())) { + + // check the study visibility to the user + if (!isStaffedBy(publication.getOwnerStudy(), _userService + .selectUser(userId)) + && Visibility.PUBLIC.equals(publication.getOwnerStudy() + .getVisibility())) { continue; } - + Study study = publication.getOwnerStudy(); ProjectElement scenario = publication.getOwner(); - + Hibernate.initialize(scenario); - if (scenario instanceof HibernateProxy) { - scenario = (ProjectElement) ((HibernateProxy) scenario).getHibernateLazyInitializer() - .getImplementation(); - } - - if(!(scenario instanceof Scenario)) { + if (scenario instanceof HibernateProxy) { + scenario = (ProjectElement) ((HibernateProxy) scenario) + .getHibernateLazyInitializer().getImplementation(); + } + + if (!(scenario instanceof Scenario)) { throw new MismatchException( "publications from postprocessing step are supposed to have owner scenario"); } - if(!studyMap.containsKey(study)) { + if (!studyMap.containsKey(study)) { studyMap.put(study, new ArrayList()); } - - if(!studyMap.get(study).contains(scenario)) { + + if (!studyMap.get(study).contains(scenario)) { studyMap.get(study).add(scenario); } - if(!scenarioMap.containsKey(scenario)) { + if (!scenarioMap.containsKey(scenario)) { scenarioMap.put(scenario, new ArrayList()); } scenarioMap.get(scenario).add(publication); } - - //Create the result DTOs + + // Create the result DTOs List result = new ArrayList(); - for(Study study : studyMap.keySet()) { - + for (Study study : studyMap.keySet()) { + StudyFacadeDTO studyDTO = new StudyFacadeDTO(); studyDTO.setName(study.getTitle()); studyDTO.setScenarios(new ArrayList()); result.add(studyDTO); - - for(ProjectElement scenario : studyMap.get(study)) { - + + for (ProjectElement scenario : studyMap.get(study)) { + StudyFacadeDTO.ScenarioDTO scenarioDTO = new StudyFacadeDTO.ScenarioDTO(); scenarioDTO.setName(scenario.getTitle()); scenarioDTO.setDocs(new ArrayList()); studyDTO.getScenarios().add(scenarioDTO); - for(Publication publication : scenarioMap.get(scenario)) { + for (Publication publication : scenarioMap.get(scenario)) { DocumentDTO documentDTO = new DocumentDTO(); documentDTO.setId(publication.getIndex()); documentDTO.setTitle(publication.value().getTitle()); - + scenarioDTO.getDocs().add(documentDTO); } } - } + } return result; } - + /** * Get the publicationDAO. * @@ -1746,4 +1807,91 @@ public class StudyServiceImpl implements StudyService { _usedByRelationDAO = usedByRelationDAO; } + /** + * {@inheritDoc} + * + * @see org.splat.service.StudyService#getStudyResultType(org.splat.dal.bo.som.Study) + */ + @Override + @Transactional(readOnly = true) + public DocumentType getStudyResultType(final Study study) { + DetachedCriteria query = DetachedCriteria.forClass(DocumentType.class) + .addOrder(Order.desc("result")); + return getDocumentTypeDAO().getFirstResult(query); + } + + /** + * Get the documentTypeDAO. + * + * @return the documentTypeDAO + */ + public DocumentTypeDAO getDocumentTypeDAO() { + return _documentTypeDAO; + } + + /** + * Set the documentTypeDAO. + * + * @param documentTypeDAO + * the documentTypeDAO to set + */ + public void setDocumentTypeDAO(final DocumentTypeDAO documentTypeDAO) { + _documentTypeDAO = documentTypeDAO; + } + + /** + * {@inheritDoc} + * + * @see org.splat.service.StudyService#canBeApproved(org.splat.dal.bo.som.Study) + */ + @Override + @Transactional(readOnly = true) + public boolean canBeApproved(final Study study) { + return resultDocsAtLeast(study, ProgressState.APPROVED); + } + + /** + * {@inheritDoc} + * + * @see org.splat.service.StudyService#canBePromoted(org.splat.dal.bo.som.Study) + */ + @Override + @Transactional(readOnly = true) + public boolean canBePromoted(final Study study) { + return resultDocsAtLeast(study, ProgressState.inDRAFT); + } + + /** + * {@inheritDoc} + * + * @see org.splat.service.StudyService#canBeReviewed(org.splat.dal.bo.som.Study) + */ + @Override + @Transactional(readOnly = true) + public boolean canBeReviewed(final Study study) { + return resultDocsAtLeast(study, ProgressState.inCHECK); + } + + /** + * Check that all result documents of the study are at least in the given state. + * + * @param study + * the study to check + * @param state + * the minimal acceptable state + * @return true if study result documents have acceptable states + */ + private boolean resultDocsAtLeast(final Study study, + final ProgressState state) { + boolean res = true; + // Check that all study result documents have the state APPROVED or more. + for (Publication pub : getProjectElementService().getLastStep(study) + .getResultDocuments()) { + res = pub.getProgressState().compareTo(ProgressState.APPROVED) >= 0; + if (!res) { + break; + } + } + return res; + } }