1 /*****************************************************************************
5 * Creation date 06.10.2012
8 *****************************************************************************/
10 package org.splat.service;
12 import java.io.IOException;
13 import java.util.Date;
14 import java.util.HashMap;
15 import java.util.Iterator;
16 import java.util.List;
18 import org.apache.log4j.Logger;
19 import org.hibernate.Session;
20 import org.splat.dal.bo.kernel.Relation;
21 import org.splat.dal.bo.kernel.User;
22 import org.splat.dal.bo.som.ActorRelation;
23 import org.splat.dal.bo.som.ContributorRelation;
24 import org.splat.dal.bo.som.DescriptionAttribute;
25 import org.splat.dal.bo.som.Document;
26 import org.splat.dal.bo.som.DocumentType;
27 import org.splat.dal.bo.som.IDBuilder;
28 import org.splat.dal.bo.som.KnowledgeElement;
29 import org.splat.dal.bo.som.KnowledgeElementType;
30 import org.splat.dal.bo.som.ProgressState;
31 import org.splat.dal.bo.som.Publication;
32 import org.splat.dal.bo.som.Scenario;
33 import org.splat.dal.bo.som.SimulationContext;
34 import org.splat.dal.bo.som.Study;
35 import org.splat.dal.bo.som.ValidationCycle;
36 import org.splat.dal.bo.som.ValidationCycleRelation;
37 import org.splat.dal.bo.som.Visibility;
38 import org.splat.dal.bo.som.Study.Properties;
39 import org.splat.dal.dao.som.Database;
40 import org.splat.kernel.InvalidPropertyException;
41 import org.splat.kernel.MissedPropertyException;
42 import org.splat.kernel.MultiplyDefinedException;
43 import org.splat.kernel.UserDirectory;
44 import org.splat.service.technical.IndexService;
45 import org.splat.service.technical.ProjectSettingsService;
46 import org.splat.som.Revision;
52 public class StudyServiceImpl implements StudyService {
54 public final static Logger logger = Logger.getLogger(org.splat.service.StudyServiceImpl.class);
56 private IndexService _indexService;
58 private StepService _stepService;
60 private ScenarioService _scenarioService;
62 private ProjectSettingsService _projectSettingsService;
64 private ProjectElementService _projectElementService;
66 public Study selectStudy(int index) {
67 // -------------------------------------------
68 StringBuffer query = new StringBuffer("from Study where rid='").append(
70 Study result = (Study) Database.getSession().createQuery(
71 query.toString()).uniqueResult();
73 result.loadWorkflow();
77 public Study selectStudy(String refid) {
78 // ----------------------------------------------
79 StringBuffer query = new StringBuffer("from Study where sid='").append(
81 Study result = (Study) Database.getSession().createQuery(
82 query.toString()).uniqueResult();
84 result.loadWorkflow();
88 public Study createStudy(Study.Properties sprop)
89 throws MissedPropertyException, InvalidPropertyException,
90 MultiplyDefinedException, RuntimeException {
91 sprop.setReference(getProjectSettings().getReferencePattern());
92 Study study = new Study(sprop);
94 buildReference(study);
95 Database.getSession().save(study); // TODO: use StudyDAO and throw out Database.
97 IndexService lucin = getIndex();
99 } catch (IOException error) {
100 logger.error("Unable to index the study '" + study.getIndex()
101 + "', reason:", error);
102 // Continue and try to index later
107 public IndexService getIndex() throws IOException {
108 IndexService lucin = getIndexService();
110 lucin.create(); // Happens when re-indexing all studies
114 public SimulationContext addProjectContext(Study aStudy,
115 SimulationContext.Properties cprop) throws MissedPropertyException,
116 InvalidPropertyException, MultiplyDefinedException,
118 // -------------------------------------------------------------------------------
119 SimulationContext added = getStepService().addSimulationContext(
120 getProjectElementService().getFirstStep(aStudy), cprop);
128 public StepService getStepService() {
132 public void setStepService(StepService stepService) {
133 _stepService = stepService;
136 public SimulationContext addProjectContext(Study aStudy,
137 SimulationContext context) {
138 // ----------------------------------------------------------------------
139 SimulationContext added = getStepService().addSimulationContext(
140 getProjectElementService().getFirstStep(aStudy), context);
145 public boolean addContributor(Study aStudy, User user) {
146 // -----------------------------------------
147 List<User> contributor = aStudy.getModifiableContributors(); // Initializes contributor
148 for (Iterator<User> i = contributor.iterator(); i.hasNext();) {
149 User present = i.next();
150 if (present.equals(user))
153 boolean absent = aStudy.getModifiableActors().add(user); // User may already be a reviewer or an approver
155 aStudy.addRelation(new ContributorRelation(aStudy, user));
157 update(aStudy); // Else, useless to re-index the study
158 contributor.add(user);
163 * Moves this study from the Public to the Reference area of the repository. For being moved to the Reference area, the study must
164 * previously be approved.
166 * @return true if the move succeeded.
167 * @see #moveToPublic()
169 * @see Publication#approve(Date)
171 public boolean moveToReference(Study aStudy) {
172 // ---------------------------------
173 if (aStudy.getProgressState() != ProgressState.APPROVED)
175 if (aStudy.getVisibility() != Visibility.PUBLIC)
178 aStudy.setVisibility(Visibility.REFERENCE);
179 if (update(aStudy)) {
180 return updateKnowledgeElementsIndex(aStudy); // If fails, the database roll-back is under responsibility of the caller
185 public boolean update(Study aStudy, Properties sprop)
186 throws InvalidPropertyException {
187 if (sprop.getTitle() != null)
188 aStudy.setTitle(sprop.getTitle());
189 if (sprop.getSummary() != null)
190 aStudy.setAttribute(new DescriptionAttribute(aStudy, sprop
192 // TODO: To be completed
193 return update(aStudy);
196 public boolean buildReference(Study aStudy) {
197 String pattern = aStudy.getReference(); // The study being supposed just created, its reference is the reference pattern
198 IDBuilder tool = Database.selectIDBuilder(aStudy.getDate());
200 tool = new IDBuilder(aStudy.getDate());
201 Database.getSession().save(tool);
203 aStudy.setReference(tool.buildReference(pattern, aStudy));
207 public boolean publishes(Study aStudy, Document doc) {
208 // ---------------------------------------
209 if (!aStudy.publishes(doc)) {
210 Scenario[] scene = aStudy.getScenarii();
211 for (int i = 0; i < scene.length; i++) {
212 if (scene[i].publishes(doc))
219 public boolean removeContributor(Study aStudy, User... users) {
220 // ------------------------------------------------
221 List<User> contributor = aStudy.getModifiableContributors(); // Initializes contributor
222 Boolean done = false;
223 for (int i = 0; i < users.length; i++) {
224 User user = users[i];
225 for (Iterator<User> j = contributor.iterator(); j.hasNext();) {
226 User present = j.next();
227 if (!present.equals(user))
230 aStudy.removeRelation(ContributorRelation.class, user);
231 j.remove(); // Updates the contributor shortcut
241 public boolean removeProjectContext(Study aStudy, SimulationContext context) {
242 // ---------------------------------------------------------------
243 boolean done = getStepService().removeSimulationContext(
244 getProjectElementService().getFirstStep(aStudy), context);
249 public void setValidationCycle(Study aStudy, DocumentType type,
250 ValidationCycle.Properties vprop) {
251 HashMap<String, ValidationCycle> validactor = aStudy
252 .getValidationCycles();
253 if (validactor == null)
254 aStudy.setShortCuts(); // Initializes validactor and actor
256 String cname = type.getName();
257 ValidationCycle cycle = validactor.get(cname);
259 if (cycle != null && cycle.isAssigned()) {
260 cycle.resetActors(vprop);
263 cycle = new ValidationCycle(aStudy, vprop.setDocumentType(type));
265 ValidationCycleRelation link = cycle.getContext();
266 aStudy.addRelation(link);
267 validactor.put(cname, link.getTo()); // Replaces the cycle if exists as default,
268 } catch (Exception error) {
269 logger.error("Unable to re-index Knowledge Elements, reason:",
273 resetActorsShortCut(aStudy);
274 update(aStudy); // Re-index the study, just in case
277 private void resetActorsShortCut(Study aStudy) {
278 aStudy.getModifiableActors().clear();
279 // Get all actors involved in validation cycles
280 for (Iterator<ValidationCycle> i = aStudy.getValidationCycles()
281 .values().iterator(); i.hasNext();) {
282 ValidationCycle cycle = i.next();
283 User[] user = cycle.getAllActors();
284 for (int j = 0; j < user.length; j++)
285 aStudy.getModifiableActors().add(user[j]);
287 // Get all other actors
288 for (Iterator<Relation> i = aStudy.getAllRelations().iterator(); i
290 Relation link = i.next();
291 Class<?> kindof = link.getClass().getSuperclass();
292 if (!kindof.equals(ActorRelation.class))
294 aStudy.getModifiableActors().add(((ActorRelation) link).getTo());
299 * Demotes this study from In-Check to In-Draft then In-Work states. This function is called internally when demoting the final result
300 * document of the study.
302 * @return true if the demotion succeeded.
304 public boolean demote(Study aStudy) {
305 // ---------------------------
306 if (aStudy.getProgressState() == ProgressState.inCHECK)
307 aStudy.setProgressState(ProgressState.inDRAFT);
308 else if (aStudy.getProgressState() == ProgressState.inDRAFT)
309 aStudy.setProgressState(ProgressState.inWORK);
312 return update(aStudy);
315 public int generateLocalIndex(Study aStudy) {
316 aStudy.setLastLocalIndex(aStudy.getLastLocalIndex() + 1);
317 Database.getSession().update(aStudy);
318 return aStudy.getLastLocalIndex();
321 // ==============================================================================================================================
322 // Public member functions
323 // ==============================================================================================================================
325 public Scenario addScenario(Study aStudy, Scenario.Properties sprop)
326 throws MissedPropertyException, InvalidPropertyException,
327 MultiplyDefinedException, RuntimeException {
328 // -------------------------------------------------------
329 if (sprop.getManager() == null)
330 sprop.setManager(aStudy.getAuthor());
332 Scenario scenario = new Scenario(sprop.setOwnerStudy(aStudy));
333 if (sprop.getBaseStep() != null)
335 .copyContentsUpTo(scenario, sprop.getBaseStep());
336 Scenario previous = sprop.getInsertAfter();
337 Session session = Database.getSession();
339 if (previous == null) {
340 aStudy.getScenariiList().add(scenario);
342 aStudy.getScenariiList().add(
343 aStudy.getScenariiList().indexOf(previous) + 1, scenario);
345 session.update(aStudy); // No need to update the Lucene index
346 session.save(scenario); // Must be done after updating this study because of the back reference to the study
347 if (sprop.getBaseStep() != null) {
348 // No need to update the Knowledge Element index as Knowledge Elements are not copied
349 scenario.refresh(); // Because saving the scenario changes the hashcode of copied Publications
351 KnowledgeElementType ucase = KnowledgeElement.selectType("usecase");
352 KnowledgeElement.Properties kprop = new KnowledgeElement.Properties();
353 User admin = UserDirectory.selectUser(1); // First user created when creating the database
354 kprop.setType(ucase).setTitle(aStudy.getTitle())
355 .setValue(scenario.getTitle()).setAuthor(admin); // Internal Knowledge Element required by the validation process of
357 getScenarioService().addKnowledgeElement(scenario, kprop);
364 private ScenarioService getScenarioService() {
365 return _scenarioService;
368 public void setScenarioService(ScenarioService scenarioService) {
369 _scenarioService = scenarioService;
373 * Promotes this study from In-Work to In-Draft then In-Check and APPROVED states. This function is called internally when promoting the
374 * final result document of the study.
376 * @return true if the demotion succeeded.
378 public boolean promote(Study aStudy) {
379 // ----------------------------
380 if (aStudy.getProgressState() == ProgressState.inWORK) {
381 aStudy.setProgressState(ProgressState.inDRAFT);
382 } else if (aStudy.getProgressState() == ProgressState.inDRAFT) {
383 aStudy.setProgressState(ProgressState.inCHECK);
384 Revision myvers = new Revision(aStudy.getVersion());
385 if (myvers.isMinor()) {
386 aStudy.setVersion(myvers.incrementAs(aStudy.getProgressState())
389 } else if (aStudy.getProgressState() == ProgressState.inCHECK) {
390 aStudy.setProgressState(ProgressState.APPROVED);
394 return update(aStudy);
398 * Moves this study from the Private to the Public area of the repository.
400 * @return true if the move succeeded.
403 public boolean moveToPublic(Study aStudy) {
404 // ------------------------------
405 if (aStudy.getVisibility() != Visibility.PRIVATE)
408 aStudy.setVisibility(Visibility.PUBLIC);
409 if (update(aStudy)) {
410 return updateKnowledgeElementsIndex(aStudy); // If fails, the database roll-back is under responsibility of the caller
415 private boolean update(Study aStudy) {
417 Database.getSession().update(aStudy); // Update of relational base
418 getIndex().update(aStudy); // Update of Lucene index
420 } catch (Exception error) {
421 logger.error("Unable to re-index the study '" + aStudy.getIndex()
422 + "', reason:", error);
427 private boolean updateKnowledgeElementsIndex(Study aStudy) {
428 // ----------------------------------------------
430 IndexService lucin = getIndex();
432 for (Iterator<Scenario> i = aStudy.getScenariiList().iterator(); i
434 Scenario scene = i.next();
435 for (Iterator<KnowledgeElement> j = scene
436 .getAllKnowledgeElements().iterator(); j.hasNext();) {
437 KnowledgeElement kelm = j.next();
442 } catch (Exception error) {
443 logger.error("Unable to re-index Knowledge Elements, reason:",
452 public IndexService getIndexService() {
453 return _indexService;
456 public void setIndexService(IndexService indexService) {
457 _indexService = indexService;
461 * Get project settings.
463 * @return Project settings service
465 private ProjectSettingsService getProjectSettings() {
466 return _projectSettingsService;
470 * Set project settings service.
472 * @param projectSettingsService
473 * project settings service
475 public void setProjectSettings(ProjectSettingsService projectSettingsService) {
476 _projectSettingsService = projectSettingsService;
480 * Get the projectElementService.
482 * @return the projectElementService
484 public ProjectElementService getProjectElementService() {
485 return _projectElementService;
489 * Set the projectElementService.
491 * @param projectElementService
492 * the projectElementService to set
494 public void setProjectElementService(
495 ProjectElementService projectElementService) {
496 _projectElementService = projectElementService;