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