1 /*****************************************************************************
5 * Creation date 06.10.2012
8 *****************************************************************************/
10 package org.splat.service;
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;
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.UsedByRelation;
30 import org.splat.dal.bo.som.ValidationCycle;
31 import org.splat.dal.bo.som.ValidationStep;
32 import org.splat.dal.dao.som.Database;
33 import org.splat.dal.dao.som.ProjectElementDAO;
34 import org.splat.dal.dao.som.PublicationDAO;
35 import org.splat.kernel.InvalidPropertyException;
36 import org.splat.kernel.NotApplicableException;
37 import org.splat.manox.Reader;
38 import org.splat.manox.Toolbox;
39 import org.splat.som.DocumentRights;
40 import org.splat.som.Revision;
41 import org.splat.som.Step;
42 import org.springframework.transaction.annotation.Transactional;
45 * Publication service implementation.
47 * @author <a href="mailto:roman.kozlov@opencascade.com">Roman Kozlov (RKV)</a>
49 public class PublicationServiceImpl implements PublicationService {
52 * Injected study service.
54 private StudyService _studyService;
56 * Injected step service.
58 private StepService _stepService;
60 * Injected document service.
62 private DocumentService _documentService;
64 * Injected project element service.
66 private ProjectElementService _projectElementService;
68 * Injected simulation context service.
70 private SimulationContextService _simulationContextService;
72 * Injected publication DAO.
74 private PublicationDAO _publicationDAO;
76 * Injected project element DAO.
78 private ProjectElementDAO _projectElementDAO;
83 * @see org.splat.service.PublicationService#copy(org.splat.dal.bo.som.Publication, org.splat.dal.bo.som.ProjectElement)
85 public Publication copy(Publication aPublication, ProjectElement publisher) {
86 Publication copy = new Publication();
87 copy.setValue(aPublication.value());
88 copy.setStep(aPublication.getStep()); // May not be initialized yet
89 copy.setOwner(publisher);
90 copy.setIsnew(aPublication.getIsnew());
91 if (!copy.getOwnerStudy().equals(aPublication.getOwnerStudy())) {
92 copy.setIsnew('N'); // The referenced document is not new for the given study
100 * @see org.splat.service.PublicationService#approve(org.splat.dal.bo.som.Publication, java.util.Date)
102 public Timestamp approve(Publication aPublication, Date adate) {
103 if (aPublication.isOutdated())
105 else if (aPublication.value().getProgressState() != ProgressState.inCHECK)
106 return null; // This statement must conform to the corresponding right
108 DocumentType type = aPublication.value().getType();
109 Study owner = aPublication.getOwnerStudy();
110 ValidationCycle cycle = getStudyService().getValidationCycleOf(owner,
112 User approver = cycle.getActor(ValidationStep.APPROVAL);
113 Timestamp stamp = new Timestamp(ValidationStep.APPROVAL,
114 aPublication.value(), approver, adate);
115 if (!getDocumentService().promote(aPublication.value(), stamp))
117 if (getDocumentService().isStudyResult(type)
118 && owner.getProgressState() == ProgressState.inCHECK)
119 getStudyService().promote(owner);
120 return stamp; // Hoping that promotion of the study succeeded
126 * @see org.splat.service.PublicationService#demote(org.splat.dal.bo.som.Publication)
128 public boolean demote(Publication aPublication) {
129 DocumentType type = aPublication.value().getType();
130 Study owner = aPublication.getOwnerStudy();
132 if (aPublication.value().getProgressState() == ProgressState.inCHECK) {
133 ValidationCycle cycle = getStudyService().getValidationCycleOf(
135 if (cycle.enables(ValidationStep.REVIEW)) {
136 if (!getDocumentService().demote(aPublication.value()))
139 if (!getDocumentService().demote(aPublication.value()))
141 getDocumentService().demote(aPublication.value());
143 } else if (aPublication.value().getProgressState() == ProgressState.inDRAFT) {
144 if (!getDocumentService().demote(aPublication.value()))
149 if (getDocumentService().isStudyResult(type)
150 && owner.getProgressState() != ProgressState.inWORK)
151 getStudyService().demote(owner);
158 * @see org.splat.service.PublicationService#invalidate(org.splat.dal.bo.som.Publication)
160 public boolean invalidate(Publication aPublication) {
161 if (aPublication.value().getProgressState() != ProgressState.inCHECK)
163 if (!getDocumentService().demote(aPublication.value())) // Removes the reviewer if this document is In-Check
165 DocumentType type = aPublication.value().getType();
166 Study owner = aPublication.getOwnerStudy();
167 if (getDocumentService().isStudyResult(type)
168 && owner.getProgressState() == ProgressState.inCHECK)
169 getStudyService().demote(owner);
176 * @see org.splat.service.PublicationService#promote(org.splat.dal.bo.som.Publication, java.util.Date)
178 public Timestamp promote(Publication aPublication, Date pdate) {
179 if (aPublication.isOutdated())
181 else if (aPublication.value().getProgressState() != ProgressState.inWORK)
182 return null; // This statement must conform to the corresponding right
184 DocumentType type = aPublication.value().getType();
185 Study owner = aPublication.getOwnerStudy();
186 ValidationCycle cycle = getStudyService().getValidationCycleOf(
188 User promoter = cycle.getActor(ValidationStep.PROMOTION);
189 if (promoter == null)
190 promoter = getInvolvedStep(aPublication).getActor();
191 if (promoter == null)
192 promoter = owner.getAuthor();
193 Timestamp stamp = new Timestamp(ValidationStep.PROMOTION,
194 aPublication.value(), promoter, pdate);
196 if (!getDocumentService().promote(aPublication.value(), stamp)) // Promotion to being reviewed
198 if (!cycle.enables(ValidationStep.REVIEW)) {
199 getDocumentService().promote(aPublication.value(), null);
201 if (getDocumentService().isStudyResult(type)
202 && owner.getProgressState() == ProgressState.inWORK)
203 getStudyService().promote(owner);
204 return stamp; // Hoping that promotion of the study succeeded
211 * @see org.splat.service.PublicationService#review(org.splat.dal.bo.som.Publication, java.util.Date)
213 public Timestamp review(Publication aPublication, Date rdate) {
214 if (aPublication.isOutdated())
216 else if (aPublication.value().getProgressState() != ProgressState.inDRAFT)
217 return null; // This statement must conform to the corresponding right
219 DocumentType type = aPublication.value().getType();
220 Study owner = aPublication.getOwnerStudy();
221 ValidationCycle cycle = getStudyService().getValidationCycleOf(owner,
223 User reviewer = cycle.getActor(ValidationStep.REVIEW);
224 Timestamp stamp = new Timestamp(ValidationStep.REVIEW,
225 aPublication.value(), reviewer, rdate);
226 if (!getDocumentService().promote(aPublication.value(), stamp))
228 if (getDocumentService().isStudyResult(type)
229 && owner.getProgressState() == ProgressState.inDRAFT)
230 getStudyService().promote(owner);
231 return stamp; // Hoping that promotion of the study succeeded
237 * @see org.splat.service.PublicationService#saveAs(org.splat.dal.bo.som.Publication, org.splat.som.Revision)
241 public void saveAs(Publication aPublication, Revision newvers)
242 throws FileNotFoundException, NotApplicableException {
243 if (aPublication.value().isUndefined())
244 throw new NotApplicableException(
245 "Cannot save a Publication object refering an undefined Document");
246 if (!aPublication.value().getSourceFile().exists())
247 throw new FileNotFoundException();
249 getPublicationDAO().create(aPublication); // Must be done before updating the study in order to fix this final (rid-based) hascode
250 getDocumentService().updateAs(aPublication.value(), newvers); // May change the branch name of given revision
251 updateOwner(aPublication);
257 * @see org.splat.service.PublicationService#saveAs(org.splat.dal.bo.som.Publication, org.splat.dal.bo.som.ProgressState)
260 public void saveAs(Publication aPublication, ProgressState state)
261 throws FileNotFoundException, NotApplicableException {
262 if (aPublication.value().isUndefined())
263 throw new NotApplicableException(
264 "Cannot save a Publication object refering an undefined Document");
265 if (!aPublication.value().getSourceFile().exists())
266 throw new FileNotFoundException();
268 if (state == ProgressState.inWORK || state == ProgressState.EXTERN) {
269 getPublicationDAO().create(aPublication); // Must be done before updating the study in order to fix this final (rid-based)
271 getDocumentService().updateAs(aPublication.value(), state);
273 DocumentType mytype = aPublication.value().getType();
274 Study owner = aPublication.getOwnerStudy();
275 ValidationCycle cycle = getStudyService().getValidationCycleOf(
277 boolean review = cycle.enables(ValidationStep.REVIEW);
278 if (!(state == ProgressState.inDRAFT && review)
279 && !(state == ProgressState.inCHECK && !review)) {
280 throw new NotApplicableException(
281 "Cannot save a result document in " + state.toString()
284 getPublicationDAO().create(aPublication); // Must be done before updating the study in order to fix this final (rid-based)
286 getDocumentService().updateAs(aPublication.value(),
287 ProgressState.inWORK);
289 promote(aPublication, aPublication.value()
290 .getLastModificationDate()); // Promotes to the appropriate state in accordance to the validation cycle
292 updateOwner(aPublication);
296 * Update an owner of the publication.
298 * @param aPublication
299 * the document publication
302 private void updateOwner(Publication aPublication) {
303 Step step = getInvolvedStep(aPublication);
305 // Update of involved step
306 Document previous = aPublication.value().getPreviousVersion();
307 if (previous != null) {
308 Publication oldoc = step.getDocument(previous.getIndex());
309 boolean done = getStepService().remove(step, oldoc); // Decrements the configuration tag count of document
311 getPublicationDAO().delete(oldoc); // WARNING: Potential problem because it's not automatically done as orphan object
313 getStepService().add(step, aPublication); // Increments the configuration tag count of document
315 // Import the document properties and update of the study
316 forwardProperties(aPublication, aPublication.value().getSourceFile()
318 getProjectElementDAO().update(aPublication.getOwner());
322 * Propagate simulation contexts from the given config file to the publication's owner (study or step).
324 * @param aPublication
325 * the document publication
331 private void forwardProperties(Publication aPublication, java.io.File from,
333 Reader tool = Toolbox.getReader(from);
335 return; // No properties extractor available for this type of document
337 SimulationContextType.Properties sprop = new SimulationContextType.Properties()
338 .setStep(to.getStep()).setProgressState(ProgressState.APPROVED);
339 List<SimulationContextType> contype = getSimulationContextService()
340 .selectTypesWhere(sprop);
341 if (contype.isEmpty())
342 return; // No approved property type configured at this step
344 SimulationContext.Properties cprop = new SimulationContext.Properties();
345 List<SimulationContext> context = to.getAllSimulationContexts();
347 context = new ArrayList<SimulationContext>(context.size());
348 context.addAll(to.getAllSimulationContexts());
349 cprop.disableCheck();
350 for (Iterator<SimulationContextType> i = contype.iterator(); i
352 SimulationContextType property = i.next();
353 for (Iterator<SimulationContext> j = context.iterator(); j
355 SimulationContext existing = j.next();
356 if (!existing.getType().equals(property))
358 property = null; // Forget this property as it is already set
361 if (property != null)
363 String value = tool.extractProperty(property.getName());
365 continue; // Property not defined into the document
367 cprop.setType(property).setValue(value);
368 if (aPublication.getOwner() instanceof Study)
369 getStudyService().addProjectContext(
370 (Study) aPublication.getOwner(), cprop); // Re-indexes knowledges and the study
372 getStepService().addSimulationContext(to, cprop); // Re-indexes knowledges only
373 } catch (Exception e) {
380 * Returns the study Step into which the document version referenced by this publication has been published.
382 * @param aPublication
383 * the document publication
384 * @return the study step where the document is published
386 public Step getInvolvedStep(Publication aPublication) {
387 if (aPublication.getStep() == null) {
388 Step[] step = getProjectElementService().getSteps(
389 aPublication.getOwner());
390 for (int i = 0; i < step.length; i++) {
391 aPublication.setStep(step[i]); // The involved step necessarily exists
392 if (aPublication.value().isInto(aPublication.getStep()))
396 return aPublication.getStep();
400 * Undo the out-date operation.
402 * @param aPublication
404 * @return true if the acceptance succeeds
406 * @see DocumentRights#canAccept()
408 public boolean actualize(Publication aPublication) {
409 if (!aPublication.isOutdated())
411 aPublication.setIsnew('Y');
412 getPublicationDAO().update(aPublication);
417 * Out-dates this publication and recursively all publications using this one. Typically, a publication is out-dated when modifying a
418 * document to which it depends.
420 * @param aPublication
423 * @see #getProgressState()
426 public void outdate(Publication aPublication) {
427 if (aPublication.isOutdated())
430 List<Publication> relist = aPublication
431 .getRelations(UsedByRelation.class);
432 for (Iterator<Publication> i = relist.iterator(); i.hasNext();) {
435 aPublication.setIsnew('O');
436 getPublicationDAO().update(aPublication);
440 * Create "Converts" relation for the given document publication and format.
442 * @param aPublication
443 * the document publication
446 * @return the created "Converts" relation
448 public ConvertsRelation attach(Publication aPublication, String format) {
449 return getDocumentService().attach(aPublication.value(), format);
453 * Create "Converts" relation for the given document publication, format and description.
455 * @param aPublication
456 * the document publication
460 * the description of the relation
461 * @return the created "Converts" relation
463 public ConvertsRelation attach(Publication aPublication, String format,
464 String description) {
465 return getDocumentService().attach(aPublication.value(), format,
470 * Rename the published document.
472 * @param aPublication
473 * the publication of the document
475 * the new document title
476 * @throws InvalidPropertyException
477 * if the new title is empty
479 public void rename(Publication aPublication, String title)
480 throws InvalidPropertyException {
481 getDocumentService().rename(aPublication.value(), title);
485 * Get the projectElementService.
487 * @return the projectElementService
489 public ProjectElementService getProjectElementService() {
490 return _projectElementService;
494 * Set the projectElementService.
496 * @param projectElementService
497 * the projectElementService to set
499 public void setProjectElementService(
500 ProjectElementService projectElementService) {
501 _projectElementService = projectElementService;
505 * Get the simulationContextService.
507 * @return the simulationContextService
509 public SimulationContextService getSimulationContextService() {
510 return _simulationContextService;
514 * Set the simulationContextService.
516 * @param simulationContextService
517 * the simulationContextService to set
519 public void setSimulationContextService(
520 SimulationContextService simulationContextService) {
521 _simulationContextService = simulationContextService;
525 * Get the studyService.
527 * @return the studyService
529 public StudyService getStudyService() {
530 return _studyService;
534 * Set the studyService.
536 * @param studyService
537 * the studyService to set
539 public void setStudyService(StudyService studyService) {
540 _studyService = studyService;
544 * Get the stepService.
546 * @return the stepService
548 public StepService getStepService() {
553 * Set the stepService.
556 * the stepService to set
558 public void setStepService(StepService stepService) {
559 _stepService = stepService;
563 * Get the documentService.
565 * @return the documentService
567 public DocumentService getDocumentService() {
568 return _documentService;
572 * Set the documentService.
574 * @param documentService
575 * the documentService to set
577 public void setDocumentService(DocumentService documentService) {
578 _documentService = documentService;
582 * Get the publicationDAO.
584 * @return the publicationDAO
586 public PublicationDAO getPublicationDAO() {
587 return _publicationDAO;
591 * Set the publicationDAO.
593 * @param publicationDAO
594 * the publicationDAO to set
596 public void setPublicationDAO(PublicationDAO publicationDAO) {
597 _publicationDAO = publicationDAO;
601 * Get the projectElementDAO.
603 * @return the projectElementDAO
605 public ProjectElementDAO getProjectElementDAO() {
606 return _projectElementDAO;
610 * Set the projectElementDAO.
612 * @param projectElementDAO
613 * the projectElementDAO to set
615 public void setProjectElementDAO(ProjectElementDAO projectElementDAO) {
616 _projectElementDAO = projectElementDAO;