Salome HOME
Pop-up menu for knowledge is changed in accordance with specification
[tools/siman.git] / Workspace / Siman / src / org / splat / simer / ApplicationSettings.java
index a6cb60108512594028ea8e951034396ceea93c71..8b092a5fb42534e2f732ca42163365375870379d 100644 (file)
@@ -2,717 +2,1459 @@ package org.splat.simer;
 
 import java.io.File;
 import java.io.IOException;
+import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
-import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Locale;
 import java.util.Map;
 import java.util.Properties;
 import java.util.Set;
-import java.util.Vector;
 
+import javax.servlet.http.HttpServletRequest;
 import javax.xml.parsers.DocumentBuilder;
 import javax.xml.parsers.DocumentBuilderFactory;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-import org.w3c.dom.NamedNodeMap;
 
 import org.apache.log4j.Logger;
-import org.splat.kernel.User;
+import org.splat.dal.bo.kernel.User;
+import org.splat.dal.bo.som.Document;
+import org.splat.dal.bo.som.DocumentType;
+import org.splat.dal.bo.som.KnowledgeElement;
+import org.splat.dal.bo.som.SimulationContext;
+import org.splat.dal.bo.som.Visibility;
 import org.splat.manox.XDOM;
-import org.splat.som.Document;
+import org.splat.service.DocumentTypeService;
+import org.splat.service.technical.ProjectSettingsService;
 import org.splat.som.DocumentRights;
-import org.splat.som.DocumentType;
-import org.splat.som.KnowledgeElement;
-import org.splat.som.ProgressState;
-import org.splat.som.ProjectSettings;
-import org.splat.som.SimulationContext;
 import org.splat.som.Step;
 import org.splat.som.StudyRights;
 import org.splat.wapp.MenuItem;
-import org.splat.wapp.PopupMenu;
 import org.splat.wapp.PopupItem;
+import org.splat.wapp.PopupMenu;
 import org.splat.wapp.SimpleMenu;
 import org.splat.wapp.ToolBar;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
 
-
+/**
+ * SIMAN project settings service. Provides settings according to XML customization.
+ */
 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
