X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;ds=sidebyside;f=Workspace%2FSiman-Common%2Fsrc%2Forg%2Fsplat%2Fservice%2FStudyServiceImpl.java;h=d6bf598962b848b99a8c3eabad3be6d38c9481c9;hb=d0f7e95389f08ff3dfec5961d9f19866e0ee956b;hp=5a0cbce2e6ae1031eab58576bd18e8347d8043dd;hpb=330b4ef8e6c87a25897847aaade03d2445bafb8c;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 5a0cbce..d6bf598 100644 --- a/Workspace/Siman-Common/src/org/splat/service/StudyServiceImpl.java +++ b/Workspace/Siman-Common/src/org/splat/service/StudyServiceImpl.java @@ -9,26 +9,47 @@ package org.splat.service; +import java.awt.Graphics2D; +import java.io.File; +import java.io.FileNotFoundException; +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; +import java.util.Scanner; 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.Restrictions; +import org.hibernate.proxy.HibernateProxy; +import org.jfree.chart.ChartFactory; +import org.jfree.chart.JFreeChart; +import org.jfree.chart.plot.PlotOrientation; +import org.jfree.data.xy.XYSeries; +import org.jfree.data.xy.XYSeriesCollection; +import org.splat.common.properties.MessageKeyEnum; import org.splat.dal.bo.kernel.Relation; import org.splat.dal.bo.kernel.User; import org.splat.dal.bo.som.ActorRelation; import org.splat.dal.bo.som.ContributorRelation; import org.splat.dal.bo.som.DescriptionAttribute; -import org.splat.dal.bo.som.Document; 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.Scenario; import org.splat.dal.bo.som.SimulationContext; @@ -39,21 +60,41 @@ 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.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.kernel.UserDirectory; 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.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.springframework.transaction.annotation.Transactional; +import com.lowagie.text.Document; +import com.lowagie.text.DocumentException; +import com.lowagie.text.Rectangle; +import com.lowagie.text.pdf.DefaultFontMapper; +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. * @@ -65,8 +106,12 @@ public class StudyServiceImpl implements StudyService { /** * logger for the service. */ - public final static AppLogger logger = AppLogger + public final static AppLogger LOG = AppLogger .getLogger(StudyServiceImpl.class); + /** + * "studyId" parameter name. + */ + public final static String PARAM_STUDY_ID = "studyId"; /** * Injected index service. @@ -81,7 +126,7 @@ public class StudyServiceImpl implements StudyService { /** * Injected project service. */ - private ProjectSettingsService _projectSettingsService; + private ProjectSettingsService _projectSettings; /** * Injected project element service. @@ -93,6 +138,11 @@ public class StudyServiceImpl implements StudyService { */ private StudyDAO _studyDAO; + /** + * Injected usedBy relations DAO. + */ + private UsedByRelationDAO _usedByRelationDAO; + /** * Injected scenario DAO. */ @@ -113,18 +163,97 @@ public class StudyServiceImpl implements StudyService { */ private DocumentTypeService _documentTypeService; + /** + * Injected user service. + */ + private UserService _userService; + + /** + * Injected publication DAO. + */ + private PublicationDAO _publicationDAO; + + /** + * Injected repository service. + */ + private RepositoryService _repositoryService; + + /** + * Injected document DAO. + */ + private DocumentDAO _documentDAO; + + /** + * Injected description attribute DAO. + */ + private DescriptionAttributeDAO _descriptionAttributeDAO; + /** * {@inheritDoc} * * @see org.splat.service.StudyService#selectStudy(long) */ @Transactional - public Study selectStudy(long index) { + public Study selectStudy(final long index) { Study result = getStudyDAO().get(index); loadWorkflow(result); return result; } + /** + * {@inheritDoc} + * + * @see org.splat.service.StudyService#removeStudy(long) + */ + @Transactional + 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); + } + } + } + /** * Get study by its reference. * @@ -133,7 +262,7 @@ public class StudyServiceImpl implements StudyService { * @return found study or null */ @Transactional(readOnly = true) - public Study selectStudy(String refid) { + public Study selectStudy(final String refid) { Study result = getStudyDAO().findByCriteria( Restrictions.eq("sid", refid)); loadWorkflow(result); @@ -146,7 +275,7 @@ public class StudyServiceImpl implements StudyService { * @see org.splat.service.StudyService#createStudy(org.splat.dal.bo.som.Study.Properties) */ @Transactional - public Study createStudy(Study.Properties sprop) + public Study createStudy(final Study.Properties sprop) throws MissedPropertyException, InvalidPropertyException, MultiplyDefinedException { sprop.setReference(getProjectSettings().getReferencePattern()); @@ -154,14 +283,14 @@ public class StudyServiceImpl implements StudyService { buildReference(study); getStudyDAO().create(study); - try { - IndexService lucin = getIndex(); - lucin.add(study); - } catch (IOException error) { - logger.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; } @@ -170,9 +299,11 @@ public class StudyServiceImpl implements StudyService { * * @see org.splat.service.StudyService#addProjectContext(org.splat.dal.bo.som.Study, org.splat.dal.bo.som.SimulationContext.Properties) */ - public SimulationContext addProjectContext(Study aStudy, - SimulationContext.Properties cprop) throws MissedPropertyException, - InvalidPropertyException, MultiplyDefinedException { + @Transactional + public SimulationContext addProjectContext(final Study aStudy, + final SimulationContext.Properties cprop) + throws MissedPropertyException, InvalidPropertyException, + MultiplyDefinedException { SimulationContext added = getStepService().addSimulationContext( getProjectElementService().getFirstStep(aStudy), cprop); update(aStudy); @@ -184,8 +315,9 @@ public class StudyServiceImpl implements StudyService { * * @see org.splat.service.StudyService#addProjectContext(org.splat.dal.bo.som.Study, org.splat.dal.bo.som.SimulationContext) */ - public SimulationContext addProjectContext(Study aStudy, - SimulationContext context) { + @Transactional + public SimulationContext addProjectContext(final Study aStudy, + final SimulationContext context) { SimulationContext added = getStepService().addSimulationContext( getProjectElementService().getFirstStep(aStudy), context); update(aStudy); @@ -197,19 +329,21 @@ public class StudyServiceImpl implements StudyService { * * @see org.splat.service.StudyService#addContributor(org.splat.dal.bo.som.Study, org.splat.dal.bo.kernel.User) */ - public boolean addContributor(Study aStudy, User 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)) + if (present.equals(user)) { return false; + } } boolean absent = getModifiableActors(aStudy).add(user); // User may already be a reviewer or an approver aStudy.addRelation(new ContributorRelation(aStudy, user)); - if (absent) + if (absent) { update(aStudy); // Else, useless to re-index the study - contributor.add(user); + } return true; } @@ -224,11 +358,13 @@ public class StudyServiceImpl implements StudyService { * @see #isPublic() * @see Publication#approve(Date) */ - public boolean moveToReference(Study aStudy) { - if (aStudy.getProgressState() != ProgressState.APPROVED) + public boolean moveToReference(final Study aStudy) { + if (aStudy.getProgressState() != ProgressState.APPROVED) { return false; - if (aStudy.getVisibility() != Visibility.PUBLIC) + } + if (aStudy.getVisibility() != Visibility.PUBLIC) { return false; + } aStudy.setVisibility(Visibility.REFERENCE); if (update(aStudy)) { @@ -242,13 +378,15 @@ public class StudyServiceImpl implements StudyService { * * @see org.splat.service.StudyService#update(org.splat.dal.bo.som.Study, org.splat.dal.bo.som.Study.Properties) */ - public boolean update(Study aStudy, Properties sprop) + public boolean update(final Study aStudy, final Properties sprop) throws InvalidPropertyException { - if (sprop.getTitle() != null) + if (sprop.getTitle() != null) { aStudy.setTitle(sprop.getTitle()); - if (sprop.getSummary() != null) + } + if (sprop.getSummary() != null) { aStudy.setAttribute(new DescriptionAttribute(aStudy, sprop .getSummary())); + } // TODO: To be completed return update(aStudy); } @@ -262,31 +400,34 @@ public class StudyServiceImpl implements StudyService { * the document * @return true if the document is published in the study */ - private boolean publishes(Study aStudy, Document doc) { +/* 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)) + 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[]) */ - public boolean removeContributor(Study aStudy, User... users) { + @Transactional + public boolean removeContributor(final Study aStudy, final User... users) { List contributor = 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)) + if (!present.equals(user)) { continue; + } aStudy.removeRelation(ContributorRelation.class, user); j.remove(); // Updates the contributor shortcut @@ -294,8 +435,9 @@ public class StudyServiceImpl implements StudyService { break; } } - if (done) + if (done) { update(aStudy); + } return done; } @@ -304,7 +446,8 @@ public class StudyServiceImpl implements StudyService { * * @see org.splat.service.StudyService#removeProjectContext(org.splat.dal.bo.som.Study, org.splat.dal.bo.som.SimulationContext) */ - public boolean removeProjectContext(Study aStudy, SimulationContext context) { + public boolean removeProjectContext(final Study aStudy, + final SimulationContext context) { boolean done = getStepService().removeSimulationContext( getProjectElementService().getFirstStep(aStudy), context); update(aStudy); @@ -318,34 +461,39 @@ public class StudyServiceImpl implements StudyService { * org.splat.dal.bo.som.ValidationCycle.Properties) */ @Transactional - public void setValidationCycle(Study aStudy, DocumentType type, - ValidationCycle.Properties vprop) { - Map validactor = aStudy.getValidationCycles(); - if (validactor == null) - setShortCuts(aStudy); // Initializes validactor and actor + 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); if (cycle != null && cycle.isAssigned()) { resetActors(cycle, vprop); - } else + } else { try { cycle = new ValidationCycle(aStudy, vprop.setDocumentType(type)); getValidationCycleDAO().create(cycle); // RKV ValidationCycleRelation link = cycle.getContext(); - // RKV: aStudy.addRelation(link); - aStudy.getAllRelations().add(link); // RKV + aStudy.addRelation(link); + aStudyDTO.getAllRelations().add(link); // RKV validactor.put(cname, link.getTo()); // Replaces the cycle if exists as default, - } catch (Exception error) { - logger.error("Unable to re-index Knowledge Elements, reason:", + } catch (BusinessException error) { + LOG.error("Unable to create validation cycle, reason:", error); return; } - resetActorsShortCut(aStudy); + } + resetActorsShortCut(aStudyDTO); update(aStudy); // Re-index the study, just in case } @@ -357,13 +505,14 @@ public class StudyServiceImpl implements StudyService { * a study to demote * @return true if the demotion succeeded. */ - public boolean demote(Study aStudy) { - if (aStudy.getProgressState() == ProgressState.inCHECK) + public boolean demote(final Study aStudy) { + if (aStudy.getProgressState() == ProgressState.inCHECK) { aStudy.setProgressState(ProgressState.inDRAFT); - else if (aStudy.getProgressState() == ProgressState.inDRAFT) + } else if (aStudy.getProgressState() == ProgressState.inDRAFT) { aStudy.setProgressState(ProgressState.inWORK); - else + } else { return false; + } return update(aStudy); } @@ -373,9 +522,8 @@ public class StudyServiceImpl implements StudyService { * @see org.splat.service.StudyService#generateLocalIndex(org.splat.dal.bo.som.Study) */ @Transactional - public int generateLocalIndex(Study aStudy) { + public int generateLocalIndex(final Study aStudy) { aStudy.setLastLocalIndex(aStudy.getLastLocalIndex() + 1); - getStudyDAO().update(aStudy); return aStudy.getLastLocalIndex(); } @@ -387,7 +535,8 @@ public class StudyServiceImpl implements StudyService { * a study to promote * @return true if the demotion succeeded. */ - public boolean promote(Study aStudy) { + @Transactional + public boolean promote(final Study aStudy) { if (aStudy.getProgressState() == ProgressState.inWORK) { aStudy.setProgressState(ProgressState.inDRAFT); } else if (aStudy.getProgressState() == ProgressState.inDRAFT) { @@ -399,8 +548,9 @@ public class StudyServiceImpl implements StudyService { } } else if (aStudy.getProgressState() == ProgressState.inCHECK) { aStudy.setProgressState(ProgressState.APPROVED); - } else + } else { return false; + } return update(aStudy); } @@ -413,7 +563,8 @@ public class StudyServiceImpl implements StudyService { * @return true if the move succeeded. * @see #isPublic() */ - public boolean moveToPublic(Study aStudy) { + @Transactional + public boolean moveToPublic(final Study aStudy) { boolean isOk = false; if (aStudy.getVisibility() == Visibility.PRIVATE) { aStudy.setVisibility(Visibility.PUBLIC); @@ -424,6 +575,25 @@ public class StudyServiceImpl implements StudyService { return isOk; } + /** + * Moves this study from the Public to the Private area of the repository. + * + * @param aStudy + * a study to move + * @return true if the move succeeded. + */ + @Transactional + public boolean moveToPrivate(final Study aStudy) { + boolean isOk = false; + 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 + } + } + return isOk; + } + /** * Update a study in the database. * @@ -432,16 +602,15 @@ public class StudyServiceImpl implements StudyService { * @return true if the study is updated successfully */ @Transactional - private boolean update(Study aStudy) { + private boolean update(final Study aStudy) { boolean isOk = false; try { - getStudyDAO().update(aStudy); // Update of relational base - setShortCuts(aStudy); //RKV: initialize transient actors set - getIndex().update(aStudy); // Update of Lucene index + getStudyDAO().merge(aStudy); // Update of relational base + setShortCuts(aStudy); // RKV: initialize transient actors set + // RKV: getIndex().update(aStudy); // Update of Lucene index isOk = true; - } catch (Exception error) { - logger.error("Unable to re-index the study '" + aStudy.getIndex() - + "', reason:", error); + } catch (Exception e) { + LOG.error("STD-000001", e, aStudy.getIndex(), e.getMessage()); } return isOk; } @@ -454,17 +623,87 @@ public class StudyServiceImpl implements StudyService { * @return true if reference building is succeded */ @Transactional - private boolean buildReference(Study aStudy) { + private boolean buildReference(final Study aStudy) { String pattern = aStudy.getReference(); // The study being supposed just created, its reference is the reference pattern IDBuilder tool = selectIDBuilder(aStudy.getDate()); if (tool == null) { tool = new IDBuilder(aStudy.getDate()); getIDBuilderDAO().create(tool); } - aStudy.setReference(tool.buildReference(pattern, aStudy)); + aStudy.setReference(buildReference(tool, pattern, aStudy)); return true; } + /** + * Build reference for the study. The reference of the study is stored as a new reference pattern (IDBuilder). + * + * @param aBuilder + * the id builder + * @param study + * the study + * @param pattern + * the reference pattern + * @return true if reference building is succeded + */ + @Transactional + public String buildReference(final IDBuilder aBuilder, + final String pattern, final Study study) { + char[] format = pattern.toCharArray(); + char[] ref = new char[80]; // Better evaluate the length of the generated string + int next = aBuilder.getBase() + 1; + + int count = 0; + for (int i = 0; i < format.length; i++) { + + // Insertion of attribute values + if (format[i] == '%') { + i += 1; + + if (format[i] == 'y') { // Insertion of year in format 2 (e.g. 09) or 4 (e.g. 2009) digits + int n = i; + while (format[i] == 'y') { + i += 1; + if (i == format.length) { + break; + } + } + 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++) { + ref[count] = year.charAt(j); + count += 1; + } + i -= 1; // Back to the last 'y' character + } else if (format[i] == '0') { // Insertion of the index + int n = i; + while (format[i] == '0') { + i += 1; + if (i == format.length) { + break; + } + } + DecimalFormat tostring = new DecimalFormat(pattern + .substring(n, i)); + String number = tostring.format(next); + for (int j = 0; j < number.length(); j++) { + ref[count] = number.charAt(j); + count += 1; + } + i -= 1; // Back to the last '0' character + } + // Keep the character + } else { + ref[count] = format[i]; + count += 1; + } + } + // Incrementation of the number of study + aBuilder.setBase(next); + getIDBuilderDAO().update(aBuilder); + return String.copyValueOf(ref, 0, count); + } + /** * Find an id builder by date. * @@ -472,7 +711,7 @@ public class StudyServiceImpl implements StudyService { * the date * @return found id builder */ - private IDBuilder selectIDBuilder(Date date) { + private IDBuilder selectIDBuilder(final Date date) { Calendar aDate = Calendar.getInstance(); aDate.setTime(date); return getIDBuilderDAO().findByCriteria( @@ -485,23 +724,25 @@ public class StudyServiceImpl implements StudyService { * @param aStudy * the study */ - private void resetActorsShortCut(Study aStudy) { + private void resetActorsShortCut(final Study aStudy) { getModifiableActors(aStudy).clear(); // Get all actors involved in validation cycles for (Iterator i = aStudy.getValidationCycles() .values().iterator(); i.hasNext();) { ValidationCycle cycle = i.next(); User[] user = cycle.getAllActors(); - for (int j = 0; j < user.length; j++) + for (int j = 0; j < user.length; j++) { getModifiableActors(aStudy).add(user[j]); + } } // Get all other actors for (Iterator i = aStudy.getAllRelations().iterator(); i .hasNext();) { Relation link = i.next(); Class kindof = link.getClass().getSuperclass(); - if (!kindof.equals(ActorRelation.class)) + if (!kindof.equals(ActorRelation.class)) { continue; + } getModifiableActors(aStudy).add(((ActorRelation) link).getTo()); } } @@ -513,26 +754,27 @@ public class StudyServiceImpl implements StudyService { * the study * @return true if reindexing succeeded */ - private boolean updateKnowledgeElementsIndex(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) { - logger.error("Unable to re-index Knowledge Elements, reason:", - error); - } - return isOk; + 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; } /** @@ -544,8 +786,14 @@ public class StudyServiceImpl implements StudyService { */ private IndexService getIndex() throws IOException { IndexService lucin = getIndexService(); - if (!lucin.exists()) + if (IndexWriter.isLocked(FSDirectory.open(getRepositoryService() + .getRepositoryIndexDirectory()))) { + IndexWriter.unlock(FSDirectory.open(getRepositoryService() + .getRepositoryIndexDirectory())); + } + if (!lucin.exists()) { lucin.create(); // Happens when re-indexing all studies + } return lucin; } @@ -558,35 +806,35 @@ public class StudyServiceImpl implements StudyService { * the cycle description * @return the new validation cycle */ - protected ValidationCycle createValidationCycle(Study from, - ProjectSettingsServiceImpl.ProjectSettingsValidationCycle cycle) { - // ----------------------------------------------------------------------------- + protected ValidationCycle createValidationCycle( + final Study from, + final ProjectSettingsServiceImpl.ProjectSettingsValidationCycle cycle) { Actor[] actype = cycle.getActorTypes(); User.Properties uprop = new User.Properties(); ValidationCycle aValidationCycle = new ValidationCycle(); aValidationCycle.setDocumentType(getDocumentTypeService().selectType( cycle.getName())); // Null in case of default validation cycle - // context = new ValidationCycleRelation(from, this); + // context = new ValidationCycleRelation(from, vprop); // RKV aValidationCycle.context = null; // Validation cycle defined in the workflow for (int i = 0; i < actype.length; i++) { User actor = null; - if (actype[i] != null) + if (actype[i] != null) { try { if (actype[i] == Actor.manager) { actor = from.getAuthor(); } else if (actype[i] == Actor.Nx1) { - List manager = UserDirectory - .selectUsersWhere(uprop - .setOrganizationName("Nx1")); - if (manager.size() == 1) + List manager = getUserService().selectUsersWhere( + uprop.setOrganizationName("Nx1")); + if (manager.size() == 1) { actor = manager.get(0); + } } else if (actype[i] == Actor.Nx2) { - List manager = UserDirectory - .selectUsersWhere(uprop - .setOrganizationName("Nx2")); - if (manager.size() == 1) + List manager = getUserService().selectUsersWhere( + uprop.setOrganizationName("Nx2")); + if (manager.size() == 1) { actor = manager.get(0); + } } else { /* Actor.customer */ actor = from.getAuthor(); // TODO: Get the customer of the study, if exists @@ -594,12 +842,14 @@ public class StudyServiceImpl implements StudyService { } catch (Exception e) { // Should not happen actor = null; } - if (i == 0) + } + if (i == 0) { aValidationCycle.setReviewer(actor); - else if (i == 1) + } else if (i == 1) { aValidationCycle.setApprover(actor); - else if (i == 2) + } else if (i == 2) { aValidationCycle.setSignatory(actor); + } } return aValidationCycle; } @@ -613,15 +863,16 @@ public class StudyServiceImpl implements StudyService { * the validation step to remove */ @Transactional - protected void remove(ValidationCycle aValidationCycle, ValidationStep step) { - // ------------------------------------------ - if (step == ValidationStep.REVIEW) + protected void remove(final ValidationCycle aValidationCycle, + final ValidationStep step) { + if (step == ValidationStep.REVIEW) { aValidationCycle.setReviewer(null); - else if (step == ValidationStep.APPROVAL) + } else if (step == ValidationStep.APPROVAL) { aValidationCycle.setApprover(null); - else if (step == ValidationStep.ACCEPTANCE - || step == ValidationStep.REFUSAL) + } else if (step == ValidationStep.ACCEPTANCE + || step == ValidationStep.REFUSAL) { aValidationCycle.setSignatory(null); + } if (aValidationCycle.isSaved()) { getValidationCycleDAO().update(aValidationCycle); } @@ -636,14 +887,14 @@ public class StudyServiceImpl implements StudyService { * new validation cycle properties containing new actors */ @Transactional - public void resetActors(ValidationCycle aValidationCycle, - ValidationCycle.Properties vprop) { + public void resetActors(final ValidationCycle aValidationCycle, + final ValidationCycle.Properties vprop) { aValidationCycle.setPublisher(vprop.getPublisher()); // May be null aValidationCycle.setReviewer(vprop.getReviewer()); // May be null aValidationCycle.setApprover(vprop.getApprover()); // May be null aValidationCycle.setSignatory(vprop.getSignatory()); // May be null if (aValidationCycle.isSaved()) { - getValidationCycleDAO().update(aValidationCycle); + getValidationCycleDAO().merge(aValidationCycle); } } @@ -658,8 +909,8 @@ public class StudyServiceImpl implements StudyService { * the actor to set */ @Transactional - protected void setActor(ValidationCycle aValidationCycle, - ValidationStep step, User actor) { + protected void setActor(final ValidationCycle aValidationCycle, + final ValidationStep step, final User actor) { if (step == ValidationStep.PROMOTION) { aValidationCycle.setPublisher(actor); } else if (step == ValidationStep.REVIEW) { @@ -683,9 +934,10 @@ public class StudyServiceImpl implements StudyService { * @return the actors of this study * @see #hasActor(User) */ - public Set getActors(Study aStudy) { - if (aStudy.getActor() == null) + public Set getActors(final Study aStudy) { + if (aStudy.getActor() == null) { setShortCuts(aStudy); + } return Collections.unmodifiableSet(aStudy.getActor()); } @@ -697,9 +949,10 @@ public class StudyServiceImpl implements StudyService { * @return the modifiable set of actors of this study * @see #hasActor(User) */ - public Set getModifiableActors(Study aStudy) { - if (aStudy.getActor() == null) + public Set getModifiableActors(final Study aStudy) { + if (aStudy.getActor() == null) { setShortCuts(aStudy); + } return aStudy.getActor(); } @@ -710,9 +963,10 @@ public class StudyServiceImpl implements StudyService { * the study * @return the unmodifiable not null transient list of contributors of this study */ - public List getContributors(Study aStudy) { - if (aStudy.getContributor() == null) + public List getContributors(final Study aStudy) { + if (aStudy.getContributor() == null) { setShortCuts(aStudy); + } return Collections.unmodifiableList(aStudy.getContributor()); // May be empty } @@ -723,9 +977,10 @@ public class StudyServiceImpl implements StudyService { * the study * @return the modifiable not null transient list of contributors of this study */ - public List getModifiableContributors(Study aStudy) { - if (aStudy.getContributor() == null) + public List getModifiableContributors(final Study aStudy) { + if (aStudy.getContributor() == null) { setShortCuts(aStudy); + } return aStudy.getContributor(); // May be empty } @@ -738,16 +993,21 @@ public class StudyServiceImpl implements StudyService { * the document type being subject of validation * @return the validation cycle of the document, or null if not defined. */ - public ValidationCycle getValidationCycleOf(Study aStudy, DocumentType type) { - if (aStudy.getValidationCycles() == null) + public ValidationCycle getValidationCycleOf(final Study aStudy, + final DocumentType type) { + if (aStudy.getValidationCycles() == null + || aStudy.getValidationCycles().isEmpty()) { setShortCuts(aStudy); + } ValidationCycle result = aStudy.getValidationCycles().get( type.getName()); if (result == null) { - if (type.isStepResult()) + if (type.isStepResult()) { result = aStudy.getValidationCycles().get("default"); // "default" validation cycle defined in the configuration, if exist - if (result == null) + } + if (result == null) { result = aStudy.getValidationCycles().get("built-in"); + } } return result; } @@ -762,13 +1022,15 @@ public class StudyServiceImpl implements StudyService { * @return true if the given user is actor of this study. * @see #getActors() */ - public boolean hasActor(Study aStudy, User user) { - if (user == null) + public boolean hasActor(final Study aStudy, final User user) { + if (user == null) { return false; + } for (Iterator i = getActors(aStudy).iterator(); i.hasNext();) { User involved = i.next(); - if (involved.equals(user)) + if (involved.equals(user)) { return true; + } } return false; } @@ -783,14 +1045,23 @@ public class StudyServiceImpl implements StudyService { * @return true if the given user is actor of this study. * @see #getContributors() */ - public boolean isStaffedBy(Study aStudy, User user) { - if (user == null) + public boolean isStaffedBy(final Study aStudy, final User user) { + if (user == null) { + return false; + } + if (aStudy == null) { + return false; + } + if (aStudy.getAuthor() == null) { return false; - if (aStudy.getAuthor().equals(user)) + } + if (aStudy.getAuthor().equals(user)) { return true; + } for (Iterator i = getContributors(aStudy).iterator(); i.hasNext();) { - if (i.next().equals(user)) + if (i.next().equals(user)) { return true; + } } return false; } @@ -801,7 +1072,7 @@ public class StudyServiceImpl implements StudyService { * @param aStudy * the study */ - public void loadWorkflow(Study aStudy) { + public void loadWorkflow(final Study aStudy) { setShortCuts(aStudy); } @@ -811,7 +1082,7 @@ public class StudyServiceImpl implements StudyService { * @param aStudy * the study */ - public void setShortCuts(Study aStudy) { + public void setShortCuts(final Study aStudy) { aStudy.getContributor().clear(); aStudy.getValidationCycles().clear(); aStudy.getActor().clear(); @@ -831,41 +1102,263 @@ public class StudyServiceImpl implements StudyService { // context } // Get the validation cycles coming from the configured workflow and not overridden in this study - for (Iterator i = ProjectSettingsServiceImpl + for (Iterator i = getProjectSettings() .getAllValidationCycles().iterator(); i.hasNext();) { ProjectSettingsServiceImpl.ProjectSettingsValidationCycle cycle = i .next(); String type = cycle.getName(); - if (!aStudy.getValidationCycles().containsKey(type)) + if (!aStudy.getValidationCycles().containsKey(type)) { aStudy.getValidationCycles().put(type, createValidationCycle(aStudy, cycle)); + } } // Get all corresponding actors for (Iterator i = aStudy.getValidationCycles() .values().iterator(); i.hasNext();) { ValidationCycle cycle = i.next(); User[] user = cycle.getAllActors(); - for (int j = 0; j < user.length; j++) + for (int j = 0; j < user.length; j++) { aStudy.getActor().add(user[j]); + } } // Get all other actors for (Iterator i = aStudy.getAllRelations().iterator(); i .hasNext();) { Relation link = i.next(); Class kindof = link.getClass().getSuperclass(); - if (!kindof.equals(ActorRelation.class)) + if (!kindof.equals(ActorRelation.class)) { continue; + } 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); + } + + /** + * + * {@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); + 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(PARAM_STUDY_ID, "null"); + } + Study study = _studyDAO.get(studyId); + 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) + throws InvalidParameterException { + if (studyId == null) { + throw new InvalidParameterException(PARAM_STUDY_ID, "null"); + } + Study study = _studyDAO.get(studyId); + 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(PARAM_STUDY_ID, String + .valueOf(studyId)); + } + Study study = _studyDAO.get(studyId); + if (study == null) { + throw new InvalidParameterException(PARAM_STUDY_ID, String + .valueOf(studyId)); + } + 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 { + + 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() + " Document: " + docDTO.getDocumentTitle()); + + // read the file and get points information. + try { + Scanner input = new Scanner(compDocFile); + + //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 ("".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()); + } + + 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()); + } + } + + // Get the XY points series. + while (input.hasNext()) { + + String currentString = input.nextLine(); + + if (!("".equals(currentString))) { + String[] tokens = currentString.split(" "); + series.add(Double.valueOf(tokens[0]), Double + .valueOf(tokens[1])); + } + + } // while + + dataset.addSeries(series); + + } catch (FileNotFoundException e) { + LOG.error("Sorry, the file is not found.", e); + } + } // for + + JFreeChart chart = ChartFactory.createXYLineChart( + chartTitle, // Title + axis1Name, // x-axis Label + axis2Name, // y-axis Label + dataset, // Dataset + PlotOrientation.VERTICAL, // Plot Orientation + true, // Show Legend + true, // Use tooltips + false // Configure chart to generate URLs? + ); + + // 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; + try { + File resFile = new File(resultPath); + 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(); + + } catch (FileNotFoundException e) { + LOG.error("Sorry, the file is not found.", e); + } catch (DocumentException e) { + LOG.error("Sorry, the DocumentException is thrown.", e); + } + + return resultPath; + } + /** * Get project settings. * * @return Project settings service */ private ProjectSettingsService getProjectSettings() { - return _projectSettingsService; + return _projectSettings; } /** @@ -874,8 +1367,9 @@ public class StudyServiceImpl implements StudyService { * @param projectSettingsService * project settings service */ - public void setProjectSettings(ProjectSettingsService projectSettingsService) { - _projectSettingsService = projectSettingsService; + public void setProjectSettings( + final ProjectSettingsService projectSettingsService) { + _projectSettings = projectSettingsService; } /** @@ -894,7 +1388,7 @@ public class StudyServiceImpl implements StudyService { * the projectElementService to set */ public void setProjectElementService( - ProjectElementService projectElementService) { + final ProjectElementService projectElementService) { _projectElementService = projectElementService; } @@ -913,7 +1407,7 @@ public class StudyServiceImpl implements StudyService { * @param stepService * the stepService to set */ - public void setStepService(StepService stepService) { + public void setStepService(final StepService stepService) { _stepService = stepService; } @@ -932,7 +1426,7 @@ public class StudyServiceImpl implements StudyService { * @param indexService * the indexService to set */ - public void setIndexService(IndexService indexService) { + public void setIndexService(final IndexService indexService) { _indexService = indexService; } @@ -951,7 +1445,7 @@ public class StudyServiceImpl implements StudyService { * @param studyDAO * the studyDAO to set */ - public void setStudyDAO(StudyDAO studyDAO) { + public void setStudyDAO(final StudyDAO studyDAO) { _studyDAO = studyDAO; } @@ -970,7 +1464,7 @@ public class StudyServiceImpl implements StudyService { * @param builderDAO * the iDBuilderDAO to set */ - public void setIDBuilderDAO(IDBuilderDAO builderDAO) { + public void setIDBuilderDAO(final IDBuilderDAO builderDAO) { _iDBuilderDAO = builderDAO; } @@ -989,7 +1483,7 @@ public class StudyServiceImpl implements StudyService { * @param scenarioDAO * the scenarioDAO to set */ - public void setScenarioDAO(ScenarioDAO scenarioDAO) { + public void setScenarioDAO(final ScenarioDAO scenarioDAO) { _scenarioDAO = scenarioDAO; } @@ -1008,7 +1502,8 @@ public class StudyServiceImpl implements StudyService { * @param validationCycleDAO * the validationCycleDAO to set */ - public void setValidationCycleDAO(ValidationCycleDAO validationCycleDAO) { + public void setValidationCycleDAO( + final ValidationCycleDAO validationCycleDAO) { _validationCycleDAO = validationCycleDAO; } @@ -1027,7 +1522,222 @@ public class StudyServiceImpl implements StudyService { * @param documentTypeService * the documentTypeService to set */ - public void setDocumentTypeService(DocumentTypeService documentTypeService) { + public void setDocumentTypeService( + final DocumentTypeService documentTypeService) { _documentTypeService = documentTypeService; } + + /** + * 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; + } + + /** + * {@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() { + return _publicationDAO; + } + + /** + * Set the publicationDAO. + * + * @param publicationDAO + * the publicationDAO to set + */ + public void setPublicationDAO(final PublicationDAO publicationDAO) { + _publicationDAO = publicationDAO; + } + + /** + * 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; + } + + /** + * 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 descriptionAttributeDAO. + * + * @return the descriptionAttributeDAO + */ + public DescriptionAttributeDAO getDescriptionAttributeDAO() { + return _descriptionAttributeDAO; + } + + /** + * Set the descriptionAttributeDAO. + * + * @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; + } + }