]> SALOME platform Git repositories - tools/siman.git/blob - Workspace/Siman-Common/src/org/splat/service/StepServiceImpl.java
Salome HOME
Ignore temp subfolder.
[tools/siman.git] / Workspace / Siman-Common / src / org / splat / service / StepServiceImpl.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.IOException;
13 import java.util.Iterator;
14 import java.util.List;
15 import java.util.Set;
16 import java.util.Vector;
17
18 import org.splat.dal.bo.kernel.Relation;
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.File;
23 import org.splat.dal.bo.som.KnowledgeElement;
24 import org.splat.dal.bo.som.Publication;
25 import org.splat.dal.bo.som.Scenario;
26 import org.splat.dal.bo.som.SimulationContext;
27 import org.splat.dal.bo.som.Study;
28 import org.splat.dal.bo.som.UsedByRelation;
29 import org.splat.dal.bo.som.UsesRelation;
30 import org.splat.dal.bo.som.VersionsRelation;
31 import org.splat.dal.dao.som.DocumentDAO;
32 import org.splat.dal.dao.som.FileDAO;
33 import org.splat.dal.dao.som.ProjectElementDAO;
34 import org.splat.dal.dao.som.SimulationContextDAO;
35 import org.splat.dal.dao.som.VersionsRelationDAO;
36 import org.splat.kernel.InvalidPropertyException;
37 import org.splat.kernel.MismatchException;
38 import org.splat.kernel.MissedPropertyException;
39 import org.splat.kernel.MultiplyDefinedException;
40 import org.splat.kernel.NotApplicableException;
41 import org.splat.log.AppLogger;
42 import org.splat.service.technical.IndexService;
43 import org.splat.service.technical.ProjectSettingsService;
44 import org.splat.som.Revision;
45 import org.splat.som.Step;
46 import org.springframework.transaction.annotation.Transactional;
47
48 /**
49  * Step service implementation.
50  * 
51  * @author <a href="mailto:roman.kozlov@opencascade.com">Roman Kozlov (RKV)</a>
52  */
53 public class StepServiceImpl implements StepService {
54
55         /**
56          * logger for the service.
57          */
58         public final static AppLogger logger = AppLogger
59                         .getLogger(StepServiceImpl.class);
60         /**
61          * Injected index service.
62          */
63         private IndexService _indexService;
64         /**
65          * Injected document service.
66          */
67         private DocumentService _documentService;
68         /**
69          * Injected document type service.
70          */
71         private DocumentTypeService _documentTypeService;
72         /**
73          * Injected document DAO.
74          */
75         private DocumentDAO _documentDAO;
76         /**
77          * Injected file DAO.
78          */
79         private FileDAO _fileDAO;
80         /**
81          * Injected simulation context service.
82          */
83         private SimulationContextService _simulationContextService;
84         /**
85          * Injected simulation context DAO.
86          */
87         private SimulationContextDAO _simulationContextDAO;
88         /**
89          * Injected project element DAO.
90          */
91         private ProjectElementDAO _projectElementDAO;
92         /**
93          * Injected versions relation DAO.
94          */
95         private VersionsRelationDAO _versionsRelationDAO;
96         /**
97          * Injected project service.
98          */
99         private ProjectSettingsService _projectSettingsService;
100
101         /**
102          * {@inheritDoc}
103          * 
104          * @see org.splat.service.StepService#addSimulationContext(org.splat.som.Step, org.splat.dal.bo.som.SimulationContext.Properties)
105          */
106         public SimulationContext addSimulationContext(final Step aStep,
107                         final SimulationContext.Properties dprop) throws MissedPropertyException,
108                         InvalidPropertyException, MultiplyDefinedException {
109                 SimulationContext context = new SimulationContext(dprop.setStep(aStep
110                                 .getStep()));
111                 return addSimulationContext(aStep, context);
112         }
113
114         /**
115          * {@inheritDoc}
116          * 
117          * @see org.splat.service.StepService#addSimulationContext(org.splat.som.Step, org.splat.dal.bo.som.SimulationContext)
118          */
119         @Transactional
120         public SimulationContext addSimulationContext(final Step aStep,
121                         final SimulationContext context) {
122                 getSimulationContextService().hold(context); // Increments the reference count of simulation context
123                 if (aStep.getOwner().isSaved()) {
124                         try {
125                                 if (!context.isSaved()) {
126                                         getSimulationContextDAO().create(context);
127                                 }
128                                 aStep.getOwner().add(context);
129                                 aStep.getContex().add(context); // The context is also referenced from this (transient) Step
130                                 getProjectElementDAO().update(aStep.getOwner());
131                                 updateKnowledgeElementsIndex(aStep);
132                         } catch (Exception error) {
133                                 return null;
134                         }
135                 } else { // Happens when copying a scenario
136                         aStep.getOwner().add(context);
137                         aStep.getContex().add(context); // The context is also referenced from this (transient) Step
138                         // In case of owner scenario, the Knowledge Element index will be updated later, when saving the scenario
139                 }
140                 return context;
141         }
142
143         /**
144          * Update lucene index of knowledge elements of a scenario or a study which the given step is related to.
145          * 
146          * @param aStep
147          *            the step (activity)
148          */
149         private void updateKnowledgeElementsIndex(final Step aStep) {
150                 Scenario[] scenarii;
151                 if (aStep.getOwner() instanceof Scenario) {
152                         scenarii = new Scenario[1];
153                         scenarii[0] = (Scenario) aStep.getOwner();
154                 } else {
155                         scenarii = aStep.getOwnerStudy().getScenarii();
156                 }
157                 try {
158                         for (int i = 0; i < scenarii.length; i++) {
159                                 Scenario scene = scenarii[i];
160                                 List<KnowledgeElement> knelm = scene.getAllKnowledgeElements();
161                                 for (Iterator<KnowledgeElement> j = knelm.iterator(); j
162                                                 .hasNext();) {
163                                         KnowledgeElement kelm = j.next();
164                                         getIndexService().update(kelm);
165                                 }
166                                 updateScenarioIndex(scene);
167                         }
168                 } catch (Exception error) {
169                         logger.error("Unable to re-index Knowledge Elements, reason:",
170                                         error);
171                 }
172         }
173
174         /**
175          * Update lucene index for knowledge elements of the scenario.
176          * 
177          * @param scene
178          *            the scenario
179          * @throws IOException
180          *             if can't update lucene index
181          */
182         private void updateScenarioIndex(final Scenario scene) throws IOException {
183                 if (scene.getUcase() == null) {
184                         for (Iterator<KnowledgeElement> i = scene.getKnowledgeElements()
185                                         .iterator(); i.hasNext();) {
186                                 KnowledgeElement kelm = i.next();
187                                 if (!kelm.getType().equals("usecase")) {
188                                         continue;
189                                 }
190                                 scene.setUcase(kelm);
191                                 break;
192                         }
193                 }
194                 getIndexService().update(scene.getUcase());
195         }
196
197         /**
198          * {@inheritDoc}
199          * 
200          * @see org.splat.service.StepService#removeSimulationContext(org.splat.som.Step, org.splat.dal.bo.som.SimulationContext)
201          */
202         @Transactional
203         public boolean removeSimulationContext(final Step aStep, final SimulationContext context) {
204                 boolean isOk = false;
205                 SimulationContext torem = aStep
206                                 .getSimulationContext(context.getIndex());
207
208                 if ((torem != null) && (aStep.getOwner().remove(torem))) {
209
210                         aStep.getContex().remove(torem);
211                         getProjectElementDAO().update(aStep.getOwner());
212                         if (torem.isShared()) {
213                                 getSimulationContextService().release(torem);
214                                 getSimulationContextDAO().update(torem);
215                         } else {
216                                 getSimulationContextDAO().delete(torem);
217                         }
218                         isOk = true;
219                 }
220                 return isOk;
221         }
222
223         /**
224          * {@inheritDoc}
225          * 
226          * @see org.splat.service.StepService#createDocument(org.splat.som.Step, org.splat.dal.bo.som.Document.Properties)
227          */
228         @Transactional
229         public Publication createDocument(final Step aStep, final Document.Properties dprop)
230                         throws MissedPropertyException, InvalidPropertyException,
231                         MultiplyDefinedException, IOException {
232                 Document newdoc = new Document(dprop.setOwner(aStep.getOwner())
233                                 .setStep(aStep.getStep()));
234                 getDocumentService().generateDocumentId(newdoc, dprop);
235
236                 // Creation of the save directory
237                 java.io.File wdir = getDocumentService().getSaveDirectory(newdoc);
238                 if (!wdir.exists()) {
239                         if (!wdir.mkdirs()) {
240                                 throw new IOException(
241                                                 "Cannot create the repository vault directory");
242                         }
243                 }
244
245                 // Identification and save
246                 getDocumentService().buildReferenceFrom(newdoc, aStep.getOwnerStudy());
247                 getDocumentDAO().create(newdoc);
248
249                 return new Publication(newdoc, aStep.getOwner());
250         }
251
252         /**
253          * {@inheritDoc}
254          * 
255          * @see org.splat.service.StepService#assignDocument(org.splat.som.Step, org.splat.dal.bo.som.Document.Properties)
256          */
257         public Publication assignDocument(final Step aStep, final Document.Properties dprop)
258                         throws MissedPropertyException, InvalidPropertyException,
259                         NotApplicableException {
260                 String refid = dprop.getReference();
261                 if (refid == null) {
262                         return null;
263                 }
264
265                 Document slot = getDocumentService().selectDocument(refid,
266                                 new Revision().toString());
267                 if (slot == null) {
268                         return null;
269                 }
270                 if (!slot.isUndefined()) {
271                         return null; // Should not happen
272                 }
273
274                 getDocumentService().initialize(slot,
275                                 dprop.setOwner(aStep.getOwnerStudy()));
276                 return new Publication(slot, aStep.getOwner());
277         }
278
279         /**
280          * Create a new version of a document in the given study step.
281          * 
282          * @param aStep
283          *            the study step
284          * @param base
285          *            the base document published version
286          * @return the new version publication
287          * @throws MissedPropertyException
288          *             if a mandatory property is missed
289          * @throws InvalidPropertyException
290          *             if some property doesn't exist
291          * @throws MultiplyDefinedException
292          *             if some property is defined several times
293          * @throws IOException
294          *             if a file system error occurs
295          * @throws MismatchException
296          *             if the document is not applicable to the given study step
297          */
298         public Publication versionDocument(final Step aStep, final Publication base)
299                         throws MissedPropertyException, InvalidPropertyException,
300                         MultiplyDefinedException, IOException, MismatchException {
301                 return versionDocument(aStep, base, new Document.Properties());
302         }
303
304         /**
305          * Create a new version of a document in the given study step.
306          * 
307          * @param aStep
308          *            the study step
309          * @param base
310          *            the base document published version
311          * @param reason
312          *            the comment for the new version
313          * @return the new version publication
314          * @throws MissedPropertyException
315          *             if a mandatory property is missed
316          * @throws InvalidPropertyException
317          *             if some property doesn't exist
318          * @throws MultiplyDefinedException
319          *             if some property is defined several times
320          * @throws IOException
321          *             if a file system error occurs
322          * @throws MismatchException
323          *             if the document is not applicable to the given study step
324          */
325         public Publication versionDocument(final Step aStep, final Publication base,
326                         final String reason) throws MissedPropertyException,
327                         InvalidPropertyException, MultiplyDefinedException, IOException,
328                         MismatchException {
329                 return versionDocument(aStep, base, new Document.Properties()
330                                 .setDescription(reason));
331         }
332
333         /**
334          * Create a new version of a document in the given study step.
335          * 
336          * @param aStep
337          *            the study step
338          * @param base
339          *            the base document published version
340          * @param dprop
341          *            properties of the new version
342          * @return the new version publication
343          * @throws MissedPropertyException
344          *             if a mandatory property is missed
345          * @throws InvalidPropertyException
346          *             if some property doesn't exist
347          * @throws MultiplyDefinedException
348          *             if some property is defined several times
349          * @throws IOException
350          *             if a file system error occurs
351          * @throws MismatchException
352          *             if the document is not applicable to the given study step
353          */
354         @Transactional
355         public Publication versionDocument(final Step aStep, final Publication base,
356                         final Document.Properties dprop) throws MissedPropertyException,
357                         InvalidPropertyException, MultiplyDefinedException, IOException,
358                         MismatchException {
359                 Document previous = base.value();
360
361                 dprop.setDocument(previous, getProjectSettings().getStep(base.getStep().getNumber())); // Initializes the Step property
362                 if (dprop.getStep().getNumber() != aStep.getNumber()) {
363                         throw new MismatchException();
364                 }
365
366                 if (dprop.getAuthor() == null) {
367                         dprop.setAuthor(previous.getAuthor());
368                 }
369                 String summary = dprop.getDescription();
370
371                 // Creation of the document
372                 Document newdoc = new Document(dprop.setOwner(aStep.getOwner())
373                                 .setStep(aStep.getStep()));
374                 getDocumentService().generateDocumentId(newdoc, dprop);
375                 getDocumentService().buildReferenceFrom(newdoc, aStep.getOwner(),
376                                 previous);
377                 getDocumentDAO().create(newdoc);
378
379                 // Versioning
380                 VersionsRelation aRel;
381                 aRel = new VersionsRelation(newdoc, previous, summary);
382 //              getVersionsRelationDAO().create(aRel);
383                 newdoc.addRelation(aRel);
384                 
385                 // Update of usedby relations, if exist
386                 List<Relation> relist = previous.getRelations(UsedByRelation.class);
387                 Study scope = aStep.getOwnerStudy();
388                 for (Iterator<Relation> i = relist.iterator(); i.hasNext();) {
389                         UsedByRelation relation = (UsedByRelation) i.next();
390                         Document relatedoc = relation.getTo();
391                         if (scope.shares(relatedoc)) {
392                                 relatedoc.addRelation(new UsesRelation(relatedoc, newdoc));
393                         } else {
394                                 relation.moveTo(newdoc);
395                         }
396                 }
397                 return new Publication(newdoc, aStep.getOwner());
398         }
399
400         /**
401          * Get document types which are applicable for the given study step (activity).
402          * 
403          * @param aStep
404          *            the study step
405          * @return the list of document types
406          */
407         public List<DocumentType> getValidDocumentTypes(final Step aStep) {
408                 return getDocumentTypeService().selectTypesOf(aStep.getStep());
409         }
410
411         /**
412          * Add a document publication to the given step.
413          * 
414          * @param aStep
415          *            the target study step
416          * @param newdoc
417          *            the document publication to add
418          * @return true if publication succeeded
419          */
420         public boolean add(final Step aStep, final Publication newdoc) {
421                 if (!aStep.getOwner().add(newdoc)) {
422                         return false; // Updates the study in memory
423                 }
424                 aStep.getDocuments().add(0, newdoc); // Updates this step
425                 getDocumentService().hold(newdoc.value()); // Increments the configuration tag count of document
426                 // If not yet saved, the Publication MUST NOT be saved here, although this creates a temporary inconsistent state into the
427                 // database (it will be saved later by cascading the update of owner scenario).
428                 return true;
429         }
430
431         /**
432          * Remove a document publication from the given step.
433          * 
434          * @param aStep
435          *            the study step
436          * @param oldoc
437          *            the document publication to remove
438          * @return true if removing of the publication succeeded
439          */
440         public boolean remove(final Step aStep, final Publication oldoc) {
441                 if (!aStep.getOwner().remove(oldoc)) {
442                         return false; // Updates the study in memory
443                 }
444                 aStep.getDocuments().remove(oldoc); // Updates this step
445                 getDocumentService().release(oldoc.value()); // Decrements the configuration tag count of document
446                 // The publication becoming orphan, it should automatically be removed from the database when updating of owner scenario.
447                 return true;
448         }
449
450         /**
451          * Remove a document from the given step.
452          * 
453          * @param aStep
454          *            the study step
455          * @param doctag
456          *            the document publication
457          * @return true if removing of the document succeeded
458          */
459         @Transactional
460         public boolean removeDocument(final Step aStep, final Publication doctag) {
461                 Document value = doctag.value();
462                 getDocumentDAO().update(value);
463                 Publication torem = aStep.getDocument(value.getIndex());
464
465                 if (torem == null) {
466                         return false;
467                 }
468
469                 remove(aStep, torem);
470                 getProjectElementDAO().update(aStep.getOwner());
471                 if (!value.isPublished() && !value.isVersioned()) { // The referenced document is no more used
472                         Set<Relation> links = value.getAllRelations(); // Get all relation of the document to remove them
473                         List<Document> using = new Vector<Document>();
474                         for (Iterator<Relation> i = links.iterator(); i.hasNext();) {
475                                 Relation link = i.next();
476                                 if (link.getClass().equals(ConvertsRelation.class)) { // File conversion
477                                         getFileDAO().delete((File) link.getTo()); // The corresponding physical file is not removed from the vault
478                                 } else if (link.getClass().equals(UsesRelation.class)) { // Document dependency
479                                         using.add((Document) link.getTo());
480                                 }
481                         }
482                         for (Iterator<Document> i = using.iterator(); i.hasNext();) {
483                                 i.next().removeRelation(UsedByRelation.class, value); // TODO: RKV: don't use Database.getSession in removeRelation
484                         }
485                         getDocumentDAO().delete(value); // The corresponding physical file is not removed from the vault
486                 }
487                 return true;
488         }
489
490         /**
491          * Get the documentService.
492          * 
493          * @return the documentService
494          */
495         public DocumentService getDocumentService() {
496                 return _documentService;
497         }
498
499         /**
500          * Set the documentService.
501          * 
502          * @param documentService
503          *            the documentService to set
504          */
505         public void setDocumentService(final DocumentService documentService) {
506                 _documentService = documentService;
507         }
508
509         /**
510          * Get the simulationContextService.
511          * 
512          * @return the simulationContextService
513          */
514         public SimulationContextService getSimulationContextService() {
515                 return _simulationContextService;
516         }
517
518         /**
519          * Set the simulationContextService.
520          * 
521          * @param simulationContextService
522          *            the simulationContextService to set
523          */
524         public void setSimulationContextService(
525                         final SimulationContextService simulationContextService) {
526                 _simulationContextService = simulationContextService;
527         }
528
529         /**
530          * Get the documentDAO.
531          * 
532          * @return the documentDAO
533          */
534         public DocumentDAO getDocumentDAO() {
535                 return _documentDAO;
536         }
537
538         /**
539          * Set the documentDAO.
540          * 
541          * @param documentDAO
542          *            the documentDAO to set
543          */
544         public void setDocumentDAO(final DocumentDAO documentDAO) {
545                 _documentDAO = documentDAO;
546         }
547
548         /**
549          * Get the simulationContextDAO.
550          * 
551          * @return the simulationContextDAO
552          */
553         public SimulationContextDAO getSimulationContextDAO() {
554                 return _simulationContextDAO;
555         }
556
557         /**
558          * Set the simulationContextDAO.
559          * 
560          * @param simulationContextDAO
561          *            the simulationContextDAO to set
562          */
563         public void setSimulationContextDAO(
564                         final SimulationContextDAO simulationContextDAO) {
565                 _simulationContextDAO = simulationContextDAO;
566         }
567
568         /**
569          * Get the projectElementDAO.
570          * 
571          * @return the projectElementDAO
572          */
573         public ProjectElementDAO getProjectElementDAO() {
574                 return _projectElementDAO;
575         }
576
577         /**
578          * Set the projectElementDAO.
579          * 
580          * @param projectElementDAO
581          *            the projectElementDAO to set
582          */
583         public void setProjectElementDAO(final ProjectElementDAO projectElementDAO) {
584                 _projectElementDAO = projectElementDAO;
585         }
586
587         /**
588          * Get the indexService.
589          * 
590          * @return the indexService
591          */
592         public IndexService getIndexService() {
593                 return _indexService;
594         }
595
596         /**
597          * Set the indexService.
598          * 
599          * @param indexService
600          *            the indexService to set
601          */
602         public void setIndexService(final IndexService indexService) {
603                 _indexService = indexService;
604         }
605
606         /**
607          * Get the fileDAO.
608          * 
609          * @return the fileDAO
610          */
611         public FileDAO getFileDAO() {
612                 return _fileDAO;
613         }
614
615         /**
616          * Set the fileDAO.
617          * 
618          * @param fileDAO
619          *            the fileDAO to set
620          */
621         public void setFileDAO(final FileDAO fileDAO) {
622                 _fileDAO = fileDAO;
623         }
624
625         /**
626          * Get the documentTypeService.
627          * 
628          * @return the documentTypeService
629          */
630         public DocumentTypeService getDocumentTypeService() {
631                 return _documentTypeService;
632         }
633
634         /**
635          * Set the documentTypeService.
636          * 
637          * @param documentTypeService
638          *            the documentTypeService to set
639          */
640         public void setDocumentTypeService(final DocumentTypeService documentTypeService) {
641                 _documentTypeService = documentTypeService;
642         }
643
644         /**
645          * Get the versionsRelationDAO.
646          * @return the versionsRelationDAO
647          */
648         public VersionsRelationDAO getVersionsRelationDAO() {
649                 return _versionsRelationDAO;
650         }
651
652         /**
653          * Set the versionsRelationDAO.
654          * @param versionsRelationDAO the versionsRelationDAO to set
655          */
656         public void setVersionsRelationDAO(final VersionsRelationDAO versionsRelationDAO) {
657                 _versionsRelationDAO = versionsRelationDAO;
658         }
659
660         /**
661          * Get project settings.
662          * 
663          * @return Project settings service
664          */
665         private ProjectSettingsService getProjectSettings() {
666                 return _projectSettingsService;
667         }
668
669         /**
670          * Set project settings service.
671          * 
672          * @param projectSettingsService
673          *            project settings service
674          */
675         public void setProjectSettings(
676                         final ProjectSettingsService projectSettingsService) {
677                 _projectSettingsService = projectSettingsService;
678         }
679 }