]> SALOME platform Git repositories - tools/siman.git/blobdiff - Workspace/Siman/src/org/splat/simer/ApplicationSettings.java
Salome HOME
More business logic has been moved from BO to services. ServiceLocator is created...
[tools/siman.git] / Workspace / Siman / src / org / splat / simer / ApplicationSettings.java
index ebf3e06d37f7c1b69bbe53ba653c5d2fcfab8a08..0707ca507f6d00cf31b3ac49e3a68780bb90195f 100644 (file)
@@ -27,6 +27,7 @@ import org.splat.som.DocumentRights;
 import org.splat.dal.bo.som.DocumentType;
 import org.splat.dal.bo.som.KnowledgeElement;
 import org.splat.dal.bo.som.ProgressState;
+import org.splat.service.DocumentTypeService;
 import org.splat.service.technical.ProjectSettingsService;
 import org.splat.dal.bo.som.SimulationContext;
 import org.splat.som.Step;
@@ -37,710 +38,902 @@ import org.splat.wapp.PopupItem;
 import org.splat.wapp.SimpleMenu;
 import org.splat.wapp.ToolBar;
 
-
 public class ApplicationSettings {
 
-    private  String                            wappserver;
-    private  String                            wappname;
-       private  Properties                        wapprops;                 // General properties from the application properties files
-       private  Locale                            locale;                   // Current user locale
-    private  Map<String,SimpleMenu>            menus      = null;        // Application menus
-    private  Map<Integer,ToolBar>              bars       = null;        // Study module-bars structured by steps
-    private  Map<String,PopupMenu>             popups     = null;
-    private  Map<String,Map<String,Object>>    filter     = null;        // Named search filters
-       private  Map<String,DocumentType>          defdoctype = null;        // Default document types structured by step.formats
-    private  Map<String,String>                tempfile   = null;        // Available template files
-    private  String[]                          viewermap  = null;        // List of file extensions mapped to a viewer
-    private  Map<String,Converter>             convertmap = null;        // Available document format converters
-    private  Properties                        jndprops   = null;        // JNDI context for launching converters
-
-       private         static ApplicationSettings my         = null;        // Singleton instance
        /**
         * Application settings logger.
         */
-    protected final static Logger              logger     = Logger.getLogger(ApplicationSettings.class);
-
+       protected final static Logger logger = Logger
+                       .getLogger(ApplicationSettings.class);
+
+       private String wappserver;
+       private String wappname;
+       private Properties wapprops; // General properties from the application properties files
+       private Locale locale; // Current user locale
+       private Map<String, SimpleMenu> menus = null; // Application menus
+       private Map<Integer, ToolBar> bars = null; // Study module-bars structured by steps
+       private Map<String, PopupMenu> popups = null;
+       private Map<String, Map<String, Object>> filter = null; // Named search filters
+       private Map<String, DocumentType> defdoctype = null; // Default document types structured by step.formats
+       private Map<String, String> tempfile = null; // Available template files
+       private String[] viewermap = null; // List of file extensions mapped to a viewer
+       private Map<String, Converter> convertmap = null; // Available document format converters
+       private Properties jndprops = null; // JNDI context for launching converters
+
+       private static ApplicationSettings my = null; // Singleton instance
        /**
         * Injected project settings service.
         */
-    private ProjectSettingsService _projectSettingsService;
+       private ProjectSettingsService _projectSettingsService;
+       /**
+        * Injected document type service.
+        */
+       private DocumentTypeService _documentTypeService;
 
        /**
         * Get the projectSettingsService.
+        * 
         * @return the projectSettingsService
         */
        public ProjectSettingsService getProjectSettings() {
                return _projectSettingsService;
        }
+
        /**
         * Set the projectSettingsService.
-        * @param projectSettingsService the projectSettingsService to set
+        * 
+        * @param projectSettingsService
+        *            the projectSettingsService to set
         */
-       public void setProjectSettings(
-                       ProjectSettingsService projectSettingsService) {
+       public void setProjectSettings(ProjectSettingsService projectSettingsService) {
                _projectSettingsService = projectSettingsService;
        }
 
-       private   static class NewMenu                 extends SimpleMenu {
-//  -----------------------------------------------------------------
-      private NewMenu ()
-      {
-        super("create"); 
-        addItem("new-empty", "menu.new.empty", "image.empty.png", "select?menu=create&item=new-empty");
-        addItem("new-copy",     new MenuItem("menu.new.copy").icon("image.copy.png") );
-        addItem("new-instance", new MenuItem("menu.new.instance").icon("image.hold.gif") );
-        addItem("new-import",   new MenuItem("menu.new.import").icon("icon.upload.png") );
-        this.selects("new-empty");
-      }
-       }
-       private   static class SearchMenu              extends SimpleMenu {
-//  -----------------------------------------------------------------
-      private SearchMenu ()
-      {
-        super("search");
-        addItem("search-study",     "menu.search.study", "image.study.png", "select?menu=search&item=search-study");
-        addItem("search-knowledge", "menu.search.idea",  "image.idea.png",  "select?menu=search&item=search-knowledge");
-        addItem("search-document", new MenuItem("menu.search.document").icon("icon.any.png") );
-        this.selects("search-study");
-      }
-       }
-    private   static class PropertiesMenu          extends SimpleMenu {
-//  -----------------------------------------------------------------
-      private PropertiesMenu ()
-      {
-        super("configuration");
-        addItem("prop-general",  "menu.prop.general",  "image.hold.gif", "select?menu=properties&item=prop-general");
-        addItem("prop-scenario", "menu.prop.scenario", "image.hold.gif", "select?menu=properties&item=prop-scenario");
-        addItem("prop-timestamp", new MenuItem("menu.prop.timestamp").icon("image.stamp.png") );
-        addItem("prop-comlog",    new MenuItem("menu.prop.comlog").icon("image.hold.gif") );
-        addItem("prop-version",   new MenuItem("menu.prop.version").icon("image.dirclosed.png") );
-      }
-    }
-       private   static class DatadminMenu            extends SimpleMenu {
-//  -----------------------------------------------------------------
-         private DatadminMenu ()
-         {
-               super("datadmin");
-        addItem("admin-scontext", "menu.admin.context",   "image.hold.gif", "select?menu=datadmin&item=admin-scontext");
-        addItem("admin-knowelm",  "menu.admin.knowledge", "image.idea.png", "select?menu=datadmin&item=admin-knowelm");
-        addItem("admin-study", new MenuItem("menu.admin.study").icon("image.study.png") );
-         }
-       }
-       private   static class SysadminMenu            extends SimpleMenu {
-//  -----------------------------------------------------------------
-      private SysadminMenu ()
-      {
-        super("sysadmin");
-        addItem("admin-indexing",   "menu.admin.indexing",   "image.index.png", "select?menu=sysadmin&item=admin-indexing");
-        addItem("admin-importuser", "menu.admin.importuser", "image.group.png", "select?menu=sysadmin&item=admin-importuser");
-      }
-       }
-       private          enum  Item { publish, accept, approve, promote, demote, undo, rename, attach, edit, script, version, replace, export, remove, purge };
-//  Resources relative to studies
-    private   static class EditableStudyPopup      extends PopupMenu {
-//  ----------------------------------------------------------------
-      private StudyRights  user = null;
-
-      private EditableStudyPopup ()
-      {
-        addItem("publish", new PopupItem("menu.publish").icon("image.publish.png").action("edit-study?action=publish").confirmation("message.publish.study"));
-        addItem("promote", new PopupItem("menu.archive"));
-        addSeparator();
-        addItem("edit",    new PopupItem("menu.properties").icon("icon.ed.png").action("../select?menu=properties"));
-        addSeparator();
-        addItem("script",  new PopupItem("menu.newscenario").action("add-scenario"));
-       addItem("version", new PopupItem("menu.version").icon("image.version.png").action("notyetimplemented"));
-        addSeparator();
-        addItem("purge",   new PopupItem("menu.purge").confirmation("message.purge.study"));
-        addItem("export",  new PopupItem("menu.export").icon("image.export.png"));   // For future needs
-        addItem("remove",  new PopupItem("menu.remove.version").icon("icon.delete.png").action("notyetimplemented").confirmation("message.delete.study"));
-      }
-      public boolean isEnabled (String name)
-      {
-        if (user == null) return false;      // Should not happen
-        Item item =  Item.valueOf(name);
-        if  (item == Item.publish) return user.canPublish();
-        if  (item == Item.edit)    return user.canEditProperties();
-        if  (item == Item.script)  return user.canAddScenario();
-        if  (item == Item.version) return user.canVersion();
-        if  (item == Item.remove)  return user.canRemove();
-        if  (item == Item.purge)   return user.canPurge();
-        return false;
-      }
-      public void setContext (String name, Object context)
-      {
-        if (context instanceof StudyRights) {
-          user = (StudyRights)context;          // Just for optimizing
-          boolean       history = user.getOperand().isVersioned();
-          PopupItem     item    = this.item("remove");
-          if (history) item.rename("menu.remove.version");
-          else         item.rename("menu.remove.study");
-        }
-      }
-    }
-//  Resources relative to documents
-       private   static class EditableDocumentPopup   extends PopupMenu {   // Popup of In-Work documents
-//  ----------------------------------------------------------------
-      private DocumentRights  user = null;
-
-      private EditableDocumentPopup ()
-      {
-        addItem("accept",  new PopupItem("menu.accept").icon("image.accept.png").action("setDocument?action=accept").confirmation("message.accept.document"));
-               addItem("promote", new PopupItem("menu.promote").icon("image.publish.png").action("setDocument?action=promote").confirmation("message.promote.document"));
-        addSeparator();
-        addItem("rename",  new PopupItem("menu.rename").action("edit-document?action=renameDocument"));
-        addItem("attach",  new PopupItem("menu.attach").icon("image.attach.png").action("select-file?nextAction=attach"));
-        addSeparator();
-       addItem("version", new PopupItem("menu.version").icon("image.version.png").action("select-file?nextAction=version"));
-        addItem("replace", new PopupItem("menu.replace").icon("image.replace.png").action("select-file?nextAction=replace"));
-        addSeparator();
-        addItem("purge",   new PopupItem("menu.purge").action("notyetimplemented").confirmation("message.purge.document"));
-        addItem("remove",  new PopupItem("menu.remove.version").icon("icon.delete.png").action("remove-document").confirmation("message.delete.document"));
-      }
-      public boolean isEnabled (String name)
-      {
-        if (user == null) return false;      // Should not happen
-        Item item =  Item.valueOf(name);
-        if  (item == Item.accept)  return user.canAccept();
-        if  (item == Item.promote) return user.canPromote();
-        if  (item == Item.rename)  return user.canRename();
-        if  (item == Item.attach)  return user.canAttach();
-        if  (item == Item.version) return user.canVersion();
-        if  (item == Item.replace) return user.canReplace();
-        if  (item == Item.purge)   return user.canPurge();
-        if  (item == Item.remove)  return user.canRemove();
-        return false;
-      }
-      public void setContext (String name, Object context)
-      {
-        if (context instanceof DocumentRights) {
-          user = (DocumentRights)context;       // Just for optimizing
-          Document downer = user.getOperand();
-          PopupItem  item = this.item("remove");
-          if (downer.isVersioned()) item.rename("menu.remove.version");
-          else                      item.rename("menu.remove.document");
-        }
-      }
-       }
-       private   static class ReviewableDocumentPopup extends PopupMenu {   // Popup of In-Draft documents
-//  ----------------------------------------------------------------
-      private DocumentRights  user = null;
-
-      private ReviewableDocumentPopup ()
-      {
-        addItem("demote",  new PopupItem("menu.demote").icon("image.demote.png").action("setDocument?action=demote").confirmation("message.demote.document"));
-               addItem("promote", new PopupItem("menu.review").icon("image.review.png").action("setDocument?action=review").confirmation("message.review.document"));
-        addSeparator();
-        addItem("attach",  new PopupItem("menu.attach").icon("image.attach.png").action("select-file?nextAction=attach"));
-        addSeparator();
-       addItem("version", new PopupItem("menu.version").icon("image.version.png").action("select-file?nextAction=version"));
-        addSeparator();
-        addItem("purge",   new PopupItem("menu.purge").action("notyetimplemented").confirmation("message.purge.document"));
-      }
-      public boolean isEnabled (String name)
-      {
-        if (user == null) return false;      // Should not happen
-        Item item =  Item.valueOf(name);
-        if  (item == Item.demote)  return user.canDemote();
-        if  (item == Item.promote) return user.canReview();
-        if  (item == Item.attach)  return user.canAttach();
-        if  (item == Item.version) return user.canVersion();
-        if  (item == Item.purge)   return user.canPurge();
-        return false;
-      }
-      public void setContext (String name, Object context)
-      {
-        if (context instanceof DocumentRights) {
-          user = (DocumentRights)context;       // Just for optimizing
-        }
-      }
-       }
-       private   static class NotResultDocumentPopup  extends PopupMenu {
-//  ----------------------------------------------------------------
-      private DocumentRights  user = null;
-
-      private NotResultDocumentPopup ()
-      {
-        addItem("demote",  new PopupItem("menu.demote").icon("image.demote.png").action("setDocument?action=demote").confirmation("message.demote.document"));
-        addSeparator();
-        addItem("attach",  new PopupItem("menu.attach").icon("image.attach.png").action("select-file?nextAction=attach"));
-        addSeparator();
-       addItem("version", new PopupItem("menu.version").icon("image.version.png").action("select-file?nextAction=version"));
-        addSeparator();
-        addItem("purge",   new PopupItem("menu.purge").action("notyetimplemented").confirmation("message.purge.document"));
-        addItem("remove",  new PopupItem("menu.remove.version").icon("icon.delete.png").action("remove-document").confirmation("message.delete.document"));
-      }
-       }
-    private   static class ApprovableDocumentPopup extends PopupMenu {   // Popup of In-Check documents
-//  ----------------------------------------------------------------
-      private DocumentRights  user = null;
-
-      private ApprovableDocumentPopup ()
-      {
-        addItem("undo",    new PopupItem("menu.demote").icon("image.invalidate.png").action("setDocument?action=invalidate").confirmation("message.demote.document"));
-        addItem("demote",  new PopupItem("menu.disapprove").icon("image.demote.png").action("setDocument?action=disapprove").confirmation("message.disapprove.document"));
-        addItem("approve", new PopupItem("menu.approve").icon("icon.APPROVED.png").action("setDocument?action=approve").confirmation("message.approve.document"));
-      }
-      public boolean isEnabled (String name)
-      {
-        if (user == null) return false;      // Should not happen
-        Item item =  Item.valueOf(name);
-        if  (item == Item.undo)    return user.canInvalidate();
-        if  (item == Item.demote)  return user.canDemote(); 
-        if  (item == Item.approve) return user.canApprove();
-        return false;
-      }
-      public void setContext (String name, Object context)
-      {
-        if (context instanceof DocumentRights) {
-          user = (DocumentRights)context;       // Just for optimizing
-        }
-      }
-    }
-    private   static class ApprovedPopup           extends PopupMenu {   // Popup of Approved documents
-//  ----------------------------------------------------------------
-      private ApprovedPopup ()
-      {
-        addItem("attach",  new PopupItem("menu.attach").icon("image.attach.png").action("select-file?nextAction=attach"));
-        addSeparator();
-        addItem("version", new PopupItem("menu.version").icon("image.version.png").action("select-file?nextAction=version"));
-      }
-    }
-    private   static class ExternPopup             extends PopupMenu {   // Popup of Extern documents
-//  ----------------------------------------------------------------
-      private DocumentRights  user = null;
-
-      private ExternPopup ()
-      {
-        addItem("rename",  new PopupItem("menu.rename").action("edit-document?action=renameDocument"));
-        addItem("replace", new PopupItem("menu.replace").icon("image.replace.png").action("select-file?nextAction=replace"));
-        addSeparator();
-        addItem("remove",  new PopupItem("menu.remove.document").icon("icon.delete.png").action("remove-document").confirmation("message.delete.document"));
-      }
-      public boolean isEnabled (String name)
-      {
-        if (user == null) return false;      // Should not happen
-        Item item =  Item.valueOf(name);
-        if  (item == Item.rename)  return user.canRename();
-        if  (item == Item.replace) return user.canReplace();
-        if  (item == Item.remove)  return user.canRemove();
-        return false;
-      }
-      public void setContext (String name, Object context)
-      {
-        if (context instanceof DocumentRights) {
-          user = (DocumentRights)context;          // Just for optimizing
-        }
-      }
-    }
-//  Resources relative to simulation contexts
-    private   static class ScontextPopup   extends PopupMenu {
-//  --------------------------------------------------------
-      private SimulationContextFacade owner = null;
-
-      private ScontextPopup ()
-      {
-        addItem("rename",  new PopupItem("menu.rename").action("edit-context?action=renameContext"));
-        addItem("edit",    new PopupItem("menu.edit").action("edit-context?action=editContext"));
-        addSeparator();
-        addItem("remove",  new PopupItem("menu.remove").icon("icon.delete.png").action("remove-context").confirmation("message.delete.context"));
-      }
-      public boolean isEnabled (String name)
-      {
-        Item  item = Item.valueOf(name);
-
-        if (item == Item.rename) {
-          return false;
-        } else
-        if (item == Item.edit) {
-//        if (!owner.isEditable())
-            return false;
-        }
-        return true;
-      }
-      public void setContext (String name, Object context)
-      {
-        if (context instanceof SimulationContextFacade) {
-          owner = (SimulationContextFacade)context;   // Just for optimizing
-        }
-        else {
-          super.setContext(name, context);
-        }
-      }
-    }
-//  Resources relative to knowledge
-       private   static class FeedbexPopup    extends PopupMenu {
-//  --------------------------------------------------------
-      private KnowledgeElement  owner = null;
-
-      private FeedbexPopup ()
-      {
-        addItem("promote", new PopupItem("menu.promote").icon("image.review.png").action("promote-knowledge").confirmation("message.promote.knowledge"));
-        addItem("demote",  new PopupItem("menu.demote").icon("image.invalidate.png").action("demote-knowledge").confirmation("message.demote.knowledge"));
-        addSeparator();
-        addItem("rename",  new PopupItem("menu.rename").action("edit-knowledge?action=renameKnowledge"));
-        addItem("edit",    new PopupItem("menu.edit").action("edit-knowledge?action=editKnowledge"));
-        addSeparator();
-        addItem("remove",  new PopupItem("menu.remove").icon("icon.delete.png").action("remove-knowledge").confirmation("message.delete.knowledge"));
-      }
-      public boolean isEnabled (String name)
-      {
-        Item  item = Item.valueOf(name);
-
-        if (item == Item.promote) {
-          if (owner.getProgressState() != ProgressState.inDRAFT) return false;
-        } else
-        if (item == Item.demote) {
-          if (owner.getProgressState() != ProgressState.inCHECK) return false;
-        }
-        return true;
-      }
-      public void setContext (String name, Object context)
-      {
-        if (context instanceof KnowledgeElement) owner = (KnowledgeElement)context;   // Just for optimizing
-        else {
-          super.setContext(name, context);
-        }
-      }
-       }
-
-//  ==============================================================================================================================
-//  Construction
-//  ==============================================================================================================================
-
-    public static ApplicationSettings getMe () {
-//  ------------------------------------------
-      return my;                                  // The application is supposed being previously created below
-    }
+       private static class NewMenu extends SimpleMenu {
+               // -----------------------------------------------------------------
+               private NewMenu() {
+                       super("create");
+                       addItem("new-empty", "menu.new.empty", "image.empty.png",
+                                       "select?menu=create&item=new-empty");
+                       addItem("new-copy", new MenuItem("menu.new.copy")
+                                       .icon("image.copy.png"));
+                       addItem("new-instance", new MenuItem("menu.new.instance")
+                                       .icon("image.hold.gif"));
+                       addItem("new-import", new MenuItem("menu.new.import")
+                                       .icon("icon.upload.png"));
+                       this.selects("new-empty");
+               }
+       }
+
+       private static class SearchMenu extends SimpleMenu {
+               // -----------------------------------------------------------------
+               private SearchMenu() {
+                       super("search");
+                       addItem("search-study", "menu.search.study", "image.study.png",
+                                       "select?menu=search&item=search-study");
+                       addItem("search-knowledge", "menu.search.idea", "image.idea.png",
+                                       "select?menu=search&item=search-knowledge");
+                       addItem("search-document", new MenuItem("menu.search.document")
+                                       .icon("icon.any.png"));
+                       this.selects("search-study");
+               }
+       }
+
+       private static class PropertiesMenu extends SimpleMenu {
+               // -----------------------------------------------------------------
+               private PropertiesMenu() {
+                       super("configuration");
+                       addItem("prop-general", "menu.prop.general", "image.hold.gif",
+                                       "select?menu=properties&item=prop-general");
+                       addItem("prop-scenario", "menu.prop.scenario", "image.hold.gif",
+                                       "select?menu=properties&item=prop-scenario");
+                       addItem("prop-timestamp", new MenuItem("menu.prop.timestamp")
+                                       .icon("image.stamp.png"));
+                       addItem("prop-comlog", new MenuItem("menu.prop.comlog")
+                                       .icon("image.hold.gif"));
+                       addItem("prop-version", new MenuItem("menu.prop.version")
+                                       .icon("image.dirclosed.png"));
+               }
+       }
+
+       private static class DatadminMenu extends SimpleMenu {
+               // -----------------------------------------------------------------
+               private DatadminMenu() {
+                       super("datadmin");
+                       addItem("admin-scontext", "menu.admin.context", "image.hold.gif",
+                                       "select?menu=datadmin&item=admin-scontext");
+                       addItem("admin-knowelm", "menu.admin.knowledge", "image.idea.png",
+                                       "select?menu=datadmin&item=admin-knowelm");
+                       addItem("admin-study", new MenuItem("menu.admin.study")
+                                       .icon("image.study.png"));
+               }
+       }
+
+       private static class SysadminMenu extends SimpleMenu {
+               // -----------------------------------------------------------------
+               private SysadminMenu() {
+                       super("sysadmin");
+                       addItem("admin-indexing", "menu.admin.indexing", "image.index.png",
+                                       "select?menu=sysadmin&item=admin-indexing");
+                       addItem("admin-importuser", "menu.admin.importuser",
+                                       "image.group.png",
+                                       "select?menu=sysadmin&item=admin-importuser");
+               }
+       }
+
+       private enum Item {
+               publish, accept, approve, promote, demote, undo, rename, attach, edit, script, version, replace, export, remove, purge
+       };
+
+       // Resources relative to studies
+       private static class EditableStudyPopup extends PopupMenu {
+               // ----------------------------------------------------------------
+               private StudyRights user = null;
+
+               private EditableStudyPopup() {
+                       addItem("publish", new PopupItem("menu.publish").icon(
+                                       "image.publish.png").action("edit-study?action=publish")
+                                       .confirmation("message.publish.study"));
+                       addItem("promote", new PopupItem("menu.archive"));
+                       addSeparator();
+                       addItem("edit", new PopupItem("menu.properties")
+                                       .icon("icon.ed.png").action("../select?menu=properties"));
+                       addSeparator();
+                       addItem("script", new PopupItem("menu.newscenario")
+                                       .action("add-scenario"));
+                       addItem("version", new PopupItem("menu.version").icon(
+                                       "image.version.png").action("notyetimplemented"));
+                       addSeparator();
+                       addItem("purge", new PopupItem("menu.purge")
+                                       .confirmation("message.purge.study"));
+                       addItem("export", new PopupItem("menu.export")
+                                       .icon("image.export.png")); // For future needs
+                       addItem("remove", new PopupItem("menu.remove.version").icon(
+                                       "icon.delete.png").action("notyetimplemented")
+                                       .confirmation("message.delete.study"));
+               }
+
+               public boolean isEnabled(String name) {
+                       if (user == null)
+                               return false; // Should not happen
+                       Item item = Item.valueOf(name);
+                       if (item == Item.publish)
+                               return user.canPublish();
+                       if (item == Item.edit)
+                               return user.canEditProperties();
+                       if (item == Item.script)
+                               return user.canAddScenario();
+                       if (item == Item.version)
+                               return user.canVersion();
+                       if (item == Item.remove)
+                               return user.canRemove();
+                       if (item == Item.purge)
+                               return user.canPurge();
+                       return false;
+               }
+
+               public void setContext(String name, Object context) {
+                       if (context instanceof StudyRights) {
+                               user = (StudyRights) context; // Just for optimizing
+                               boolean history = user.getOperand().isVersioned();
+                               PopupItem item = this.item("remove");
+                               if (history)
+                                       item.rename("menu.remove.version");
+                               else
+                                       item.rename("menu.remove.study");
+                       }
+               }
+       }
+
+       // Resources relative to documents
+       private static class EditableDocumentPopup extends PopupMenu { // Popup of In-Work documents
+       // ----------------------------------------------------------------
+               private DocumentRights user = null;
+
+               private EditableDocumentPopup() {
+                       addItem("accept", new PopupItem("menu.accept").icon(
+                                       "image.accept.png").action("setDocument?action=accept")
+                                       .confirmation("message.accept.document"));
+                       addItem("promote", new PopupItem("menu.promote").icon(
+                                       "image.publish.png").action("setDocument?action=promote")
+                                       .confirmation("message.promote.document"));
+                       addSeparator();
+                       addItem("rename", new PopupItem("menu.rename")
+                                       .action("edit-document?action=renameDocument"));
+                       addItem("attach", new PopupItem("menu.attach").icon(
+                                       "image.attach.png").action("select-file?nextAction=attach"));
+                       addSeparator();
+                       addItem("version", new PopupItem("menu.version").icon(
+                                       "image.version.png").action(
+                                       "select-file?nextAction=version"));
+                       addItem("replace", new PopupItem("menu.replace").icon(
+                                       "image.replace.png").action(
+                                       "select-file?nextAction=replace"));
+                       addSeparator();
+                       addItem("purge", new PopupItem("menu.purge").action(
+                                       "notyetimplemented").confirmation("message.purge.document"));
+                       addItem("remove", new PopupItem("menu.remove.version").icon(
+                                       "icon.delete.png").action("remove-document").confirmation(
+                                       "message.delete.document"));
+               }
+
+               public boolean isEnabled(String name) {
+                       if (user == null)
+                               return false; // Should not happen
+                       Item item = Item.valueOf(name);
+                       if (item == Item.accept)
+                               return user.canAccept();
+                       if (item == Item.promote)
+                               return user.canPromote();
+                       if (item == Item.rename)
+                               return user.canRename();
+                       if (item == Item.attach)
+                               return user.canAttach();
+                       if (item == Item.version)
+                               return user.canVersion();
+                       if (item == Item.replace)
+                               return user.canReplace();
+                       if (item == Item.purge)
+                               return user.canPurge();
+                       if (item == Item.remove)
+                               return user.canRemove();
+                       return false;
+               }
+
+               public void setContext(String name, Object context) {
+                       if (context instanceof DocumentRights) {
+                               user = (DocumentRights) context; // Just for optimizing
+                               Document downer = user.getOperand();
+                               PopupItem item = this.item("remove");
+                               if (downer.isVersioned())
+                                       item.rename("menu.remove.version");
+                               else
+                                       item.rename("menu.remove.document");
+                       }
+               }
+       }
+
+       private static class ReviewableDocumentPopup extends PopupMenu { // Popup of In-Draft documents
+       // ----------------------------------------------------------------
+               private DocumentRights user = null;
+
+               private ReviewableDocumentPopup() {
+                       addItem("demote", new PopupItem("menu.demote").icon(
+                                       "image.demote.png").action("setDocument?action=demote")
+                                       .confirmation("message.demote.document"));
+                       addItem("promote", new PopupItem("menu.review").icon(
+                                       "image.review.png").action("setDocument?action=review")
+                                       .confirmation("message.review.document"));
+                       addSeparator();
+                       addItem("attach", new PopupItem("menu.attach").icon(
+                                       "image.attach.png").action("select-file?nextAction=attach"));
+                       addSeparator();
+                       addItem("version", new PopupItem("menu.version").icon(
+                                       "image.version.png").action(
+                                       "select-file?nextAction=version"));
+                       addSeparator();
+                       addItem("purge", new PopupItem("menu.purge").action(
+                                       "notyetimplemented").confirmation("message.purge.document"));
+               }
+
+               public boolean isEnabled(String name) {
+                       if (user == null)
+                               return false; // Should not happen
+                       Item item = Item.valueOf(name);
+                       if (item == Item.demote)
+                               return user.canDemote();
+                       if (item == Item.promote)
+                               return user.canReview();
+                       if (item == Item.attach)
+                               return user.canAttach();
+                       if (item == Item.version)
+                               return user.canVersion();
+                       if (item == Item.purge)
+                               return user.canPurge();
+                       return false;
+               }
+
+               public void setContext(String name, Object context) {
+                       if (context instanceof DocumentRights) {
+                               user = (DocumentRights) context; // Just for optimizing
+                       }
+               }
+       }
+
+       private static class NotResultDocumentPopup extends PopupMenu {
+               // ----------------------------------------------------------------
+               private DocumentRights user = null;
+
+               private NotResultDocumentPopup() {
+                       addItem("demote", new PopupItem("menu.demote").icon(
+                                       "image.demote.png").action("setDocument?action=demote")
+                                       .confirmation("message.demote.document"));
+                       addSeparator();
+                       addItem("attach", new PopupItem("menu.attach").icon(
+                                       "image.attach.png").action("select-file?nextAction=attach"));
+                       addSeparator();
+                       addItem("version", new PopupItem("menu.version").icon(
+                                       "image.version.png").action(
+                                       "select-file?nextAction=version"));
+                       addSeparator();
+                       addItem("purge", new PopupItem("menu.purge").action(
+                                       "notyetimplemented").confirmation("message.purge.document"));
+                       addItem("remove", new PopupItem("menu.remove.version").icon(
+                                       "icon.delete.png").action("remove-document").confirmation(
+                                       "message.delete.document"));
+               }
+       }
+
+       private static class ApprovableDocumentPopup extends PopupMenu { // Popup of In-Check documents
+       // ----------------------------------------------------------------
+               private DocumentRights user = null;
+
+               private ApprovableDocumentPopup() {
+                       addItem("undo", new PopupItem("menu.demote").icon(
+                                       "image.invalidate.png").action(
+                                       "setDocument?action=invalidate").confirmation(
+                                       "message.demote.document"));
+                       addItem("demote", new PopupItem("menu.disapprove").icon(
+                                       "image.demote.png").action("setDocument?action=disapprove")
+                                       .confirmation("message.disapprove.document"));
+                       addItem("approve", new PopupItem("menu.approve").icon(
+                                       "icon.APPROVED.png").action("setDocument?action=approve")
+                                       .confirmation("message.approve.document"));
+               }
+
+               public boolean isEnabled(String name) {
+                       if (user == null)
+                               return false; // Should not happen
+                       Item item = Item.valueOf(name);
+                       if (item == Item.undo)
+                               return user.canInvalidate();
+                       if (item == Item.demote)
+                               return user.canDemote();
+                       if (item == Item.approve)
+                               return user.canApprove();
+                       return false;
+               }
+
+               public void setContext(String name, Object context) {
+                       if (context instanceof DocumentRights) {
+                               user = (DocumentRights) context; // Just for optimizing
+                       }
+               }
+       }
+
+       private static class ApprovedPopup extends PopupMenu { // Popup of Approved documents
+       // ----------------------------------------------------------------
+               private ApprovedPopup() {
+                       addItem("attach", new PopupItem("menu.attach").icon(
+                                       "image.attach.png").action("select-file?nextAction=attach"));
+                       addSeparator();
+                       addItem("version", new PopupItem("menu.version").icon(
+                                       "image.version.png").action(
+                                       "select-file?nextAction=version"));
+               }
+       }
+
+       private static class ExternPopup extends PopupMenu { // Popup of Extern documents
+       // ----------------------------------------------------------------
+               private DocumentRights user = null;
+
+               private ExternPopup() {
+                       addItem("rename", new PopupItem("menu.rename")
+                                       .action("edit-document?action=renameDocument"));
+                       addItem("replace", new PopupItem("menu.replace").icon(
+                                       "image.replace.png").action(
+                                       "select-file?nextAction=replace"));
+                       addSeparator();
+                       addItem("remove", new PopupItem("menu.remove.document").icon(
+                                       "icon.delete.png").action("remove-document").confirmation(
+                                       "message.delete.document"));
+               }
+
+               public boolean isEnabled(String name) {
+                       if (user == null)
+                               return false; // Should not happen
+                       Item item = Item.valueOf(name);
+                       if (item == Item.rename)
+                               return user.canRename();
+                       if (item == Item.replace)
+                               return user.canReplace();
+                       if (item == Item.remove)
+                               return user.canRemove();
+                       return false;
+               }
+
+               public void setContext(String name, Object context) {
+                       if (context instanceof DocumentRights) {
+                               user = (DocumentRights) context; // Just for optimizing
+                       }
+               }
+       }
+
+       // Resources relative to simulation contexts
+       private static class ScontextPopup extends PopupMenu {
+               // --------------------------------------------------------
+               private SimulationContextFacade owner = null;
+
+               private ScontextPopup() {
+                       addItem("rename", new PopupItem("menu.rename")
+                                       .action("edit-context?action=renameContext"));
+                       addItem("edit", new PopupItem("menu.edit")
+                                       .action("edit-context?action=editContext"));
+                       addSeparator();
+                       addItem("remove", new PopupItem("menu.remove").icon(
+                                       "icon.delete.png").action("remove-context").confirmation(
+                                       "message.delete.context"));
+               }
+
+               public boolean isEnabled(String name) {
+                       Item item = Item.valueOf(name);
+
+                       if (item == Item.rename) {
+                               return false;
+                       } else if (item == Item.edit) {
+                               // if (!owner.isEditable())
+                               return false;
+                       }
+                       return true;
+               }
+
+               public void setContext(String name, Object context) {
+                       if (context instanceof SimulationContextFacade) {
+                               owner = (SimulationContextFacade) context; // Just for optimizing
+                       } else {
+                               super.setContext(name, context);
+                       }
+               }
+       }
+
+       // Resources relative to knowledge
+       private static class FeedbexPopup extends PopupMenu {
+               // --------------------------------------------------------
+               private KnowledgeElement owner = null;
+
+               private FeedbexPopup() {
+                       addItem("promote", new PopupItem("menu.promote").icon(
+                                       "image.review.png").action("promote-knowledge")
+                                       .confirmation("message.promote.knowledge"));
+                       addItem("demote", new PopupItem("menu.demote").icon(
+                                       "image.invalidate.png").action("demote-knowledge")
+                                       .confirmation("message.demote.knowledge"));
+                       addSeparator();
+                       addItem("rename", new PopupItem("menu.rename")
+                                       .action("edit-knowledge?action=renameKnowledge"));
+                       addItem("edit", new PopupItem("menu.edit")
+                                       .action("edit-knowledge?action=editKnowledge"));
+                       addSeparator();
+                       addItem("remove", new PopupItem("menu.remove").icon(
+                                       "icon.delete.png").action("remove-knowledge").confirmation(
+                                       "message.delete.knowledge"));
+               }
+
+               public boolean isEnabled(String name) {
+                       Item item = Item.valueOf(name);
+
+                       if (item == Item.promote) {
+                               if (owner.getProgressState() != ProgressState.inDRAFT)
+                                       return false;
+                       } else if (item == Item.demote) {
+                               if (owner.getProgressState() != ProgressState.inCHECK)
+                                       return false;
+                       }
+                       return true;
+               }
+
+               public void setContext(String name, Object context) {
+                       if (context instanceof KnowledgeElement)
+                               owner = (KnowledgeElement) context; // Just for optimizing
+                       else {
+                               super.setContext(name, context);
+                       }
+               }
+       }
+
+       // ==============================================================================================================================
+       // Construction
+       // ==============================================================================================================================
+
+       public static ApplicationSettings getMe() {
+               // ------------------------------------------
+               return my; // The application is supposed being previously created below
+       }
+
        /**
         * @param wappurl
         * @param lang
         * @return
         */
-       public ApplicationSettings init(String wappurl, Locale lang) throws IOException {
-      ClassLoader cloader = getClass().getClassLoader();
-      String[]    wurl    = wappurl.split("/");   // [0]="http:", [1]="", [2]="{server}:{port}", [3]="name"
-
-      locale     = lang;
-         wappserver = wurl[2];
-         wappname   = wurl[3];
-      wapprops   = new Properties();
-      jndprops   = new Properties();
-      wapprops.load(cloader.getResourceAsStream(wappname + ".properties"));
-      jndprops.load(cloader.getResourceAsStream("jndi.properties"));
-
-      logger.info("Application root set to " + wapprops.getProperty("wapp.root"));
-      my = this;
-      return this;
-    }
-    
-//  ==============================================================================================================================
-//  Public member functions
-//  ==============================================================================================================================
-
-       public void configure (String filename) {
-//  ---------------------------------------
-//    Non customizable settings
-      menus = new HashMap<String, SimpleMenu>();
-      SimpleMenu menu = new NewMenu();
-      menus.put( menu.getName(), menu );
-                 menu = new SearchMenu();
-      menus.put( menu.getName(), menu );
-                 menu = new DatadminMenu();
-      menus.put( menu.getName(), menu );
-                 menu = new SysadminMenu();
-      menus.put( menu.getName(), menu );
-                 menu = new PropertiesMenu();
-      menus.put( menu.getName(), menu );
-
-      popups = new HashMap<String, PopupMenu>();
-      popups.put("steditable", new EditableStudyPopup());
-      popups.put("editable",   new EditableDocumentPopup());
-      popups.put("notresult",  new NotResultDocumentPopup());
-      popups.put("reviewable", new ReviewableDocumentPopup());
-      popups.put("approvable", new ApprovableDocumentPopup());
-      popups.put("approved",   new ApprovedPopup());
-      popups.put("extern",     new ExternPopup());
-      popups.put("scontext",   new ScontextPopup());
-      popups.put("feedbex",    new FeedbexPopup());
-
-//    Default customizable mandatory settings
-      Map<String, Object> fprop = new HashMap<String, Object>();
-      fprop.put("visibility", "PRIVATE");
-      fprop.put("matchamong", "all");
-      fprop.put("matcontext", "all");
-      fprop.put("state",     "END");
-      fprop.put("author",    "0");
-      fprop.put("reference", "");
-      fprop.put("title",     "");
-      fprop.put("context", new Vector<SimulationContext>());
-             
-      Map<String, Object> gprop = new HashMap<String, Object>();
-      gprop.put("visibility", "PUBLIC");
-      gprop.put("matchamong", "all");
-      gprop.put("matcontext", "all");
-      gprop.put("type",      "2");                        //TODO: Get the index from the type name
-      gprop.put("author",    "0");
-      gprop.put("reference", "");
-      gprop.put("title",     "");
-      gprop.put("context", new Vector<SimulationContext>());
-
-      defdoctype = new LinkedHashMap<String, DocumentType>();
-      tempfile   = new HashMap<String, String>();
-      viewermap  = new String[0];
-      convertmap = new HashMap<String, Converter>();
-      filter     = new HashMap<String, Map<String, Object>>();
-      filter.put("study", fprop);
-      filter.put("knowledge", gprop);
-
-//       Customization (must be done after above default settings)
-      File config = new File(filename);
-      if  (config.exists()) {
-        loadCustomization(config);   // Sets default document types, installed modules and available templates
-      } else {
-        logger.info("Could not find the application configuration file \"" + config.getAbsolutePath() + "\", using default settings");
-      }
-//    Settings based on the customization
-         bars = new HashMap<Integer, ToolBar>();             // May be empty if no module installed
-         
-         List<ProjectSettingsService.Step> steps = getProjectSettings().getAllSteps();
-         for (Iterator<ProjectSettingsService.Step> i=steps.iterator(); i.hasNext();) {
-                 ProjectSettingsService.Step step    = i.next();
-               List<String>         formats = getDefaultFormats(step);
-               if (formats.size() == 0) continue;
-
-        ToolBar         bar    = new ToolBar(24);         // Height of the module-bar
-        HashSet<String> module = new HashSet<String>();   // For not duplicating modules
-               for (Iterator<String> j=formats.iterator(); j.hasNext();) {
-          String   format  = j.next();
-          String   command = getApplicationProperty("executable." + format);
-          if (command == null)          continue;         // Module not installed
-          if (module.contains(command)) continue;
-          module.add(command);
-          String[] parsed  = command.split("/");
-          String[] name    = parsed[parsed.length-1].split("\\x2E");
-          String   docname = my.defdoctype.get(step.getNumber() + "." + format).getName();
-          if (tempfile.get(docname) == null) {            // No available template
-            String tool = parsed[parsed.length-1];
-            String icon = name[0];
-            if    (icon.equals("index")) {
-                   tool = parsed[parsed.length-2];
-                   icon = "tool." + tool.toLowerCase() + ".png";
-            }
-            else {
-                  icon = "tool." + icon.toLowerCase() + ".png";
-            }
-            File   image = new File(ApplicationSettings.getApplicationSkinPath() + icon);
-            if   (!image.exists()) icon = "tool.any.png";
-            bar.addTool(tool, icon, command);
-          } else {
-                     docname = "/jsp/newDocument.jsp?type=" + docname;
-            String   icon    = "tool." + name[0].toLowerCase() + ".png";
-            File    image = new File(ApplicationSettings.getApplicationSkinPath() + icon);
-            if    (!image.exists()) icon = "tool.any.png";
-            bar.addTool(name[0], icon, command, docname);
-          }
-               }
-               if (!bar.isEmpty()) bars.put(step.getNumber(), bar);
-         }
-       }
-
-    public String getApplicationProperty (String name) {
-//  --------------------------------------------------
-      return wapprops.getProperty(name);                // May be null
-    }
-
-    public String getApplicationRootPath () {
-//  ---------------------------------------
-      return getApplicationProperty("wapp.root");       // The property is supposed including the Web application name
-    }
-
-    public String getApplicationURL () {
-//  ----------------------------------
-      StringBuffer url = new StringBuffer("http://").append(my.wappserver).append("/").append(wappname);
-      return       url.toString();
-    }
-
-    public Map<String, Object> getFilter (String name) {
-//  --------------------------------------------------
-      return filter.get(name);
-    }
-
-    public ToolBar getModuleBar (Step step) {
-//  -----------------------------------------
-      return bars.get(step.getNumber());
-    }
-
-    public Properties getNamingProperties () {
-//  ----------------------------------------
-      return jndprops;
-    }
-
-//  ==============================================================================================================================
-//  Public services
-//  ==============================================================================================================================    
-
-    public static String getApplicationPluginPath () {
-//  ------------------------------------------------
-      return my.getApplicationRootPath() + "plugin/";
-    }
-    public static String getApplicationResourcePath () {
-//  --------------------------------------------------
-      return my.getApplicationRootPath() + "WEB-INF/classes/";
-    }
-    public static String getApplicationSkinPath () {
-//  ----------------------------------------------
-      return my.getApplicationRootPath() + "skin/";
-    }
-    public static Converter getConverter (DocumentType type, String format) {
-//  -----------------------------------------------------------------------
-      return my.convertmap.get(format + type.getName());                           // May be null;
-    }
-    public static DocumentType getDefaultDocumentType (Step step, String format) {
-//  ----------------------------------------------------------------------------
-      String[] table = format.split("\\x2E");
-      return my.defdoctype.get(step.getNumber() + "." + table[table.length-1]);    // May be null
-    }
-    public static String getDownloadURL (User user) {
-//  --------------------------------------------------
-      StringBuffer url = new StringBuffer("http://").append(my.wappserver).append("/download/").append(user.getUsername()).append("/");
-      return       url.toString();     // The download Tomcat context is supposed being defined
-    }
-    public static Locale getCurrentLocale () {
-//  ----------------------------------------
-      return my.locale;
-    }
-    public static SimpleMenu getMenu (String name) {
-//  ----------------------------------------------
-      return my.menus.get(name);
-       }
-    public static PopupMenu getPopupMenu (String name) {
-//  --------------------------------------------------
-      return my.popups.get(name);
-    }
-    public static String getRepositoryURL () {
-//  ----------------------------------------
-      StringBuffer url = new StringBuffer("http://").append(my.wappserver).append("/repository/");
-      return       url.toString();     // The repository Tomcat context is supposed being defined
-    }
-    public static Locale[] getSupportedLocales () {
-//  ---------------------------------------------
-      String[] code   = my.wapprops.getProperty("locale.supported").split(",");
-      Locale[] result = new Locale[code.length];
-      for (int i=0; i<code.length; i++) result[i] = new Locale(code[i]);
-      return result;
-    }
-    public static String[] getViewersMapping () {
-//  -------------------------------------------
-      return my.viewermap;
-    }
-    public static String getWebSiteURL () {
-//  -------------------------------------
-      return my.getApplicationProperty("wapp.website");
-    }
-    public static String getHelpURL () {
-//  ----------------------------------
-      return my.getApplicationProperty("wapp.onlinehelp");
-    }
-//  ==============================================================================================================================
-//  Private services
-//  ==============================================================================================================================
-
-    private List<String> getDefaultFormats (ProjectSettingsService.Step step) {
-//  ------------------------------------------------------------------
-      Set<String>    keys   = defdoctype.keySet();
-      int            number = step.getNumber();
-      Vector<String> result = new Vector<String>();
-
-      for (Iterator<String> i=keys.iterator(); i.hasNext();) {
-       String[] key = i.next().split("\\x2E");
-       if (Integer.valueOf(key[0]) != number) continue;
-       if (key[1].equals("pdf"))              continue;           // PDF is not an authoring format
-       result.add(key[1]);                                        // Formats are unique
-      }
-      return result;
-    }
-
-    private void loadCustomization (File config) {
-//  --------------------------------------------
-      try {
-        DocumentBuilderFactory dfactory = javax.xml.parsers.DocumentBuilderFactory.newInstance();
-        DocumentBuilder        dBuilder = dfactory.newDocumentBuilder();
-     
-        org.w3c.dom.Document   conf     = dBuilder.parse(config.getPath());
-        HashMap<String, Node>  children = XDOM.getNamedChildNodes(conf.getDocumentElement());
-
-//      Default document types tag
-        Node     child = children.get("default-doctypes");
-           NodeList nlist = child.getChildNodes();
-           
-        List<DocumentType>           listype = Document.selectAllTypes();
-        HashMap<String,DocumentType> maptype = new HashMap<String,DocumentType>();
-        for (Iterator<DocumentType> i=listype.iterator(); i.hasNext();) {
-         DocumentType  type = i.next();
-         maptype.put(type.getName(), type);
-        }          
-        for (int i=0; i<nlist.getLength(); i++) {
-          child = nlist.item(i);
-          if (!child.getNodeName().equals("step")) continue;
-
-          String   nstep = child.getAttributes().getNamedItem("number").getNodeValue();
-          NodeList map   = child.getChildNodes();
-          for (int j=0; j<map.getLength(); j++) {
-            child = map.item(j);
-            if (!child.getNodeName().equals("mapping")) continue;
-            NamedNodeMap natr = child.getAttributes();
-            String       dext = natr.getNamedItem("extension").getNodeValue();
-            String       type = natr.getNamedItem("type").getNodeValue();
-            defdoctype.put(nstep + "." + dext, maptype.get(type));
-          }
-        }
-//      Modules tag
-        child = children.get("modules");
-        nlist = child.getChildNodes();
-        for (int i=0; i<nlist.getLength(); i++) {
-          child = nlist.item(i);
-          if (!child.getNodeName().equals("mapping")) continue;
-          
-          NamedNodeMap natr = child.getAttributes();
-          String       dext = natr.getNamedItem("extension").getNodeValue();
-          String       exec = natr.getNamedItem("executable").getNodeValue();
-          wapprops.put("executable." + dext,  exec);
-        }
-//      Viewer mappings tag
-        child     = children.get("viewers");
-        viewermap = child.getAttributes().getNamedItem("extension").getNodeValue().split(",");
-
-//      Converters tag
-        child = children.get("converters");
-        nlist = child.getChildNodes();
-        for (int i=0; i<nlist.getLength(); i++) {
-          child = nlist.item(i);
-
-          if (child.getNodeName().equals("geometry")) {
-            NamedNodeMap natr = child.getAttributes();
-            String       from = natr.getNamedItem("from").getNodeValue();
-            String       to   = natr.getNamedItem("to").getNodeValue();
-            String       exec = natr.getNamedItem("executable").getNodeValue();
-            convertmap.put(from + "geometry", new Converter("geometry", from, to, exec));
-          }
-        }
-
-//      Templates tag
-        child = children.get("templates");
-        nlist = child.getChildNodes();
-        for (int i=0; i<nlist.getLength(); i++) {
-          child = nlist.item(i);
-          if (!child.getNodeName().equals("document")) continue;
-
-          NamedNodeMap natr = child.getAttributes();
-          String       type = natr.getNamedItem("type").getNodeValue();
-          String       file = natr.getNamedItem("file").getNodeValue();
-          tempfile.put(type, file);
-        }
-      }
-      catch (Exception error) {
-               logger.info("Error in customization", error);
-      }
-    }
+       public ApplicationSettings init(String wappurl, Locale lang)
+                       throws IOException {
+               ClassLoader cloader = getClass().getClassLoader();
+               String[] wurl = wappurl.split("/"); // [0]="http:", [1]="", [2]="{server}:{port}", [3]="name"
+
+               locale = lang;
+               wappserver = wurl[2];
+               wappname = wurl[3];
+               wapprops = new Properties();
+               jndprops = new Properties();
+               wapprops.load(cloader.getResourceAsStream(wappname + ".properties"));
+               jndprops.load(cloader.getResourceAsStream("jndi.properties"));
+
+               logger.info("Application root set to "
+                               + wapprops.getProperty("wapp.root"));
+               my = this;
+               return this;
+       }
+
+       // ==============================================================================================================================
+       // Public member functions
+       // ==============================================================================================================================
+
+       public void configure(String filename) {
+               // ---------------------------------------
+               // Non customizable settings
+               menus = new HashMap<String, SimpleMenu>();
+               SimpleMenu menu = new NewMenu();
+               menus.put(menu.getName(), menu);
+               menu = new SearchMenu();
+               menus.put(menu.getName(), menu);
+               menu = new DatadminMenu();
+               menus.put(menu.getName(), menu);
+               menu = new SysadminMenu();
+               menus.put(menu.getName(), menu);
+               menu = new PropertiesMenu();
+               menus.put(menu.getName(), menu);
+
+               popups = new HashMap<String, PopupMenu>();
+               popups.put("steditable", new EditableStudyPopup());
+               popups.put("editable", new EditableDocumentPopup());
+               popups.put("notresult", new NotResultDocumentPopup());
+               popups.put("reviewable", new ReviewableDocumentPopup());
+               popups.put("approvable", new ApprovableDocumentPopup());
+               popups.put("approved", new ApprovedPopup());
+               popups.put("extern", new ExternPopup());
+               popups.put("scontext", new ScontextPopup());
+               popups.put("feedbex", new FeedbexPopup());
+
+               // Default customizable mandatory settings
+               Map<String, Object> fprop = new HashMap<String, Object>();
+               fprop.put("visibility", "PRIVATE");
+               fprop.put("matchamong", "all");
+               fprop.put("matcontext", "all");
+               fprop.put("state", "END");
+               fprop.put("author", "0");
+               fprop.put("reference", "");
+               fprop.put("title", "");
+               fprop.put("context", new Vector<SimulationContext>());
+
+               Map<String, Object> gprop = new HashMap<String, Object>();
+               gprop.put("visibility", "PUBLIC");
+               gprop.put("matchamong", "all");
+               gprop.put("matcontext", "all");
+               gprop.put("type", "2"); // TODO: Get the index from the type name
+               gprop.put("author", "0");
+               gprop.put("reference", "");
+               gprop.put("title", "");
+               gprop.put("context", new Vector<SimulationContext>());
+
+               defdoctype = new LinkedHashMap<String, DocumentType>();
+               tempfile = new HashMap<String, String>();
+               viewermap = new String[0];
+               convertmap = new HashMap<String, Converter>();
+               filter = new HashMap<String, Map<String, Object>>();
+               filter.put("study", fprop);
+               filter.put("knowledge", gprop);
+
+               // Customization (must be done after above default settings)
+               File config = new File(filename);
+               if (config.exists()) {
+                       loadCustomization(config); // Sets default document types, installed modules and available templates
+               } else {
+                       logger.info("Could not find the application configuration file \""
+                                       + config.getAbsolutePath() + "\", using default settings");
+               }
+               // Settings based on the customization
+               bars = new HashMap<Integer, ToolBar>(); // May be empty if no module installed
+
+               List<ProjectSettingsService.Step> steps = getProjectSettings()
+                               .getAllSteps();
+               for (Iterator<ProjectSettingsService.Step> i = steps.iterator(); i
+                               .hasNext();) {
+                       ProjectSettingsService.Step step = i.next();
+                       List<String> formats = getDefaultFormats(step);
+                       if (formats.size() == 0)
+                               continue;
+
+                       ToolBar bar = new ToolBar(24); // Height of the module-bar
+                       HashSet<String> module = new HashSet<String>(); // For not duplicating modules
+                       for (Iterator<String> j = formats.iterator(); j.hasNext();) {
+                               String format = j.next();
+                               String command = getApplicationProperty("executable." + format);
+                               if (command == null)
+                                       continue; // Module not installed
+                               if (module.contains(command))
+                                       continue;
+                               module.add(command);
+                               String[] parsed = command.split("/");
+                               String[] name = parsed[parsed.length - 1].split("\\x2E");
+                               String docname = my.defdoctype.get(
+                                               step.getNumber() + "." + format).getName();
+                               if (tempfile.get(docname) == null) { // No available template
+                                       String tool = parsed[parsed.length - 1];
+                                       String icon = name[0];
+                                       if (icon.equals("index")) {
+                                               tool = parsed[parsed.length - 2];
+                                               icon = "tool." + tool.toLowerCase() + ".png";
+                                       } else {
+                                               icon = "tool." + icon.toLowerCase() + ".png";
+                                       }
+                                       File image = new File(ApplicationSettings
+                                                       .getApplicationSkinPath()
+                                                       + icon);
+                                       if (!image.exists())
+                                               icon = "tool.any.png";
+                                       bar.addTool(tool, icon, command);
+                               } else {
+                                       docname = "/jsp/newDocument.jsp?type=" + docname;
+                                       String icon = "tool." + name[0].toLowerCase() + ".png";
+                                       File image = new File(ApplicationSettings
+                                                       .getApplicationSkinPath()
+                                                       + icon);
+                                       if (!image.exists())
+                                               icon = "tool.any.png";
+                                       bar.addTool(name[0], icon, command, docname);
+                               }
+                       }
+                       if (!bar.isEmpty())
+                               bars.put(step.getNumber(), bar);
+               }
+       }
+
+       public String getApplicationProperty(String name) {
+               // --------------------------------------------------
+               return wapprops.getProperty(name); // May be null
+       }
+
+       public String getApplicationRootPath() {
+               // ---------------------------------------
+               return getApplicationProperty("wapp.root"); // The property is supposed including the Web application name
+       }
+
+       public String getApplicationURL() {
+               // ----------------------------------
+               StringBuffer url = new StringBuffer("http://").append(my.wappserver)
+                               .append("/").append(wappname);
+               return url.toString();
+       }
+
+       public Map<String, Object> getFilter(String name) {
+               // --------------------------------------------------
+               return filter.get(name);
+       }
+
+       public ToolBar getModuleBar(Step step) {
+               // -----------------------------------------
+               return bars.get(step.getNumber());
+       }
+
+       public Properties getNamingProperties() {
+               // ----------------------------------------
+               return jndprops;
+       }
+
+       // ==============================================================================================================================
+       // Public services
+       // ==============================================================================================================================
+
+       public static String getApplicationPluginPath() {
+               // ------------------------------------------------
+               return my.getApplicationRootPath() + "plugin/";
+       }
+
+       public static String getApplicationResourcePath() {
+               // --------------------------------------------------
+               return my.getApplicationRootPath() + "WEB-INF/classes/";
+       }
+
+       public static String getApplicationSkinPath() {
+               // ----------------------------------------------
+               return my.getApplicationRootPath() + "skin/";
+       }
+
+       public static Converter getConverter(DocumentType type, String format) {
+               // -----------------------------------------------------------------------
+               return my.convertmap.get(format + type.getName()); // May be null;
+       }
+
+       public static DocumentType getDefaultDocumentType(Step step, String format) {
+               // ----------------------------------------------------------------------------
+               String[] table = format.split("\\x2E");
+               return my.defdoctype.get(step.getNumber() + "."
+                               + table[table.length - 1]); // May be null
+       }
+
+       public static String getDownloadURL(User user) {
+               // --------------------------------------------------
+               StringBuffer url = new StringBuffer("http://").append(my.wappserver)
+                               .append("/download/").append(user.getUsername()).append("/");
+               return url.toString(); // The download Tomcat context is supposed being defined
+       }
+
+       public static Locale getCurrentLocale() {
+               // ----------------------------------------
+               return my.locale;
+       }
+
+       public static SimpleMenu getMenu(String name) {
+               // ----------------------------------------------
+               return my.menus.get(name);
+       }
+
+       public static PopupMenu getPopupMenu(String name) {
+               // --------------------------------------------------
+               return my.popups.get(name);
+       }
+
+       public static String getRepositoryURL() {
+               // ----------------------------------------
+               StringBuffer url = new StringBuffer("http://").append(my.wappserver)
+                               .append("/repository/");
+               return url.toString(); // The repository Tomcat context is supposed being defined
+       }
+
+       public static Locale[] getSupportedLocales() {
+               // ---------------------------------------------
+               String[] code = my.wapprops.getProperty("locale.supported").split(",");
+               Locale[] result = new Locale[code.length];
+               for (int i = 0; i < code.length; i++)
+                       result[i] = new Locale(code[i]);
+               return result;
+       }
+
+       public static String[] getViewersMapping() {
+               // -------------------------------------------
+               return my.viewermap;
+       }
+
+       public static String getWebSiteURL() {
+               // -------------------------------------
+               return my.getApplicationProperty("wapp.website");
+       }
+
+       public static String getHelpURL() {
+               // ----------------------------------
+               return my.getApplicationProperty("wapp.onlinehelp");
+       }
+
+       // ==============================================================================================================================
+       // Private services
+       // ==============================================================================================================================
+
+       private List<String> getDefaultFormats(ProjectSettingsService.Step step) {
+               // ------------------------------------------------------------------
+               Set<String> keys = defdoctype.keySet();
+               int number = step.getNumber();
+               Vector<String> result = new Vector<String>();
+
+               for (Iterator<String> i = keys.iterator(); i.hasNext();) {
+                       String[] key = i.next().split("\\x2E");
+                       if (Integer.valueOf(key[0]) != number)
+                               continue;
+                       if (key[1].equals("pdf"))
+                               continue; // PDF is not an authoring format
+                       result.add(key[1]); // Formats are unique
+               }
+               return result;
+       }
+
+       private void loadCustomization(File config) {
+               // --------------------------------------------
+               try {
+                       DocumentBuilderFactory dfactory = javax.xml.parsers.DocumentBuilderFactory
+                                       .newInstance();
+                       DocumentBuilder dBuilder = dfactory.newDocumentBuilder();
+
+                       org.w3c.dom.Document conf = dBuilder.parse(config.getPath());
+                       HashMap<String, Node> children = XDOM.getNamedChildNodes(conf
+                                       .getDocumentElement());
+
+                       // Default document types tag
+                       Node child = children.get("default-doctypes");
+                       NodeList nlist = child.getChildNodes();
+
+                       List<DocumentType> listype = getDocumentTypeService()
+                                       .selectAllTypes();
+                       HashMap<String, DocumentType> maptype = new HashMap<String, DocumentType>();
+                       for (Iterator<DocumentType> i = listype.iterator(); i.hasNext();) {
+                               DocumentType type = i.next();
+                               maptype.put(type.getName(), type);
+                       }
+                       for (int i = 0; i < nlist.getLength(); i++) {
+                               child = nlist.item(i);
+                               if (!child.getNodeName().equals("step"))
+                                       continue;
+
+                               String nstep = child.getAttributes().getNamedItem("number")
+                                               .getNodeValue();
+                               NodeList map = child.getChildNodes();
+                               for (int j = 0; j < map.getLength(); j++) {
+                                       child = map.item(j);
+                                       if (!child.getNodeName().equals("mapping"))
+                                               continue;
+                                       NamedNodeMap natr = child.getAttributes();
+                                       String dext = natr.getNamedItem("extension").getNodeValue();
+                                       String type = natr.getNamedItem("type").getNodeValue();
+                                       defdoctype.put(nstep + "." + dext, maptype.get(type));
+                               }
+                       }
+                       // Modules tag
+                       child = children.get("modules");
+                       nlist = child.getChildNodes();
+                       for (int i = 0; i < nlist.getLength(); i++) {
+                               child = nlist.item(i);
+                               if (!child.getNodeName().equals("mapping"))
+                                       continue;
+
+                               NamedNodeMap natr = child.getAttributes();
+                               String dext = natr.getNamedItem("extension").getNodeValue();
+                               String exec = natr.getNamedItem("executable").getNodeValue();
+                               wapprops.put("executable." + dext, exec);
+                       }
+                       // Viewer mappings tag
+                       child = children.get("viewers");
+                       viewermap = child.getAttributes().getNamedItem("extension")
+                                       .getNodeValue().split(",");
+
+                       // Converters tag
+                       child = children.get("converters");
+                       nlist = child.getChildNodes();
+                       for (int i = 0; i < nlist.getLength(); i++) {
+                               child = nlist.item(i);
+
+                               if (child.getNodeName().equals("geometry")) {
+                                       NamedNodeMap natr = child.getAttributes();
+                                       String from = natr.getNamedItem("from").getNodeValue();
+                                       String to = natr.getNamedItem("to").getNodeValue();
+                                       String exec = natr.getNamedItem("executable")
+                                                       .getNodeValue();
+                                       convertmap.put(from + "geometry", new Converter("geometry",
+                                                       from, to, exec));
+                               }
+                       }
+
+                       // Templates tag
+                       child = children.get("templates");
+                       nlist = child.getChildNodes();
+                       for (int i = 0; i < nlist.getLength(); i++) {
+                               child = nlist.item(i);
+                               if (!child.getNodeName().equals("document"))
+                                       continue;
+
+                               NamedNodeMap natr = child.getAttributes();
+                               String type = natr.getNamedItem("type").getNodeValue();
+                               String file = natr.getNamedItem("file").getNodeValue();
+                               tempfile.put(type, file);
+                       }
+               } catch (Exception error) {
+                       logger.info("Error in customization", error);
+               }
+       }
+
+       /**
+        * Get the documentTypeService.
+        * 
+        * @return the documentTypeService
+        */
+       public DocumentTypeService getDocumentTypeService() {
+               return _documentTypeService;
+       }
+
+       /**
+        * Set the documentTypeService.
+        * 
+        * @param documentTypeService
+        *            the documentTypeService to set
+        */
+       public void setDocumentTypeService(DocumentTypeService documentTypeService) {
+               _documentTypeService = documentTypeService;
+       }
 }
\ No newline at end of file