Salome HOME
app.root property is removed.
[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.HashMap;
6 import java.util.HashSet;
7 import java.util.Iterator;
8 import java.util.LinkedHashMap;
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 import java.util.Vector;
15
16 import javax.servlet.ServletContext;
17 import javax.xml.parsers.DocumentBuilder;
18 import javax.xml.parsers.DocumentBuilderFactory;
19 import org.w3c.dom.Node;
20 import org.w3c.dom.NodeList;
21 import org.w3c.dom.NamedNodeMap;
22
23 import org.apache.log4j.Logger;
24 import org.splat.dal.bo.kernel.User;
25 import org.splat.manox.XDOM;
26 import org.splat.dal.bo.som.Document;
27 import org.splat.som.DocumentRights;
28 import org.splat.dal.bo.som.DocumentType;
29 import org.splat.dal.bo.som.KnowledgeElement;
30 import org.splat.dal.bo.som.ProgressState;
31 import org.splat.service.DocumentTypeService;
32 import org.splat.service.technical.ProjectSettingsService;
33 import org.splat.simer.Converter;
34 import org.splat.dal.bo.som.SimulationContext;
35 import org.splat.som.Step;
36 import org.splat.som.StudyRights;
37 import org.splat.wapp.MenuItem;
38 import org.splat.wapp.PopupMenu;
39 import org.splat.wapp.PopupItem;
40 import org.splat.wapp.SimpleMenu;
41 import org.splat.wapp.ToolBar;
42 import org.springframework.web.context.ServletContextAware;
43
44 public class ApplicationSettings implements ServletContextAware {
45
46         /**
47          * Application settings logger.
48          */
49         protected final static Logger logger = Logger
50                         .getLogger(ApplicationSettings.class);
51
52         /**
53          * Injected servlet context to get path to resources.
54          */
55         private ServletContext _servletContext; 
56         
57         private String wappserver;
58         private String wappname;
59         private Properties wapprops; // General properties from the application properties files
60         private Locale locale; // Current user locale
61         private Map<String, SimpleMenu> menus = null; // Application menus
62         private Map<Integer, ToolBar> bars = null; // Study module-bars structured by steps
63         private Map<String, PopupMenu> popups = null;
64         private Map<String, Map<String, Object>> filter = null; // Named search filters
65         private Map<String, DocumentType> defdoctype = null; // Default document types structured by step.formats
66         private Map<String, String> tempfile = null; // Available template files
67         private String[] viewermap = null; // List of file extensions mapped to a viewer
68         private Map<String, Converter> convertmap = null; // Available document format converters
69         private Properties jndprops = null; // JNDI context for launching converters
70
71         private static ApplicationSettings my = null; // Singleton instance
72         /**
73          * Injected project settings service.
74          */
75         private ProjectSettingsService _projectSettingsService;
76         /**
77          * Injected document type service.
78          */
79         private DocumentTypeService _documentTypeService;
80
81         /**
82          * Get the projectSettingsService.
83          * 
84          * @return the projectSettingsService
85          */
86         public ProjectSettingsService getProjectSettings() {
87                 return _projectSettingsService;
88         }
89
90         /**
91          * Set the projectSettingsService.
92          * 
93          * @param projectSettingsService
94          *            the projectSettingsService to set
95          */
96         public void setProjectSettings(ProjectSettingsService projectSettingsService) {
97                 _projectSettingsService = projectSettingsService;
98         }
99
100         private static class NewMenu extends SimpleMenu {
101                 // -----------------------------------------------------------------
102                 private NewMenu() {
103                         super("create");
104                         addItem("new-empty", "menu.new.empty", "image.empty.png",
105                                         "select?menu=create&item=new-empty");
106                         addItem("new-copy", new MenuItem("menu.new.copy")
107                                         .icon("image.copy.png"));
108                         addItem("new-instance", new MenuItem("menu.new.instance")
109                                         .icon("image.hold.gif"));
110                         addItem("new-import", new MenuItem("menu.new.import")
111                                         .icon("icon.upload.png"));
112                         this.selects("new-empty");
113                 }
114         }
115
116         private static class SearchMenu extends SimpleMenu {
117                 // -----------------------------------------------------------------
118                 private SearchMenu() {
119                         super("search");
120                         addItem("search-study", "menu.search.study", "image.study.png",
121                                         "select?menu=search&item=search-study");
122                         addItem("search-knowledge", "menu.search.idea", "image.idea.png",
123                                         "select?menu=search&item=search-knowledge");
124                         addItem("search-document", new MenuItem("menu.search.document")
125                                         .icon("icon.any.png"));
126                         this.selects("search-study");
127                 }
128         }
129
130         private static class PropertiesMenu extends SimpleMenu {
131                 // -----------------------------------------------------------------
132                 private PropertiesMenu() {
133                         super("configuration");
134                         addItem("prop-general", "menu.prop.general", "image.hold.gif",
135                                         "select?menu=properties&item=prop-general");
136                         addItem("prop-scenario", "menu.prop.scenario", "image.hold.gif",
137                                         "select?menu=properties&item=prop-scenario");
138                         addItem("prop-timestamp", new MenuItem("menu.prop.timestamp")
139                                         .icon("image.stamp.png"));
140                         addItem("prop-comlog", new MenuItem("menu.prop.comlog")
141                                         .icon("image.hold.gif"));
142                         addItem("prop-version", new MenuItem("menu.prop.version")
143                                         .icon("image.dirclosed.png"));
144                 }
145         }
146
147         private static class DatadminMenu extends SimpleMenu {
148                 // -----------------------------------------------------------------
149                 private DatadminMenu() {
150                         super("datadmin");
151                         addItem("admin-scontext", "menu.admin.context", "image.hold.gif",
152                                         "select?menu=datadmin&item=admin-scontext");
153                         addItem("admin-knowelm", "menu.admin.knowledge", "image.idea.png",
154                                         "select?menu=datadmin&item=admin-knowelm");
155                         addItem("admin-study", new MenuItem("menu.admin.study")
156                                         .icon("image.study.png"));
157                 }
158         }
159
160         private static class SysadminMenu extends SimpleMenu {
161                 // -----------------------------------------------------------------
162                 private SysadminMenu() {
163                         super("sysadmin");
164                         addItem("admin-indexing", "menu.admin.indexing", "image.index.png",
165                                         "select?menu=sysadmin&item=admin-indexing");
166                         addItem("admin-importuser", "menu.admin.importuser",
167                                         "image.group.png",
168                                         "select?menu=sysadmin&item=admin-importuser");
169                 }
170         }
171
172         private enum Item {
173                 publish, accept, approve, promote, demote, undo, rename, attach, edit, script, version, replace, export, remove, purge
174         };
175
176         // Resources relative to studies
177         private static class EditableStudyPopup extends PopupMenu {
178                 // ----------------------------------------------------------------
179                 private StudyRights user = null;
180
181                 private EditableStudyPopup() {
182                         addItem("publish", new PopupItem("menu.publish").icon(
183                                         "image.publish.png").action("edit-study?action=publish")
184                                         .confirmation("message.publish.study"));
185                         addItem("promote", new PopupItem("menu.archive"));
186                         addSeparator();
187                         addItem("edit", new PopupItem("menu.properties")
188                                         .icon("icon.ed.png").action("../select?menu=properties"));
189                         addSeparator();
190                         addItem("script", new PopupItem("menu.newscenario")
191                                         .action("add-scenario"));
192                         addItem("version", new PopupItem("menu.version").icon(
193                                         "image.version.png").action("notyetimplemented"));
194                         addSeparator();
195                         addItem("purge", new PopupItem("menu.purge")
196                                         .confirmation("message.purge.study"));
197                         addItem("export", new PopupItem("menu.export")
198                                         .icon("image.export.png")); // For future needs
199                         addItem("remove", new PopupItem("menu.remove.version").icon(
200                                         "icon.delete.png").action("notyetimplemented")
201                                         .confirmation("message.delete.study"));
202                 }
203
204                 public boolean isEnabled(String name) {
205                         if (user == null)
206                                 return false; // Should not happen
207                         Item item = Item.valueOf(name);
208                         if (item == Item.publish)
209                                 return user.canPublish();
210                         if (item == Item.edit)
211                                 return user.canEditProperties();
212                         if (item == Item.script)
213                                 return user.canAddScenario();
214                         if (item == Item.version)
215                                 return user.canVersion();
216                         if (item == Item.remove)
217                                 return user.canRemove();
218                         if (item == Item.purge)
219                                 return user.canPurge();
220                         return false;
221                 }
222
223                 public void setContext(String name, Object context) {
224                         if (context instanceof StudyRights) {
225                                 user = (StudyRights) context; // Just for optimizing
226                                 boolean history = user.getOperand().isVersioned();
227                                 PopupItem item = this.item("remove");
228                                 if (history)
229                                         item.rename("menu.remove.version");
230                                 else
231                                         item.rename("menu.remove.study");
232                         }
233                 }
234         }
235
236         // Resources relative to documents
237         private static class EditableDocumentPopup extends PopupMenu { // Popup of In-Work documents
238         // ----------------------------------------------------------------
239                 private DocumentRights user = null;
240
241                 private EditableDocumentPopup() {
242                         addItem("accept", new PopupItem("menu.accept").icon(
243                                         "image.accept.png").action("setDocument?action=accept")
244                                         .confirmation("message.accept.document"));
245                         addItem("promote", new PopupItem("menu.promote").icon(
246                                         "image.publish.png").action("setDocument?action=promote")
247                                         .confirmation("message.promote.document"));
248                         addSeparator();
249                         addItem("rename", new PopupItem("menu.rename")
250                                         .action("edit-document?action=renameDocument"));
251                         addItem("attach", new PopupItem("menu.attach").icon(
252                                         "image.attach.png").action("select-file?nextAction=attach"));
253                         addSeparator();
254                         addItem("version", new PopupItem("menu.version").icon(
255                                         "image.version.png").action(
256                                         "select-file?nextAction=version"));
257                         addItem("replace", new PopupItem("menu.replace").icon(
258                                         "image.replace.png").action(
259                                         "select-file?nextAction=replace"));
260                         addSeparator();
261                         addItem("purge", new PopupItem("menu.purge").action(
262                                         "notyetimplemented").confirmation("message.purge.document"));
263                         addItem("remove", new PopupItem("menu.remove.version").icon(
264                                         "icon.delete.png").action("remove-document").confirmation(
265                                         "message.delete.document"));
266                 }
267
268                 public boolean isEnabled(String name) {
269                         if (user == null)
270                                 return false; // Should not happen
271                         Item item = Item.valueOf(name);
272                         if (item == Item.accept)
273                                 return user.canAccept();
274                         if (item == Item.promote)
275                                 return user.canPromote();
276                         if (item == Item.rename)
277                                 return user.canRename();
278                         if (item == Item.attach)
279                                 return user.canAttach();
280                         if (item == Item.version)
281                                 return user.canVersion();
282                         if (item == Item.replace)
283                                 return user.canReplace();
284                         if (item == Item.purge)
285                                 return user.canPurge();
286                         if (item == Item.remove)
287                                 return user.canRemove();
288                         return false;
289                 }
290
291                 public void setContext(String name, Object context) {
292                         if (context instanceof DocumentRights) {
293                                 user = (DocumentRights) context; // Just for optimizing
294                                 Document downer = user.getOperand();
295                                 PopupItem item = this.item("remove");
296                                 if (downer.isVersioned())
297                                         item.rename("menu.remove.version");
298                                 else
299                                         item.rename("menu.remove.document");
300                         }
301                 }
302         }
303
304         private static class ReviewableDocumentPopup extends PopupMenu { // Popup of In-Draft documents
305         // ----------------------------------------------------------------
306                 private DocumentRights user = null;
307
308                 private ReviewableDocumentPopup() {
309                         addItem("demote", new PopupItem("menu.demote").icon(
310                                         "image.demote.png").action("setDocument?action=demote")
311                                         .confirmation("message.demote.document"));
312                         addItem("promote", new PopupItem("menu.review").icon(
313                                         "image.review.png").action("setDocument?action=review")
314                                         .confirmation("message.review.document"));
315                         addSeparator();
316                         addItem("attach", new PopupItem("menu.attach").icon(
317                                         "image.attach.png").action("select-file?nextAction=attach"));
318                         addSeparator();
319                         addItem("version", new PopupItem("menu.version").icon(
320                                         "image.version.png").action(
321                                         "select-file?nextAction=version"));
322                         addSeparator();
323                         addItem("purge", new PopupItem("menu.purge").action(
324                                         "notyetimplemented").confirmation("message.purge.document"));
325                 }
326
327                 public boolean isEnabled(String name) {
328                         if (user == null)
329                                 return false; // Should not happen
330                         Item item = Item.valueOf(name);
331                         if (item == Item.demote)
332                                 return user.canDemote();
333                         if (item == Item.promote)
334                                 return user.canReview();
335                         if (item == Item.attach)
336                                 return user.canAttach();
337                         if (item == Item.version)
338                                 return user.canVersion();
339                         if (item == Item.purge)
340                                 return user.canPurge();
341                         return false;
342                 }
343
344                 public void setContext(String name, Object context) {
345                         if (context instanceof DocumentRights) {
346                                 user = (DocumentRights) context; // Just for optimizing
347                         }
348                 }
349         }
350
351         private static class NotResultDocumentPopup extends PopupMenu {
352                 // ----------------------------------------------------------------
353                 private DocumentRights user = null;
354
355                 private NotResultDocumentPopup() {
356                         addItem("demote", new PopupItem("menu.demote").icon(
357                                         "image.demote.png").action("setDocument?action=demote")
358                                         .confirmation("message.demote.document"));
359                         addSeparator();
360                         addItem("attach", new PopupItem("menu.attach").icon(
361                                         "image.attach.png").action("select-file?nextAction=attach"));
362                         addSeparator();
363                         addItem("version", new PopupItem("menu.version").icon(
364                                         "image.version.png").action(
365                                         "select-file?nextAction=version"));
366                         addSeparator();
367                         addItem("purge", new PopupItem("menu.purge").action(
368                                         "notyetimplemented").confirmation("message.purge.document"));
369                         addItem("remove", new PopupItem("menu.remove.version").icon(
370                                         "icon.delete.png").action("remove-document").confirmation(
371                                         "message.delete.document"));
372                 }
373         }
374
375         private static class ApprovableDocumentPopup extends PopupMenu { // Popup of In-Check documents
376         // ----------------------------------------------------------------
377                 private DocumentRights user = null;
378
379                 private ApprovableDocumentPopup() {
380                         addItem("undo", new PopupItem("menu.demote").icon(
381                                         "image.invalidate.png").action(
382                                         "setDocument?action=invalidate").confirmation(
383                                         "message.demote.document"));
384                         addItem("demote", new PopupItem("menu.disapprove").icon(
385                                         "image.demote.png").action("setDocument?action=disapprove")
386                                         .confirmation("message.disapprove.document"));
387                         addItem("approve", new PopupItem("menu.approve").icon(
388                                         "icon.APPROVED.png").action("setDocument?action=approve")
389                                         .confirmation("message.approve.document"));
390                 }
391
392                 public boolean isEnabled(String name) {
393                         if (user == null)
394                                 return false; // Should not happen
395                         Item item = Item.valueOf(name);
396                         if (item == Item.undo)
397                                 return user.canInvalidate();
398                         if (item == Item.demote)
399                                 return user.canDemote();
400                         if (item == Item.approve)
401                                 return user.canApprove();
402                         return false;
403                 }
404
405                 public void setContext(String name, Object context) {
406                         if (context instanceof DocumentRights) {
407                                 user = (DocumentRights) context; // Just for optimizing
408                         }
409                 }
410         }
411
412         private static class ApprovedPopup extends PopupMenu { // Popup of Approved documents
413         // ----------------------------------------------------------------
414                 private ApprovedPopup() {
415                         addItem("attach", new PopupItem("menu.attach").icon(
416                                         "image.attach.png").action("select-file?nextAction=attach"));
417                         addSeparator();
418                         addItem("version", new PopupItem("menu.version").icon(
419                                         "image.version.png").action(
420                                         "select-file?nextAction=version"));
421                 }
422         }
423
424         private static class ExternPopup extends PopupMenu { // Popup of Extern documents
425         // ----------------------------------------------------------------
426                 private DocumentRights user = null;
427
428                 private ExternPopup() {
429                         addItem("rename", new PopupItem("menu.rename")
430                                         .action("edit-document?action=renameDocument"));
431                         addItem("replace", new PopupItem("menu.replace").icon(
432                                         "image.replace.png").action(
433                                         "select-file?nextAction=replace"));
434                         addSeparator();
435                         addItem("remove", new PopupItem("menu.remove.document").icon(
436                                         "icon.delete.png").action("remove-document").confirmation(
437                                         "message.delete.document"));
438                 }
439
440                 public boolean isEnabled(String name) {
441                         if (user == null)
442                                 return false; // Should not happen
443                         Item item = Item.valueOf(name);
444                         if (item == Item.rename)
445                                 return user.canRename();
446                         if (item == Item.replace)
447                                 return user.canReplace();
448                         if (item == Item.remove)
449                                 return user.canRemove();
450                         return false;
451                 }
452
453                 public void setContext(String name, Object context) {
454                         if (context instanceof DocumentRights) {
455                                 user = (DocumentRights) context; // Just for optimizing
456                         }
457                 }
458         }
459
460         // Resources relative to simulation contexts
461         private static class ScontextPopup extends PopupMenu {
462                 // --------------------------------------------------------
463                 private SimulationContextFacade owner = null;
464
465                 private ScontextPopup() {
466                         addItem("rename", new PopupItem("menu.rename")
467                                         .action("edit-context?action=renameContext"));
468                         addItem("edit", new PopupItem("menu.edit")
469                                         .action("edit-context?action=editContext"));
470                         addSeparator();
471                         addItem("remove", new PopupItem("menu.remove").icon(
472                                         "icon.delete.png").action("remove-context").confirmation(
473                                         "message.delete.context"));
474                 }
475
476                 public boolean isEnabled(String name) {
477                         Item item = Item.valueOf(name);
478
479                         if (item == Item.rename) {
480                                 return false;
481                         } else if (item == Item.edit) {
482                                 // if (!owner.isEditable())
483                                 return false;
484                         }
485                         return true;
486                 }
487
488                 public void setContext(String name, Object context) {
489                         if (context instanceof SimulationContextFacade) {
490                                 owner = (SimulationContextFacade) context; // Just for optimizing
491                         } else {
492                                 super.setContext(name, context);
493                         }
494                 }
495         }
496
497         // Resources relative to knowledge
498         private static class FeedbexPopup extends PopupMenu {
499                 // --------------------------------------------------------
500                 private KnowledgeElement owner = null;
501
502                 private FeedbexPopup() {
503                         addItem("promote", new PopupItem("menu.promote").icon(
504                                         "image.review.png").action("promote-knowledge")
505                                         .confirmation("message.promote.knowledge"));
506                         addItem("demote", new PopupItem("menu.demote").icon(
507                                         "image.invalidate.png").action("demote-knowledge")
508                                         .confirmation("message.demote.knowledge"));
509                         addSeparator();
510                         addItem("rename", new PopupItem("menu.rename")
511                                         .action("edit-knowledge?action=renameKnowledge"));
512                         addItem("edit", new PopupItem("menu.edit")
513                                         .action("edit-knowledge?action=editKnowledge"));
514                         addSeparator();
515                         addItem("remove", new PopupItem("menu.remove").icon(
516                                         "icon.delete.png").action("remove-knowledge").confirmation(
517                                         "message.delete.knowledge"));
518                 }
519
520                 public boolean isEnabled(String name) {
521                         Item item = Item.valueOf(name);
522
523                         if (item == Item.promote) {
524                                 if (owner.getProgressState() != ProgressState.inDRAFT)
525                                         return false;
526                         } else if (item == Item.demote) {
527                                 if (owner.getProgressState() != ProgressState.inCHECK)
528                                         return false;
529                         }
530                         return true;
531                 }
532
533                 public void setContext(String name, Object context) {
534                         if (context instanceof KnowledgeElement)
535                                 owner = (KnowledgeElement) context; // Just for optimizing
536                         else {
537                                 super.setContext(name, context);
538                         }
539                 }
540         }
541
542         // ==============================================================================================================================
543         // Construction
544         // ==============================================================================================================================
545
546         public static ApplicationSettings getMe() {
547                 // ------------------------------------------
548                 if (my == null) {
549                         my = new ApplicationSettings();
550                 }
551                 return my; // The application is supposed being previously created below
552         }
553
554         /**
555          * @param wappurl
556          * @param lang
557          * @return
558          */
559         public ApplicationSettings init(String wappurl, Locale lang)
560                         throws IOException {
561                 ClassLoader cloader = getClass().getClassLoader();
562                 String[] wurl = wappurl.split("/"); // [0]="http:", [1]="", [2]="{server}:{port}", [3]="name"
563
564                 locale = lang;
565                 wappserver = wurl[2];
566                 wappname = wurl[3];
567                 wapprops = new Properties();
568                 jndprops = new Properties();
569                 wapprops.load(cloader.getResourceAsStream(wappname + ".properties"));
570                 jndprops.load(cloader.getResourceAsStream("jndi.properties"));
571
572                 logger.info("Application root set to "
573                                 + wapprops.getProperty("wapp.root"));
574                 if (my == null) {
575                         my = this;
576                 }
577 //RKV           my = this;
578 //RKV           return this;
579                 return my;
580         }
581
582         // ==============================================================================================================================
583         // Public member functions
584         // ==============================================================================================================================
585
586         public void configure(String filename) {
587                 // ---------------------------------------
588                 // Non customizable settings
589                 menus = new HashMap<String, SimpleMenu>();
590                 SimpleMenu menu = new NewMenu();
591                 menus.put(menu.getName(), menu);
592                 menu = new SearchMenu();
593                 menus.put(menu.getName(), menu);
594                 menu = new DatadminMenu();
595                 menus.put(menu.getName(), menu);
596                 menu = new SysadminMenu();
597                 menus.put(menu.getName(), menu);
598                 menu = new PropertiesMenu();
599                 menus.put(menu.getName(), menu);
600
601                 popups = new HashMap<String, PopupMenu>();
602                 popups.put("steditable", new EditableStudyPopup());
603                 popups.put("editable", new EditableDocumentPopup());
604                 popups.put("notresult", new NotResultDocumentPopup());
605                 popups.put("reviewable", new ReviewableDocumentPopup());
606                 popups.put("approvable", new ApprovableDocumentPopup());
607                 popups.put("approved", new ApprovedPopup());
608                 popups.put("extern", new ExternPopup());
609                 popups.put("scontext", new ScontextPopup());
610                 popups.put("feedbex", new FeedbexPopup());
611
612                 // Default customizable mandatory settings
613                 Map<String, Object> fprop = new HashMap<String, Object>();
614                 fprop.put("visibility", "PRIVATE");
615                 fprop.put("matchamong", "all");
616                 fprop.put("matcontext", "all");
617                 fprop.put("state", "APPROVED");
618                 fprop.put("author", "0");
619                 fprop.put("reference", "");
620                 fprop.put("title", "");
621                 fprop.put("context", new Vector<SimulationContext>());
622
623                 Map<String, Object> gprop = new HashMap<String, Object>();
624                 gprop.put("visibility", "PUBLIC");
625                 gprop.put("matchamong", "all");
626                 gprop.put("matcontext", "all");
627                 gprop.put("type", "2"); // TODO: Get the index from the type name
628                 gprop.put("author", "0");
629                 gprop.put("reference", "");
630                 gprop.put("title", "");
631                 gprop.put("context", new Vector<SimulationContext>());
632
633                 defdoctype = new LinkedHashMap<String, DocumentType>();
634                 tempfile = new HashMap<String, String>();
635                 viewermap = new String[0];
636                 convertmap = new HashMap<String, Converter>();
637                 filter = new HashMap<String, Map<String, Object>>();
638                 filter.put("study", fprop);
639                 filter.put("knowledge", gprop);
640
641                 // Customization (must be done after above default settings)
642                 File config = new File(filename);
643                 if (config.exists()) {
644                         loadCustomization(config); // Sets default document types, installed modules and available templates
645                 } else {
646                         logger.info("Could not find the application configuration file \""
647                                         + config.getAbsolutePath() + "\", using default settings");
648                 }
649                 // Settings based on the customization
650                 bars = new HashMap<Integer, ToolBar>(); // May be empty if no module installed
651
652                 List<ProjectSettingsService.Step> steps = getProjectSettings()
653                                 .getAllSteps();
654                 for (Iterator<ProjectSettingsService.Step> i = steps.iterator(); i
655                                 .hasNext();) {
656                         ProjectSettingsService.Step step = i.next();
657                         List<String> formats = getDefaultFormats(step);
658                         if (formats.size() == 0)
659                                 continue;
660
661                         ToolBar bar = new ToolBar(24); // Height of the module-bar
662                         HashSet<String> module = new HashSet<String>(); // For not duplicating modules
663                         for (Iterator<String> j = formats.iterator(); j.hasNext();) {
664                                 String format = j.next();
665                                 String command = getApplicationProperty("executable." + format);
666                                 if (command == null)
667                                         continue; // Module not installed
668                                 if (module.contains(command))
669                                         continue;
670                                 module.add(command);
671                                 String[] parsed = command.split("/");
672                                 String[] name = parsed[parsed.length - 1].split("\\x2E");
673                                 DocumentType dtype = my.defdoctype.get(
674                                                 step.getNumber() + "." + format);
675                                 String docname = "";
676                                 if (dtype != null) {
677                                         docname = dtype.getName();
678                                 }
679                                 if (tempfile.get(docname) == null) { // No available template
680                                         String tool = parsed[parsed.length - 1];
681                                         String icon = name[0];
682                                         if (icon.equals("index")) {
683                                                 tool = parsed[parsed.length - 2];
684                                                 icon = "tool." + tool.toLowerCase() + ".png";
685                                         } else {
686                                                 icon = "tool." + icon.toLowerCase() + ".png";
687                                         }
688                                         File image = new File(ApplicationSettings
689                                                         .getApplicationSkinPath()
690                                                         + icon);
691                                         if (!image.exists())
692                                                 icon = "tool.any.png";
693                                         bar.addTool(tool, icon, command);
694                                 } else {
695                                         docname = "/jsp/newDocument.jsp?type=" + docname;
696                                         String icon = "tool." + name[0].toLowerCase() + ".png";
697                                         File image = new File(ApplicationSettings
698                                                         .getApplicationSkinPath()
699                                                         + icon);
700                                         if (!image.exists())
701                                                 icon = "tool.any.png";
702                                         bar.addTool(name[0], icon, command, docname);
703                                 }
704                         }
705                         if (!bar.isEmpty())
706                                 bars.put(step.getNumber(), bar);
707                 }
708         }
709
710         public String getApplicationProperty(String name) {
711                 // --------------------------------------------------
712                 return wapprops.getProperty(name); // May be null
713         }
714
715         public String getApplicationRootPath() {
716                 //RKV: return getApplicationProperty("wapp.root"); // The property is supposed including the Web application name
717                 return _servletContext.getRealPath("/");
718         }
719
720         public String getApplicationURL() {
721                 // ----------------------------------
722                 StringBuffer url = new StringBuffer("http://").append(my.wappserver)
723                                 .append("/").append(wappname);
724                 return url.toString();
725         }
726
727         public Map<String, Object> getFilter(String name) {
728                 // --------------------------------------------------
729                 return filter.get(name);
730         }
731
732         public ToolBar getModuleBar(Step step) {
733                 // -----------------------------------------
734                 return bars.get(step.getNumber());
735         }
736
737         public Properties getNamingProperties() {
738                 // ----------------------------------------
739                 return jndprops;
740         }
741
742         // ==============================================================================================================================
743         // Public services
744         // ==============================================================================================================================
745
746         public static String getApplicationPluginPath() {
747                 // ------------------------------------------------
748                 return my.getApplicationRootPath() + "plugin/";
749         }
750
751         public static String getApplicationResourcePath() {
752                 // --------------------------------------------------
753                 return my.getApplicationRootPath() + "WEB-INF/classes/";
754         }
755
756         public static String getApplicationSkinPath() {
757                 // ----------------------------------------------
758                 return my.getApplicationRootPath() + "skin/";
759         }
760
761         public static Converter getConverter(DocumentType type, String format) {
762                 // -----------------------------------------------------------------------
763                 return my.convertmap.get(format + type.getName()); // May be null;
764         }
765
766         public static DocumentType getDefaultDocumentType(Step step, String format) {
767                 // ----------------------------------------------------------------------------
768                 String[] table = format.split("\\x2E");
769                 return my.defdoctype.get(step.getNumber() + "."
770                                 + table[table.length - 1]); // May be null
771         }
772
773         public static String getDownloadURL(User user) {
774                 // --------------------------------------------------
775                 StringBuffer url = new StringBuffer("http://").append(my.wappserver)
776                                 .append("/download/").append(user.getUsername()).append("/");
777                 return url.toString(); // The download Tomcat context is supposed being defined
778         }
779
780         public static Locale getCurrentLocale() {
781                 // ----------------------------------------
782                 return my.locale;
783         }
784
785         public static SimpleMenu getMenu(String name) {
786                 // ----------------------------------------------
787                 return my.menus.get(name);
788         }
789
790         public static PopupMenu getPopupMenu(String name) {
791                 // --------------------------------------------------
792                 return my.popups.get(name);
793         }
794
795         public static String getRepositoryURL() {
796                 // ----------------------------------------
797                 StringBuffer url = new StringBuffer("http://").append(my.wappserver)
798                                 .append("/repository/");
799                 return url.toString(); // The repository Tomcat context is supposed being defined
800         }
801
802         public static Locale[] getSupportedLocales() {
803                 // ---------------------------------------------
804                 String[] code = my.wapprops.getProperty("locale.supported").split(",");
805                 Locale[] result = new Locale[code.length];
806                 for (int i = 0; i < code.length; i++)
807                         result[i] = new Locale(code[i]);
808                 return result;
809         }
810
811         public static String[] getViewersMapping() {
812                 // -------------------------------------------
813                 return my.viewermap;
814         }
815
816         public static String getWebSiteURL() {
817                 // -------------------------------------
818                 return my.getApplicationProperty("wapp.website");
819         }
820
821         public static String getHelpURL() {
822                 // ----------------------------------
823                 return my.getApplicationProperty("wapp.onlinehelp");
824         }
825
826         // ==============================================================================================================================
827         // Private services
828         // ==============================================================================================================================
829
830         private List<String> getDefaultFormats(ProjectSettingsService.Step step) {
831                 // ------------------------------------------------------------------
832                 Set<String> keys = defdoctype.keySet();
833                 int number = step.getNumber();
834                 Vector<String> result = new Vector<String>();
835
836                 for (Iterator<String> i = keys.iterator(); i.hasNext();) {
837                         String[] key = i.next().split("\\x2E");
838                         if (Integer.valueOf(key[0]) != number)
839                                 continue;
840                         if (key[1].equals("pdf"))
841                                 continue; // PDF is not an authoring format
842                         result.add(key[1]); // Formats are unique
843                 }
844                 return result;
845         }
846
847         private void loadCustomization(File config) {
848                 // --------------------------------------------
849                 try {
850                         DocumentBuilderFactory dfactory = javax.xml.parsers.DocumentBuilderFactory
851                                         .newInstance();
852                         DocumentBuilder dBuilder = dfactory.newDocumentBuilder();
853
854                         org.w3c.dom.Document conf = dBuilder.parse(config.getPath());
855                         HashMap<String, Node> children = XDOM.getNamedChildNodes(conf
856                                         .getDocumentElement());
857
858                         // Default document types tag
859                         Node child = children.get("default-doctypes");
860                         NodeList nlist = child.getChildNodes();
861
862                         List<DocumentType> listype = getDocumentTypeService()
863                                         .selectAllTypes();
864                         HashMap<String, DocumentType> maptype = new HashMap<String, DocumentType>();
865                         for (Iterator<DocumentType> i = listype.iterator(); i.hasNext();) {
866                                 DocumentType type = i.next();
867                                 maptype.put(type.getName(), type);
868                         }
869                         for (int i = 0; i < nlist.getLength(); i++) {
870                                 child = nlist.item(i);
871                                 if (!child.getNodeName().equals("step"))
872                                         continue;
873
874                                 String nstep = child.getAttributes().getNamedItem("number")
875                                                 .getNodeValue();
876                                 NodeList map = child.getChildNodes();
877                                 for (int j = 0; j < map.getLength(); j++) {
878                                         child = map.item(j);
879                                         if (!child.getNodeName().equals("mapping"))
880                                                 continue;
881                                         NamedNodeMap natr = child.getAttributes();
882                                         String dext = natr.getNamedItem("extension").getNodeValue();
883                                         String type = natr.getNamedItem("type").getNodeValue();
884                                         defdoctype.put(nstep + "." + dext, maptype.get(type));
885                                 }
886                         }
887                         // Modules tag
888                         child = children.get("modules");
889                         nlist = child.getChildNodes();
890                         for (int i = 0; i < nlist.getLength(); i++) {
891                                 child = nlist.item(i);
892                                 if (!child.getNodeName().equals("mapping"))
893                                         continue;
894
895                                 NamedNodeMap natr = child.getAttributes();
896                                 String dext = natr.getNamedItem("extension").getNodeValue();
897                                 String exec = natr.getNamedItem("executable").getNodeValue();
898                                 wapprops.put("executable." + dext, exec);
899                         }
900                         // Viewer mappings tag
901                         child = children.get("viewers");
902                         viewermap = child.getAttributes().getNamedItem("extension")
903                                         .getNodeValue().split(",");
904
905                         // Converters tag
906                         child = children.get("converters");
907                         nlist = child.getChildNodes();
908                         for (int i = 0; i < nlist.getLength(); i++) {
909                                 child = nlist.item(i);
910
911                                 if (child.getNodeName().equals("geometry")) {
912                                         NamedNodeMap natr = child.getAttributes();
913                                         String from = natr.getNamedItem("from").getNodeValue();
914                                         String to = natr.getNamedItem("to").getNodeValue();
915                                         String exec = natr.getNamedItem("executable")
916                                                         .getNodeValue();
917                                         convertmap.put(from + "geometry", new Converter("geometry",
918                                                         from, to, exec));
919                                 }
920                         }
921
922                         // Templates tag
923                         child = children.get("templates");
924                         nlist = child.getChildNodes();
925                         for (int i = 0; i < nlist.getLength(); i++) {
926                                 child = nlist.item(i);
927                                 if (!child.getNodeName().equals("document"))
928                                         continue;
929
930                                 NamedNodeMap natr = child.getAttributes();
931                                 String type = natr.getNamedItem("type").getNodeValue();
932                                 String file = natr.getNamedItem("file").getNodeValue();
933                                 tempfile.put(type, file);
934                         }
935                 } catch (Exception error) {
936                         logger.info("Error in customization", error);
937                 }
938         }
939
940         /**
941          * Get the documentTypeService.
942          * 
943          * @return the documentTypeService
944          */
945         public DocumentTypeService getDocumentTypeService() {
946                 return _documentTypeService;
947         }
948
949         /**
950          * Set the documentTypeService.
951          * 
952          * @param documentTypeService
953          *            the documentTypeService to set
954          */
955         public void setDocumentTypeService(DocumentTypeService documentTypeService) {
956                 _documentTypeService = documentTypeService;
957         }
958
959         /** 
960          * {@inheritDoc}
961          * @see org.apache.struts2.util.ServletContextAware#setServletContext(javax.servlet.ServletContext)
962          */
963         @Override
964         public void setServletContext(ServletContext context) {
965                 _servletContext = context;
966         }
967
968 }