1 /*****************************************************************************
5 * Creation date 06.10.2012
8 *****************************************************************************/
10 package org.splat.service;
12 import java.io.IOException;
13 import java.util.ArrayList;
14 import java.util.Calendar;
15 import java.util.Date;
16 import java.util.HashMap;
17 import java.util.Iterator;
18 import java.util.List;
21 import org.splat.common.properties.MessageKeyEnum;
22 import org.splat.dal.bo.kernel.Relation;
23 import org.splat.dal.bo.kernel.User;
24 import org.splat.dal.bo.som.ConvertsRelation;
25 import org.splat.dal.bo.som.Document;
26 import org.splat.dal.bo.som.DocumentType;
27 import org.splat.dal.bo.som.File;
28 import org.splat.dal.bo.som.KnowledgeElement;
29 import org.splat.dal.bo.som.KnowledgeElementType;
30 import org.splat.dal.bo.som.ProgressState;
31 import org.splat.dal.bo.som.Publication;
32 import org.splat.dal.bo.som.Scenario;
33 import org.splat.dal.bo.som.SimulationContext;
34 import org.splat.dal.bo.som.Study;
35 import org.splat.dal.bo.som.UsesRelation;
36 import org.splat.dal.dao.kernel.UserDAO;
37 import org.splat.dal.dao.som.KnowledgeElementDAO;
38 import org.splat.dal.dao.som.KnowledgeElementTypeDAO;
39 import org.splat.dal.dao.som.ScenarioDAO;
40 import org.splat.dal.dao.som.StudyDAO;
41 import org.splat.kernel.InvalidPropertyException;
42 import org.splat.kernel.MismatchException;
43 import org.splat.kernel.MissedPropertyException;
44 import org.splat.kernel.MultiplyDefinedException;
45 import org.splat.kernel.NotApplicableException;
46 import org.splat.log.AppLogger;
47 import org.splat.service.dto.DocumentDTO;
48 import org.splat.service.dto.FileDTO;
49 import org.splat.service.dto.StepDTO;
50 import org.splat.service.technical.IndexService;
51 import org.splat.service.technical.ProjectSettingsService;
52 import org.splat.som.Step;
53 import org.splat.util.BeanHelper;
54 import org.springframework.transaction.annotation.Transactional;
57 * Scenario service implementation.
59 * @author <a href="mailto:roman.kozlov@opencascade.com">Roman Kozlov (RKV)</a>
61 public class ScenarioServiceImpl implements ScenarioService {
64 * The logger for the service.
66 public final static AppLogger LOG = AppLogger
67 .getLogger(ScenarioServiceImpl.class);
70 * Injected index service.
72 private IndexService _indexService;
74 * Injected step service.
76 private StepService _stepService;
78 * Injected study service.
80 private StudyService _studyService;
82 * Injected publication service.
84 private PublicationService _publicationService;
86 * Injected project element service.
88 private ProjectElementService _projectElementService;
90 * Injected knowledge element DAO.
92 private KnowledgeElementDAO _knowledgeElementDAO;
94 * Injected scenario DAO.
96 private ScenarioDAO _scenarioDAO;
101 private StudyDAO _studyDAO;
104 * Injected knowledge element service.
106 private KnowledgeElementTypeService _knowledgeElementTypeService;
109 * Injected user service.
111 private UserService _userService;
116 private UserDAO _userDAO;
119 * Injected knowledge element type DAO.
121 private KnowledgeElementTypeDAO _knowledgeElementTypeDAO;
124 * Injected simulation context service.
126 private SimulationContextService _simulationContextService;
129 * Injected project service.
131 private ProjectSettingsService _projectSettings;
134 * Injected document type service.
136 private DocumentTypeService _documentTypeService;
139 * Get the projectElementService.
141 * @return the projectElementService
143 public ProjectElementService getProjectElementService() {
144 return _projectElementService;
148 * Set the projectElementService.
150 * @param projectElementService
151 * the projectElementService to set
153 public void setProjectElementService(
154 final ProjectElementService projectElementService) {
155 _projectElementService = projectElementService;
159 * Get the publicationService.
161 * @return the publicationService
163 public PublicationService getPublicationService() {
164 return _publicationService;
168 * Set the publicationService.
170 * @param publicationService
171 * the publicationService to set
173 public void setPublicationService(
174 final PublicationService publicationService) {
175 _publicationService = publicationService;
179 * Get the stepService.
181 * @return the stepService
183 public StepService getStepService() {
188 * Set the stepService.
191 * the stepService to set
193 public void setStepService(final StepService stepService) {
194 _stepService = stepService;
200 * @see org.splat.service.ScenarioService#getScenarioInfo(long)
202 @Transactional(readOnly = true)
203 public List<StepDTO> getScenarioInfo(final long scenarioId) {
204 List<StepDTO> res = new ArrayList<StepDTO>();
205 // Get the scenario from the database by id
206 Scenario scen = getScenarioDAO().get(scenarioId);
207 if (LOG.isDebugEnabled()) {
208 LOG.debug("Scenario[" + scenarioId + "]: Number of publications: "
209 + scen.getDocums().size());
211 // Get activities of the scenario
212 Step[] steps = getProjectElementService().getSteps(scen);
215 String docType, fileFormat;
218 // For each activity create a step DTO and add it to the result list
219 for (Step step : steps) {
220 stepDTO = BeanHelper.copyBean(step.getStep(), StepDTO.class);
222 if (LOG.isDebugEnabled()) {
223 LOG.debug("Step[" + stepDTO.getNumber()
224 + "]: Number of documents: "
225 + step.getDocuments().size());
227 // For each publication of the activity create a document DTO.
228 // Each file is considered as a source file.
229 for (Publication tag : step.getDocuments()) {
230 docDTO = stepDTO.addDoc(tag.value().getIndex(), tag.value()
232 char aState = tag.getIsnew();
233 docType = tag.value().getType().getName();
234 // For each file of the document create a file DTO
235 // Process source file of the document
236 fileFormat = tag.value().getFile().getFormat();
237 doImport = getProjectSettings().doImport(docType, fileFormat);
238 if (doImport && (!tag.isOutdated())) {
239 processing = "file-import";
241 processing = "file-download";
243 docDTO.addFile(tag.value().getFile().getRelativePath(), aState,
245 // Process all exported files
246 for (Relation rel : tag.value().getRelations(
247 ConvertsRelation.class)) {
248 File aFile = ((ConvertsRelation) rel).getTo();
249 fileFormat = aFile.getFormat();
250 doImport = getProjectSettings().doImport(docType,
252 if (doImport && (!tag.isOutdated())) {
253 processing = "file-import";
255 processing = "file-download";
257 docDTO.addFile(aFile.getRelativePath(), aState, processing,
266 * Create a new study with one scenario and "product" simulation context.
269 * the study properties
271 * the scenario properties
273 * the "product" simulation context properties
274 * @return the created study
275 * @throws MissedPropertyException
276 * if a mandatory property is missed
277 * @throws InvalidPropertyException
278 * if a property is invalid
279 * @throws MultiplyDefinedException
280 * if some property occurs several times
283 public Study createStudy(final Study.Properties sprop,
284 final Scenario.Properties oprop,
285 final SimulationContext.Properties cprop)
286 throws MissedPropertyException, InvalidPropertyException,
287 MultiplyDefinedException {
288 Study study = getStudyService().createStudy(sprop);
289 addScenario(study, oprop);
290 if (cprop.getIndex() == 0) { // Input of new project context
291 cprop.setType(getSimulationContextService().selectType("product"))
292 .setValue(cprop.getValue());
293 getStudyService().addProjectContext(study, cprop);
294 } else { // Selection of existing project context
295 SimulationContext context = getSimulationContextService()
296 .selectSimulationContext(cprop.getIndex());
297 getStudyService().addProjectContext(study, context);
305 * @see org.splat.service.ScenarioService#addKnowledgeElement(org.splat.dal.bo.som.Scenario,
306 * org.splat.dal.bo.som.KnowledgeElement.Properties)
309 public KnowledgeElement addKnowledgeElement(final Scenario aScenarioDTO,
310 final KnowledgeElement.Properties kprop)
311 throws MissedPropertyException, InvalidPropertyException,
312 MultiplyDefinedException {
313 KnowledgeElement kelm = null;
315 long aScenarioId = aScenarioDTO.getIndex();
316 if (LOG.isDebugEnabled()) {
317 LOG.debug("Add a knowledge element to the scenario #"
320 // Get the persistent scenario.
321 Scenario aScenario = getScenarioDAO().get(aScenarioId);
322 // Get persistent objects for creating a new knowledge.
323 // TODO: Actions must use DTO instead of persistent objects.
324 getUserDAO().merge(kprop.getAuthor());
325 getKnowledgeElementTypeDAO().merge(kprop.getType());
326 // Create a transient knowledge element related to the given scenario.
327 kelm = new KnowledgeElement(kprop.setOwnerScenario(aScenario));
328 // Save the new knowledge in the database.
329 getKnowledgeElementDAO().create(kelm);
330 // Update scenario transient data.
331 if (kelm.getType().equals("usecase")) {
332 aScenarioDTO.setUcase(kelm);
333 } else if (aScenarioDTO.getKnowledgeElementsList() != null) { // If null, knowl will be initialized when needed
334 aScenarioDTO.getKnowledgeElementsList().add(kelm);
337 // Load the workflow for the parent study to take into account
338 // all study actors durng reindexing.
339 getStudyService().loadWorkflow(aScenario.getOwnerStudy());
341 // Update the lucene index of knowledge elements.
342 getIndexService().add(kelm);
343 if (LOG.isDebugEnabled()) {
344 LOG.debug("A knowledge element #" + kelm.getIndex()
345 + " is added to the scenario #" + aScenario.getIndex());
347 } catch (IOException error) {
348 LOG.error("Unable to index the knowedge element '"
349 + kelm.getIndex() + "', reason:", error);
357 * Update the scenario in the database.
360 * the scenario to update
361 * @return true if updating succeeded
364 private boolean update(final Scenario aScenario) {
365 boolean isOk = false;
367 getScenarioDAO().update(aScenario); // Update of relational base
369 } catch (Exception error) {
370 LOG.error("Unable to re-index the knowledge element '"
371 + aScenario.getIndex() + "', reason:", error);
379 * @see org.splat.service.ScenarioService#checkin(long, long, java.util.List)
382 public void checkin(final long scenId, final long userId,
383 final List<StepDTO> scInfo) throws InvalidPropertyException,
384 MissedPropertyException, MultiplyDefinedException,
385 MismatchException, IOException, NotApplicableException {
386 // Get the scenario from the database by id
387 Scenario aScenario = getScenarioDAO().get(scenId);
388 // Get the user who perform this check-in operation
389 User aUser = getUserService().selectUser(userId);
390 // Get activities of the scenario
391 Step[] steps = getProjectElementService().getSteps(aScenario);
392 // Find result document types
393 List<DocumentType> resTypes = getDocumentTypeService()
394 .selectResultTypes();
396 // For each processed existing document keep its new version
397 Map<Document, Document> newVersion = new HashMap<Document, Document>();
398 // Keep newly created documents to create uses relations to results of a previous step.
399 List<Publication> newVers = new ArrayList<Publication>();
400 List<Publication> newDocs = new ArrayList<Publication>();
402 DocumentType resType;
404 Document.Properties dprop = new Document.Properties();
405 Date aDate = new Date();
406 for (StepDTO stepDTO : scInfo) {
407 if (LOG.isDebugEnabled()) {
408 LOG.debug("Checkin the step:\n" + stepDTO);
410 // Find a result document type of the step
414 if (resTypes.get(i).isResultOf(
415 getProjectSettings().getStep(stepDTO.getNumber()))) {
416 resType = resTypes.get(i);
419 } while ((resType == null) && (i < resTypes.size()));
421 // Find the appropriate scenario step
422 Step step = findStep(stepDTO, steps);
424 // Process documents of the step
425 for (DocumentDTO doc : stepDTO.getDocs()) {
426 if (doc.getFiles().size() > 0) {
427 // NOTE: Process only the first attached file for each document
428 FileDTO file = doc.getFiles().get(0);
430 // Get document title as the file name
431 java.io.File upfile = new java.io.File(file.getPath());
432 String fileFormat = upfile.getName().substring(
433 upfile.getName().lastIndexOf('.') + 1);
434 String docname = upfile.getName().substring(0,
435 upfile.getName().lastIndexOf('.'));
437 // Create a new document or a new version of the document
439 dprop.setAuthor(aUser).setDate(aDate);
440 Publication pub, newPub;
442 if (doc.getId() > 0) {
443 // If the document already exists then create a new version of it
444 // Find the document publication
445 pub = step.getDocument(doc.getId());
447 throw new InvalidPropertyException(
448 MessageKeyEnum.SCN_000002.toString(), doc
451 if (pub.value() == null) {
452 throw new MismatchException(
453 MessageKeyEnum.SCN_000002.toString(), doc
456 newPub = getStepService().versionDocument(step, pub,
458 // Remeber the link from the old document to the new document version
459 newVersion.put(pub.value(), newPub.value());
460 // Remember the new version publication
464 // Otherwise create a new document of the result type
465 // If result type is not found try to get type by file extension
466 if (resType == null) {
467 dprop.setType(getProjectSettings()
468 .getDefaultDocumentType(step.getStep(),
471 dprop.setType(resType);
473 dprop.setDescription("Checked in").setName(docname)
474 .setFormat(fileFormat);
475 newPub = getStepService().createDocument(step, dprop);
477 // Remeber the new document
481 // Attach the file to the created document
482 updir = newPub.getSourceFile().asFile();
483 if (LOG.isDebugEnabled()) {
484 LOG.debug("Moving \"" + upfile.getName() + "\" to \""
485 + updir.getPath() + "\".");
487 if (updir.exists()) {
488 if (updir.delete()) {
489 LOG.info(MessageKeyEnum.SCN_000003.toString(),
490 updir.getAbsoluteFile(), scenId);
492 throw new IOException(
493 "Can't delete the existing destination file to move file from "
494 + file.getPath() + " to "
495 + updir.getAbsolutePath());
498 if (upfile.renameTo(updir)) {
499 // Save the new publication in the scenario.
500 // The old publication is removed from the scenario here.
501 getPublicationService().saveAs(newPub,
502 ProgressState.inWORK); // May throw FileNotFound if rename was not done
504 throw new IOException("Can't move file from "
505 + file.getPath() + " to "
506 + updir.getAbsolutePath());
512 // Set uses/used relations
514 // For each new version copy uses relations from the previous version.
515 for (Publication newVer : newVers) {
516 // For each Uses relation of the previous version
517 Document prevDoc = newVer.value().getPreviousVersion();// prevVersion.get(newVer);
518 if (LOG.isDebugEnabled()) {
519 LOG.debug("Previous version for publication #"
520 + newVer.getIndex() + " is found: " + prevDoc);
522 List<Relation> usesRelations = prevDoc
523 .getRelations(UsesRelation.class);
524 for (Relation rel : usesRelations) {
525 // If used document has been also versioned then refer to its new version.
526 Document usedDoc = ((UsesRelation) rel).getTo();
527 if (newVersion.containsKey(usedDoc)) {
528 usedDoc = newVersion.get(usedDoc);
530 // Build the appropriate relation for the new version.
531 newVer.addDependency(usedDoc);
533 // TODO: Outdate documents which depend from the previous version and were not checked in during this operation.
537 // For each new document create uses relation to the last versions of
538 // results of the previous step.
539 for (Publication newDoc : newDocs) {
540 // Find used document type according to the configuration.
541 // Find documents of used type in the previous study step.
543 // Create uses relation from the new document
544 // to the found document in the previous step.
545 // newDoc.addDependency(to);
548 // Mark the scenario as checked in
553 * Find appropriate step in the array of scenario steps according to the given step DTO.
559 * @return appropriate scenario step
560 * @throws InvalidPropertyException
561 * if appropriate step is not found
563 private Step findStep(final StepDTO stepDTO, final Step[] steps)
564 throws InvalidPropertyException {
568 if (steps[i].getNumber() == stepDTO.getNumber()) {
572 } while ((step == null) && (i < steps.length));
575 throw new InvalidPropertyException(MessageKeyEnum.SCN_000001
576 .toString(), stepDTO.getNumber());
584 * @see org.splat.service.ScenarioService#checkin(org.splat.dal.bo.som.Scenario)
586 public void checkin(final Scenario aScenario) {
587 aScenario.setUser(null);
588 aScenario.setLastModificationDate(Calendar.getInstance().getTime());
589 getScenarioDAO().update(aScenario);
595 * @see org.splat.service.ScenarioService#checkout(org.splat.dal.bo.som.Scenario, org.splat.dal.bo.kernel.User)
597 public boolean checkout(final Scenario aScenario, final User user) {
598 boolean res = getStudyService().isStaffedBy(aScenario.getOwnerStudy(),
601 aScenario.setUser(user);
602 aScenario.setLastModificationDate(Calendar.getInstance().getTime());
603 getScenarioDAO().update(aScenario);
611 * @see org.splat.service.ScenarioService#copyContentsUpTo(org.splat.dal.bo.som.Scenario, org.splat.som.Step)
613 public void copyContentsUpTo(final Scenario scenario, final Step lastep) {
614 Scenario base = (Scenario) lastep.getOwner();
615 Step[] from = getProjectElementService().getSteps(base);
616 Step[] to = getProjectElementService().getSteps(scenario);
617 for (int i = 0; i < from.length; i++) {
619 if (step.getNumber() > lastep.getNumber()) {
623 List<Publication> docs = step.getAllDocuments();
624 for (Iterator<Publication> j = docs.iterator(); j.hasNext();) {
625 Publication doc = getPublicationService().copy(j.next(),
626 scenario); // Creation of a new reference to the document
627 // Database.getSession().save(doc); Publications MUST be saved later through cascading when saving the scenario
628 getStepService().add(to[i], doc);
630 List<SimulationContext> ctex = step.getAllSimulationContexts();
631 for (Iterator<SimulationContext> j = ctex.iterator(); j.hasNext();) {
632 getStepService().addSimulationContext(to[i], j.next());
640 * @see org.splat.service.ScenarioService#isEmpty(org.splat.dal.bo.som.Scenario)
642 public boolean isEmpty(final Scenario scenario) {
643 Step[] mystep = getProjectElementService().getSteps(scenario);
644 boolean isEmp = true;
645 for (int i = 0; i < mystep.length; i++) {
646 if (mystep[i].isStarted()) {
658 public boolean isFinished(final Scenario scenario) {
659 Step[] mystep = getProjectElementService().getSteps(scenario);
660 boolean notempty = false; // If this is empty, this is not finished
661 for (int i = 0; i < mystep.length; i++) {
662 if (!mystep[i].isStarted()) {
665 if (!mystep[i].isFinished()) {
676 * @see org.splat.service.StudyService#addScenario(org.splat.dal.bo.som.Study, org.splat.dal.bo.som.Scenario.Properties)
679 public Scenario addScenario(final Study aStudy,
680 final Scenario.Properties sprop) throws MissedPropertyException,
681 InvalidPropertyException, MultiplyDefinedException {
682 if (sprop.getManager() == null) {
683 sprop.setManager(aStudy.getAuthor());
686 Scenario scenario = new Scenario(sprop.setOwnerStudy(aStudy));
687 if (sprop.getBaseStep() != null) {
688 copyContentsUpTo(scenario, sprop.getBaseStep());
690 Scenario previous = sprop.getInsertAfter();
692 if (previous == null) {
693 aStudy.getScenariiList().add(scenario);
695 aStudy.getScenariiList().add(
696 aStudy.getScenariiList().indexOf(previous) + 1, scenario);
698 getStudyDAO().update(aStudy); // No need to update the Lucene index
699 getScenarioDAO().create(scenario); // Must be done after updating this study because of the back reference to the study
700 if (sprop.getBaseStep() != null) {
701 // No need to update the Knowledge Element index as Knowledge Elements are not copied
702 getProjectElementService().refresh(scenario); // Because saving the scenario changes the hashcode of copied Publications
704 KnowledgeElementType ucase = getKnowledgeElementTypeService()
705 .selectType("usecase");
706 KnowledgeElement.Properties kprop = new KnowledgeElement.Properties();
707 User admin = getUserService().selectUser(1); // First user created when creating the database
708 kprop.setType(ucase).setTitle(aStudy.getTitle()).setValue(
709 scenario.getTitle()).setAuthor(admin); // Internal Knowledge Element required by the validation process of
711 addKnowledgeElement(scenario, kprop);
716 * Remove a knowledge element from a scenario.
721 * the knowledge element to remove
722 * @return true if removal succeeded
724 public boolean removeKnowledgeElement(final Scenario scenario,
725 final KnowledgeElement kelm) {
726 KnowledgeElement torem = scenario.getKnowledgeElement(kelm.getIndex());
730 boolean done = scenario.getKnowledgeElements().remove(torem);
732 // Update of my transient data
733 // RKV: These transient data are not used indeed.
734 // RKV: List<KnowledgeElement> kelms = scenario.getKnowledgeByType().get(
735 // RKV: kelm.getType().getIndex());
736 // RKV: kelms.remove(torem);
737 if (scenario.getKnowledgeElementsList() != null) {
738 scenario.getKnowledgeElementsList().remove(torem);
740 getScenarioDAO().update(scenario);
741 // TODO: If the owner study is not private, remove the knowledge from the Lucene index
749 * Get the knowledgeElementDAO.
751 * @return the knowledgeElementDAO
753 public KnowledgeElementDAO getKnowledgeElementDAO() {
754 return _knowledgeElementDAO;
758 * Set the knowledgeElementDAO.
760 * @param knowledgeElementDAO
761 * the knowledgeElementDAO to set
763 public void setKnowledgeElementDAO(
764 final KnowledgeElementDAO knowledgeElementDAO) {
765 _knowledgeElementDAO = knowledgeElementDAO;
769 * Get the indexService.
771 * @return the indexService
773 public IndexService getIndexService() {
774 return _indexService;
778 * Set the indexService.
780 * @param indexService
781 * the indexService to set
783 public void setIndexService(final IndexService indexService) {
784 _indexService = indexService;
788 * Get the scenarioDAO.
790 * @return the scenarioDAO
792 public ScenarioDAO getScenarioDAO() {
797 * Set the scenarioDAO.
800 * the scenarioDAO to set
802 public void setScenarioDAO(final ScenarioDAO scenarioDAO) {
803 _scenarioDAO = scenarioDAO;
809 * @return the studyDAO
811 public StudyDAO getStudyDAO() {
819 * the studyDAO to set
821 public void setStudyDAO(final StudyDAO studyDAO) {
822 _studyDAO = studyDAO;
826 * Get the knowledgeElementTypeService.
828 * @return the knowledgeElementTypeService
830 public KnowledgeElementTypeService getKnowledgeElementTypeService() {
831 return _knowledgeElementTypeService;
835 * Set the knowledgeElementTypeService.
837 * @param knowledgeElementTypeService
838 * the knowledgeElementTypeService to set
840 public void setKnowledgeElementTypeService(
841 final KnowledgeElementTypeService knowledgeElementTypeService) {
842 _knowledgeElementTypeService = knowledgeElementTypeService;
846 * Get the studyService.
848 * @return the studyService
850 public StudyService getStudyService() {
851 return _studyService;
855 * Set the studyService.
857 * @param studyService
858 * the studyService to set
860 public void setStudyService(final StudyService studyService) {
861 _studyService = studyService;
865 * Get the userService.
867 * @return the userService
869 public UserService getUserService() {
874 * Set the userService.
877 * the userService to set
879 public void setUserService(final UserService userService) {
880 _userService = userService;
886 * @return the userDAO
888 public UserDAO getUserDAO() {
898 public void setUserDAO(final UserDAO userDAO) {
903 * Get the knowledgeElementTypeDAO.
905 * @return the knowledgeElementTypeDAO
907 public KnowledgeElementTypeDAO getKnowledgeElementTypeDAO() {
908 return _knowledgeElementTypeDAO;
912 * Set the knowledgeElementTypeDAO.
914 * @param knowledgeElementTypeDAO
915 * the knowledgeElementTypeDAO to set
917 public void setKnowledgeElementTypeDAO(
918 final KnowledgeElementTypeDAO knowledgeElementTypeDAO) {
919 _knowledgeElementTypeDAO = knowledgeElementTypeDAO;
923 * Get the simulationContextService.
925 * @return the simulationContextService
927 public SimulationContextService getSimulationContextService() {
928 return _simulationContextService;
932 * Set the simulationContextService.
934 * @param simulationContextService
935 * the simulationContextService to set
937 public void setSimulationContextService(
938 final SimulationContextService simulationContextService) {
939 _simulationContextService = simulationContextService;
943 * Get project settings.
945 * @return Project settings service
947 private ProjectSettingsService getProjectSettings() {
948 return _projectSettings;
952 * Set project settings service.
954 * @param projectSettingsService
955 * project settings service
957 public void setProjectSettings(
958 final ProjectSettingsService projectSettingsService) {
959 _projectSettings = projectSettingsService;
963 * Get the documentTypeService.
965 * @return the documentTypeService
967 public DocumentTypeService getDocumentTypeService() {
968 return _documentTypeService;
972 * Set the documentTypeService.
974 * @param documentTypeService
975 * the documentTypeService to set
977 public void setDocumentTypeService(
978 final DocumentTypeService documentTypeService) {
979 _documentTypeService = documentTypeService;