]> SALOME platform Git repositories - tools/siman.git/blob - Workspace/Siman-Common/src/org/splat/service/technical/ProjectSettingsServiceImpl.java
Salome HOME
Each document type now uses itself. So default uses iincludes documents of the type...
[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                                                 // Parse uses attribute
805                                                 String[] usesArr = uses.split(",");
806                                                 List<DocumentType> usesTypesList = new ArrayList<DocumentType>();
807                                                 for (String usesType: usesArr) {
808                                                         tdoc = maptype.get(usesType.trim());
809                                                         if (tdoc == null) {
810                                                                 LOG.warn("Undefined \"" + usesType.trim()
811                                                                                 + "\" document type.");
812                                                         } else {
813                                                                 if (!usesTypesList.contains(tdoc)) {
814                                                                         usesTypesList.add(tdoc);
815                                                                 }
816                                                         }
817                                                 }
818                                                 tprop.setUses(usesTypesList.toArray(new DocumentType[]{}));
819                                         }
820                                         if (step != null) {
821                                                 tprop.setResult(step);
822                                         }
823
824                                         tprop.disableCheck();
825                                         tdoc = getDocumentTypeService().createType(tprop); // Creation of Document Types
826                                         getDocumentTypeService().approve(tdoc);
827                                         maptype.put(type, tdoc);
828                                         // Remember default type if it is
829                                         if (_defdoctypeKeys.containsKey(type)) {
830                                                 for (String key : _defdoctypeKeys.get(type)) {
831                                                         if (LOG.isDebugEnabled()) {
832                                                                 LOG.debug("Put mapping for default type: "
833                                                                                 + key + ": " + tdoc);
834                                                         }
835                                                         _defdoctype.put(key, tdoc);
836                                                 }
837                                         }
838                                 }
839                         }
840                 } catch (Exception error) {
841                         LOG.warn("Error creating document types, reason:", error); // Should not happen
842                 }
843                 if (LOG.isDebugEnabled()) {
844                         LOG.debug("Documents types are created: " + maptype.size());
845                 }
846         }
847
848         /**
849          * Create in the database knowledge types defined in the custom configuration.
850          */
851         private void createKnowledgeElementTypes() {
852                 try {
853                         KnowledgeElementType ktype = getKnowledgeElementTypeService()
854                                         .createType("usecase"); // Internal reserved knowledge element type
855                         getKnowledgeElementTypeService().reserve(ktype);
856                         for (Iterator<String> i = _kname.iterator(); i.hasNext();) {
857                                 String type = i.next();
858
859                                 ktype = getKnowledgeElementTypeService().createType(type); // Knowledge Elements Types defined in the configuration
860                                 getKnowledgeElementTypeService().approve(ktype);
861                         }
862                 } catch (Exception error) {
863                         LOG.warn("Error creating knowledge types, reason:", error); // Should not happen
864                 }
865         }
866
867         /**
868          * Create in the database simulation contexts types defined in the custom configuration.
869          */
870         private void createSimulationContextTypes() {
871                 Map<String, ProjectSettingsService.Step> mapstep = new HashMap<String, ProjectSettingsService.Step>();
872                 int snum = 0;
873                 for (Iterator<NamedNodeMap> i = _sclass.iterator(); i.hasNext(); snum++) {
874                         NamedNodeMap clatr = i.next();
875                         if (clatr != null) {
876                                 String[] clist = clatr.getNamedItem("context").getNodeValue()
877                                                 .split(",");
878                                 for (int j = 0; j < clist.length; j++) {
879                                         mapstep.put(clist[j], _steps.get(snum));
880                                 }
881                         }
882                 }
883                 try {
884                         SimulationContextType tctex = null;
885                         for (Iterator<String> i = _context.iterator(); i.hasNext();) {
886                                 String type = i.next();
887                                 if (mapstep.containsKey(type)) {
888                                         tctex = getSimulationContextTypeService().createType(type,
889                                                         mapstep.get(type)); // Creation of Simulation Context Types
890                                         getSimulationContextTypeService().approve(tctex);
891                                 } else {
892                                         LOG
893                                                         .warn("Could not find \""
894                                                                         + type
895                                                                         + "\" classification. Simulation Context type ignored.");
896                                 }
897                         }
898                 } catch (Exception error) {
899                         LOG.warn("Error creating context types, reason:", error); // Should not happen
900                 }
901         }
902
903         /**
904          * Get the database.
905          * 
906          * @return the database
907          */
908         public Database getDatabase() {
909                 return _database;
910         }
911
912         /**
913          * Set the database.
914          * 
915          * @param database
916          *            the database to set
917          */
918         public void setDatabase(final Database database) {
919                 _database = database;
920         }
921
922         /**
923          * Get the simulationContextTypeService.
924          * 
925          * @return the simulationContextTypeService
926          */
927         public SimulationContextTypeService getSimulationContextTypeService() {
928                 return _simulationContextTypeService;
929         }
930
931         /**
932          * Set the simulationContextTypeService.
933          * 
934          * @param simulationContextTypeService
935          *            the simulationContextTypeService to set
936          */
937         public void setSimulationContextTypeService(
938                         final SimulationContextTypeService simulationContextTypeService) {
939                 _simulationContextTypeService = simulationContextTypeService;
940         }
941
942         /**
943          * Get the knowledgeElementTypeService.
944          * 
945          * @return the knowledgeElementTypeService
946          */
947         public KnowledgeElementTypeService getKnowledgeElementTypeService() {
948                 return _knowledgeElementTypeService;
949         }
950
951         /**
952          * Set the knowledgeElementTypeService.
953          * 
954          * @param knowledgeElementTypeService
955          *            the knowledgeElementTypeService to set
956          */
957         public void setKnowledgeElementTypeService(
958                         final KnowledgeElementTypeService knowledgeElementTypeService) {
959                 _knowledgeElementTypeService = knowledgeElementTypeService;
960         }
961
962         /**
963          * Get the documentTypeService.
964          * 
965          * @return the documentTypeService
966          */
967         public DocumentTypeService getDocumentTypeService() {
968                 return _documentTypeService;
969         }
970
971         /**
972          * Set the documentTypeService.
973          * 
974          * @param documentTypeService
975          *            the documentTypeService to set
976          */
977         public void setDocumentTypeService(
978                         final DocumentTypeService documentTypeService) {
979                 _documentTypeService = documentTypeService;
980         }
981 }