1 /*****************************************************************************
5 * Creation date 06.10.2012
8 *****************************************************************************/
10 package org.splat.service;
13 import java.io.FileNotFoundException;
14 import java.io.IOException;
15 import java.text.ParseException;
16 import java.util.ArrayList;
17 import java.util.Date;
18 import java.util.HashSet;
19 import java.util.Iterator;
20 import java.util.List;
22 import org.apache.log4j.Logger;
23 import org.splat.common.properties.MessageKeyEnum;
24 import org.splat.dal.bo.kernel.User;
25 import org.splat.dal.bo.som.ConvertsRelation;
26 import org.splat.dal.bo.som.Document;
27 import org.splat.dal.bo.som.DocumentType;
28 import org.splat.dal.bo.som.ProgressState;
29 import org.splat.dal.bo.som.ProjectElement;
30 import org.splat.dal.bo.som.Publication;
31 import org.splat.dal.bo.som.SimulationContext;
32 import org.splat.dal.bo.som.SimulationContextType;
33 import org.splat.dal.bo.som.Study;
34 import org.splat.dal.bo.som.Timestamp;
35 import org.splat.dal.bo.som.UsedByRelation;
36 import org.splat.dal.bo.som.ValidationCycle;
37 import org.splat.dal.bo.som.ValidationStep;
38 import org.splat.dal.dao.som.ProjectElementDAO;
39 import org.splat.dal.dao.som.PublicationDAO;
40 import org.splat.dal.dao.som.TimestampDAO;
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.manox.Reader;
47 import org.splat.manox.Toolbox;
48 import org.splat.service.technical.RepositoryService;
49 import org.splat.som.DocumentRights;
50 import org.splat.som.Revision;
51 import org.splat.som.Step;
52 import org.springframework.transaction.annotation.Transactional;
55 * Publication service implementation.
57 * @author <a href="mailto:roman.kozlov@opencascade.com">Roman Kozlov (RKV)</a>
59 public class PublicationServiceImpl implements PublicationService {
62 * Logger for this class.
64 protected final static Logger LOG = Logger
65 .getLogger(PublicationServiceImpl.class);
68 * Injected study service.
70 private StudyService _studyService;
72 * Injected step service.
74 private StepService _stepService;
76 * Injected document service.
78 private DocumentService _documentService;
80 * Injected document type service.
82 private DocumentTypeService _documentTypeService;
84 * Injected user service.
86 private UserService _userService;
88 * Injected project element service.
90 private ProjectElementService _projectElementService;
92 * Injected simulation context service.
94 private SimulationContextService _simulationContextService;
96 * Injected publication DAO.
98 private PublicationDAO _publicationDAO;
100 * Injected timestamp DAO.
102 private TimestampDAO _timestampDAO;
104 * Injected project element DAO.
106 private ProjectElementDAO _projectElementDAO;
108 * Injected repository service.
110 private RepositoryService _repositoryService;
115 * @see org.splat.service.PublicationService#copy(org.splat.dal.bo.som.Publication, org.splat.dal.bo.som.ProjectElement)
117 public Publication copy(final Publication aPublication,
118 final ProjectElement publisher) {
119 Publication copy = new Publication();
120 copy.setValue(aPublication.value());
121 copy.setStep(aPublication.getStep()); // May not be initialized yet
122 copy.setOwner(publisher);
123 copy.setIsnew(aPublication.getIsnew());
124 if (!copy.getOwnerStudy().equals(aPublication.getOwnerStudy())) {
125 copy.setIsnew('N'); // The referenced document is not new for the given study
133 * @see org.splat.service.PublicationService#createDoc(long, org.splat.som.Step, long, long, java.lang.String, java.lang.String,
134 * org.splat.dal.bo.som.ProgressState, java.lang.String, java.lang.String, java.util.Date, java.util.List)
137 public Publication createDoc(final long ownerId, final Step step,
138 final long documentTypeId, final long userId, final String fname,
139 final String doctitle, final ProgressState docstate,
140 final String reference, final String version, final Date docDate,
141 final List<Long> docuses) throws MissedPropertyException,
142 InvalidPropertyException, MultiplyDefinedException, IOException,
143 NotApplicableException, InterruptedException, ParseException {
144 DocumentType type = getDocumentTypeService().selectType(
145 (int) documentTypeId);
146 User user = getUserService().selectUser(userId);
147 File updir = getRepositoryService().getDownloadDirectory(user);
148 File upfile = new File(updir.getPath() + "/" + fname);
149 String[] table = fname.split("\\x2E");
151 // Creation of the document
152 Document.Properties dprop = new Document.Properties();
153 dprop.setLocalPath(upfile.getPath());
156 if (reference.length() == 0) { // Importation of a foreign document
157 // TODO: Extract property of supported documents (DOCX, ODT...)
158 addoc = getStepService().createDocument(
160 dprop.setName(doctitle).setType(type).setFormat(
161 table[table.length - 1]).setAuthor(user));
162 updir = addoc.getSourceFile().asFile();
163 if (LOG.isInfoEnabled()) {
164 LOG.info("Moving \"" + upfile.getAbsolutePath() + "\" to \""
165 + updir.getPath() + "\".");
167 upfile.renameTo(updir);
169 saveAs(addoc, docstate); // May throw FileNotFound if rename was not done
170 } catch (FileNotFoundException saverror) {
172 LOG.info("Waiting for the file.");
173 upfile.renameTo(updir);
174 saveAs(addoc, docstate); // Forget it if throw again FileNotFound
176 } else { // Importation of a previously created template-based document
177 if (docDate != null) {
178 dprop.setDate(docDate);
180 addoc = getStepService().assignDocument(step,
181 dprop.setReference(reference).setName(doctitle));
182 updir = addoc.getSourceFile().asFile();
183 if (LOG.isInfoEnabled()) {
184 LOG.info("Moving \"" + upfile.getName() + "\" to \""
185 + updir.getPath() + "\".");
187 upfile.renameTo(updir);
189 if (version.length() > 0) {
190 saveAs(addoc, new Revision(version));
192 saveAs(addoc, docstate);
194 } catch (FileNotFoundException saverror) {
196 LOG.info("Waiting for the file.");
197 upfile.renameTo(updir);
198 if (version.length() > 0) {
199 saveAs(addoc, new Revision(version));
201 saveAs(addoc, docstate);
205 // Creation of uses relations
206 if (docuses != null) {
207 for (Long index : docuses) {
208 Document used = getDocumentService().selectDocument(index);
209 addoc.addDependency(used);
218 * @see org.splat.service.PublicationService#versionDocument(org.splat.som.Step, org.splat.dal.bo.kernel.User, java.lang.String, long,
219 * java.lang.String, java.lang.String, org.splat.dal.bo.som.ProgressState, java.util.Date, java.lang.String[], long[])
222 public void versionDocument(final Step step, final User user,
223 final String filename, final long docIndex, final String docver,
224 final String summary, final ProgressState state, final Date date,
225 final String[] docuses, final long[] docusedby)
226 throws MissedPropertyException, InvalidPropertyException,
227 MultiplyDefinedException, IOException, MismatchException,
228 NotApplicableException, InterruptedException {
229 File updir = getRepositoryService().getDownloadDirectory(user);
230 File upfile = new File(updir.getPath() + "/" + filename);
232 // Versioning of the document
233 Document.Properties dprop = new Document.Properties();
234 dprop.setLocalPath(upfile.getPath());
235 Publication current = step.getDocument(docIndex);
238 if ((docver.length() != 0) && // Importation of a not foreign document
242 if ((summary != null) && (summary.length() > 0)) {
243 dprop.setDescription(summary);
245 next = getStepService().versionDocument(step, current,
246 dprop.setAuthor(user));
247 updir = next.getSourceFile().asFile();
248 if (LOG.isInfoEnabled()) {
249 LOG.info("Moving \"" + upfile.getName() + "\" to \""
250 + updir.getPath() + "\".");
252 upfile.renameTo(updir);
255 if (docver.length() == 0) { // Importation of a foreign document
256 saveAs(next, state); // May throw FileNotFound if rename was not done
258 saveAs(next, new Revision(docver));
260 } catch (FileNotFoundException saverror) {
262 LOG.info("Waiting for the file.");
263 upfile.renameTo(updir);
266 // TODO: Remove current document details from the contents of open study
268 // Creation of uses relations
269 updateRelations(current, next, docuses, docusedby);
273 * Update relations after creation of a new document version.
276 * the current version
280 * ids of used documents
282 * ids of documents used by the versioned one.
284 private void updateRelations(final Publication current,
285 final Publication next, final String[] docuses,
286 final long[] docusedby) {
287 if (docuses != null) {
288 for (int i = 0; i < docuses.length; i++) {
289 Long index = Long.valueOf(docuses[i].trim());
290 Document used = getDocumentService().selectDocument(index);// RKV: getPublication(index, steps);
291 next.addDependency(used);
294 // Outdating impacted document
295 HashSet<Long> compatible = new HashSet<Long>();
296 if (docusedby != null) {
297 for (int i = 0; i < docusedby.length; i++) {
298 compatible.add(docusedby[i]);
301 List<Publication> relist = current.getRelations(UsedByRelation.class);
302 for (Iterator<Publication> i = relist.iterator(); i.hasNext();) {
303 Publication using = i.next();
304 if (!compatible.contains(using.getIndex())) {
311 * protected Publication getPublication(int index, List<Step> steps) { for (Iterator<Step> i = steps.iterator(); i.hasNext();) { List<Publication>
312 * published = i.next().getAllDocuments(); for (Iterator<Publication> j = published.iterator(); j.hasNext();) { Publication found =
313 * j.next(); // In a given study step, if (found.value().getIndex() == index) return found; // there is only one publication of a given
314 * document } } return null; }
319 * @see org.splat.service.PublicationService#approve(org.splat.dal.bo.som.Publication, java.util.Date)
322 public Timestamp approve(final Publication aPublication, final Date adate) {
323 Timestamp res = null;
324 if (!(aPublication.isOutdated() || (aPublication.value()
325 .getProgressState() != ProgressState.inCHECK))) {
326 DocumentType type = aPublication.value().getType();
327 Study owner = aPublication.getOwnerStudy();
328 ValidationCycle cycle = getStudyService().getValidationCycleOf(
330 User approver = cycle.getActor(ValidationStep.APPROVAL);
331 Timestamp stamp = new Timestamp(ValidationStep.APPROVAL,
332 aPublication.value(), approver, adate);
333 getTimestampDAO().create(stamp);
335 if (getDocumentService().promote(aPublication.value(), stamp)) {
337 if (getDocumentService().isStudyResult(type)
338 && owner.getProgressState() == ProgressState.inCHECK) {
339 getStudyService().promote(owner);
343 return res; // Hoping that promotion of the study succeeded
349 * @see org.splat.service.PublicationService#demote(org.splat.dal.bo.som.Publication)
352 public boolean demote(final Publication aPublication) {
354 DocumentType type = aPublication.value().getType();
355 Study owner = aPublication.getOwnerStudy();
357 if (aPublication.value().getProgressState() == ProgressState.inCHECK) {
358 ValidationCycle cycle = getStudyService().getValidationCycleOf(
360 if (cycle.enables(ValidationStep.REVIEW)) {
361 res = getDocumentService().demote(aPublication.value());
363 res = getDocumentService().demote(aPublication.value());
365 getDocumentService().demote(aPublication.value());
368 } else if (aPublication.value().getProgressState() == ProgressState.inDRAFT) {
369 res = getDocumentService().demote(aPublication.value());
371 if (res && getDocumentService().isStudyResult(type)
372 && owner.getProgressState() != ProgressState.inWORK) {
373 getStudyService().demote(owner);
381 * @see org.splat.service.PublicationService#invalidate(org.splat.dal.bo.som.Publication)
384 public boolean invalidate(final Publication aPublication) {
386 if ((aPublication.value().getProgressState() == ProgressState.inCHECK)) {
387 DocumentType type = aPublication.value().getType();
388 Study owner = aPublication.getOwnerStudy();
390 ValidationCycle cycle = getStudyService().getValidationCycleOf(
392 // Check if the validation cycle allows the review step
393 if (cycle.enables(ValidationStep.REVIEW)) {
394 if (getDocumentService().demote(aPublication.value())
395 && getDocumentService().isStudyResult(type)
396 && owner.getProgressState() == ProgressState.inCHECK) {
397 getStudyService().demote(owner);
400 } else { // If the validation cycle has no inDraft step
401 res = demote(aPublication);
410 * @see org.splat.service.PublicationService#promote(org.splat.dal.bo.som.Publication, java.util.Date)
413 public Timestamp promote(final Publication aPublication, final Date pdate) {
414 Timestamp res = null;
415 if ((!aPublication.isOutdated())
416 && (aPublication.value().getProgressState() == ProgressState.inWORK)) {
417 DocumentType type = aPublication.value().getType();
418 Study owner = aPublication.getOwnerStudy();
419 ValidationCycle cycle = getStudyService().getValidationCycleOf(
421 User promoter = cycle.getActor(ValidationStep.PROMOTION);
422 if (promoter == null) {
423 promoter = getInvolvedStep(aPublication).getActor();
425 if (promoter == null) {
426 promoter = owner.getAuthor();
428 Timestamp stamp = new Timestamp(ValidationStep.PROMOTION,
429 aPublication.value(), promoter, pdate);
430 getTimestampDAO().create(stamp);
432 if (getDocumentService().promote(aPublication.value(), stamp)) {
434 if (!cycle.enables(ValidationStep.REVIEW)) {
435 getDocumentService().promote(aPublication.value(), null);
437 if (getDocumentService().isStudyResult(type)
438 && owner.getProgressState() == ProgressState.inWORK) {
439 getStudyService().promote(owner);
443 return res; // Hoping that promotion of the study succeeded
449 * @see org.splat.service.PublicationService#review(org.splat.dal.bo.som.Publication, java.util.Date)
452 public Timestamp review(final Publication aPublication, final Date rdate) {
453 Timestamp res = null;
454 if (!aPublication.isOutdated()
455 && !(aPublication.value().getProgressState() != ProgressState.inDRAFT)) {
457 DocumentType type = aPublication.value().getType();
458 Study owner = aPublication.getOwnerStudy();
459 ValidationCycle cycle = getStudyService().getValidationCycleOf(
461 User reviewer = cycle.getActor(ValidationStep.REVIEW);
462 Timestamp stamp = new Timestamp(ValidationStep.REVIEW, aPublication
463 .value(), reviewer, rdate);
464 getTimestampDAO().create(stamp);
466 if (getDocumentService().promote(aPublication.value(), stamp)) {
468 if (getDocumentService().isStudyResult(type)
469 && owner.getProgressState() == ProgressState.inDRAFT) {
470 getStudyService().promote(owner);
474 return res; // Hoping that promotion of the study succeeded
480 * @see org.splat.service.PublicationService#saveAs(org.splat.dal.bo.som.Publication, org.splat.som.Revision)
485 public void saveAs(final Publication aPublication, final Revision newvers)
486 throws FileNotFoundException, NotApplicableException {
487 if (aPublication.value().isUndefined()) {
488 throw new NotApplicableException(
489 "Cannot save a Publication object refering an undefined Document");
491 if (!aPublication.value().getSourceFile().exists()) {
492 throw new FileNotFoundException();
495 getPublicationDAO().create(aPublication); // Must be done before updating the study in order to fix this final (rid-based) hascode
496 getDocumentService().updateAs(aPublication.value(), newvers); // May change the branch name of given revision
497 updateOwner(aPublication);
503 * @see org.splat.service.PublicationService#saveAs(org.splat.dal.bo.som.Publication, org.splat.dal.bo.som.ProgressState)
506 public void saveAs(final Publication aPublication, final ProgressState state)
507 throws FileNotFoundException, NotApplicableException {
508 if (aPublication.value().isUndefined()) {
509 throw new NotApplicableException(
510 "Cannot save a Publication object refering an undefined Document");
512 if (!aPublication.value().getSourceFile().exists()) {
513 throw new FileNotFoundException(aPublication.value()
514 .getSourceFile().asFile().getAbsolutePath());
517 if (state == ProgressState.inWORK || state == ProgressState.EXTERN) {
518 getPublicationDAO().create(aPublication); // Must be done before updating the study in order to fix this final (rid-based)
520 getDocumentService().updateAs(aPublication.value(), state);
522 // Check that the state is applicable for the validation cycle
523 DocumentType mytype = aPublication.value().getType();
524 Study owner = aPublication.getOwnerStudy();
525 ValidationCycle cycle = getStudyService().getValidationCycleOf(
527 boolean review = cycle.enables(ValidationStep.REVIEW);
528 if (!(state == ProgressState.inDRAFT && review)
529 && !(state == ProgressState.inCHECK && !review)) {
530 throw new NotApplicableException(MessageKeyEnum.DCT_000003
531 .toString(), state.toString());
533 getPublicationDAO().create(aPublication); // Must be done before updating the study in order to fix this final (rid-based)
535 getDocumentService().updateAs(aPublication.value(),
536 ProgressState.inWORK);
538 promote(aPublication, aPublication.value()
539 .getLastModificationDate()); // Promotes to the appropriate state in accordance to the validation cycle
541 updateOwner(aPublication);
545 * Update an owner of the publication.
547 * @param aPublication
548 * the document publication
551 private void updateOwner(final Publication aPublication) {
552 Step step = getInvolvedStep(aPublication);
554 // Update of involved step
555 Document previous = aPublication.value().getPreviousVersion();
556 if (previous != null) {
557 Publication oldoc = step.getDocument(previous.getIndex());
558 getStepService().remove(step, oldoc); // Decrements the configuration tag count of document
560 getStepService().add(step, aPublication); // Increments the configuration tag count of document
562 // Import the document properties and update of the study
563 forwardProperties(aPublication, aPublication.value().getSourceFile()
565 getProjectElementDAO().merge(aPublication.getOwner());
569 * Propagate simulation contexts from the given config file to the publication's owner (study or step).
571 * @param aPublication
572 * the document publication
578 private void forwardProperties(final Publication aPublication,
579 final java.io.File from, final Step to) {
580 Reader tool = Toolbox.getReader(from);
581 if (tool != null) { // Properties extractor available for this type of document
582 SimulationContextType.Properties sprop = new SimulationContextType.Properties()
583 .setStep(to.getStep()).setProgressState(
584 ProgressState.APPROVED);
585 List<SimulationContextType> contype = getSimulationContextService()
586 .selectTypesWhere(sprop);
587 if (!contype.isEmpty()) { // There is an approved property type configured at this step
589 SimulationContext.Properties cprop = new SimulationContext.Properties();
590 List<SimulationContext> context = to.getAllSimulationContexts();
592 context = new ArrayList<SimulationContext>(context.size());
593 context.addAll(to.getAllSimulationContexts());
594 cprop.disableCheck();
595 for (Iterator<SimulationContextType> i = contype.iterator(); i
597 SimulationContextType property = i.next();
598 boolean isFound = false;
599 for (Iterator<SimulationContext> j = context.iterator(); j
601 SimulationContext existing = j.next();
602 isFound = existing.getType().equals(property);
604 // Forget this property as it is already set
610 String value = tool.extractProperty(property
613 continue; // Property not defined into the document
616 cprop.setType(property).setValue(value);
617 if (aPublication.getOwner() instanceof Study) {
618 getStudyService().addProjectContext(
619 (Study) aPublication.getOwner(), cprop); // Re-indexes knowledges and the study
622 .addSimulationContext(to, cprop); // Re-indexes knowledges only
624 } catch (Exception e) {
634 * Returns the study Step into which the document version referenced by this publication has been published.
636 * @param aPublication
637 * the document publication
638 * @return the study step where the document is published
640 public Step getInvolvedStep(final Publication aPublication) {
641 if (aPublication.getStep() == null) {
642 Step[] step = getProjectElementService().getSteps(
643 aPublication.getOwner());
644 for (int i = 0; i < step.length; i++) {
645 aPublication.setStep(step[i]); // The involved step necessarily exists
646 if (aPublication.value().isInto(aPublication.getStep())) {
651 return aPublication.getStep();
655 * Undo the out-date operation.
657 * @param aPublication
659 * @return true if the acceptance succeeds
661 * @see DocumentRights#canAccept()
664 public boolean actualize(final Publication aPublication) {
665 boolean res = aPublication.isOutdated();
667 aPublication.setIsnew('Y');
668 getPublicationDAO().update(aPublication);
674 * Out-dates this publication and recursively all publications using this one. Typically, a publication is out-dated when modifying a
675 * document to which it depends.
677 * @param aPublication
680 * @see #getProgressState()
683 public void outdate(final Publication aPublication) {
684 if (aPublication.isOutdated()) {
688 List<Publication> relist = aPublication
689 .getRelations(UsedByRelation.class);
690 for (Iterator<Publication> i = relist.iterator(); i.hasNext();) {
693 aPublication.setIsnew('O');
694 getPublicationDAO().update(aPublication);
698 * Create "Converts" relation for the given document publication and format.
700 * @param aPublication
701 * the document publication
704 * @return the created "Converts" relation
707 public ConvertsRelation attach(final Publication aPublication,
708 final String format) {
709 return getDocumentService().attach(aPublication.value(), format);
713 * Create "Converts" relation for the given document publication, format and description.
715 * @param aPublication
716 * the document publication
720 * the description of the relation
721 * @return the created "Converts" relation
724 public ConvertsRelation attach(final Publication aPublication,
725 final String format, final String description) {
726 return getDocumentService().attach(aPublication.value(), format,
731 * Rename the published document.
733 * @param aPublication
734 * the publication of the document
736 * the new document title
737 * @throws InvalidPropertyException
738 * if the new title is empty
740 public void rename(final Publication aPublication, final String title)
741 throws InvalidPropertyException {
742 getDocumentService().rename(aPublication.value(), title);
746 * Get the projectElementService.
748 * @return the projectElementService
750 public ProjectElementService getProjectElementService() {
751 return _projectElementService;
755 * Set the projectElementService.
757 * @param projectElementService
758 * the projectElementService to set
760 public void setProjectElementService(
761 final ProjectElementService projectElementService) {
762 _projectElementService = projectElementService;
766 * Get the simulationContextService.
768 * @return the simulationContextService
770 public SimulationContextService getSimulationContextService() {
771 return _simulationContextService;
775 * Set the simulationContextService.
777 * @param simulationContextService
778 * the simulationContextService to set
780 public void setSimulationContextService(
781 final SimulationContextService simulationContextService) {
782 _simulationContextService = simulationContextService;
786 * Get the studyService.
788 * @return the studyService
790 public StudyService getStudyService() {
791 return _studyService;
795 * Set the studyService.
797 * @param studyService
798 * the studyService to set
800 public void setStudyService(final StudyService studyService) {
801 _studyService = studyService;
805 * Get the stepService.
807 * @return the stepService
809 public StepService getStepService() {
814 * Set the stepService.
817 * the stepService to set
819 public void setStepService(final StepService stepService) {
820 _stepService = stepService;
824 * Get the documentService.
826 * @return the documentService
828 public DocumentService getDocumentService() {
829 return _documentService;
833 * Set the documentService.
835 * @param documentService
836 * the documentService to set
838 public void setDocumentService(final DocumentService documentService) {
839 _documentService = documentService;
843 * Get the publicationDAO.
845 * @return the publicationDAO
847 public PublicationDAO getPublicationDAO() {
848 return _publicationDAO;
852 * Set the publicationDAO.
854 * @param publicationDAO
855 * the publicationDAO to set
857 public void setPublicationDAO(final PublicationDAO publicationDAO) {
858 _publicationDAO = publicationDAO;
862 * Get the projectElementDAO.
864 * @return the projectElementDAO
866 public ProjectElementDAO getProjectElementDAO() {
867 return _projectElementDAO;
871 * Set the projectElementDAO.
873 * @param projectElementDAO
874 * the projectElementDAO to set
876 public void setProjectElementDAO(final ProjectElementDAO projectElementDAO) {
877 _projectElementDAO = projectElementDAO;
881 * Get the repositoryService.
883 * @return the repositoryService
885 public RepositoryService getRepositoryService() {
886 return _repositoryService;
890 * Set the repositoryService.
892 * @param repositoryService
893 * the repositoryService to set
895 public void setRepositoryService(final RepositoryService repositoryService) {
896 _repositoryService = repositoryService;
900 * Get the timestampDAO.
902 * @return the timestampDAO
904 public TimestampDAO getTimestampDAO() {
905 return _timestampDAO;
909 * Set the timestampDAO.
911 * @param timestampDAO
912 * the timestampDAO to set
914 public void setTimestampDAO(final TimestampDAO timestampDAO) {
915 _timestampDAO = timestampDAO;
919 * Get the documentTypeService.
921 * @return the documentTypeService
923 public DocumentTypeService getDocumentTypeService() {
924 return _documentTypeService;
928 * Set the documentTypeService.
930 * @param documentTypeService
931 * the documentTypeService to set
933 public void setDocumentTypeService(
934 final DocumentTypeService documentTypeService) {
935 _documentTypeService = documentTypeService;
939 * Get the userService.
941 * @return the userService
943 public UserService getUserService() {
948 * Set the userService.
951 * the userService to set
953 public void setUserService(final UserService userService) {
954 _userService = userService;