]> SALOME platform Git repositories - tools/siman.git/blob - Workspace/Siman/src/org/splat/simer/ApplicationSettings.java
Salome HOME
Applet is working now and calls runSalome with appropriate parameters. New ant target...
[tools/siman.git] / Workspace / Siman / src / org / splat / simer / ApplicationSettings.java
1 package org.splat.simer;
2
3 import java.io.File;
4 import java.io.IOException;
5 import java.util.ArrayList;
6 import java.util.HashMap;
7 import java.util.HashSet;
8 import java.util.Iterator;
9 import java.util.List;
10 import java.util.Locale;
11 import java.util.Map;
12 import java.util.Properties;
13 import java.util.Set;
14
15 import javax.servlet.ServletContext;
16 import javax.xml.parsers.DocumentBuilder;
17 import javax.xml.parsers.DocumentBuilderFactory;
18
19 import org.apache.log4j.Logger;
20 import org.splat.dal.bo.kernel.User;
21 import org.splat.dal.bo.som.Document;
22 import org.splat.dal.bo.som.DocumentType;
23 import org.splat.dal.bo.som.KnowledgeElement;
24 import org.splat.dal.bo.som.ProgressState;
25 import org.splat.dal.bo.som.SimulationContext;
26 import org.splat.manox.XDOM;
27 import org.splat.service.DocumentTypeService;
28 import org.splat.service.technical.ProjectSettingsService;
29 import org.splat.som.DocumentRights;
30 import org.splat.som.Step;
31 import org.splat.som.StudyRights;
32 import org.splat.wapp.MenuItem;
33 import org.splat.wapp.PopupItem;
34 import org.splat.wapp.PopupMenu;
35 import org.splat.wapp.SimpleMenu;
36 import org.splat.wapp.ToolBar;
37 import org.springframework.web.context.ServletContextAware;
38 import org.w3c.dom.NamedNodeMap;
39 import org.w3c.dom.Node;
40 import org.w3c.dom.NodeList;
41
42 /**
43  * SIMAN project settings service. Provides settings according to XML customization.
44  */
45 public class ApplicationSettings implements ServletContextAware {
46
47         /**
48          * Application settings logger.
49          */
50         protected final static Logger LOG = Logger
51                         .getLogger(ApplicationSettings.class);
52
53         /**
54          * Singleton instance of application settings service.
55          */
56         private static final ApplicationSettings MY_APP = new ApplicationSettings();
57
58         /**
59          * All value.
60          */
61         private static final String ALL = "all";
62
63         /**
64          * Hold icon file name.
65          */
66         private static final String IMG_HOLD = "image.hold.gif";
67         /**
68          * Attach icon file name.
69          */
70         private static final String IMG_ATTACH = "image.attach.png";
71         /**
72          * Version icon file name.
73          */
74         private static final String IMG_VERSION = "image.version.png";
75         /**
76          * Delete icon file name.
77          */
78         private static final String IMG_DELETE = "icon.delete.png";
79         /**
80          * Attach menu item name.
81          */
82         private static final String MNU_ATTACH = "attach";
83         /**
84          * Demote menu item name.
85          */
86         private static final String MNU_DEMOTE = "demote";
87         /**
88          * Promote menu item name.
89          */
90         private static final String MNU_PROMOTE = "promote";
91         /**
92          * Publish menu item name.
93          */
94         private static final String MNU_PUBLISH = "publish";
95         /**
96          * Edit menu item name.
97          */
98         private static final String MNU_EDIT = "edit";
99         /**
100          * Script menu item name.
101          */
102         private static final String MNU_SCRIPT = "script";
103         /**
104          * Version menu item name.
105          */
106         private static final String MNU_VERSION = "version";
107         /**
108          * Purge menu item name.
109          */
110         private static final String MNU_PURGE = "purge";
111         /**
112          * Remove menu item name.
113          */
114         private static final String MNU_REMOVE = "remove";
115         /**
116          * Rename menu item name.
117          */
118         private static final String MNU_RENAME = "rename";
119
120         /**
121          * Attach menu item name.
122          */
123         private static final String MNU_NAME_ATTACH = "menu.attach";
124         /**
125          * Demote menu item name.
126          */
127         private static final String MNU_NAME_DEMOTE = "menu.demote";
128         /**
129          * Promote menu item name.
130          */
131         private static final String MNU_NAME_PROMOTE = "menu.promote";
132         /**
133          * Publish menu item name.
134          */
135         private static final String MNU_NAME_PUBLISH = "menu.publish";
136         /**
137          * Edit menu item name.
138          */
139         private static final String MNU_NAME_EDIT = "menu.edit";
140         /**
141          * Script menu item name.
142          */
143         private static final String MNU_NAME_SCRIPT = "menu.newscenario";
144         /**
145          * Version menu item name.
146          */
147         private static final String MNU_NAME_VERSION = "menu.version";
148         /**
149          * Purge menu item name.
150          */
151         private static final String MNU_NAME_PURGE = "menu.purge";
152         /**
153          * Remove menu item name.
154          */
155         private static final String MNU_NAME_REMOVE = "menu.remove.version";
156         /**
157          * Rename menu item name.
158          */
159         private static final String MNU_NAME_RENAME = "menu.rename";
160         /**
161          * Not yet implemented action name.
162          */
163         private static final String ACT_NOT_YET_IMPLEMENTED = "notyetimplemented";
164         /**
165          * Attach action name.
166          */
167         private static final String ACT_ATTACH = "select-file?nextAction=attach";
168         /**
169          * Version action name.
170          */
171         private static final String ACT_VERSION = "select-file?nextAction=version";
172
173         /**
174          * Injected servlet context to get path to resources.
175          */
176         private transient ServletContext _servletContext;
177
178         /**
179          * Siman application server name.
180          */
181         private transient String _wappserver;
182         /**
183          * Siman web application name.
184          */
185         private transient String _wappname;
186         /**
187          * General properties from the application properties files.
188          */
189         private transient final Properties _wapprops = new Properties();
190         /**
191          * Current user locale.
192          */
193         private transient Locale _locale;
194         /**
195          * Application menus.
196          */
197         private transient final Map<String, SimpleMenu> _menus = new HashMap<String, SimpleMenu>();
198         /**
199          * Study module-bars structured by steps.
200          */
201         private transient Map<Integer, ToolBar> _bars = null;
202         /**
203          * Popup menus.
204          */
205         private transient Map<String, PopupMenu> _popups = null;
206         /**
207          * Named search filters.
208          */
209         private transient Map<String, Map<String, Object>> _filter = null;
210         /**
211          * Available template files.
212          */
213         private transient Map<String, String> _tempfile = null;
214         /**
215          * List of file extensions mapped to a viewer.
216          */
217         private transient String[] _viewermap = null;
218         /**
219          * Available document format converters.
220          */
221         private transient Map<String, Converter> _convertmap = null;
222         /**
223          * JNDI context for launching converters.
224          */
225         private transient final Properties _jndprops = new Properties();
226         /**
227          * Injected project settings service.
228          */
229         private ProjectSettingsService _projectSettings;
230         /**
231          * Injected document type service.
232          */
233         private DocumentTypeService _documentTypeService;
234
235         /**
236          * Get the projectSettingsService.
237          * 
238          * @return the projectSettingsService
239          */
240         public ProjectSettingsService getProjectSettings() {
241                 return _projectSettings;
242         }
243
244         /**
245          * Set the projectSettingsService.
246          * 
247          * @param projectSettingsService
248          *            the projectSettingsService to set
249          */
250         public void setProjectSettings(
251                         final ProjectSettingsService projectSettingsService) {
252                 _projectSettings = projectSettingsService;
253         }
254
255         private static class NewMenu extends SimpleMenu {
256                 private NewMenu() {
257                         super("create");
258                         addItem("new-empty", "menu.new.empty", "image.empty.png",
259                                         "select?menu=create&item=new-empty");
260                         addItem("new-copy",
261                                         new MenuItem("menu.new.copy").icon("image.copy.png"));
262                         addItem("new-instance",
263                                         new MenuItem("menu.new.instance").icon(IMG_HOLD));
264                         addItem("new-import",
265                                         new MenuItem("menu.new.import").icon("icon.upload.png"));
266                         this.selects("new-empty");
267                 }
268         }
269
270         private static class SearchMenu extends SimpleMenu {
271                 private SearchMenu() {
272                         super("search");
273                         addItem("search-study", "menu.search.study", "image.study.png",
274                                         "select?menu=search&item=search-study");
275                         addItem("search-knowledge", "menu.search.idea", "image.idea.png",
276                                         "select?menu=search&item=search-knowledge");
277                         addItem("search-document",
278                                         new MenuItem("menu.search.document").icon("icon.any.png"));
279                         this.selects("search-study");
280                 }
281         }
282
283         private static class PropertiesMenu extends SimpleMenu {
284                 private PropertiesMenu() {
285                         super("configuration");
286                         addItem("prop-general", "menu.prop.general", IMG_HOLD,
287                                         "select?menu=properties&item=prop-general");
288                         addItem("prop-scenario", "menu.prop.scenario", IMG_HOLD,
289                                         "select?menu=properties&item=prop-scenario");
290                         // These menu items will not be implemented in the current version.
291                         /*
292                          * addItem("prop-timestamp", new MenuItem("menu.prop.timestamp") .icon("image.stamp.png")); addItem("prop-comlog", new
293                          * MenuItem("menu.prop.comlog") .icon(IMG_HOLD)); addItem("prop-version", new MenuItem("menu.prop.version")
294                          * .icon("image.dirclosed.png"));
295                          */
296                 }
297         }
298
299         private static class DatadminMenu extends SimpleMenu {
300                 private DatadminMenu() {
301                         super("datadmin");
302                         addItem("admin-scontext", "menu.admin.context", IMG_HOLD,
303                                         "select?menu=datadmin&item=admin-scontext");
304                         addItem("admin-knowelm", "menu.admin.knowledge", "image.idea.png",
305                                         "select?menu=datadmin&item=admin-knowelm");
306                         addItem("admin-study",
307                                         new MenuItem("menu.admin.study").icon("image.study.png"));
308                 }
309         }
310
311         private static class SysadminMenu extends SimpleMenu {
312                 private SysadminMenu() {
313                         super("sysadmin");
314                         addItem("admin-indexing", "menu.admin.indexing", "image.index.png",
315                                         "select?menu=sysadmin&item=admin-indexing");
316                         addItem("admin-importuser", "menu.admin.importuser",
317                                         "image.group.png",
318                                         "select?menu=sysadmin&item=admin-importuser");
319                 }
320         }
321
322         private enum Item {
323                 publish, accept, approve, promote, demote, undo, rename, attach, edit, script, version, replace, export, remove, purge
324         };
325
326         // Resources relative to studies
327         private static class EditableStudyPopup extends PopupMenu {
328                 private transient StudyRights _user = null;
329
330                 private EditableStudyPopup() {
331                         super();
332                         addItem(MNU_PUBLISH,
333                                         new PopupItem(MNU_NAME_PUBLISH).icon("image.publish.png")
334                                                         .action("edit-study?action=publish")
335                                                         .confirmation("message.publish.study"));
336                         addItem(MNU_PROMOTE, new PopupItem("menu.archive"));
337                         addSeparator();
338                         addItem(MNU_EDIT,
339                                         new PopupItem("menu.properties").icon("icon.ed.png")
340                                                         .action("../select?menu=properties"));
341                         addSeparator();
342                         addItem(MNU_SCRIPT,
343                                         new PopupItem(MNU_NAME_SCRIPT).action("add-scenario"));
344                         addItem(MNU_VERSION,
345                                         new PopupItem(MNU_NAME_VERSION).icon(IMG_VERSION).action(
346                                                         ACT_NOT_YET_IMPLEMENTED));
347                         addSeparator();
348                         addItem(MNU_PURGE,
349                                         new PopupItem(MNU_NAME_PURGE)
350                                                         .confirmation("message.purge.study"));
351                         addItem("export",
352                                         new PopupItem("menu.export").icon("image.export.png")); // For future needs
353                         addItem(MNU_REMOVE,
354                                         new PopupItem(MNU_NAME_REMOVE).icon(IMG_DELETE)
355                                                         .action(ACT_NOT_YET_IMPLEMENTED)
356                                                         .confirmation("message.delete.study"));
357                 }
358
359                 @Override
360                 public boolean isEnabled(final String name) {
361                         boolean res = (_user != null);
362                         if (res) {
363                                 Item item = Item.valueOf(name);
364                                 switch (item) {
365                                         case publish:
366                                                 res = _user.canPublish();
367                                                 break;
368                                         case edit:
369                                                 res = _user.canEditProperties();
370                                                 break;
371                                         case script:
372                                                 res = _user.canAddScenario();
373                                                 break;
374                                         case version:
375                                                 res = _user.canVersion();
376                                                 break;
377                                         case remove:
378                                                 res = _user.canRemove();
379                                                 break;
380                                         case purge:
381                                                 res = _user.canPurge();
382                                                 break;
383                                         default:
384                                                 res = false;
385                                 }
386                         }
387                         return res;
388                 }
389
390                 @Override
391                 public void setContext(final String name, final Object context) {
392                         if (context instanceof StudyRights) {
393                                 _user = (StudyRights) context; // Just for optimizing
394                                 boolean history = _user.getOperand().isVersioned();
395                                 PopupItem item = this.item(MNU_REMOVE);
396                                 if (history) {
397                                         item.rename(MNU_NAME_REMOVE);
398                                 } else {
399                                         item.rename("menu.remove.study");
400                                 }
401                         }
402                 }
403         }
404
405         // Resources relative to documents
406         /**
407          * Popup of In-Work documents.
408          */
409         private static class EditableDocumentPopup extends PopupMenu {
410                 private transient DocumentRights _user = null;
411
412                 private EditableDocumentPopup() {
413                         super();
414                         addItem("accept",
415                                         new PopupItem("menu.accept").icon("image.accept.png")
416                                                         .action("setDocument?action=accept")
417                                                         .confirmation("message.accept.document"));
418                         addItem(MNU_PROMOTE,
419                                         new PopupItem(MNU_NAME_PROMOTE).icon("image.publish.png")
420                                                         .action("setDocument?action=promote")
421                                                         .confirmation("message.promote.document"));
422                         addSeparator();
423                         addItem(MNU_RENAME,
424                                         new PopupItem(MNU_NAME_RENAME)
425                                                         .action("edit-document?action=renameDocument"));
426                         addItem(MNU_ATTACH, new PopupItem(MNU_NAME_ATTACH).icon(IMG_ATTACH)
427                                         .action(ACT_ATTACH));
428                         addSeparator();
429                         addItem(MNU_VERSION,
430                                         new PopupItem(MNU_NAME_VERSION).icon(IMG_VERSION).action(
431                                                         ACT_VERSION));
432                         addItem("replace",
433                                         new PopupItem("menu.replace").icon("image.replace.png")
434                                                         .action("select-file?nextAction=replace"));
435                         addSeparator();
436                         addItem(MNU_PURGE,
437                                         new PopupItem(MNU_NAME_PURGE).action(
438                                                         ACT_NOT_YET_IMPLEMENTED).confirmation(
439                                                         "message.purge.document"));
440                         addItem(MNU_REMOVE,
441                                         new PopupItem(MNU_NAME_REMOVE).icon(IMG_DELETE)
442                                                         .action("remove-document")
443                                                         .confirmation("message.delete.document"));
444                 }
445
446                 @Override
447                 public boolean isEnabled(final String name) {
448                         boolean res = (_user != null);
449                         if (res) {
450                                 Item item = Item.valueOf(name);
451                                 switch (item) {
452                                         case accept:
453                                                 res = _user.canAccept();
454                                                 break;
455                                         case promote:
456                                                 res = _user.canPromote();
457                                                 break;
458                                         case rename:
459                                                 res = _user.canRename();
460                                                 break;
461                                         case attach:
462                                                 res = _user.canAttach();
463                                                 break;
464                                         case version:
465                                                 res = _user.canVersion();
466                                                 break;
467                                         case replace:
468                                                 res = _user.canReplace();
469                                                 break;
470                                         case purge:
471                                                 res = _user.canPurge();
472                                                 break;
473                                         case remove:
474                                                 res = _user.canRemove();
475                                                 break;
476                                         default:
477                                                 res = false;
478                                 }
479                         }
480                         return res;
481                 }
482
483                 @Override
484                 public void setContext(final String name, final Object context) {
485                         if (context instanceof DocumentRights) {
486                                 _user = (DocumentRights) context; // Just for optimizing
487                                 Document downer = _user.getOperand();
488                                 PopupItem item = this.item(MNU_REMOVE);
489                                 if (downer.isVersioned()) {
490                                         item.rename(MNU_NAME_REMOVE);
491                                 } else {
492                                         item.rename("menu.remove.document");
493                                 }
494                         }
495                 }
496         }
497
498         /**
499          * Popup of In-Draft documents.
500          */
501         private static class ReviewableDocumentPopup extends PopupMenu {
502                 private transient DocumentRights _user = null;
503
504                 private ReviewableDocumentPopup() {
505                         super();
506                         addItem(MNU_DEMOTE,
507                                         new PopupItem(MNU_NAME_DEMOTE).icon("image.demote.png")
508                                                         .action("setDocument?action=demote")
509                                                         .confirmation("message.demote.document"));
510                         addItem(MNU_PROMOTE,
511                                         new PopupItem("menu.review").icon("image.review.png")
512                                                         .action("setDocument?action=review")
513                                                         .confirmation("message.review.document"));
514                         addSeparator();
515                         addItem(MNU_ATTACH, new PopupItem(MNU_NAME_ATTACH).icon(IMG_ATTACH)
516                                         .action(ACT_ATTACH));
517                         addSeparator();
518                         addItem(MNU_VERSION,
519                                         new PopupItem(MNU_NAME_VERSION).icon(IMG_VERSION).action(
520                                                         ACT_VERSION));
521                         addSeparator();
522                         addItem(MNU_PURGE,
523                                         new PopupItem(MNU_NAME_PURGE).action(
524                                                         ACT_NOT_YET_IMPLEMENTED).confirmation(
525                                                         "message.purge.document"));
526                 }
527
528                 @Override
529                 public boolean isEnabled(final String name) {
530                         boolean res = (_user != null);
531                         if (res) {
532                                 Item item = Item.valueOf(name);
533                                 switch (item) {
534                                         case demote:
535                                                 res = _user.canDemote();
536                                                 break;
537                                         case promote:
538                                                 res = _user.canReview();
539                                                 break;
540                                         case attach:
541                                                 res = _user.canAttach();
542                                                 break;
543                                         case version:
544                                                 res = _user.canVersion();
545                                                 break;
546                                         case purge:
547                                                 res = _user.canPurge();
548                                                 break;
549                                         default:
550                                                 res = false;
551                                 }
552                         }
553                         return res;
554                 }
555
556                 @Override
557                 public void setContext(final String name, final Object context) {
558                         if (context instanceof DocumentRights) {
559                                 _user = (DocumentRights) context; // Just for optimizing
560                         }
561                 }
562         }
563
564         private static class NotResultDocumentPopup extends PopupMenu {
565                 // private final DocumentRights _user = null;
566
567                 private NotResultDocumentPopup() {
568                         super();
569                         addItem(MNU_DEMOTE,
570                                         new PopupItem(MNU_NAME_DEMOTE).icon("image.demote.png")
571                                                         .action("setDocument?action=demote")
572                                                         .confirmation("message.demote.document"));
573                         addSeparator();
574                         addItem(MNU_ATTACH, new PopupItem(MNU_NAME_ATTACH).icon(IMG_ATTACH)
575                                         .action(ACT_ATTACH));
576                         addSeparator();
577                         addItem(MNU_VERSION,
578                                         new PopupItem(MNU_NAME_VERSION).icon(IMG_VERSION).action(
579                                                         ACT_VERSION));
580                         addSeparator();
581                         addItem(MNU_PURGE,
582                                         new PopupItem(MNU_NAME_PURGE).action(
583                                                         ACT_NOT_YET_IMPLEMENTED).confirmation(
584                                                         "message.purge.document"));
585                         addItem(MNU_REMOVE,
586                                         new PopupItem(MNU_NAME_REMOVE).icon(IMG_DELETE)
587                                                         .action("remove-document")
588                                                         .confirmation("message.delete.document"));
589                 }
590         }
591
592         /**
593          * Popup of In-Check documents.
594          */
595         private static class ApprovableDocumentPopup extends PopupMenu {
596                 private transient DocumentRights _user = null;
597
598                 private ApprovableDocumentPopup() {
599                         super();
600                         addItem("undo",
601                                         new PopupItem(MNU_NAME_DEMOTE).icon("image.invalidate.png")
602                                                         .action("setDocument?action=invalidate")
603                                                         .confirmation("message.demote.document"));
604                         addItem(MNU_DEMOTE,
605                                         new PopupItem("menu.disapprove").icon("image.demote.png")
606                                                         .action("setDocument?action=disapprove")
607                                                         .confirmation("message.disapprove.document"));
608                         addItem("approve",
609                                         new PopupItem("menu.approve").icon("icon.APPROVED.png")
610                                                         .action("setDocument?action=approve")
611                                                         .confirmation("message.approve.document"));
612                 }
613
614                 @Override
615                 public boolean isEnabled(final String name) {
616                         boolean res = (_user != null);
617                         if (res) {
618                                 Item item = Item.valueOf(name);
619                                 switch (item) {
620                                         case undo:
621                                                 res = _user.canInvalidate();
622                                                 break;
623                                         case demote:
624                                                 res = _user.canDemote();
625                                                 break;
626                                         case approve:
627                                                 res = _user.canApprove();
628                                                 break;
629                                         default:
630                                                 res = false;
631                                 }
632                         }
633                         return res;
634                 }
635
636                 @Override
637                 public void setContext(final String name, final Object context) {
638                         if (context instanceof DocumentRights) {
639                                 _user = (DocumentRights) context; // Just for optimizing
640                         }
641                 }
642         }
643
644         /**
645          * Popup of Approved documents.
646          */
647         private static class ApprovedPopup extends PopupMenu {
648                 private ApprovedPopup() {
649                         super();
650                         addItem(MNU_ATTACH, new PopupItem(MNU_NAME_ATTACH).icon(IMG_ATTACH)
651                                         .action(ACT_ATTACH));
652                         addSeparator();
653                         addItem(MNU_VERSION,
654                                         new PopupItem(MNU_NAME_VERSION).icon(IMG_VERSION).action(
655                                                         ACT_VERSION));
656                 }
657         }
658
659         /**
660          * Popup of Extern documents.
661          */
662         private static class ExternPopup extends PopupMenu {
663                 private transient DocumentRights _user = null;
664
665                 private ExternPopup() {
666                         super();
667                         addItem(MNU_RENAME,
668                                         new PopupItem(MNU_NAME_RENAME)
669                                                         .action("edit-document?action=renameDocument"));
670                         addItem("replace",
671                                         new PopupItem("menu.replace").icon("image.replace.png")
672                                                         .action("select-file?nextAction=replace"));
673                         addSeparator();
674                         addItem(MNU_REMOVE,
675                                         new PopupItem("menu.remove.document").icon(IMG_DELETE)
676                                                         .action("remove-document")
677                                                         .confirmation("message.delete.document"));
678                 }
679
680                 @Override
681                 public boolean isEnabled(final String name) {
682                         boolean res = (_user != null);
683                         if (res) {
684                                 Item item = Item.valueOf(name);
685                                 switch (item) {
686                                         case rename:
687                                                 res = _user.canRename();
688                                                 break;
689                                         case replace:
690                                                 res = _user.canReplace();
691                                                 break;
692                                         case remove:
693                                                 res = _user.canRemove();
694                                                 break;
695                                         default:
696                                                 res = false;
697                                 }
698                         }
699                         return res;
700                 }
701
702                 @Override
703                 public void setContext(final String name, final Object context) {
704                         if (context instanceof DocumentRights) {
705                                 _user = (DocumentRights) context; // Just for optimizing
706                         }
707                 }
708         }
709
710         // Resources relative to simulation contexts
711         private static class ScontextPopup extends PopupMenu {
712                 private SimulationContextFacade _owner = null; // RKV: NOPMD: TODO: Refine the usage of this field or remove it.
713
714                 private ScontextPopup() {
715                         super();
716                         addItem(MNU_RENAME,
717                                         new PopupItem(MNU_NAME_RENAME)
718                                                         .action("edit-context?action=renameContext"));
719                         addItem(MNU_EDIT,
720                                         new PopupItem(MNU_NAME_EDIT)
721                                                         .action("edit-context?action=editContext"));
722                         addSeparator();
723                         addItem(MNU_REMOVE,
724                                         new PopupItem("menu.remove").icon(IMG_DELETE)
725                                                         .action("remove-context")
726                                                         .confirmation("message.delete.context"));
727                 }
728
729                 @Override
730                 public boolean isEnabled(final String name) {
731                         Item item = Item.valueOf(name);
732                         boolean res = true;
733
734                         if (item == Item.rename) {
735                                 res = false;
736                         } else if (item == Item.edit) {
737                                 // if (!owner.isEditable())
738                                 res = false;
739                         }
740                         return res;
741                 }
742
743                 @Override
744                 public void setContext(final String name, final Object context) {
745                         if (context instanceof SimulationContextFacade) {
746                                 _owner = (SimulationContextFacade) context; // Just for optimizing
747                         } else {
748                                 super.setContext(name, context);
749                         }
750                 }
751         }
752
753         // Resources relative to knowledge
754         private static class FeedbexPopup extends PopupMenu {
755                 private transient KnowledgeElement _owner = null;
756
757                 private FeedbexPopup() {
758                         super();
759                         addItem(MNU_PROMOTE,
760                                         new PopupItem(MNU_NAME_PROMOTE).icon("image.review.png")
761                                                         .action("promote-knowledge")
762                                                         .confirmation("message.promote.knowledge"));
763                         addItem(MNU_DEMOTE,
764                                         new PopupItem(MNU_NAME_DEMOTE).icon("image.invalidate.png")
765                                                         .action("demote-knowledge")
766                                                         .confirmation("message.demote.knowledge"));
767                         addSeparator();
768                         addItem(MNU_RENAME,
769                                         new PopupItem(MNU_NAME_RENAME)
770                                                         .action("edit-knowledge?action=renameKnowledge"));
771                         addItem(MNU_EDIT,
772                                         new PopupItem(MNU_NAME_EDIT)
773                                                         .action("edit-knowledge?action=editKnowledge"));
774                         addSeparator();
775                         addItem(MNU_REMOVE,
776                                         new PopupItem("menu.remove").icon(IMG_DELETE)
777                                                         .action("remove-knowledge")
778                                                         .confirmation("message.delete.knowledge"));
779                 }
780
781                 @Override
782                 public boolean isEnabled(final String name) {
783                         Item item = Item.valueOf(name);
784                         boolean res = true;
785
786                         if (item == Item.promote) {
787                                 if (_owner.getProgressState() != ProgressState.inDRAFT) {
788                                         res = false;
789                                 }
790                         } else if ((item == Item.demote)
791                                         && (_owner.getProgressState() != ProgressState.inCHECK)) {
792                                 res = false;
793                         }
794                         return res;
795                 }
796
797                 @Override
798                 public void setContext(final String name, final Object context) {
799                         if (context instanceof KnowledgeElement) {
800                                 _owner = (KnowledgeElement) context; // Just for optimizing
801                         } else {
802                                 super.setContext(name, context);
803                         }
804                 }
805         }
806
807         // ==============================================================================================================================
808         // Construction
809         // ==============================================================================================================================
810
811         public static ApplicationSettings getMe() {
812                 return MY_APP; // The application is supposed being previously created below
813         }
814
815         /**
816          * @param wappurl
817          * @param lang
818          * @return
819          */
820         public ApplicationSettings init(final String wappurl, final Locale lang)
821                         throws IOException {
822                 ClassLoader cloader = Thread.currentThread().getContextClassLoader();
823                 String[] wurl = wappurl.split("/"); // [0]="http:", [1]="", [2]="{server}:{port}", [3]="name"
824
825                 synchronized (MY_APP) {
826                         MY_APP._locale = lang;
827                         MY_APP._wappserver = wurl[2];
828                         MY_APP._wappname = wurl[3];
829                         MY_APP._wapprops.clear();
830                         MY_APP._jndprops.clear();
831                         MY_APP._wapprops.load(cloader.getResourceAsStream(_wappname
832                                         + ".properties"));
833                         MY_APP._jndprops.load(cloader
834                                         .getResourceAsStream("jndi.properties"));
835                 }
836
837                 LOG.info("Application root set to "
838                                 + _wapprops.getProperty("wapp.root"));
839                 return MY_APP;
840         }
841
842         // ==============================================================================================================================
843         // Public member functions
844         // ==============================================================================================================================
845
846         public void configure(final String filename) {
847                 // Non customizable settings
848                 _menus.clear();
849                 SimpleMenu menu = new NewMenu();
850                 _menus.put(menu.getName(), menu);
851                 menu = new SearchMenu();
852                 _menus.put(menu.getName(), menu);
853                 menu = new DatadminMenu();
854                 _menus.put(menu.getName(), menu);
855                 menu = new SysadminMenu();
856                 _menus.put(menu.getName(), menu);
857                 menu = new PropertiesMenu();
858                 _menus.put(menu.getName(), menu);
859
860                 _popups = new HashMap<String, PopupMenu>();
861                 _popups.put("steditable", new EditableStudyPopup());
862                 _popups.put("editable", new EditableDocumentPopup());
863                 _popups.put("notresult", new NotResultDocumentPopup());
864                 _popups.put("reviewable", new ReviewableDocumentPopup());
865                 _popups.put("approvable", new ApprovableDocumentPopup());
866                 _popups.put("approved", new ApprovedPopup());
867                 _popups.put("extern", new ExternPopup());
868                 _popups.put("scontext", new ScontextPopup());
869                 _popups.put("feedbex", new FeedbexPopup());
870
871                 // Default customizable mandatory settings
872                 Map<String, Object> fprop = new HashMap<String, Object>();
873                 fprop.put("visibility", "PRIVATE");
874                 fprop.put("matchamong", ALL);
875                 fprop.put("matcontext", ALL);
876                 fprop.put("state", "APPROVED");
877                 fprop.put("author", "0");
878                 fprop.put("reference", "");
879                 fprop.put("title", "");
880                 fprop.put("context", new ArrayList<SimulationContext>());
881
882                 Map<String, Object> gprop = new HashMap<String, Object>();
883                 gprop.put("visibility", "PUBLIC");
884                 gprop.put("matchamong", ALL);
885                 gprop.put("matcontext", ALL);
886                 gprop.put("type", "2"); // TODO: Get the index from the type name
887                 gprop.put("author", "0");
888                 gprop.put("reference", "");
889                 gprop.put("title", "");
890                 gprop.put("context", new ArrayList<SimulationContext>());
891
892                 _filter = new HashMap<String, Map<String, Object>>();
893                 _filter.put("study", fprop);
894                 _filter.put("knowledge", gprop);
895
896                 _tempfile = new HashMap<String, String>();
897                 _viewermap = new String[0];
898                 _convertmap = new HashMap<String, Converter>();
899
900                 // Customization (must be done after above default settings)
901                 File config = new File(filename);
902                 if (config.exists()) {
903                         loadCustomization(config); // Sets default document types, installed modules and available templates
904                 } else {
905                         LOG.info("Could not find the application configuration file \""
906                                         + config.getAbsolutePath() + "\", using default settings");
907                 }
908                 // Settings based on the customization
909                 configureToolbars();
910         }
911
912         /**
913          * Configure toolbars for steps.
914          */
915         private void configureToolbars() {
916                 _bars = new HashMap<Integer, ToolBar>(); // May be empty if no module installed
917
918                 List<ProjectSettingsService.Step> steps = getProjectSettings()
919                                 .getAllSteps();
920                 for (Iterator<ProjectSettingsService.Step> i = steps.iterator(); i
921                                 .hasNext();) {
922                         ProjectSettingsService.Step step = i.next();
923                         List<String> formats = getProjectSettings().getDefaultFormats(step);
924                         if (formats.isEmpty()) {
925                                 continue;
926                         }
927
928                         ToolBar bar = new ToolBar(24); // Height of the module-bar
929                         Set<String> module = new HashSet<String>(); // For not duplicating modules
930                         for (String format : formats) {
931                                 String command = getApplicationProperty("executable." + format);
932                                 if (command == null) {
933                                         continue; // Module not installed
934                                 }
935                                 if (module.contains(command)) {
936                                         continue;
937                                 }
938                                 module.add(command);
939                                 String[] parsed = command.split("/");
940                                 String[] name = parsed[parsed.length - 1].split("\\x2E");
941                                 DocumentType dtype = getProjectSettings()
942                                                 .getDefaultDocumentType(step, format);
943                                 String docname = "";
944                                 if (dtype != null) {
945                                         docname = dtype.getName();
946                                 }
947                                 if (_tempfile.get(docname) == null) { // No available template
948                                         String tool = parsed[parsed.length - 1];
949                                         String icon = name[0];
950                                         if ("index".equals(icon)) {
951                                                 tool = parsed[parsed.length - 2];
952                                                 icon = "tool." + tool.toLowerCase() + ".png";
953                                         } else {
954                                                 icon = "tool." + icon.toLowerCase() + ".png";
955                                         }
956                                         File image = new File(
957                                                         ApplicationSettings.getApplicationSkinPath() + icon);
958                                         if (!image.exists()) {
959                                                 icon = "tool.any.png";
960                                         }
961                                         bar.addTool(tool, icon, command);
962                                 } else {
963                                         docname = "/jsp/newDocument.jsp?type=" + docname;
964                                         String icon = "tool." + name[0].toLowerCase() + ".png";
965                                         File image = new File(
966                                                         ApplicationSettings.getApplicationSkinPath() + icon);
967                                         if (!image.exists()) {
968                                                 icon = "tool.any.png";
969                                         }
970                                         bar.addTool(name[0], icon, command, docname);
971                                 }
972                         }
973                         if (!bar.isEmpty()) {
974                                 _bars.put(step.getNumber(), bar);
975                         }
976                 }
977         }
978
979         public String getApplicationProperty(final String name) {
980                 return _wapprops.getProperty(name); // May be null
981         }
982
983         public String getApplicationRootPath() {
984                 // RKV: return getApplicationProperty("wapp.root"); // The property is supposed including the Web application name
985                 return _servletContext.getRealPath("/");
986         }
987
988         public String getApplicationURL() {
989                 StringBuffer url = new StringBuffer("http://")
990                                 .append(MY_APP._wappserver).append("/").append(_wappname);
991                 return url.toString();
992         }
993
994         public Map<String, Object> getFilter(final String name) {
995                 return _filter.get(name);
996         }
997
998         public ToolBar getModuleBar(final Step step) {
999                 return _bars.get(step.getNumber());
1000         }
1001
1002         public Properties getNamingProperties() {
1003                 return _jndprops;
1004         }
1005
1006         // ==============================================================================================================================
1007         // Public services
1008         // ==============================================================================================================================
1009
1010         public static String getApplicationPluginPath() {
1011                 return MY_APP.getApplicationRootPath() + "plugin/";
1012         }
1013
1014         public static String getApplicationResourcePath() {
1015                 return MY_APP.getApplicationRootPath() + "WEB-INF/classes/";
1016         }
1017
1018         public static String getApplicationSkinPath() {
1019                 return MY_APP.getApplicationRootPath() + "skin/";
1020         }
1021
1022         public static Converter getConverter(final DocumentType type,
1023                         final String format) {
1024                 return MY_APP._convertmap.get(format + type.getName()); // May be null;
1025         }
1026
1027         public DocumentType getDefaultDocumentType(final Step step,
1028                         final String format) {
1029                 return getProjectSettings().getDefaultDocumentType(step.getStep(),
1030                                 format); // May be null
1031         }
1032
1033         public static String getDownloadURL(final User user) {
1034                 StringBuffer url = new StringBuffer("http://")
1035                                 .append(MY_APP._wappserver).append("/download/")
1036                                 .append(user.getUsername()).append("/");
1037                 return url.toString(); // The download Tomcat context is supposed being defined
1038         }
1039
1040         public static Locale getCurrentLocale() {
1041                 return MY_APP._locale;
1042         }
1043
1044         public static SimpleMenu getMenu(final String name) {
1045                 return MY_APP._menus.get(name);
1046         }
1047
1048         public static PopupMenu getPopupMenu(final String name) {
1049                 return MY_APP._popups.get(name);
1050         }
1051
1052         public static String getRepositoryURL() {
1053                 StringBuffer url = new StringBuffer("http://").append(
1054                                 MY_APP._wappserver).append("/repository/");
1055                 return url.toString(); // The repository Tomcat context is supposed being defined
1056         }
1057
1058         public static Locale[] getSupportedLocales() {
1059                 String[] code = MY_APP._wapprops.getProperty("locale.supported").split(
1060                                 ",");
1061                 Locale[] result = new Locale[code.length];
1062                 for (int i = 0; i < code.length; i++) {
1063                         result[i] = new Locale(code[i]);
1064                 }
1065                 return result;
1066         }
1067
1068         public static String[] getViewersMapping() {
1069                 return MY_APP._viewermap;
1070         }
1071
1072         public static String getWebSiteURL() {
1073                 return MY_APP.getApplicationProperty("wapp.website");
1074         }
1075
1076         public static String getHelpURL() {
1077                 return MY_APP.getApplicationProperty("wapp.onlinehelp");
1078         }
1079
1080         // ==============================================================================================================================
1081         // Private services
1082         // ==============================================================================================================================
1083
1084         /**
1085          * Load customization of workflow from the given XML file.
1086          * 
1087          * @param config
1088          *            the XML configuration file
1089          */
1090         private void loadCustomization(final File config) {
1091                 try {
1092                         DocumentBuilderFactory dfactory = javax.xml.parsers.DocumentBuilderFactory
1093                                         .newInstance();
1094                         DocumentBuilder dBuilder = dfactory.newDocumentBuilder();
1095
1096                         org.w3c.dom.Document conf = dBuilder.parse(config.getPath());
1097                         HashMap<String, Node> children = XDOM.getNamedChildNodes(conf
1098                                         .getDocumentElement());
1099
1100                         // Modules tag
1101                         loadModules(children);
1102
1103                         // Converters tag
1104                         loadConverters(children);
1105
1106                         // Templates tag
1107                         loadTemplates(children);
1108                 } catch (Exception error) {
1109                         LOG.info("Error in customization", error);
1110                 }
1111         }
1112
1113         /**
1114          * Load modules from XML configuration.
1115          * 
1116          * @param children
1117          *            XML nodes
1118          */
1119         private void loadModules(final Map<String, Node> children) {
1120                 Node child = children.get("modules");
1121                 NodeList nlist = child.getChildNodes();
1122                 for (int i = 0; i < nlist.getLength(); i++) {
1123                         child = nlist.item(i);
1124                         if (!child.getNodeName().equals("mapping")) {
1125                                 continue;
1126                         }
1127
1128                         NamedNodeMap natr = child.getAttributes();
1129                         String dext = natr.getNamedItem("extension").getNodeValue();
1130                         String exec = natr.getNamedItem("executable").getNodeValue();
1131                         _wapprops.put("executable." + dext, exec);
1132                 }
1133                 // Viewer mappings tag
1134                 child = children.get("viewers");
1135                 _viewermap = child.getAttributes().getNamedItem("extension")
1136                                 .getNodeValue().split(",");
1137         }
1138
1139         /**
1140          * Load converters from XML configuration.
1141          * 
1142          * @param children
1143          *            XML nodes
1144          */
1145         private void loadConverters(final Map<String, Node> children) {
1146                 Node child = children.get("converters");
1147                 NodeList nlist = child.getChildNodes();
1148                 for (int i = 0; i < nlist.getLength(); i++) {
1149                         child = nlist.item(i);
1150
1151                         if (child.getNodeName().equals("geometry")) {
1152                                 NamedNodeMap natr = child.getAttributes();
1153                                 String from = natr.getNamedItem("from").getNodeValue();
1154                                 String to = natr.getNamedItem("to").getNodeValue();
1155                                 String exec = natr.getNamedItem("executable").getNodeValue();
1156                                 _convertmap.put(from + "geometry", new Converter("geometry",
1157                                                 from, to, exec));
1158                         }
1159                 }
1160         }
1161
1162         /**
1163          * Load templates from XML configuration.
1164          * 
1165          * @param children
1166          *            XML nodes
1167          */
1168         private void loadTemplates(final Map<String, Node> children) {
1169                 Node child = children.get("templates");
1170                 NodeList nlist = child.getChildNodes();
1171                 for (int i = 0; i < nlist.getLength(); i++) {
1172                         child = nlist.item(i);
1173                         if (!child.getNodeName().equals("document")) {
1174                                 continue;
1175                         }
1176
1177                         NamedNodeMap natr = child.getAttributes();
1178                         String type = natr.getNamedItem("type").getNodeValue();
1179                         String file = natr.getNamedItem("file").getNodeValue();
1180                         _tempfile.put(type, file);
1181                 }
1182         }
1183
1184         /**
1185          * Get the documentTypeService.
1186          * 
1187          * @return the documentTypeService
1188          */
1189         public DocumentTypeService getDocumentTypeService() {
1190                 return _documentTypeService;
1191         }
1192
1193         /**
1194          * Set the documentTypeService.
1195          * 
1196          * @param documentTypeService
1197          *            the documentTypeService to set
1198          */
1199         public void setDocumentTypeService(
1200                         final DocumentTypeService documentTypeService) {
1201                 _documentTypeService = documentTypeService;
1202         }
1203
1204         /**
1205          * {@inheritDoc}
1206          * 
1207          * @see org.apache.struts2.util.ServletContextAware#setServletContext(javax.servlet.ServletContext)
1208          */
1209         @Override
1210         public void setServletContext(final ServletContext context) {
1211                 _servletContext = context;
1212         }
1213
1214 }