1 /*****************************************************************************
5 * Creation date 06.10.2012
8 *****************************************************************************/
10 package org.splat.service;
12 import java.io.IOException;
13 import java.util.Iterator;
14 import java.util.List;
16 import java.util.Vector;
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.kernel.InvalidPropertyException;
36 import org.splat.kernel.MismatchException;
37 import org.splat.kernel.MissedPropertyException;
38 import org.splat.kernel.MultiplyDefinedException;
39 import org.splat.kernel.NotApplicableException;
40 import org.splat.log.AppLogger;
41 import org.splat.service.technical.IndexService;
42 import org.splat.som.Revision;
43 import org.splat.som.Step;
44 import org.springframework.transaction.annotation.Transactional;
47 * Step service implementation.
49 * @author <a href="mailto:roman.kozlov@opencascade.com">Roman Kozlov (RKV)</a>
51 public class StepServiceImpl implements StepService {
54 * logger for the service.
56 public final static AppLogger logger = AppLogger
57 .getLogger(StepServiceImpl.class);
59 * Injected index service.
61 private IndexService _indexService;
63 * Injected document service.
65 private DocumentService _documentService;
67 * Injected document type service.
69 private DocumentTypeService _documentTypeService;
71 * Injected document DAO.
73 private DocumentDAO _documentDAO;
77 private FileDAO _fileDAO;
79 * Injected simulation context service.
81 private SimulationContextService _simulationContextService;
83 * Injected simulation context DAO.
85 private SimulationContextDAO _simulationContextDAO;
87 * Injected project element DAO.
89 private ProjectElementDAO _projectElementDAO;
94 * @see org.splat.service.StepService#addSimulationContext(org.splat.som.Step, org.splat.dal.bo.som.SimulationContext.Properties)
96 public SimulationContext addSimulationContext(Step aStep,
97 SimulationContext.Properties dprop) throws MissedPropertyException,
98 InvalidPropertyException, MultiplyDefinedException {
99 SimulationContext context = new SimulationContext(dprop.setStep(aStep
101 return addSimulationContext(aStep, context);
107 * @see org.splat.service.StepService#addSimulationContext(org.splat.som.Step, org.splat.dal.bo.som.SimulationContext)
110 public SimulationContext addSimulationContext(Step aStep,
111 SimulationContext context) {
112 getSimulationContextService().hold(context); // Increments the reference count of simulation context
113 if (aStep.getOwner().isSaved())
115 if (!context.isSaved())
116 getSimulationContextDAO().create(context);
117 aStep.getOwner().add(context);
118 aStep.getContex().add(context); // The context is also referenced from this (transient) Step
119 getProjectElementDAO().update(aStep.getOwner());
120 updateKnowledgeElementsIndex(aStep);
121 } catch (Exception error) {
124 else { // Happens when copying a scenario
125 aStep.getOwner().add(context);
126 aStep.getContex().add(context); // The context is also referenced from this (transient) Step
127 // In case of owner scenario, the Knowledge Element index will be updated later, when saving the scenario
133 * Update lucene index of knowledge elements of a scenario or a study which the given step is related to.
136 * the step (activity)
138 private void updateKnowledgeElementsIndex(Step aStep) {
140 if (aStep.getOwner() instanceof Scenario) {
141 scenarii = new Scenario[1];
142 scenarii[0] = (Scenario) aStep.getOwner();
144 scenarii = aStep.getOwnerStudy().getScenarii();
147 for (int i = 0; i < scenarii.length; i++) {
148 Scenario scene = scenarii[i];
149 List<KnowledgeElement> knelm = scene.getAllKnowledgeElements();
150 for (Iterator<KnowledgeElement> j = knelm.iterator(); j
152 KnowledgeElement kelm = j.next();
153 getIndexService().update(kelm);
155 updateScenarioIndex(scene);
157 } catch (Exception error) {
158 logger.error("Unable to re-index Knowledge Elements, reason:",
164 * Update lucene index for knowledge elements of the scenario.
168 * @throws IOException
169 * if can't update lucene index
171 private void updateScenarioIndex(Scenario scene) throws IOException {
172 if (scene.getUcase() == null) {
173 for (Iterator<KnowledgeElement> i = scene.getKnowledgeElements()
174 .iterator(); i.hasNext();) {
175 KnowledgeElement kelm = i.next();
176 if (!kelm.getType().equals("usecase"))
178 scene.setUcase(kelm);
182 getIndexService().update(scene.getUcase());
188 * @see org.splat.service.StepService#removeSimulationContext(org.splat.som.Step, org.splat.dal.bo.som.SimulationContext)
191 public boolean removeSimulationContext(Step aStep, SimulationContext context) {
192 boolean isOk = false;
193 SimulationContext torem = aStep
194 .getSimulationContext(context.getIndex());
196 if ((torem != null) && (aStep.getOwner().remove(torem))) {
198 aStep.getContex().remove(torem);
199 getProjectElementDAO().update(aStep.getOwner());
200 if (torem.isShared()) {
201 getSimulationContextService().release(torem);
202 getSimulationContextDAO().update(torem);
204 getSimulationContextDAO().delete(torem);
214 * @see org.splat.service.StepService#createDocument(org.splat.som.Step, org.splat.dal.bo.som.Document.Properties)
217 public Publication createDocument(Step aStep, Document.Properties dprop)
218 throws MissedPropertyException, InvalidPropertyException,
219 MultiplyDefinedException, IOException {
220 Document newdoc = new Document(dprop.setOwner(aStep.getOwner())
221 .setStep(aStep.getStep()));
222 getDocumentService().generateDocumentId(newdoc, dprop);
224 // Creation of the save directory
225 java.io.File wdir = getDocumentService().getSaveDirectory(newdoc);
228 throw new IOException(
229 "Cannot create the repository vault directory");
231 // Identification and save
232 getDocumentService().buildReferenceFrom(newdoc, aStep.getOwnerStudy());
233 getDocumentDAO().create(newdoc);
235 return new Publication(newdoc, aStep.getOwner());
241 * @see org.splat.service.StepService#assignDocument(org.splat.som.Step, org.splat.dal.bo.som.Document.Properties)
243 public Publication assignDocument(Step aStep, Document.Properties dprop)
244 throws MissedPropertyException, InvalidPropertyException,
245 NotApplicableException {
246 String refid = dprop.getReference();
250 Document slot = getDocumentService().selectDocument(refid,
251 new Revision().toString());
254 if (!slot.isUndefined())
255 return null; // Should not happen
257 getDocumentService().initialize(slot,
258 dprop.setOwner(aStep.getOwnerStudy()));
259 return new Publication(slot, aStep.getOwner());
263 * Create a new version of a document in the given study step.
268 * the base document published version
269 * @return the new version publication
270 * @throws MissedPropertyException
271 * if a mandatory property is missed
272 * @throws InvalidPropertyException
273 * if some property doesn't exist
274 * @throws MultiplyDefinedException
275 * if some property is defined several times
276 * @throws IOException
277 * if a file system error occurs
278 * @throws MismatchException
279 * if the document is not applicable to the given study step
281 public Publication versionDocument(Step aStep, Publication base)
282 throws MissedPropertyException, InvalidPropertyException,
283 MultiplyDefinedException, IOException, MismatchException {
284 return versionDocument(aStep, base, new Document.Properties());
288 * Create a new version of a document in the given study step.
293 * the base document published version
295 * the comment for the new version
296 * @return the new version publication
297 * @throws MissedPropertyException
298 * if a mandatory property is missed
299 * @throws InvalidPropertyException
300 * if some property doesn't exist
301 * @throws MultiplyDefinedException
302 * if some property is defined several times
303 * @throws IOException
304 * if a file system error occurs
305 * @throws MismatchException
306 * if the document is not applicable to the given study step
308 public Publication versionDocument(Step aStep, Publication base,
309 String reason) throws MissedPropertyException,
310 InvalidPropertyException, MultiplyDefinedException, IOException,
312 return versionDocument(aStep, base, new Document.Properties()
313 .setDescription(reason));
317 * Create a new version of a document in the given study step.
322 * the base document published version
324 * properties of the new version
325 * @return the new version publication
326 * @throws MissedPropertyException
327 * if a mandatory property is missed
328 * @throws InvalidPropertyException
329 * if some property doesn't exist
330 * @throws MultiplyDefinedException
331 * if some property is defined several times
332 * @throws IOException
333 * if a file system error occurs
334 * @throws MismatchException
335 * if the document is not applicable to the given study step
338 public Publication versionDocument(Step aStep, Publication base,
339 Document.Properties dprop) throws MissedPropertyException,
340 InvalidPropertyException, MultiplyDefinedException, IOException,
342 Document previous = base.value();
344 dprop.setDocument(previous); // Initializes the Step property
345 if (dprop.getStep().getNumber() != aStep.getNumber())
346 throw new MismatchException();
348 if (dprop.getAuthor() == null)
349 dprop.setAuthor(previous.getAuthor());
350 String summary = dprop.getDescription();
352 // Creation of the document
353 Document newdoc = new Document(dprop.setOwner(aStep.getOwner())
354 .setStep(aStep.getStep()));
355 getDocumentService().generateDocumentId(newdoc, dprop);
356 getDocumentService().buildReferenceFrom(newdoc, aStep.getOwner(),
358 getDocumentDAO().create(newdoc);
362 newdoc.addRelation(new VersionsRelation(newdoc, previous));
364 newdoc.addRelation(new VersionsRelation(newdoc, previous, summary));
366 // Update of usedby relations, if exist
367 List<Relation> relist = previous.getRelations(UsedByRelation.class);
368 Study scope = aStep.getOwnerStudy();
369 for (Iterator<Relation> i = relist.iterator(); i.hasNext();) {
370 UsedByRelation relation = (UsedByRelation) i.next();
371 Document relatedoc = relation.getTo();
372 if (scope.shares(relatedoc))
373 relatedoc.addRelation(new UsesRelation(relatedoc, newdoc));
375 relation.moveTo(newdoc);
377 return new Publication(newdoc, aStep.getOwner());
381 * Get document types which are applicable for the given study step (activity).
385 * @return the list of document types
387 public List<DocumentType> getValidDocumentTypes(Step aStep) {
388 return getDocumentTypeService().selectTypesOf(aStep.getStep());
392 * Add a document publication to the given step.
395 * the target study step
397 * the document publication to add
398 * @return true if publication succeeded
400 public boolean add(Step aStep, Publication newdoc) {
401 if (!aStep.getOwner().add(newdoc))
402 return false; // Updates the study in memory
403 aStep.getDocuments().add(0, newdoc); // Updates this step
404 getDocumentService().hold(newdoc.value()); // Increments the configuration tag count of document
405 // If not yet saved, the Publication MUST NOT be saved here, although this creates a temporary inconsistent state into the
406 // database (it will be saved later by cascading the update of owner scenario).
411 * Remove a document publication from the given step.
416 * the document publication to remove
417 * @return true if removing of the publication succeeded
419 public boolean remove(Step aStep, Publication oldoc) {
420 if (!aStep.getOwner().remove(oldoc))
421 return false; // Updates the study in memory
422 aStep.getDocuments().remove(oldoc); // Updates this step
423 getDocumentService().release(oldoc.value()); // Decrements the configuration tag count of document
424 // The publication becoming orphan, it should automatically be removed from the database when updating of owner scenario.
429 * Remove a document from the given step.
434 * the document publication
435 * @return true if removing of the document succeeded
437 public boolean removeDocument(Step aStep, Publication doctag) {
438 Document value = doctag.value();
439 Publication torem = aStep.getDocument(value.getIndex());
444 remove(aStep, torem);
445 getProjectElementDAO().update(aStep.getOwner());
446 if (!value.isPublished() && !value.isVersioned()) { // The referenced document is no more used
447 Set<Relation> links = value.getAllRelations(); // Get all relation of the document to remove them
448 List<Document> using = new Vector<Document>();
449 for (Iterator<Relation> i = links.iterator(); i.hasNext();) {
450 Relation link = i.next();
451 if (link.getClass().equals(ConvertsRelation.class)) { // File conversion
452 getFileDAO().delete((File) link.getTo()); // The corresponding physical file is not removed from the vault
453 } else if (link.getClass().equals(UsesRelation.class)) { // Document dependency
454 using.add((Document) link.getTo());
457 for (Iterator<Document> i = using.iterator(); i.hasNext();) {
458 i.next().removeRelation(UsedByRelation.class, value); // TODO: RKV: don't use Database.getSession in removeRelation
460 getDocumentDAO().delete(value); // The corresponding physical file is not removed from the vault
466 * Get the documentService.
468 * @return the documentService
470 public DocumentService getDocumentService() {
471 return _documentService;
475 * Set the documentService.
477 * @param documentService
478 * the documentService to set
480 public void setDocumentService(DocumentService documentService) {
481 _documentService = documentService;
485 * Get the simulationContextService.
487 * @return the simulationContextService
489 public SimulationContextService getSimulationContextService() {
490 return _simulationContextService;
494 * Set the simulationContextService.
496 * @param simulationContextService
497 * the simulationContextService to set
499 public void setSimulationContextService(
500 SimulationContextService simulationContextService) {
501 _simulationContextService = simulationContextService;
505 * Get the documentDAO.
507 * @return the documentDAO
509 public DocumentDAO getDocumentDAO() {
514 * Set the documentDAO.
517 * the documentDAO to set
519 public void setDocumentDAO(DocumentDAO documentDAO) {
520 _documentDAO = documentDAO;
524 * Get the simulationContextDAO.
526 * @return the simulationContextDAO
528 public SimulationContextDAO getSimulationContextDAO() {
529 return _simulationContextDAO;
533 * Set the simulationContextDAO.
535 * @param simulationContextDAO
536 * the simulationContextDAO to set
538 public void setSimulationContextDAO(
539 SimulationContextDAO simulationContextDAO) {
540 _simulationContextDAO = simulationContextDAO;
544 * Get the projectElementDAO.
546 * @return the projectElementDAO
548 public ProjectElementDAO getProjectElementDAO() {
549 return _projectElementDAO;
553 * Set the projectElementDAO.
555 * @param projectElementDAO
556 * the projectElementDAO to set
558 public void setProjectElementDAO(ProjectElementDAO projectElementDAO) {
559 _projectElementDAO = projectElementDAO;
563 * Get the indexService.
565 * @return the indexService
567 public IndexService getIndexService() {
568 return _indexService;
572 * Set the indexService.
574 * @param indexService
575 * the indexService to set
577 public void setIndexService(IndexService indexService) {
578 _indexService = indexService;
584 * @return the fileDAO
586 public FileDAO getFileDAO() {
596 public void setFileDAO(FileDAO fileDAO) {
601 * Get the documentTypeService.
603 * @return the documentTypeService
605 public DocumentTypeService getDocumentTypeService() {
606 return _documentTypeService;
610 * Set the documentTypeService.
612 * @param documentTypeService
613 * the documentTypeService to set
615 public void setDocumentTypeService(DocumentTypeService documentTypeService) {
616 _documentTypeService = documentTypeService;