Fixed 19078: Reduce number of files compiled for apply.module a lot
authorStefan Hühner <stefan.huehner@openbravo.com>
Thu, 09 Feb 2012 14:55:01 +0100
changeset 15451 607dccd3524a
parent 15450 9794bd1516c7
child 15452 b1b35d6343bf
Fixed 19078: Reduce number of files compiled for apply.module a lot
- Split out parts of Utility.java into new file BasicUtility.java
- Split out parts of ModuleUtilltiy.java into new file ModuleUtility.java
- Remove error translation code from apply.module call to verify languages
- Reduce list of xsql files being processed in compile.apply.module
src/build.xml
src/org/openbravo/erpCommon/ad_forms/TranslationManager.java
src/org/openbravo/erpCommon/modules/ApplyModule.java
src/org/openbravo/erpCommon/modules/ModuleUtility.java
src/org/openbravo/erpCommon/modules/ModuleUtiltiy.java
src/org/openbravo/erpCommon/utility/BasicUtility.java
src/org/openbravo/erpCommon/utility/OBError.java
src/org/openbravo/erpCommon/utility/Utility.java
--- a/src/build.xml	Fri Feb 10 18:05:01 2012 +0100
+++ b/src/build.xml	Thu Feb 09 14:55:01 2012 +0100
@@ -166,7 +166,7 @@
     <mkdir dir="${build.apply.module}" />
     <java classname="org.openbravo.data.Sqlc" fork="yes" jvm="${env.JAVA_HOME}/bin/java" maxmemory="${build.maxmemory}" failonerror="true">
       <arg line="'${base.config}'/Openbravo.properties .xsql . '${build.sqlc}'/src" />
-      <jvmarg value="-Dsqlc.listOfFiles=PInstanceProcess_data.xsql,ApplyModule_data.xsql,TableSQLQuery_data.xsql,DateTime_data.xsql,ComboTableQuery_data.xsql,PrintJR_data.xsql,DocumentNo_data.xsql,WindowAccess_data.xsql,Tab_data.xsql,WindowTree_data.xsql,ErrorTextParser_data.xsql,Utility_data.xsql,MessageBD_data.xsql,Translation_data.xsql,Buscador_data.xsql,Pinstance_data.xsql,ProcessRequest_data.xsql,Trigger_data.xsql,ProcessRun_data.xsql,Process_data.xsql,OrgTree_data.xsql,VersionUtility_data.xsql,ImportModule_data.xsql,SystemInfo_data.xsql,Heartbeat_data.xsql,Alert_data.xsql,Registration_data.xsql"/>
+      <jvmarg value="-Dsqlc.listOfFiles=ApplyModule_data.xsql,PInstanceProcess_data.xsql,Translation_data.xsql,MessageBD_data.xsql"/>
       <classpath refid="project.class.path" />
       <syspropertyset>
          <propertyref name="java.security.egd" />
--- a/src/org/openbravo/erpCommon/ad_forms/TranslationManager.java	Fri Feb 10 18:05:01 2012 +0100
+++ b/src/org/openbravo/erpCommon/ad_forms/TranslationManager.java	Thu Feb 09 14:55:01 2012 +0100
@@ -40,8 +40,8 @@
 import org.openbravo.database.ConnectionProvider;
 import org.openbravo.erpCommon.ad_process.buildStructure.Build;
 import org.openbravo.erpCommon.ad_process.buildStructure.BuildTranslation;
+import org.openbravo.erpCommon.utility.BasicUtility;
 import org.openbravo.erpCommon.utility.OBError;
-import org.openbravo.erpCommon.utility.Utility;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 import org.xml.sax.InputSource;
@@ -125,7 +125,7 @@
     } else {
       log4j.error("Can't write on directory: " + strFTPDirectory);
       myMessage.setType("Error");
-      myMessage.setMessage(Utility.messageBD(conn, "CannotWriteDirectory", uiLanguage) + " "
+      myMessage.setMessage(BasicUtility.messageBD(conn, "CannotWriteDirectory", uiLanguage) + " "
           + strFTPDirectory);
       return myMessage;
     }
@@ -154,11 +154,11 @@
     } catch (final Exception e) {
       log4j.error(e);
       myMessage.setType("Error");
-      myMessage.setMessage(Utility.messageBD(conn, "Error", uiLanguage));
+      myMessage.setMessage(BasicUtility.messageBD(conn, "Error", uiLanguage));
       return myMessage;
     }
     myMessage.setType("Success");
