1 package org.splat.service.technical;
5 * @author Daniel Brunier-Coulin
6 * @copyright OPEN CASCADE 2012
10 import java.io.FileNotFoundException;
11 import java.io.IOException;
12 import java.sql.SQLException;
13 import java.util.HashMap;
14 import java.util.Iterator;
15 import java.util.LinkedHashMap;
16 import java.util.List;
17 import java.util.Properties;
19 import java.util.Vector;
21 import javax.xml.parsers.DocumentBuilder;
22 import javax.xml.parsers.DocumentBuilderFactory;
24 import org.apache.log4j.Logger;
25 import org.w3c.dom.NamedNodeMap;
26 import org.w3c.dom.Node;
27 import org.w3c.dom.NodeList;
29 import org.splat.dal.bo.som.Document;
30 import org.splat.dal.bo.som.DocumentType;
31 import org.splat.dal.bo.som.KnowledgeElement;
32 import org.splat.dal.bo.som.KnowledgeElementType;
33 import org.splat.dal.bo.som.ProjectElement;
34 import org.splat.dal.bo.som.Scenario;
35 import org.splat.dal.bo.som.SimulationContext;
36 import org.splat.dal.bo.som.SimulationContextType;
37 import org.splat.dal.bo.som.Study;
38 import org.splat.dal.bo.som.ValidationCycle.Actor;
39 import org.splat.dal.dao.som.Database;
40 import org.splat.manox.XDOM;
41 import org.splat.service.SimulationContextService;
43 public class ProjectSettingsServiceImpl implements ProjectSettingsService {
45 // Non persistent configuration information
46 private Properties reprop; // Repository settings
47 private String pattern; // Pattern of study references
48 private FileNaming naming; // Scheme of file names stored into the repository
49 private String versioning; // Pattern of the presentation of version numbers
50 private Vector<ProjectSettingsService.Step> steps; // Ordered list of (transient) study steps
51 private Vector<ProjectSettingsValidationCycle> concycles; // Configuration document validation cycles
53 // Temporary attributes initialized from the configuration file for populating the database with object types
54 private LinkedHashMap<String, String> mapuse; // Document type names and uses mapping
55 private Vector<String> context; // Simulation Context type names
56 private Vector<String> kname; // Knowledge Element type names
57 private Vector<NamedNodeMap> flows; // Document flows
58 private Vector<NamedNodeMap> sclass; // Study classifications
61 private static ProjectSettingsServiceImpl my = null; // Singleton instance
62 private Database _database;
64 * Injected simulation context service.
66 private SimulationContextService _simulationContextService;
67 protected final static Logger logger = Logger
68 .getLogger(ProjectSettingsServiceImpl.class);
70 public enum FileNaming {
74 public static class ProjectSettingsValidationCycle {
75 // -----------------------------------
77 private Actor[] actor;
79 private ProjectSettingsValidationCycle() {
80 this.name = "built-in";
81 this.actor = new Actor[] { null, null, null };
84 private ProjectSettingsValidationCycle(String name, Actor[] actor) {
89 public String getName() {
93 public Actor[] getActorTypes() {
98 // ==============================================================================================================================
100 // ==============================================================================================================================
101 protected ProjectSettingsServiceImpl() {
102 // ----------------------------
103 reprop = new Properties();
104 steps = new Vector<ProjectSettingsService.Step>();
108 // ==============================================================================================================================
110 // ==============================================================================================================================
112 public void configure(String filename) throws IOException, SQLException {
113 // ---------------------------------------
114 if (!steps.isEmpty())
115 return; // Project already configured
117 Database base = getDatabase().getMe();
118 File config = new File(filename);
119 if (config.exists()) {
120 loadCustomization(config);
122 logger.fatal("Could not find the database configuration file \""
123 + config.getAbsolutePath() + "\"");
124 throw new FileNotFoundException();
126 base.configure(reprop);
127 if (!base.isInitialized()) {
129 initialize(); // Populates the database with all necessary stuff
133 public List<ProjectSettingsService.Step> getAllSteps() {
134 // ---------------------------------------
139 * Return the validation cycles of result documents defined in the workflow, ordered by study activities and ending by the default
140 * validation cycle, if defined.
142 * @return the validation cycles of the workflow
144 public static List<ProjectSettingsValidationCycle> getAllValidationCycles() {
145 // -------------------------------------------------------------
149 public FileNaming getFileNamingScheme() {
150 // -----------------------------------------------
154 public static ProjectSettingsValidationCycle getNewValidationCycle() {
155 // ------------------------------------------------------
156 return new ProjectSettingsValidationCycle();
159 public String getReferencePattern() {
163 public String getRevisionPattern() {
164 // ------------------------------------------
168 public static ProjectSettingsService.Step getStep(int number) {
169 // ---------------------------------------
170 for (int i = 0; i < my.steps.size(); i++) {
171 ProjectSettingsService.Step step = my.steps.get(i);
172 if (step.number == number)
178 public List<ProjectSettingsService.Step> getStepsOf(
179 Class<? extends ProjectElement> level) {
180 // ---------------------------------------------------------------------------
181 Vector<ProjectSettingsService.Step> result = new Vector<ProjectSettingsService.Step>();
183 for (int i = 0; i < steps.size(); i++) {
184 ProjectSettingsService.Step step = steps.get(i);
185 if (step.appliesTo(level))
191 // ==============================================================================================================================
192 // Protected member function
193 // ==============================================================================================================================
195 public void initialize() {
196 // ----------------------------
197 createDocumentTypes();
198 createSimulationContextTypes();
199 createKnowledgeElementTypes();
202 // ==============================================================================================================================
203 // Private member function
204 // ==============================================================================================================================
206 private void loadCustomization(File config) {
207 // --------------------------------------------
209 DocumentBuilderFactory dfactory = javax.xml.parsers.DocumentBuilderFactory
211 DocumentBuilder dBuilder = dfactory.newDocumentBuilder();
213 org.w3c.dom.Document conf = dBuilder.parse(config.getPath());
214 HashMap<String, Node> children = XDOM.getNamedChildNodes(conf
215 .getDocumentElement());
217 // Repository tag initializing the reprop attribute
218 Node child = children.get("database");
219 HashMap<String, Node> datag = XDOM.getNamedChildNodes(child);
221 String disk = datag.get("repository").getAttributes().getNamedItem(
222 "disk").getNodeValue();
223 if (!disk.endsWith("/"))
225 logger.info("Database root set to " + disk);
226 reprop.setProperty("repository", disk);
228 // Formats tag initializing the reference pattern and date attributes
229 child = children.get("formats");
230 datag = XDOM.getNamedChildNodes(child);
232 NamedNodeMap natr = datag.get("references").getAttributes();
233 pattern = natr.getNamedItem("study").getNodeValue();
235 natr = datag.get("files").getAttributes();
236 naming = FileNaming.valueOf(natr.getNamedItem("name")
239 natr = datag.get("versions").getAttributes();
240 versioning = natr.getNamedItem("pattern").getNodeValue();
242 // Activities tag initializing the steps and rex attributes
243 child = children.get("activities");
244 NodeList nlist = child.getChildNodes();
245 Vector<NamedNodeMap> flist = new Vector<NamedNodeMap>();
246 Vector<String> resultype = new Vector<String>();
247 Vector<NamedNodeMap> clist = new Vector<NamedNodeMap>();
249 int snum = 1; // Base number of steps
250 for (int i = 0; i < nlist.getLength(); i++) {
251 child = nlist.item(i);
252 if (child.getNodeName().equals("scenario")) {
253 NodeList slist = child.getChildNodes();
254 for (int j = 0; j < slist.getLength(); j++) {
255 child = slist.item(j);
256 if (!child.getNodeName().equals("step"))
258 HashMap<String, Node> tags = XDOM
259 .getNamedChildNodes(child);
261 natr = tags.get("storage").getAttributes();
262 ProjectSettingsService.Step step = new ProjectSettingsService.Step(
263 snum, Scenario.class, natr.getNamedItem("path")
266 // Keeping flow and classification information for eventual later use
267 natr = tags.get("flow").getAttributes();
269 child = natr.getNamedItem("result");
271 resultype.add(child.getNodeValue());
273 child = tags.get("classification");
275 clist.add(child.getAttributes());
279 if (natr.getNamedItem("contents").getNodeValue()
280 .equals("knowledge")) {
281 // TODO In a given scenario, only one step must contain knowledges
282 step.contents.add(KnowledgeElement.class);
284 step.contents.add(Document.class);
290 if (!child.getNodeName().equals("step"))
292 HashMap<String, Node> tags = XDOM.getNamedChildNodes(child);
294 natr = tags.get("storage").getAttributes(); // Mandatory information
295 ProjectSettingsService.Step step = new ProjectSettingsService.Step(
296 snum, Study.class, natr.getNamedItem("path")
299 // Keeping flow and classification information for eventual later use
300 natr = tags.get("flow").getAttributes();
302 child = natr.getNamedItem("result");
304 resultype.add(child.getNodeValue());
306 child = tags.get("classification"); // Optional information
308 clist.add(child.getAttributes());
312 if (natr.getNamedItem("contents").getNodeValue().equals(
314 // TODO Error: knowledges must be attached to scenarios
316 step.contents.add(Document.class);
323 child = children.get("validations");
324 concycles = new Vector<ProjectSettingsValidationCycle>();
325 datag = XDOM.getNamedChildNodes(child);
327 String[] step = { "review", "approval", "acceptance" };
328 resultype.add("default");
329 for (Iterator<String> i = resultype.iterator(); i.hasNext();) {
330 Actor[] actor = { null, null, null };
331 String name = i.next();
332 child = datag.get(name);
334 continue; // Document type not subject of any validation
335 natr = child.getAttributes();
336 for (int j = 0; j < step.length; j++) {
337 child = natr.getNamedItem(step[j]);
339 continue; // Validation step not required
340 actor[j] = Actor.valueOf(child.getNodeValue());
342 concycles.add(new ProjectSettingsValidationCycle(name, actor));
344 concycles.add(new ProjectSettingsValidationCycle()); // Adds the built-in validation cycle
346 if (getDatabase().getMe().isInitialized())
347 return; // No need to load object type definitions as they are already stored
350 child = children.get("documents");
351 nlist = child.getChildNodes();
353 flows = flist; // Kept for later use in document type definition
354 sclass = clist; // Kept for later use in simulation context type definition
355 mapuse = new LinkedHashMap<String, String>();
356 for (int i = 0; i < nlist.getLength(); i++) {
357 child = nlist.item(i);
358 if (!child.getNodeName().equals("article"))
361 natr = child.getAttributes();
362 String type = natr.getNamedItem("type").getNodeValue();
364 child = natr.getNamedItem("uses");
366 uses = child.getNodeValue();
367 mapuse.put(type, uses); // Must be added to the map even if no (null) uses
369 // Simulation Contexts tag
370 child = children.get("contexts");
371 nlist = child.getChildNodes();
373 context = new Vector<String>();
374 for (int i = 0; i < nlist.getLength(); i++) {
375 child = nlist.item(i);
376 if (!child.getNodeName().equals("article"))
379 context.add(child.getAttributes().getNamedItem("type")
382 // Knowledge Elements tag
383 child = children.get("knowledges");
384 nlist = child.getChildNodes();
386 kname = new Vector<String>();
387 for (int i = 0; i < nlist.getLength(); i++) {
388 child = nlist.item(i);
389 if (!child.getNodeName().equals("article"))
392 kname.add(child.getAttributes().getNamedItem("type")
395 } catch (Exception error) {
396 logger.info("Error in customization", error);
400 private void createDocumentTypes() {
401 // -----------------------------------
402 DocumentType.Properties tprop = new DocumentType.Properties();
403 HashMap<String, Vector<ProjectSettingsService.Step>> mapsteps = new HashMap<String, Vector<ProjectSettingsService.Step>>();
404 HashMap<String, ProjectSettingsService.Step> mapresult = new HashMap<String, ProjectSettingsService.Step>();
405 HashMap<String, DocumentType> maptype = new HashMap<String, DocumentType>();
407 Vector<ProjectSettingsService.Step> slist = null; // List of Steps to which each document type is valid
408 int snum = 0; // Step number
411 for (Iterator<NamedNodeMap> i = flows.iterator(); i.hasNext(); snum++) {
412 NamedNodeMap flow = i.next();
413 ProjectSettingsService.Step step = steps.get(snum);
414 String[] contents = flow.getNamedItem("contents").getNodeValue()
416 for (int j = 0; j < contents.length; j++) {
418 if (!mapuse.containsKey(type)) {
419 logger.warn("Undefined \"" + type + "\" document type.");
422 slist = mapsteps.get(type);
424 slist = new Vector<ProjectSettingsService.Step>();
426 mapsteps.put(type, slist);
428 Node result = flow.getNamedItem("result");
430 mapresult.put(result.getNodeValue(), step);
433 DocumentType tdoc = null;
434 Set<String> tset = mapuse.keySet();
435 ProjectSettingsService.Step step;
436 for (Iterator<String> i = tset.iterator(); i.hasNext();) {
438 slist = mapsteps.get(type);
439 uses = mapuse.get(type);
440 step = mapresult.get(type);
443 tprop.setName(type).setStep(
444 slist.toArray(new ProjectSettingsService.Step[slist
447 tdoc = maptype.get(uses);
450 .warn("Undefined \"" + uses
451 + "\" document type.");
456 tprop.setResult(step);
458 tprop.disableCheck();
459 tdoc = Document.createType(tprop); // Creation of Document Types
461 maptype.put(type, tdoc);
463 } catch (Exception error) {
464 logger.warn("Error creating document types, reason:", error); // Should not happen
468 private void createKnowledgeElementTypes() {
469 // -------------------------------------------
471 KnowledgeElementType ktype = KnowledgeElement.createType("usecase"); // Internal reserved knowledge element type
473 for (Iterator<String> i = kname.iterator(); i.hasNext();) {
474 String type = i.next();
476 ktype = KnowledgeElement.createType(type); // Knowledge Elements Types defined in the configuration
479 } catch (Exception error) {
480 logger.warn("Error creating knowledge types, reason:", error); // Should not happen
484 private void createSimulationContextTypes() {
485 // --------------------------------------------
486 HashMap<String, ProjectSettingsService.Step> mapstep = new HashMap<String, ProjectSettingsService.Step>();
488 for (Iterator<NamedNodeMap> i = sclass.iterator(); i.hasNext(); snum++) {
489 NamedNodeMap clatr = i.next();
493 String[] clist = clatr.getNamedItem("context").getNodeValue()
495 for (int j = 0; j < clist.length; j++) {
496 mapstep.put(clist[j], steps.get(snum));
500 SimulationContextType tctex = null;
501 for (Iterator<String> i = context.iterator(); i.hasNext();) {
502 String type = i.next();
503 if (!mapstep.containsKey(type)) {
505 .warn("Could not find \""
507 + "\" classification. Simulation Context type ignored.");
510 tctex = getSimulationContextService().createType(type,
511 mapstep.get(type)); // Creation of Simulation Context Types
514 } catch (Exception error) {
515 logger.warn("Error creating context types, reason:", error); // Should not happen
522 * @return the database
524 public Database getDatabase() {
532 * the database to set
534 public void setDatabase(Database database) {
535 _database = database;
539 * Get the simulationContextService.
541 * @return the simulationContextService
543 public SimulationContextService getSimulationContextService() {
544 return _simulationContextService;
548 * Set the simulationContextService.
550 * @param simulationContextService
551 * the simulationContextService to set
553 public void setSimulationContextService(
554 SimulationContextService simulationContextService) {
555 _simulationContextService = simulationContextService;