Salome HOME
Update uses list functionality
[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.http.HttpServletRequest;
16 import javax.xml.parsers.DocumentBuilder;
17 import javax.xml.parsers.DocumentBuilderFactory;
18
19 import org.splat.dal.bo.kernel.User;
20 import org.splat.dal.bo.som.Document;
21 import org.splat.dal.bo.som.DocumentType;
22 import org.splat.dal.bo.som.KnowledgeElement;
23 import org.splat.dal.bo.som.SimulationContext;
24 import org.splat.dal.bo.som.Visibility;
25 import org.splat.log.AppLogger;
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.request.RequestContextHolder;
38 import org.springframework.web.context.request.ServletRequestAttributes;
39 import org.w3c.dom.NamedNodeMap;
40 import org.w3c.dom.Node;
41 import org.w3c.dom.NodeList;
42
43 /**
44  * SIMAN project settings service. Provides settings according to XML customization.
45  */
46 public class ApplicationSettings {
47
48         /**
49          * Application settings logger.
50          */
51         protected final static AppLogger LOG = AppLogger
52                         .getLogger(ApplicationSettings.class);
53         /**
54          * JNDI context for launching converters.
55          */
56         private transient static final Properties _JNDPROPS;
57         /**
58          * Siman web application name.
59          */
60         private transient static String wappname;
61         /**
62          * General properties from the application properties files.
63          */
64         private transient static final Properties _WAPPROPS = new Properties();
65         /**
66          * Siman web application root path on the server.
67          */
68         private transient static String wapproot;
69         /**
70          * Available template files.
71          */
72         private transient static Map<String, String> tempfile;
73         /**
74          * List of file extensions mapped to a viewer.
75          */
76         private transient static String[] viewermap;
77         /**
78          * Available document format converters.
79          */
80         private transient static Map<String, Converter> convertmap;
81
82         static {
83                 synchronized (_WAPPROPS) {
84                         // Do common configuration for all users
85
86                         _JNDPROPS = new Properties();
87                         tempfile = new HashMap<String, String>();
88                         viewermap = new String[0];
89                         convertmap = new HashMap<String, Converter>();
90
91                         ClassLoader cloader = Thread.currentThread()
92                                         .getContextClassLoader();
93                         HttpServletRequest curRequest = ((ServletRequestAttributes) RequestContextHolder
94                                         .currentRequestAttributes()).getRequest();
95                         String appname = curRequest.getContextPath();
96                         if (appname.startsWith("/")) {
97                                 wappname = appname.substring(1);
98                         }
99                         // Set local path on the server to the application root.
100                         wapproot = curRequest.getSession().getServletContext().getRealPath(
101                                         "/");
102
103                         try {
104                                 _JNDPROPS.load(cloader.getResourceAsStream("jndi.properties"));
105                                 _WAPPROPS.load(cloader.getResourceAsStream(wappname
106                                                 + ".properties"));
107                         } catch (IOException e) {
108                                 LOG.info(
109                                                 "Can't load application properties: " + e.getMessage(),
110                                                 e);
111                         }
112
113                         // Configure login security
114                         System.setProperty("java.security.auth.login.config", wapproot
115                                         + ApplicationSettings.getApplicationProperty("wapp.login"));
116
117                         // Customization (must be done after above default settings)
118                         File config = new File(wapproot
119                                         + getApplicationProperty("wapp.customization"));
120                         if (config.exists()) {
121                                 loadCustomization(config); // Sets default document types, installed modules and available templates
122                         } else {
123                                 LOG.info("Could not find the application configuration file \""
124                                                 + config.getAbsolutePath()
125                                                 + "\", using default settings");
126                         }
127                 }
128         }
129
130         /**
131          * All value.
132          */
133         private static final String ALL = "all";
134
135         /**
136          * Hold icon file name.
137          */
138         private static final String IMG_HOLD = "image.hold.gif";
139         /**
140          * Attach icon file name.
141          */
142         private static final String IMG_ATTACH = "image.attach.png";
143         /**
144          * Version icon file name.
145          */
146         private static final String IMG_VERSION = "image.version.png";
147         /**
148          * Delete icon file name.
149          */
150         private static final String IMG_DELETE = "icon.delete.png";
151         /**
152          * Promote icon file name.
153          */
154         private static final String IMG_PROMOTE = "image.publish.png";
155         /**
156          * Demote icon file name.
157          */
158         private static final String IMG_DEMOTE = "image.demote.png";
159         /**
160          * Accept icon file name.
161          */
162         private static final String IMG_ACCEPT = "image.accept.png";
163         
164         /**
165          * Attach menu item name.
166          */
167         private static final String MNU_ATTACH = "attach";
168         /**
169          * Demote menu item name.
170          */
171         private static final String MNU_DEMOTE = "demote";
172         /**
173          * Promote menu item name.
174          */
175         private static final String MNU_PROMOTE = "promote";
176         /**
177          * Publish menu item name.
178          */
179         private static final String MNU_PUBLISH = "publish";
180         /**
181          * Edit menu item name.
182          */
183         private static final String MNU_EDIT = "edit";
184         /**
185          * Script menu item name.
186          */
187         private static final String MNU_SCRIPT = "script";
188         /**
189          * Version menu item name.
190          */
191         private static final String MNU_VERSION = "version";
192         // /**
193         // * Purge menu item name.
194         // */
195         // private static final String MNU_PURGE = "purge";
196         /**
197          * Remove menu item name.
198          */
199         private static final String MNU_REMOVE = "remove";
200         /**
201          * Rename menu item name.
202          */
203         private static final String MNU_RENAME = "rename";
204         /**
205          * Set up-to-date menu item name.
206          */
207         private static final String MNU_ACTUALIZE = "accept";
208
209         /**
210          * Attach menu item name.
211          */
212         private static final String MNU_NAME_ATTACH = "menu.attach";
213         /**
214          * Demote menu item name.
215          */
216         private static final String MNU_NAME_DEMOTE = "menu.demote";
217         /**
218          * Promote menu item name.
219          */
220         private static final String MNU_NAME_PROMOTE = "menu.promote";
221         /**
222          * Publish menu item name.
223          */
224         private static final String MNU_NAME_PUBLISH = "menu.publish";
225         /**
226          * Protect menu item name.
227          */
228         private static final String MNU_NAME_PROTECT = "menu.protect";
229         /**
230          * Edit menu item name.
231          */
232         private static final String MNU_NAME_EDIT = "menu.edit";
233         /**
234          * Edit menu item name.
235          */
236         private static final String MNU_NAME_REMOVE = "menu.remove";
237         /**
238          * Script menu item name.
239          */
240         private static final String MNU_NAME_SCRIPT = "menu.newscenario";
241         /**
242          * Version menu item name.
243          */
244         private static final String MNU_NAME_VERSION = "menu.version";
245         /**
246          * Purge menu item name.
247          */
248         // private static final String MNU_NAME_PURGE = "menu.purge";
249         /**
250          * Remove menu item name.
251          */
252         private static final String MNU_NAME_REMOVE_VERSION = "menu.remove.version";
253         /**
254          * Remove scenario menu item name.
255          */
256         private static final String MNU_NAME_REMOVE_SCENARIO = "menu.remove.scenario";
257         /**
258          * Rename menu item name.
259          */
260         private static final String MNU_NAME_RENAME = "menu.rename";
261         /**
262          * Mark as reference menu item name.
263          */
264         private static final String MNU_MARK_AS_REFERENCE = "markasreference";
265         /**
266          * Mark as reference menu item label key.
267          */
268         private static final String MNU_NAME_MARK_AS_REFERENCE = "menu.markasreference";
269         /**
270          * Remove as reference menu item label key.
271          */
272         private static final String MNU_NAME_REMOVE_AS_REFERENCE = "menu.removeasreference";
273         /**
274          * Set up-to-date menu item label key.
275          */
276         private static final String MNU_NAME_ACTUALIZE = "menu.actualize";
277         // /**
278         // * Not yet implemented action name.
279         // */
280         // private static final String ACT_NOT_YET_IMPLEMENTED = "notyetimplemented";
281         /**
282          * Attach action name.
283          */
284         private static final String ACT_ATTACH = "select-file?nextAction=attach";
285         /**
286          * Version action name.
287          */
288         private static final String ACT_VERSION = "select-file?nextAction=version";
289         /**
290          * Mark as reference action name.
291          */
292         private static final String ACT_MARK_AS_REFERENCE = "markasref-study";
293         /**
294          * Remove as reference action name.
295          */
296         private static final String ACT_REMOVE_AS_REFERENCE = "removeasref-study";
297         /**
298          * Remove scenario action name.
299          */
300         private static final String ACT_REMOVE_SCENARIO = "remove-study";
301         /**
302          * Promote the study action name.
303          */
304         private static final String ACT_PROMOTE_STUDY = "edit-study?action=promote";
305         /**
306          * Set up-to-date action name.
307          */
308         private static final String ACT_ACTUALIZE = "setDocument?action=accept";
309         
310         /**
311          * Siman application server name.
312          */
313         private transient final String _wappserver;
314         /**
315          * Current user locale.
316          */
317         private transient Locale _locale;
318         /**
319          * Application menus.
320          */
321         private transient final Map<String, SimpleMenu> _menus = new HashMap<String, SimpleMenu>();
322         /**
323          * Study module-bars structured by steps.
324          */
325         private transient Map<Integer, ToolBar> _bars = null;
326         /**
327          * Popup menus.
328          */
329         private transient Map<String, PopupMenu> _popups = null;
330         /**
331          * Named search filters.
332          */
333         private transient Map<String, Map<String, Object>> _filter = null;
334         /**
335          * Injected project settings service.
336          */
337         private ProjectSettingsService _projectSettings;
338         /**
339          * Injected document type service.
340          */
341         private DocumentTypeService _documentTypeService;
342
343         /**
344          * Application settings constructor.
345          */
346         public ApplicationSettings() {
347                 HttpServletRequest curRequest = ((ServletRequestAttributes) RequestContextHolder
348                                 .currentRequestAttributes()).getRequest();
349                 _wappserver = curRequest.getServerName() + ":"
350                                 + curRequest.getServerPort();
351
352                 LOG.info("Application server is set to " + _wappserver);
353                 LOG.info("Application name is set to " + wappname);
354         }
355
356         /**
357          * Get the projectSettingsService.
358          * 
359          * @return the projectSettingsService
360          */
361         public ProjectSettingsService getProjectSettings() {
362                 return _projectSettings;
363         }
364
365         /**
366          * Set the projectSettingsService.
367          * 
368          * @param projectSettingsService
369          *            the projectSettingsService to set
370          */
371         public void setProjectSettings(
372                         final ProjectSettingsService projectSettingsService) {
373                 _projectSettings = projectSettingsService;
374         }
375
376         /**
377          * New study menu.
378          */
379         private static class NewMenu extends SimpleMenu {
380                 /**
381                  * New study menu constructor.
382                  */
383                 private NewMenu() {
384                         super("create");
385                         addItem("new-empty", "menu.new.empty", "image.empty.png",
386                                         "select?menu=create&item=new-empty");
387                         addItem("new-copy", "menu.new.copy", "image.copy.png",
388                                         "select?menu=create&item=new-copy");
389                         /*
390                          * addItem("new-instance", new MenuItem("menu.new.instance") .icon(IMG_HOLD)); addItem("new-import", new
391                          * MenuItem("menu.new.import") .icon("icon.upload.png"));
392                          */
393                         this.selects("new-empty");
394                 }
395         }
396
397         /**
398          * Search menu.
399          */
400         private static class SearchMenu extends SimpleMenu {
401                 /**
402                  * Search menu constructor.
403                  */
404                 private SearchMenu() {
405                         super("search");
406                         addItem("search-study", "menu.search.study", "image.study.png",
407                                         "select?menu=search&item=search-study");
408                         addItem("search-knowledge", "menu.search.idea", "image.idea.png",
409                                         "select?menu=search&item=search-knowledge");
410                         addItem("search-document", new MenuItem("menu.search.document")
411                                         .icon("icon.any.png"));
412                         this.selects("search-study");
413                 }
414         }
415
416         /**
417          * Configuration menu.
418          */
419         private static class PropertiesMenu extends SimpleMenu {
420                 /**
421                  * Configuration menu constructor.
422                  */
423                 private PropertiesMenu() {
424                         super("configuration");
425                         addItem("prop-general", "menu.prop.general", IMG_HOLD,
426                                         "select?menu=configuration&item=prop-general");
427                         addItem("prop-scenario", "menu.prop.scenario", IMG_HOLD,
428                                         "select?menu=configuration&item=prop-scenario");
429                         // These menu items will not be implemented in the current version.
430                         /*
431                          * addItem("prop-timestamp", new MenuItem("menu.prop.timestamp") .icon("image.stamp.png")); addItem("prop-comlog", new
432                          * MenuItem("menu.prop.comlog") .icon(IMG_HOLD)); addItem("prop-version", new MenuItem("menu.prop.version")
433                          * .icon("image.dirclosed.png"));
434                          */
435                 }
436         }
437
438         /**
439          * Data administrator menu.
440          */
441         private static class DatadminMenu extends SimpleMenu {
442                 /**
443                  * Data administrator menu constructor.
444                  */
445                 private DatadminMenu() {
446                         super("datadmin");
447                         addItem("admin-scontext", "menu.admin.context", IMG_HOLD,
448                                         "select?menu=datadmin&item=admin-scontext");
449                         addItem("admin-knowelm", "menu.admin.knowledge", "image.idea.png",
450                                         "select?menu=datadmin&item=admin-knowelm");
451                         addItem("admin-study", new MenuItem("menu.admin.study")
452                                         .icon("image.study.png"));
453                 }
454         }
455
456         /**
457          * System administrator menu.
458          */
459         private static class SysadminMenu extends SimpleMenu {
460                 /**
461                  * System administrator menu constructor.
462                  */
463                 private SysadminMenu() {
464                         super("sysadmin");
465                         addItem("admin-indexing", "menu.admin.indexing", "image.index.png",
466                                         "select?menu=sysadmin&item=admin-indexing");
467                         addItem("admin-importuser", "menu.admin.importuser",
468                                         "image.group.png",
469                                         "select?menu=sysadmin&item=admin-importuser");
470                 }
471         }
472
473         /**
474          * Menu items enumeration.
475          */
476         private enum Item {
477                 /**
478                  * Publish the study.
479                  */
480                 publish,
481                 /**
482                  * Accept the document.
483                  */
484                 accept,
485                 /**
486                  * Approve the document.
487                  */
488                 approve,
489                 /**
490                  * Promote the document.
491                  */
492                 promote,
493                 /**
494                  * Demote the docuemnt.
495                  */
496                 demote,
497                 /**
498                  * Undo the last operation.
499                  */
500                 undo,
501                 /**
502                  * Rename the document.
503                  */
504                 rename,
505                 /**
506                  * Attach a file to the document.
507                  */
508                 attach,
509                 /**
510                  * Edit the document.
511                  */
512                 edit,
513                 /**
514                  * script.
515                  */
516                 script,
517                 /**
518                  * Version the document.
519                  */
520                 version,
521                 /**
522                  * replace.
523                  */
524                 replace,
525                 /**
526                  * export.
527                  */
528                 export,
529                 /**
530                  * Remove the document.
531                  */
532                 remove,
533                 /**
534                  * purge.
535                  */
536                 purge,
537                 /**
538                  * Mark the study as reference.
539                  */
540                 markasreference,
541                 /**
542                  * Remove selected scenario.
543                  */
544                 removescenario
545         };
546
547         // Resources relative to studies
548         /**
549          * Base study popup menu.
550          */
551         private static class StudyPopup extends PopupMenu {
552                 /**
553                  * User rights for the selected study.
554                  */
555                 protected transient StudyRights _user = null;
556
557                 /**
558                  * Specifies if a scenario is selected, hence the "remove scenario" menu item can be enabled.
559                  */
560                 private boolean _scenarioSlected = false;
561
562                 /**
563                  * Add items which are common for all study popup menus.
564                  */
565                 protected void addCommonItems() {
566                         addSeparator();
567                         addItem(MNU_EDIT, new PopupItem("menu.properties").icon(
568                                         "icon.ed.png").action(
569                                         "../select.action?menu=configuration"));
570                         addSeparator();
571                         addItem(MNU_SCRIPT, new PopupItem(MNU_NAME_SCRIPT)
572                                         .action("add-scenario"));
573                         /*
574                          * addItem(MNU_VERSION, new PopupItem(MNU_NAME_VERSION).icon( IMG_VERSION).action(ACT_NOT_YET_IMPLEMENTED));
575                          * addItem(MNU_PURGE, new PopupItem(MNU_NAME_PURGE) .confirmation("message.purge.study")); addItem("export", new
576                          * PopupItem("menu.export") .icon("image.export.png")); // For future needs
577                          */
578                         addItem(Item.removescenario.toString(),
579                                         new PopupItem(MNU_NAME_REMOVE_SCENARIO)
580                                         .icon(IMG_DELETE).action("remove-scenario"/*"ACT_REMOVE_SCENARIO"*/)
581                                         .confirmation("message.delete.scenario"));
582                         addSeparator();
583                         addItem(MNU_REMOVE, new PopupItem(MNU_NAME_REMOVE_VERSION).icon(
584                                         IMG_DELETE).action(ACT_REMOVE_SCENARIO).confirmation(
585                                         "message.delete.study"));
586                 }
587
588                 /**
589                  * {@inheritDoc}
590                  * 
591                  * @see org.splat.wapp.ContextualMenu#isEnabled(java.lang.String)
592                  */
593                 @Override
594                 public boolean isEnabled(final String name) {
595                         boolean res = (_user != null);
596                         if (res) {
597                                 Item item = Item.valueOf(name);
598                                 switch (item) {
599                                         case publish:
600                                                 if (_user.getOperand().getVisibility() == Visibility.PRIVATE) {
601                                                         res = _user.canPublish();
602                                                 } else {
603                                                         res = _user.canProtect();
604                                                 }
605                                                 break;
606                                         case edit:
607                                                 res = _user.canEditProperties();
608                                                 break;
609                                         case script:
610                                                 res = _user.canAddScenario();
611                                                 break;
612                                         case version:
613                                                 res = _user.canVersion();
614                                                 break;
615                                         case remove:
616                                                 res = _user.canRemove();
617                                                 break;
618                                         case promote:
619                                                 res = _user.canPromote();
620                                                 break;
621                                         case demote:
622                                                 res = _user.canDemote();
623                                                 break;
624                                         case approve:
625                                                 res = _user.canApprove();
626                                                 break;
627                                         case markasreference:
628                                                 if (_user.getOperand().getMarkreference() == 0) {
629                                                         res = _user.canMarkStudyAsReference();
630                                                 } else {
631                                                         res = _user.canRemoveStudyAsReference();
632                                                 }
633                                                 break;
634                                         case removescenario:
635                                                 if(_scenarioSlected) {
636                                                         res = _user.canRemoveScenario();
637                                                 } else {
638                                                         res =false;
639                                                 }
640                                                 break;
641                                         default:
642                                                 res = false;
643                                 }
644                         }
645                         return res;
646                 }
647
648                 /**
649                  * {@inheritDoc}
650                  * 
651                  * @see org.splat.wapp.ContextualMenu#setContext(java.lang.String, java.lang.Object)
652                  */
653                 @Override
654                 public void setContext(final String name, final Object context) {
655                         if (context instanceof StudyRights) {
656                                 _user = (StudyRights) context; // Just for optimizing
657                                 boolean history = _user.getOperand().isVersioned();
658                                 PopupItem item = this.item(MNU_REMOVE);
659                                 if (history) {
660                                         item.rename(MNU_NAME_REMOVE_VERSION);
661                                 } else {
662                                         item.rename("menu.remove.study");
663                                 }
664                         }
665                 }
666
667                 /**
668                  * Set the scenarioSlected.
669                  * @param scenarioSlected the scenarioSlected to set
670                  */
671                 public StudyPopup setScenarioSlected(final boolean scenarioSlected) {
672                         _scenarioSlected = scenarioSlected;
673                         return this;
674                 }
675         }
676
677         /**
678          * Approved study popup menu.
679          */
680         private static class EditableMarkedStudyPopup extends StudyPopup {
681
682                 /**
683                  * Study popup menu constructor.
684                  * 
685                  * @param isPublic
686                  *            public study flag
687                  * @param isMarked
688                  *            "marked as reference" study flag
689                  */
690                 private EditableMarkedStudyPopup(final boolean isPublic,
691                                 final boolean isMarked) {
692                         super();
693
694                         if (isMarked) {
695                                 addItem(MNU_MARK_AS_REFERENCE, new PopupItem(
696                                                 MNU_NAME_REMOVE_AS_REFERENCE).action(
697                                                 ACT_REMOVE_AS_REFERENCE).confirmation(
698                                                 "message.removeasreference.study"));
699                         } else {
700                                 addItem(MNU_MARK_AS_REFERENCE, new PopupItem(
701                                                 MNU_NAME_MARK_AS_REFERENCE).action(
702                                                 ACT_MARK_AS_REFERENCE).confirmation(
703                                                 "message.markasreference.study"));
704                         }
705
706                         if (isPublic) {
707                                 addItem(MNU_PUBLISH, new PopupItem(MNU_NAME_PROTECT).icon(
708                                                 IMG_PROMOTE)
709                                                 .action("edit-study?action=protect").confirmation(
710                                                                 "message.protect.study"));
711                         } else {
712                                 addItem(MNU_PUBLISH, new PopupItem(MNU_NAME_PUBLISH).icon(
713                                                 IMG_PROMOTE)
714                                                 .action("edit-study?action=publish").confirmation(
715                                                                 "message.publish.study"));
716                         }
717
718                         addCommonItems();
719                 }
720
721         }
722
723         /**
724          * In-Work study popup menu.
725          */
726         private static class EditableStudyPopup extends StudyPopup {
727                 /**
728                  * Study popup menu constructor.
729                  */
730                 private EditableStudyPopup() {
731                         super();
732
733                         addItem(MNU_PROMOTE, new PopupItem(MNU_NAME_PROMOTE).icon(
734                                         IMG_PROMOTE).action(ACT_PROMOTE_STUDY)
735                                         .confirmation("message.promote.study"));
736
737                         addCommonItems();
738                 }
739         }
740
741         /**
742          * In-Work study popup menu.
743          */
744         private static class ReviewableStudyPopup extends StudyPopup {
745                 /**
746                  * Study popup menu constructor.
747                  */
748                 private ReviewableStudyPopup() {
749                         super();
750
751                         addItem(MNU_DEMOTE, new PopupItem(MNU_NAME_DEMOTE).icon(
752                                         IMG_DEMOTE).action("edit-study?action=demote")
753                                         .confirmation("message.demote.study"));
754                         addItem(MNU_PROMOTE, new PopupItem("menu.review").icon(
755                                         "image.review.png").action(ACT_PROMOTE_STUDY)
756                                         .confirmation("message.review.study"));
757
758                         addCommonItems();
759                 }
760         }
761
762         /**
763          * In-Work study popup menu.
764          */
765         private static class ApprovableStudyPopup extends StudyPopup {
766                 /**
767                  * Study popup menu constructor.
768                  */
769                 private ApprovableStudyPopup() {
770                         super();
771
772                         addItem(MNU_PROMOTE, new PopupItem(MNU_NAME_PROMOTE).icon(
773                                         IMG_PROMOTE).action(ACT_PROMOTE_STUDY)
774                                         .confirmation("message.promote.study"));
775                         // Refuse
776                         addItem(MNU_DEMOTE, new PopupItem("menu.demote").icon(
777                                         IMG_DEMOTE).action("edit-study?action=demote")
778                                         .confirmation("message.demote.study"));
779                         addItem("approve", new PopupItem("menu.approve").icon(
780                                         "icon.APPROVED.png").action(ACT_PROMOTE_STUDY)
781                                         .confirmation("message.approve.study"));
782
783                         addCommonItems();
784                 }
785         }
786
787         // Resources relative to documents
788         /**
789          * Popup of a document.
790          */
791         private static class DocumentPopup extends PopupMenu {
792                 /**
793                  * Current user rights.
794                  */
795                 private transient DocumentRights _user = null;
796
797                 /**
798                  * {@inheritDoc}
799                  * 
800                  * @see org.splat.wapp.ContextualMenu#isEnabled(java.lang.String)
801                  */
802                 @Override
803                 public boolean isEnabled(final String name) {
804                         boolean res = (_user != null);
805                         if (res) {
806                                 Item item = Item.valueOf(name);
807                                 switch (item) {
808                                         case accept:
809                                                 res = _user.canAccept();
810                                                 break;
811                                         case promote:
812                                                 res = _user.canPromote();
813                                                 break;
814                                         case rename:
815                                                 res = _user.canRename();
816                                                 break;
817                                         case attach:
818                                                 res = _user.canAttach();
819                                                 break;
820                                         case edit:
821                                                 res = _user.canEdit();
822                                                 break;
823                                         case version:
824                                                 res = _user.canVersion();
825                                                 break;
826                                         case replace:
827                                                 res = _user.canReplace();
828                                                 break;
829                                         case remove:
830                                                 res = _user.canRemove();
831                                                 break;
832                                         case purge:
833                                                 res = _user.canPurge();
834                                                 break;
835                                         case undo:
836                                                 res = _user.canInvalidate();
837                                                 break;
838                                         case demote:
839                                                 res = _user.canDemote();
840                                                 break;
841                                         case approve:
842                                                 res = _user.canApprove();
843                                                 break;
844                                         default:
845                                                 res = false;
846                                 }
847                         }
848                         return res;
849                 }
850
851                 /**
852                  * {@inheritDoc}
853                  * 
854                  * @see org.splat.wapp.ContextualMenu#setContext(java.lang.String, java.lang.Object)
855                  */
856                 @Override
857                 public void setContext(final String name, final Object context) {
858                         if (context instanceof DocumentRights) {
859                                 _user = (DocumentRights) context; // Just for optimizing
860                                 Document downer = _user.getOperand();
861                                 if (this.hasItem(MNU_REMOVE)) {
862                                         if (downer.getPreviousVersion() == null) {
863                                                 this.item(MNU_REMOVE).rename("menu.remove.document");
864                                         } else {
865                                                 this.item(MNU_REMOVE).rename(MNU_NAME_REMOVE_VERSION);
866                                         }
867                                 }
868                         }
869                 }
870                 
871                 /**
872                  * Add Actualize menu item.
873                  */
874                 protected void addActualize() {
875                         addItem(MNU_ACTUALIZE, new PopupItem(MNU_NAME_ACTUALIZE)
876                         .icon(IMG_ACCEPT).action(ACT_ACTUALIZE)
877                         .confirmation("message.actualize.document"));
878                 }
879                 /**
880                  * Add Review menu item.
881                  */
882                 protected void addReview() {
883                         addItem(MNU_PROMOTE, new PopupItem("menu.review").icon(
884                         "image.review.png").action("setDocument?action=review")
885                         .confirmation("message.review.document"));
886                 }
887                 /**
888                  * Add Demote menu item.
889                  * @param author
890                  *                      indicates if the connected user is the author of the document.
891                  */
892                 protected void addDemote(final boolean author) {
893                         String itemName;
894                         if(author) {
895                                 itemName = MNU_NAME_DEMOTE;
896                         } else {
897                                 itemName = "menu.reject";
898                         }
899                         addItem(MNU_DEMOTE, new PopupItem(itemName).icon(
900                                 IMG_DEMOTE).action("setDocument?action=demote")
901                                 .confirmation("message.demote.document"));
902                 }
903                 /**
904                  * Add Version menu item.
905                  */
906                 protected void addVersion() {
907                         addItem(MNU_VERSION, new PopupItem(MNU_NAME_VERSION).icon(
908                                         IMG_VERSION).action(ACT_VERSION));
909                 }
910                 /**
911                  * Add Attach menu item.
912                  */
913                 protected void addAttach() {
914                         addItem(MNU_ATTACH, new PopupItem(MNU_NAME_ATTACH).icon(IMG_ATTACH)
915                                         .action(ACT_ATTACH));
916                 }
917                 /**
918                  * Add Remove menu item.
919                  */
920                 protected void addRemove() {
921                         addItem(MNU_REMOVE, new PopupItem(MNU_NAME_REMOVE_VERSION).icon(
922                                         IMG_DELETE).action("remove-document").confirmation(
923                                         "message.delete.document"));
924                 }
925                 /**
926                  * Add Approve menu item.
927                  */
928                 protected void addApprove() {
929                         addItem("approve", new PopupItem("menu.approve").icon(
930                         "icon.APPROVED.png").action("setDocument?action=approve")
931                         .confirmation("message.approve.document"));
932                         
933                 }
934         }
935
936         /**
937          * Popup of In-Work documents.
938          */
939         private static class EditableDocumentPopup extends DocumentPopup {
940                 /**
941                  * Document popup menu constructor.
942                  */
943                 private EditableDocumentPopup() {
944                         super();
945                         addItem(MNU_ACTUALIZE, new PopupItem(MNU_NAME_ACTUALIZE)
946                                         .icon(IMG_ACCEPT).action(ACT_ACTUALIZE)
947                                         .confirmation("message.actualize.document"));
948                         addItem(MNU_PROMOTE, new PopupItem(MNU_NAME_PROMOTE).icon(
949                                         IMG_PROMOTE).action("setDocument?action=promote")
950                                         .confirmation("message.promote.document"));
951                         addSeparator();
952                         addItem(MNU_RENAME, new PopupItem(MNU_NAME_RENAME)
953                                         .action("edit-document?action=renameDocument"));
954                         addItem(MNU_ATTACH, new PopupItem(MNU_NAME_ATTACH).icon(IMG_ATTACH)
955                                         .action(ACT_ATTACH));
956                         addSeparator();
957                         addItem(MNU_VERSION, new PopupItem(MNU_NAME_VERSION).icon(
958                                         IMG_VERSION).action(ACT_VERSION));
959                         addItem("replace", new PopupItem("menu.replace").icon(
960                                         "image.replace.png").action(
961                                         "select-file?nextAction=replace"));
962                         addSeparator();
963                         /*
964                          * addItem(MNU_PURGE, new PopupItem(MNU_NAME_PURGE).action( ACT_NOT_YET_IMPLEMENTED).confirmation( "message.purge.document"));
965                          */
966                         addItem(MNU_REMOVE, new PopupItem(MNU_NAME_REMOVE_VERSION).icon(
967                                         IMG_DELETE).action("remove-document").confirmation(
968                                         "message.delete.document"));
969                 }
970         }
971
972         /**
973          * Popup of In-Draft documents when connected user is the author of the document.
974          */
975         private static class ReviewableDocumentPopupAuthor extends DocumentPopup {
976                 /**
977                  * Document popup menu constructor.
978                  */
979                 private ReviewableDocumentPopupAuthor() {
980                         super();
981                         addItem(MNU_ACTUALIZE, new PopupItem(MNU_NAME_ACTUALIZE)
982                                         .icon(IMG_ACCEPT).action(ACT_ACTUALIZE)
983                                         .confirmation("message.actualize.document"));
984                         addItem(MNU_DEMOTE, new PopupItem(MNU_NAME_DEMOTE).icon(
985                                         IMG_DEMOTE).action("setDocument?action=demote")
986                                         .confirmation("message.demote.document"));
987                         addItem(MNU_PROMOTE, new PopupItem("menu.review").icon(
988                                         "image.review.png").action("setDocument?action=review")
989                                         .confirmation("message.review.document"));
990                         addSeparator();
991                         addItem(MNU_ATTACH, new PopupItem(MNU_NAME_ATTACH).icon(IMG_ATTACH)
992                                         .action(ACT_ATTACH));
993                         addSeparator();
994                         addItem(MNU_VERSION, new PopupItem(MNU_NAME_VERSION).icon(
995                                         IMG_VERSION).action(ACT_VERSION));
996                         /*
997                          * addSeparator();
998                          * addItem(MNU_PURGE, new PopupItem(MNU_NAME_PURGE).action( ACT_NOT_YET_IMPLEMENTED).confirmation( "message.purge.document"));
999                          */
1000                 }
1001         }
1002         
1003         /**
1004          * Popup of In-Draft documents when connected user is not the author of the document.
1005          */
1006         private static class ReviewableDocumentPopupNonAuthor extends DocumentPopup {
1007                 /**
1008                  * Default constructor.
1009                  */
1010                 private ReviewableDocumentPopupNonAuthor() {
1011                         super();
1012                         addActualize();
1013                         addDemote(false);
1014                         addReview();
1015                         addSeparator();
1016                         addAttach();
1017                         addSeparator();
1018                         addVersion();
1019                 }
1020         }
1021
1022         /**
1023          * Popup menu for documents which are not results of a step
1024          * when connected user is the author of the document.
1025          */
1026         private static class NotResultDocumentPopupAuthor extends DocumentPopup {
1027                 /**
1028                  * Default constructor.
1029                  */
1030                 private NotResultDocumentPopupAuthor() {
1031                         super();
1032                         addItem(MNU_ACTUALIZE, new PopupItem(MNU_NAME_ACTUALIZE)
1033                                         .icon(IMG_ACCEPT).action(ACT_ACTUALIZE)
1034                                         .confirmation("message.actualize.document"));
1035                         addItem(MNU_DEMOTE, new PopupItem(MNU_NAME_DEMOTE).icon(
1036                                         IMG_DEMOTE).action("setDocument?action=demote")
1037                                         .confirmation("message.demote.document"));
1038                         addSeparator();
1039                         addItem(MNU_ATTACH, new PopupItem(MNU_NAME_ATTACH).icon(IMG_ATTACH)
1040                                         .action(ACT_ATTACH));
1041                         addSeparator();
1042                         addItem(MNU_VERSION, new PopupItem(MNU_NAME_VERSION).icon(
1043                                         IMG_VERSION).action(ACT_VERSION));
1044                         addSeparator();
1045                         /*
1046                          * addItem(MNU_PURGE, new PopupItem(MNU_NAME_PURGE).action( ACT_NOT_YET_IMPLEMENTED).confirmation( "message.purge.document"));
1047                          */
1048                         addItem(MNU_REMOVE, new PopupItem(MNU_NAME_REMOVE_VERSION).icon(
1049                                         IMG_DELETE).action("remove-document").confirmation(
1050                                         "message.delete.document"));
1051                 }
1052         }
1053         
1054         /**
1055          * Popup menu for documents which are not results of a step
1056          * when connected user is not the author of the document.
1057          */
1058         private static class NotResultDocumentPopupNonAuthor extends DocumentPopup {
1059                 /**
1060                  * Default constructor.
1061                  */
1062                 private NotResultDocumentPopupNonAuthor() {
1063                         super();
1064                         addActualize();
1065                         addDemote(false);
1066                         addSeparator();
1067                         addAttach();
1068                         addSeparator();
1069                         addVersion();
1070                         addSeparator();
1071                         addRemove();
1072                 }
1073         }
1074
1075         /**
1076          * Popup of In-Check documents
1077          * when connected user is the author of the document.
1078          */
1079         private static class ApprovableDocumentPopupAuthor extends DocumentPopup {
1080                 /**
1081                  * Default constructor.
1082                  */
1083                 private ApprovableDocumentPopupAuthor() {
1084                         super();
1085                         addItem(MNU_ACTUALIZE, new PopupItem(MNU_NAME_ACTUALIZE)
1086                                         .icon(IMG_ACCEPT).action(ACT_ACTUALIZE)
1087                                         .confirmation("message.actualize.document"));
1088                         
1089                         /*addItem("undo", new PopupItem(MNU_NAME_DEMOTE).icon(
1090                                         "image.invalidate.png").action(
1091                                         "setDocument?action=invalidate").confirmation(
1092                                         "message.demote.document"));*/
1093                         addItem(MNU_DEMOTE, new PopupItem("menu.demote").icon(
1094                                         IMG_DEMOTE).action("setDocument?action=demote")
1095                                         .confirmation("message.demote.document"));
1096                         addItem("approve", new PopupItem("menu.approve").icon(
1097                                         "icon.APPROVED.png").action("setDocument?action=approve")
1098                                         .confirmation("message.approve.document"));
1099                 }
1100         }
1101
1102         /**
1103          * Popup of In-Check documents
1104          * when connected user is not the author of the document.
1105          */
1106         private static class ApprovableDocumentPopupNonAuthor extends DocumentPopup {
1107                 /**
1108                  * Default constructor.
1109                  */
1110                 private ApprovableDocumentPopupNonAuthor() {
1111                         super();
1112                         addActualize();
1113                         addDemote(false);
1114                         addApprove();
1115                 }
1116         }
1117
1118         /**
1119          * Popup of Approved documents.
1120          */
1121         private static class ApprovedPopup extends DocumentPopup {
1122                 /**
1123                  * Default constructor.
1124                  */
1125                 private ApprovedPopup() {
1126                         super();
1127                         addItem(MNU_ACTUALIZE, new PopupItem(MNU_NAME_ACTUALIZE)
1128                                         .icon(IMG_ACCEPT).action(ACT_ACTUALIZE)
1129                                         .confirmation("message.actualize.document"));
1130                         addItem(MNU_ATTACH, new PopupItem(MNU_NAME_ATTACH).icon(IMG_ATTACH)
1131                                         .action(ACT_ATTACH));
1132                         addSeparator();
1133                         addItem(MNU_VERSION, new PopupItem(MNU_NAME_VERSION).icon(
1134                                         IMG_VERSION).action(ACT_VERSION));
1135                 }
1136         }
1137
1138         /**
1139          * Popup of external documents.
1140          */
1141         private static class ExternPopup extends DocumentPopup {
1142                 /**
1143                  * Default constructor.
1144                  */
1145                 private ExternPopup() {
1146                         super();
1147                         addItem(MNU_RENAME, new PopupItem(MNU_NAME_RENAME)
1148                                         .action("edit-document?action=renameDocument"));
1149                         addSeparator();
1150                         addItem(MNU_VERSION, new PopupItem(MNU_NAME_VERSION).icon(
1151                                         IMG_VERSION).action(ACT_VERSION));
1152                         addSeparator();
1153                         addItem("replace", new PopupItem("menu.replace").icon(
1154                                         "image.replace.png").action(
1155                                         "select-file?nextAction=replace"));
1156                         addSeparator();
1157                         addItem(MNU_REMOVE, new PopupItem("menu.remove.document").icon(
1158                                         IMG_DELETE).action("remove-document").confirmation(
1159                                         "message.delete.document"));
1160                 }
1161         }
1162
1163         /**
1164          * Simulation context popup menu.
1165          */
1166         private static class ScontextPopup extends PopupMenu {
1167                 /**
1168                  * Owner object.
1169                  */
1170                 private SimulationContextFacade _owner = null; // RKV: NOPMD: TODO: Refine the usage of this field or remove it.
1171
1172                 /**
1173                  * Default constructor.
1174                  */
1175                 private ScontextPopup() {
1176                         super();
1177                         addItem(MNU_RENAME, new PopupItem(MNU_NAME_RENAME)
1178                                         .action("edit-context?action=renameContext"));
1179                         addItem(MNU_EDIT, new PopupItem(MNU_NAME_EDIT)
1180                                         .action("edit-context?action=editContext"));
1181                         addSeparator();
1182                         addItem(MNU_REMOVE, new PopupItem(MNU_NAME_REMOVE).icon(IMG_DELETE)
1183                                         .action("remove-context").confirmation(
1184                                                         "message.delete.context"));
1185                 }
1186
1187                 /**
1188                  * {@inheritDoc}
1189                  * 
1190                  * @see org.splat.wapp.ContextualMenu#isEnabled(java.lang.String)
1191                  */
1192                 @Override
1193                 public boolean isEnabled(final String name) {
1194                         Item item = Item.valueOf(name);
1195                         boolean res = true;
1196
1197                         if (item == Item.rename) {
1198                                 res = false;
1199                         } else if (item == Item.edit) {
1200                                 // if (!owner.isEditable())
1201                                 res = false;
1202                         }
1203                         return res;
1204                 }
1205
1206                 /**
1207                  * {@inheritDoc}
1208                  * 
1209                  * @see org.splat.wapp.ContextualMenu#setContext(java.lang.String, java.lang.Object)
1210                  */
1211                 @Override
1212                 public void setContext(final String name, final Object context) {
1213                         if (context instanceof SimulationContextFacade) {
1214                                 _owner = (SimulationContextFacade) context; // Just for optimizing
1215                         } else {
1216                                 super.setContext(name, context);
1217                         }
1218                 }
1219         }
1220
1221         // Resources relative to knowledge
1222         /**
1223          * Knowledge element popup menu.
1224          */
1225         private static class FeedbexPopup extends PopupMenu {
1226
1227                 /**
1228                  * Popup menu owner object.
1229                  */
1230                 protected transient KnowledgeElement _owner = null;
1231
1232                 /**
1233                  * Default constructor.
1234                  */
1235                 private FeedbexPopup() {
1236                         super();
1237                         addItem(MNU_RENAME, new PopupItem(MNU_NAME_RENAME)
1238                                         .action("edit-knowledge?action=renameKnowledge"));
1239                         addItem(MNU_EDIT, new PopupItem(MNU_NAME_EDIT)
1240                                         .action("edit-knowledge?action=editKnowledge"));
1241                         addSeparator();
1242                         addItem(MNU_REMOVE, new PopupItem(MNU_NAME_REMOVE).icon(IMG_DELETE)
1243                                         .action("remove-knowledge").confirmation(
1244                                                         "message.delete.knowledge"));
1245                 }
1246
1247                 /**
1248                  * {@inheritDoc}
1249                  * 
1250                  * @see org.splat.wapp.ContextualMenu#isEnabled(java.lang.String)
1251                  */
1252                 @Override
1253                 public boolean isEnabled(final String name) {
1254                         boolean res = true;
1255                         return res;
1256                 }
1257
1258                 /**
1259                  * {@inheritDoc}
1260                  * 
1261                  * @see org.splat.wapp.ContextualMenu#setContext(java.lang.String, java.lang.Object)
1262                  */
1263                 @Override
1264                 public void setContext(final String name, final Object context) {
1265                         if (context instanceof KnowledgeElement) {
1266                                 _owner = (KnowledgeElement) context; // Just for optimizing
1267                         } else {
1268                                 super.setContext(name, context);
1269                         }
1270                 }
1271         }
1272
1273         /**
1274          * Pop-up menu for comments.
1275          */
1276         private static class CommentPopup extends PopupMenu {
1277                 /**
1278                  * Default constructor.
1279                  */
1280                 private CommentPopup() {
1281                         super();
1282                         addItem(MNU_EDIT, new PopupItem(MNU_NAME_EDIT).icon("icon.ed.png")
1283                                         .action("editComment(entity_index)"));
1284                         addItem(MNU_REMOVE, new PopupItem(MNU_NAME_REMOVE).icon(IMG_DELETE)
1285                                         .action("removeComment(entity_index)").confirmation(
1286                                                         "message.delete.comment"));
1287                 }
1288
1289                 /**
1290                  * Is enabled.
1291                  * 
1292                  * @param name
1293                  *            the entry name
1294                  * @return true
1295                  */
1296                 @Override
1297                 public boolean isEnabled(final String name) {
1298                         return true;
1299                 }
1300         }
1301
1302         /**
1303          * Pop-up menu for comments.
1304          */
1305         private static class DescritptionPopup extends PopupMenu {
1306                 /**
1307                  * Default constructor.
1308                  */
1309                 private DescritptionPopup() {
1310                         super();
1311                         addItem(MNU_EDIT, new PopupItem(MNU_NAME_EDIT).icon("icon.ed.png")
1312                                         .action("showDescriptionEditor()"));
1313                         addItem(MNU_REMOVE, new PopupItem(MNU_NAME_REMOVE).icon(IMG_DELETE)
1314                                         .action("removeDescription()").confirmation(
1315                                                         "message.delete.description"));
1316                 }
1317
1318                 /**
1319                  * Is enable.
1320                  * 
1321                  * @param name
1322                  *            the entry name
1323                  * @return true
1324                  */
1325                 @Override
1326                 public boolean isEnabled(final String name) {
1327                         return true;
1328                 }
1329         }
1330
1331         // ==============================================================================================================================
1332         // Construction
1333         // ==============================================================================================================================
1334
1335         // ==============================================================================================================================
1336         // Public member functions
1337         // ==============================================================================================================================
1338
1339         /**
1340          * Initialize application menus.
1341          */
1342         public void configure() {
1343                 // Non customizable settings
1344                 _menus.clear();
1345                 SimpleMenu menu = new NewMenu();
1346                 _menus.put(menu.getName(), menu);
1347                 menu = new SearchMenu();
1348                 _menus.put(menu.getName(), menu);
1349                 menu = new DatadminMenu();
1350                 _menus.put(menu.getName(), menu);
1351                 menu = new SysadminMenu();
1352                 _menus.put(menu.getName(), menu);
1353                 menu = new PropertiesMenu();
1354                 _menus.put(menu.getName(), menu);
1355
1356                 _popups = new HashMap<String, PopupMenu>();
1357                 _popups.put("steditablemarkpublic", new EditableMarkedStudyPopup(false,
1358                                 false));
1359                 _popups.put("steditableunmarkpublic", new EditableMarkedStudyPopup(
1360                                 false, true));
1361                 _popups.put("steditablemarkprivate", new EditableMarkedStudyPopup(true,
1362                                 false));
1363                 _popups.put("steditableunmarkprivate", new EditableMarkedStudyPopup(
1364                                 true, true));
1365                 _popups.put("steditable", new EditableStudyPopup());
1366                 _popups.put("streviewable", new ReviewableStudyPopup());
1367                 _popups.put("stapprovable", new ApprovableStudyPopup());
1368
1369                 _popups.put("steditablemarkpublicScenarioSelected",
1370                                 new EditableMarkedStudyPopup(false, false).setScenarioSlected(true));
1371                 _popups.put("steditableScenarioSelected", new EditableStudyPopup().setScenarioSlected(true));
1372                 _popups.put("streviewableScenarioSelected", new ReviewableStudyPopup().setScenarioSlected(true));
1373                 _popups.put("stapprovableScenarioSelected", new ApprovableStudyPopup().setScenarioSlected(true));
1374
1375                 _popups.put("editable", new EditableDocumentPopup());
1376                 _popups.put("notresult", new NotResultDocumentPopupAuthor());
1377                 _popups.put("reviewable", new ReviewableDocumentPopupAuthor());
1378                 _popups.put("approvable", new ApprovableDocumentPopupAuthor());
1379                 _popups.put("notresultNonAuthor", new NotResultDocumentPopupNonAuthor());
1380                 _popups.put("reviewableNonAuthor", new ReviewableDocumentPopupNonAuthor());
1381                 _popups.put("approvableNonAuthor", new ApprovableDocumentPopupNonAuthor());
1382                 _popups.put("approved", new ApprovedPopup());
1383                 _popups.put("extern", new ExternPopup());
1384                 _popups.put("scontext", new ScontextPopup());
1385                 _popups.put("feedbex", new FeedbexPopup());
1386                 _popups.put("comment", new CommentPopup());
1387                 _popups.put("description", new DescritptionPopup());
1388
1389                 // Default customizable mandatory settings
1390                 Map<String, Object> fprop = new HashMap<String, Object>();
1391                 fprop.put("visibility", "PRIVATE");
1392                 fprop.put("matchamong", ALL);
1393                 fprop.put("matcontext", ALL);
1394                 fprop.put("state", "APPROVED");
1395                 fprop.put("author", "0");
1396                 fprop.put("reference", "");
1397                 fprop.put("title", "");
1398                 fprop.put("context", new ArrayList<SimulationContext>());
1399
1400                 Map<String, Object> gprop = new HashMap<String, Object>();
1401                 gprop.put("visibility", "PUBLIC");
1402                 gprop.put("matchamong", ALL);
1403                 gprop.put("matcontext", ALL);
1404                 gprop.put("type", "2"); // TODO: Get the index from the type name
1405                 gprop.put("author", "0");
1406                 gprop.put("reference", "");
1407                 gprop.put("title", "");
1408                 gprop.put("context", new ArrayList<SimulationContext>());
1409
1410                 _filter = new HashMap<String, Map<String, Object>>();
1411                 _filter.put("study", fprop);
1412                 _filter.put("knowledge", gprop);
1413
1414                 // Settings based on the customization
1415                 configureToolbars();
1416         }
1417
1418         /**
1419          * Configure toolbars for steps.
1420          */
1421         private void configureToolbars() {
1422                 _bars = new HashMap<Integer, ToolBar>(); // May be empty if no module installed
1423
1424                 List<ProjectSettingsService.Step> steps = getProjectSettings()
1425                                 .getAllSteps();
1426                 for (Iterator<ProjectSettingsService.Step> i = steps.iterator(); i
1427                                 .hasNext();) {
1428                         ProjectSettingsService.Step step = i.next();
1429                         List<String> formats = getProjectSettings().getDefaultFormats(step);
1430                         if (formats.isEmpty()) {
1431                                 continue;
1432                         }
1433
1434                         ToolBar bar = new ToolBar(24); // Height of the module-bar
1435                         Set<String> module = new HashSet<String>(); // For not duplicating modules
1436                         for (String format : formats) {
1437                                 String command = getApplicationProperty("executable." + format);
1438                                 if (command == null) {
1439                                         continue; // Module not installed
1440                                 }
1441                                 if (module.contains(command)) {
1442                                         continue;
1443                                 }
1444                                 module.add(command);
1445                                 String[] parsed = command.split("/");
1446                                 String[] name = parsed[parsed.length - 1].split("\\x2E");
1447                                 DocumentType dtype = getProjectSettings()
1448                                                 .getDefaultDocumentType(step, format);
1449                                 String docname = "";
1450                                 if (dtype != null) {
1451                                         docname = dtype.getName();
1452                                 }
1453                                 if (tempfile.get(docname) == null) { // No available template
1454                                         String tool = parsed[parsed.length - 1];
1455                                         String icon = name[0];
1456                                         if ("index".equals(icon)) {
1457                                                 tool = parsed[parsed.length - 2];
1458                                                 icon = "tool." + tool.toLowerCase() + ".png";
1459                                         } else {
1460                                                 icon = "tool." + icon.toLowerCase() + ".png";
1461                                         }
1462                                         File image = new File(ApplicationSettings
1463                                                         .getApplicationSkinPath()
1464                                                         + icon);
1465                                         if (!image.exists()) {
1466                                                 icon = "tool.any.png";
1467                                         }
1468                                         bar.addTool(tool, icon, command);
1469                                 } else {
1470                                         docname = "/jsp/newDocument.jsp?type=" + docname;
1471                                         String icon = "tool." + name[0].toLowerCase() + ".png";
1472                                         File image = new File(ApplicationSettings
1473                                                         .getApplicationSkinPath()
1474                                                         + icon);
1475                                         if (!image.exists()) {
1476                                                 icon = "tool.any.png";
1477                                         }
1478                                         bar.addTool(name[0], icon, command, docname);
1479                                 }
1480                         }
1481                         if (!bar.isEmpty()) {
1482                                 _bars.put(step.getNumber(), bar);
1483                         }
1484                 }
1485         }
1486
1487         public static String getApplicationProperty(final String name) {
1488                 return _WAPPROPS.getProperty(name); // May be null
1489         }
1490
1491         public static String getApplicationRootPath() {
1492                 // The property is supposed including the Web application name
1493                 return wapproot;
1494         }
1495
1496         public String getApplicationURL() {
1497                 StringBuffer url = new StringBuffer("http://").append(_wappserver)
1498                                 .append("/").append(wappname);
1499                 return url.toString();
1500         }
1501
1502         public Map<String, Object> getFilter(final String name) {
1503                 return _filter.get(name);
1504         }
1505
1506         public ToolBar getModuleBar(final Step step) {
1507                 return _bars.get(step.getNumber());
1508         }
1509
1510         static public Properties getNamingProperties() {
1511                 return _JNDPROPS;
1512         }
1513
1514         // ==============================================================================================================================
1515         // Public services
1516         // ==============================================================================================================================
1517
1518         public static String getApplicationPluginPath() {
1519                 return getApplicationRootPath() + "plugin/";
1520         }
1521
1522         public static String getApplicationResourcePath() {
1523                 return getApplicationRootPath() + "WEB-INF/classes/";
1524         }
1525
1526         public static String getApplicationSkinPath() {
1527                 return getApplicationRootPath() + "skin/";
1528         }
1529
1530         public static Converter getConverter(final DocumentType type,
1531                         final String format) {
1532                 return convertmap.get(format + type.getName()); // May be null;
1533         }
1534
1535         /**
1536          * Get default document type for the given format on the given study step.
1537          * 
1538          * @param step
1539          *            the study step
1540          * @param format
1541          *            the file format
1542          * @return default document type or null if not defined in the configuration
1543          */
1544         public DocumentType getDefaultDocumentType(final Step step,
1545                         final String format) {
1546                 return getProjectSettings().getDefaultDocumentType(step.getStep(),
1547                                 format); // May be null
1548         }
1549
1550         public String getDownloadURL(final User user) {
1551                 StringBuffer url = new StringBuffer("http://").append(_wappserver)
1552                                 .append("/download/").append(user.getUsername()).append("/");
1553                 return url.toString(); // The download Tomcat context is supposed being defined
1554         }
1555
1556         public Locale getCurrentLocale() {
1557                 return _locale;
1558         }
1559
1560         public SimpleMenu getMenu(final String name) {
1561                 return _menus.get(name);
1562         }
1563
1564         public PopupMenu getPopupMenu(final String name) {
1565                 return _popups.get(name);
1566         }
1567
1568         public String getRepositoryURL() {
1569                 StringBuffer url = new StringBuffer("http://").append(_wappserver)
1570                                 .append("/repository/");
1571                 return url.toString(); // The repository Tomcat context is supposed being defined
1572         }
1573
1574         public static Locale[] getSupportedLocales() {
1575                 String[] code = _WAPPROPS.getProperty("locale.supported").split(",");
1576                 Locale[] result = new Locale[code.length];
1577                 for (int i = 0; i < code.length; i++) {
1578                         result[i] = new Locale(code[i]);
1579                 }
1580                 return result;
1581         }
1582
1583         public static String[] getViewersMapping() {
1584                 return viewermap;
1585         }
1586
1587         public static String getWebSiteURL() {
1588                 return getApplicationProperty("wapp.website");
1589         }
1590
1591         public static String getHelpURL() {
1592                 return getApplicationProperty("wapp.onlinehelp");
1593         }
1594
1595         // ==============================================================================================================================
1596         // Private services
1597         // ==============================================================================================================================
1598
1599         /**
1600          * Load application custom configuration from the given XML file (see conf/my.xml).
1601          * 
1602          * @param config
1603          *            the XML configuration file
1604          */
1605         private static void loadCustomization(final File config) {
1606                 try {
1607                         DocumentBuilderFactory dfactory = javax.xml.parsers.DocumentBuilderFactory
1608                                         .newInstance();
1609                         DocumentBuilder dBuilder = dfactory.newDocumentBuilder();
1610
1611                         org.w3c.dom.Document conf = dBuilder.parse(config.getPath());
1612                         HashMap<String, Node> children = XDOM.getNamedChildNodes(conf
1613                                         .getDocumentElement());
1614
1615                         // Modules tag
1616                         loadModules(children);
1617
1618                         // Converters tag
1619                         loadConverters(children);
1620
1621                         // Templates tag
1622                         loadTemplates(children);
1623                 } catch (Exception error) {
1624                         LOG.info("Error in customization", error);
1625                 }
1626         }
1627
1628         /**
1629          * Load modules from XML configuration.
1630          * 
1631          * @param children
1632          *            XML nodes
1633          */
1634         private static void loadModules(final Map<String, Node> children) {
1635                 Node child = children.get("modules");
1636                 NodeList nlist = child.getChildNodes();
1637                 for (int i = 0; i < nlist.getLength(); i++) {
1638                         child = nlist.item(i);
1639                         if (!child.getNodeName().equals("mapping")) {
1640                                 continue;
1641                         }
1642
1643                         NamedNodeMap natr = child.getAttributes();
1644                         String dext = natr.getNamedItem("extension").getNodeValue();
1645                         String exec = natr.getNamedItem("executable").getNodeValue();
1646                         _WAPPROPS.put("executable." + dext, exec);
1647                 }
1648                 // Viewer mappings tag
1649                 child = children.get("viewers");
1650                 viewermap = child.getAttributes().getNamedItem("extension")
1651                                 .getNodeValue().split(",");
1652         }
1653
1654         /**
1655          * Load converters from XML configuration.
1656          * 
1657          * @param children
1658          *            XML nodes
1659          */
1660         private static void loadConverters(final Map<String, Node> children) {
1661                 Node child = children.get("converters");
1662                 NodeList nlist = child.getChildNodes();
1663                 for (int i = 0; i < nlist.getLength(); i++) {
1664                         child = nlist.item(i);
1665
1666                         if (child.getNodeName().equals("geometry")) {
1667                                 NamedNodeMap natr = child.getAttributes();
1668                                 String from = natr.getNamedItem("from").getNodeValue();
1669                                 String to = natr.getNamedItem("to").getNodeValue();
1670                                 String exec = natr.getNamedItem("executable").getNodeValue();
1671                                 convertmap.put(from + "geometry", new Converter("geometry",
1672                                                 from, to, exec));
1673                         }
1674                 }
1675         }
1676
1677         /**
1678          * Load templates from XML configuration.
1679          * 
1680          * @param children
1681          *            XML nodes
1682          */
1683         private static void loadTemplates(final Map<String, Node> children) {
1684                 Node child = children.get("templates");
1685                 NodeList nlist = child.getChildNodes();
1686                 for (int i = 0; i < nlist.getLength(); i++) {
1687                         child = nlist.item(i);
1688                         if (!child.getNodeName().equals("document")) {
1689                                 continue;
1690                         }
1691
1692                         NamedNodeMap natr = child.getAttributes();
1693                         String type = natr.getNamedItem("type").getNodeValue();
1694                         String file = natr.getNamedItem("file").getNodeValue();
1695                         tempfile.put(type, file);
1696                 }
1697         }
1698
1699         /**
1700          * Get the documentTypeService.
1701          * 
1702          * @return the documentTypeService
1703          */
1704         public DocumentTypeService getDocumentTypeService() {
1705                 return _documentTypeService;
1706         }
1707
1708         /**
1709          * Set the documentTypeService.
1710          * 
1711          * @param documentTypeService
1712          *            the documentTypeService to set
1713          */
1714         public void setDocumentTypeService(
1715                         final DocumentTypeService documentTypeService) {
1716                 _documentTypeService = documentTypeService;
1717         }
1718
1719         /**
1720          * Get the locale.
1721          * 
1722          * @return the locale
1723          */
1724         public Locale getLocale() {
1725                 return _locale;
1726         }
1727
1728         /**
1729          * Set the locale.
1730          * 
1731          * @param locale
1732          *            the locale to set
1733          */
1734         public void setLocale(final Locale locale) {
1735                 _locale = locale;
1736         }
1737
1738 }