-    myMessage.setMessage(Utility.messageBD(conn, "Success", uiLanguage));
+    myMessage.setMessage(BasicUtility.messageBD(conn, "Success", uiLanguage));
     return myMessage;
   }
 
@@ -235,7 +235,7 @@
     } else {
       log4j.error("Can't read on directory: " + directory);
       myMessage.setType("Error");
-      myMessage.setMessage(Utility.messageBD(cp, "CannotReadDirectory", UILanguage) + " "
+      myMessage.setMessage(BasicUtility.messageBD(cp, "CannotReadDirectory", UILanguage) + " "
           + directory);
       return myMessage;
     }
@@ -249,7 +249,7 @@
     } catch (final Exception e) {
       log4j.error(e.toString());
       myMessage.setType("Error");
-      myMessage.setMessage(Utility.messageBD(cp, "Error", UILanguage));
+      myMessage.setMessage(BasicUtility.messageBD(cp, "Error", UILanguage));
       return myMessage;
     }
 
@@ -265,7 +265,7 @@
     }
 
     myMessage.setType("Success");
-    myMessage.setMessage(Utility.messageBD(cp, "Success", UILanguage));
+    myMessage.setMessage(BasicUtility.messageBD(cp, "Success", UILanguage));
     return myMessage;
   }
 
--- a/src/org/openbravo/erpCommon/modules/ApplyModule.java	Fri Feb 10 18:05:01 2012 +0100
+++ b/src/org/openbravo/erpCommon/modules/ApplyModule.java	Thu Feb 09 14:55:01 2012 +0100
@@ -30,15 +30,14 @@
 import org.apache.log4j.Logger;
 import org.apache.log4j.PropertyConfigurator;
 import org.openbravo.base.exception.OBException;
-import org.openbravo.base.secureApp.VariablesSecureApp;
 import org.openbravo.dal.service.OBDal;
 import org.openbravo.database.CPStandAlone;
 import org.openbravo.database.ConnectionProvider;
 import org.openbravo.erpCommon.ad_forms.TranslationManager;
 import org.openbravo.erpCommon.reference.PInstanceProcessData;
+import org.openbravo.erpCommon.utility.BasicUtility;
 import org.openbravo.erpCommon.utility.OBError;
 import org.openbravo.erpCommon.utility.SequenceIdData;
-import org.openbravo.erpCommon.utility.Utility;
 import org.openbravo.model.ad.module.Module;
 import org.openbravo.model.ad.system.Client;
 import org.openbravo.model.common.enterprise.Organization;
@@ -102,18 +101,15 @@
           final String pinstance = SequenceIdData.getUUID();
           PInstanceProcessData.insertPInstance(pool, pinstance, "179", "0", "N", "0", "0", "0");
 
-          final VariablesSecureApp vars = new VariablesSecureApp("0", "0", "0");
-
           ApplyModuleData.process179(pool, pinstance);
 
-          final PInstanceProcessData[] pinstanceData = PInstanceProcessData.select(pool, pinstance);
-          final OBError myMessage = Utility.getProcessInstanceMessage(pool, vars, pinstanceData);
+          final OBError myMessage = getProcessInstanceMessageSimple(pool, pinstance);
           if (myMessage.getType().equals("Error"))
             log4j.error(myMessage.getMessage());
           else
             log4j.info(myMessage.getMessage());
         } catch (final ServletException ex) {
-          ex.printStackTrace();
+          log4j.error("Error running verify language process", ex);
         }
 
         // Import language modules
