/*****************************************************************************
- * Company EURIWARE
+ * Company OPEN CASCADE
* Application SIMAN
* File $Id$
* Creation date 06.10.2012
import java.util.List;
import org.apache.log4j.Logger;
-import org.hibernate.HibernateException;
-import org.hibernate.Session;
-import org.hibernate.Transaction;
import org.splat.dal.bo.kernel.User;
import org.splat.dal.bo.som.KnowledgeElement;
-import org.splat.dal.bo.som.ProjectElement;
+import org.splat.dal.bo.som.KnowledgeElementType;
import org.splat.dal.bo.som.Publication;
import org.splat.dal.bo.som.Scenario;
import org.splat.dal.bo.som.SimulationContext;
import org.splat.dal.bo.som.Study;
-import org.splat.dal.dao.som.Database;
+import org.splat.dal.dao.kernel.UserDAO;
+import org.splat.dal.dao.som.KnowledgeElementDAO;
+import org.splat.dal.dao.som.KnowledgeElementTypeDAO;
+import org.splat.dal.dao.som.ScenarioDAO;
+import org.splat.dal.dao.som.StudyDAO;
import org.splat.kernel.InvalidPropertyException;
import org.splat.kernel.MissedPropertyException;
import org.splat.kernel.MultiplyDefinedException;
import org.splat.service.technical.IndexService;
import org.splat.som.Step;
+import org.springframework.transaction.annotation.Transactional;
/**
- * @author RKV
+ * Scenario service implementation.
*
+ * @author <a href="mailto:roman.kozlov@opencascade.com">Roman Kozlov (RKV)</a>
*/
public class ScenarioServiceImpl implements ScenarioService {
+ /**
+ * Logger for this class.
+ */
protected final static Logger logger = Logger
.getLogger(ScenarioServiceImpl.class);
+ /**
+ * Injected index service.
+ */
private IndexService _indexService;
+ /**
+ * Injected step service.
+ */
private StepService _stepService;
+ /**
+ * Injected study service.
+ */
+ private StudyService _studyService;
+ /**
+ * Injected publication service.
+ */
private PublicationService _publicationService;
+ /**
+ * Injected project element service.
+ */
private ProjectElementService _projectElementService;
+ /**
+ * Injected knowledge element DAO.
+ */
+ private KnowledgeElementDAO _knowledgeElementDAO;
+ /**
+ * Injected scenario DAO.
+ */
+ private ScenarioDAO _scenarioDAO;
+
+ /**
+ * Injected study DAO.
+ */
+ private StudyDAO _studyDAO;
+
+ /**
+ * Injected knowledge element service.
+ */
+ private KnowledgeElementTypeService _knowledgeElementTypeService;
+
+ /**
+ * Injected user service.
+ */
+ private UserService _userService;
+
+ /**
+ * Injected user DAO.
+ */
+ private UserDAO _userDAO;
+
+ /**
+ * Injected knowledge element type DAO.
+ */
+ private KnowledgeElementTypeDAO _knowledgeElementTypeDAO;
+
+ /**
+ * Injected simulation context service.
+ */
+ private SimulationContextService _simulationContextService;
/**
* Get the projectElementService.
+ *
* @return the projectElementService
*/
public ProjectElementService getProjectElementService() {
/**
* Set the projectElementService.
- * @param projectElementService the projectElementService to set
+ *
+ * @param projectElementService
+ * the projectElementService to set
*/
- public void setProjectElementService(ProjectElementService projectElementService) {
+ public void setProjectElementService(
+ ProjectElementService projectElementService) {
_projectElementService = projectElementService;
}
/**
* Get the publicationService.
+ *
* @return the publicationService
*/
public PublicationService getPublicationService() {
/**
* Set the publicationService.
- * @param publicationService the publicationService to set
+ *
+ * @param publicationService
+ * the publicationService to set
*/
public void setPublicationService(PublicationService publicationService) {
_publicationService = publicationService;
/**
* Get the stepService.
+ *
* @return the stepService
*/
public StepService getStepService() {
/**
* Set the stepService.
- * @param stepService the stepService to set
+ *
+ * @param stepService
+ * the stepService to set
*/
public void setStepService(StepService stepService) {
_stepService = stepService;
}
- public KnowledgeElement addKnowledgeElement(Scenario aScenario,
+ /**
+ * Create a new study with one scenario and "product" simulation context.
+ *
+ * @param sprop
+ * the study properties
+ * @param oprop
+ * the scenario properties
+ * @param cprop
+ * the "product" simulation context properties
+ * @return the created study
+ * @throws MissedPropertyException
+ * if a mandatory property is missed
+ * @throws InvalidPropertyException
+ * if a property is invalid
+ * @throws MultiplyDefinedException
+ * if some property occurs several times
+ */
+ @Transactional
+ public Study createStudy(Study.Properties sprop, Scenario.Properties oprop,
+ SimulationContext.Properties cprop) throws MissedPropertyException,
+ InvalidPropertyException, MultiplyDefinedException {
+ Study study = getStudyService().createStudy(sprop);
+ addScenario(study, oprop);
+ if (cprop.getIndex() == 0) { // Input of new project context
+ cprop.setType(getSimulationContextService().selectType("product"))
+ .setValue(cprop.getValue());
+ getStudyService().addProjectContext(study, cprop);
+ } else { // Selection of existing project context
+ SimulationContext context = getSimulationContextService()
+ .selectSimulationContext(cprop.getIndex());
+ getStudyService().addProjectContext(study, context);
+ }
+ return study;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.splat.service.ScenarioService#addKnowledgeElement(org.splat.dal.bo.som.Scenario,
+ * org.splat.dal.bo.som.KnowledgeElement.Properties)
+ */
+ @Transactional
+ public KnowledgeElement addKnowledgeElement(Scenario aScenarioDTO,
KnowledgeElement.Properties kprop) throws MissedPropertyException,
InvalidPropertyException, MultiplyDefinedException {
- // -------------------------------------------------------------------------------
- KnowledgeElement kelm = new KnowledgeElement(
- kprop.setOwnerScenario(aScenario));
- Session session = Database.getSession();
- Transaction transax = session.getTransaction();
+ KnowledgeElement kelm = null;
try {
- session.save(kelm);
- session.flush(); //RKV
- // Update of my persistent data
- aScenario.getKnowledgeElements().add(kelm);
- session.merge(aScenario); //RKV
- // Update of my transient data
- List<KnowledgeElement> known = aScenario
- .getKnowledgeElementsOf(kelm.getType()); // Initializes this.known, if not yet done
- known.add(kelm);
+ long aScenarioId = aScenarioDTO.getIndex();
+ if (logger.isDebugEnabled()) {
+ logger.debug("Add a knowledge element to the scenario #"
+ + aScenarioId);
+ }
+ // Get the persistent scenario.
+ Scenario aScenario = getScenarioDAO().get(aScenarioId);
+ // Get persistent objects for creating a new knowledge.
+ // TODO: Actions must use DTO instead of persistent objects.
+ getUserDAO().merge(kprop.getAuthor());
+ getKnowledgeElementTypeDAO().merge(kprop.getType());
+ // Create a transient knowledge element related to the given scenario.
+ kelm = new KnowledgeElement(kprop.setOwnerScenario(aScenario));
+ // Save the new knowledge in the database.
+ getKnowledgeElementDAO().create(kelm);
+ // Update scenario transient data.
if (kelm.getType().equals("usecase")) {
- aScenario.setUcase(kelm);
- } else if (aScenario.getKnowledgeElementsList() != null) { // If null, knowl will be initialized when needed
- aScenario.getKnowledgeElementsList().add(kelm);
+ aScenarioDTO.setUcase(kelm);
+ } else if (aScenarioDTO.getKnowledgeElementsList() != null) { // If null, knowl will be initialized when needed
+ aScenarioDTO.getKnowledgeElementsList().add(kelm);
}
- // Update of the index of Knowledge Elements
+ // Update the lucene index of knowledge elements.
getIndexService().add(kelm);
- update(aScenario);
- return kelm;
- } catch (RuntimeException e) {
- if (transax != null && transax.isActive()) {
- // Second try-catch as the rollback could fail as well
- try {
- transax.rollback();
- } catch (HibernateException error) {
- logger.debug("Error rolling back transaction", error);
- }
- // Throw again the first exception
- throw e;
+ if (logger.isDebugEnabled()) {
+ logger.debug("A knowledge element #" + kelm.getIndex()
+ + " is added to the scenario #" + aScenario.getIndex());
}
- return null;
} catch (IOException error) {
- logger.error(
- "Unable to index the knowedge element '" + kelm.getIndex()
- + "', reason:", error);
- return null;
+ logger.error("Unable to index the knowedge element '"
+ + kelm.getIndex() + "', reason:", error);
+ kelm = null;
}
+
+ return kelm;
}
+ /**
+ * Update the scenario in the database.
+ *
+ * @param aScenario
+ * the scenario to update
+ * @return true if updating succeeded
+ */
+ @Transactional
private boolean update(Scenario aScenario) {
- // ---------------------------
+ boolean isOk = false;
try {
- Database.getSession().update(aScenario); // Update of relational base
- return true;
+ getScenarioDAO().update(aScenario); // Update of relational base
+ isOk = true;
} catch (Exception error) {
logger.error("Unable to re-index the knowledge element '"
+ aScenario.getIndex() + "', reason:", error);
+ }
+ return isOk;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.splat.service.ScenarioService#checkin(org.splat.dal.bo.som.Scenario)
+ */
+ public void checkin(Scenario aScenario) {
+ aScenario.setUser(null);
+ aScenario.setLastModificationDate(Calendar.getInstance().getTime());
+ getScenarioDAO().update(aScenario);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.splat.service.ScenarioService#checkout(org.splat.dal.bo.som.Scenario, org.splat.dal.bo.kernel.User)
+ */
+ public boolean checkout(Scenario aScenario, User user) {
+ if (!getStudyService().isStaffedBy(aScenario.getOwnerStudy(), user))
return false;
+
+ aScenario.setUser(user);
+ aScenario.setLastModificationDate(Calendar.getInstance().getTime());
+ getScenarioDAO().update(aScenario);
+ return true;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.splat.service.ScenarioService#copyContentsUpTo(org.splat.dal.bo.som.Scenario, org.splat.som.Step)
+ */
+ public void copyContentsUpTo(Scenario scenario, Step lastep) {
+ Scenario base = (Scenario) lastep.getOwner();
+ Step[] from = getProjectElementService().getSteps(base);
+ Step[] to = getProjectElementService().getSteps(scenario);
+ for (int i = 0; i < from.length; i++) {
+ Step step = from[i];
+ if (step.getNumber() > lastep.getNumber())
+ break;
+
+ List<Publication> docs = step.getAllDocuments();
+ for (Iterator<Publication> j = docs.iterator(); j.hasNext();) {
+ Publication doc = getPublicationService().copy(j.next(),
+ scenario); // Creation of a new reference to the document
+ // Database.getSession().save(doc); Publications MUST be saved later through cascading when saving the scenario
+ getStepService().add(to[i], doc);
+ }
+ List<SimulationContext> ctex = step.getAllSimulationContexts();
+ for (Iterator<SimulationContext> j = ctex.iterator(); j.hasNext();) {
+ getStepService().addSimulationContext(to[i], j.next());
+ }
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.splat.service.ScenarioService#isEmpty(org.splat.dal.bo.som.Scenario)
+ */
+ public boolean isEmpty(Scenario scenario) {
+ Step[] mystep = getProjectElementService().getSteps(scenario);
+ boolean isEmp = true;
+ for (int i = 0; i < mystep.length; i++) {
+ if (mystep[i].isStarted()) {
+ isEmp = false;
+ break;
+ }
}
+ return isEmp;
}
/**
+ * @param scenario
* @return
*/
+ public boolean isFinished(Scenario scenario) {
+ Step[] mystep = getProjectElementService().getSteps(scenario);
+ boolean notempty = false; // If this is empty, this is not finished
+ for (int i = 0; i < mystep.length; i++) {
+ if (!mystep[i].isStarted())
+ continue;
+ if (!mystep[i].isFinished())
+ return false;
+ notempty = true;
+ }
+ return notempty;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.splat.service.StudyService#addScenario(org.splat.dal.bo.som.Study, org.splat.dal.bo.som.Scenario.Properties)
+ */
+ @Transactional
+ public Scenario addScenario(Study aStudy, Scenario.Properties sprop)
+ throws MissedPropertyException, InvalidPropertyException,
+ MultiplyDefinedException {
+ if (sprop.getManager() == null)
+ sprop.setManager(aStudy.getAuthor());
+
+ Scenario scenario = new Scenario(sprop.setOwnerStudy(aStudy));
+ if (sprop.getBaseStep() != null)
+ copyContentsUpTo(scenario, sprop.getBaseStep());
+ Scenario previous = sprop.getInsertAfter();
+
+ if (previous == null) {
+ aStudy.getScenariiList().add(scenario);
+ } else {
+ aStudy.getScenariiList().add(
+ aStudy.getScenariiList().indexOf(previous) + 1, scenario);
+ }
+ getStudyDAO().update(aStudy); // No need to update the Lucene index
+ getScenarioDAO().create(scenario); // Must be done after updating this study because of the back reference to the study
+ if (sprop.getBaseStep() != null) {
+ // No need to update the Knowledge Element index as Knowledge Elements are not copied
+ getProjectElementService().refresh(scenario); // Because saving the scenario changes the hashcode of copied Publications
+ }
+ KnowledgeElementType ucase = getKnowledgeElementTypeService()
+ .selectType("usecase");
+ KnowledgeElement.Properties kprop = new KnowledgeElement.Properties();
+ User admin = getUserService().selectUser(1); // First user created when creating the database
+ kprop.setType(ucase).setTitle(aStudy.getTitle()).setValue(
+ scenario.getTitle()).setAuthor(admin); // Internal Knowledge Element required by the validation process of
+ // knowledges
+ addKnowledgeElement(scenario, kprop);
+ return scenario;
+ }
+
+ /**
+ * Remove a knowledge element from a scenario.
+ *
+ * @param scenario
+ * the scenario
+ * @param kelm
+ * the knowledge element to remove
+ * @return true if removal succeeded
+ */
+ public boolean removeKnowledgeElement(Scenario scenario,
+ KnowledgeElement kelm) {
+ KnowledgeElement torem = scenario.getKnowledgeElement(kelm.getIndex());
+ if (torem == null)
+ return false;
+ boolean done = scenario.getKnowledgeElements().remove(torem);
+ if (done) {
+ // Update of my transient data
+ // RKV: These transient data are not used indeed.
+ // RKV: List<KnowledgeElement> kelms = scenario.getKnowledgeByType().get(
+ // RKV: kelm.getType().getIndex());
+ // RKV: kelms.remove(torem);
+ if (scenario.getKnowledgeElementsList() != null)
+ scenario.getKnowledgeElementsList().remove(torem);
+ getScenarioDAO().update(scenario);
+ // TODO: If the owner study is not private, remove the knowledge from the Lucene index
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Get the knowledgeElementDAO.
+ *
+ * @return the knowledgeElementDAO
+ */
+ public KnowledgeElementDAO getKnowledgeElementDAO() {
+ return _knowledgeElementDAO;
+ }
+
+ /**
+ * Set the knowledgeElementDAO.
+ *
+ * @param knowledgeElementDAO
+ * the knowledgeElementDAO to set
+ */
+ public void setKnowledgeElementDAO(KnowledgeElementDAO knowledgeElementDAO) {
+ _knowledgeElementDAO = knowledgeElementDAO;
+ }
+
+ /**
+ * Get the indexService.
+ *
+ * @return the indexService
+ */
public IndexService getIndexService() {
return _indexService;
}
+ /**
+ * Set the indexService.
+ *
+ * @param indexService
+ * the indexService to set
+ */
public void setIndexService(IndexService indexService) {
_indexService = indexService;
}
- public void checkin(Scenario aScenario) {
- // ----------------------
- aScenario.setUser(null);
- aScenario.setLastModificationDate(Calendar.getInstance().getTime());
- Database.getSession().update(aScenario);
+ /**
+ * Get the scenarioDAO.
+ *
+ * @return the scenarioDAO
+ */
+ public ScenarioDAO getScenarioDAO() {
+ return _scenarioDAO;
}
- public boolean checkout(Scenario aScenario, User user) {
- // -----------------------------------
- if (!aScenario.getOwnerStudy().isStaffedBy(user))
- return false;
+ /**
+ * Set the scenarioDAO.
+ *
+ * @param scenarioDAO
+ * the scenarioDAO to set
+ */
+ public void setScenarioDAO(ScenarioDAO scenarioDAO) {
+ _scenarioDAO = scenarioDAO;
+ }
- aScenario.setUser(user);
- aScenario.setLastModificationDate(Calendar.getInstance().getTime());
- Database.getSession().update(aScenario);
- return true;
+ /**
+ * Get the studyDAO.
+ *
+ * @return the studyDAO
+ */
+ public StudyDAO getStudyDAO() {
+ return _studyDAO;
+ }
+
+ /**
+ * Set the studyDAO.
+ *
+ * @param studyDAO
+ * the studyDAO to set
+ */
+ public void setStudyDAO(StudyDAO studyDAO) {
+ _studyDAO = studyDAO;
+ }
+
+ /**
+ * Get the knowledgeElementTypeService.
+ *
+ * @return the knowledgeElementTypeService
+ */
+ public KnowledgeElementTypeService getKnowledgeElementTypeService() {
+ return _knowledgeElementTypeService;
+ }
+
+ /**
+ * Set the knowledgeElementTypeService.
+ *
+ * @param knowledgeElementTypeService
+ * the knowledgeElementTypeService to set
+ */
+ public void setKnowledgeElementTypeService(
+ KnowledgeElementTypeService knowledgeElementTypeService) {
+ _knowledgeElementTypeService = knowledgeElementTypeService;
+ }
+
+ /**
+ * Get the studyService.
+ *
+ * @return the studyService
+ */
+ public StudyService getStudyService() {
+ return _studyService;
+ }
+
+ /**
+ * Set the studyService.
+ *
+ * @param studyService
+ * the studyService to set
+ */
+ public void setStudyService(StudyService studyService) {
+ _studyService = studyService;
+ }
+
+ /**
+ * Get the userService.
+ *
+ * @return the userService
+ */
+ public UserService getUserService() {
+ return _userService;
+ }
+
+ /**
+ * Set the userService.
+ *
+ * @param userService
+ * the userService to set
+ */
+ public void setUserService(UserService userService) {
+ _userService = userService;
+ }
+
+ /**
+ * Get the userDAO.
+ *
+ * @return the userDAO
+ */
+ public UserDAO getUserDAO() {
+ return _userDAO;
+ }
+
+ /**
+ * Set the userDAO.
+ *
+ * @param userDAO
+ * the userDAO to set
+ */
+ public void setUserDAO(UserDAO userDAO) {
+ _userDAO = userDAO;
+ }
+
+ /**
+ * Get the knowledgeElementTypeDAO.
+ *
+ * @return the knowledgeElementTypeDAO
+ */
+ public KnowledgeElementTypeDAO getKnowledgeElementTypeDAO() {
+ return _knowledgeElementTypeDAO;
}
- // ==============================================================================================================================
- // Private services
- // ==============================================================================================================================
-
- public void copyContentsUpTo (Scenario scenario, Step lastep) {
- // -------------------------------------------
- Scenario base = (Scenario)lastep.getOwner();
- Step[] from = getProjectElementService().getSteps(base);
- Step[] to = getProjectElementService().getSteps(scenario);
- for (int i=0; i<from.length; i++) {
- Step step = from[i];
- if (step.getNumber() > lastep.getNumber()) break;
-
- List<Publication> docs = step.getAllDocuments();
- for (Iterator<Publication> j=docs.iterator(); j.hasNext(); ) {
- Publication doc = getPublicationService().copy(j.next(), scenario); // Creation of a new reference to the document
- // Database.getSession().save(doc); Publications MUST be saved later through cascading when saving the scenario
- to[i].add(doc);
- }
- List<SimulationContext> ctex = step.getAllSimulationContexts();
- for (Iterator<SimulationContext> j=ctex.iterator(); j.hasNext(); ) {
- getStepService().addSimulationContext(to[i], j.next());
- }
- }
- }
-
- public boolean isEmpty (Scenario scenario) {
- // -------------------------
- Step[] mystep = getProjectElementService().getSteps(scenario);
- for (int i=0; i<mystep.length; i++) if (mystep[i].isStarted()) return false;
- return true;
- }
-
- public boolean isFinished (Scenario scenario) {
- // ----------------------------
- Step[] mystep = getProjectElementService().getSteps(scenario);
- boolean notempty = false; // If this is empty, this is not finished
- for (int i=0; i<mystep.length; i++) {
- if (!mystep[i].isStarted()) continue;
- if (!mystep[i].isFinished()) return false;
- notempty = true;
- }
- return notempty;
- }
+ /**
+ * Set the knowledgeElementTypeDAO.
+ *
+ * @param knowledgeElementTypeDAO
+ * the knowledgeElementTypeDAO to set
+ */
+ public void setKnowledgeElementTypeDAO(
+ KnowledgeElementTypeDAO knowledgeElementTypeDAO) {
+ _knowledgeElementTypeDAO = knowledgeElementTypeDAO;
+ }
+
+ /**
+ * Get the simulationContextService.
+ *
+ * @return the simulationContextService
+ */
+ public SimulationContextService getSimulationContextService() {
+ return _simulationContextService;
+ }
+
+ /**
+ * Set the simulationContextService.
+ *
+ * @param simulationContextService
+ * the simulationContextService to set
+ */
+ public void setSimulationContextService(
+ SimulationContextService simulationContextService) {
+ _simulationContextService = simulationContextService;
+ }
}