Salome HOME
More business logic has been moved from BO to services. ServiceLocator is created...
[tools/siman.git] / Workspace / Siman-Common / src / org / splat / service / PublicationServiceImpl.java
1 /*****************************************************************************
2  * Company         OPEN CASCADE
3  * Application     SIMAN
4  * File            $Id$ 
5  * Creation date   06.10.2012
6  * @author         $Author$
7  * @version        $Revision$
8  *****************************************************************************/
9
10 package org.splat.service;
11
12 import java.io.FileNotFoundException;
13 import java.util.ArrayList;
14 import java.util.Date;
15 import java.util.Iterator;
16 import java.util.List;
17
18 import org.splat.dal.bo.kernel.User;
19 import org.splat.dal.bo.som.ConvertsRelation;
20 import org.splat.dal.bo.som.Document;
21 import org.splat.dal.bo.som.DocumentType;
22 import org.splat.dal.bo.som.ProgressState;
23 import org.splat.dal.bo.som.ProjectElement;
24 import org.splat.dal.bo.som.Publication;
25 import org.splat.dal.bo.som.SimulationContext;
26 import org.splat.dal.bo.som.SimulationContextType;
27 import org.splat.dal.bo.som.Study;
28 import org.splat.dal.bo.som.Timestamp;
29 import org.splat.dal.bo.som.ValidationCycle;
30 import org.splat.dal.bo.som.ValidationStep;
31 import org.splat.dal.dao.som.ProjectElementDAO;
32 import org.splat.dal.dao.som.PublicationDAO;
33 import org.splat.kernel.InvalidPropertyException;
34 import org.splat.kernel.NotApplicableException;
35 import org.splat.manox.Reader;
36 import org.splat.manox.Toolbox;
37 import org.splat.som.Revision;
38 import org.splat.som.Step;
39 import org.springframework.transaction.annotation.Transactional;
40
41 /**
42  * Publication service implementation.
43  * 
44  * @author <a href="mailto:roman.kozlov@opencascade.com">Roman Kozlov (RKV)</a>
45  */
46 public class PublicationServiceImpl implements PublicationService {
47
48         /**
49          * Injected study service.
50          */
51         private StudyService _studyService;
52         /**
53          * Injected step service.
54          */
55         private StepService _stepService;
56         /**
57          * Injected document service.
58          */
59         private DocumentService _documentService;
60         /**
61          * Injected project element service.
62          */
63         private ProjectElementService _projectElementService;
64         /**
65          * Injected simulation context service.
66          */
67         private SimulationContextService _simulationContextService;
68         /**
69          * Injected publication DAO.
70          */
71         private PublicationDAO _publicationDAO;
72         /**
73          * Injected project element DAO.
74          */
75         private ProjectElementDAO _projectElementDAO;
76
77         /**
78          * {@inheritDoc}
79          * 
80          * @see org.splat.service.PublicationService#copy(org.splat.dal.bo.som.Publication, org.splat.dal.bo.som.ProjectElement)
81          */
82         public Publication copy(Publication aPublication, ProjectElement publisher) {
83                 Publication copy = new Publication();
84                 copy.setValue(aPublication.value());
85                 copy.setStep(aPublication.getStep()); // May not be initialized yet
86                 copy.setOwner(publisher);
87                 copy.setIsnew(aPublication.getIsnew());
88                 if (!copy.getOwnerStudy().equals(aPublication.getOwnerStudy())) {
89                         copy.setIsnew('N'); // The referenced document is not new for the given study
90                 }
91                 return copy;
92         }
93
94         /**
95          * {@inheritDoc}
96          * 
97          * @see org.splat.service.PublicationService#approve(org.splat.dal.bo.som.Publication, java.util.Date)
98          */
99         public Timestamp approve(Publication aPublication, Date adate) {
100                 if (aPublication.isOutdated())
101                         return null;
102                 else if (aPublication.value().getProgressState() != ProgressState.inCHECK)
103                         return null; // This statement must conform to the corresponding right
104
105                 DocumentType type = aPublication.value().getType();
106                 Study owner = aPublication.getOwnerStudy();
107                 ValidationCycle cycle = getStudyService().getValidationCycleOf(owner,
108                                 type);
109                 User approver = cycle.getActor(ValidationStep.APPROVAL);
110                 Timestamp stamp = new Timestamp(ValidationStep.APPROVAL, aPublication
111                                 .value(), approver, adate);
112                 if (!getDocumentService().promote(aPublication.value(), stamp))
113                         return null;
114                 if (getDocumentService().isStudyResult(type)
115                                 && owner.getProgressState() == ProgressState.inCHECK)
116                         getStudyService().promote(owner);
117                 return stamp; // Hoping that promotion of the study succeeded
118         }
119
120         /**
121          * {@inheritDoc}
122          * 
123          * @see org.splat.service.PublicationService#demote(org.splat.dal.bo.som.Publication)
124          */
125         public boolean demote(Publication aPublication) {
126                 DocumentType type = aPublication.value().getType();
127                 Study owner = aPublication.getOwnerStudy();
128
129                 if (aPublication.value().getProgressState() == ProgressState.inCHECK) {
130                         ValidationCycle cycle = getStudyService().getValidationCycleOf(
131                                         owner, type);
132                         if (cycle.enables(ValidationStep.REVIEW)) {
133                                 if (!getDocumentService().demote(aPublication.value()))
134                                         return false;
135                         } else {
136                                 if (!getDocumentService().demote(aPublication.value()))
137                                         return false;
138                                 getDocumentService().demote(aPublication.value());
139                         }
140                 } else if (aPublication.value().getProgressState() == ProgressState.inDRAFT) {
141                         if (!getDocumentService().demote(aPublication.value()))
142                                 return false;
143                 } else {
144                         return false;
145                 }
146                 if (getDocumentService().isStudyResult(type)
147                                 && owner.getProgressState() != ProgressState.inWORK)
148                         getStudyService().demote(owner);
149                 return true;
150         }
151
152         /**
153          * {@inheritDoc}
154          * 
155          * @see org.splat.service.PublicationService#invalidate(org.splat.dal.bo.som.Publication)
156          */
157         public boolean invalidate(Publication aPublication) {
158                 if (aPublication.value().getProgressState() != ProgressState.inCHECK)
159                         return false;
160                 if (!getDocumentService().demote(aPublication.value())) // Removes the reviewer if this document is In-Check
161                         return false;
162                 DocumentType type = aPublication.value().getType();
163                 Study owner = aPublication.getOwnerStudy();
164                 if (getDocumentService().isStudyResult(type)
165                                 && owner.getProgressState() == ProgressState.inCHECK)
166                         getStudyService().demote(owner);
167                 return true;
168         }
169
170         /**
171          * {@inheritDoc}
172          * 
173          * @see org.splat.service.PublicationService#promote(org.splat.dal.bo.som.Publication, java.util.Date)
174          */
175         public Timestamp promote(Publication aPublication, Date pdate) {
176                 if (aPublication.isOutdated())
177                         return null;
178                 else if (aPublication.value().getProgressState() != ProgressState.inWORK)
179                         return null; // This statement must conform to the corresponding right
180                 else {
181                         DocumentType type = aPublication.value().getType();
182                         Study owner = aPublication.getOwnerStudy();
183                         ValidationCycle cycle = getStudyService().getValidationCycleOf(
184                                         owner, type);
185                         User promoter = cycle.getActor(ValidationStep.PROMOTION);
186                         if (promoter == null)
187                                 promoter = getInvolvedStep(aPublication).getActor();
188                         if (promoter == null)
189                                 promoter = owner.getAuthor();
190                         Timestamp stamp = new Timestamp(ValidationStep.PROMOTION,
191                                         aPublication.value(), promoter, pdate);
192
193                         if (!getDocumentService().promote(aPublication.value(), stamp)) // Promotion to being reviewed
194                                 return null;
195                         if (!cycle.enables(ValidationStep.REVIEW)) {
196                                 getDocumentService().promote(aPublication.value(), null);
197                         }
198                         if (getDocumentService().isStudyResult(type)
199                                         && owner.getProgressState() == ProgressState.inWORK)
200                                 getStudyService().promote(owner);
201                         return stamp; // Hoping that promotion of the study succeeded
202                 }
203         }
204
205         /**
206          * {@inheritDoc}
207          * 
208          * @see org.splat.service.PublicationService#review(org.splat.dal.bo.som.Publication, java.util.Date)
209          */
210         public Timestamp review(Publication aPublication, Date rdate) {
211                 if (aPublication.isOutdated())
212                         return null;
213                 else if (aPublication.value().getProgressState() != ProgressState.inDRAFT)
214                         return null; // This statement must conform to the corresponding right
215
216                 DocumentType type = aPublication.value().getType();
217                 Study owner = aPublication.getOwnerStudy();
218                 ValidationCycle cycle = getStudyService().getValidationCycleOf(owner,
219                                 type);
220                 User reviewer = cycle.getActor(ValidationStep.REVIEW);
221                 Timestamp stamp = new Timestamp(ValidationStep.REVIEW, aPublication
222                                 .value(), reviewer, rdate);
223                 if (!getDocumentService().promote(aPublication.value(), stamp))
224                         return null;
225                 if (getDocumentService().isStudyResult(type)
226                                 && owner.getProgressState() == ProgressState.inDRAFT)
227                         getStudyService().promote(owner);
228                 return stamp; // Hoping that promotion of the study succeeded
229         }
230
231         /**
232          * {@inheritDoc}
233          * 
234          * @see org.splat.service.PublicationService#saveAs(org.splat.dal.bo.som.Publication, org.splat.som.Revision)
235          * @deprecated
236          */
237         @Transactional
238         public void saveAs(Publication aPublication, Revision newvers)
239                         throws FileNotFoundException, NotApplicableException {
240                 if (aPublication.value().isUndefined())
241                         throw new NotApplicableException(
242                                         "Cannot save a Publication object refering an undefined Document");
243                 if (!aPublication.value().getSourceFile().exists())
244                         throw new FileNotFoundException();
245
246                 getPublicationDAO().create(aPublication); // Must be done before updating the study in order to fix this final (rid-based) hascode
247                 getDocumentService().updateAs(aPublication.value(), newvers); // May change the branch name of given revision
248                 updateOwner(aPublication);
249         }
250
251         /**
252          * {@inheritDoc}
253          * 
254          * @see org.splat.service.PublicationService#saveAs(org.splat.dal.bo.som.Publication, org.splat.dal.bo.som.ProgressState)
255          */
256         @Transactional
257         public void saveAs(Publication aPublication, ProgressState state)
258                         throws FileNotFoundException, NotApplicableException {
259                 if (aPublication.value().isUndefined())
260                         throw new NotApplicableException(
261                                         "Cannot save a Publication object refering an undefined Document");
262                 if (!aPublication.value().getSourceFile().exists())
263                         throw new FileNotFoundException();
264
265                 if (state == ProgressState.inWORK || state == ProgressState.EXTERN) {
266                         getPublicationDAO().create(aPublication); // Must be done before updating the study in order to fix this final (rid-based)
267                         // hascode
268                         getDocumentService().updateAs(aPublication.value(), state);
269                 } else {
270                         DocumentType mytype = aPublication.value().getType();
271                         Study owner = aPublication.getOwnerStudy();
272                         ValidationCycle cycle = getStudyService().getValidationCycleOf(
273                                         owner, mytype);
274                         boolean review = cycle.enables(ValidationStep.REVIEW);
275                         if (!(state == ProgressState.inDRAFT && review)
276                                         && !(state == ProgressState.inCHECK && !review)) {
277                                 throw new NotApplicableException(
278                                                 "Cannot save a result document in " + state.toString()
279                                                                 + " state");
280                         }
281                         getPublicationDAO().create(aPublication); // Must be done before updating the study in order to fix this final (rid-based)
282                         // hascode
283                         getDocumentService().updateAs(aPublication.value(),
284                                         ProgressState.inWORK);
285
286                         promote(aPublication, aPublication.value()
287                                         .getLastModificationDate()); // Promotes to the appropriate state in accordance to the validation cycle
288                 }
289                 updateOwner(aPublication);
290         }
291
292         /**
293          * Update an owner of the publication.
294          * 
295          * @param aPublication
296          *            the document publication
297          */
298         @Transactional
299         private void updateOwner(Publication aPublication) {
300                 Step step = getInvolvedStep(aPublication);
301
302                 // Update of involved step
303                 Document previous = aPublication.value().getPreviousVersion();
304                 if (previous != null) {
305                         Publication oldoc = step.getDocument(previous.getIndex());
306                         boolean done = getStepService().remove(step, oldoc); // Decrements the configuration tag count of document
307                         if (done)
308                                 getPublicationDAO().delete(oldoc); // WARNING: Potential problem because it's not automatically done as orphan object
309                 }
310                 getStepService().add(step, aPublication); // Increments the configuration tag count of document
311
312                 // Import the document properties and update of the study
313                 forwardProperties(aPublication, aPublication.value().getSourceFile()
314                                 .asFile(), step);
315                 getProjectElementDAO().update(aPublication.getOwner());
316         }
317
318         /**
319          * Propagate simulation contexts from the given config file to the publication's owner (study or step).
320          * 
321          * @param aPublication
322          *            the document publication
323          * @param from
324          *            the config file
325          * @param to
326          *            the study step
327          */
328         private void forwardProperties(Publication aPublication, java.io.File from,
329                         Step to) {
330                 Reader tool = Toolbox.getReader(from);
331                 if (tool == null)
332                         return; // No properties extractor available for this type of document
333
334                 SimulationContextType.Properties sprop = new SimulationContextType.Properties()
335                                 .setStep(to.getStep()).setState(ProgressState.APPROVED);
336                 List<SimulationContextType> contype = getSimulationContextService()
337                                 .selectTypesWhere(sprop);
338                 if (contype.isEmpty())
339                         return; // No approved property type configured at this step
340
341                 SimulationContext.Properties cprop = new SimulationContext.Properties();
342                 List<SimulationContext> context = to.getAllSimulationContexts();
343
344                 context = new ArrayList<SimulationContext>(context.size());
345                 context.addAll(to.getAllSimulationContexts());
346                 cprop.disableCheck();
347                 for (Iterator<SimulationContextType> i = contype.iterator(); i
348                                 .hasNext();) {
349                         SimulationContextType property = i.next();
350                         for (Iterator<SimulationContext> j = context.iterator(); j
351                                         .hasNext();) {
352                                 SimulationContext existing = j.next();
353                                 if (!existing.getType().equals(property))
354                                         continue;
355                                 property = null; // Forget this property as it is already set
356                                 break;
357                         }
358                         if (property != null)
359                                 try {
360                                         String value = tool.extractProperty(property.getName());
361                                         if (value == null)
362                                                 continue; // Property not defined into the document
363
364                                         cprop.setType(property).setValue(value);
365                                         if (aPublication.getOwner() instanceof Study)
366                                                 getStudyService().addProjectContext(
367                                                                 (Study) aPublication.getOwner(), cprop); // Re-indexes knowledges and the study
368                                         else
369                                                 getStepService().addSimulationContext(to, cprop); // Re-indexes knowledges only
370                                 } catch (Exception e) {
371                                         break;
372                                 }
373                 }
374         }
375
376         /**
377          * Returns the study Step into which the document version referenced by this publication has been published.
378          * 
379          * @param aPublication
380          *            the document publication
381          * @return the study step where the document is published
382          */
383         public Step getInvolvedStep(Publication aPublication) {
384                 if (aPublication.getStep() == null) {
385                         Step[] step = getProjectElementService().getSteps(
386                                         aPublication.getOwner());
387                         for (int i = 0; i < step.length; i++) {
388                                 aPublication.setStep(step[i]); // The involved step necessarily exists
389                                 if (aPublication.value().isInto(aPublication.getStep()))
390                                         break;
391                         }
392                 }
393                 return aPublication.getStep();
394         }
395
396         /**
397          * Create "Converts" relation for the given document publication and format.
398          * 
399          * @param aPublication
400          *            the document publication
401          * @param format
402          *            the format
403          * @return the created "Converts" relation
404          */
405         public ConvertsRelation attach(Publication aPublication, String format) {
406                 return getDocumentService().attach(aPublication.value(), format);
407         }
408
409         /**
410          * Create "Converts" relation for the given document publication, format and description.
411          * 
412          * @param aPublication
413          *            the document publication
414          * @param format
415          *            the format
416          * @param description
417          *            the description of the relation
418          * @return the created "Converts" relation
419          */
420         public ConvertsRelation attach(Publication aPublication, String format,
421                         String description) {
422                 return getDocumentService().attach(aPublication.value(), format,
423                                 description);
424         }
425
426         /**
427          * Rename the published document.
428          * 
429          * @param aPublication
430          *            the publication of the document
431          * @param title
432          *            the new document title
433          * @throws InvalidPropertyException
434          *             if the new title is empty
435          */
436         public void rename(Publication aPublication, String title)
437                         throws InvalidPropertyException {
438                 getDocumentService().rename(aPublication.value(), title);
439         }
440
441         /**
442          * Get the projectElementService.
443          * 
444          * @return the projectElementService
445          */
446         public ProjectElementService getProjectElementService() {
447                 return _projectElementService;
448         }
449
450         /**
451          * Set the projectElementService.
452          * 
453          * @param projectElementService
454          *            the projectElementService to set
455          */
456         public void setProjectElementService(
457                         ProjectElementService projectElementService) {
458                 _projectElementService = projectElementService;
459         }
460
461         /**
462          * Get the simulationContextService.
463          * 
464          * @return the simulationContextService
465          */
466         public SimulationContextService getSimulationContextService() {
467                 return _simulationContextService;
468         }
469
470         /**
471          * Set the simulationContextService.
472          * 
473          * @param simulationContextService
474          *            the simulationContextService to set
475          */
476         public void setSimulationContextService(
477                         SimulationContextService simulationContextService) {
478                 _simulationContextService = simulationContextService;
479         }
480
481         /**
482          * Get the studyService.
483          * 
484          * @return the studyService
485          */
486         public StudyService getStudyService() {
487                 return _studyService;
488         }
489
490         /**
491          * Set the studyService.
492          * 
493          * @param studyService
494          *            the studyService to set
495          */
496         public void setStudyService(StudyService studyService) {
497                 _studyService = studyService;
498         }
499
500         /**
501          * Get the stepService.
502          * 
503          * @return the stepService
504          */
505         public StepService getStepService() {
506                 return _stepService;
507         }
508
509         /**
510          * Set the stepService.
511          * 
512          * @param stepService
513          *            the stepService to set
514          */
515         public void setStepService(StepService stepService) {
516                 _stepService = stepService;
517         }
518
519         /**
520          * Get the documentService.
521          * 
522          * @return the documentService
523          */
524         public DocumentService getDocumentService() {
525                 return _documentService;
526         }
527
528         /**
529          * Set the documentService.
530          * 
531          * @param documentService
532          *            the documentService to set
533          */
534         public void setDocumentService(DocumentService documentService) {
535                 _documentService = documentService;
536         }
537
538         /**
539          * Get the publicationDAO.
540          * 
541          * @return the publicationDAO
542          */
543         public PublicationDAO getPublicationDAO() {
544                 return _publicationDAO;
545         }
546
547         /**
548          * Set the publicationDAO.
549          * 
550          * @param publicationDAO
551          *            the publicationDAO to set
552          */
553         public void setPublicationDAO(PublicationDAO publicationDAO) {
554                 _publicationDAO = publicationDAO;
555         }
556
557         /**
558          * Get the projectElementDAO.
559          * 
560          * @return the projectElementDAO
561          */
562         public ProjectElementDAO getProjectElementDAO() {
563                 return _projectElementDAO;
564         }
565
566         /**
567          * Set the projectElementDAO.
568          * 
569          * @param projectElementDAO
570          *            the projectElementDAO to set
571          */
572         public void setProjectElementDAO(ProjectElementDAO projectElementDAO) {
573                 _projectElementDAO = projectElementDAO;
574         }
575 }