@@ -130,7 +126,7 @@
       final ApplyModuleData[] ds = ApplyModuleData.selectClientReferenceModules(pool);
 
       if (ds != null && ds.length > 0) {
-        ModuleUtiltiy.orderModuleByDependency(ds);
+        ModuleUtility.orderModuleByDependency(ds);
         // build list of reference data modules which have files to import
         List<ApplyModuleData> dsToImport = new ArrayList<ApplyModuleData>();
         for (ApplyModuleData amd : ds) {
@@ -149,10 +145,10 @@
 
           File datasetFile = new File(strImportFile);
           log4j.info("Importing data from " + amd.name + " module. Dataset: "
-              + Utility.wikifiedName(amd.dsName) + ".xml");
+              + BasicUtility.wikifiedName(amd.dsName) + ".xml");
 
           // Import data from the xml file
-          final String strXml = Utility.fileToString(datasetFile.getPath());
+          final String strXml = BasicUtility.fileToString(datasetFile.getPath());
           final DataImportService importService = DataImportService.getInstance();
           final ImportResult result = importService.importDataFromXML(
               OBDal.getInstance().get(Client.class, "0"),
@@ -187,6 +183,42 @@
   }
 
   /**
+   * Gets untranslated result of the 'ad_language_create' pl-function call.
+   * 
+   * This is a very much simplified version of the 'Utility.getProcesInstanceMessage' function
+   * suitable for the simple usecase as needed inside ApplyModule.
+   * 
+   * @param conn
+   *          Handler for the database connection.
+   * @param pinstance
+   *          ad_pinstance_id to look at
+   * @return Object with the message.
+   * @throws ServletException
+   */
+  private static OBError getProcessInstanceMessageSimple(ConnectionProvider conn, String pinstance)
+      throws ServletException {
+    PInstanceProcessData[] pinstanceData = PInstanceProcessData.select(pool, pinstance);
+
+    OBError myMessage = new OBError();
+    if (pinstanceData != null && pinstanceData.length > 0) {
+      String message = pinstanceData[0].errormsg;
+
+      String type = "Error";
+      if (pinstanceData[0].result.equals("1")) {
+        type = "Success";
+      }
+
+      int errorPos = message.indexOf("@ERROR=");
+      if (errorPos != -1) {
+        // skip the @ERROR= marker in output
+        myMessage.setMessage(message.substring(errorPos + 7));
+      }
+      myMessage.setType(type);
+    }
+    return myMessage;
+  }
+
+  /**
    * Helper function to construct the data-file name for a dataset.
    */
   private String dataSet2ImportFilename(ApplyModuleData ds) throws FileNotFoundException {
@@ -196,7 +228,7 @@
     else
       strPath = obDir + "/modules/" + ds.javapackage + "/referencedata/standard";
 
-    strPath = strPath + "/" + Utility.wikifiedName(ds.dsName) + ".xml";
+    strPath = strPath + "/" + BasicUtility.wikifiedName(ds.dsName) + ".xml";
     return strPath;
   }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/org/openbravo/erpCommon/modules/ModuleUtility.java	Thu Feb 09 14:55:01 2012 +0100
@@ -0,0 +1,175 @@
+/*
+ *************************************************************************
+ * The contents of this file are subject to the Openbravo  Public  License
+ * Version  1.1  (the  "License"),  being   the  Mozilla   Public  License
+ * Version 1.1  with a permitted attribution clause; you may not  use this
+ * file except in compliance with the License. You  may  obtain  a copy of
+ * the License at http://www.openbravo.com/legal/license.html 
+ * Software distributed under the License  is  distributed  on  an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+ * License for the specific  language  governing  rights  and  limitations
+ * under the License. 
+ * The Original Code is Openbravo ERP. 
+ * The Initial Developer of the Original Code is Openbravo SLU 
+ * All portions are Copyright (C) 2008-2012 Openbravo SLU 
+ * All Rights Reserved. 
+ * Contributor(s):  ______________________________________.
+ ************************************************************************
+ */
+
+package org.openbravo.erpCommon.modules;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.log4j.Logger;
+import org.openbravo.dal.core.OBContext;
+import org.openbravo.dal.service.OBDal;
+import org.openbravo.data.FieldProvider;
+import org.openbravo.model.ad.module.Module;
+import org.openbravo.model.ad.module.ModuleDependency;
+
+/**
+ * Module related utilities needed by the 'ApplyModule' module class.
+ * 
+ * Before the 'ant apply.module' target is run a mini compilation is done to compile all classes
+ * needed by that code (and not more). This ModuleUtility class was split out of the main 'ModuleUtiltiy'
+ * class to not pull in the big chain of transitive compile-time dependencies into ApplyModule.
+ * 
+ * Nothing should be added here without reviewing the list of files compiled by the 'ant
+ * compile.apply.module' target to check that it did not grow.
+ * 
+ */
+
+/**
+ * This class implements different utilities related to modules
+ * 
+ * 
+ */
+class ModuleUtility {
+  protected static Logger log4j = Logger.getLogger(ModuleUtility.class);
+
+  /**
+   * It receives an ArrayList<String> with modules IDs and returns the same list ordered taking into
+   * account the module dependency tree.
+   * <p/>
+   * Note that the module list must be a complete list of modules, no dependencies will be checked
+   * for more than one level of deep, this means that passing an incomplete list might not be
+   * ordered correctly.
+   * 
+   * @param modules
+   *          List of module to order
+   * @return modules list ordered
+   * @throws Exception
+   */
+  public static List<String> orderByDependency(List<String> modules) throws Exception {
+
+    Map<String, List<String>> modsWithDeps = getModsDeps(modules);
+    List<String> rt = orderDependencies(modsWithDeps);
+    return rt;
+  }
+
+  /**
+   * Modifies the passed modules {@link FieldProvider} parameter ordering it taking into account
+   * dependencies.
+   * <p/>
+   * 
+   * @param modules
+   *          {@link FieldProvider} that will be sorted. It must contain at least a field named
+   *          <i>adModuleId</i>
+   * @throws Exception
+   */
+  public static void orderModuleByDependency(FieldProvider[] modules) throws Exception {
+    OBContext.setAdminMode();
+    try {
+      List<Module> allModules = OBDal.getInstance().createCriteria(Module.class).list();
+      ArrayList<String> allMdoulesId = new ArrayList<String>();
+      for (Module mod : allModules) {
+        allMdoulesId.add(mod.getId());
+      }
+      List<String> modulesOrder = orderByDependency(allMdoulesId);
+
+      FieldProvider[] fpModulesOrder = new FieldProvider[modules.length];
+      int i = 0;
+      for (String modId : modulesOrder) {
+        for (int j = 0; j < modules.length; j++) {
+          if (modules[j].getField("adModuleId").equals(modId)) {
+            fpModulesOrder[i] = modules[j];
+            i++;
+          }
+        }
+      }
+
+      for (int j = 0; j < modules.length; j++) {
+        modules[j] = fpModulesOrder[j];
+      }
+    } finally {
+      OBContext.restorePreviousMode();
+    }
+
+  }
+
+  /**
+   * Orders modules by dependencies. It adds to a List the modules that have not dependencies to the
+   * ones in the list and calls itself recursively
+   */
+  private static List<String> orderDependencies(Map<String, List<String>> modsWithDeps)
+      throws Exception {
+    ArrayList<String> rt = new ArrayList<String>();
+
+    for (String moduleId : modsWithDeps.keySet()) {
+      if (noDependenciesFromModule(moduleId, modsWithDeps)) {
+        rt.add(moduleId);
+      }
+    }
+
+    for (String modId : rt) {
+      modsWithDeps.remove(modId);
+    }
+
+    if (rt.size() == 0) {
+      throw new Exception("Recursive module dependencies found!" + modsWithDeps.size());
+    }
+
+    if (modsWithDeps.size() != 0) {
+      rt.addAll(orderDependencies(modsWithDeps));
+    }
+    return rt;
+  }
+
+  /**
+   * Checks the module has not dependencies to other modules in the list
+   * 
+   */
+  private static boolean noDependenciesFromModule(String checkModule,
+      Map<String, List<String>> modsWithDeps) {
+
+    List<String> moduleDependencies = modsWithDeps.get(checkModule);
+
+    for (String module : modsWithDeps.keySet()) {
+      if (moduleDependencies.contains(module)) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  /**
+   * Returns a Map with all the modules and their dependencies
+   */
+  private static Map<String, List<String>> getModsDeps(List<String> modules) {
+    Map<String, List<String>> rt = new HashMap<String, List<String>>();
+    for (String moduleId : modules) {
+      Module module = OBDal.getInstance().get(Module.class, moduleId);
+      ArrayList<String> deps = new ArrayList<String>();
+      for (ModuleDependency dep : module.getModuleDependencyList()) {
+        deps.add(dep.getDependentModule().getId());
+      }
+      rt.put(moduleId, deps);
+    }
+    return rt;
+  }
+
+}
--- a/src/org/openbravo/erpCommon/modules/ModuleUtiltiy.java	Fri Feb 10 18:05:01 2012 +0100
+++ b/src/org/openbravo/erpCommon/modules/ModuleUtiltiy.java	Thu Feb 09 14:55:01 2012 +0100
@@ -22,7 +22,6 @@
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
-import java.util.Map;
 
 import org.apache.log4j.Logger;
 import org.openbravo.dal.core.OBContext;
@@ -31,8 +30,6 @@
 import org.openbravo.database.ConnectionProvider;
 import org.openbravo.erpCommon.ad_forms.MaturityLevel;
 import org.openbravo.erpCommon.obps.ActivationKey;
-import org.openbravo.model.ad.module.Module;
-import org.openbravo.model.ad.module.ModuleDependency;
 import org.openbravo.model.ad.system.SystemInformation;
 
 /**
@@ -59,10 +56,7 @@
    * @throws Exception
    */
   public static List<String> orderByDependency(List<String> modules) throws Exception {
-
-    Map<String, List<String>> modsWithDeps = getModsDeps(modules);
-    List<String> rt = orderDependencies(modsWithDeps);
-    return rt;
+    return ModuleUtility.orderByDependency(modules);
   }
 
   /**
@@ -93,33 +87,7 @@
    * @throws Exception
    */
   public static void orderModuleByDependency(FieldProvider[] modules) throws Exception {
-    OBContext.setAdminMode();
-    try {
-      List<Module> allModules = OBDal.getInstance().createCriteria(Module.class).list();
-      ArrayList<String> allMdoulesId = new ArrayList<String>();
-      for (Module mod : allModules) {
-        allMdoulesId.add(mod.getId());
-      }
-      List<String> modulesOrder = orderByDependency(allMdoulesId);
-
-      FieldProvider[] fpModulesOrder = new FieldProvider[modules.length];
-      int i = 0;
-      for (String modId : modulesOrder) {
-        for (int j = 0; j < modules.length; j++) {
-          if (modules[j].getField("adModuleId").equals(modId)) {
-            fpModulesOrder[i] = modules[j];
-            i++;
-          }
-        }
-      }
-
-      for (int j = 0; j < modules.length; j++) {
-        modules[j] = fpModulesOrder[j];
-      }
-    } finally {
-      OBContext.restorePreviousMode();
-    }
-
+    ModuleUtility.orderModuleByDependency(modules);
   }
 
   /**
@@ -138,67 +106,6 @@
   }
 
   /**
-   * Orders modules by dependencies. It adds to a List the modules that have not dependencies to the
-   * ones in the list and calls itself recursively
-   */
-  private static List<String> orderDependencies(Map<String, List<String>> modsWithDeps)
-      throws Exception {
-    ArrayList<String> rt = new ArrayList<String>();
-
-    for (String moduleId : modsWithDeps.keySet()) {
-      if (noDependenciesFromModule(moduleId, modsWithDeps)) {
-        rt.add(moduleId);
-      }
-    }
-
-    for (String modId : rt) {
-      modsWithDeps.remove(modId);
-    }
-
-    if (rt.size() == 0) {
-      throw new Exception("Recursive module dependencies found!" + modsWithDeps.size());
-    }
-
-    if (modsWithDeps.size() != 0) {
-      rt.addAll(orderDependencies(modsWithDeps));
-    }
-    return rt;
-  }
-
-  /**
-   * Checks the module has not dependencies to other modules in the list
-   * 
-   */
-  private static boolean noDependenciesFromModule(String checkModule,
-      Map<String, List<String>> modsWithDeps) {
-
-    List<String> moduleDependencies = modsWithDeps.get(checkModule);
-
-    for (String module : modsWithDeps.keySet()) {
-      if (moduleDependencies.contains(module)) {
-        return false;
-      }
-    }
-    return true;
-  }
-
-  /**
-   * Returns a Map with all the modules and their dependencies
-   */
-  private static Map<String, List<String>> getModsDeps(List<String> modules) {
-    Map<String, List<String>> rt = new HashMap<String, List<String>>();
-    for (String moduleId : modules) {
-      Module module = OBDal.getInstance().get(Module.class, moduleId);
-      ArrayList<String> deps = new ArrayList<String>();
-      for (ModuleDependency dep : module.getModuleDependencyList()) {
-        deps.add(dep.getDependentModule().getId());
-      }
-      rt.put(moduleId, deps);
-    }
-    return rt;
-  }
-
-  /**
    * Obtains the global minimum maturity levels defined for module installation and update.
    * 
    * For installation these 2 values might be different, for update both values are set with the
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/org/openbravo/erpCommon/utility/BasicUtility.java	Thu Feb 09 14:55:01 2012 +0100
@@ -0,0 +1,181 @@
+/*
+ *************************************************************************
+ * The contents of this file are subject to the Openbravo  Public  License
+ * Version  1.1  (the  "License"),  being   the  Mozilla   Public  License
+ * Version 1.1  with a permitted attribution clause; you may not  use this
+ * file except in compliance with the License. You  may  obtain  a copy of
+ * the License at http://www.openbravo.com/legal/license.html 
+ * Software distributed under the License  is  distributed  on  an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+ * License for the specific  language  governing  rights  and  limitations
+ * under the License. 
+ * The Original Code is Openbravo ERP. 
+ * The Initial Developer of the Original Code is Openbravo SLU 
+ * All portions are Copyright (C) 2001-2012 Openbravo SLU
+ * All Rights Reserved. 
+ * Contributor(s):  ______________________________________.
+ ************************************************************************
+ */
+package org.openbravo.erpCommon.utility;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.StringTokenizer;
+
+import org.apache.log4j.Logger;
+import org.openbravo.database.ConnectionProvider;
+import org.openbravo.utils.Replace;
+
+/**
+ * Basic utilities needed by the 'ApplyModule' module class.
+ * 
+ * Before the 'ant apply.module' target is run a mini compilation is done to compile all classes
+ * needed by that code (and not more). This BasicUtility class was split out of the main 'Utility'
+ * class to not pull in the big chain of transitive compile-time dependencies into ApplyModule.
+ * 
+ * Nothing should be added here without reviewing the list of files compiled by the 'ant
+ * compile.apply.module' target to check that it did not grow.
+ * 
+ */
+public class BasicUtility {
+  private static final Logger log4j = Logger.getLogger(BasicUtility.class);
+
+  /**
+   * @see Utility#messageBD(ConnectionProvider, String, String, boolean)
+   */
+  public static String messageBD(ConnectionProvider conn, String strCode, String strLanguage) {
+    return messageBD(conn, strCode, strLanguage, true);
+  }
+
+  /**
+   * Translate the given code into some message from the application dictionary.
+   * 
+   * @param conn
+   *          Handler for the database connection.
+   * @param strCode
+   *          String with the code to search.
+   * @param strLanguage
+   *          String with the translation language.
+   * @param escape
+   *          Escape \n and " characters
+   * @return String with the translated message.
+   */
+  public static String messageBD(ConnectionProvider conn, String strCode, String strLanguage,
+      boolean escape) {
+    String strMessage = "";
+    if (strLanguage == null || strLanguage.equals(""))
+      strLanguage = "en_US";
+
+    try {
+      log4j.debug("Utility.messageBD - Message Code: " + strCode);
+      strMessage = MessageBDData.message(conn, strLanguage, strCode);
+    } catch (final Exception ignore) {
+      log4j.error("Error getting message", ignore);
+    }
+    log4j.debug("Utility.messageBD - Message description: " + strMessage);
+    if (strMessage == null || strMessage.equals("")) {
+      try {
+        strMessage = MessageBDData.columnname(conn, strLanguage, strCode);
+      } catch (final Exception e) {
+        log4j.error("Error getting message", e);
+        strMessage = strCode;
+      }
+    }
+    if (strMessage == null || strMessage.equals("")) {
+      strMessage = strCode;
+    }
+    if (escape) {
+      strMessage = Replace.replace(Replace.replace(strMessage, "\n", "\\n"), "\"", "&quot;");
+    }
+    return strMessage;
+  }
+
+  /**
+   * 
+   * Formats a message String into a String for html presentation. Escapes the &, <, >, " and ®, and
+   * replace the \n by <br/>
+   * and \r for space.
+   * 
+   * IMPORTANT! : this method is designed to transform the output of Utility.messageBD method, and
+   * this method replaces \n by \\n and \" by &quote. Because of that, the first replacements revert
+   * this previous replacements.
+   * 
+   * @param message
+   *          message with java formating
+   * @return html format message
+   */
+  public static String formatMessageBDToHtml(String message) {
+    return Replace.replace(Replace.replace(Replace.replace(Replace.replace(Replace.replace(Replace
+        .replace(Replace.replace(Replace.replace(Replace.replace(
+            Replace.replace(Replace.replace(message, "\\n", "\n"), "&quot", "\""), "&", "&amp;"),
+            "\"", "&quot;"), "<", "&lt;"), ">", "&gt;"), "\n", "<br/>"), "\r", " "), "®", "&reg;"),
+        "&lt;![CDATA[", "<![CDATA["), "]]&gt;", "]]>");
+  }
+
+  /**
+   * Generates a String representing the file in a path
+   * 
+   * @param strPath
+   * @return file to a String
+   */
+  public static String fileToString(String strPath) throws FileNotFoundException {
+    StringBuffer strMyFile = new StringBuffer("");
+    try {
+      File f = new File(strPath);
+      FileInputStream fis = new FileInputStream(f);
+      InputStreamReader isr = new InputStreamReader(fis, "UTF-8");
+
+      final BufferedReader mybr = new BufferedReader(isr);
+
+      String strTemp = mybr.readLine();
+      strMyFile.append(strTemp);
+      while (strTemp != null) {
+        strTemp = mybr.readLine();
+        if (strTemp != null)
+          strMyFile.append("\n").append(strTemp);
+        else {
+          mybr.close();
+          fis.close();
+        }
+      }
+    } catch (final IOException e) {
+      e.printStackTrace();
+    }
+    return strMyFile.toString();
+  }
+
+  /**
+   * Generates a String representing the wikified name from source
+   * 
+   * @param strSource
+   * @return strTarget: wikified name
+   */
+  public static String wikifiedName(String strSource) throws FileNotFoundException {
+    if (strSource == null || strSource.equals(""))
+      return strSource;
+    strSource = strSource.trim();
+    if (strSource.equals(""))
+      return strSource;
+    final StringTokenizer source = new StringTokenizer(strSource, " ", false);
+    String strTarget = "";
+    String strTemp = "";
+    int i = 0;
+    while (source.hasMoreTokens()) {
+      strTemp = source.nextToken();
+      if (i != 0)
+        strTarget = strTarget + "_" + strTemp;
+      else {
+        final String strFirstChar = strTemp.substring(0, 1);
+        strTemp = strFirstChar.toUpperCase() + strTemp.substring(1, strTemp.length());
+        strTarget = strTarget + strTemp;
+      }
+      i++;
+    }
+    return strTarget;
+  }
+
+}
--- a/src/org/openbravo/erpCommon/utility/OBError.java	Fri Feb 10 18:05:01 2012 +0100
+++ b/src/org/openbravo/erpCommon/utility/OBError.java	Thu Feb 09 14:55:01 2012 +0100
@@ -69,8 +69,8 @@
   }
 
   public void setError(OBError e) {
-    setTitle(Utility.formatMessageBDToHtml(e.getTitle()));
-    setMessage(Utility.formatMessageBDToHtml(e.getMessage()));
+    setTitle(BasicUtility.formatMessageBDToHtml(e.getTitle()));
+    setMessage(BasicUtility.formatMessageBDToHtml(e.getMessage()));
     setType(e.getType());
     setConnectionAvailable(e.isConnectionAvailable());
   }
--- a/src/org/openbravo/erpCommon/utility/Utility.java	Fri Feb 10 18:05:01 2012 +0100
+++ b/src/org/openbravo/erpCommon/utility/Utility.java	Thu Feb 09 14:55:01 2012 +0100
@@ -22,7 +22,6 @@
 import java.awt.RenderingHints;
 import java.awt.image.BufferedImage;
 import java.io.BufferedInputStream;
-import java.io.BufferedReader;
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.File;
@@ -32,7 +31,6 @@
 import java.io.FileWriter;
 import java.io.IOException;
 import java.io.InputStream;
-import java.io.InputStreamReader;
 import java.io.OutputStream;
 import java.io.PrintWriter;
 import java.math.BigDecimal;
@@ -89,7 +87,6 @@
 import org.openbravo.uiTranslation.TranslationHandler;
 import org.openbravo.utils.FileUtility;
 import org.openbravo.utils.FormatUtilities;
-import org.openbravo.utils.Replace;
 
 /**
  * @author Fernando Iriazabal
@@ -297,7 +294,7 @@
    * @see Utility#messageBD(ConnectionProvider, String, String, boolean)
    */
   public static String messageBD(ConnectionProvider conn, String strCode, String strLanguage) {
-    return messageBD(conn, strCode, strLanguage, true);
+    return BasicUtility.messageBD(conn, strCode, strLanguage, true);
   }
 
   /**
@@ -315,32 +312,7 @@
    */
   public static String messageBD(ConnectionProvider conn, String strCode, String strLanguage,
       boolean escape) {
-    String strMessage = "";
-    if (strLanguage == null || strLanguage.equals(""))
-      strLanguage = "en_US";
-
-    try {
-      log4j.debug("Utility.messageBD - Message Code: " + strCode);
-      strMessage = MessageBDData.message(conn, strLanguage, strCode);
-    } catch (final Exception ignore) {
-      log4j.error("Error getting message", ignore);
-    }
-    log4j.debug("Utility.messageBD - Message description: " + strMessage);
-    if (strMessage == null || strMessage.equals("")) {
-      try {
-        strMessage = MessageBDData.columnname(conn, strLanguage, strCode);
-      } catch (final Exception e) {
-        log4j.error("Error getting message", e);
-        strMessage = strCode;
-      }
-    }
-    if (strMessage == null || strMessage.equals("")) {
-      strMessage = strCode;
-    }
-    if (escape) {
-      strMessage = Replace.replace(Replace.replace(strMessage, "\n", "\\n"), "\"", "&quot;");
-    }
-    return strMessage;
+    return BasicUtility.messageBD(conn, strCode, strLanguage, escape);
   }
 
   /**
@@ -358,11 +330,7 @@
    * @return html format message
    */
   public static String formatMessageBDToHtml(String message) {
-    return Replace.replace(Replace.replace(Replace.replace(Replace.replace(Replace.replace(Replace
-        .replace(Replace.replace(Replace.replace(Replace.replace(
-            Replace.replace(Replace.replace(message, "\\n", "\n"), "&quot", "\""), "&", "&amp;"),
-            "\"", "&quot;"), "<", "&lt;"), ">", "&gt;"), "\n", "<br/>"), "\r", " "), "®", "&reg;"),
-        "&lt;![CDATA[", "<![CDATA["), "]]&gt;", "]]>");
+    return BasicUtility.formatMessageBDToHtml(message);
   }
 
   /**
@@ -1709,29 +1677,7 @@
    * @return file to a String
    */
   public static String fileToString(String strPath) throws FileNotFoundException {
-    StringBuffer strMyFile = new StringBuffer("");
-    try {
-      File f = new File(strPath);
-      FileInputStream fis = new FileInputStream(f);
-      InputStreamReader isr = new InputStreamReader(fis, "UTF-8");
-
-      final BufferedReader mybr = new BufferedReader(isr);
-
-      String strTemp = mybr.readLine();
-      strMyFile.append(strTemp);
-      while (strTemp != null) {
-        strTemp = mybr.readLine();
-        if (strTemp != null)
-          strMyFile.append("\n").append(strTemp);
-        else {
-          mybr.close();
-          fis.close();
-        }
-      }
-    } catch (final IOException e) {
-      e.printStackTrace();
-    }
-    return strMyFile.toString();
+    return BasicUtility.fileToString(strPath);
   }
 
   /**
@@ -1741,27 +1687,7 @@
    * @return strTarget: wikified name
    */
   public static String wikifiedName(String strSource) throws FileNotFoundException {
-    if (strSource == null || strSource.equals(""))
-      return strSource;
-    strSource = strSource.trim();
-    if (strSource.equals(""))
-      return strSource;
-    final StringTokenizer source = new StringTokenizer(strSource, " ", false);
-    String strTarget = "";
-    String strTemp = "";
-    int i = 0;
-    while (source.hasMoreTokens()) {
-      strTemp = source.nextToken();
-      if (i != 0)
-        strTarget = strTarget + "_" + strTemp;
-      else {
-        final String strFirstChar = strTemp.substring(0, 1);
-        strTemp = strFirstChar.toUpperCase() + strTemp.substring(1, strTemp.length());
-        strTarget = strTarget + strTemp;
-      }
-      i++;
-    }
-    return strTarget;
+    return BasicUtility.wikifiedName(strSource);
   }
 
   public static String getButtonName(ConnectionProvider conn, VariablesSecureApp vars,