-    protected final static Logger              logger     = Logger.getLogger(ApplicationSettings.class);
-
-
-       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
-    }
-    protected ApplicationSettings (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;
-    }
-    
-//  ==============================================================================================================================
-//  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<ProjectSettings.Step> steps = ProjectSettings.getAllSteps();
-         for (Iterator<ProjectSettings.Step> i=steps.iterator(); i.hasNext();) {
-        ProjectSettings.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 (ProjectSettings.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);
-      }
-    }
+       /**
+        * Application settings logger.
+        */
+       protected final static Logger LOG = Logger
+                       .getLogger(ApplicationSettings.class);
+       /**
+        * JNDI context for launching converters.
+        */
+       private transient static final Properties _JNDPROPS;
+       /**
+        * Siman web application name.
+        */
+       private transient static String wappname;
+       /**
+        * General properties from the application properties files.
+        */
+       private transient static final Properties _WAPPROPS = new Properties();
+       /**
+        * Siman web application root path on the server.
+        */
+       private transient static String wapproot;
+       /**
+        * Available template files.
+        */
+       private transient static Map<String, String> tempfile;
+       /**
+        * List of file extensions mapped to a viewer.
+        */
+       private transient static String[] viewermap;
+       /**
+        * Available document format converters.
+        */
+       private transient static Map<String, Converter> convertmap;
+
+       static {
+               synchronized (_WAPPROPS) {
+                       // Do common configuration for all users
+
+                       _JNDPROPS = new Properties();
+                       tempfile = new HashMap<String, String>();
+                       viewermap = new String[0];
+                       convertmap = new HashMap<String, Converter>();
+
+                       ClassLoader cloader = Thread.currentThread()
+                                       .getContextClassLoader();
+                       HttpServletRequest curRequest = ((ServletRequestAttributes) RequestContextHolder
+                                       .currentRequestAttributes()).getRequest();
+                       String appname = curRequest.getContextPath();
+                       if (appname.startsWith("/")) {
+                               wappname = appname.substring(1);
+                       }
+                       // Set local path on the server to the application root.
+                       wapproot = curRequest.getSession().getServletContext().getRealPath(
+                                       "/");
+
+                       try {
+                               _JNDPROPS.load(cloader.getResourceAsStream("jndi.properties"));
+                               _WAPPROPS.load(cloader.getResourceAsStream(wappname
+                                               + ".properties"));
+                       } catch (IOException e) {
+                               LOG.info(
+                                               "Can't load application properties: " + e.getMessage(),
+                                               e);
+                       }
+
+                       // Configure login security
+                       System.setProperty("java.security.auth.login.config", wapproot
+                                       + ApplicationSettings.getApplicationProperty("wapp.login"));
+
+                       // Customization (must be done after above default settings)
+                       File config = new File(wapproot
+                                       + getApplicationProperty("wapp.customization"));
+                       if (config.exists()) {
+                               loadCustomization(config); // Sets default document types, installed modules and available templates
+                       } else {
+                               LOG.info("Could not find the application configuration file \""
+                                               + config.getAbsolutePath()
+                                               + "\", using default settings");
+                       }
+               }
+       }
+
+       /**
+        * All value.
+        */
+       private static final String ALL = "all";
+
+       /**
+        * Hold icon file name.
+        */
+       private static final String IMG_HOLD = "image.hold.gif";
+       /**
+        * Attach icon file name.
+        */
+       private static final String IMG_ATTACH = "image.attach.png";
+       /**
+        * Version icon file name.
+        */
+       private static final String IMG_VERSION = "image.version.png";
+       /**
+        * Delete icon file name.
+        */
+       private static final String IMG_DELETE = "icon.delete.png";
+       /**
+        * Attach menu item name.
+        */
+       private static final String MNU_ATTACH = "attach";
+       /**
+        * Demote menu item name.
+        */
+       private static final String MNU_DEMOTE = "demote";
+       /**
+        * Promote menu item name.
+        */
+       private static final String MNU_PROMOTE = "promote";
+       /**
+        * Publish menu item name.
+        */
+       private static final String MNU_PUBLISH = "publish";
+       /**
+        * Edit menu item name.
+        */
+       private static final String MNU_EDIT = "edit";
+       /**
+        * Script menu item name.
+        */
+       private static final String MNU_SCRIPT = "script";
+       /**
+        * Version menu item name.
+        */
+       private static final String MNU_VERSION = "version";
+       /**
+        * Purge menu item name.
+        */
+       private static final String MNU_PURGE = "purge";
+       /**
+        * Remove menu item name.
+        */
+       private static final String MNU_REMOVE = "remove";
+       /**
+        * Rename menu item name.
+        */
+       private static final String MNU_RENAME = "rename";
+
+       /**
+        * Attach menu item name.
+        */
+       private static final String MNU_NAME_ATTACH = "menu.attach";
+       /**
+        * Demote menu item name.
+        */
+       private static final String MNU_NAME_DEMOTE = "menu.demote";
+       /**
+        * Promote menu item name.
+        */
+       private static final String MNU_NAME_PROMOTE = "menu.promote";
+       /**
+        * Publish menu item name.
+        */
+       private static final String MNU_NAME_PUBLISH = "menu.publish";
+       /**
+        * Protect menu item name.
+        */
+       private static final String MNU_NAME_PROTECT = "menu.protect";
+       /**
+        * Edit menu item name.
+        */
+       private static final String MNU_NAME_EDIT = "menu.edit";
+       /**
+        * Edit menu item name.
+        */
+       private static final String MNU_NAME_REMOVE = "menu.remove";
+       /**
+        * Script menu item name.
+        */
+       private static final String MNU_NAME_SCRIPT = "menu.newscenario";
+       /**
+        * Version menu item name.
+        */
+       private static final String MNU_NAME_VERSION = "menu.version";
+       /**
+        * Purge menu item name.
+        */
+       private static final String MNU_NAME_PURGE = "menu.purge";
+       /**
+        * Remove menu item name.
+        */
+       private static final String MNU_NAME_REMOVE_VERSION = "menu.remove.version";
+       /**
+        * Rename menu item name.
+        */
+       private static final String MNU_NAME_RENAME = "menu.rename";
+       /**
+        * Mark as reference menu item name.
+        */
+       private static final String MNU_MARK_AS_REFERENCE = "markasreference";
+       /**
+        * Mark as reference menu item label key.
+        */
+       private static final String MNU_NAME_MARK_AS_REFERENCE = "menu.markasreference";
+       /**
+        * Remove as reference menu item label key.
+        */
+       private static final String MNU_NAME_REMOVE_AS_REFERENCE = "menu.removeasreference";
+       /**
+        * Not yet implemented action name.
+        */
+       private static final String ACT_NOT_YET_IMPLEMENTED = "notyetimplemented";
+       /**
+        * Attach action name.
+        */
+       private static final String ACT_ATTACH = "select-file?nextAction=attach";
+       /**
+        * Version action name.
+        */
+       private static final String ACT_VERSION = "select-file?nextAction=version";
+       /**
+        * Mark as reference action name.
+        */
+       private static final String ACT_MARK_AS_REFERENCE = "markasref-study";
+       /**
+        * Remove as reference action name.
+        */
+       private static final String ACT_REMOVE_AS_REFERENCE = "removeasref-study";
+
+       /**
+        * Siman application server name.
+        */
+       private transient final String _wappserver;
+       /**
+        * Current user locale.
+        */
+       private transient Locale _locale;
+       /**
+        * Application menus.
+        */
+       private transient final Map<String, SimpleMenu> _menus = new HashMap<String, SimpleMenu>();
+       /**
+        * Study module-bars structured by steps.
+        */
+       private transient Map<Integer, ToolBar> _bars = null;
+       /**
+        * Popup menus.
+        */
+       private transient Map<String, PopupMenu> _popups = null;
+       /**
+        * Named search filters.
+        */
+       private transient Map<String, Map<String, Object>> _filter = null;
+       /**
+        * Injected project settings service.
+        */
+       private ProjectSettingsService _projectSettings;
+       /**
+        * Injected document type service.
+        */
+       private DocumentTypeService _documentTypeService;
+
+       /**
+        * Application settings constructor.
+        */
+       public ApplicationSettings() {
+               HttpServletRequest curRequest = ((ServletRequestAttributes) RequestContextHolder
+                               .currentRequestAttributes()).getRequest();
+               _wappserver = curRequest.getServerName() + ":"
+                               + curRequest.getServerPort();
+
+               LOG.info("Application server is set to " + _wappserver);
+               LOG.info("Application name is set to " + wappname);
+       }
+
+       /**
+        * Get the projectSettingsService.
+        * 
+        * @return the projectSettingsService
+        */
+       public ProjectSettingsService getProjectSettings() {
+               return _projectSettings;
+       }
+
+       /**
+        * Set the projectSettingsService.
+        * 
+        * @param projectSettingsService
+        *            the projectSettingsService to set
+        */
+       public void setProjectSettings(
+                       final ProjectSettingsService projectSettingsService) {
+               _projectSettings = projectSettingsService;
+       }
+
+       /**
+        * New study menu.
+        */
+       private static class NewMenu extends SimpleMenu {
+               /**
+                * New study menu constructor.
+                */
+               private NewMenu() {
+                       super("create");
+                       addItem("new-empty", "menu.new.empty", "image.empty.png",
+                                       "select?menu=create&item=new-empty");
+                       addItem("new-copy", "menu.new.copy", "image.copy.png",
+                                       "select?menu=create&item=new-copy");
+                       /*
+                        * addItem("new-instance", new MenuItem("menu.new.instance") .icon(IMG_HOLD)); addItem("new-import", new
+                        * MenuItem("menu.new.import") .icon("icon.upload.png"));
+                        */
+                       this.selects("new-empty");
+               }
+       }
+
+       /**
+        * Search menu.
+        */
+       private static class SearchMenu extends SimpleMenu {
+               /**
+                * Search menu constructor.
+                */
+               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");
+               }
+       }
+
+       /**
+        * Configuration menu.
+        */
+       private static class PropertiesMenu extends SimpleMenu {
+               /**
+                * Configuration menu constructor.
+                */
+               private PropertiesMenu() {
+                       super("configuration");
+                       addItem("prop-general", "menu.prop.general", IMG_HOLD,
+                                       "select?menu=configuration&item=prop-general");
+                       addItem("prop-scenario", "menu.prop.scenario", IMG_HOLD,
+                                       "select?menu=configuration&item=prop-scenario");
+                       // These menu items will not be implemented in the current version.
+                       /*
+                        * addItem("prop-timestamp", new MenuItem("menu.prop.timestamp") .icon("image.stamp.png")); addItem("prop-comlog", new
+                        * MenuItem("menu.prop.comlog") .icon(IMG_HOLD)); addItem("prop-version", new MenuItem("menu.prop.version")
+                        * .icon("image.dirclosed.png"));
+                        */
+               }
+       }
+
+       /**
+        * Data administrator menu.
+        */
+       private static class DatadminMenu extends SimpleMenu {
+               /**
+                * Data administrator menu constructor.
+                */
+               private DatadminMenu() {
+                       super("datadmin");
+                       addItem("admin-scontext", "menu.admin.context", IMG_HOLD,
+                                       "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"));
+               }
+       }
+
+       /**
+        * System administrator menu.
+        */
+       private static class SysadminMenu extends SimpleMenu {
+               /**
+                * System administrator menu constructor.
+                */
+               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");
+               }
+       }
+
+       /**
+        * Menu items enumeration.
+        */
+       private enum Item {
+               /**
+                * Publish the study.
+                */
+               publish,
+               /**
+                * Accept the document.
+                */
+               accept,
+               /**
+                * Approve the document.
+                */
+               approve,
+               /**
+                * Promote the document.
+                */
+               promote,
+               /**
+                * Demote the docuemnt.
+                */
+               demote,
+               /**
+                * Undo the last operation.
+                */
+               undo,
+               /**
+                * Rename the document.
+                */
+               rename,
+               /**
+                * Attach a file to the document.
+                */
+               attach,
+               /**
+                * Edit the document.
+                */
+               edit,
+               /**
+                * script
+                */
+               script,
+               /**
+                * Version the document.
+                */
+               version,
+               /**
+                * replace
+                */
+               replace,
+               /**
+                * export
+                */
+               export,
+               /**
+                * Remove the document.
+                */
+               remove,
+               /**
+                * purge
+                */
+               purge,
+               /**
+                * Mark the study as reference.
+                */
+               markasreference
+       };
+
+       // Resources relative to studies
+       /**
+        * Study popup menu.
+        */
+       private static class EditableMarkedStudyPopup extends PopupMenu {
+               /**
+                * User rights for the selected study.
+                */
+               private transient StudyRights _user = null;
+
+               /**
+                * Study popup menu constructor.
+                * 
+                * @param isPublic
+                *            public study flag
+                * @param isMarked
+                *            "marked as reference" study flag
+                */
+               private EditableMarkedStudyPopup(final boolean isPublic,
+                               final boolean isMarked) {
+                       super();
+
+                       if (isMarked) {
+                               addItem(MNU_MARK_AS_REFERENCE, new PopupItem(
+                                               MNU_NAME_REMOVE_AS_REFERENCE).action(
+                                               ACT_REMOVE_AS_REFERENCE).confirmation(
+                                               "message.removeasreference.study"));
+                       } else {
+                               addItem(MNU_MARK_AS_REFERENCE, new PopupItem(
+                                               MNU_NAME_MARK_AS_REFERENCE).action(
+                                               ACT_MARK_AS_REFERENCE).confirmation(
+                                               "message.markasreference.study"));
+                       }
+
+                       if (isPublic) {
+                               addItem(MNU_PUBLISH, new PopupItem(MNU_NAME_PROTECT).icon(
+                                               "image.publish.png")
+                                               .action("edit-study?action=protect").confirmation(
+                                                               "message.protect.study"));
+                       } else {
+                               addItem(MNU_PUBLISH, new PopupItem(MNU_NAME_PUBLISH).icon(
+                                               "image.publish.png")
+                                               .action("edit-study?action=publish").confirmation(
+                                                               "message.publish.study"));
+                       }
+
+                       /* addItem(MNU_PROMOTE, new PopupItem("menu.archive")); */
+                       addSeparator();
+                       addItem(MNU_EDIT, new PopupItem("menu.properties").icon(
+                                       "icon.ed.png").action(
+                                       "../select?menu=configuration&item=prop-general"));
+                       addSeparator();
+                       addItem(MNU_SCRIPT, new PopupItem(MNU_NAME_SCRIPT)
+                                       .action("add-scenario"));
+                       /*
+                        * addItem(MNU_VERSION, new PopupItem(MNU_NAME_VERSION).icon( IMG_VERSION).action(ACT_NOT_YET_IMPLEMENTED));
+                        */
+                       addSeparator();
+                       /*
+                        * addItem(MNU_PURGE, new PopupItem(MNU_NAME_PURGE) .confirmation("message.purge.study")); addItem("export", new
+                        * PopupItem("menu.export") .icon("image.export.png")); // For future needs
+                        */addItem(MNU_REMOVE, new PopupItem(MNU_NAME_REMOVE_VERSION).icon(
+                                       IMG_DELETE).action("remove-study").confirmation(
+                                       "message.delete.study"));
+               }
+
+               /**
+                * {@inheritDoc}
+                * 
+                * @see org.splat.wapp.ContextualMenu#isEnabled(java.lang.String)
+                */
+               @Override
+               public boolean isEnabled(final String name) {
+                       boolean res = (_user != null);
+                       if (res) {
+                               Item item = Item.valueOf(name);
+                               switch (item) {
+                                       case publish:
+                                               if (_user.getOperand().getVisibility() == Visibility.PRIVATE) {
+                                                       res = _user.canPublish();
+                                               } else {
+                                                       res = _user.canProtect();
+                                               }
+                                               break;
+                                       case edit:
+                                               res = _user.canEditProperties();
+                                               break;
+                                       case script:
+                                               res = _user.canAddScenario();
+                                               break;
+                                       case version:
+                                               res = _user.canVersion();
+                                               break;
+                                       case remove:
+                                               res = _user.canRemove();
+                                               break;
+                                       case purge:
+                                               res = _user.canPurge();
+                                               break;
+                                       case markasreference:
+                                               if (_user.getOperand().getMarkreference() == 0) {
+                                                       res = _user.canMarkStudyAsReference();
+                                               } else {
+                                                       res = _user.canRemoveStudyAsReference();
+                                               }
+                                               break;
+                                       default:
+                                               res = false;
+                               }
+                       }
+                       return res;
+               }
+
+               @Override
+               public void setContext(final String name, final Object context) {
+                       if (context instanceof StudyRights) {
+                               _user = (StudyRights) context; // Just for optimizing
+                               boolean history = _user.getOperand().isVersioned();
+                               PopupItem item = this.item(MNU_REMOVE);
+                               if (history) {
+                                       item.rename(MNU_NAME_REMOVE_VERSION);
+                               } else {
+                                       item.rename("menu.remove.study");
+                               }
+                       }
+               }
+       }
+
+       // Resources relative to documents
+       /**
+        * Popup of In-Work documents.
+        */
+       private static class EditableDocumentPopup extends PopupMenu {
+               /**
+                * User rights for the selected document.
+                */
+               private transient DocumentRights _user = null;
+
+               /**
+                * Document popup menu constructor.
+                */
+               private EditableDocumentPopup() {
+                       super();
+                       addItem("accept", new PopupItem("menu.accept").icon(
+                                       "image.accept.png").action("setDocument?action=accept")
+                                       .confirmation("message.accept.document"));
+                       addItem(MNU_PROMOTE, new PopupItem(MNU_NAME_PROMOTE).icon(
+                                       "image.publish.png").action("setDocument?action=promote")
+                                       .confirmation("message.promote.document"));
+                       addSeparator();
+                       addItem(MNU_RENAME, new PopupItem(MNU_NAME_RENAME)
+                                       .action("edit-document?action=renameDocument"));
+                       addItem(MNU_ATTACH, new PopupItem(MNU_NAME_ATTACH).icon(IMG_ATTACH)
+                                       .action(ACT_ATTACH));
+                       addSeparator();
+                       addItem(MNU_VERSION, new PopupItem(MNU_NAME_VERSION).icon(
+                                       IMG_VERSION).action(ACT_VERSION));
+                       addItem("replace", new PopupItem("menu.replace").icon(
+                                       "image.replace.png").action(
+                                       "select-file?nextAction=replace"));
+                       addSeparator();
+                       addItem(MNU_PURGE, new PopupItem(MNU_NAME_PURGE).action(
+                                       ACT_NOT_YET_IMPLEMENTED).confirmation(
+                                       "message.purge.document"));
+                       addItem(MNU_REMOVE, new PopupItem(MNU_NAME_REMOVE_VERSION).icon(
+                                       IMG_DELETE).action("remove-document").confirmation(
+                                       "message.delete.document"));
+               }
+
+               @Override
+               public boolean isEnabled(final String name) {
+                       boolean res = (_user != null);
+                       if (res) {
+                               Item item = Item.valueOf(name);
+                               switch (item) {
+                                       case accept:
+                                               res = _user.canAccept();
+                                               break;
+                                       case promote:
+                                               res = _user.canPromote();
+                                               break;
+                                       case rename:
+                                               res = _user.canRename();
+                                               break;
+                                       case attach:
+                                               res = _user.canAttach();
+                                               break;
+                                       case version:
+                                               res = _user.canVersion();
+                                               break;
+                                       case replace:
+                                               res = _user.canReplace();
+                                               break;
+                                       case purge:
+                                               res = _user.canPurge();
+                                               break;
+                                       case remove:
+                                               res = _user.canRemove();
+                                               break;
+                                       default:
+                                               res = false;
+                               }
+                       }
+                       return res;
+               }
+
+               @Override
+               public void setContext(final String name, final Object context) {
+                       if (context instanceof DocumentRights) {
+                               _user = (DocumentRights) context; // Just for optimizing
+                               Document downer = _user.getOperand();
+                               PopupItem item = this.item(MNU_REMOVE);
+                               if (downer.isVersioned()) {
+                                       item.rename(MNU_NAME_REMOVE_VERSION);
+                               } else {
+                                       item.rename("menu.remove.document");
+                               }
+                       }
+               }
+       }
+
+       /**
+        * Popup of In-Draft documents.
+        */
+       private static class ReviewableDocumentPopup extends PopupMenu {
+               /**
+                * User rights for the selected document.
+                */
+               private transient DocumentRights _user = null;
+
+               /**
+                * Document popup menu constructor.
+                */
+               private ReviewableDocumentPopup() {
+                       super();
+                       addItem(MNU_DEMOTE, new PopupItem(MNU_NAME_DEMOTE).icon(
+                                       "image.demote.png").action("setDocument?action=demote")
+                                       .confirmation("message.demote.document"));
+                       addItem(MNU_PROMOTE, new PopupItem("menu.review").icon(
+                                       "image.review.png").action("setDocument?action=review")
+                                       .confirmation("message.review.document"));
+                       addSeparator();
+                       addItem(MNU_ATTACH, new PopupItem(MNU_NAME_ATTACH).icon(IMG_ATTACH)
+                                       .action(ACT_ATTACH));
+                       addSeparator();
+                       addItem(MNU_VERSION, new PopupItem(MNU_NAME_VERSION).icon(
+                                       IMG_VERSION).action(ACT_VERSION));
+                       addSeparator();
+                       addItem(MNU_PURGE, new PopupItem(MNU_NAME_PURGE).action(
+                                       ACT_NOT_YET_IMPLEMENTED).confirmation(
+                                       "message.purge.document"));
+               }
+
+               @Override
+               public boolean isEnabled(final String name) {
+                       boolean res = (_user != null);
+                       if (res) {
+                               Item item = Item.valueOf(name);
+                               switch (item) {
+                                       case demote:
+                                               res = _user.canDemote();
+                                               break;
+                                       case promote:
+                                               res = _user.canReview();
+                                               break;
+                                       case attach:
+                                               res = _user.canAttach();
+                                               break;
+                                       case version:
+                                               res = _user.canVersion();
+                                               break;
+                                       case purge:
+                                               res = _user.canPurge();
+                                               break;
+                                       default:
+                                               res = false;
+                               }
+                       }
+                       return res;
+               }
+
+               @Override
+               public void setContext(final String name, final Object context) {
+                       if (context instanceof DocumentRights) {
+                               _user = (DocumentRights) context; // Just for optimizing
+                       }
+               }
+       }
+
+       private static class NotResultDocumentPopup extends PopupMenu {
+               // private final DocumentRights _user = null;
+
+               private NotResultDocumentPopup() {
+                       super();
+                       addItem(MNU_DEMOTE, new PopupItem(MNU_NAME_DEMOTE).icon(
+                                       "image.demote.png").action("setDocument?action=demote")
+                                       .confirmation("message.demote.document"));
+                       addSeparator();
+                       addItem(MNU_ATTACH, new PopupItem(MNU_NAME_ATTACH).icon(IMG_ATTACH)
+                                       .action(ACT_ATTACH));
+                       addSeparator();
+                       addItem(MNU_VERSION, new PopupItem(MNU_NAME_VERSION).icon(
+                                       IMG_VERSION).action(ACT_VERSION));
+                       addSeparator();
+                       addItem(MNU_PURGE, new PopupItem(MNU_NAME_PURGE).action(
+                                       ACT_NOT_YET_IMPLEMENTED).confirmation(
+                                       "message.purge.document"));
+                       addItem(MNU_REMOVE, new PopupItem(MNU_NAME_REMOVE_VERSION).icon(
+                                       IMG_DELETE).action("remove-document").confirmation(
+                                       "message.delete.document"));
+               }
+       }
+
+       /**
+        * Popup of In-Check documents.
+        */
+       private static class ApprovableDocumentPopup extends PopupMenu {
+               private transient DocumentRights _user = null;
+
+               private ApprovableDocumentPopup() {
+                       super();
+                       addItem("undo", new PopupItem(MNU_NAME_DEMOTE).icon(
+                                       "image.invalidate.png").action(
+                                       "setDocument?action=invalidate").confirmation(
+                                       "message.demote.document"));
+                       addItem(MNU_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"));
+               }
+
+               @Override
+               public boolean isEnabled(final String name) {
+                       boolean res = (_user != null);
+                       if (res) {
+                               Item item = Item.valueOf(name);
+                               switch (item) {
+                                       case undo:
+                                               res = _user.canInvalidate();
+                                               break;
+                                       case demote:
+                                               res = _user.canDemote();
+                                               break;
+                                       case approve:
+                                               res = _user.canApprove();
+                                               break;
+                                       default:
+                                               res = false;
+                               }
+                       }
+                       return res;
+               }
+
+               @Override
+               public void setContext(final String name, final Object context) {
+                       if (context instanceof DocumentRights) {
+                               _user = (DocumentRights) context; // Just for optimizing
+                       }
+               }
+       }
+
+       /**
+        * Popup of Approved documents.
+        */
+       private static class ApprovedPopup extends PopupMenu {
+               private ApprovedPopup() {
+                       super();
+                       addItem(MNU_ATTACH, new PopupItem(MNU_NAME_ATTACH).icon(IMG_ATTACH)
+                                       .action(ACT_ATTACH));
+                       addSeparator();
+                       addItem(MNU_VERSION, new PopupItem(MNU_NAME_VERSION).icon(
+                                       IMG_VERSION).action(ACT_VERSION));
+               }
+       }
+
+       /**
+        * Popup of Extern documents.
+        */
+       private static class ExternPopup extends PopupMenu {
+               private transient DocumentRights _user = null;
+
+               private ExternPopup() {
+                       super();
+                       addItem(MNU_RENAME, new PopupItem(MNU_NAME_RENAME)
+                                       .action("edit-document?action=renameDocument"));
+                       addSeparator();
+                       addItem(MNU_VERSION, new PopupItem(MNU_NAME_VERSION).icon(
+                                       IMG_VERSION).action(ACT_VERSION));
+                       addSeparator();
+                       addItem("replace", new PopupItem("menu.replace").icon(
+                                       "image.replace.png").action(
+                                       "select-file?nextAction=replace"));
+                       addSeparator();
+                       addItem(MNU_REMOVE, new PopupItem("menu.remove.document").icon(
+                                       IMG_DELETE).action("remove-document").confirmation(
+                                       "message.delete.document"));
+               }
+
+               @Override
+               public boolean isEnabled(final String name) {
+                       boolean res = (_user != null);
+                       if (res) {
+                               Item item = Item.valueOf(name);
+                               switch (item) {
+                                       case rename:
+                                               res = _user.canRename();
+                                               break;
+                                       case version:
+                                               res = _user.canVersion();
+                                               break;
+                                       case replace:
+                                               res = _user.canReplace();
+                                               break;
+                                       case remove:
+                                               res = _user.canRemove();
+                                               break;
+                                       default:
+                                               res = false;
+                               }
+                       }
+                       return res;
+               }
+
+               @Override
+               public void setContext(final String name, final 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; // RKV: NOPMD: TODO: Refine the usage of this field or remove it.
+
+               private ScontextPopup() {
+                       super();
+                       addItem(MNU_RENAME, new PopupItem(MNU_NAME_RENAME)
+                                       .action("edit-context?action=renameContext"));
+                       addItem(MNU_EDIT, new PopupItem(MNU_NAME_EDIT)
+                                       .action("edit-context?action=editContext"));
+                       addSeparator();
+                       addItem(MNU_REMOVE, new PopupItem(MNU_NAME_REMOVE).icon(IMG_DELETE)
+                                       .action("remove-context").confirmation(
+                                                       "message.delete.context"));
+               }
+
+               @Override
+               public boolean isEnabled(final String name) {
+                       Item item = Item.valueOf(name);
+                       boolean res = true;
+
+                       if (item == Item.rename) {
+                               res = false;
+                       } else if (item == Item.edit) {
+                               // if (!owner.isEditable())
+                               res = false;
+                       }
+                       return res;
+               }
+
+               @Override
+               public void setContext(final String name, final 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 transient KnowledgeElement _owner = null;
+
+               private FeedbexPopup() {
+                       super();
+                       addItem(MNU_RENAME, new PopupItem(MNU_NAME_RENAME)
+                                       .action("edit-knowledge?action=renameKnowledge"));
+                       addItem(MNU_EDIT, new PopupItem(MNU_NAME_EDIT)
+                                       .action("edit-knowledge?action=editKnowledge"));
+                       addSeparator();
+                       addItem(MNU_REMOVE, new PopupItem(MNU_NAME_REMOVE).icon(IMG_DELETE)
+                                       .action("remove-knowledge").confirmation(
+                                                       "message.delete.knowledge"));
+               }
+
+               @Override
+               public boolean isEnabled(final String name) {
+                       boolean res = true;
+                       return res;
+               }
+
+               @Override
+               public void setContext(final String name, final Object context) {
+                       if (context instanceof KnowledgeElement) {
+                               _owner = (KnowledgeElement) context; // Just for optimizing
+                       } else {
+                               super.setContext(name, context);
+                       }
+               }
+       }
+
+       /**
+        * Pop-up menu for comments.
+        */
+       private static class CommentPopup extends PopupMenu {
+               /**
+                * Default constructor.
+                */
+               private CommentPopup() {
+                       super();
+                       addItem(MNU_EDIT, new PopupItem(MNU_NAME_EDIT).icon("icon.ed.png")
+                                       .action("editComment(entity_index)"));
+                       addItem(MNU_REMOVE, new PopupItem(MNU_NAME_REMOVE).icon(IMG_DELETE)
+                                       .action("removeComment(entity_index)").confirmation(
+                                                       "message.delete.comment"));
+               }
+
+               /**
+                * Is enabled.
+                * 
+                * @param name
+                *            the entry name
+                * @return true
+                */
+               @Override
+               public boolean isEnabled(final String name) {
+                       return true;
+               }
+       }
+
+       /**
+        * Pop-up menu for comments.
+        */
+       private static class DescritptionPopup extends PopupMenu {
+               /**
+                * Default constructor.
+                */
+               private DescritptionPopup() {
+                       super();
+                       addItem(MNU_EDIT, new PopupItem(MNU_NAME_EDIT).icon("icon.ed.png")
+                                       .action("showDescriptionEditor()"));
+                       addItem(MNU_REMOVE, new PopupItem(MNU_NAME_REMOVE).icon(IMG_DELETE)
+                                       .action("removeDescription()").confirmation(
+                                                       "message.delete.description"));
+               }
+
+               /**
+                * Is enable.
+                * 
+                * @param name
+                *            the entry name
+                * @return true
+                */
+               @Override
+               public boolean isEnabled(final String name) {
+                       return true;
+               }
+       }
+
+       // ==============================================================================================================================
+       // Construction
+       // ==============================================================================================================================
+
+       // ==============================================================================================================================
+       // Public member functions
+       // ==============================================================================================================================
+
+       public void configure() {
+               // Non customizable settings
+               _menus.clear();
+               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("steditablemarkpublic", new EditableMarkedStudyPopup(false,
+                               false));
+               _popups.put("steditableunmarkpublic", new EditableMarkedStudyPopup(
+                               false, true));
+               _popups.put("steditablemarkprivate", new EditableMarkedStudyPopup(true,
+                               false));
+               _popups.put("steditableunmarkprivate", new EditableMarkedStudyPopup(
+                               true, true));
+               _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());
+               _popups.put("comment", new CommentPopup());
+               _popups.put("description", new DescritptionPopup());
+
+               // 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", "APPROVED");
+               fprop.put("author", "0");
+               fprop.put("reference", "");
+               fprop.put("title", "");
+               fprop.put("context", new ArrayList<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 ArrayList<SimulationContext>());
+
+               _filter = new HashMap<String, Map<String, Object>>();
+               _filter.put("study", fprop);
+               _filter.put("knowledge", gprop);
+
+               // Settings based on the customization
+               configureToolbars();
+       }
+
+       /**
+        * Configure toolbars for steps.
+        */
+       private void configureToolbars() {
+               _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 = getProjectSettings().getDefaultFormats(step);
+                       if (formats.isEmpty()) {
+                               continue;
+                       }
+
+                       ToolBar bar = new ToolBar(24); // Height of the module-bar
+                       Set<String> module = new HashSet<String>(); // For not duplicating modules
+                       for (String format : formats) {
+                               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");
+                               DocumentType dtype = getProjectSettings()
+                                               .getDefaultDocumentType(step, format);
+                               String docname = "";
+                               if (dtype != null) {
+                                       docname = dtype.getName();
+                               }
+                               if (tempfile.get(docname) == null) { // No available template
+                                       String tool = parsed[parsed.length - 1];
+                                       String icon = name[0];
+                                       if ("index".equals(icon)) {
+                                               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 static String getApplicationProperty(final String name) {
+               return _WAPPROPS.getProperty(name); // May be null
+       }
+
+       public static String getApplicationRootPath() {
+               // The property is supposed including the Web application name
+               return wapproot;
+       }
+
+       public String getApplicationURL() {
+               StringBuffer url = new StringBuffer("http://").append(_wappserver)
+                               .append("/").append(wappname);
+               return url.toString();
+       }
+
+       public Map<String, Object> getFilter(final String name) {
+               return _filter.get(name);
+       }
+
+       public ToolBar getModuleBar(final Step step) {
+               return _bars.get(step.getNumber());
+       }
+
+       static public Properties getNamingProperties() {
+               return _JNDPROPS;
+       }
+
+       // ==============================================================================================================================
+       // Public services
+       // ==============================================================================================================================
+
+       public static String getApplicationPluginPath() {
+               return getApplicationRootPath() + "plugin/";
+       }
+
+       public static String getApplicationResourcePath() {
+               return getApplicationRootPath() + "WEB-INF/classes/";
+       }
+
+       public static String getApplicationSkinPath() {
+               return getApplicationRootPath() + "skin/";
+       }
+
+       public static Converter getConverter(final DocumentType type,
+                       final String format) {
+               return convertmap.get(format + type.getName()); // May be null;
+       }
+
+       /**
+        * Get default document type for the given format on the given study step.
+        * 
+        * @param step
+        *            the study step
+        * @param format
+        *            the file format
+        * @return default document type or null if not defined in the configuration
+        */
+       public DocumentType getDefaultDocumentType(final Step step,
+                       final String format) {
+               return getProjectSettings().getDefaultDocumentType(step.getStep(),
+                               format); // May be null
+       }
+
+       public String getDownloadURL(final User user) {
+               StringBuffer url = new StringBuffer("http://").append(_wappserver)
+                               .append("/download/").append(user.getUsername()).append("/");
+               return url.toString(); // The download Tomcat context is supposed being defined
+       }
+
+       public Locale getCurrentLocale() {
+               return _locale;
+       }
+
+       public SimpleMenu getMenu(final String name) {
+               return _menus.get(name);
+       }
+
+       public PopupMenu getPopupMenu(final String name) {
+               return _popups.get(name);
+       }
+
+       public String getRepositoryURL() {
+               StringBuffer url = new StringBuffer("http://").append(_wappserver)
+                               .append("/repository/");
+               return url.toString(); // The repository Tomcat context is supposed being defined
+       }
+
+       public static Locale[] getSupportedLocales() {
+               String[] code = _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 viewermap;
+       }
+
+       public static String getWebSiteURL() {
+               return getApplicationProperty("wapp.website");
+       }
+
+       public static String getHelpURL() {
+               return getApplicationProperty("wapp.onlinehelp");
+       }
+
+       // ==============================================================================================================================
+       // Private services
+       // ==============================================================================================================================
+
+       /**
+        * Load application custom configuration from the given XML file (see conf/my.xml).
+        * 
+        * @param config
+        *            the XML configuration file
+        */
+       private static void loadCustomization(final 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());
+
+                       // Modules tag
+                       loadModules(children);
+
+                       // Converters tag
+                       loadConverters(children);
+
+                       // Templates tag
+                       loadTemplates(children);
+               } catch (Exception error) {
+                       LOG.info("Error in customization", error);
+               }
+       }
+
+       /**
+        * Load modules from XML configuration.
+        * 
+        * @param children
+        *            XML nodes
+        */
+       private static void loadModules(final Map<String, Node> children) {
+               Node child = children.get("modules");
+               NodeList 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(",");
+       }
+
+       /**
+        * Load converters from XML configuration.
+        * 
+        * @param children
+        *            XML nodes
+        */
+       private static void loadConverters(final Map<String, Node> children) {
+               Node child = children.get("converters");
+               NodeList 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));
+                       }
+               }
+       }
+
+       /**
+        * Load templates from XML configuration.
+        * 
+        * @param children
+        *            XML nodes
+        */
+       private static void loadTemplates(final Map<String, Node> children) {
+               Node child = children.get("templates");
+               NodeList 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);
+               }
+       }
+
+       /**
+        * Get the documentTypeService.
+        * 
+        * @return the documentTypeService
+        */
+       public DocumentTypeService getDocumentTypeService() {
+               return _documentTypeService;
+       }
+
+       /**
+        * Set the documentTypeService.
+        * 
+        * @param documentTypeService
+        *            the documentTypeService to set
+        */
+       public void setDocumentTypeService(
+                       final DocumentTypeService documentTypeService) {
+               _documentTypeService = documentTypeService;
+       }
+
+       /**
+        * Get the locale.
+        * 
+        * @return the locale
+        */
+       public Locale getLocale() {
+               return _locale;
+       }
+
+       /**
+        * Set the locale.
+        * 
+        * @param locale
+        *            the locale to set
+        */
+       public void setLocale(final Locale locale) {
+               _locale = locale;
+       }
+
 }
\ No newline at end of file