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.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;
42 * Publication service implementation.
44 * @author <a href="mailto:roman.kozlov@opencascade.com">Roman Kozlov (RKV)</a>
46 public class PublicationServiceImpl implements PublicationService {
49 * Injected study service.
51 private StudyService _studyService;
53 * Injected step service.
55 private StepService _stepService;
57 * Injected document service.
59 private DocumentService _documentService;
61 * Injected project element service.
63 private ProjectElementService _projectElementService;
65 * Injected simulation context service.
67 private SimulationContextService _simulationContextService;
69 * Injected publication DAO.
71 private PublicationDAO _publicationDAO;
73 * Injected project element DAO.
75 private ProjectElementDAO _projectElementDAO;
80 * @see org.splat.service.PublicationService#copy(org.splat.dal.bo.som.Publication, org.splat.dal.bo.som.ProjectElement)
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
97 * @see org.splat.service.PublicationService#approve(org.splat.dal.bo.som.Publication, java.util.Date)
99 public Timestamp approve(Publication aPublication, Date adate) {
100 if (aPublication.isOutdated())
102 else if (aPublication.value().getProgressState() != ProgressState.inCHECK)
103 return null; // This statement must conform to the corresponding right
105 DocumentType type = aPublication.value().getType();
106 Study owner = aPublication.getOwnerStudy();
107 ValidationCycle cycle = getStudyService().getValidationCycleOf(owner,
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))
114 if (getDocumentService().isStudyResult(type)
115 && owner.getProgressState() == ProgressState.inCHECK)
116 getStudyService().promote(owner);
117 return stamp; // Hoping that promotion of the study succeeded
123 * @see org.splat.service.PublicationService#demote(org.splat.dal.bo.som.Publication)
125 public boolean demote(Publication aPublication) {
126 DocumentType type = aPublication.value().getType();
127 Study owner = aPublication.getOwnerStudy();
129 if (aPublication.value().getProgressState() == ProgressState.inCHECK) {
130 ValidationCycle cycle = getStudyService().getValidationCycleOf(
132 if (cycle.enables(ValidationStep.REVIEW)) {
133 if (!getDocumentService().demote(aPublication.value()))
136 if (!getDocumentService().demote(aPublication.value()))
138 getDocumentService().demote(aPublication.value());
140 } else if (aPublication.value().getProgressState() == ProgressState.inDRAFT) {
141 if (!getDocumentService().demote(aPublication.value()))
146 if (getDocumentService().isStudyResult(type)
147 && owner.getProgressState() != ProgressState.inWORK)
148 getStudyService().demote(owner);
155 * @see org.splat.service.PublicationService#invalidate(org.splat.dal.bo.som.Publication)
157 public boolean invalidate(Publication aPublication) {
158 if (aPublication.value().getProgressState() != ProgressState.inCHECK)
160 if (!getDocumentService().demote(aPublication.value())) // Removes the reviewer if this document is In-Check
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);
173 * @see org.splat.service.PublicationService#promote(org.splat.dal.bo.som.Publication, java.util.Date)
175 public Timestamp promote(Publication aPublication, Date pdate) {
176 if (aPublication.isOutdated())
178 else if (aPublication.value().getProgressState() != ProgressState.inWORK)
179 return null; // This statement must conform to the corresponding right
181 DocumentType type = aPublication.value().getType();
182 Study owner = aPublication.getOwnerStudy();
183 ValidationCycle cycle = getStudyService().getValidationCycleOf(
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);
193 if (!getDocumentService().promote(aPublication.value(), stamp)) // Promotion to being reviewed
195 if (!cycle.enables(ValidationStep.REVIEW)) {
196 getDocumentService().promote(aPublication.value(), null);
198 if (getDocumentService().isStudyResult(type)
199 && owner.getProgressState() == ProgressState.inWORK)
200 getStudyService().promote(owner);
201 return stamp; // Hoping that promotion of the study succeeded
208 * @see org.splat.service.PublicationService#review(org.splat.dal.bo.som.Publication, java.util.Date)
210 public Timestamp review(Publication aPublication, Date rdate) {
211 if (aPublication.isOutdated())
213 else if (aPublication.value().getProgressState() != ProgressState.inDRAFT)
214 return null; // This statement must conform to the corresponding right
216 DocumentType type = aPublication.value().getType();
217 Study owner = aPublication.getOwnerStudy();
218 ValidationCycle cycle = getStudyService().getValidationCycleOf(owner,
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))
225 if (getDocumentService().isStudyResult(type)
226 && owner.getProgressState() == ProgressState.inDRAFT)
227 getStudyService().promote(owner);
228 return stamp; // Hoping that promotion of the study succeeded
234 * @see org.splat.service.PublicationService#saveAs(org.splat.dal.bo.som.Publication, org.splat.som.Revision)
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();
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);
254 * @see org.splat.service.PublicationService#saveAs(org.splat.dal.bo.som.Publication, org.splat.dal.bo.som.ProgressState)
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();
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)
268 getDocumentService().updateAs(aPublication.value(), state);
270 DocumentType mytype = aPublication.value().getType();
271 Study owner = aPublication.getOwnerStudy();
272 ValidationCycle cycle = getStudyService().getValidationCycleOf(
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()
281 getPublicationDAO().create(aPublication); // Must be done before updating the study in order to fix this final (rid-based)
283 getDocumentService().updateAs(aPublication.value(),
284 ProgressState.inWORK);
286 promote(aPublication, aPublication.value()
287 .getLastModificationDate()); // Promotes to the appropriate state in accordance to the validation cycle
289 updateOwner(aPublication);
293 * Update an owner of the publication.
295 * @param aPublication
296 * the document publication
299 private void updateOwner(Publication aPublication) {
300 Step step = getInvolvedStep(aPublication);
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
308 getPublicationDAO().delete(oldoc); // WARNING: Potential problem because it's not automatically done as orphan object
310 getStepService().add(step, aPublication); // Increments the configuration tag count of document
312 // Import the document properties and update of the study
313 forwardProperties(aPublication, aPublication.value().getSourceFile()
315 getProjectElementDAO().update(aPublication.getOwner());
319 * Propagate simulation contexts from the given config file to the publication's owner (study or step).
321 * @param aPublication
322 * the document publication
328 private void forwardProperties(Publication aPublication, java.io.File from,
330 Reader tool = Toolbox.getReader(from);
332 return; // No properties extractor available for this type of document
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
341 SimulationContext.Properties cprop = new SimulationContext.Properties();
342 List<SimulationContext> context = to.getAllSimulationContexts();
344 context = new ArrayList<SimulationContext>(context.size());
345 context.addAll(to.getAllSimulationContexts());
346 cprop.disableCheck();
347 for (Iterator<SimulationContextType> i = contype.iterator(); i
349 SimulationContextType property = i.next();
350 for (Iterator<SimulationContext> j = context.iterator(); j
352 SimulationContext existing = j.next();
353 if (!existing.getType().equals(property))
355 property = null; // Forget this property as it is already set
358 if (property != null)
360 String value = tool.extractProperty(property.getName());
362 continue; // Property not defined into the document
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
369 getStepService().addSimulationContext(to, cprop); // Re-indexes knowledges only
370 } catch (Exception e) {
377 * Returns the study Step into which the document version referenced by this publication has been published.
379 * @param aPublication
380 * the document publication
381 * @return the study step where the document is published
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()))
393 return aPublication.getStep();
397 * Create "Converts" relation for the given document publication and format.
399 * @param aPublication
400 * the document publication
403 * @return the created "Converts" relation
405 public ConvertsRelation attach(Publication aPublication, String format) {
406 return getDocumentService().attach(aPublication.value(), format);
410 * Create "Converts" relation for the given document publication, format and description.
412 * @param aPublication
413 * the document publication
417 * the description of the relation
418 * @return the created "Converts" relation
420 public ConvertsRelation attach(Publication aPublication, String format,
421 String description) {
422 return getDocumentService().attach(aPublication.value(), format,
427 * Rename the published document.
429 * @param aPublication
430 * the publication of the document
432 * the new document title
433 * @throws InvalidPropertyException
434 * if the new title is empty
436 public void rename(Publication aPublication, String title)
437 throws InvalidPropertyException {
438 getDocumentService().rename(aPublication.value(), title);
442 * Get the projectElementService.
444 * @return the projectElementService
446 public ProjectElementService getProjectElementService() {
447 return _projectElementService;
451 * Set the projectElementService.
453 * @param projectElementService
454 * the projectElementService to set
456 public void setProjectElementService(
457 ProjectElementService projectElementService) {
458 _projectElementService = projectElementService;
462 * Get the simulationContextService.
464 * @return the simulationContextService
466 public SimulationContextService getSimulationContextService() {
467 return _simulationContextService;
471 * Set the simulationContextService.
473 * @param simulationContextService
474 * the simulationContextService to set
476 public void setSimulationContextService(
477 SimulationContextService simulationContextService) {
478 _simulationContextService = simulationContextService;
482 * Get the studyService.
484 * @return the studyService
486 public StudyService getStudyService() {
487 return _studyService;
491 * Set the studyService.
493 * @param studyService
494 * the studyService to set
496 public void setStudyService(StudyService studyService) {
497 _studyService = studyService;
501 * Get the stepService.
503 * @return the stepService
505 public StepService getStepService() {
510 * Set the stepService.
513 * the stepService to set
515 public void setStepService(StepService stepService) {
516 _stepService = stepService;
520 * Get the documentService.
522 * @return the documentService
524 public DocumentService getDocumentService() {
525 return _documentService;
529 * Set the documentService.
531 * @param documentService
532 * the documentService to set
534 public void setDocumentService(DocumentService documentService) {
535 _documentService = documentService;
539 * Get the publicationDAO.
541 * @return the publicationDAO
543 public PublicationDAO getPublicationDAO() {
544 return _publicationDAO;
548 * Set the publicationDAO.
550 * @param publicationDAO
551 * the publicationDAO to set
553 public void setPublicationDAO(PublicationDAO publicationDAO) {
554 _publicationDAO = publicationDAO;
558 * Get the projectElementDAO.
560 * @return the projectElementDAO
562 public ProjectElementDAO getProjectElementDAO() {
563 return _projectElementDAO;
567 * Set the projectElementDAO.
569 * @param projectElementDAO
570 * the projectElementDAO to set
572 public void setProjectElementDAO(ProjectElementDAO projectElementDAO) {
573 _projectElementDAO = projectElementDAO;