4 * @author Daniel Brunier-Coulin
5 * @copyright OPEN CASCADE 2012
8 import java.io.IOException;
9 import java.util.Calendar;
10 import java.util.Collections;
11 import java.util.Date;
12 import java.util.HashMap;
13 import java.util.Iterator;
14 import java.util.List;
16 import java.util.HashSet;
17 import java.util.Vector;
19 import org.hibernate.HibernateException;
20 import org.hibernate.Session;
21 import org.hibernate.Transaction;
22 import org.splat.kernel.Persistent;
23 import org.splat.kernel.InvalidPropertyException;
24 import org.splat.kernel.MissedPropertyException;
25 import org.splat.kernel.MultiplyDefinedException;
26 import org.splat.kernel.User;
29 public class Scenario extends ProjectElement {
33 private int sid; // Identifier unique in the scope of owner study
34 private User cuser; // User having checked-out the scenario, if done
35 private Set<KnowledgeElement> kelms;
38 private HashMap<Integer, List<KnowledgeElement>> known;
39 private List<KnowledgeElement> knowl; // Copy of kelms excluding the internal Knowledge Element (ucase below)
40 private KnowledgeElement ucase; // Internal Knowledge Element for accessing to all used simulation contexts
43 // ==============================================================================================================================
45 // ==============================================================================================================================
47 // Fields initialization class
48 public static class Properties extends Persistent.Properties {
49 // ------------------------------------------------------------
50 private Study owner = null;
51 private Scenario previous = null;
52 private Step base = null;
53 private String title = null;
54 private String summary = null;
55 private User manager = null;
56 private Date date = null;
60 public void clear () {
70 // - Protected services
72 protected Step getBaseStep () {
73 return base; // May be null
75 protected Scenario getInsertAfter () {
76 return previous; // May be null
78 protected User getManager () {
81 protected Properties setOwnerStudy (Study owner)
86 // - Setters of Scenario properties
88 public Properties setBaseStep (Step base) throws InvalidPropertyException
90 if (!(base.getOwner() instanceof Scenario)) throw new InvalidPropertyException("step");
94 public Properties setDate (Date date)
99 public Properties setDescription (String summary)
101 if (summary.length() > 0) this.summary = summary;
104 public Properties setInsertAfter (Scenario previous)
106 this.previous = previous;
109 public Properties setManager (User user)
114 public Properties setTitle (String title) throws InvalidPropertyException
116 if (title.length() == 0) throw new InvalidPropertyException("title");
120 // - Global validity check
122 public void checkValidity() throws MissedPropertyException, InvalidPropertyException, MultiplyDefinedException
124 if (owner == null) throw new MissedPropertyException("owner");
125 if (title == null) throw new MissedPropertyException("title");
126 if (manager == null) throw new MissedPropertyException("manager");
129 // Database fetch constructor
130 protected Scenario () {
131 // ---------------------
136 // Internal constructor
137 protected Scenario (Properties sprop) throws MissedPropertyException, InvalidPropertyException, MultiplyDefinedException {
138 // -------------------------------------
139 super(sprop); // Throws one of the above exception if not valid
143 title = sprop.title; // Inherited attribute
145 knowl = null; // Initialized when getting all Knowledge Elements
147 kelms = new HashSet<KnowledgeElement>();
149 manager = sprop.manager;
150 if (!owner.isStaffedBy(manager)) throw new InvalidPropertyException("manager");
152 credate = sprop.date; // Inherited attribute
153 if (credate == null) {
154 Calendar current = Calendar.getInstance();
155 credate = current.getTime(); // Today
157 lasdate = credate; // Inherited attribute
159 if (sprop.summary != null) this.setAttribute( new DescriptionAttribute(this, sprop.summary) );
161 Scenario[] scene = owner.getScenarii();
162 for (int i=0; i<scene.length; i++) if (scene[i].sid > this.sid) this.sid = scene[i].sid;
164 if (sprop.base != null) copyContentsUpTo(sprop.base);
167 // ==============================================================================================================================
168 // Public member functions
169 // ==============================================================================================================================
171 public KnowledgeElement addKnowledgeElement (KnowledgeElement.Properties kprop) throws MissedPropertyException, InvalidPropertyException, MultiplyDefinedException {
172 // -------------------------------------------------------------------------------
173 KnowledgeElement kelm = new KnowledgeElement(kprop.setOwnerScenario(this));
174 Session session = Database.getSession();
175 Transaction transax = session.getTransaction();
178 // Update of my persistent data
180 // Update of my transient data
181 List<KnowledgeElement> known = getKnowledgeElementsOf(kelm.getType()); // Initializes this.known, if not yet done
183 if (kelm.getType().equals("usecase")) {
186 if (knowl != null) { // If null, knowl will be initialized when needed
189 // Update of the index of Knowledge Elements
190 Database.getIndex().add(kelm);
194 catch (RuntimeException e) {
195 if (transax != null && transax.isActive()) {
196 // Second try-catch as the rollback could fail as well
199 } catch (HibernateException error) {
200 Study.logger.debug("Error rolling back transaction", error);
202 // Throw again the first exception
207 catch (IOException error) {
208 logger.error("Unable to index the knowedge element '" + kelm.getIndex() + "', reason:", error);
213 public void checkin () {
214 // ----------------------
216 lasdate = Calendar.getInstance().getTime();
217 Database.getSession().update(this);
220 public boolean checkout (User user) {
221 // -----------------------------------
222 if (!owner.isStaffedBy(user)) return false;
225 lasdate = Calendar.getInstance().getTime();
226 Database.getSession().update(this);
230 public List<KnowledgeElement> getAllKnowledgeElements () {
231 // --------------------------------------------------------
233 knowl = new Vector<KnowledgeElement>(kelms.size());
234 for (Iterator<KnowledgeElement> i=kelms.iterator(); i.hasNext(); ) {
235 KnowledgeElement kelm = i.next();
236 if (kelm.getType().equals("usecase")) ucase = kelm;
237 else knowl.add(kelm);
240 return Collections.unmodifiableList(knowl);
243 public KnowledgeElement getKnowledgeElement (int index) {
244 // -------------------------------------------------------
245 for (Iterator<KnowledgeElement> i=kelms.iterator(); i.hasNext();) {
246 KnowledgeElement mykelm = i.next();
247 if (mykelm.getIndex() == index) return mykelm;
252 public List<KnowledgeElement> getKnowledgeElementsOf (KnowledgeElementType type) {
253 // --------------------------------------------------------------------------------
254 if (kelms.isEmpty()) return new Vector<KnowledgeElement>(); // Smarter than returning null
255 if (known == null) known = new HashMap<Integer, List<KnowledgeElement>>();
257 int numtype = type.getIndex();
258 List<KnowledgeElement> listype = known.get(numtype);
259 if (listype == null) {
260 listype = new Vector<KnowledgeElement>();
261 for (Iterator<KnowledgeElement> i=kelms.iterator(); i.hasNext();) {
262 KnowledgeElement kelm = i.next();
263 if (kelm.getType().getIndex() == numtype) listype.add(kelm);
265 known.put(numtype, listype);
267 return listype; // No protection against this object corruption as it would not corrupt the database
270 public Study getOwnerStudy () {
271 // -----------------------------
275 * Returns the local reference of this scenario. This reference is unique in the scope of the owner study.
277 public String getReference () {
278 // -----------------------------
279 return String.valueOf(sid);
282 public User getUser () {
283 // ----------------------
284 return cuser; // Null if the scenario has not been checked-out
287 public boolean removeKnowledgeElement (KnowledgeElement kelm) {
288 // -------------------------------------------------------------
289 KnowledgeElement torem = getKnowledgeElement(kelm.getIndex());
290 if (torem == null) return false;
291 boolean done = kelms.remove(torem);
293 // Update of my transient data
294 List<KnowledgeElement> kelms = known.get(kelm.getType().getIndex());
296 if (knowl != null) knowl.remove(torem);
297 Database.getSession().update(this);
298 //TODO: If the owner study is not private, remove the knowledge from the Lucene index
305 public boolean isCheckedout () {
306 // ------------------------------
307 return (cuser != null);
310 public boolean isEmpty () {
311 // -------------------------
312 Step[] mystep = this.getSteps();
313 for (int i=0; i<mystep.length; i++) if (mystep[i].isStarted()) return false;
317 public boolean isFinished () {
318 // ----------------------------
319 Step[] mystep = this.getSteps();
320 boolean notempty = false; // If this is empty, this is not finished
321 for (int i=0; i<mystep.length; i++) {
322 if (!mystep[i].isStarted()) continue;
323 if (!mystep[i].isFinished()) return false;
329 // ==============================================================================================================================
330 // Protected member function
331 // ==============================================================================================================================
333 protected void updateMyIndex (Index lucin) throws IOException {
334 // ------------------------------------------
335 if (ucase == null) for (Iterator<KnowledgeElement> i=kelms.iterator(); i.hasNext(); ) {
336 KnowledgeElement kelm = i.next();
337 if (!kelm.getType().equals("usecase")) continue;
344 // ==============================================================================================================================
346 // ==============================================================================================================================
348 private void copyContentsUpTo (Step lastep) {
349 // -------------------------------------------
350 Scenario base = (Scenario)lastep.getOwner();
351 Step[] from = base.getSteps();
352 Step[] to = this.getSteps();
353 for (int i=0; i<from.length; i++) {
355 if (step.getNumber() > lastep.getNumber()) break;
357 List<Publication> docs = step.getAllDocuments();
358 for (Iterator<Publication> j=docs.iterator(); j.hasNext(); ) {
359 Publication doc = j.next().copy(this); // Creation of a new reference to the document
360 // Database.getSession().save(doc); Publications MUST be saved later through cascading when saving the scenario
363 List<SimulationContext> ctex = step.getAllSimulationContexts();
364 for (Iterator<SimulationContext> j=ctex.iterator(); j.hasNext(); ) {
365 to[i].addSimulationContext(j.next());
370 private boolean updateMe () {
371 // ---------------------------
373 Database.getSession().update(this); // Update of relational base
376 catch (Exception error) {
377 logger.error("Unable to re-index the knowledge element '" + getIndex() + "', reason:", error);