Java tutorial
/* ************************************************************************* * 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-2015 Openbravo SLU * All Rights Reserved. * Contributor(s): ______________________________________. ************************************************************************ */ package org.openbravo.erpCommon.ad_forms; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.PrintWriter; import java.net.URL; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.Enumeration; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Properties; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.dbcp.BasicDataSource; import org.apache.commons.fileupload.FileItem; import org.apache.commons.lang.StringEscapeUtils; import org.apache.commons.lang.StringUtils; import org.apache.ddlutils.Platform; import org.apache.ddlutils.PlatformFactory; import org.apache.ddlutils.model.Database; import org.codehaus.jettison.json.JSONArray; import org.codehaus.jettison.json.JSONException; import org.codehaus.jettison.json.JSONObject; import org.hibernate.criterion.Order; import org.hibernate.criterion.Restrictions; import org.openbravo.base.exception.OBException; import org.openbravo.base.filter.IsIDFilter; import org.openbravo.base.secureApp.HttpSecureAppServlet; import org.openbravo.base.secureApp.VariablesSecureApp; import org.openbravo.base.session.OBPropertiesProvider; import org.openbravo.dal.core.OBContext; import org.openbravo.dal.core.OBInterceptor; import org.openbravo.dal.service.OBCriteria; import org.openbravo.dal.service.OBDal; import org.openbravo.data.FieldProvider; import org.openbravo.database.ConnectionProvider; import org.openbravo.ddlutils.task.DatabaseUtils; import org.openbravo.ddlutils.util.DBSMOBUtil; import org.openbravo.ddlutils.util.OBDataset; import org.openbravo.erpCommon.ad_process.HeartbeatProcess; import org.openbravo.erpCommon.businessUtility.WindowTabs; import org.openbravo.erpCommon.modules.ImportModule; import org.openbravo.erpCommon.modules.ModuleTree; import org.openbravo.erpCommon.modules.ModuleUtiltiy; import org.openbravo.erpCommon.modules.UninstallModule; import org.openbravo.erpCommon.modules.VersionUtility; import org.openbravo.erpCommon.modules.VersionUtility.VersionComparator; import org.openbravo.erpCommon.obps.ActivationKey; import org.openbravo.erpCommon.obps.ActivationKey.CommercialModuleStatus; import org.openbravo.erpCommon.obps.ActivationKey.LicenseClass; import org.openbravo.erpCommon.obps.ActivationKey.SubscriptionStatus; import org.openbravo.erpCommon.obps.DisabledModules; import org.openbravo.erpCommon.utility.ComboTableData; import org.openbravo.erpCommon.utility.FieldProviderFactory; import org.openbravo.erpCommon.utility.HttpsUtils; import org.openbravo.erpCommon.utility.LeftTabsBar; import org.openbravo.erpCommon.utility.NavigationBar; import org.openbravo.erpCommon.utility.OBError; import org.openbravo.erpCommon.utility.OBErrorBuilder; import org.openbravo.erpCommon.utility.OBMessageUtils; import org.openbravo.erpCommon.utility.SQLReturnObject; import org.openbravo.erpCommon.utility.ToolBar; import org.openbravo.erpCommon.utility.Utility; import org.openbravo.model.ad.system.SystemInformation; import org.openbravo.services.webservice.Module; import org.openbravo.services.webservice.ModuleDependency; import org.openbravo.services.webservice.SimpleModule; import org.openbravo.services.webservice.WebService3Impl; import org.openbravo.services.webservice.WebService3ImplServiceLocator; import org.openbravo.utils.Replace; import org.openbravo.xmlEngine.XmlDocument; /** * This servlet is in charge of showing the Module Manager Console which have three tabs: *Installed * modules *Add Modules *Installation history * * */ public class ModuleManagement extends HttpSecureAppServlet { private static final long serialVersionUID = 1L; public static final String UPDATE_ALL_RECORD_ID = "FFF"; private static final String UPGRADE_INFO_URL = "https://butler.openbravo.com/heartbeat-server/org.openbravo.utility.centralrepository/UpgradeInfo"; /** * Main method that controls the sent command */ @Override public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { final VariablesSecureApp vars = new VariablesSecureApp(request); if (vars.commandIn("DEFAULT")) { printPageInstalled(response, vars); } else if (vars.commandIn("APPLY")) { printPageApply(response, vars); } else if (vars.commandIn("ADD")) { final String searchText = vars.getGlobalVariable("inpSearchText", "ModuleManagemetAdd|text", ""); printPageAdd(request, response, vars, searchText, true); } else if (vars.commandIn("ADD_NOSEARCH")) { final String searchText = vars.getGlobalVariable("inpSearchText", "ModuleManagemetAdd|text", ""); printPageAdd(request, response, vars, searchText, false); } else if (vars.commandIn("ADD_SEARCH")) { final String searchText = vars.getRequestGlobalVariable("inpSearchText", "ModuleManagemetAdd|text"); printPageAdd(request, response, vars, searchText, true); } else if (vars.commandIn("HISTORY")) { final String strDateFrom = vars.getGlobalVariable("inpDateFrom", "ModuleManagement|DateFrom", ""); final String strDateTo = vars.getGlobalVariable("inpDateTo", "ModuleManagement|DateTo", ""); final String strUser = vars.getGlobalVariable("inpUser", "ModuleManagement|inpUser", ""); printPageHistory(response, vars, strDateFrom, strDateTo, strUser); } else if (vars.commandIn("HISTORY_SEARCH")) { final String strDateFrom = vars.getRequestGlobalVariable("inpDateFrom", "ModuleManagement|DateFrom"); final String strDateTo = vars.getRequestGlobalVariable("inpDateTo", "ModuleManagement|DateTo"); final String strUser = vars.getRequestGlobalVariable("inpUser", "ModuleManagement|inpUser"); printPageHistory(response, vars, strDateFrom, strDateTo, strUser); } else if (vars.commandIn("DETAIL")) { final String record = vars.getStringParameter("inpcRecordId"); final boolean local = vars.getStringParameter("inpLocalInstall").equals("Y"); printPageDetail(response, vars, record, local); } else if (vars.commandIn("INSTALL")) { final String record = vars.getStringParameter("inpcRecordId"); printPageInstall1(response, request, vars, record, false, null, new String[0], ModuleUtiltiy.getSystemMaturityLevels(true), null); } else if (vars.commandIn("INSTALL2")) { printPageInstall2(response, vars); } else if (vars.commandIn("INSTALL3")) { printPageInstall3(response, vars); } else if (vars.commandIn("LICENSE")) { final String record = vars.getStringParameter("inpcRecordId"); printLicenseAgreement(response, vars, record); } else if (vars.commandIn("LOCAL")) { printSearchFile(response, vars, null); } else if (vars.commandIn("INSTALLFILE")) { printPageInstallFile(response, request, vars); } else if (vars.commandIn("UNINSTALL")) { final String modules = vars.getInStringParameter("inpNodes", IsIDFilter.instance); final UninstallModule um = new UninstallModule(this, vars.getSessionValue("#sourcePath"), vars); um.execute(modules); OBError msg = um.getOBError(); vars.setMessage("ModuleManagement|message", msg); // clean module updates if there are any boolean isCleaned = cleanModulesUpdates(); if (isCleaned) { msg = OBErrorBuilder.buildMessage(msg, "Info", Utility.messageBD(this, "ModuleUpdatesRemoved", vars.getLanguage())); } response.sendRedirect(strDireccion + request.getServletPath() + "?Command=DEFAULT"); log4j.info(modules); } else if (vars.commandIn("DISABLE")) { disable(vars); response.sendRedirect(strDireccion + request.getServletPath() + "?Command=DEFAULT"); } else if (vars.commandIn("ENABLE")) { enable(vars); response.sendRedirect(strDireccion + request.getServletPath() + "?Command=DEFAULT"); } else if (vars.commandIn("SCAN")) { printScan(response, vars); } else if (vars.commandIn("UPDATE")) { final String updateModule = vars.getStringParameter("inpcUpdate"); String[] modulesToUpdate; if (updateModule.equals("all")) { modulesToUpdate = getUpdateableModules(); } else { modulesToUpdate = new String[1]; modulesToUpdate[0] = updateModule; } // For update obtain just update maturity level printPageInstall1(response, request, vars, null, false, null, modulesToUpdate, ModuleUtiltiy.getSystemMaturityLevels(false), null); } else if (vars.commandIn("UPGRADE", "UPGRADE1")) { OBContext.setAdminMode(); try { printPageUpgrade(response, request); } finally { OBContext.restorePreviousMode(); } } else if (vars.commandIn("SETTINGS", "SETTINGS_ADD", "SETTINGS_REMOVE", "SETTINGS_SAVE")) { printPageSettings(response, request); } else { pageError(response); } } /** * Show the tab for installed modules, where it is possible to look for updates, uninstall and * apply changes- * * @param response * @param vars * @throws IOException * @throws ServletException */ private void printPageInstalled(HttpServletResponse response, VariablesSecureApp vars) throws IOException, ServletException { if (log4j.isDebugEnabled()) log4j.debug("Output: Installed"); response.setContentType("text/html; charset=UTF-8"); final PrintWriter out = response.getWriter(); final XmlDocument xmlDocument = xmlEngine .readXmlTemplate("org/openbravo/erpCommon/ad_forms/ModuleManagementInstalled").createXmlDocument(); xmlDocument.setParameter("directory", "var baseDirectory = \"" + strReplaceWith + "/\";\n"); xmlDocument.setParameter("language", "defaultLang=\"" + vars.getLanguage() + "\";"); // Interface parameters final ToolBar toolbar = new ToolBar(this, vars.getLanguage(), "ModuleManagement", false, "", "", "", false, "ad_forms", strReplaceWith, false, true); toolbar.prepareSimpleToolBarTemplate(); xmlDocument.setParameter("toolbar", toolbar.toString()); try { final WindowTabs tabs = new WindowTabs(this, vars, "org.openbravo.erpCommon.ad_forms.ModuleManagement"); xmlDocument.setParameter("theme", vars.getTheme()); final NavigationBar nav = new NavigationBar(this, vars.getLanguage(), "ModuleManagement.html", classInfo.id, classInfo.type, strReplaceWith, tabs.breadcrumb()); xmlDocument.setParameter("navigationBar", nav.toString()); final LeftTabsBar lBar = new LeftTabsBar(this, vars.getLanguage(), "ModuleManagement.html", strReplaceWith); xmlDocument.setParameter("leftTabs", lBar.manualTemplate()); } catch (final Exception ex) { throw new ServletException(ex); } { final OBError myMessage = vars.getMessage("ModuleManagement|message"); vars.removeMessage("ModuleManagement|message"); if (myMessage != null) { xmlDocument.setParameter("messageType", myMessage.getType()); xmlDocument.setParameter("messageTitle", myMessage.getTitle()); xmlDocument.setParameter("messageMessage", myMessage.getMessage()); } } // //---- final ModuleTree tree = new ModuleTree(this); tree.setLanguage(vars.getLanguage()); tree.showNotifications(true); String notificationsHTML = ""; try { JSONObject updatesUpgrades = getNotificationsJSON(vars.getLanguage()); if (updatesUpgrades.has("updatesRebuildHTML")) { notificationsHTML = updatesUpgrades.getString("updatesRebuildHTML"); } List<Map<String, String>> upgs = new ArrayList<Map<String, String>>(); if (updatesUpgrades.has("upgrades")) { JSONArray jsonUpgrades = updatesUpgrades.getJSONArray("upgrades"); for (int i = 0; i < jsonUpgrades.length(); i++) { JSONArray versions = jsonUpgrades.getJSONObject(i).getJSONArray("version"); for (int v = 0; v < versions.length(); v++) { Map<String, String> upg = new HashMap<String, String>(); upg.put("id", ((JSONObject) jsonUpgrades.get(i)).getString("moduleId")); upg.put("name", ((JSONObject) jsonUpgrades.get(i)).getString("moduleName") + " " + versions.get(v)); upg.put("version", versions.getString(v)); upgs.add(upg); } } xmlDocument.setParameter("showUpgrades", ""); } xmlDocument.setData("upgrades", FieldProviderFactory.getFieldProviderArray(upgs)); } catch (JSONException e) { log4j.error("Error getting notifications", e); } tree.setNotifications(notificationsHTML); // Obtains a tree for the installed modules xmlDocument.setParameter("moduleTree", tree.toHtml()); // Obtains a box for display the modules descriptions xmlDocument.setParameter("moduleTreeDescription", tree.descriptionToHtml()); out.println(xmlDocument.print()); out.close(); } /** * Displays the pop-up to execute an ant task * * @param response * @param vars * @throws IOException * @throws ServletException */ private void printPageApply(HttpServletResponse response, VariablesSecureApp vars) throws IOException, ServletException { try { final XmlDocument xmlDocument = xmlEngine .readXmlTemplate("org/openbravo/erpCommon/ad_forms/ApplyModule").createXmlDocument(); final PrintWriter out = response.getWriter(); response.setContentType("text/html; charset=UTF-8"); out.println(xmlDocument.print()); out.close(); } catch (final Exception e) { log4j.error(e.getMessage(), e); } } /** * Returns an HTML with the available notifications which can be: *Unapplied changes: rebuild * system *Available updates: install them */ private JSONObject getNotificationsJSON(String lang) { String updatesRebuildHTML = ""; JSONArray upgrades = new JSONArray(); try { String restartTomcat = ModuleManagementData.selectRestartTomcat(this); String totalToBeRebuilt = ModuleManagementData.selectRebuild(this); /* * Set rebuild now option if System is under Maintenance. Refer * https://issues.openbravo.com/view.php?id=13212 */ Boolean lastBuildFailed = false; SystemInformation sysInfo = OBDal.getInstance().get(SystemInformation.class, "0"); if (sysInfo.getSystemStatus() != null && !sysInfo.getSystemStatus().equals("RB70")) { lastBuildFailed = true; } // Check if last build was done but Tomcat wasn't restarted, // but dont show the restart tomcat message is a rebuild need to be done if (!restartTomcat.equals("0") && totalToBeRebuilt.equals("0")) { updatesRebuildHTML = "<a class=\"LabelLink_noicon\" href=\"#\" onclick=\"openServletNewWindow('TOMCAT', false, '../ad_process/ApplyModules.html', 'BUTTON', null, true, 650, 900, null, null, null, null, true);return false;\">" + Utility.messageBD(this, "Restart_Tomcat", lang) + "</a>"; } else { // Check for rebuild system if (!totalToBeRebuilt.equals("0") || lastBuildFailed) { updatesRebuildHTML = totalToBeRebuilt + " " + Utility.messageBD(this, "ApplyModules", lang) + ", <a id=\"rebuildNow\" class=\"LabelLink_noicon\" href=\"#\" onclick=\"openServletNewWindow('DEFAULT', false, '../ad_process/ApplyModules.html', 'BUTTON', null, true, 700, 900, null, null, null, null, true);return false;\">" + Utility.messageBD(this, "RebuildNow", lang) + "</a>"; } // Check for updates String message = ""; String total = ModuleManagementData.selectUpdate(this); if (!total.equals("0")) { if (!updatesRebuildHTML.isEmpty()) { updatesRebuildHTML += " / "; } if (total.equals("1")) { message = Utility.messageBD(this, "UpdateAvailable", lang).toLowerCase(); } else { message = Utility.messageBD(this, "UpdatesAvailable", lang); } updatesRebuildHTML += total + " " + message + " " + "<a class=\"LabelLink_noicon\" href=\"#\" onclick=\"installUpdate('all'); return false;\">" + Utility.messageBD(this, "InstallUpdatesNow", lang) + "</a>"; } } OBCriteria<org.openbravo.model.ad.module.Module> qUpgr = OBDal.getInstance() .createCriteria(org.openbravo.model.ad.module.Module.class); qUpgr.add(Restrictions.isNotNull(org.openbravo.model.ad.module.Module.PROPERTY_UPGRADEAVAILABLE)); for (org.openbravo.model.ad.module.Module upgr : qUpgr.list()) { JSONObject upgrade = new JSONObject(); upgrade.put("moduleId", upgr.getId()); upgrade.put("version", new JSONArray(upgr.getUpgradeAvailable())); upgrade.put("moduleName", upgr.getName()); upgrades.put(upgrade); } } catch (final Exception e) { log4j.error(e.getMessage(), e); } JSONObject rt = new JSONObject(); try { if (!updatesRebuildHTML.isEmpty()) { rt.put("updatesRebuildHTML", updatesRebuildHTML); } if (upgrades.length() != 0) { rt.put("upgrades", upgrades); } } catch (JSONException e) { log4j.error("Error genrating updates notifications", e); } return rt; } /** * Displays the second tab: Add modules where it is possible to search and install modules * remotely or locally * * @param request * @param response * @param vars * @param searchText * @param displaySearch * @throws IOException * @throws ServletException */ private void printPageAdd(HttpServletRequest request, HttpServletResponse response, VariablesSecureApp vars, String searchText, boolean displaySearch) throws IOException, ServletException { if (log4j.isDebugEnabled()) log4j.debug("Output: Installed"); response.setContentType("text/html; charset=UTF-8"); final PrintWriter out = response.getWriter(); final XmlDocument xmlDocument = xmlEngine .readXmlTemplate("org/openbravo/erpCommon/ad_forms/ModuleManagementAdd").createXmlDocument(); xmlDocument.setParameter("directory", "var baseDirectory = \"" + strReplaceWith + "/\";\n"); xmlDocument.setParameter("language", "defaultLang=\"" + vars.getLanguage() + "\";"); // Interface parameters final ToolBar toolbar = new ToolBar(this, vars.getLanguage(), "ModuleManagement", false, "", "", "", false, "ad_forms", strReplaceWith, false, true); toolbar.prepareSimpleToolBarTemplate(); xmlDocument.setParameter("toolbar", toolbar.toString()); try { final WindowTabs tabs = new WindowTabs(this, vars, "org.openbravo.erpCommon.ad_forms.ModuleManagement"); xmlDocument.setParameter("theme", vars.getTheme()); final NavigationBar nav = new NavigationBar(this, vars.getLanguage(), "ModuleManagement.html", classInfo.id, classInfo.type, strReplaceWith, tabs.breadcrumb()); xmlDocument.setParameter("navigationBar", nav.toString()); final LeftTabsBar lBar = new LeftTabsBar(this, vars.getLanguage(), "ModuleManagement.html", strReplaceWith); xmlDocument.setParameter("leftTabs", lBar.manualTemplate()); } catch (final Exception ex) { throw new ServletException(ex); } { final OBError myMessage = vars.getMessage("ModuleManagement"); vars.removeMessage("ModuleManagement"); if (myMessage != null) { xmlDocument.setParameter("messageType", myMessage.getType()); xmlDocument.setParameter("messageTitle", myMessage.getTitle()); xmlDocument.setParameter("messageMessage", myMessage.getMessage()); } } // //---- xmlDocument.setParameter("inpSearchText", searchText); // In case the search results must be shown request and display them if (displaySearch) xmlDocument.setParameter("searchResults", getSearchResults(request, response, vars, searchText)); out.println(xmlDocument.print()); out.close(); } /** * Displays the third tab "Installation History" with a log of all installation actions * * @param response * @param vars * @param strDateFrom * @param strDateTo * @param strUser * @throws IOException * @throws ServletException */ private void printPageHistory(HttpServletResponse response, VariablesSecureApp vars, String strDateFrom, String strDateTo, String strUser) throws IOException, ServletException { if (log4j.isDebugEnabled()) log4j.debug("Output: Installed"); response.setContentType("text/html; charset=UTF-8"); final PrintWriter out = response.getWriter(); final XmlDocument xmlDocument = xmlEngine .readXmlTemplate("org/openbravo/erpCommon/ad_forms/ModuleManagementHistory").createXmlDocument(); xmlDocument.setParameter("directory", "var baseDirectory = \"" + strReplaceWith + "/\";\n"); xmlDocument.setParameter("language", "defaultLang=\"" + vars.getLanguage() + "\";"); // Interface parameters final ToolBar toolbar = new ToolBar(this, vars.getLanguage(), "ModuleManagement", false, "", "", "", false, "ad_forms", strReplaceWith, false, true); toolbar.prepareSimpleToolBarTemplate(); xmlDocument.setParameter("toolbar", toolbar.toString()); try { final WindowTabs tabs = new WindowTabs(this, vars, "org.openbravo.erpCommon.ad_forms.ModuleManagement"); xmlDocument.setParameter("theme", vars.getTheme()); final NavigationBar nav = new NavigationBar(this, vars.getLanguage(), "ModuleManagement.html", classInfo.id, classInfo.type, strReplaceWith, tabs.breadcrumb()); xmlDocument.setParameter("navigationBar", nav.toString()); final LeftTabsBar lBar = new LeftTabsBar(this, vars.getLanguage(), "ModuleManagement.html", strReplaceWith); xmlDocument.setParameter("leftTabs", lBar.manualTemplate()); } catch (final Exception ex) { throw new ServletException(ex); } xmlDocument.setParameter("dateFrom", strDateFrom); xmlDocument.setParameter("dateFromdisplayFormat", vars.getSessionValue("#AD_SqlDateFormat")); xmlDocument.setParameter("dateFromsaveFormat", vars.getSessionValue("#AD_SqlDateFormat")); xmlDocument.setParameter("dateTo", strDateTo); xmlDocument.setParameter("dateTodisplayFormat", vars.getSessionValue("#AD_SqlDateFormat")); xmlDocument.setParameter("dateTosaveFormat", vars.getSessionValue("#AD_SqlDateFormat")); xmlDocument.setParameter("inpUser", strUser); try { ComboTableData comboTableData = new ComboTableData(vars, this, "18", "AD_User_ID", "110", "", Utility.getContext(this, vars, "#AccessibleOrgTree", "ModuleManagement"), Utility.getContext(this, vars, "#User_Client", "ModuleManagement"), 0); Utility.fillSQLParameters(this, vars, null, comboTableData, "ModuleManagement", strUser); xmlDocument.setData("reportUser", "liststructure", comboTableData.select(false)); comboTableData = null; } catch (final Exception ex) { throw new ServletException(ex); } final ModuleManagementData data[] = ModuleManagementData.selectLog(this, vars.getLanguage(), strUser, strDateFrom, strDateTo); xmlDocument.setData("detail", data); out.println(xmlDocument.print()); out.close(); } /** * Shows the detail pop-up for a module * * @param response * @param vars * @param recordId * @throws IOException * @throws ServletException */ private void printPageDetail(HttpServletResponse response, VariablesSecureApp vars, String recordId, boolean local) throws IOException, ServletException { Module module = null; if (!local) { try { // retrieve the module details from the webservice final WebService3ImplServiceLocator loc = new WebService3ImplServiceLocator(); final WebService3Impl ws = loc.getWebService3(); module = ws.moduleDetail(recordId); } catch (final Exception e) { log4j.error(e.getMessage(), e); throw new ServletException(e); } } else { final ImportModule im = (ImportModule) vars.getSessionObject("InstallModule|ImportModule"); module = im.getModule(recordId); } final ModuleDependency[] dependencies = module.getDependencies(); final ModuleDependency[] includes = module.getIncludes(); final String discard[] = { "", "" }; if (includes == null || includes.length == 0) discard[0] = "includeDiscard"; if (dependencies == null || dependencies.length == 0) discard[1] = "dependDiscard"; final XmlDocument xmlDocument = xmlEngine .readXmlTemplate("org/openbravo/erpCommon/ad_forms/ModuleManagementDetails", discard) .createXmlDocument(); xmlDocument.setParameter("language", "defaultLang=\"" + vars.getLanguage() + "\";"); xmlDocument.setParameter("theme", vars.getTheme()); xmlDocument.setParameter("key", recordId); xmlDocument.setParameter("type", (module.getType() == null ? "M" : module.getType()).equals("M") ? "Module" : module.getType().equals("T") ? "Template" : "Pack"); xmlDocument.setParameter("moduleName", module.getName()); xmlDocument.setParameter("moduleVersion", module.getVersionNo()); xmlDocument.setParameter("description", module.getDescription()); xmlDocument.setParameter("help", module.getHelp()); xmlDocument.setParameter("author", module.getAuthor()); String url = module.getUrl(); if (url == null || url.equals("")) { xmlDocument.setParameter("urlDisplay", "none"); } else { xmlDocument.setParameter("urlLink", getLink(url)); xmlDocument.setParameter("url", url); } xmlDocument.setParameter("license", Utility.getListValueName("License Type", module.getLicenseType(), vars.getLanguage())); if (dependencies != null && dependencies.length > 0) { xmlDocument.setData("dependencies", formatDeps4Display(dependencies, vars, this)); } if (includes != null && includes.length > 0) { xmlDocument.setData("includes", formatDeps4Display(includes, vars, this)); } response.setContentType("text/html; charset=UTF-8"); final PrintWriter out = response.getWriter(); out.println(xmlDocument.print()); out.close(); } private String getLink(String url) { if (url == null || url.isEmpty()) { return ""; } String link = url; if (!url.matches("^[a-z]+://.+")) { // url without protocol: infer http link = "http://" + url; } return link; } private static FieldProvider[] formatDeps4Display(ModuleDependency[] deps, VariablesSecureApp vars, ConnectionProvider conn) { @SuppressWarnings("unchecked") HashMap<String, String>[] res = new HashMap[deps.length]; for (int i = 0; i < deps.length; i++) { res[i] = new HashMap<String, String>(); res[i].put("moduleName", getDisplayString(deps[i], vars, conn)); } return FieldProviderFactory.getFieldProviderArray(res); } private static String getDisplayString(ModuleDependency dep, VariablesSecureApp vars, ConnectionProvider conn) { final String DETAIL_MSG_DETAIL_BETWEEN = Utility.messageBD(conn, "MODULE_VERSION_BETWEEN", vars.getLanguage()); final String DETAIL_MSG_OR_LATER = Utility.messageBD(conn, "MODULE_VERSION_OR_LATER", vars.getLanguage()); final String VERSION = Utility.messageBD(conn, "VERSION", vars.getLanguage()); String displayString = dep.getModuleName() + " " + VERSION + " "; if (dep.getVersionEnd() != null && dep.getVersionEnd().equals(dep.getVersionStart())) { displayString += dep.getVersionStart(); } else if (dep.getVersionEnd() == null || dep.getVersionEnd().contains(".999999")) { // NOTE: dep.getVersionEnd() is .999999 from CR but null when installing from .obx displayString += DETAIL_MSG_OR_LATER.replace("@MODULE_VERSION@", dep.getVersionStart()); } else { String tmp = DETAIL_MSG_DETAIL_BETWEEN.replace("@MIN_VERSION@", dep.getVersionStart()); tmp = tmp.replace("@MAX_VERSION@", dep.getVersionEnd()); displayString += tmp; } return displayString; } /** * A decision needs to be made when executing this method/pop-up: * * a. The file is not a .obx file -> Display the search file pop-up again, with an error * indicating the file must be a .obx file. * * b. The file is an .obx file but no need to update -> Display the same pop-up again with a * warning indicating the module is already the most recent version. * * b. The .obx file is okay -> redirect to the moduleInstall1 pop-up. * * @param request * @param response * @throws IOException */ private void printPageInstallFile(HttpServletResponse response, HttpServletRequest request, VariablesSecureApp vars) throws ServletException, IOException { final FileItem fi = vars.getMultiFile("inpFile"); if (!fi.getName().toUpperCase().endsWith(".OBX")) { // We don't have a .obx file OBError message = new OBError(); message.setType("Error"); message.setTitle(Utility.messageBD(this, message.getType(), vars.getLanguage())); message.setMessage(Utility.messageBD(this, "MOD_OBX", vars.getLanguage())); printSearchFile(response, vars, message); } else { ImportModule im = new ImportModule(this, vars.getSessionValue("#sourcePath"), vars); try { if (im.isModuleUpdate(fi.getInputStream())) { vars.setSessionObject("ModuleManagementInstall|File", vars.getMultiFile("inpFile")); printPageInstall1(response, request, vars, null, true, fi.getInputStream(), new String[0], null, null); } else { OBError message = im.getOBError(this); printSearchFile(response, vars, message); } } catch (Exception e) { log4j.error(e.getMessage(), e); throw new ServletException(e); } } } private void printPageUpgrade(HttpServletResponse response, HttpServletRequest request) throws IOException, ServletException { final VariablesSecureApp vars = new VariablesSecureApp(request); final String moduleId = vars.getStringParameter("inpcUpdate"); final String version = vars.getStringParameter("upgradeVersion"); String usingAprm = "Y"; if (vars.commandIn("UPGRADE")) { // Remote upgrade is only allowed for heartbeat enabled instances if (!HeartbeatProcess.isHeartbeatEnabled()) { String command = "UPGRADE"; response.sendRedirect(strDireccion + "/ad_forms/Heartbeat.html?Command=" + command + "_MODULE&inpcRecordId=" + moduleId + "&version=" + version); return; } // Show information about upgrade org.openbravo.model.ad.module.Module mod = OBDal.getInstance() .get(org.openbravo.model.ad.module.Module.class, moduleId); String upgradeName = mod.getName() + " - " + version; String upgradeInfo = ""; try { String infoRequest = "Command=info"; infoRequest += "&modId=" + moduleId; infoRequest += "&version=" + version; infoRequest += "&lang=" + vars.getLanguage(); infoRequest += "&aprm=" + usingAprm; infoRequest += "&professional=" + (ActivationKey.getInstance().isActive() ? "Y" : "N"); upgradeInfo = new JSONObject(HttpsUtils.sendSecure(new URL(UPGRADE_INFO_URL), infoRequest)) .getString("description"); } catch (Exception e1) { log4j.error("Error getting upgrade info", e1); } final XmlDocument xmlDocument = xmlEngine .readXmlTemplate("org/openbravo/erpCommon/ad_forms/ModuleManagement_UpgradeInfo", new String[] { "updateNeeded" }) .createXmlDocument(); xmlDocument.setParameter("directory", "var baseDirectory = \"" + strReplaceWith + "/\";\n"); xmlDocument.setParameter("language", "defaultLang=\"" + vars.getLanguage() + "\";"); xmlDocument.setParameter("theme", vars.getTheme()); xmlDocument.setParameter("upgradeName", upgradeName); xmlDocument.setParameter("upgradeInfo", upgradeInfo); xmlDocument.setParameter("moduleID", moduleId); xmlDocument.setParameter("upgradeVersion", version); response.setContentType("text/html; charset=UTF-8"); final PrintWriter out = response.getWriter(); out.println(xmlDocument.print()); out.close(); return; } if (vars.commandIn("UPGRADE1")) { // Check the pre-requisites are fulfilled String infoRequest = "Command=requirements"; infoRequest += "&modId=" + moduleId; infoRequest += "&version=" + version; infoRequest += "&lang=" + vars.getLanguage(); infoRequest += "&aprm=" + usingAprm; infoRequest += "&professional=" + (ActivationKey.getInstance().isActive() ? "Y" : "N"); try { JSONArray requirements = new JSONObject( HttpsUtils.sendSecure(new URL(UPGRADE_INFO_URL), infoRequest)).getJSONArray("requirements"); List<Map<String, String>> requiredUpdates = new ArrayList<Map<String, String>>(); SystemInformation sys = OBDal.getInstance().get(SystemInformation.class, "0"); Integer maturityUpdate = Integer.parseInt(sys.getMaturityUpdate()); for (int i = 0; i < requirements.length(); i++) { JSONObject requisit = requirements.getJSONObject(i); log4j.debug("Checking upgrade prerequisit " + requisit.toString()); String modId = requisit.getString("moduleId"); org.openbravo.model.ad.module.Module mod = OBDal.getInstance() .get(org.openbravo.model.ad.module.Module.class, modId); if (mod == null) { log4j.debug("Module is not installed, skipt it"); continue; } String requiredVersion = requisit.getString("version"); String installedVersion = mod.getVersion(); if (new VersionUtility.VersionComparator().compare(installedVersion, requiredVersion) >= 0) { log4j.debug("ok " + installedVersion + ">=" + requiredVersion); continue; } Map<String, String> requiredUpdate = new HashMap<String, String>(); requiredUpdate.put("id", modId); requiredUpdate.put("name", mod.getName()); requiredUpdate.put("installed", installedVersion); requiredUpdate.put("required", requisit.getString("versionName")); Integer maximumMaturity = Integer.parseInt(requisit.getString("maturity")); Integer acceptedMaturity; if (mod.getMaturityUpdate() != null) { acceptedMaturity = Integer.parseInt(mod.getMaturityUpdate()); } else { acceptedMaturity = maturityUpdate; } if (maximumMaturity < acceptedMaturity) { requiredUpdate.put("displayMaturity", "block"); requiredUpdate.put("mat", requisit.getString("maturityName")); } else { requiredUpdate.put("displayMaturity", "none"); } requiredUpdates.add(requiredUpdate); } if (!requiredUpdates.isEmpty()) { String discard[] = { "buttonContinue", "info" }; OBError msg = new OBError(); msg.setType("Warning"); msg.setTitle(Utility.messageBD(this, "UpgradeRequiresUpdates", vars.getLanguage())); msg.setMessage(Utility.messageBD(this, "UpgradeRequiresUpdatesMsg", vars.getLanguage())); final XmlDocument xmlDocument = xmlEngine .readXmlTemplate("org/openbravo/erpCommon/ad_forms/ModuleManagement_UpgradeInfo", discard) .createXmlDocument(); xmlDocument.setParameter("messageType", msg.getType()); xmlDocument.setParameter("messageTitle", msg.getTitle()); xmlDocument.setParameter("messageMessage", msg.getMessage()); xmlDocument.setParameter("directory", "var baseDirectory = \"" + strReplaceWith + "/\";\n"); xmlDocument.setParameter("language", "defaultLang=\"" + vars.getLanguage() + "\";"); xmlDocument.setParameter("theme", vars.getTheme()); xmlDocument.setParameter("moduleID", moduleId); xmlDocument.setParameter("upgradeVersion", version); xmlDocument.setData("updateNeeded", FieldProviderFactory.getFieldProviderArray(requiredUpdates)); response.setContentType("text/html; charset=UTF-8"); final PrintWriter out = response.getWriter(); out.println(xmlDocument.print()); out.close(); return; } } catch (Exception e) { log4j.error("Error getting upgrade pre requisites", e); } // All pre-checks were successful, now start with the upgrade try { HashMap<String, String> additionalInfo = ModuleUtiltiy.getSystemMaturityLevels(false); additionalInfo.put("upgrade.module", moduleId); additionalInfo.put("upgrade.version", version); additionalInfo.put("upgrade.aprm", usingAprm); final ImportModule im = new ImportModule(this, vars.getSessionValue("#sourcePath"), vars); im.setInstallLocal(false); im.checkDependenciesId(new String[0], new String[0], additionalInfo); if (im.isUpgradePrecheckFail()) { printPageUpgradeError(response, request, new JSONArray(im.getDependencyErrors()[1])); } else { // Continue with standard update printPageInstall1(response, request, vars, "0", false, null, new String[] { "0" }, ModuleUtiltiy.getSystemMaturityLevels(false), im); } } catch (Exception e) { log4j.error("Error on upgrade", e); } } } private void printPageUpgradeError(HttpServletResponse response, HttpServletRequest request, JSONArray upgradeErrors) throws IOException, JSONException { final VariablesSecureApp vars = new VariablesSecureApp(request); List<Map<String, String>> deps = new ArrayList<Map<String, String>>(); List<Map<String, String>> mats = new ArrayList<Map<String, String>>(); String msgDepGeneric = Utility.messageBD(this, "Dependency", vars.getLanguage()); String accepetedMaturity; HashMap<String, String> maturities = ModuleUtiltiy.getSystemMaturityLevels(true); if ("true".equals(maturities.get("isProfessional")) && Integer.toString(MaturityLevel.CS_MATURITY).equals(maturities.get("update.level"))) { // Community instances use CR as maximum restriction for maturity accepetedMaturity = "200"; } else { accepetedMaturity = maturities.get("update.level"); } for (int i = 0; i < upgradeErrors.length(); i++) { JSONObject mod = upgradeErrors.getJSONObject(i); Map<String, String> error = new HashMap<String, String>(); String modId = mod.getString("module"); String name; if (!mod.getString("name").isEmpty()) { name = mod.getString("name"); } else { org.openbravo.model.ad.module.Module m = OBDal.getInstance() .get(org.openbravo.model.ad.module.Module.class, modId); if (m != null) { name = m.getName(); } else { name = modId; } } JSONArray errors = mod.getJSONArray("errors"); String msg = ""; boolean isDepError = mod.has("type") && "deps".equals(mod.getString("type")); if (isDepError) { // dependency error String latestVersion = ""; if (mod.has("latestVersion")) { latestVersion = Utility.messageBD(this, "latestVerDep", vars.getLanguage()).replace("%0", mod.getString("latestVersion")); } msg += latestVersion + " "; String coreDep = ""; String otherDeps = ""; String unknownDeps = ""; for (int e = 0; e < errors.length(); e++) { JSONObject err = errors.getJSONObject(e); String code = err.has("errorCode") ? err.getString("errorCode") : ""; if (code.isEmpty()) { log4j.warn("Unknown upgrade error:" + err.toString()); } String dep = ""; if (err.has("dependency")) { JSONObject dependency = err.getJSONObject("dependency"); String depModName; if (dependency.has("moduleName")) { depModName = dependency.getString("moduleName"); } else { String depModID = dependency.getString("moduleId"); org.openbravo.model.ad.module.Module module = OBDal.getInstance() .get(org.openbravo.model.ad.module.Module.class, depModID); if (module == null) { depModName = depModID; } else { depModName = module.getName(); } } String depVersion = dependency.getString("firstVersion") + (dependency.has("lastVersion") ? " - " + dependency.getString("lastVersion") : ""); dep = msgDepGeneric.replace("%0", depModName).replace("%1", depVersion); if (!"MAJOR".equals(dependency.getString("enforcement"))) { dep += " " + Utility.messageBD(this, err.getString("errorCode"), vars.getLanguage()) .replace("%0", dependency.getString("enforcement")); } if ("No3.0CoreDep".equals(code)) { coreDep += dep; } else if ("No3.0Dependency".equals(code)) { if (!otherDeps.isEmpty()) { otherDeps += ", "; } otherDeps += dep; } else { String unknownMsg = Utility.messageBD(this, err.getString("errorCode"), vars.getLanguage()); if (unknownMsg.equals(err.getString("errorCode"))) { unknownMsg = err.getString("message"); } else if (err.has("isMaturity") && err.getBoolean("isMaturity")) { unknownMsg = unknownMsg.replace("%0", err.getString("minMaturityRequired")) .replace("%1", err.getString("maxMaturityAvailable")); } unknownDeps += " " + unknownMsg; } } } msg += coreDep; if (!otherDeps.isEmpty()) { otherDeps = Utility.messageBD(this, "otherDeps", vars.getLanguage()).replace("%0", otherDeps); if (!coreDep.isEmpty()) { msg += " " + Utility.messageBD(this, "And", vars.getLanguage()); } msg += " " + otherDeps; } if (!unknownDeps.isEmpty()) { msg += " " + unknownDeps; } } else { // maturity error for (int e = 0; e < errors.length(); e++) { JSONObject err = errors.getJSONObject(e); String code = err.has("errorCode") ? err.getString("errorCode") : ""; if (code.isEmpty()) { log4j.warn("Unknown upgrade error:" + err.toString()); } String m; if ("No3.0DependencyWithMaturity".equals(code) && accepetedMaturity.equals(err.getString("minMaturityRequiredCode"))) { m = Utility.messageBD(this, "No3.0DependencyWithMaturitySameLevel", vars.getLanguage()) .replace("%0", err.getString("maxMaturityAvailable")); } else { m = Utility.messageBD(this, err.getString("errorCode"), vars.getLanguage()); if (m.equals(err.getString("errorCode"))) { m = err.getString("message"); } else if (err.has("isMaturity") && err.getBoolean("isMaturity")) { m = m.replace("%0", err.getString("minMaturityRequired")).replace("%1", err.getString("maxMaturityAvailable")); } } msg += " " + m; } } msg += "."; error.put("msg", msg); error.put("name", name); if (isDepError) { deps.add(error); } else { mats.add(error); } } String discard[] = { deps.isEmpty() ? "deps" : "", mats.isEmpty() ? "maturity" : "" }; final XmlDocument xmlDocument = xmlEngine .readXmlTemplate("org/openbravo/erpCommon/ad_forms/ModuleManagement_ErrorUpgrade", discard) .createXmlDocument(); if (!mats.isEmpty()) { String level = new MaturityLevel().getLevelName(accepetedMaturity); xmlDocument.setParameter("instanceMat", level); } xmlDocument.setParameter("directory", "var baseDirectory = \"" + strReplaceWith + "/\";\n"); xmlDocument.setParameter("language", "defaultLang=\"" + vars.getLanguage() + "\";"); xmlDocument.setParameter("theme", vars.getTheme()); xmlDocument.setData("deps", FieldProviderFactory.getFieldProviderArray(deps)); xmlDocument.setData("maturity", FieldProviderFactory.getFieldProviderArray(mats)); response.setContentType("text/html; charset=UTF-8"); final PrintWriter out = response.getWriter(); out.println(xmlDocument.print()); out.close(); } /** * Shows the first pop-up for the installation process, where it is displayed the modules to * install/update and an error message in case it is not possible to install the selected one or a * warning message in case the selected version is not installable but it is possible to install * another one. * */ private void printPageInstall1(HttpServletResponse response, HttpServletRequest request, VariablesSecureApp vars, String recordId, boolean islocal, InputStream obx, String[] updateModules, HashMap<String, String> maturityLevels, ImportModule upgradeIM) throws IOException, ServletException { final String discard[] = { "", "", "", "", "", "", "warnMaturity", "", "missingDeps" }; Module module = null; // Remote installation is only allowed for heartbeat enabled instances if (!islocal && !HeartbeatProcess.isHeartbeatEnabled()) { String inpcRecordId = recordId; String command = "DEFAULT"; if (updateModules != null && updateModules.length > 0 && !updateModules[0].equals("")) { if (updateModules.length == 1) { // User clicked "Install Now" from the module description inpcRecordId = updateModules[0]; } else { inpcRecordId = UPDATE_ALL_RECORD_ID; } command = "UPDATE"; } response.sendRedirect(strDireccion + "/ad_forms/Heartbeat.html?Command=" + command + "_MODULE&inpcRecordId=" + inpcRecordId); return; } String localChanges = verifyLocalChanges(vars); if (localChanges != null) { final PrintWriter out = response.getWriter(); final String discardlc[] = {}; final XmlDocument xmlDocument = xmlEngine .readXmlTemplate("org/openbravo/erpCommon/ad_forms/ModuleManagement_LocalChanges", discardlc) .createXmlDocument(); xmlDocument.setParameter("directory", "var baseDirectory = \"" + strReplaceWith + "/\";\n"); xmlDocument.setParameter("language", "defaultLang=\"" + vars.getLanguage() + "\";"); xmlDocument.setParameter("theme", vars.getTheme()); xmlDocument.setParameter("welcome", Replace.replace(localChanges, "\\n", "<br/>")); out.println(xmlDocument.print()); out.close(); return; } if (upgradeIM != null) { for (Module mod : upgradeIM.getModulesToUpdate()) { if (mod.getModuleID().equals(ModuleUtiltiy.TEMPLATE_30)) { module = mod; } } } else if (!islocal && (updateModules == null || updateModules.length == 0)) { // if it is a remote installation get the module from webservice, // other case the obx file is passed as an InputStream try { if (HttpsUtils.isInternetAvailable()) { final WebService3ImplServiceLocator loc = new WebService3ImplServiceLocator(); final WebService3Impl ws = loc.getWebService3(); module = ws.moduleDetail(recordId); } } catch (final Exception e) { log4j.error("Error obtaining module info", e); } } else { discard[4] = "core"; } Module[] inst = null; Module[] upd = null; Module[] merges = null; OBError message = null; boolean found = false; boolean check = false; // to hold (key,value) = (moduleId, minVersion) Map<String, String> minVersions = new HashMap<String, String>(); VersionUtility.setPool(this); // Create a new ImportModule instance which will be used to check // dependencies and to process the installation ImportModule im; if (upgradeIM == null) { im = new ImportModule(this, vars.getSessionValue("#sourcePath"), vars); } else { im = upgradeIM; } im.setInstallLocal(islocal); try { // check the dependencies and obtain the modules to install/update if (upgradeIM != null) { check = im.isChecked(); } if (!islocal) { final String[] installableModules = { module != null ? module.getModuleVersionID() : "" }; if (upgradeIM == null) { check = im.checkDependenciesId(installableModules, updateModules, maturityLevels); } } else { check = im.checkDependenciesFile(obx); } if (islocal || check) { // dependencies are satisfied or local installation, show modules to install. If local // installation and dependencies are not ok show warning. // installOrig includes also the module to install final Module[] installOrig = im.getModulesToInstall(); if (installOrig == null || installOrig.length == 0) discard[0] = "modulesToinstall"; else { if (!islocal && module != null) { inst = new Module[installOrig.length - 1]; // to remove // the module // itself // check if the version for the selected module is the // selected one int j = 0; for (int i = 0; i < installOrig.length; i++) { found = installOrig[i].getModuleID().equals(module.getModuleID()); if (found && !module.getModuleVersionID().equals(installOrig[i].getModuleVersionID())) { message = new OBError(); message.setType("Warning"); message.setTitle(Utility.messageBD(this, message.getType(), vars.getLanguage())); message.setMessage(module.getName() + " " + module.getVersionNo() + " " + Utility.messageBD(this, "OtherModuleVersionToInstall", vars.getLanguage()) + " " + installOrig[i].getVersionNo()); } if (found) { module = installOrig[i]; } else { inst[j] = installOrig[i]; j++; } } } else { inst = installOrig; } } upd = im.getModulesToUpdate(); // after all the checks, save the ImportModule object in session // to take it in next steps vars.setSessionObject("InstallModule|ImportModule", im); // calculate minimum required version of each extra module (installs & updates) minVersions = calcMinVersions(im); if (module == null) { // set the selected module for obx installation if (installOrig != null && installOrig.length > 0) { module = installOrig[0]; } else { Module[] modsToUpdate = im.getModulesToUpdate(); if (modsToUpdate != null && modsToUpdate.length > 0) { module = modsToUpdate[0]; } } } // check commercial modules and show error page if not allowed to install if (!checkCommercialModules(im, minVersions, response, vars, module)) { return; } // Show warning message when installing/updating modules not in General availability level if (!islocal) { if (module != null && !Integer.toString(MaturityLevel.CS_MATURITY) .equals(module.getAdditionalInfo().get("maturity.level"))) { discard[6] = ""; } else { if (inst != null) { for (Module m : inst) { if (!Integer.toString(MaturityLevel.CS_MATURITY) .equals(m.getAdditionalInfo().get("maturity.level"))) { discard[6] = ""; } } } if (upd != null) { for (Module m : upd) { if (!Integer.toString(MaturityLevel.CS_MATURITY) .equals(m.getAdditionalInfo().get("maturity.level"))) { discard[6] = ""; } } } } } // Add additional messages that can come from CR OBError additionalMsg = im.getCheckError(); if (!additionalMsg.getMessage().isEmpty()) { if (message == null) { message = new OBError(); message.setType("Info"); message.setTitle(Utility.messageBD(this, message.getType(), vars.getLanguage())); } else { message.setMessage(message.getMessage() + "\n"); } message.setMessage(message.getMessage() + additionalMsg.getMessage()); if (!check) { discard[8] = ""; // show missing dependencies message message.setType("Warning"); message.setTitle(Utility.messageBD(this, "DependenciesNotSatisfied", vars.getLanguage())); } } } else { // Dependencies not satisfied, do not show continue button message = im.getCheckError(); discard[5] = "discardContinue"; if (!islocal) { // installing/updating a module from CR. Let's check if local dependencies are OK boolean locallyOk = true; OBError localDepsMsg = new OBError(); try { locallyOk = VersionUtility.checkLocal(vars, new Module[0], new Module[0], new Module[0], localDepsMsg); } catch (Exception e) { log4j.error("Error checking local dependencies", e); } if (!locallyOk) { if (!StringUtils.isEmpty(localDepsMsg.getMessage())) { String localErrorsMsg = "<br><b>" + OBMessageUtils.messageBD("ModuleLocalDepErrorsTitle") + "</b><br>" + OBMessageUtils.messageBD("ModuleLocalDepErrorsExplain") + "<ul>"; for (String localError : localDepsMsg.getMessage().split("\\n")) { localErrorsMsg += "<li>" + StringEscapeUtils.escapeHtml(localError); } localErrorsMsg += "</ul>"; if (message == null || message.getMessage() == null || message.getMessage().isEmpty()) { message = localDepsMsg; message.setMessage(localErrorsMsg); } else { message.setMessage(message.getMessage() + "<br>" + localErrorsMsg); } } } } if (message == null || message.getMessage() == null || message.getMessage().isEmpty()) { // No message: set generic one message = new OBError(); message.setType("Error"); message.setTitle(Utility.messageBD(this, message.getType(), vars.getLanguage())); message.setMessage(Utility.messageBD(this, "ModulesNotInstallable", vars.getLanguage())); } } if (upd == null || upd.length == 0) discard[1] = "updateModules"; if (inst == null || inst.length == 0) discard[2] = "installModules"; if ((upd == null || upd.length == 0) && (inst == null || inst.length == 0) && (module == null)) { discard[3] = "discardAdditional"; discard[5] = "discardContinue"; } merges = im.getModulesToMerge(); if (merges == null || merges.length == 0) { discard[7] = "mergeModules"; } } catch (final Exception e) { log4j.error(e.getMessage(), e); message = new OBError(); message.setType("Error"); message.setTitle(Utility.messageBD(this, message.getType(), vars.getLanguage())); message.setMessage(e.toString()); } final XmlDocument xmlDocument = xmlEngine .readXmlTemplate("org/openbravo/erpCommon/ad_forms/ModuleManagement_InstallP1", discard) .createXmlDocument(); xmlDocument.setParameter("directory", "var baseDirectory = \"" + strReplaceWith + "/\";\n"); xmlDocument.setParameter("language", "defaultLang=\"" + vars.getLanguage() + "\";"); xmlDocument.setParameter("theme", vars.getTheme()); if (inst != null && inst.length > 0) { xmlDocument.setData("installs", getModuleFieldProvider(inst, minVersions, false, vars.getLanguage(), islocal)); } if (upd != null && upd.length > 0) { xmlDocument.setData("updates", getModuleFieldProvider(upd, minVersions, true, vars.getLanguage(), islocal)); } if (merges != null && merges.length > 0) { xmlDocument.setData("merges", getMergesFieldProvider(merges)); } xmlDocument.setParameter("inpLocalInstall", islocal ? "Y" : "N"); if (!islocal && module != null) { xmlDocument.setParameter("key", recordId); xmlDocument.setParameter("moduleID", module.getModuleID()); xmlDocument.setParameter("moduleName", module.getName()); xmlDocument.setParameter("moduleVersion", module.getVersionNo()); xmlDocument.setParameter("linkCore", module.getModuleVersionID()); if (!check || Integer.toString(MaturityLevel.CS_MATURITY) .equals(module.getAdditionalInfo().get("maturity.level"))) { xmlDocument.setParameter("maturityStyle", "none"); } else { xmlDocument.setParameter("maturityStyle", "yes"); xmlDocument.setParameter("maturityLevel", (String) module.getAdditionalInfo().get("maturity.name")); } } { if (message != null) { xmlDocument.setParameter("messageType", message.getType()); xmlDocument.setParameter("messageTitle", message.getTitle()); xmlDocument.setParameter("messageMessage", message.getMessage()); } } response.setContentType("text/html; charset=UTF-8"); final PrintWriter out = response.getWriter(); out.println(xmlDocument.print()); out.close(); } /** * Obtains a FieldProvider to display the merged modules. */ private FieldProvider[] getMergesFieldProvider(Module[] merges) { List<Map<String, String>> rt = new ArrayList<Map<String, String>>(); for (Module merge : merges) { Map<String, String> mod = new HashMap<String, String>(); mod.put("mergedModule", merge.getName()); mod.put("mergedWith", (String) merge.getAdditionalInfo().get("mergedWith")); rt.add(mod); } return FieldProviderFactory.getFieldProviderArray(rt); } private FieldProvider[] getModuleFieldProvider(Module[] inst, Map<String, String> minVersions, boolean installed, String lang, boolean islocal) { ArrayList<HashMap<String, String>> rt = new ArrayList<HashMap<String, String>>(); for (Module module : inst) { HashMap<String, String> mod = new HashMap<String, String>(); mod.put("name", module.getName()); mod.put("versionNo", module.getVersionNo()); mod.put("moduleVersionID", module.getModuleVersionID()); if (installed) { if (minVersions != null && minVersions.get(module.getModuleID()) != null && !minVersions.get(module.getModuleID()).equals("")) { /* * Checking whether the module version is the same as the minimum version number. Refer * issue https://issues.openbravo.com/view.php?id=13576 */ String versionNumber = this.removeVersionLabel(module.getVersionNo()); Boolean moduleVersionSameAsMinimumVersion = versionNumber .equals(minVersions.get(module.getModuleID())); if (!moduleVersionSameAsMinimumVersion) { mod.put("versionNoMin", Utility.messageBD(this, "UpdateModuleNeed", lang) + " " + minVersions.get(module.getModuleID())); } } mod.put("versionNoCurr", currentInstalledVersion(module.getModuleID())); } else { mod.put("versionNoMin", (minVersions.get(module.getModuleID()) == null ? module.getVersionNo() : minVersions.get(module.getModuleID()))); } if (!islocal) { if (Integer.toString(MaturityLevel.CS_MATURITY) .equals(module.getAdditionalInfo().get("maturity.level"))) { mod.put("maturityStyle", "none"); } else { mod.put("maturityStyle", "yes"); mod.put("maturityLevel", (String) module.getAdditionalInfo().get("maturity.name")); } } rt.add(mod); } return FieldProviderFactory.getFieldProviderArray(rt); } /* * The version number of module returned by web service has the MP tag attached to it. To compare * with the minimum version, we are removing the tag. eg., Openbravo 3.0 3.0.17885 (MP15) to * Openbravo 3.0 3.0.17885. Related to Issue https://issues.openbravo.com/view.php?id=13576 */ private String removeVersionLabel(String versionWithLabel) { return versionWithLabel.split("\\(")[0].trim(); } private String currentInstalledVersion(String moduleId) { String currentVersion = ""; org.openbravo.model.ad.module.Module mod = OBDal.getInstance() .get(org.openbravo.model.ad.module.Module.class, moduleId); if (mod != null) { currentVersion = currentVersion.concat( " (" + (mod.getVersionLabel() != null ? mod.getVersionLabel() : mod.getVersion()) + ")"); } return currentVersion; } /** * calculate minimum required version for each module in consistent set of (installs, updates) * returned by a checkConsistency call * * @param im */ private Map<String, String> calcMinVersions(ImportModule im) { // (key,value) = (moduleId, minRequiredVersion) Map<String, String> minVersions = new HashMap<String, String>(); for (Module m : im.getModulesToInstall()) { calcMinVersionFromDeps(minVersions, m.getDependencies()); if (m.getIncludes() != null) { calcMinVersionFromDeps(minVersions, m.getIncludes()); } } for (Module m : im.getModulesToUpdate()) { calcMinVersionFromDeps(minVersions, m.getDependencies()); if (m.getIncludes() != null) { calcMinVersionFromDeps(minVersions, m.getIncludes()); } } // check and show: for (Module m : im.getModulesToInstall()) { log4j.debug("Install module " + m.getName() + " in version " + m.getVersionNo() + ", required is version >=" + minVersions.get(m.getModuleID())); } for (Module m : im.getModulesToUpdate()) { log4j.debug("Updating module " + m.getName() + " in version " + m.getVersionNo() + ", required is version >=" + minVersions.get(m.getModuleID())); } return minVersions; } /** * Utility method which processes a list of dependencies and fills a Map of (moduleID, minVersion) * * @param minVersions * in/out-parameter with map of (moduleID, minVersion) * @param deps * array of dependency entries */ private static void calcMinVersionFromDeps(Map<String, String> minVersions, ModuleDependency[] deps) { for (ModuleDependency md : deps) { String oldMinVersion = minVersions.get(md.getModuleID()); VersionComparator vc = new VersionComparator(); if (oldMinVersion == null || vc.compare(oldMinVersion, md.getVersionStart()) < 0) { minVersions.put(md.getModuleID(), md.getVersionStart()); } } } /** * Verifies the commercial modules to be installed/updated and shows an error message with the * actions to be taken in case some of them cannot be installed due to license restrictions. */ private boolean checkCommercialModules(ImportModule im, Map<String, String> minVersions, HttpServletResponse response, VariablesSecureApp vars, Module selectedModule) throws IOException { // get the list of all commercial modules that are not allowed in this instance List<Module> notAllowedModules = getNotAllowedModules(im.getModulesToInstall()); notAllowedModules.addAll(getNotAllowedModules(im.getModulesToUpdate())); if (notAllowedModules.isEmpty()) { // all modules are allowed, continue the installation without error return true; } String discard[] = { "", "", "", "", "", "" }; ActivationKey ak = ActivationKey.getInstance(); // check if the only module is core as a dependency of another one String minCoreVersion = ""; List<Module> modulesToAcquire = getModulesToAcquire((ArrayList<Module>) notAllowedModules); if (notAllowedModules.size() == 1 && !"0".equals(selectedModule.getModuleID()) && "0".equals(notAllowedModules.get(0).getModuleID())) { discard[0] = "OBPSInstance-Canceled"; discard[1] = "actionList"; minCoreVersion = minVersions.get("0"); } else { discard[0] = "installCore"; // check canceled instance if (ak.getSubscriptionStatus() == SubscriptionStatus.CANCEL) { discard[1] = "actionList"; // show all commercial modules, not only the ones that should be paid modulesToAcquire = notAllowedModules; } else { discard[1] = "OBPSInstance-Canceled"; } // Decide license type, if any int maxTier = getMaxTier(notAllowedModules); LicenseClass licenseEdition = ak.getLicenseClass(); if (!ak.isActive()) { if (maxTier == 1) { // show subscribe to Basic discard[2] = "subscribeSTD"; discard[3] = "upgradeSTD"; } else { // show subscribe to Standard discard[2] = "subscribeBAS"; discard[3] = "upgradeSTD"; } } else if (licenseEdition == LicenseClass.BASIC) { discard[2] = "subscribeBAS"; discard[3] = "subscribeSTD"; if (maxTier == 1) { // do not show license action discard[4] = "upgradeSTD"; } else { // show upgrade to Standard } } else if (licenseEdition == LicenseClass.STD) { // do not show license action discard[2] = "subscribeBAS"; discard[3] = "subscribeSTD"; discard[4] = "upgradeSTD"; } } if (modulesToAcquire.isEmpty()) { discard[5] = "acquireModules"; } XmlDocument xmlDocument = xmlEngine .readXmlTemplate("org/openbravo/erpCommon/ad_forms/ModuleManagement_ErrorCommercial", discard) .createXmlDocument(); xmlDocument.setParameter("directory", "var baseDirectory = \"" + strReplaceWith + "/\";\n"); xmlDocument.setParameter("language", "defaultLang=\"" + vars.getLanguage() + "\";"); xmlDocument.setParameter("theme", vars.getTheme()); xmlDocument.setParameter("minCoreVersion", minCoreVersion); xmlDocument.setData("notAllowedModules", FieldProviderFactory.getFieldProviderArray(modulesToAcquire)); response.setContentType("text/html; charset=UTF-8"); final PrintWriter out = response.getWriter(); out.println(xmlDocument.print()); out.close(); return false; } /** * Returns the list of modules which license must be acquired to be installed in the instance. * Currently it only removes core from the list of not allowed modules because it is not needed to * acquire a license for the module, just the Professional Subscription. It could be implemented * to remove also all the free commercial modules, in case this info came from CR. * * @param notAllowedModules * List with all the not allowed commercial modules * @return List with all the commercial modules that need a license to be acquired */ @SuppressWarnings("unchecked") private List<Module> getModulesToAcquire(ArrayList<Module> notAllowedModules) { List<Module> rt = (List<Module>) notAllowedModules.clone(); for (Module mod : rt) { if ("0".equals(mod.getModuleID())) { rt.remove(mod); break; } } return rt; } /** * Returns the maximum tier of the commercial modules passed as parameter. * * @param modulesToCheck * @return The maximum tier of the modules (1 or 2) */ private int getMaxTier(List<Module> modulesToCheck) { for (Module mod : modulesToCheck) { String modTier = (String) mod.getAdditionalInfo().get("tier"); if ("2".equals(modTier)) { return 2; } } return 1; } /** * Checks from the array of commercial modules passed as parameter, which ones are not allowed to * be installed in the instance and returns this list. * * @param modulesToCheck * @return List of modules that cannot be installed in the instance */ private List<Module> getNotAllowedModules(Module[] modulesToCheck) { ArrayList<Module> notAllowedModules = new ArrayList<Module>(); ActivationKey ak = ActivationKey.getInstance(); for (Module mod : modulesToCheck) { if (mod.isIsCommercial() && (!ak.isActive() || ak.isModuleSubscribed(mod.getModuleID()) != CommercialModuleStatus.ACTIVE)) { notAllowedModules.add(mod); } } return notAllowedModules; } /** * Shows the second installation pup-up with all the license agreements for the modules to * install/update * * @param response * @param vars * @throws IOException * @throws ServletException */ private void printPageInstall2(HttpServletResponse response, VariablesSecureApp vars) throws IOException, ServletException { Module[] inst = null; Module[] selected; // Obtain the session object with the modules to install/update final ImportModule im = (ImportModule) vars.getSessionObject("InstallModule|ImportModule"); final Module[] installOrig = im.getModulesToInstall(); final Module[] upd = im.getModulesToUpdate(); final String adModuleId = vars.getStringParameter("inpModuleID"); // selected // module // to // install final boolean islocal = im.getIsLocal(); if (!islocal) { selected = new Module[1]; inst = new Module[installOrig.length == 0 ? 0 : adModuleId.equals("") ? installOrig.length : installOrig.length - 1]; // to // remove // the // module // itself // check if the version for the selected module is the selected one int j = 0; for (int i = 0; i < installOrig.length; i++) { final boolean found = installOrig[i].getModuleID().equals(adModuleId); if (found) { selected[0] = installOrig[i]; } else { inst[j] = installOrig[i]; j++; } } } else { if (!im.isChecked()) { im.setForce(true); } selected = installOrig; } final String discard[] = { "", "", "" }; if (inst == null || inst.length == 0) discard[0] = "moduleIntallation"; if (upd == null || upd.length == 0) discard[1] = "moduleUpdate"; if (selected == null || selected.length == 0 || selected[0] == null) discard[2] = "moduleSelected"; final XmlDocument xmlDocument = xmlEngine .readXmlTemplate("org/openbravo/erpCommon/ad_forms/ModuleManagement_InstallP2", discard) .createXmlDocument(); // Set positions to names in order to be able to use keyboard for // navigation in the box int position = 1; if (selected != null && selected.length > 0 && selected[0] != null) { final FieldProvider[] fp = FieldProviderFactory.getFieldProviderArray(selected); for (int i = 0; i < fp.length; i++) FieldProviderFactory.setField(fp[i], "position", new Integer(position++).toString()); xmlDocument.setData("selected", fp); } if (inst != null && inst.length > 0) { final FieldProvider[] fp = FieldProviderFactory.getFieldProviderArray(inst); for (int i = 0; i < fp.length; i++) FieldProviderFactory.setField(fp[i], "position", new Integer(position++).toString()); xmlDocument.setData("installs", fp); } if (upd != null && upd.length > 0) { final FieldProvider[] fp = FieldProviderFactory.getFieldProviderArray(upd); for (int i = 0; i < fp.length; i++) FieldProviderFactory.setField(fp[i], "position", new Integer(position++).toString()); xmlDocument.setData("updates", fp); } xmlDocument.setParameter("directory", "var baseDirectory = \"" + strReplaceWith + "/\";\n"); xmlDocument.setParameter("language", "defaultLang=\"" + vars.getLanguage() + "\";"); xmlDocument.setParameter("theme", vars.getTheme()); response.setContentType("text/html; charset=UTF-8"); final PrintWriter out = response.getWriter(); out.println(xmlDocument.print()); out.close(); } /** * Shows the third pup-up for the installation process, in this popup the installation is executed * and afterwards a message is displayed with the success or fail information. * * @param response * @param vars * @throws IOException * @throws ServletException */ private void printPageInstall3(HttpServletResponse response, VariablesSecureApp vars) throws IOException, ServletException { final ImportModule im = (ImportModule) vars.getSessionObject("InstallModule|ImportModule"); final XmlDocument xmlDocument = xmlEngine .readXmlTemplate("org/openbravo/erpCommon/ad_forms/ModuleManagement_InstallP4").createXmlDocument(); xmlDocument.setParameter("directory", "var baseDirectory = \"" + strReplaceWith + "/\";\n"); xmlDocument.setParameter("language", "defaultLang=\"" + vars.getLanguage() + "\";"); xmlDocument.setParameter("theme", vars.getTheme()); OBError message; if (im.getIsLocal()) im.execute(((FileItem) vars.getSessionObject("ModuleManagementInstall|File")).getInputStream()); else im.execute(); message = im.getOBError(this); { if (message != null) { xmlDocument.setParameter("messageType", message.getType()); xmlDocument.setParameter("messageTitle", message.getTitle()); if (message.getType().equalsIgnoreCase("error")) { message.setMessage(message.getMessage() + "<br/>" + Utility.messageBD(this, "CheckUpdateTips", vars.getLanguage(), false)); } xmlDocument.setParameter("messageMessage", message.getMessage()); } } vars.removeSessionValue("ModuleManagementInstall|File"); vars.removeSessionValue("InstallModule|ImportModule"); response.setContentType("text/html; charset=UTF-8"); final PrintWriter out = response.getWriter(); out.println(xmlDocument.print()); out.close(); } /** * Executes a search query in the web service and returns a HTML with the list of modules * retrieved from the query. This list is HTML with styles. */ private String getSearchResults(HttpServletRequest request, HttpServletResponse response, VariablesSecureApp vars, String text) { SimpleModule[] modules = null; try { if (!HttpsUtils.isInternetAvailable()) { final OBError message = new OBError(); message.setType("Error"); message.setTitle(Utility.messageBD(this, "Error", vars.getLanguage())); message.setMessage(Utility.messageBD(this, "WSError", vars.getLanguage())); vars.setMessage("ModuleManagement", message); try { response.sendRedirect(strDireccion + request.getServletPath() + "?Command=ADD_NOSEARCH"); } catch (final Exception ex) { log4j.error(ex.getMessage(), ex); } } final WebService3ImplServiceLocator loc = new WebService3ImplServiceLocator(); final WebService3Impl ws = loc.getWebService3(); // Stub stub = (javax.xml.rpc.Stub) ws; // stub._setProperty(Stub.USERNAME_PROPERTY, "test"); // stub._setProperty(Stub.PASSWORD_PROPERTY, "1"); HashMap<String, String> maturitySearch = new HashMap<String, String>(); maturitySearch.put("search.level", getSystemMaturity(false)); modules = ws.moduleSearch(text, getInstalledModules(), maturitySearch); } catch (final Exception e) { final OBError message = new OBError(); message.setType("Error"); message.setTitle(Utility.messageBD(this, "Error", vars.getLanguage())); message.setMessage(Utility.messageBD(this, "WSError", vars.getLanguage())); vars.setMessage("ModuleManagement", message); log4j.error("Error searching modules", e); try { response.sendRedirect(strDireccion + request.getServletPath() + "?Command=ADD_NOSEARCH"); } catch (final Exception ex) { log4j.error("error searching modules", ex); } } FieldProvider[] modulesBox = new FieldProvider[0]; if (modules != null && modules.length > 0) { modulesBox = new FieldProvider[modules.length]; int i = 0; for (SimpleModule mod : modules) { HashMap<String, String> moduleBox = new HashMap<String, String>(); // set different icon depending on module type String icon = mod.getType(); icon = (icon == null ? "M" : icon).equals("M") ? "Module" : icon.equals("T") ? "Template" : "Pack"; moduleBox.put("name", mod.getName()); moduleBox.put("description", mod.getDescription()); moduleBox.put("type", icon); moduleBox.put("help", mod.getHelp()); // If there is no url, we need to hide the 'Visit Site' link and separator. if (mod.getUrl() == null || mod.getUrl().equals("")) { moduleBox.put("urlStyle", "none"); } else { moduleBox.put("url", getLink(mod.getUrl())); moduleBox.put("urlStyle", "true"); } moduleBox.put("moduleVersionID", mod.getModuleVersionID()); moduleBox.put("commercialStyle", (mod.isIsCommercial() ? "true" : "none")); @SuppressWarnings("unchecked") HashMap<String, String> additioanlInfo = mod.getAdditionalInfo(); if (additioanlInfo != null && !Integer.toString(MaturityLevel.CS_MATURITY) .equals(additioanlInfo.get("maturity.level"))) { // Display module's maturity in case it is not General availability (500) moduleBox.put("maturityStyle", "true"); moduleBox.put("maturityLevel", additioanlInfo.get("maturity.name")); } else { moduleBox.put("maturityStyle", "none"); } modulesBox[i] = FieldProviderFactory.getFieldProvider(moduleBox); i++; } } final XmlDocument xmlDocument = xmlEngine.readXmlTemplate("org/openbravo/erpCommon/modules/ModuleBox") .createXmlDocument(); xmlDocument.setData("structureBox", modulesBox); return xmlDocument.print(); } /** * Returns String[] with the installed modules, this is used for perform the search in the * webservice and not to obtain in the list the already installed ones. */ private String[] getInstalledModules() { try { final ModuleManagementData data[] = ModuleManagementData.selectInstalled(this); if (data != null && data.length != 0) { final String[] rt = new String[data.length]; for (int i = 0; i < data.length; i++) rt[i] = data[i].adModuleId; return rt; } else return new String[0]; } catch (final Exception e) { log4j.error(e.getMessage(), e); return (new String[0]); } } private String[] getUpdateableModules() { try { final ModuleManagementData data[] = ModuleManagementData.selectUpdateable(this); if (data != null && data.length != 0) { final String[] rt = new String[data.length]; for (int i = 0; i < data.length; i++) rt[i] = data[i].adModuleVersionId; return rt; } else return new String[0]; } catch (final Exception e) { log4j.error(e.getMessage(), e); return (new String[0]); } } /** * This ajax call displays the license agreement for a module. * * @param response * @param vars * @param record * @throws IOException * @throws ServletException */ private void printLicenseAgreement(HttpServletResponse response, VariablesSecureApp vars, String record) throws IOException, ServletException { if (log4j.isDebugEnabled()) log4j.debug("Output: ajaxreponse"); response.setContentType("text/plain; charset=UTF-8"); response.setHeader("Cache-Control", "no-cache"); final PrintWriter out = response.getWriter(); final ImportModule im = (ImportModule) vars.getSessionObject("InstallModule|ImportModule"); final Module[] inst = im.getModulesToInstall(); final Module[] upd = im.getModulesToUpdate(); int i = 0; boolean found = false; String agreement = ""; while (!found && inst != null && i < inst.length) { if (found = inst[i].getModuleID().equals(record)) agreement = inst[i].getLicenseAgreement(); i++; } i = 0; while (!found && upd != null && i < upd.length) { if (found = upd[i].getModuleID().equals(record)) agreement = upd[i].getLicenseAgreement(); i++; } out.println(agreement); out.close(); } /** * Displays the pop-up for the search locally file in order to look for an obx file and to install * it locally. * * @param response * @param vars * @throws IOException * @throws ServletException */ private void printSearchFile(HttpServletResponse response, VariablesSecureApp vars, OBError message) throws IOException, ServletException { final XmlDocument xmlDocument = xmlEngine .readXmlTemplate("org/openbravo/erpCommon/ad_forms/ModuleManagement_InstallLocal") .createXmlDocument(); xmlDocument.setParameter("directory", "var baseDirectory = \"" + strReplaceWith + "/\";\n"); xmlDocument.setParameter("language", "defaultLang=\"" + vars.getLanguage() + "\";"); xmlDocument.setParameter("theme", vars.getTheme()); if (message != null) { xmlDocument.setParameter("messageType", message.getType()); xmlDocument.setParameter("messageTitle", message.getTitle()); xmlDocument.setParameter("messageMessage", message.getMessage()); } response.setContentType("text/html; charset=UTF-8"); final PrintWriter out = response.getWriter(); out.println(xmlDocument.print()); out.close(); } private void printScan(HttpServletResponse response, VariablesSecureApp vars) throws IOException, ServletException { if (log4j.isDebugEnabled()) log4j.debug("Output: ajax response "); // clean module updates if there are any cleanModulesUpdates(); final HashMap<String, String> updates = ImportModule.scanForUpdates(this, vars); JSONObject notifications = new JSONObject(); try { notifications = getNotificationsJSON(vars.getLanguage()); if (!notifications.has("updatesRebuildHTML")) { if (!"".equals(ImportModule.getScanError().toString())) { notifications.put("updatesRebuildHTML", Utility.messageBD(this, ImportModule.getScanError().toString(), vars.getLanguage())); } else { notifications = notifications.put("updatesRebuildHTML", Utility.messageBD(this, "NoUpdatesAvailable", vars.getLanguage())); } } JSONObject jsonUpdates = new JSONObject(updates); notifications.put("updates", jsonUpdates); } catch (Exception e) { log4j.error("Error reading notifications", e); } response.setContentType("Content-type: application/json; charset=UTF-8"); response.setHeader("Cache-Control", "no-cache"); final PrintWriter out = response.getWriter(); out.println(notifications.toString()); out.close(); } @SuppressWarnings("unchecked") private void printPageSettings(HttpServletResponse response, HttpServletRequest request) throws ServletException, IOException { VariablesSecureApp vars = new VariablesSecureApp(request); boolean activeInstance = ActivationKey.getInstance().isActive(); // Possible maturity levels are obtained from CR, obtain them once per session and store MaturityLevel levels = (MaturityLevel) vars.getSessionObject("SettingsModule|MaturityLevels"); if (levels == null) { levels = new MaturityLevel(); if (!levels.hasInternetError()) { vars.setSessionObject("SettingsModule|MaturityLevels", levels); } } String discard[] = { "", "" }; OBError myMessage = null; try { OBContext.setAdminMode(); SystemInformation sysInfo = OBDal.getInstance().get(SystemInformation.class, "0"); if (vars.commandIn("SETTINGS_ADD", "SETTINGS_REMOVE")) { String moduleId; if (vars.commandIn("SETTINGS_ADD")) { moduleId = vars.getStringParameter("inpModule", IsIDFilter.instance); } else { moduleId = vars.getStringParameter("inpModuleId", IsIDFilter.instance); } org.openbravo.model.ad.module.Module mod = OBDal.getInstance() .get(org.openbravo.model.ad.module.Module.class, moduleId); if (mod != null) { // do not update the audit info here, as its a local config change, which should not be // treated as 'local changes' by i.e. update.database try { boolean warn = false; OBInterceptor.setPreventUpdateInfoChange(true); if (vars.commandIn("SETTINGS_ADD")) { // GA is not allowed for community instances int level = Integer.parseInt(vars.getNumericParameter("inpModuleLevel")); if (!activeInstance && level >= MaturityLevel.CS_MATURITY) { myMessage = OBErrorBuilder.buildMessage(myMessage, "Warning", Utility.messageBD(this, "OBUIAPP_GAinCommunity", vars.getLanguage()) .replace("%0", levels.getLevelName(Integer.toString(level)))); warn = true; } else { mod.setMaturityUpdate(Integer.toString(level)); } } else { mod.setMaturityUpdate(null); } OBDal.getInstance().flush(); OBDal.getInstance().commitAndClose(); // clean module updates if there are any if (!warn) { boolean isCleaned = cleanModulesUpdates(); if (isCleaned) { myMessage = OBErrorBuilder.buildMessage(myMessage, "Info", Utility.messageBD(this, "ModuleUpdatesRemoved", vars.getLanguage())); } myMessage = OBErrorBuilder.buildMessage(myMessage, "Success", Utility.messageBD(this, "ModuleManagementSettingSaved", vars.getLanguage())); } } finally { OBInterceptor.setPreventUpdateInfoChange(false); } } else { log4j.error("Module does not exists ID:" + moduleId); } } else if (vars.commandIn("SETTINGS_SAVE")) { boolean warn = false; // Save global maturity levels. GA is not allowed for community instances String maturityWarnMsg = ""; try { int maturitySearch = Integer.parseInt(vars.getNumericParameter("inpSearchLevel")); if (!activeInstance && maturitySearch >= MaturityLevel.CS_MATURITY) { maturityWarnMsg = Utility.messageBD(this, "OBUIAPP_GAinCommunity", vars.getLanguage()) .replace("%0", levels.getLevelName(Integer.toString(maturitySearch))); warn = true; } else { sysInfo.setMaturitySearch(Integer.toString(maturitySearch)); } int maturityScan = Integer.parseInt(vars.getNumericParameter("inpScanLevel")); if (!activeInstance && maturityScan >= MaturityLevel.CS_MATURITY) { if (maturityWarnMsg.isEmpty()) { maturityWarnMsg += Utility.messageBD(this, "OBUIAPP_GAinCommunity", vars.getLanguage()) .replace("%0", levels.getLevelName(Integer.toString(maturityScan))); } warn = true; } else { sysInfo.setMaturityUpdate(Integer.toString(maturityScan)); } } catch (Exception e) { log4j.error("Error reading maturity search", e); } // Save enforcement String warnMsg = ""; for (Enumeration<String> e = request.getParameterNames(); e.hasMoreElements();) { String parameter = e.nextElement(); if (parameter.startsWith("inpEnforcement")) { String depId = parameter.replace("inpEnforcement", ""); String value = vars.getStringParameter(parameter); org.openbravo.model.ad.module.ModuleDependency dep = OBDal.getInstance() .get(org.openbravo.model.ad.module.ModuleDependency.class, depId); if (dep != null) { boolean save = true; if ("MINOR".equals(value)) { // Setting Minor version enforcement, check the configuration is still valid VersionComparator vc = new VersionComparator(); if (dep.getLastVersion() == null && vc.compare(dep.getFirstVersion(), dep.getDependentModule().getVersion()) != 0) { save = false; warn = true; warnMsg += "<br/>" + Utility .messageBD(this, "ModuleDependsButInstalled", vars.getLanguage()) .replace("@module@", dep.getDependentModule().getName()) .replace("@version@", dep.getFirstVersion()) .replace("@installed@", dep.getDependentModule().getVersion()); } else if (dep.getLastVersion() != null && !(vc.compare(dep.getFirstVersion(), dep.getDependentModule().getVersion()) <= 0 && vc.compare(dep.getLastVersion(), dep.getDependentModule().getVersion()) >= 0)) { save = false; warn = true; warnMsg += "<br/>" + Utility .messageBD(this, "ModuleDependsButInstalled", vars.getLanguage()) .replace("@module@", dep.getDependentModule().getName()) .replace("@version@", dep.getFirstVersion() + " - " + dep.getLastVersion()) .replace("@installed@", dep.getDependentModule().getVersion()); } } if (save) { if (value.equals(dep.getDependencyEnforcement())) { // setting no instance enforcement in case the selected value is the default dep.setInstanceEnforcement(null); } else { dep.setInstanceEnforcement(value); } } } } } // clean module updates if there are any final boolean isCleaned = cleanModulesUpdates(); if (isCleaned) { myMessage = OBErrorBuilder.buildMessage(myMessage, "Info", Utility.messageBD(this, "ModuleUpdatesRemoved", vars.getLanguage())); } if (warn) { String msgBody = ""; if (!maturityWarnMsg.isEmpty()) { msgBody += maturityWarnMsg; } if (!warnMsg.isEmpty()) { msgBody += "<br/>" + Utility.messageBD(this, "CannotSetMinorEnforcements", vars.getLanguage()) + warnMsg; } myMessage = OBErrorBuilder.buildMessage(myMessage, "Warning", msgBody); } else { myMessage = OBErrorBuilder.buildMessage(myMessage, "Success", Utility.messageBD(this, "ModuleManagementSettingSaved", vars.getLanguage())); } } // Populate module specific grid OBCriteria<org.openbravo.model.ad.module.Module> qModuleSpecific = OBDal.getInstance() .createCriteria(org.openbravo.model.ad.module.Module.class); qModuleSpecific .add(Restrictions.isNotNull(org.openbravo.model.ad.module.Module.PROPERTY_MATURITYUPDATE)); qModuleSpecific.addOrder(Order.asc(org.openbravo.model.ad.module.Module.PROPERTY_NAME)); ArrayList<HashMap<String, String>> moduleSpecifics = new ArrayList<HashMap<String, String>>(); List<org.openbravo.model.ad.module.Module> moduleSpecificList = qModuleSpecific.list(); if (moduleSpecificList.isEmpty()) { discard[0] = "moduleTable"; } for (org.openbravo.model.ad.module.Module module : moduleSpecificList) { HashMap<String, String> m = new HashMap<String, String>(); m.put("id", module.getId()); m.put("name", module.getName()); if (!activeInstance && Integer.parseInt(module.getMaturityUpdate()) >= MaturityLevel.CS_MATURITY) { m.put("level", levels.getLevelName(Integer.toString(MaturityLevel.QA_APPR_MATURITY))); } else { m.put("level", levels.getLevelName(module.getMaturityUpdate())); } moduleSpecifics.add(m); } // Populate combo of modules without specific setting OBCriteria<org.openbravo.model.ad.module.Module> qModule = OBDal.getInstance() .createCriteria(org.openbravo.model.ad.module.Module.class); qModule.add(Restrictions.isNull(org.openbravo.model.ad.module.Module.PROPERTY_MATURITYUPDATE)); qModule.addOrder(Order.asc(org.openbravo.model.ad.module.Module.PROPERTY_NAME)); ArrayList<HashMap<String, String>> modules = new ArrayList<HashMap<String, String>>(); List<org.openbravo.model.ad.module.Module> moduleList = qModule.list(); if (moduleList.isEmpty()) { discard[0] = "assignModule"; } for (org.openbravo.model.ad.module.Module module : moduleList) { HashMap<String, String> m = new HashMap<String, String>(); m.put("id", module.getId()); m.put("name", module.getName()); modules.add(m); } // Dependencies table OBCriteria<org.openbravo.model.ad.module.ModuleDependency> qDeps = OBDal.getInstance() .createCriteria(org.openbravo.model.ad.module.ModuleDependency.class); qDeps.add(Restrictions .eq(org.openbravo.model.ad.module.ModuleDependency.PROPERTY_USEREDITABLEENFORCEMENT, true)); qDeps.addOrder(Order.asc(org.openbravo.model.ad.module.ModuleDependency.PROPERTY_MODULE)); qDeps.addOrder(Order.asc(org.openbravo.model.ad.module.ModuleDependency.PROPERTY_ISINCLUDED)); qDeps.addOrder(Order.asc(org.openbravo.model.ad.module.ModuleDependency.PROPERTY_DEPENDANTMODULENAME)); List<org.openbravo.model.ad.module.ModuleDependency> deps = qDeps.list(); if (deps.isEmpty()) { discard[1] = "enforcementTable"; } else { discard[1] = "noEditableEnforcement"; } FieldProvider fpDeps[] = new FieldProvider[deps.size()]; FieldProvider fpEnforcements[][] = new FieldProvider[deps.size()][]; int i = 0; String lastName = ""; Boolean lastType = null; // Get the static text values once, not to query db each time for them OBCriteria<org.openbravo.model.ad.domain.List> qList = OBDal.getInstance() .createCriteria(org.openbravo.model.ad.domain.List.class); qList.add(Restrictions.eq(org.openbravo.model.ad.domain.List.PROPERTY_REFERENCE + ".id", "8BA0A3775CE14CE69989B6C09982FB2E")); qList.addOrder(Order.asc(org.openbravo.model.ad.domain.List.PROPERTY_SEQUENCENUMBER)); SQLReturnObject[] fpEnforcementCombo = new SQLReturnObject[qList.list().size()]; for (org.openbravo.model.ad.domain.List value : qList.list()) { SQLReturnObject val = new SQLReturnObject(); val.setData("ID", value.getSearchKey()); val.setData("NAME", Utility.getListValueName("Dependency Enforcement", value.getSearchKey(), vars.getLanguage())); fpEnforcementCombo[i] = val; i++; } String inclusionType = Utility.messageBD(this, "InclusionType", vars.getLanguage()); String dependencyType = Utility.messageBD(this, "DependencyType", vars.getLanguage()); String defaultStr = Utility.messageBD(this, "Default", vars.getLanguage()); i = 0; for (org.openbravo.model.ad.module.ModuleDependency dep : deps) { HashMap<String, String> d = new HashMap<String, String>(); d.put("baseModule", dep.getDependentModule().getName()); d.put("currentVersion", dep.getDependentModule().getVersion()); d.put("firstVersion", dep.getFirstVersion()); d.put("lastVersion", dep.getLastVersion()); d.put("depId", dep.getId()); // Grouping by module and dependency String currentName = dep.getModule().getName(); Boolean currentType = dep.isIncluded(); if (lastName.equals(currentName)) { d.put("modName", ""); if (!currentType.equals(lastType)) { d.put("depType", dep.isIncluded() ? inclusionType : dependencyType); } else { d.put("depType", ""); } } else { d.put("modName", currentName); d.put("depType", dep.isIncluded() ? inclusionType : dependencyType); lastName = currentName; lastType = currentType; } d.put("selectedEnforcement", dep.getInstanceEnforcement() == null ? dep.getDependencyEnforcement() : dep.getInstanceEnforcement()); fpDeps[i] = FieldProviderFactory.getFieldProvider(d); fpEnforcements[i] = getEnforcementCombo(dep, fpEnforcementCombo, defaultStr); i++; } final XmlDocument xmlDocument = xmlEngine .readXmlTemplate("org/openbravo/erpCommon/ad_forms/ModuleManagementSettings", discard) .createXmlDocument(); xmlDocument.setData("moduleDetail", FieldProviderFactory.getFieldProviderArray(moduleSpecifics)); xmlDocument.setData("moduleCombo", FieldProviderFactory.getFieldProviderArray(modules)); // Populate maturity levels combos String selectedScanLevel; String selectedSearchLevel; if (activeInstance) { selectedScanLevel = sysInfo.getMaturityUpdate() == null ? Integer.toString(MaturityLevel.CS_MATURITY) : sysInfo.getMaturityUpdate(); selectedSearchLevel = sysInfo.getMaturitySearch() == null ? Integer.toString(MaturityLevel.CS_MATURITY) : sysInfo.getMaturitySearch(); } else { // Community instances cannot use GA, setting CR if it is used int actualScanLevel = sysInfo.getMaturityUpdate() == null ? MaturityLevel.QA_APPR_MATURITY : Integer.parseInt(sysInfo.getMaturityUpdate()); int actualSearchLevel = sysInfo.getMaturitySearch() == null ? MaturityLevel.QA_APPR_MATURITY : Integer.parseInt(sysInfo.getMaturitySearch()); if (actualScanLevel >= MaturityLevel.CS_MATURITY) { actualScanLevel = MaturityLevel.QA_APPR_MATURITY; } if (actualSearchLevel >= MaturityLevel.CS_MATURITY) { actualSearchLevel = MaturityLevel.QA_APPR_MATURITY; } selectedScanLevel = Integer.toString(actualScanLevel); selectedSearchLevel = Integer.toString(actualSearchLevel); } xmlDocument.setParameter("selectedScanLevel", selectedScanLevel); xmlDocument.setData("reportScanLevel", "liststructure", levels.getCombo()); xmlDocument.setParameter("selectedSearchLevel", selectedSearchLevel); xmlDocument.setData("reportSearchLevel", "liststructure", levels.getCombo()); xmlDocument.setData("reportModuleLevel", "liststructure", levels.getCombo()); // less and most mature values xmlDocument.setParameter("lessMature", levels.getLessMature()); xmlDocument.setParameter("mostMature", levels.getMostMature()); response.setContentType("text/html; charset=UTF-8"); final PrintWriter out = response.getWriter(); xmlDocument.setParameter("directory", "var baseDirectory = \"" + strReplaceWith + "/\";\n"); xmlDocument.setParameter("language", "defaultLang=\"" + vars.getLanguage() + "\";"); xmlDocument.setData("dependencyDetail", fpDeps); xmlDocument.setDataArray("reportEnforcementType", "liststructure", fpEnforcements); // Interface parameters final ToolBar toolbar = new ToolBar(this, vars.getLanguage(), "ModuleManagement", false, "", "", "", false, "ad_forms", strReplaceWith, false, true); toolbar.prepareSimpleToolBarTemplate(); xmlDocument.setParameter("toolbar", toolbar.toString()); try { final WindowTabs tabs = new WindowTabs(this, vars, "org.openbravo.erpCommon.ad_forms.ModuleManagement"); xmlDocument.setParameter("theme", vars.getTheme()); final NavigationBar nav = new NavigationBar(this, vars.getLanguage(), "ModuleManagement.html", classInfo.id, classInfo.type, strReplaceWith, tabs.breadcrumb()); xmlDocument.setParameter("navigationBar", nav.toString()); final LeftTabsBar lBar = new LeftTabsBar(this, vars.getLanguage(), "ModuleManagement.html", strReplaceWith); xmlDocument.setParameter("leftTabs", lBar.manualTemplate()); } catch (final Exception ex) { throw new ServletException(ex); } if (myMessage != null) { xmlDocument.setParameter("messageType", myMessage.getType()); xmlDocument.setParameter("messageTitle", myMessage.getTitle()); xmlDocument.setParameter("messageMessage", myMessage.getMessage()); } out.println(xmlDocument.print()); out.close(); } finally { OBContext.restorePreviousMode(); } } /** * Checks whether there are any updates available for the installed modules and cleans the update * info if so. */ private boolean cleanModulesUpdates() throws ServletException { boolean hasChanged = false; if (ModuleManagementData.selectUpdateable(this).length > 0) { // cleaning modules updates ModuleManagementData.cleanModulesUpdates(this); hasChanged = true; } // cleaning module upgrades OBCriteria<org.openbravo.model.ad.module.Module> qUpgr = OBDal.getInstance() .createCriteria(org.openbravo.model.ad.module.Module.class); qUpgr.add(Restrictions.isNotNull(org.openbravo.model.ad.module.Module.PROPERTY_UPGRADEAVAILABLE)); try { OBInterceptor.setPreventUpdateInfoChange(true); for (org.openbravo.model.ad.module.Module mod : qUpgr.list()) { mod.setUpgradeAvailable(null); hasChanged = true; } OBDal.getInstance().flush(); try { // A commit is necessary to avoid a lock which can happen because xsql statements are being // executed (but not committed yet) in parallel with DAL statements over the same tables // (see issue 18697) OBDal.getInstance().getConnection().commit(); } catch (SQLException e) { // Do nothing, this will not happen } } finally { OBInterceptor.setPreventUpdateInfoChange(false); } return hasChanged; } /** * Obtains the combo used for enforcement, showing which is the default setting. */ private FieldProvider[] getEnforcementCombo(org.openbravo.model.ad.module.ModuleDependency dep, SQLReturnObject[] fpEnforcementCombo, String defaultStr) { SQLReturnObject[] rt = new SQLReturnObject[fpEnforcementCombo.length]; int i = 0; for (SQLReturnObject val : fpEnforcementCombo) { rt[i] = new SQLReturnObject(); rt[i].setData("ID", val.getData("ID")); if (val.getData("ID").equals(dep.getDependencyEnforcement())) { rt[i].setData("NAME", val.getData("NAME") + " " + defaultStr); } else { rt[i].setData("NAME", val.getData("NAME")); } i++; } return rt; } private String getSystemMaturity(boolean updateLevel) { try { OBContext.setAdminMode(); SystemInformation sys = OBDal.getInstance().get(SystemInformation.class, "0"); String maturity; boolean activeInstance = ActivationKey.getInstance().isActive(); if (updateLevel) { maturity = sys.getMaturityUpdate(); } else { maturity = sys.getMaturitySearch(); } if (!activeInstance && maturity != null && Integer.parseInt(maturity) >= MaturityLevel.CS_MATURITY) { maturity = Integer.toString(MaturityLevel.QA_APPR_MATURITY); } return maturity; } finally { OBContext.restorePreviousMode(); } } /** * Enable the passed in module */ private void enable(VariablesSecureApp vars) throws ServletException { try { OBInterceptor.setPreventUpdateInfoChange(true); ArrayList<String> notEnabledModules = new ArrayList<String>(); enableDisableModule(OBDal.getInstance().get(org.openbravo.model.ad.module.Module.class, vars.getStringParameter("inpcRecordId")), true, notEnabledModules); finishEnabling(notEnabledModules, vars); } finally { OBInterceptor.setPreventUpdateInfoChange(false); } } /** * Disables all the selected modules */ private void disable(VariablesSecureApp vars) throws ServletException { String modules = vars.getInStringParameter("inpNodes", IsIDFilter.instance); // check if disabling core if (modules.contains("'0'")) { OBError msg = new OBError(); msg.setType("Error"); msg.setMessage("Cannot disable core"); vars.setMessage("ModuleManagement|message", msg); return; } String[] moduleIds = modules.replace("(", "").replace(")", "").replace(" ", "").replace("'", "").split(","); ArrayList<String> notEnabledModules = new ArrayList<String>(); try { OBInterceptor.setPreventUpdateInfoChange(true); for (String moduleId : moduleIds) { org.openbravo.model.ad.module.Module module = OBDal.getInstance() .get(org.openbravo.model.ad.module.Module.class, moduleId); enableDisableModule(module, false, notEnabledModules); } finishEnabling(notEnabledModules, vars); } finally { OBInterceptor.setPreventUpdateInfoChange(false); } } /** * Enables or disables the module passed as parameter. In case it has other modules has inclusions * they are disabled/enabled recursively. * * @param module * Module to enable or disable * @param enable * If true, the module will be enabled, if false, it will be disabled * @param notEnabledModules * List of modules that couldn't be enabled because they are commercial and are not part * of the instance license's subscribed modules */ private void enableDisableModule(org.openbravo.model.ad.module.Module module, boolean enable, List<String> notEnabledModules) { if (module == null) { return; } if (enable && !ActivationKey.getInstance().isModuleEnableable(module)) { log4j.warn("Cannot enable not subscribed commercial module " + module); notEnabledModules.add(module.getName()); } else { log4j.info((enable ? "Enabling " : "Disabling ") + module.getName()); module.setEnabled(enable); } if ("M".equals(module.getType())) { // Standard modules do not have inclusions return; } // For packs and templates enable/disable recursively all inclusions for (org.openbravo.model.ad.module.ModuleDependency dependency : module.getModuleDependencyList()) { if (dependency.isIncluded()) { enableDisableModule(dependency.getDependentModule(), enable, notEnabledModules); } } } /** * Finishes the enabling/disabling process. The actions it performs are: * <ul> * <li>In case the are no modules that couldn't be enabled, it reloads the disabled modules in * memory. * <li>If any module coudn't no be enabled, shows an error message and rolls back the transaction * </ul> */ private void finishEnabling(List<String> notEnabledModules, VariablesSecureApp vars) { if (notEnabledModules == null || notEnabledModules.isEmpty()) { OBDal.getInstance().flush(); DisabledModules.reload(); return; } String msg = Utility.messageBD(this, "CannotEnableNonSubscribedModules", vars.getLanguage()); for (String module : notEnabledModules) { msg += "<br/>" + module; } OBError err = new OBError(); err.setType("Error"); err.setMessage(msg); vars.setMessage("ModuleManagement|message", err); OBDal.getInstance().rollbackAndClose(); } /** * Checks if there are local changes in the application */ private String verifyLocalChanges(VariablesSecureApp vars) { Connection connection = OBDal.getInstance().getConnection(); List<String> tablesModified = new ArrayList<String>(); PreparedStatement ps = null; String localChanges = null; try { ps = connection.prepareStatement("SELECT ad_db_modified('N') FROM DUAL"); ps.execute(); ResultSet rs = ps.getResultSet(); rs.next(); String answer = rs.getString(1); if (answer.equalsIgnoreCase("Y")) { localChanges = Utility.messageBD(this, "ErrorLocalChanges", vars.getLanguage()); localChanges = localChanges.concat( " <br><br> " + Utility.messageBD(this, "StructuralChangesInDB", vars.getLanguage())); } } catch (Exception e) { log4j.error("Couldn't verify local changes"); } finally { try { ps.close(); } catch (SQLException e) { // won't happen } } List<File> modelFiles = new ArrayList<File>(); String sourcePath = OBPropertiesProvider.getInstance().getOpenbravoProperties().getProperty("source.path"); File sources = new File(sourcePath); // Added file exists condition to check invalid source path if (!sources.exists()) { throw new OBException(Utility.messageBD(this, "WrongPathError", vars.getLanguage())); } // Added to check write access if (!sources.canWrite()) { throw new OBException(Utility.messageBD(this, "NoApplicableModules", vars.getLanguage())); } File model = new File(sources, "src-db/database/model/tables"); if (model.exists()) { modelFiles.add(model); } else { throw new OBException(Utility.messageBD(this, "WrongPathError", vars.getLanguage())); } for (File moduleFile : (new File(sources, "modules").listFiles())) { File mmodel = new File(moduleFile, "src-db/database/model/tables"); if (mmodel.exists()) { modelFiles.add(mmodel); } } Database db = DatabaseUtils.readDatabase(modelFiles.toArray(new File[1])); Properties obProp = OBPropertiesProvider.getInstance().getOpenbravoProperties(); String driver = obProp.getProperty("bbdd.driver"); String url = obProp.getProperty("bbdd.rdbms").equals("POSTGRE") ? obProp.getProperty("bbdd.url") + "/" + obProp.getProperty("bbdd.sid") : obProp.getProperty("bbdd.url"); String user = obProp.getProperty("bbdd.user"); String password = obProp.getProperty("bbdd.password"); BasicDataSource datasource = DBSMOBUtil.getDataSource(driver, url, user, password); final Platform platform = PlatformFactory.createNewPlatformInstance(datasource); OBDataset ad = new OBDataset(platform, db, "AD"); boolean datachange = ad.hasChanged(connection, log4j, tablesModified); if (datachange) { if (localChanges == null) { localChanges = Utility.messageBD(this, "ErrorLocalChanges", vars.getLanguage()); } localChanges = localChanges.concat( " <br><br> " + Utility.messageBD(this, "ModifiedTablesInDB", vars.getLanguage()) + " : "); localChanges = localChanges.concat(" " + tablesModified.toString()); } return localChanges; } }