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=2e3fc4538e3f9af18d1473a7f3099a09c8ec20c1;hpb=d9ff6416d0b257189f05c7c2f1f7f3ad50b5544b;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 2e3fc45..86863e9 100644 --- a/Workspace/Siman-Common/src/org/splat/service/StudyServiceImpl.java +++ b/Workspace/Siman-Common/src/org/splat/service/StudyServiceImpl.java @@ -16,9 +16,12 @@ import java.io.FileOutputStream; import java.io.IOException; import java.text.DecimalFormat; import java.text.SimpleDateFormat; +import java.util.ArrayList; import java.util.Calendar; import java.util.Collections; import java.util.Date; +import java.util.HashMap; +import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; @@ -27,7 +30,12 @@ import java.util.Set; import org.apache.lucene.index.IndexWriter; 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; import org.jfree.chart.JFreeChart; import org.jfree.chart.plot.PlotOrientation; @@ -41,35 +49,48 @@ 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; +import org.splat.kernel.MismatchException; import org.splat.kernel.MissedPropertyException; import org.splat.kernel.MultiplyDefinedException; 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.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; @@ -80,7 +101,6 @@ import com.lowagie.text.pdf.PdfContentByte; import com.lowagie.text.pdf.PdfTemplate; import com.lowagie.text.pdf.PdfWriter; - /** * This class defines all methods for creation, modification the study. * @@ -94,6 +114,10 @@ public class StudyServiceImpl implements StudyService { */ public final static AppLogger LOG = AppLogger .getLogger(StudyServiceImpl.class); + /** + * "studyId" parameter name. + */ + public final static String PARAM_STUDY_ID = "studyId"; /** * Injected index service. @@ -120,6 +144,11 @@ public class StudyServiceImpl implements StudyService { */ private StudyDAO _studyDAO; + /** + * Injected usedBy relations DAO. + */ + private UsedByRelationDAO _usedByRelationDAO; + /** * Injected scenario DAO. */ @@ -144,7 +173,7 @@ public class StudyServiceImpl implements StudyService { * Injected user service. */ private UserService _userService; - + /** * Injected publication DAO. */ @@ -164,6 +193,10 @@ public class StudyServiceImpl implements StudyService { * Injected description attribute DAO. */ private DescriptionAttributeDAO _descriptionAttributeDAO; + /** + * Injected document type DAO. + */ + private DocumentTypeDAO _documentTypeDAO; /** * {@inheritDoc} @@ -173,19 +206,65 @@ 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; } - /** + /** * {@inheritDoc} + * * @see org.splat.service.StudyService#removeStudy(long) */ @Transactional - public void removeStudy(final long index) { + public void removeStudy(final Long index) { Study study = getStudyDAO().get(index); + Set docums = new HashSet(); if (study != null) { + // Select all documents published in the study and study's scenarios. + DetachedCriteria query = DetachedCriteria.forClass( + Publication.class, "pub"); + query + .createCriteria("pub.owner", "projelem", + Criteria.INNER_JOIN) + .createAlias("projelem.owner", "study", Criteria.LEFT_JOIN) + .add( + Restrictions + .or(Restrictions.eq("projelem.rid", index), + Restrictions.eq("study.rid", index))) + .setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY); + + if (LOG.isDebugEnabled()) { + LOG.debug("Find study documents: " + query.toString()); + } + for (Publication pub : getPublicationDAO().getFilteredList(query)) { + docums.add(pub.value()); + // Find also all previous versions of the document + for (org.splat.dal.bo.som.Document prev = pub.value() + .getPreviousVersion(); prev != null; prev = prev + .getPreviousVersion()) { + docums.add(prev); + } + } + + // Delete the study with its relations, scenarios and publications getStudyDAO().delete(study); + + // 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() + "]"); + 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() + "]"); + getDocumentDAO().delete(doc); + } } } @@ -218,14 +297,14 @@ public class StudyServiceImpl implements StudyService { buildReference(study); getStudyDAO().create(study); -// try { -// IndexService lucin = getIndex(); -// lucin.add(study); -// } catch (IOException error) { -// LOG.error("Unable to index the study '" + study.getIndex() -// + "', reason:", error); -// // Continue and try to index later -// } + // try { + // IndexService lucin = getIndex(); + // lucin.add(study); + // } catch (IOException error) { + // LOG.error("Unable to index the study '" + study.getIndex() + // + "', reason:", error); + // // Continue and try to index later + // } return study; } @@ -264,55 +343,42 @@ public class StudyServiceImpl implements StudyService { * * @see org.splat.service.StudyService#addContributor(org.splat.dal.bo.som.Study, org.splat.dal.bo.kernel.User) */ + @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)); if (absent) { update(aStudy); // Else, useless to re-index the study } - contributor.add(user); 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) { @@ -335,38 +401,24 @@ 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} * * @see org.splat.service.StudyService#removeContributor(org.splat.dal.bo.som.Study, org.splat.dal.bo.kernel.User[]) */ + @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) { @@ -380,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( @@ -395,15 +448,16 @@ public class StudyServiceImpl implements StudyService { * org.splat.dal.bo.som.ValidationCycle.Properties) */ @Transactional - public void setValidationCycle(final Study aStudyDTO, final DocumentType type, - final ValidationCycle.Properties vprop) { - Map validactor = aStudyDTO.getValidationCycles(); + public void setValidationCycle(final Study aStudyDTO, + final DocumentType type, final ValidationCycle.Properties vprop) { + Map validactor = aStudyDTO + .getValidationCycles(); if (validactor == null) { setShortCuts(aStudyDTO); // Initializes validactor and actor } Study aStudy = selectStudy(aStudyDTO.getIndex()); - + String cname = type.getName(); ValidationCycle cycle = validactor.get(cname); @@ -417,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; } } @@ -430,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} * @@ -461,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; } /** @@ -502,12 +566,12 @@ 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; } - + /** * Moves this study from the Public to the Private area of the repository. * @@ -521,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; @@ -534,13 +598,12 @@ 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 { getStudyDAO().merge(aStudy); // Update of relational base setShortCuts(aStudy); // RKV: initialize transient actors set - //RKV: getIndex().update(aStudy); // Update of Lucene index + // RKV: getIndex().update(aStudy); // Update of Lucene index isOk = true; } catch (Exception e) { LOG.error("STD-000001", e, aStudy.getIndex(), e.getMessage()); @@ -600,7 +663,7 @@ public class StudyServiceImpl implements StudyService { break; } } - SimpleDateFormat tostring = new SimpleDateFormat("yyyy"); //RKV: NOPMD: TODO: Use locale here? + SimpleDateFormat tostring = new SimpleDateFormat("yyyy"); // RKV: NOPMD: TODO: Use locale here? String year = tostring.format(study.getDate()); year = year.substring(4 - (i - n), 4); // 4-(i-n) must be equal to either 0 or 2 for (int j = 0; j < year.length(); j++) { @@ -681,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 - */ - 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; + * @return true if succeeded + */ + private boolean updateKnowledgeElementsState(final Study aStudy) { + for (Scenario scenario : aStudy.getScenariiList()) { + for (KnowledgeElement element : scenario.getAllKnowledgeElements()) { + element.setProgressState(aStudy.getProgressState()); + } + } return true; } @@ -928,13 +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) { @@ -1064,166 +1118,188 @@ public class StudyServiceImpl implements StudyService { aStudy.getActor().add(((ActorRelation) link).getTo()); } } - + /** * * {@inheritDoc} + * * @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; } - + /** * * {@inheritDoc} + * * @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); } - - /** + + /** * {@inheritDoc} + * * @see org.splat.service.StudyService#getDescription(java.lang.Long) */ @Override @Transactional(readOnly = true) - public String getDescription(final Long studyId) throws InvalidParameterException { - if(studyId == null) { - throw new InvalidParameterException("studyId", "null"); + public String getDescription(final Long studyId) + throws InvalidParameterException { + if (studyId == null) { + throw new InvalidParameterException(PARAM_STUDY_ID, "null"); } Study study = _studyDAO.get(studyId); - if(study == null) { - throw new InvalidParameterException("studyId", studyId.toString()); + if (study == null) { + throw new InvalidParameterException(PARAM_STUDY_ID, studyId + .toString()); } return study.getDescription(); } - - - /** + + /** * {@inheritDoc} + * * @see org.splat.service.StudyService#setDescription(java.lang.Long, java.lang.String) */ - @Override @Transactional - public void setDescription(final Long studyId, final String descriptionText) + public void setDescription(final Long studyId, final String descriptionText) throws InvalidParameterException { - if(studyId == null) { - throw new InvalidParameterException("studyId", "null"); + if (studyId == null) { + throw new InvalidParameterException(PARAM_STUDY_ID, "null"); } Study study = _studyDAO.get(studyId); - if(study == null) { - throw new InvalidParameterException("studyId", studyId.toString()); + if (study == null) { + throw new InvalidParameterException(PARAM_STUDY_ID, studyId + .toString()); } study.setAttribute(new DescriptionAttribute(study, descriptionText)); } /** * {@inheritDoc} + * * @see org.splat.service.StudyService#removeStudyDescription(java.lang.Long) */ - @Override @Transactional - public boolean removeDescription(final Long studyId) throws InvalidParameterException { - if(studyId == null) { - throw new InvalidParameterException("studyId", String.valueOf(studyId)); + public boolean removeDescription(final Long studyId) + throws InvalidParameterException { + if (studyId == null) { + throw new InvalidParameterException(PARAM_STUDY_ID, String + .valueOf(studyId)); } Study study = _studyDAO.get(studyId); - if(study == null) { - throw new InvalidParameterException("studyId", String.valueOf(studyId)); + if (study == null) { + throw new InvalidParameterException(PARAM_STUDY_ID, String + .valueOf(studyId)); } - return study.removeAttribute(study.getAttribute(DescriptionAttribute.class)); + return study.removeAttribute(study + .getAttribute(DescriptionAttribute.class)); } - + /** * * {@inheritDoc} + * * @see org.splat.service.StudyService#compare(java.util.List) */ @Override - public String compare (final List docsList, final String userName) throws IncompatibleDataException { - + public String compare(final List docsList, + final String userName) throws IncompatibleDataException { + String axis1Name = ""; String axis2Name = ""; + String chartTitle = ""; String resultPath = ""; - + XYSeriesCollection dataset = new XYSeriesCollection(); - + Iterator docListIter = docsList.iterator(); - + for (; docListIter.hasNext();) { - + DocToCompareDTO docDTO = docListIter.next(); String pathToFile = docDTO.getPathToFile(); File compDocFile = new File(pathToFile); - - resultPath = pathToFile.substring(0, pathToFile.indexOf("vault")) + "downloads" + File.separator + userName + File.separator + "ComparisonResult.pdf"; - - XYSeries series = new XYSeries("Study: " + docDTO.getStudyTitle() + " Scenario: " + docDTO.getScenarioTitle()); - - //read the file and get points information. + + resultPath = pathToFile.substring(0, pathToFile.indexOf("vault")) + + "downloads" + File.separator + userName + File.separator + + "ComparisonResult.pdf"; + + 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 name of the axis. + + // 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(","); - - if (tokens.length < 2) - throw new IncompatibleDataException(MessageKeyEnum.IDT_000001.toString()); - + + if (tokens.length < 2) { + throw new IncompatibleDataException( + MessageKeyEnum.IDT_000001.toString()); + } + if ("".equals(axis1Name)) { axis1Name = tokens[0]; } else if (!axis1Name.equals(tokens[0])) { LOG.debug("Axis must be the same for all documents"); - throw new IncompatibleDataException(MessageKeyEnum.IDT_000001.toString()); + throw new IncompatibleDataException( + MessageKeyEnum.IDT_000001.toString()); } - + if ("".equals(axis2Name)) { axis2Name = tokens[1]; } else if (!axis2Name.equals(tokens[1])) { LOG.debug("Axis must be the same for all documents"); - throw new IncompatibleDataException(MessageKeyEnum.IDT_000001.toString()); + throw new IncompatibleDataException( + MessageKeyEnum.IDT_000001.toString()); } } - - //Get the XY points series. - while(input.hasNext()) { - + + // Get the XY points series. + while (input.hasNext()) { + String currentString = input.nextLine(); - - if ("".equals(currentString)) { - continue; - } - else { + + if (!("".equals(currentString))) { String[] tokens = currentString.split(" "); - series.add(Double.valueOf(tokens[0]), Double.valueOf(tokens[1])); - } - - } //while - + series.add(Double.valueOf(tokens[0]), Double + .valueOf(tokens[1])); + } + + } // while + dataset.addSeries(series); - + } catch (FileNotFoundException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - return "ERROR"; + LOG.error("Sorry, the file is not found.", e); } - } //for - - JFreeChart chart = ChartFactory.createXYLineChart( - "Comparision of Studies Results", // Title + } // for + + JFreeChart chart = ChartFactory.createXYLineChart(chartTitle, // Title axis1Name, // x-axis Label axis2Name, // y-axis Label dataset, // Dataset @@ -1232,39 +1308,113 @@ public class StudyServiceImpl implements StudyService { true, // Use tooltips false // Configure chart to generate URLs? ); - - //export to PDF - file. + + // export to PDF - file. int x = 500; int y = 300; Rectangle pagesize = new Rectangle(x, y); Document document = new Document(pagesize, 50, 50, 50, 50); - PdfWriter writer; + PdfWriter writer; try { File resFile = new File(resultPath); - File resFolder = new File(resultPath.substring(0, resultPath.lastIndexOf(File.separator))); + File resFolder = new File(resultPath.substring(0, resultPath + .lastIndexOf(File.separator))); resFolder.mkdirs(); - writer = PdfWriter.getInstance(document, new FileOutputStream(resFile)); - - document.open(); - PdfContentByte cb = writer.getDirectContent(); - PdfTemplate tp = cb.createTemplate(x, y); - Graphics2D g2 = tp.createGraphics(x, y, new DefaultFontMapper()); - chart.draw(g2, new java.awt.Rectangle(x,y)); - g2.dispose(); - cb.addTemplate(tp, 0, 0); - document.close(); - + writer = PdfWriter.getInstance(document, new FileOutputStream( + resFile)); + + document.open(); + PdfContentByte cb = writer.getDirectContent(); + PdfTemplate tp = cb.createTemplate(x, y); + Graphics2D g2 = tp.createGraphics(x, y, new DefaultFontMapper()); + chart.draw(g2, new java.awt.Rectangle(x, y)); + g2.dispose(); + cb.addTemplate(tp, 0, 0); + document.close(); + } catch (FileNotFoundException e) { - // TODO Auto-generated catch block - e.printStackTrace(); + LOG.error("Sorry, the file is not found.", e); } catch (DocumentException e) { - // TODO Auto-generated catch block - e.printStackTrace(); + 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. * @@ -1459,8 +1609,111 @@ public class StudyServiceImpl implements StudyService { _userService = userService; } + /** + * {@inheritDoc} + * + * @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 + List allSteps = _projectSettings.getAllSteps(); + Step theAnalyzeStep = null; + 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."); + } + + List publications = _publicationDAO.getFilteredList( + "mydoc", Restrictions.eq("step", Integer.valueOf(theAnalyzeStep + .getNumber()))); + + // 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) + || !"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())) { + 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)) { + throw new MismatchException( + "publications from postprocessing step are supposed to have owner scenario"); + } + + if (!studyMap.containsKey(study)) { + studyMap.put(study, new ArrayList()); + } + + if (!studyMap.get(study).contains(scenario)) { + studyMap.get(study).add(scenario); + } + + if (!scenarioMap.containsKey(scenario)) { + scenarioMap.put(scenario, new ArrayList()); + } + scenarioMap.get(scenario).add(publication); + } + + // Create the result DTOs + List result = new ArrayList(); + 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)) { + + StudyFacadeDTO.ScenarioDTO scenarioDTO = new StudyFacadeDTO.ScenarioDTO(); + scenarioDTO.setName(scenario.getTitle()); + scenarioDTO.setDocs(new ArrayList()); + studyDTO.getScenarios().add(scenarioDTO); + + 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. + * * @return the publicationDAO */ public PublicationDAO getPublicationDAO() { @@ -1469,7 +1722,9 @@ public class StudyServiceImpl implements StudyService { /** * Set the publicationDAO. - * @param publicationDAO the publicationDAO to set + * + * @param publicationDAO + * the publicationDAO to set */ public void setPublicationDAO(final PublicationDAO publicationDAO) { _publicationDAO = publicationDAO; @@ -1477,6 +1732,7 @@ public class StudyServiceImpl implements StudyService { /** * Get the repositoryService. + * * @return the repositoryService */ public RepositoryService getRepositoryService() { @@ -1485,7 +1741,9 @@ public class StudyServiceImpl implements StudyService { /** * Set the repositoryService. - * @param repositoryService the repositoryService to set + * + * @param repositoryService + * the repositoryService to set */ public void setRepositoryService(final RepositoryService repositoryService) { _repositoryService = repositoryService; @@ -1493,6 +1751,7 @@ public class StudyServiceImpl implements StudyService { /** * Get the documentDAO. + * * @return the documentDAO */ public DocumentDAO getDocumentDAO() { @@ -1501,7 +1760,9 @@ public class StudyServiceImpl implements StudyService { /** * Set the documentDAO. - * @param documentDAO the documentDAO to set + * + * @param documentDAO + * the documentDAO to set */ public void setDocumentDAO(final DocumentDAO documentDAO) { _documentDAO = documentDAO; @@ -1509,6 +1770,7 @@ public class StudyServiceImpl implements StudyService { /** * Get the descriptionAttributeDAO. + * * @return the descriptionAttributeDAO */ public DescriptionAttributeDAO getDescriptionAttributeDAO() { @@ -1517,11 +1779,119 @@ public class StudyServiceImpl implements StudyService { /** * Set the descriptionAttributeDAO. - * @param descriptionAttributeDAO the descriptionAttributeDAO to set + * + * @param descriptionAttributeDAO + * the descriptionAttributeDAO to set */ public void setDescriptionAttributeDAO( final DescriptionAttributeDAO descriptionAttributeDAO) { _descriptionAttributeDAO = descriptionAttributeDAO; } + /** + * Get the usedByRelationDAO. + * + * @return the usedByRelationDAO + */ + public UsedByRelationDAO getUsedByRelationDAO() { + return _usedByRelationDAO; + } + + /** + * Set the usedByRelationDAO. + * + * @param usedByRelationDAO + * the usedByRelationDAO to set + */ + public void setUsedByRelationDAO(final UsedByRelationDAO usedByRelationDAO) { + _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; + } }