]> SALOME platform Git repositories - tools/siman.git/blob - Workspace/SPlat/src/org/splat/som/ProjectSettings.java
Salome HOME
SIMAN Eclipse workspace first version
[tools/siman.git] / Workspace / SPlat / src / org / splat / som / ProjectSettings.java
1 package org.splat.som;
2 /**
3  * 
4  * @author    Daniel Brunier-Coulin
5  * @copyright OPEN CASCADE 2012
6  */
7
8 import java.io.File;
9 import java.io.FileNotFoundException;
10 import java.io.IOException;
11 import java.sql.SQLException;
12 import java.util.HashMap;
13 import java.util.HashSet;
14 import java.util.Iterator;
15 import java.util.LinkedHashMap;
16 import java.util.List;
17 import java.util.Properties;
18 import java.util.Set;
19 import java.util.Vector;
20
21 import javax.xml.parsers.DocumentBuilder;
22 import javax.xml.parsers.DocumentBuilderFactory;
23
24 import org.apache.log4j.Logger;
25 import org.w3c.dom.NamedNodeMap;
26 import org.w3c.dom.Node;
27 import org.w3c.dom.NodeList;
28
29 import org.splat.kernel.XDOM;
30 import org.splat.som.ValidationCycle.Actor;
31
32
33 public class ProjectSettings {
34
35 //  Non persistent configuration information
36         private  Properties                            reprop;       // Repository settings
37         private  String                                pattern;      // Pattern of study references
38         private  FileNaming                            naming;       // Scheme of file names stored into the repository
39         private  String                                versioning;   // Pattern of the presentation of version numbers 
40         private  Vector<Step>                          steps;        // Ordered list of (transient) study steps
41         private  Vector<ValidationCycle>               concycles;    // Configuration document validation cycles
42
43 //  Temporary attributes initialized from the configuration file for populating the database with object types
44     private  LinkedHashMap<String,String>          mapuse;       // Document type names and uses mapping
45     private  Vector<String>                        context;      // Simulation Context type names
46     private  Vector<String>                        kname;        // Knowledge Element type names
47     private  Vector<NamedNodeMap>                  flows;        // Document flows
48     private  Vector<NamedNodeMap>                  sclass;       // Study classifications
49
50 //  Other resources
51         private         static ProjectSettings  my     = null;       // Singleton instance
52     protected final static Logger           logger = Logger.getLogger(ProjectSettings.class);
53
54     protected enum FileNaming { title, encoded, asis }
55         public static class Step {
56 //  ------------------------
57       private int                             number;
58           private Class<? extends ProjectElement> level;        // Study or Scenario
59           private Set<Class<?>>                   contents;     // Set of Document and/or Knowledge
60           private String                          path;
61           
62           private Step (int number, Class<? extends ProjectElement> level, String path) {
63         this.initialize(number, level, path);
64           }
65           private Step (int number, Class<? extends ProjectElement> level, Class<?> contents, String path) {
66         this.initialize(number, level, path);
67         this.contents.add(contents);
68           }
69           private void initialize (int number, Class<? extends ProjectElement> level, String path) {
70         this.number   = number;
71         this.level    = level;
72         this.path     = path + "/";
73         this.contents = new HashSet<Class<?>>();
74           }
75           public boolean appliesTo (Class<? extends ProjectElement> level) {
76         return (level == this.level);
77           }
78           public boolean mayContain (Class<?> type) {
79                 return contents.contains(type);
80           }
81           public int getNumber () {
82         return number;
83           }
84           public String getPath () {
85         return path;
86           }
87         }    
88     public static class ValidationCycle {
89 //  -----------------------------------
90       private String  name;
91       private Actor[] actor;
92
93       private ValidationCycle () {
94         this.name  = "built-in";
95         this.actor = new Actor[] { null, null, null };
96       }
97       private ValidationCycle (String name, Actor[] actor) {
98         this.name  = name;
99         this.actor = actor;
100       }
101       public String getName () {
102         return name;
103       }
104       public Actor[] getActorTypes () {
105         return actor;
106       }
107     }
108
109 //  ==============================================================================================================================
110 //  Construction
111 //  ==============================================================================================================================
112
113     public static ProjectSettings getMe () {
114 //  --------------------------------------
115       if (my == null) my = new ProjectSettings();
116       return my;
117     }
118         protected ProjectSettings () {
119 //  ----------------------------
120           reprop = new Properties();
121       steps  = new Vector<Step>();
122         }       
123     
124 //  ==============================================================================================================================
125 //  Public functions
126 //  ==============================================================================================================================
127
128         public void configure (String filename) throws IOException, SQLException {
129 //  ---------------------------------------
130       if (!steps.isEmpty()) return;       // Project already configured
131
132       Database base   = Database.getMe();
133           File     config = new File(filename);
134           if  (config.exists()) {
135         loadCustomization(config);
136           } else {
137         logger.fatal("Could not find the database configuration file \"" + config.getAbsolutePath() + "\"");
138         throw new FileNotFoundException();
139           }
140           base.configure(reprop);
141       if (!base.isInitialized()) {
142         base.initialize();
143 //TODO: Move the second part of loadCustomization here
144       }
145         }
146
147     public static List<Step> getAllSteps () {
148 //  ---------------------------------------
149       return my.steps;
150     }
151
152 /**
153  * Return the validation cycles of result documents defined in the workflow, ordered by study activities
154  * and ending by the default validation cycle, if defined.
155  * 
156  * @return the validation cycles of the workflow
157  */
158     public static List<ValidationCycle> getAllValidationCycles () {
159 //  -------------------------------------------------------------
160       return my.concycles;
161     }
162
163     public static FileNaming getFileNamingScheme () {
164 //  -----------------------------------------------
165       return my.naming;
166     }
167
168     public static ValidationCycle getNewValidationCycle () {
169 //  ------------------------------------------------------
170       return  new ValidationCycle();
171     }
172
173     public static String getReferencePattern () {
174 //  -------------------------------------------
175       return my.pattern;
176     }
177
178     public static String getRevisionPattern () {
179 //  ------------------------------------------
180       return my.versioning;
181     }
182
183     public static Step getStep (int number) {
184 //  ---------------------------------------
185       for (int i=0; i<my.steps.size(); i++) {
186         Step step = my.steps.get(i);
187         if  (step.number == number)  return step;
188       }
189       return null;
190     }
191
192         public static List<Step> getStepsOf (Class<? extends ProjectElement> level) {
193 //  ---------------------------------------------------------------------------
194       Vector<Step> result = new Vector<Step>();
195       
196       for (int i=0; i<my.steps.size(); i++) {
197         Step step = my.steps.get(i);
198         if  (step.appliesTo(level)) result.add(step);         
199       }
200       return result;
201     }
202
203 //  ==============================================================================================================================
204 //  Protected member function
205 //  ==============================================================================================================================
206
207     protected void initialize () {
208 //  ----------------------------
209       createDocumentTypes();
210       createSimulationContextTypes();
211       createKnowledgeElementTypes();
212     }
213
214 //  ==============================================================================================================================
215 //  Private member function
216 //  ==============================================================================================================================
217     
218     private void loadCustomization (File config) {
219 //  --------------------------------------------
220       try {
221         DocumentBuilderFactory dfactory = javax.xml.parsers.DocumentBuilderFactory.newInstance();
222         DocumentBuilder        dBuilder = dfactory.newDocumentBuilder();
223         
224         org.w3c.dom.Document   conf     = dBuilder.parse(config.getPath());
225         HashMap<String, Node>  children = XDOM.getNamedChildNodes(conf.getDocumentElement());
226
227 //      Repository tag initializing the reprop attribute
228         Node                   child = children.get("database");
229         HashMap<String, Node>  datag = XDOM.getNamedChildNodes(child);
230
231         String disk = datag.get("repository").getAttributes().getNamedItem("disk").getNodeValue();
232         if (!disk.endsWith("/")) disk = disk + "/";
233         logger.info("Database root set to " + disk);
234         reprop.setProperty("repository", disk);
235
236 //      Formats tag initializing the reference pattern and date attributes
237         child = children.get("formats");
238         datag = XDOM.getNamedChildNodes(child);
239
240         NamedNodeMap natr = datag.get("references").getAttributes();
241         pattern    = natr.getNamedItem("study").getNodeValue();
242         
243         natr       = datag.get("files").getAttributes();
244         naming     = FileNaming.valueOf(natr.getNamedItem("name").getNodeValue());
245         
246         natr       = datag.get("versions").getAttributes();
247         versioning = natr.getNamedItem("pattern").getNodeValue();
248
249 //      Activities tag initializing the steps and rex attributes
250                                child     = children.get("activities");
251         NodeList               nlist     = child.getChildNodes();
252         Vector<NamedNodeMap>   flist     = new Vector<NamedNodeMap>();
253         Vector<String>         resultype = new Vector<String>();
254         Vector<NamedNodeMap>   clist     = new Vector<NamedNodeMap>();
255
256         int snum = 1;                                        // Base number of steps
257         for (int i=0; i<nlist.getLength(); i++) {
258           child = nlist.item(i);
259           if (child.getNodeName().equals("scenario")) {
260                 NodeList slist = child.getChildNodes();
261             for (int j=0; j<slist.getLength(); j++) {
262               child = slist.item(j);
263               if (!child.getNodeName().equals("step")) continue;
264               HashMap<String, Node>  tags = XDOM.getNamedChildNodes(child);
265
266               natr = tags.get("storage").getAttributes();
267               Step step = new Step(snum, Scenario.class, natr.getNamedItem("path").getNodeValue());
268
269 //            Keeping flow and classification information for eventual later use
270               natr = tags.get("flow").getAttributes();
271               flist.add(natr);              
272               child = natr.getNamedItem("result");
273               if (child != null) resultype.add(child.getNodeValue());
274
275               child = tags.get("classification");
276               if (child != null) clist.add( child.getAttributes() );
277               else               clist.add( null );
278
279               if (natr.getNamedItem("contents").getNodeValue().equals("knowledge")) {
280 //TODO            In a given scenario, only one step must contain knowledges
281                   step.contents.add(KnowledgeElement.class);
282               } else {
283                 step.contents.add(Document.class);
284               }
285               steps.add(step);
286               snum += 1;
287             }
288           } else {
289             if (!child.getNodeName().equals("step")) continue;
290             HashMap<String, Node>  tags = XDOM.getNamedChildNodes(child);
291
292             natr = tags.get("storage").getAttributes();      // Mandatory information
293             Step step = new Step(snum, Study.class, natr.getNamedItem("path").getNodeValue());
294
295 //          Keeping flow and classification information for eventual later use
296             natr = tags.get("flow").getAttributes();
297             flist.add(natr);              
298             child = natr.getNamedItem("result");
299             if (child != null) resultype.add(child.getNodeValue());
300
301             child = tags.get("classification");              // Optional information
302             if (child != null) clist.add( child.getAttributes() );
303             else               clist.add( null );
304
305             if (natr.getNamedItem("contents").getNodeValue().equals("knowledge")) {
306 //TODO        Error: knowledges must be attached to scenarios
307             } else {
308               step.contents.add(Document.class);
309             }
310             steps.add(step);
311             snum += 1;
312           }
313         }
314 //      Validations tag
315         child     = children.get("validations");
316         concycles = new Vector<ValidationCycle>();
317         datag     = XDOM.getNamedChildNodes(child);
318
319         String[]  step   = { "review", "approval", "acceptance" };
320         resultype.add("default");
321         for (Iterator<String> i=resultype.iterator(); i.hasNext(); ) {
322           Actor[] actor = {  null,     null,       null        };
323           String  name  = i.next();
324           child = datag.get(name);
325           if (child == null) continue;                        // Document type not subject of any validation
326           natr = child.getAttributes();
327           for (int j=0; j<step.length; j++) {
328             child = natr.getNamedItem(step[j]);
329             if (child == null) continue;                      // Validation step not required
330             actor[j] = Actor.valueOf(child.getNodeValue());
331           }
332           concycles.add( new ValidationCycle(name, actor) );
333         }
334         concycles.add( new ValidationCycle() );               // Adds the built-in validation cycle
335
336         if (Database.getMe().isInitialized()) return;         // No need to load object type definitions as they are already stored
337
338 //      Documents tag
339         child  = children.get("documents");
340             nlist  = child.getChildNodes();
341
342             flows  = flist;             // Kept for later use in document type definition
343             sclass = clist;             // Kept for later use in simulation context type definition
344         mapuse = new LinkedHashMap<String,String>();
345         for (int i=0; i<nlist.getLength(); i++) {
346           child = nlist.item(i);
347           if (!child.getNodeName().equals("article")) continue;
348
349                        natr = child.getAttributes();
350           String       type = natr.getNamedItem("type").getNodeValue();
351           String       uses = null;
352           child = natr.getNamedItem("uses");
353           if (child != null) uses = child.getNodeValue();
354           mapuse.put(type, uses);   // Must be added to the map even if no (null) uses
355         }
356 //      Simulation Contexts tag
357         child  = children.get("contexts");
358             nlist  = child.getChildNodes();
359
360             context  = new Vector<String>();
361         for (int i=0; i<nlist.getLength(); i++) {
362           child = nlist.item(i);
363           if (!child.getNodeName().equals("article")) continue;
364           
365           context.add(child.getAttributes().getNamedItem("type").getNodeValue());
366         }
367 //      Knowledge Elements tag
368         child  = children.get("knowledges");
369             nlist  = child.getChildNodes();
370
371             kname  = new Vector<String>();
372         for (int i=0; i<nlist.getLength(); i++) {
373           child = nlist.item(i);
374           if (!child.getNodeName().equals("article")) continue;
375           
376           kname.add(child.getAttributes().getNamedItem("type").getNodeValue());
377         }
378       }
379       catch (Exception error) {
380                 logger.info("Error in customization", error);
381       }
382     }
383
384     private void createDocumentTypes () {
385 //  -----------------------------------
386       DocumentType.Properties       tprop     = new DocumentType.Properties();
387       HashMap<String,Vector<Step>>  mapsteps  = new HashMap<String,Vector<Step>>();
388       HashMap<String,Step>          mapresult = new HashMap<String,Step>();
389       HashMap<String,DocumentType>  maptype   = new HashMap<String,DocumentType>();
390         
391       Vector<Step> slist = null;     // List of Steps to which each document type is valid
392       int          snum  = 0;        // Step number
393       String       type  = null;
394       String       uses  = null;
395       for (Iterator<NamedNodeMap> i=flows.iterator(); i.hasNext(); snum++) {
396             NamedNodeMap    flow     = i.next();
397             Step            step     = steps.get(snum);
398         String[]        contents = flow.getNamedItem("contents").getNodeValue().split(",");
399         for (int j=0; j<contents.length; j++) {
400               type = contents[j];
401           if (!mapuse.containsKey(type)) {
402             logger.warn("Undefined \"" + type + "\" document type.");
403             continue;
404           }                  slist = mapsteps.get(type);
405           if (slist == null) slist = new Vector<Step>();
406           slist.add(step);
407           mapsteps.put(type, slist);
408         }
409         Node result = flow.getNamedItem("result");
410         if  (result != null)  mapresult.put(result.getNodeValue(), step);
411       }
412       try {
413         DocumentType tdoc = null;
414         Set<String>  tset = mapuse.keySet();
415         Step         step;
416         for (Iterator<String> i=tset.iterator(); i.hasNext(); ) {
417           type  = i.next();
418           slist = mapsteps.get(type);
419           uses  = mapuse.get(type);
420           step  = mapresult.get(type);
421
422           tprop.clear();
423           tprop.setName(type).setStep(slist.toArray(new Step[slist.size()]));
424           if (uses != null) {
425                 tdoc = maptype.get(uses);
426                 if (tdoc == null) logger.warn("Undefined \"" + uses + "\" document type.");
427                 else              tprop.setUses(tdoc);
428           }
429           if (step != null)   tprop.setResult(step);
430
431           tprop.disableCheck();
432           tdoc = Document.createType(tprop);                                  // Creation of Document Types
433           tdoc.approve();
434           maptype.put(type, tdoc);
435         }
436       } catch (Exception error) {
437         logger.warn("Error creating document types, reason:", error);         // Should not happen
438       }
439     }
440
441     private void createKnowledgeElementTypes () {
442 //  -------------------------------------------
443       try {
444         KnowledgeElementType ktype = KnowledgeElement.createType("usecase");  // Internal reserved knowledge element type
445         ktype.reserve();
446         for (Iterator<String> i=kname.iterator(); i.hasNext(); ) {
447           String  type = i.next();
448
449           ktype = KnowledgeElement.createType(type);                          // Knowledge Elements Types defined in the configuration
450           ktype.approve();
451         }
452       } catch (Exception error) {
453         logger.warn("Error creating knowledge types, reason:", error);        // Should not happen
454       }
455     }
456
457     private void createSimulationContextTypes () {
458 //  --------------------------------------------
459       HashMap<String,Step>  mapstep = new HashMap<String,Step>();
460       int snum = 0;
461       for (Iterator<NamedNodeMap> i=sclass.iterator(); i.hasNext(); snum++) {
462         NamedNodeMap clatr = i.next();
463         if (clatr == null) continue;
464
465         String[]        clist = clatr.getNamedItem("context").getNodeValue().split(",");
466         for (int j=0; j<clist.length; j++) {
467           mapstep.put(clist[j], steps.get(snum));
468         }
469       }
470       try {
471         SimulationContextType tctex = null;
472         for (Iterator<String> i=context.iterator(); i.hasNext(); ) {
473           String type = i.next();
474               if (!mapstep.containsKey(type)) {
475             logger.warn("Could not find \"" + type + "\" classification. Simulation Context type ignored.");
476             continue;
477               }
478               tctex = SimulationContext.createType(type, mapstep.get(type));   // Creation of Simulation Context Types
479               tctex.approve();
480         }
481       } catch (Exception error) {
482         logger.warn("Error creating context types, reason:", error);       // Should not happen
483       }
484     }
485 }