Salome HOME
Refactoring of Database, replacing SQL by DAOs calls. Methods for search by criteria...
[tools/siman.git] / Workspace / Siman-Common / src / org / splat / service / PublicationServiceImpl.java
1 /*****************************************************************************
2  * Company         EURIWARE
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.hibernate.Session;
19 import org.splat.dal.bo.kernel.User;
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.Database;
32 import org.splat.kernel.NotApplicableException;
33 import org.splat.manox.Reader;
34 import org.splat.manox.Toolbox;
35 import org.splat.som.Revision;
36 import org.splat.som.Step;
37
38 /**
39  * Publication service implementation.
40  * 
41  * @author <a href="mailto:roman.kozlov@opencascade.com">Roman Kozlov (RKV)</a>
42  */
43 public class PublicationServiceImpl implements PublicationService {
44
45         /**
46          * Injected study service.
47          */
48         private StudyService _studyService;
49         /**
50          * Injected study service.
51          */
52         private StepService _stepService;
53         /**
54          * Injected study service.
55          */
56         private DocumentTypeService _documentTypeService;
57         /**
58          * Injected study service.
59          */
60         private ProjectElementService _projectElementService;
61         /**
62          * Injected simulation context service.
63          */
64         private SimulationContextService _simulationContextService;
65
66         /**
67          * {@inheritDoc}
68          * 
69          * @see org.splat.service.PublicationService#copy(org.splat.dal.bo.som.Publication, org.splat.dal.bo.som.ProjectElement)
70          */
71         public Publication copy(Publication aPublication, ProjectElement publisher) {
72                 Publication copy = new Publication();
73                 copy.setValue(aPublication.value());
74                 copy.setStep(aPublication.getStep()); // May not be initialized yet
75                 copy.setOwner(publisher);
76                 copy.setIsnew(aPublication.getIsnew());
77                 if (!copy.getOwnerStudy().equals(aPublication.getOwnerStudy())) {
78                         copy.setIsnew('N'); // The referenced document is not new for the given study
79                 }
80                 return copy;
81         }
82
83         /**
84          * {@inheritDoc}
85          * 
86          * @see org.splat.service.PublicationService#approve(org.splat.dal.bo.som.Publication, java.util.Date)
87          */
88         public Timestamp approve(Publication aPublication, Date adate) {
89                 // -------------------------------------
90                 if (aPublication.isOutdated())
91                         return null;
92                 else if (aPublication.value().getProgressState() != ProgressState.inCHECK)
93                         return null; // This statement must conform to the corresponding right
94
95                 DocumentType type = aPublication.value().getType();
96                 Study owner = aPublication.getOwnerStudy();
97                 ValidationCycle cycle = owner.getValidationCycleOf(type);
98                 User approver = cycle.getActor(ValidationStep.APPROVAL);
99                 Timestamp stamp = new Timestamp(ValidationStep.APPROVAL, aPublication
100                                 .value(), approver, adate);
101                 if (!aPublication.value().promote(stamp))
102                         return null;
103                 if (getDocumentTypeService().isStudyResult(type)
104                                 && owner.getProgressState() == ProgressState.inCHECK)
105                         getStudyService().promote(owner);
106                 return stamp; // Hoping that promotion of the study succeeded
107         }
108
109         /**
110          * {@inheritDoc}
111          * 
112          * @see org.splat.service.PublicationService#demote(org.splat.dal.bo.som.Publication)
113          */
114         public boolean demote(Publication aPublication) {
115                 // ------------------------
116                 DocumentType type = aPublication.value().getType();
117                 Study owner = aPublication.getOwnerStudy();
118
119                 if (aPublication.value().getProgressState() == ProgressState.inCHECK) {
120                         ValidationCycle cycle = owner.getValidationCycleOf(type);
121                         if (cycle.enables(ValidationStep.REVIEW)) {
122                                 if (!aPublication.value().demote())
123                                         return false;
124                         } else {
125                                 if (!aPublication.value().demote())
126                                         return false;
127                                 aPublication.value().demote();
128                         }
129                 } else if (aPublication.value().getProgressState() == ProgressState.inDRAFT) {
130                         if (!aPublication.value().demote())
131                                 return false;
132                 } else {
133                         return false;
134                 }
135                 if (getDocumentTypeService().isStudyResult(type)
136                                 && owner.getProgressState() != ProgressState.inWORK)
137                         getStudyService().demote(owner);
138                 return true;
139         }
140
141         /**
142          * {@inheritDoc}
143          * 
144          * @see org.splat.service.PublicationService#invalidate(org.splat.dal.bo.som.Publication)
145          */
146         public boolean invalidate(Publication aPublication) {
147                 // ----------------------------
148                 if (aPublication.value().getProgressState() != ProgressState.inCHECK)
149                         return false;
150                 if (!aPublication.value().demote()) // Removes the reviewer if this document is In-Check
151                         return false;
152                 DocumentType type = aPublication.value().getType();
153                 Study owner = aPublication.getOwnerStudy();
154                 if (getDocumentTypeService().isStudyResult(type)
155                                 && owner.getProgressState() == ProgressState.inCHECK)
156                         getStudyService().demote(owner);
157                 return true;
158         }
159
160         /**
161          * {@inheritDoc}
162          * 
163          * @see org.splat.service.PublicationService#promote(org.splat.dal.bo.som.Publication, java.util.Date)
164          */
165         public Timestamp promote(Publication aPublication, Date pdate) {
166                 if (aPublication.isOutdated())
167                         return null;
168                 else if (aPublication.value().getProgressState() != ProgressState.inWORK)
169                         return null; // This statement must conform to the corresponding right
170                 else {
171                         DocumentType type = aPublication.value().getType();
172                         Study owner = aPublication.getOwnerStudy();
173                         ValidationCycle cycle = owner.getValidationCycleOf(type);
174                         User promoter = cycle.getActor(ValidationStep.PROMOTION);
175                         if (promoter == null)
176                                 promoter = getInvolvedStep(aPublication).getActor();
177                         if (promoter == null)
178                                 promoter = owner.getAuthor();
179                         Timestamp stamp = new Timestamp(ValidationStep.PROMOTION,
180                                         aPublication.value(), promoter, pdate);
181
182                         if (!aPublication.value().promote(stamp)) // Promotion to being reviewed
183                                 return null;
184                         if (!cycle.enables(ValidationStep.REVIEW)) {
185                                 aPublication.value().promote(null);
186                         }
187                         if (getDocumentTypeService().isStudyResult(type)
188                                         && owner.getProgressState() == ProgressState.inWORK)
189                                 getStudyService().promote(owner);
190                         return stamp; // Hoping that promotion of the study succeeded
191                 }
192         }
193
194         /**
195          * {@inheritDoc}
196          * 
197          * @see org.splat.service.PublicationService#review(org.splat.dal.bo.som.Publication, java.util.Date)
198          */
199         public Timestamp review(Publication aPublication, Date rdate) {
200                 if (aPublication.isOutdated())
201                         return null;
202                 else if (aPublication.value().getProgressState() != ProgressState.inDRAFT)
203                         return null; // This statement must conform to the corresponding right
204
205                 DocumentType type = aPublication.value().getType();
206                 Study owner = aPublication.getOwnerStudy();
207                 ValidationCycle cycle = owner.getValidationCycleOf(type);
208                 User reviewer = cycle.getActor(ValidationStep.REVIEW);
209                 Timestamp stamp = new Timestamp(ValidationStep.REVIEW, aPublication
210                                 .value(), reviewer, rdate);
211                 if (!aPublication.value().promote(stamp))
212                         return null;
213                 if (getDocumentTypeService().isStudyResult(type)
214                                 && owner.getProgressState() == ProgressState.inDRAFT)
215                         getStudyService().promote(owner);
216                 return stamp; // Hoping that promotion of the study succeeded
217         }
218
219         /**
220          * {@inheritDoc}
221          * 
222          * @see org.splat.service.PublicationService#saveAs(org.splat.dal.bo.som.Publication, org.splat.som.Revision)
223          * @deprecated
224          */
225         public void saveAs(Publication aPublication, Revision newvers)
226                         throws FileNotFoundException, NotApplicableException {
227                 // -------------------------------------
228                 if (aPublication.value().isUndefined())
229                         throw new NotApplicableException(
230                                         "Cannot save a Publication object refering an undefined Document");
231                 if (!aPublication.value().getSourceFile().exists())
232                         throw new FileNotFoundException();
233
234                 Database.getSession().save(aPublication); // Must be done before updating the study in order to fix this final (rid-based) hascode
235                 aPublication.value().updateAs(newvers); // May change the branch name of given revision
236                 updateOwner(aPublication);
237         }
238
239         /**
240          * {@inheritDoc}
241          * 
242          * @see org.splat.service.PublicationService#saveAs(org.splat.dal.bo.som.Publication, org.splat.dal.bo.som.ProgressState)
243          */
244         public void saveAs(Publication aPublication, ProgressState state)
245                         throws FileNotFoundException, NotApplicableException {
246                 // ----------------------------------------
247                 if (aPublication.value().isUndefined())
248                         throw new NotApplicableException(
249                                         "Cannot save a Publication object refering an undefined Document");
250                 if (!aPublication.value().getSourceFile().exists())
251                         throw new FileNotFoundException();
252
253                 if (state == ProgressState.inWORK || state == ProgressState.EXTERN) {
254                         Database.getSession().save(aPublication); // Must be done before updating the study in order to fix this final (rid-based)
255                         // hascode
256                         aPublication.value().updateAs(state);
257                 } else {
258                         DocumentType mytype = aPublication.value().getType();
259                         Study owner = aPublication.getOwnerStudy();
260                         ValidationCycle cycle = owner.getValidationCycleOf(mytype);
261                         boolean review = cycle.enables(ValidationStep.REVIEW);
262                         if (!(state == ProgressState.inDRAFT && review)
263                                         && !(state == ProgressState.inCHECK && !review)) {
264                                 throw new NotApplicableException(
265                                                 "Cannot save a result document in " + state.toString()
266                                                                 + " state");
267                         }
268                         Database.getSession().save(aPublication); // Must be done before updating the study in order to fix this final (rid-based)
269                         // hascode
270                         aPublication.value().updateAs(ProgressState.inWORK);
271
272                         promote(aPublication, aPublication.value()
273                                         .getLastModificationDate()); // Promotes to the appropriate state in accordance to the validation cycle
274                 }
275                 updateOwner(aPublication);
276         }
277
278         /**
279          * Update an owner of the publication.
280          * 
281          * @param aPublication
282          *            the document publication
283          */
284         private void updateOwner(Publication aPublication) {
285                 Session session = Database.getSession();
286                 Step step = getInvolvedStep(aPublication);
287
288                 // Update of involved step
289                 Document previous = aPublication.value().getPreviousVersion();
290                 if (previous != null) {
291                         Publication oldoc = step.getDocument(previous.getIndex());
292                         boolean done = step.remove(oldoc); // Decrements the configuration tag count of document
293                         if (done)
294                                 session.delete(oldoc); // WARNING: Potential problem because it's not automatically done as orphan object
295                 }
296                 step.add(aPublication); // Increments the configuration tag count of document
297
298                 // Import the document properties and update of the study
299                 forwardProperties(aPublication, aPublication.value().getSourceFile()
300                                 .asFile(), step);
301                 session.update(aPublication.getOwner());
302         }
303
304         /**
305          * Propagate simulation contexts from the given config file to the publication's owner (study or step).
306          * 
307          * @param aPublication
308          *            the document publication
309          * @param from
310          *            the config file
311          * @param to
312          *            the study step
313          */
314         private void forwardProperties(Publication aPublication, java.io.File from,
315                         Step to) {
316                 // -----------------------------------------------------------
317                 Reader tool = Toolbox.getReader(from);
318                 if (tool == null)
319                         return; // No properties extractor available for this type of document
320
321                 SimulationContextType.Properties sprop = new SimulationContextType.Properties()
322                                 .setStep(to.getStep()).setState(ProgressState.APPROVED);
323                 List<SimulationContextType> contype = getSimulationContextService()
324                                 .selectTypesWhere(sprop);
325                 if (contype.isEmpty())
326                         return; // No approved property type configured at this step
327
328                 SimulationContext.Properties cprop = new SimulationContext.Properties();
329                 List<SimulationContext> context = to.getAllSimulationContexts();
330
331                 context = new ArrayList<SimulationContext>(context.size());
332                 context.addAll(to.getAllSimulationContexts());
333                 cprop.disableCheck();
334                 for (Iterator<SimulationContextType> i = contype.iterator(); i
335                                 .hasNext();) {
336                         SimulationContextType property = i.next();
337                         for (Iterator<SimulationContext> j = context.iterator(); j
338                                         .hasNext();) {
339                                 SimulationContext existing = j.next();
340                                 if (!existing.getType().equals(property))
341                                         continue;
342                                 property = null; // Forget this property as it is already set
343                                 break;
344                         }
345                         if (property != null)
346                                 try {
347                                         String value = tool.extractProperty(property.getName());
348                                         if (value == null)
349                                                 continue; // Property not defined into the document
350
351                                         cprop.setType(property).setValue(value);
352                                         if (aPublication.getOwner() instanceof Study)
353                                                 getStudyService().addProjectContext(
354                                                                 (Study) aPublication.getOwner(), cprop); // Re-indexes knowledges and the study
355                                         else
356                                                 getStepService().addSimulationContext(to, cprop); // Re-indexes knowledges only
357                                 } catch (Exception e) {
358                                         break;
359                                 }
360                 }
361         }
362
363         /**
364          * Returns the study Step into which the document version referenced by this publication has been published.
365          * 
366          * @param aPublication
367          *            the document publication
368          * @return the study step where the document is published
369          */
370         public Step getInvolvedStep(Publication aPublication) {
371                 if (aPublication.getStep() == null) {
372                         Step[] step = getProjectElementService().getSteps(
373                                         aPublication.getOwner());
374                         for (int i = 0; i < step.length; i++) {
375                                 aPublication.setStep(step[i]); // The involved step necessarily exists
376                                 if (aPublication.value().isInto(aPublication.getStep()))
377                                         break;
378                         }
379                 }
380                 return aPublication.getStep();
381         }
382
383         /**
384          * Get the projectElementService.
385          * 
386          * @return the projectElementService
387          */
388         public ProjectElementService getProjectElementService() {
389                 return _projectElementService;
390         }
391
392         /**
393          * Set the projectElementService.
394          * 
395          * @param projectElementService
396          *            the projectElementService to set
397          */
398         public void setProjectElementService(
399                         ProjectElementService projectElementService) {
400                 _projectElementService = projectElementService;
401         }
402
403         /**
404          * Get the simulationContextService.
405          * 
406          * @return the simulationContextService
407          */
408         public SimulationContextService getSimulationContextService() {
409                 return _simulationContextService;
410         }
411
412         /**
413          * Set the simulationContextService.
414          * 
415          * @param simulationContextService
416          *            the simulationContextService to set
417          */
418         public void setSimulationContextService(
419                         SimulationContextService simulationContextService) {
420                 _simulationContextService = simulationContextService;
421         }
422
423         /**
424          * Get the studyService.
425          * @return the studyService
426          */
427         public StudyService getStudyService() {
428                 return _studyService;
429         }
430
431         /**
432          * Set the studyService.
433          * @param studyService the studyService to set
434          */
435         public void setStudyService(StudyService studyService) {
436                 _studyService = studyService;
437         }
438
439         /**
440          * Get the stepService.
441          * @return the stepService
442          */
443         public StepService getStepService() {
444                 return _stepService;
445         }
446
447         /**
448          * Set the stepService.
449          * @param stepService the stepService to set
450          */
451         public void setStepService(StepService stepService) {
452                 _stepService = stepService;
453         }
454
455         /**
456          * Get the documentTypeService.
457          * @return the documentTypeService
458          */
459         public DocumentTypeService getDocumentTypeService() {
460                 return _documentTypeService;
461         }
462
463         /**
464          * Set the documentTypeService.
465          * @param documentTypeService the documentTypeService to set
466          */
467         public void setDocumentTypeService(DocumentTypeService documentTypeService) {
468                 _documentTypeService = documentTypeService;
469         }
470 }