Salome HOME
08feeae8374fa27a8a524ce55efe817358a6e02f
[tools/siman.git] / Workspace / Siman-Common / src / org / splat / service / technical / ProjectSettingsServiceImpl.java
1 package org.splat.service.technical;
2
3 /**
4  * 
5  * @author    Daniel Brunier-Coulin
6  * @copyright OPEN CASCADE 2012
7  */
8
9 import java.io.File;
10 import java.io.FileNotFoundException;
11 import java.io.IOException;
12 import java.sql.SQLException;
13 import java.util.ArrayList;
14 import java.util.HashMap;
15 import java.util.Iterator;
16 import java.util.LinkedHashMap;
17 import java.util.List;
18 import java.util.Map;
19 import java.util.Properties;
20 import java.util.Set;
21
22 import javax.xml.parsers.DocumentBuilder;
23 import javax.xml.parsers.DocumentBuilderFactory;
24
25 import org.apache.log4j.Logger;
26 import org.splat.dal.bo.som.Document;
27 import org.splat.dal.bo.som.DocumentType;
28 import org.splat.dal.bo.som.KnowledgeElement;
29 import org.splat.dal.bo.som.KnowledgeElementType;
30 import org.splat.dal.bo.som.ProjectElement;
31 import org.splat.dal.bo.som.Scenario;
32 import org.splat.dal.bo.som.SimulationContextType;
33 import org.splat.dal.bo.som.Study;
34 import org.splat.dal.bo.som.ValidationCycle.Actor;
35 import org.splat.dal.dao.som.Database;
36 import org.splat.manox.XDOM;
37 import org.splat.service.DocumentTypeService;
38 import org.splat.service.KnowledgeElementTypeService;
39 import org.splat.service.SimulationContextTypeService;
40 import org.springframework.transaction.annotation.Transactional;
41 import org.w3c.dom.Element;
42 import org.w3c.dom.NamedNodeMap;
43 import org.w3c.dom.Node;
44 import org.w3c.dom.NodeList;
45
46 /**
47  * SIMAN workflow configuration data service.
48  */
49 public class ProjectSettingsServiceImpl implements ProjectSettingsService {
50
51         /**
52          * The logger for the service.
53          */
54         protected final static Logger LOG = Logger
55                         .getLogger(ProjectSettingsServiceImpl.class);
56
57         /**
58          * Type attribute name.
59          */
60         private final static String TYPE_ATTR = "type";
61
62         // Non persistent configuration information
63         /**
64          * Repository settings.
65          */
66         private transient final Properties _reprop = new Properties();
67         /**
68          * Pattern of study references.
69          */
70         private transient String _pattern;
71         /**
72          * Scheme of file names stored into the repository.
73          */
74         private transient FileNaming _naming;
75         /**
76          * Pattern of the presentation of version numbers.
77          */
78         private transient String _versioning;
79         /**
80          * Ordered list of (transient) study steps.
81          */
82         private transient final List<ProjectSettingsService.Step> _steps = new ArrayList<ProjectSettingsService.Step>();
83         /**
84          * Configuration document validation cycles.
85          */
86         private transient final List<ProjectSettingsValidationCycle> _concycles = new ArrayList<ProjectSettingsValidationCycle>();
87         /**
88          * Document type mappings to file formats which should be imported into SALOME during check-out.
89          */
90         private transient final Map<String, List<String>> _mapimport = new HashMap<String, List<String>>();
91         /**
92          * Default document types structured by step.formats.
93          */
94         private transient final Map<String, DocumentType> _defdoctype = new LinkedHashMap<String, DocumentType>();
95
96         // Temporary attributes initialized from the configuration file for populating the database with object types
97         /**
98          * Step.format keys structured by Default document types names. This map is used for loading config before document types are created in
99          * the database. When document types are created then _defdoctype is filled.
100          */
101         private transient final Map<String, List<String>> _defdoctypeKeys = new HashMap<String, List<String>>();
102
103         /**
104          * Document type names and uses mapping.
105          */
106         private transient Map<String, String> _mapuse;
107         /**
108          * Simulation Context type names.
109          */
110         private transient List<String> _context;
111         /**
112          * Knowledge Element type names.
113          */
114         private transient List<String> _kname;
115         /**
116          * Document flows.
117          */
118         private transient List<NamedNodeMap> _flows;
119         /**
120          * Study classifications.
121          */
122         private transient List<NamedNodeMap> _sclass;
123
124         // Other resources
125         /**
126          * Database service to check its version, etc.
127          */
128         private Database _database;
129         /**
130          * Injected simulation context type service.
131          */
132         private SimulationContextTypeService _simulationContextTypeService;
133         /**
134          * Injected knowledge element type service.
135          */
136         private KnowledgeElementTypeService _knowledgeElementTypeService;
137         /**
138          * Injected document type service.
139          */
140         private DocumentTypeService _documentTypeService;
141
142         /**
143          * File naming strategy enumeration.
144          */
145         public enum FileNaming {
146                 /**
147                  * Name by document title.
148                  */
149                 title,
150                 /**
151                  * Generate encoded name.
152                  */
153                 encoded,
154                 /**
155                  * Keep original file name.
156                  */
157                 asis
158         }
159
160         /**
161          * Validation cycle defined in the XML configuration.
162          */
163         public static class ProjectSettingsValidationCycle {
164                 /**
165                  * Cycle (document) type name.
166                  */
167                 private transient final String _name;
168                 /**
169                  * Array of cycle actors positions in the organization. TODO: Must be replaced by Roles.
170                  */
171                 private transient final Actor[] _actor;
172
173                 /**
174                  * Default constructor.
175                  */
176                 private ProjectSettingsValidationCycle() {
177                         this._name = "built-in";
178                         this._actor = new Actor[] { null, null, null };
179                 }
180
181                 /**
182                  * Create a validation cycle definition for the given document type name and actors positions.
183                  * 
184                  * @param name
185                  *            the document type name
186                  * @param actor
187                  *            the array of actors positions
188                  */
189                 private ProjectSettingsValidationCycle(final String name,
190                                 final Actor[] actor) {
191                         this._name = name;
192                         this._actor = actor;
193                 }
194
195                 /**
196                  * The processed document type name.
197                  * 
198                  * @return the document type name
199                  */
200                 public String getName() {
201                         return _name;
202                 }
203
204                 /**
205                  * Get an array of cycle actors positions.
206                  * 
207                  * @return the array of actors positions
208                  * @see org.splat.dal.bo.som.ValidationCycle.Actor
209                  */
210                 public Actor[] getActorTypes() {
211                         return _actor;
212                 }
213         }
214
215         // ==============================================================================================================================
216         // Public functions
217         // ==============================================================================================================================
218
219         /**
220          * Load workflow configuration from the given file. <br/> Create necessary default staff in the database if it is not initialized yet.
221          * 
222          * @param filename
223          *            the workflow configuration file
224          * @throws IOException
225          *             if there is a file reading or index creation problem
226          * @throws SQLException
227          *             if there is a database population problem
228          */
229         @Transactional
230         public void configure(final String filename) throws IOException,
231                         SQLException {
232                 if (!_steps.isEmpty()) {
233                         return; // Project already configured
234                 }
235
236                 Database base = getDatabase().getCheckedDB();
237                 File config = new File(filename);
238                 if (config.exists()) {
239                         loadCustomization(config);
240                 } else {
241                         LOG.fatal("Could not find the database configuration file \""
242                                         + config.getAbsolutePath() + "\"");
243                         throw new FileNotFoundException();
244                 }
245                 base.configure(_reprop);
246                 if (!base.isInitialized()) {
247                         base.initialize();
248                         initialize(); // Populates the database with all necessary stuff
249                 }
250         }
251
252         /**
253          * Get ordered list of (transient) study steps.
254          * 
255          * @return the list of steps from project settings
256          */
257         public List<ProjectSettingsService.Step> getAllSteps() {
258                 return _steps;
259         }
260
261         /**
262          * Return the validation cycles of result documents defined in the workflow, ordered by study activities and ending by the default
263          * validation cycle, if defined.
264          * 
265          * @return the validation cycles of the workflow
266          */
267         public List<ProjectSettingsValidationCycle> getAllValidationCycles() {
268                 return _concycles;
269         }
270
271         /**
272          * Get file naming scheme setting.
273          * 
274          * @return file naming scheme
275          * @see org.splat.service.technical.ProjectSettingsServiceImpl.FileNaming
276          */
277         public FileNaming getFileNamingScheme() {
278                 return _naming;
279         }
280
281         /**
282          * Get a pattern of study references.
283          * 
284          * @return the reference pattern
285          */
286         public String getReferencePattern() {
287                 return _pattern;
288         }
289
290         /**
291          * Get a pattern of the presentation of version numbers.
292          * 
293          * @return the version numbers presentation pattern
294          */
295         public String getRevisionPattern() {
296                 return _versioning;
297         }
298
299         /**
300          * Get a study step by its sequential number.
301          * 
302          * @param number
303          *            the step number
304          * @return the step
305          */
306         public ProjectSettingsService.Step getStep(final int number) {
307                 ProjectSettingsService.Step res = null;
308                 for (int i = 0; i < _steps.size(); i++) {
309                         ProjectSettingsService.Step step = _steps.get(i);
310                         if (step.getNumber() == number) {
311                                 res = step;
312                                 break;
313                         }
314                 }
315                 return res;
316         }
317
318         /**
319          * Get steps of the given project element (study or scenario).
320          * 
321          * @param level
322          *            the project element (study or scenario)
323          * @return the list of steps
324          */
325         public List<ProjectSettingsService.Step> getStepsOf(
326                         final Class<? extends ProjectElement> level) {
327                 List<ProjectSettingsService.Step> result = new ArrayList<ProjectSettingsService.Step>();
328
329                 for (int i = 0; i < _steps.size(); i++) {
330                         ProjectSettingsService.Step step = _steps.get(i);
331                         if (step.appliesTo(level)) {
332                                 result.add(step);
333                         }
334                 }
335                 return result;
336         }
337
338         /**
339          * Check if a file of the given format should be imported during check-out of a document of the given type.
340          * 
341          * @param type
342          *            document type
343          * @param format
344          *            file format
345          * @return true if file should be imported
346          */
347         public boolean doImport(final String type, final String format) {
348                 if (LOG.isDebugEnabled()) {
349                         LOG.debug("Do import for ("
350                                         + type
351                                         + ", "
352                                         + format
353                                         + "): "
354                                         + (_mapimport.containsKey(type) && _mapimport.get(type)
355                                                         .contains(format)));
356                 }
357                 return (_mapimport.containsKey(type) && _mapimport.get(type).contains(
358                                 format));
359         }
360
361         /**
362          * Get default document type for the given file format on the given study step.
363          * 
364          * @param step
365          *            the study step
366          * @param format
367          *            the file format (extension)
368          * @return document type
369          */
370         public DocumentType getDefaultDocumentType(final Step step,
371                         final String format) {
372                 String[] table = format.split("\\x2E");
373                 if (LOG.isDebugEnabled()) {
374                         LOG.debug("Trying to get default type: " + step.getNumber() + "."
375                                         + table[table.length - 1]);
376                 }
377                 return _defdoctype
378                                 .get(step.getNumber() + "." + table[table.length - 1]); // May be null
379         }
380
381         /**
382          * Get the list of default formats for the given study step.
383          * 
384          * @param step
385          *            the study step
386          * @return list of formats (file extensions)
387          */
388         public List<String> getDefaultFormats(final Step step) {
389                 Integer stepNumber = step.getNumber();
390                 List<String> result = new ArrayList<String>();
391
392                 for (String i : _defdoctype.keySet()) {
393                         String[] key = i.split("\\x2E");
394                         // PDF is not an authoring format
395                         if (stepNumber.equals(Integer.valueOf(key[0]))
396                                         && (!key[1].equals("pdf"))) {
397                                 result.add(key[1]); // Formats are unique
398                         }
399                 }
400                 return result;
401         }
402
403         /**
404          * Initialize the database: create all necessary default staff defined in the configuration file.
405          */
406         protected void initialize() {
407                 createDocumentTypes();
408                 createSimulationContextTypes();
409                 createKnowledgeElementTypes();
410         }
411
412         // ==============================================================================================================================
413         // Private member function
414         // ==============================================================================================================================
415
416         /**
417          * Read the configuration file and fill transient project settings fields.
418          * 
419          * @param config
420          *            the configuration XML file
421          */
422         private void loadCustomization(final File config) {
423                 try {
424                         DocumentBuilderFactory dfactory = javax.xml.parsers.DocumentBuilderFactory
425                                         .newInstance();
426                         DocumentBuilder dBuilder = dfactory.newDocumentBuilder();
427
428                         org.w3c.dom.Document conf = dBuilder.parse(config.getPath());
429                         HashMap<String, Node> children = XDOM.getNamedChildNodes(conf
430                                         .getDocumentElement());
431
432                         // Repository tag initializing the reprop attribute
433                         Node child = children.get("database");
434                         HashMap<String, Node> datag = XDOM.getNamedChildNodes(child);
435
436                         String disk = datag.get("repository").getAttributes().getNamedItem(
437                                         "disk").getNodeValue();
438                         if (!disk.endsWith("/")) {
439                                 disk = disk + "/";
440                         }
441                         LOG.info("Database root set to " + disk);
442                         _reprop.setProperty("repository", disk);
443
444                         // Formats tag initializing the reference pattern and date attributes
445                         child = children.get("formats");
446                         datag = XDOM.getNamedChildNodes(child);
447
448                         NamedNodeMap natr = datag.get("references").getAttributes();
449                         _pattern = natr.getNamedItem("study").getNodeValue();
450
451                         natr = datag.get("files").getAttributes();
452                         _naming = FileNaming.valueOf(natr.getNamedItem("name")
453                                         .getNodeValue());
454
455                         natr = datag.get("versions").getAttributes();
456                         _versioning = natr.getNamedItem("pattern").getNodeValue();
457
458                         // Activities tag initializing the steps and rex attributes
459                         child = children.get("activities");
460                         NodeList nlist = child.getChildNodes();
461                         List<NamedNodeMap> flist = new ArrayList<NamedNodeMap>();
462                         List<String> resultype = new ArrayList<String>();
463                         List<NamedNodeMap> clist = new ArrayList<NamedNodeMap>();
464
465                         int snum = 1; // Base number of steps
466                         for (int i = 0; i < nlist.getLength(); i++) {
467                                 child = nlist.item(i);
468                                 if ("scenario".equals(child.getNodeName())) {
469                                         NodeList slist = child.getChildNodes();
470                                         for (int j = 0; j < slist.getLength(); j++) {
471                                                 snum = loadStep(slist.item(j), Scenario.class, snum,
472                                                                 flist, clist, resultype);
473                                         }
474                                 } else {
475                                         snum = loadStep(child, Study.class, snum, flist, clist,
476                                                         resultype);
477                                 }
478                         }
479
480                         // Validations tag
481                         loadValidationCycles(children, resultype);
482                         // Load steps result document types mapped to file formats
483                         loadFormatMappings(children);
484                         // Load default mapping of file formats to document types for each step
485                         loadDefaultDocTypes(children);
486
487                         if (!getDatabase().getCheckedDB().isInitialized()) {
488                                 // Load object type definitions
489                                 // Documents tag
490                                 child = children.get("documents");
491                                 nlist = child.getChildNodes();
492
493                                 _flows = flist; // Kept for later use in document type definition
494                                 _sclass = clist; // Kept for later use in simulation context type definition
495                                 _mapuse = new LinkedHashMap<String, String>();
496                                 for (int i = 0; i < nlist.getLength(); i++) {
497                                         child = nlist.item(i);
498                                         if ("article".equals(child.getNodeName())) {
499                                                 natr = child.getAttributes();
500                                                 String type = natr.getNamedItem(TYPE_ATTR)
501                                                                 .getNodeValue();
502                                                 String uses = null;
503                                                 child = natr.getNamedItem("uses");
504                                                 if (child != null) {
505                                                         uses = child.getNodeValue();
506                                                 }
507                                                 _mapuse.put(type, uses); // Must be added to the map even if no (null) uses
508                                         }
509                                 }
510                                 // Simulation Contexts tag
511                                 _context = loadArticles(children, "contexts");
512                                 // Knowledge Elements tag
513                                 _kname = loadArticles(children, "knowledges");
514                         }
515                 } catch (Exception error) {
516                         LOG.info("Error in customization", error);
517                 }
518         }
519
520         /**
521          * Load mappings of document types to lists of importable file formats.
522          * 
523          * @param children
524          *            XML nodes
525          */
526         private void loadFormatMappings(final Map<String, Node> children) {
527                 _mapimport.clear();
528                 Element maps = (Element) children.get("mappings");
529                 Element doc, imp;
530                 String type, format;
531                 List<String> formats;
532                 NodeList docs, imports;
533                 if (maps != null) {
534                         // Read document types
535                         docs = maps.getElementsByTagName("document");
536                         for (int i = 0; i < docs.getLength(); i++) {
537                                 doc = (Element) docs.item(i);
538                                 type = doc.getAttribute(TYPE_ATTR);
539                                 if (!type.isEmpty()) {
540                                         // Read file formats for the document type
541                                         imports = doc.getElementsByTagName("import");
542                                         formats = new ArrayList<String>();
543                                         for (int j = 0; j < imports.getLength(); j++) {
544                                                 imp = (Element) imports.item(j);
545                                                 format = imp.getAttribute("format");
546                                                 if (!format.isEmpty()) {
547                                                         formats.add(format);
548                                                 }
549                                         }
550                                         if (!formats.isEmpty()) {
551                                                 _mapimport.put(type, formats);
552                                         }
553                                 }
554                         }
555                 }
556         }
557
558         /**
559          * Load default document types from XML configuration.
560          * 
561          * @param children
562          *            XML nodes
563          */
564         private void loadDefaultDocTypes(final Map<String, Node> children) {
565                 _defdoctype.clear();
566                 _defdoctypeKeys.clear();
567                 Node child = children.get("default-doctypes");
568                 if (child != null) {
569                         NodeList nlist = child.getChildNodes();
570
571                         List<DocumentType> listype = getDocumentTypeService()
572                                         .selectAllTypes();
573                         Map<String, DocumentType> maptype = new HashMap<String, DocumentType>();
574                         for (Iterator<DocumentType> i = listype.iterator(); i.hasNext();) {
575                                 DocumentType type = i.next();
576                                 maptype.put(type.getName(), type);
577                         }
578                         for (int i = 0; i < nlist.getLength(); i++) {
579                                 child = nlist.item(i);
580                                 if (!child.getNodeName().equals("step")) {
581                                         continue;
582                                 }
583
584                                 String nstep = child.getAttributes().getNamedItem("number")
585                                                 .getNodeValue();
586                                 NodeList map = child.getChildNodes();
587                                 for (int j = 0; j < map.getLength(); j++) {
588                                         child = map.item(j);
589                                         if (!child.getNodeName().equals("mapping")) {
590                                                 continue;
591                                         }
592                                         NamedNodeMap natr = child.getAttributes();
593                                         String dext = natr.getNamedItem("extension").getNodeValue();
594                                         String type = natr.getNamedItem(TYPE_ATTR).getNodeValue();
595                                         if (LOG.isDebugEnabled()) {
596                                                 LOG.debug("Map default type: " + nstep + "." + dext
597                                                                 + ": (type name = " + type + ")"
598                                                                 + maptype.get(type));
599                                         }
600                                         _defdoctype.put(nstep + "." + dext, maptype.get(type));
601                                         // Remember the key if type is not created yet
602                                         if (maptype.get(type) == null) {
603                                                 List<String> keys;
604                                                 if (_defdoctypeKeys.containsKey(type)) {
605                                                         keys = _defdoctypeKeys.get(type);
606                                                 } else {
607                                                         keys = new ArrayList<String>();
608                                                         _defdoctypeKeys.put(type, keys);
609                                                 }
610                                                 keys.add(nstep + "." + dext);
611                                         }
612                                 }
613                         }
614                 }
615         }
616
617         /**
618          * Load a step from the given XML node. Return the next step's number.
619          * 
620          * @param node
621          *            XML node to parse
622          * @param ownerClass
623          *            the class of a step's owner project element - study or scenario
624          * @param snum
625          *            step's number
626          * @param flist
627          *            list of flows
628          * @param clist
629          *            list of classifications
630          * @param resultype
631          *            list of flow results
632          * @return the next step's number
633          */
634         private int loadStep(final Node node,
635                         final Class<? extends ProjectElement> ownerClass, final int snum,
636                         final List<NamedNodeMap> flist, final List<NamedNodeMap> clist,
637                         final List<String> resultype) {
638                 int res = snum;
639                 if ("step".equals(node.getNodeName())) {
640
641                         String name = ((Element) node).getAttribute("name");
642                         HashMap<String, Node> tags = XDOM.getNamedChildNodes(node);
643
644                         NamedNodeMap natr = tags.get("storage").getAttributes();
645                         ProjectSettingsService.Step step = new ProjectSettingsService.Step(
646                                         snum, ownerClass, natr.getNamedItem("path").getNodeValue());
647                         step.setKey(name);
648
649                         // Keeping flow and classification information for eventual later use
650                         natr = tags.get("flow").getAttributes();
651                         flist.add(natr);
652                         Node child = natr.getNamedItem("result");
653                         if (child != null) {
654                                 resultype.add(child.getNodeValue());
655                         }
656
657                         child = tags.get("classification");
658                         if (child == null) {
659                                 clist.add(null);
660                         } else {
661                                 clist.add(child.getAttributes());
662                         }
663
664                         if (natr.getNamedItem("contents").getNodeValue()
665                                         .equals("knowledge")) {
666                                 if (Study.class.equals(ownerClass)) {
667                                         LOG
668                                                         .error("Error: knowledges must be attached to scenarios.");
669                                 } else {
670                                         // TODO In a given scenario, only one step must contain knowledges
671                                         step._contents.add(KnowledgeElement.class);
672                                 }
673                         } else {
674                                 step._contents.add(Document.class);
675                         }
676
677                         Element module = (Element) tags.get("module");
678                         if (module != null) {
679                                 step.setModule(module.getAttribute("name"));
680                         }
681
682                         _steps.add(step);
683                         res += 1;
684                 }
685                 return res;
686         }
687
688         /**
689          * Get custom validation cycles.
690          * 
691          * @param children
692          *            XML nodes
693          * @param resultype
694          *            list of result types
695          */
696         private void loadValidationCycles(final Map<String, Node> children,
697                         final List<String> resultype) {
698                 _concycles.clear();
699                 Node child = children.get("validations");
700                 Map<String, Node> datag = XDOM.getNamedChildNodes(child);
701                 NamedNodeMap natr;
702
703                 String[] step = { "review", "approval", "acceptance" };
704                 resultype.add("default");
705                 for (Iterator<String> i = resultype.iterator(); i.hasNext();) {
706                         Actor[] actor = { null, null, null };
707                         String name = i.next();
708                         child = datag.get(name);
709                         if (child != null) {
710                                 // Document type is the subject of a validation
711                                 natr = child.getAttributes();
712                                 for (int j = 0; j < step.length; j++) {
713                                         child = natr.getNamedItem(step[j]);
714                                         if (child != null) {
715                                                 actor[j] = Actor.valueOf(child.getNodeValue()); // Validation step is required
716                                         }
717                                 }
718                                 _concycles.add(new ProjectSettingsValidationCycle(name, actor));
719                         }
720                 }
721                 _concycles.add(new ProjectSettingsValidationCycle()); // Adds the built-in validation cycle
722         }
723
724         /**
725          * Read list of articles types.
726          * 
727          * @param children
728          *            XML nodes containing articles
729          * @param listName
730          *            the name of the list of articles
731          * @return list of articles types
732          */
733         private List<String> loadArticles(final Map<String, Node> children,
734                         final String listName) {
735                 Node child = children.get(listName);
736                 NodeList nlist = child.getChildNodes();
737
738                 List<String> articles = new ArrayList<String>();
739                 for (int i = 0; i < nlist.getLength(); i++) {
740                         child = nlist.item(i);
741                         if (child.getNodeName().equals("article")) {
742                                 articles.add(child.getAttributes().getNamedItem(TYPE_ATTR)
743                                                 .getNodeValue());
744                         }
745                 }
746                 return articles;
747         }
748
749         /**
750          * Create in the database document types defined in the custom configuration.
751          */
752         private void createDocumentTypes() {
753                 if (LOG.isDebugEnabled()) {
754                         LOG.debug("Creating documents types...");
755                 }
756                 DocumentType.Properties tprop = new DocumentType.Properties();
757                 Map<String, List<ProjectSettingsService.Step>> mapsteps = new HashMap<String, List<ProjectSettingsService.Step>>();
758                 Map<String, ProjectSettingsService.Step> mapresult = new HashMap<String, ProjectSettingsService.Step>();
759                 Map<String, DocumentType> maptype = new HashMap<String, DocumentType>();
760
761                 List<ProjectSettingsService.Step> slist = null; // List of Steps to which each document type is valid
762                 int snum = 0; // Step number
763                 String type = null;
764                 String uses = null;
765                 for (Iterator<NamedNodeMap> i = _flows.iterator(); i.hasNext(); snum++) {
766                         NamedNodeMap flow = i.next();
767                         ProjectSettingsService.Step step = _steps.get(snum);
768                         String[] contents = flow.getNamedItem("contents").getNodeValue()
769                                         .split(",");
770                         for (int j = 0; j < contents.length; j++) {
771                                 type = contents[j];
772                                 if (!_mapuse.containsKey(type)) {
773                                         LOG.warn("Undefined \"" + type + "\" document type.");
774                                         continue;
775                                 }
776                                 slist = mapsteps.get(type);
777                                 if (slist == null) {
778                                         slist = new ArrayList<ProjectSettingsService.Step>();
779                                 }
780                                 slist.add(step);
781                                 mapsteps.put(type, slist);
782                         }
783                         Node result = flow.getNamedItem("result");
784                         if (result != null) {
785                                 mapresult.put(result.getNodeValue(), step);
786                         }
787                 }
788                 try {
789                         DocumentType tdoc = null;
790                         Set<String> tset = _mapuse.keySet();
791                         ProjectSettingsService.Step step;
792                         for (Iterator<String> i = tset.iterator(); i.hasNext();) {
793                                 type = i.next();
794                                 slist = mapsteps.get(type);
795                                 if (slist != null) {
796                                         uses = _mapuse.get(type);
797                                         step = mapresult.get(type);
798
799                                         tprop.clear();
800                                         tprop.setName(type).setStep(
801                                                         slist.toArray(new ProjectSettingsService.Step[slist
802                                                                         .size()]));
803                                         if (uses != null) {
804                                                 tdoc = maptype.get(uses);
805                                                 if (tdoc == null) {
806                                                         LOG.warn("Undefined \"" + uses
807                                                                         + "\" document type.");
808                                                 } else {
809                                                         tprop.setUses(tdoc);
810                                                 }
811                                         }
812                                         if (step != null) {
813                                                 tprop.setResult(step);
814                                         }
815
816                                         tprop.disableCheck();
817                                         tdoc = getDocumentTypeService().createType(tprop); // Creation of Document Types
818                                         getDocumentTypeService().approve(tdoc);
819                                         maptype.put(type, tdoc);
820                                         // Remember default type if it is
821                                         if (_defdoctypeKeys.containsKey(type)) {
822                                                 for (String key : _defdoctypeKeys.get(type)) {
823                                                         if (LOG.isDebugEnabled()) {
824                                                                 LOG.debug("Put mapping for default type: "
825                                                                                 + key + ": " + tdoc);
826                                                         }
827                                                         _defdoctype.put(key, tdoc);
828                                                 }
829                                         }
830                                 }
831                         }
832                 } catch (Exception error) {
833                         LOG.warn("Error creating document types, reason:", error); // Should not happen
834                 }
835                 if (LOG.isDebugEnabled()) {
836                         LOG.debug("Documents types are created: " + maptype.size());
837                 }
838         }
839
840         /**
841          * Create in the database knowledge types defined in the custom configuration.
842          */
843         private void createKnowledgeElementTypes() {
844                 try {
845                         KnowledgeElementType ktype = getKnowledgeElementTypeService()
846                                         .createType("usecase"); // Internal reserved knowledge element type
847                         getKnowledgeElementTypeService().reserve(ktype);
848                         for (Iterator<String> i = _kname.iterator(); i.hasNext();) {
849                                 String type = i.next();
850
851                                 ktype = getKnowledgeElementTypeService().createType(type); // Knowledge Elements Types defined in the configuration
852                                 getKnowledgeElementTypeService().approve(ktype);
853                         }
854                 } catch (Exception error) {
855                         LOG.warn("Error creating knowledge types, reason:", error); // Should not happen
856                 }
857         }
858
859         /**
860          * Create in the database simulation contexts types defined in the custom configuration.
861          */
862         private void createSimulationContextTypes() {
863                 Map<String, ProjectSettingsService.Step> mapstep = new HashMap<String, ProjectSettingsService.Step>();
864                 int snum = 0;
865                 for (Iterator<NamedNodeMap> i = _sclass.iterator(); i.hasNext(); snum++) {
866                         NamedNodeMap clatr = i.next();
867                         if (clatr != null) {
868                                 String[] clist = clatr.getNamedItem("context").getNodeValue()
869                                                 .split(",");
870                                 for (int j = 0; j < clist.length; j++) {
871                                         mapstep.put(clist[j], _steps.get(snum));
872                                 }
873                         }
874                 }
875                 try {
876                         SimulationContextType tctex = null;
877                         for (Iterator<String> i = _context.iterator(); i.hasNext();) {
878                                 String type = i.next();
879                                 if (mapstep.containsKey(type)) {
880                                         tctex = getSimulationContextTypeService().createType(type,
881                                                         mapstep.get(type)); // Creation of Simulation Context Types
882                                         getSimulationContextTypeService().approve(tctex);
883                                 } else {
884                                         LOG
885                                                         .warn("Could not find \""
886                                                                         + type
887                                                                         + "\" classification. Simulation Context type ignored.");
888                                 }
889                         }
890                 } catch (Exception error) {
891                         LOG.warn("Error creating context types, reason:", error); // Should not happen
892                 }
893         }
894
895         /**
896          * Get the database.
897          * 
898          * @return the database
899          */
900         public Database getDatabase() {
901                 return _database;
902         }
903
904         /**
905          * Set the database.
906          * 
907          * @param database
908          *            the database to set
909          */
910         public void setDatabase(final Database database) {
911                 _database = database;
912         }
913
914         /**
915          * Get the simulationContextTypeService.
916          * 
917          * @return the simulationContextTypeService
918          */
919         public SimulationContextTypeService getSimulationContextTypeService() {
920                 return _simulationContextTypeService;
921         }
922
923         /**
924          * Set the simulationContextTypeService.
925          * 
926          * @param simulationContextTypeService
927          *            the simulationContextTypeService to set
928          */
929         public void setSimulationContextTypeService(
930                         final SimulationContextTypeService simulationContextTypeService) {
931                 _simulationContextTypeService = simulationContextTypeService;
932         }
933
934         /**
935          * Get the knowledgeElementTypeService.
936          * 
937          * @return the knowledgeElementTypeService
938          */
939         public KnowledgeElementTypeService getKnowledgeElementTypeService() {
940                 return _knowledgeElementTypeService;
941         }
942
943         /**
944          * Set the knowledgeElementTypeService.
945          * 
946          * @param knowledgeElementTypeService
947          *            the knowledgeElementTypeService to set
948          */
949         public void setKnowledgeElementTypeService(
950                         final KnowledgeElementTypeService knowledgeElementTypeService) {
951                 _knowledgeElementTypeService = knowledgeElementTypeService;
952         }
953
954         /**
955          * Get the documentTypeService.
956          * 
957          * @return the documentTypeService
958          */
959         public DocumentTypeService getDocumentTypeService() {
960                 return _documentTypeService;
961         }
962
963         /**
964          * Set the documentTypeService.
965          * 
966          * @param documentTypeService
967          *            the documentTypeService to set
968          */
969         public void setDocumentTypeService(
970                         final DocumentTypeService documentTypeService) {
971                 _documentTypeService = documentTypeService;
972         }
973 }