001/* 002 * This library is part of OpenCms - 003 * the Open Source Content Management System 004 * 005 * Copyright (c) Alkacon Software GmbH & Co. KG (http://www.alkacon.com) 006 * 007 * This library is free software; you can redistribute it and/or 008 * modify it under the terms of the GNU Lesser General Public 009 * License as published by the Free Software Foundation; either 010 * version 2.1 of the License, or (at your option) any later version. 011 * 012 * This library is distributed in the hope that it will be useful, 013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 015 * Lesser General Public License for more details. 016 * 017 * For further information about Alkacon Software GmbH & Co. KG, please see the 018 * company website: http://www.alkacon.com 019 * 020 * For further information about OpenCms, please see the 021 * project website: http://www.opencms.org 022 * 023 * You should have received a copy of the GNU Lesser General Public 024 * License along with this library; if not, write to the Free Software 025 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 026 */ 027 028package org.opencms.setup; 029 030import org.opencms.configuration.CmsConfigurationException; 031import org.opencms.configuration.CmsConfigurationManager; 032import org.opencms.configuration.CmsModuleConfiguration; 033import org.opencms.configuration.CmsParameterConfiguration; 034import org.opencms.file.CmsProject; 035import org.opencms.file.CmsResource; 036import org.opencms.file.types.I_CmsResourceType; 037import org.opencms.i18n.CmsEncoder; 038import org.opencms.importexport.CmsImportParameters; 039import org.opencms.main.CmsException; 040import org.opencms.main.CmsLog; 041import org.opencms.main.CmsShell; 042import org.opencms.main.CmsSystemInfo; 043import org.opencms.main.OpenCms; 044import org.opencms.module.CmsModule; 045import org.opencms.module.CmsModuleVersion; 046import org.opencms.module.CmsModuleXmlHandler; 047import org.opencms.relations.I_CmsLinkParseable; 048import org.opencms.report.CmsHtmlReport; 049import org.opencms.report.CmsShellReport; 050import org.opencms.report.I_CmsReport; 051import org.opencms.security.CmsRole; 052import org.opencms.setup.db.CmsUpdateDBThread; 053import org.opencms.setup.xml.CmsXmlConfigUpdater; 054import org.opencms.util.CmsStringUtil; 055import org.opencms.workplace.threads.CmsXmlContentRepairSettings; 056import org.opencms.workplace.threads.CmsXmlContentRepairThread; 057import org.opencms.workplace.tools.CmsIdentifiableObjectContainer; 058import org.opencms.xml.CmsXmlException; 059 060import java.io.File; 061import java.io.FileFilter; 062import java.io.FileInputStream; 063import java.io.FileOutputStream; 064import java.io.IOException; 065import java.lang.reflect.Method; 066import java.nio.file.FileVisitResult; 067import java.nio.file.FileVisitor; 068import java.nio.file.Files; 069import java.nio.file.Path; 070import java.nio.file.attribute.BasicFileAttributes; 071import java.util.ArrayList; 072import java.util.Arrays; 073import java.util.Collections; 074import java.util.HashMap; 075import java.util.HashSet; 076import java.util.Iterator; 077import java.util.List; 078import java.util.Map; 079import java.util.Map.Entry; 080import java.util.Set; 081import java.util.jar.Attributes; 082import java.util.jar.JarInputStream; 083import java.util.jar.Manifest; 084 085import javax.servlet.jsp.JspWriter; 086 087import org.apache.commons.logging.Log; 088 089import com.google.common.base.Objects; 090import com.google.common.collect.Lists; 091 092/** 093 * A java bean as a controller for the OpenCms update wizard.<p> 094 * 095 * @since 6.0.0 096 */ 097public class CmsUpdateBean extends CmsSetupBean { 098 099 /** The empty jar marker attribute key. */ 100 public static final String EMPTY_JAR_ATTRIBUTE_KEY = "OpenCms-empty-jar"; 101 102 /** Folder constant name.<p> */ 103 public static final String FOLDER_UPDATE = "WEB-INF/updatedata" + File.separatorChar; 104 105 /** The static log object for this class. */ 106 static final Log LOG = CmsLog.getLog(CmsUpdateBean.class); 107 108 /** replace pattern constant for the cms script. */ 109 private static final String C_ADMIN_GROUP = "@ADMIN_GROUP@"; 110 111 /** replace pattern constant for the cms script. */ 112 private static final String C_ADMIN_PWD = "@ADMIN_PWD@"; 113 114 /** replace pattern constant for the cms script. */ 115 private static final String C_ADMIN_USER = "@ADMIN_USER@"; 116 117 /** replace pattern constant for the cms script. */ 118 private static final String C_UPDATE_PROJECT = "@UPDATE_PROJECT@"; 119 120 /** replace pattern constant for the cms script. */ 121 private static final String C_UPDATE_SITE = "@UPDATE_SITE@"; 122 123 /** New MySQL JDBC driver class name. */ 124 private static final String MYSQL_DRIVER_CLASS_NEW = "com.mysql.cj.jdbc.Driver"; 125 126 /** Old MySQL JDBC driver class name. */ 127 private static final String MYSQL_DRIVER_CLASS_OLD = "org.gjt.mm.mysql.Driver"; 128 129 /** MariaDB MySQL JDBC driver class name (used from OpenCms 12 onwards). */ 130 private static final String MYSQL_DRIVER_CLASS_MARIADB = "org.mariadb.jdbc.Driver"; 131 132 /** The obsolete modules that should be removed. */ 133 private static String[] OBSOLETE_MODULES = new String[] { 134 "org.opencms.ade.config", 135 "org.opencms.ade.containerpage", 136 "org.opencms.ade.contenteditor", 137 "org.opencms.ade.editprovider", 138 "org.opencms.ade.galleries", 139 "org.opencms.ade.postupload", 140 "org.opencms.ade.properties", 141 "org.opencms.ade.publish", 142 "org.opencms.ade.sitemap", 143 "org.opencms.ade.upload", 144 "org.opencms.editors.codemirror", 145 "org.opencms.editors.tinymce", 146 "org.opencms.editors", 147 "org.opencms.gwt", 148 "org.opencms.jquery", 149 "org.opencms.jsp.search", 150 "org.opencms.locale.cs", 151 "org.opencms.locale.da", 152 "org.opencms.locale.de", 153 "org.opencms.locale.es", 154 "org.opencms.locale.it", 155 "org.opencms.locale.ja", 156 "org.opencms.locale.ru", 157 "org.opencms.locale.zh", 158 "org.opencms.ugc", 159 "org.opencms.workplace", 160 "org.opencms.workplace.administration", 161 "org.opencms.workplace.explorer", 162 "org.opencms.workplace.handler", 163 "org.opencms.workplace.spellcheck", 164 "org.opencms.workplace.tools.accounts", 165 "org.opencms.workplace.tools.cache", 166 "org.opencms.workplace.tools.content", 167 "org.opencms.workplace.tools.database", 168 "org.opencms.workplace.tools.galleryoverview", 169 "org.opencms.workplace.tools.git", 170 "org.opencms.workplace.tools.history", 171 "org.opencms.workplace.tools.link", 172 "org.opencms.workplace.tools.modules", 173 "org.opencms.workplace.tools.projects", 174 "org.opencms.workplace.tools.publishqueue", 175 "org.opencms.workplace.tools.scheduler", 176 "org.opencms.workplace.tools.searchindex", 177 "org.opencms.workplace.tools.sites", 178 "org.opencms.workplace.tools.workplace", 179 "org.opencms.workplace.traditional", 180 "org.opencms.workplace.help.de", 181 "org.opencms.workplace.help.en", 182 "org.opencms.workplace.help", 183 "org.opencms.workplace.tools.git"}; 184 185 /** Static flag to indicate if all modules should be updated regardless of their version number. */ 186 private static final boolean UPDATE_ALL_MODULES = false; 187 188 /** The new logging offset in the database update thread. */ 189 protected int m_newLoggingDBOffset; 190 191 /** The old logging offset in the database update thread. */ 192 protected int m_oldLoggingDBOffset; 193 194 /** The used admin user name. */ 195 private String m_adminGroup = "_tmpUpdateGroup" + (System.currentTimeMillis() % 1000); 196 197 /** the admin user password. */ 198 private String m_adminPwd = "admin"; 199 200 /** The used admin user name. */ 201 private String m_adminUser = "Admin"; 202 203 /** The XML updater instance (lazily initialized). */ 204 private CmsXmlConfigUpdater m_configUpdater; 205 206 /** The update database thread. */ 207 private CmsUpdateDBThread m_dbUpdateThread; 208 209 /** The detected mayor version, based on DB structure. */ 210 private double m_detectedVersion; 211 212 /** Parameter for keeping the history. */ 213 private boolean m_keepHistory; 214 215 /** List of module to be updated. */ 216 private List<String> m_modulesToUpdate; 217 218 /** The list of modules that should keep their libs. */ 219 private List<String> m_preserveLibModules; 220 221 /** the update project. */ 222 private String m_updateProject = "_tmpUpdateProject" + (System.currentTimeMillis() % 1000); 223 224 /** the site for update. */ 225 private String m_updateSite = CmsResource.VFS_FOLDER_SITES + "/default/"; 226 227 /** Cache for the up-to-date module names. */ 228 private List<String> m_uptodateModules; 229 230 /** The workplace import thread. */ 231 private CmsUpdateThread m_workplaceUpdateThread; 232 233 /** 234 * Default constructor.<p> 235 */ 236 public CmsUpdateBean() { 237 238 super(); 239 m_preserveLibModules = Collections.emptyList(); 240 m_modulesFolder = FOLDER_UPDATE + CmsSystemInfo.FOLDER_MODULES; 241 m_logFile = OpenCms.getSystemInfo().getLogFileRfsFolder() + "update.log"; 242 } 243 244 /** 245 * Adds the subscription driver to the properties.<p> 246 */ 247 public void addSubscriptionDriver() { 248 249 setExtProperty("driver.subscription", "db"); 250 String dbName = getExtProperty("db.name"); 251 String packageName = getDbPackage(dbName); 252 setExtProperty("db.subscription.driver", "org.opencms.db." + packageName + ".CmsSubscriptionDriver"); 253 setExtProperty("db.subscription.pool", "opencms:default"); 254 setExtProperty("db.subscription.sqlmanager", "org.opencms.db." + packageName + ".CmsSqlManager"); 255 } 256 257 /** 258 * Compatibility check for OCEE modules.<p> 259 * 260 * @param version the opencms version 261 * 262 * @return <code>false</code> if OCEE is present but not compatible with opencms version 263 */ 264 @SuppressWarnings({"boxing"}) 265 public boolean checkOceeVersion(String version) { 266 267 try { 268 Class<?> manager = Class.forName("org.opencms.ocee.base.CmsOceeManager"); 269 Method checkVersion = manager.getMethod("checkOceeVersion", String.class); 270 return (Boolean)checkVersion.invoke(manager, version); 271 } catch (@SuppressWarnings("unused") ClassNotFoundException e) { 272 return true; 273 } catch (Exception e) { 274 e.printStackTrace(); 275 return false; 276 } 277 } 278 279 /** 280 * Creates the shared folder if possible.<p> 281 * 282 * @throws Exception if something goes wrong 283 */ 284 public void createSharedFolder() throws Exception { 285 286 String originalSiteRoot = m_cms.getRequestContext().getSiteRoot(); 287 CmsProject originalProject = m_cms.getRequestContext().getCurrentProject(); 288 try { 289 m_cms.getRequestContext().setSiteRoot(""); 290 m_cms.getRequestContext().setCurrentProject(m_cms.createTempfileProject()); 291 if (!m_cms.existsResource("/shared")) { 292 m_cms.createResource("/shared", OpenCms.getResourceManager().getResourceType("folder")); 293 } 294 295 try { 296 m_cms.lockResourceTemporary("/shared"); 297 } catch (CmsException e) { 298 LOG.error(e.getLocalizedMessage(), e); 299 } 300 try { 301 m_cms.chacc("/shared", "group", "Users", "+v+w+r+i"); 302 } catch (CmsException e) { 303 LOG.error(e.getLocalizedMessage(), e); 304 } 305 CmsResource shared = m_cms.readResource("/shared"); 306 try { 307 OpenCms.getPublishManager().publishProject( 308 m_cms, 309 new CmsHtmlReport(m_cms.getRequestContext().getLocale(), m_cms.getRequestContext().getSiteRoot()), 310 shared, 311 false); 312 OpenCms.getPublishManager().waitWhileRunning(); 313 } catch (CmsException e) { 314 LOG.error(e.getLocalizedMessage(), e); 315 } 316 } finally { 317 m_cms.getRequestContext().setSiteRoot(originalSiteRoot); 318 m_cms.getRequestContext().setCurrentProject(originalProject); 319 } 320 321 } 322 323 /** 324 * CmsShell command to delete spellcheck index.<p> 325 * 326 * Called by cmsupdate.ori to remove spellcheck index. Necessary because Solr/Lucene versions might have 327 * incompatible changes, and deleting the index causes the spellcheck index to be rebuilt. 328 */ 329 public void deleteSpellcheckIndex() { 330 331 String dataPath = OpenCms.getSystemInfo().getAbsoluteRfsPathRelativeToWebInf("solr/spellcheck/data"); 332 File dataDir = new File(dataPath); 333 if (dataDir.exists()) { 334 try { 335 Files.walkFileTree(dataDir.toPath(), new FileVisitor<Path>() { 336 337 public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException { 338 339 dir.toFile().delete(); 340 return FileVisitResult.CONTINUE; 341 } 342 343 public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException { 344 345 return FileVisitResult.CONTINUE; 346 } 347 348 public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { 349 350 file.toFile().delete(); 351 return FileVisitResult.CONTINUE; 352 } 353 354 public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException { 355 356 return FileVisitResult.CONTINUE; 357 358 } 359 }); 360 } catch (IOException e) { 361 e.printStackTrace(System.err); 362 } 363 } 364 365 } 366 367 /** 368 * Returns html code to display an error.<p> 369 * 370 * @param pathPrefix to adjust the path 371 * 372 * @return html code 373 */ 374 @Override 375 public String displayError(String pathPrefix) { 376 377 if (pathPrefix == null) { 378 pathPrefix = ""; 379 } 380 StringBuffer html = new StringBuffer(512); 381 html.append("<table border='0' cellpadding='5' cellspacing='0' style='width: 100%; height: 100%;'>"); 382 html.append("\t<tr>"); 383 html.append("\t\t<td style='vertical-align: middle; height: 100%;'>"); 384 html.append(getHtmlPart("C_BLOCK_START", "Error")); 385 html.append("\t\t\t<table border='0' cellpadding='0' cellspacing='0' style='width: 100%;'>"); 386 html.append("\t\t\t\t<tr>"); 387 html.append("\t\t\t\t\t<td><img src='").append(pathPrefix).append("resources/error.png' border='0'></td>"); 388 html.append("\t\t\t\t\t<td> </td>"); 389 html.append("\t\t\t\t\t<td style='width: 100%;'>"); 390 html.append("\t\t\t\t\t\tThe Alkacon OpenCms update wizard has not been started correctly!<br>"); 391 html.append("\t\t\t\t\t\tPlease click <a href='").append(pathPrefix); 392 html.append("index.jsp'>here</a> to restart the wizard."); 393 html.append("\t\t\t\t\t</td>"); 394 html.append("\t\t\t\t</tr>"); 395 html.append("\t\t\t</table>"); 396 html.append(getHtmlPart("C_BLOCK_END")); 397 html.append("\t\t</td>"); 398 html.append("\t</tr>"); 399 html.append("</table>"); 400 return html.toString(); 401 } 402 403 /** 404 * Returns the admin Pwd.<p> 405 * 406 * @return the admin Pwd 407 */ 408 public String getAdminPwd() { 409 410 return m_adminPwd; 411 } 412 413 /** 414 * Returns the admin User.<p> 415 * 416 * @return the admin User 417 */ 418 public String getAdminUser() { 419 420 return m_adminUser; 421 } 422 423 /** 424 * Gets the folder for config files. 425 * 426 * @return the folder for config files 427 */ 428 public File getConfigFolder() { 429 430 return new File(getWebAppRfsPath() + "WEB-INF/config"); 431 } 432 433 /** 434 * Returns the detected mayor version, based on DB structure.<p> 435 * 436 * @return the detected mayor version 437 */ 438 public double getDetectedVersion() { 439 440 return m_detectedVersion; 441 } 442 443 /** 444 * Returns a map of all previously installed modules.<p> 445 * 446 * @return a map of <code>[String, {@link org.opencms.module.CmsModuleVersion}]</code> objects 447 * 448 * @see org.opencms.module.CmsModuleManager#getAllInstalledModules() 449 */ 450 public Map<String, CmsModuleVersion> getInstalledModules() { 451 452 String file = CmsModuleConfiguration.DEFAULT_XML_FILE_NAME; 453 // /opencms/modules/module[?] 454 String basePath = new StringBuffer("/").append(CmsConfigurationManager.N_ROOT).append("/").append( 455 CmsModuleConfiguration.N_MODULES).append("/").append(CmsModuleXmlHandler.N_MODULE).append( 456 "[?]/").toString(); 457 Map<String, CmsModuleVersion> modules = new HashMap<String, CmsModuleVersion>(); 458 String name = ""; 459 for (int i = 1; name != null; i++) { 460 if (i > 1) { 461 String ver = CmsModuleVersion.DEFAULT_VERSION; 462 try { 463 ver = getXmlHelper().getValue( 464 file, 465 CmsStringUtil.substitute(basePath, "?", "" + (i - 1)) + CmsModuleXmlHandler.N_VERSION); 466 } catch (@SuppressWarnings("unused") CmsXmlException e) { 467 // ignore 468 } 469 modules.put(name, new CmsModuleVersion(ver)); 470 } 471 try { 472 name = getXmlHelper().getValue( 473 file, 474 CmsStringUtil.substitute(basePath, "?", "" + i) + CmsModuleXmlHandler.N_NAME); 475 } catch (@SuppressWarnings("unused") CmsXmlException e) { 476 // ignore 477 } 478 } 479 return modules; 480 } 481 482 /** 483 * List of modules to be updated.<p> 484 * 485 * @return a list of module names 486 */ 487 public List<String> getModulesToUpdate() { 488 489 if (m_modulesToUpdate == null) { 490 getUptodateModules(); 491 m_components = new CmsIdentifiableObjectContainer<CmsSetupComponent>(true, true); 492 try { 493 addComponentsFromPath(m_webAppRfsPath + FOLDER_UPDATE); 494 } catch (CmsConfigurationException e) { 495 // 496 } 497 } 498 return m_modulesToUpdate; 499 } 500 501 /** 502 * Returns the update database thread.<p> 503 * 504 * @return the update database thread 505 */ 506 public CmsUpdateDBThread getUpdateDBThread() { 507 508 return m_dbUpdateThread; 509 } 510 511 /** 512 * Returns the update Project.<p> 513 * 514 * @return the update Project 515 */ 516 public String getUpdateProject() { 517 518 return m_updateProject; 519 } 520 521 /** 522 * Returns the update site.<p> 523 * 524 * @return the update site 525 */ 526 public String getUpdateSite() { 527 528 return m_updateSite; 529 } 530 531 /** 532 * Returns the modules that does not need to be updated.<p> 533 * 534 * @return a list of module names 535 */ 536 public List<String> getUptodateModules() { 537 538 if (m_uptodateModules == null) { 539 m_uptodateModules = new ArrayList<String>(); 540 m_modulesToUpdate = new ArrayList<String>(); 541 Map<String, CmsModuleVersion> installedModules = getInstalledModules(); 542 Map<String, CmsModule> availableModules = getAvailableModules(); 543 Iterator<Map.Entry<String, CmsModule>> itMods = availableModules.entrySet().iterator(); 544 while (itMods.hasNext()) { 545 Map.Entry<String, CmsModule> entry = itMods.next(); 546 String name = entry.getKey(); 547 CmsModuleVersion instVer = installedModules.get(name); 548 CmsModuleVersion availVer = entry.getValue().getVersion(); 549 boolean uptodate = (!UPDATE_ALL_MODULES) && ((instVer != null) && (instVer.compareTo(availVer) >= 0)); 550 if (uptodate) { 551 m_uptodateModules.add(name); 552 } else { 553 m_modulesToUpdate.add(name); 554 } 555 if (LOG.isDebugEnabled()) { 556 LOG.debug( 557 name + " --- installed: " + instVer + " available: " + availVer + " --- uptodate: " + uptodate); 558 } 559 } 560 } 561 return m_uptodateModules; 562 } 563 564 /** 565 * Returns the workplace update thread.<p> 566 * 567 * @return the workplace update thread 568 */ 569 public CmsUpdateThread getWorkplaceUpdateThread() { 570 571 return m_workplaceUpdateThread; 572 } 573 574 /** 575 * Gets the XML updater (lazily create it if it hasn't been created yet). 576 * 577 * @return the XML updater 578 */ 579 public CmsXmlConfigUpdater getXmlConfigUpdater() { 580 581 if (m_configUpdater == null) { 582 m_configUpdater = new CmsXmlConfigUpdater(getXmlUpdateFolder(), getConfigFolder()); 583 } 584 return m_configUpdater; 585 } 586 587 /** 588 * Gets the folder for XML update files. 589 * 590 * @return the folder for XML update files 591 */ 592 public File getXmlUpdateFolder() { 593 594 return new File(new File(getWebAppRfsPath()), "WEB-INF/updatedata/xmlupdate"); 595 596 } 597 598 /** 599 * @see org.opencms.setup.CmsSetupBean#htmlModules() 600 */ 601 @Override 602 public String htmlModules() { 603 604 StringBuffer html = new StringBuffer(1024); 605 Set<String> uptodate = new HashSet<String>(getUptodateModules()); 606 Iterator<String> itModules = sortModules(getAvailableModules().values()).iterator(); 607 boolean hasModules = false; 608 for (int i = 0; itModules.hasNext(); i++) { 609 String moduleName = itModules.next(); 610 CmsModule module = getAvailableModules().get(moduleName); 611 if (UPDATE_ALL_MODULES || !uptodate.contains(moduleName)) { 612 html.append(htmlModule(module, i)); 613 hasModules = true; 614 } else { 615 html.append("<input type='hidden' name='availableModules' value='"); 616 html.append(moduleName); 617 html.append("'>\n"); 618 } 619 } 620 if (!hasModules) { 621 html.append("\t<tr>\n"); 622 html.append("\t\t<td style='vertical-align: middle;'>\n"); 623 html.append(Messages.get().getBundle().key(Messages.GUI_WARNING_ALL_MODULES_UPTODATE_0)); 624 html.append("\t\t</td>\n"); 625 html.append("\t</tr>\n"); 626 } 627 return html.toString(); 628 } 629 630 /** 631 * Creates a new instance of the setup Bean.<p> 632 * 633 * @param webAppRfsPath path to the OpenCms web application 634 * @param servletMapping the OpenCms servlet mapping 635 * @param defaultWebApplication the name of the default web application 636 */ 637 @Override 638 public void init(String webAppRfsPath, String servletMapping, String defaultWebApplication) { 639 640 try { 641 super.init(webAppRfsPath, servletMapping, defaultWebApplication); 642 CmsUpdateInfo.INSTANCE.setAdeModuleVersion(getInstalledModules().get("org.opencms.ade.containerpage")); 643 644 if (m_workplaceUpdateThread != null) { 645 if (m_workplaceUpdateThread.isAlive()) { 646 m_workplaceUpdateThread.kill(); 647 } 648 m_workplaceUpdateThread = null; 649 } 650 if (m_dbUpdateThread != null) { 651 if (m_dbUpdateThread.isAlive()) { 652 m_dbUpdateThread.kill(); 653 } 654 m_dbUpdateThread = null; 655 m_newLoggingOffset = 0; 656 m_oldLoggingOffset = 0; 657 } 658 } catch (Exception e) { 659 e.printStackTrace(); 660 throw new RuntimeException(e); 661 } 662 } 663 664 /** 665 * Returns the keep History parameter value.<p> 666 * 667 * @return the keep History parameter value 668 */ 669 public boolean isKeepHistory() { 670 671 return m_keepHistory; 672 } 673 674 /** 675 * Returns <code>true</code> if a DB update is needed.<p> 676 * 677 * @return <code>true</code> if a DB update is needed 678 */ 679 public boolean isNeedDbUpdate() { 680 681 return m_detectedVersion != 8; 682 } 683 684 /** 685 * Checks whether the selected user and password are valid and the user has the ROOT_ADMIN role.<p> 686 * 687 * @return <code>true</code> if the selected user and password are valid and the user has the ROOT_ADMIN role 688 */ 689 public boolean isValidUser() { 690 691 CmsShell shell = new CmsShell( 692 getWebAppRfsPath() + "WEB-INF" + File.separator, 693 getServletMapping(), 694 getDefaultWebApplication(), 695 "${user}@${project}>", 696 Collections.emptyList()); 697 boolean validUser = shell.validateUser(getAdminUser(), getAdminPwd(), CmsRole.ROOT_ADMIN); 698 shell.exit(); 699 return validUser; 700 } 701 702 /** 703 * Prepares step 1 of the update wizard.<p> 704 */ 705 public void prepareUpdateStep1() { 706 707 // the MySQL driver class name has changed with OpenCms 11.0.0 708 // it needs to be updated before any database access 709 //updateDBDriverClassName(); 710 } 711 712 /** 713 * Prepares step 1 of the update wizard.<p> 714 */ 715 public void prepareUpdateStep1b() { 716 717 if (!isInitialized()) { 718 return; 719 } 720 721 if ((m_dbUpdateThread != null) && (m_dbUpdateThread.isFinished())) { 722 // update is already finished, just wait for client to collect final data 723 return; 724 } 725 726 if (m_dbUpdateThread == null) { 727 m_dbUpdateThread = new CmsUpdateDBThread(this); 728 } 729 730 if (!m_dbUpdateThread.isAlive()) { 731 m_dbUpdateThread.start(); 732 } 733 } 734 735 /** 736 * Generates the output for step 1 of the setup wizard.<p> 737 * 738 * @param out the JSP print stream 739 * @throws IOException in case errors occur while writing to "out" 740 */ 741 public void prepareUpdateStep1bOutput(JspWriter out) throws IOException { 742 743 m_oldLoggingDBOffset = m_newLoggingDBOffset; 744 m_newLoggingDBOffset = m_dbUpdateThread.getLoggingThread().getMessages().size(); 745 if (isInitialized()) { 746 for (int i = m_oldLoggingDBOffset; i < m_newLoggingDBOffset; i++) { 747 String str = m_dbUpdateThread.getLoggingThread().getMessages().get(i).toString(); 748 str = CmsEncoder.escapeWBlanks(str, CmsEncoder.ENCODING_UTF_8); 749 out.println("output[" + (i - m_oldLoggingDBOffset) + "] = \"" + str + "\";"); 750 } 751 } else { 752 out.println("output[0] = 'ERROR';"); 753 } 754 755 boolean threadFinished = m_dbUpdateThread.isFinished(); 756 boolean allWritten = m_oldLoggingDBOffset >= m_dbUpdateThread.getLoggingThread().getMessages().size(); 757 758 out.println("function initThread() {"); 759 if (isInitialized()) { 760 out.print("send();"); 761 if (threadFinished && allWritten) { 762 out.println("setTimeout('top.display.finish()', 1000);"); 763 } else { 764 int timeout = 5000; 765 if (getUpdateDBThread().getLoggingThread().getMessages().size() < 20) { 766 timeout = 2000; 767 } 768 out.println("setTimeout('location.reload()', " + timeout + ");"); 769 } 770 } 771 out.println("}"); 772 } 773 774 /** 775 * Prepares step 5 of the update wizard.<p> 776 */ 777 public void prepareUpdateStep5() { 778 779 if (isInitialized()) { 780 try { 781 String fileName = getWebAppRfsPath() + FOLDER_UPDATE + "cmsupdate"; 782 // read the file 783 FileInputStream fis = new FileInputStream(fileName + CmsConfigurationManager.POSTFIX_ORI); 784 String script = ""; 785 int readChar = fis.read(); 786 while (readChar > -1) { 787 script += (char)readChar; 788 readChar = fis.read(); 789 } 790 fis.close(); 791 // substitute macros 792 script = CmsStringUtil.substitute(script, C_ADMIN_USER, getAdminUser()); 793 script = CmsStringUtil.substitute(script, C_ADMIN_PWD, getAdminPwd()); 794 script = CmsStringUtil.substitute(script, C_UPDATE_PROJECT, getUpdateProject()); 795 script = CmsStringUtil.substitute(script, C_UPDATE_SITE, getUpdateSite()); 796 script = CmsStringUtil.substitute(script, C_ADMIN_GROUP, getAdminGroup()); 797 // write the new script 798 FileOutputStream fos = new FileOutputStream(fileName + ".txt"); 799 fos.write(script.getBytes()); 800 fos.close(); 801 } catch (IOException e) { 802 e.printStackTrace(); 803 throw new RuntimeException(e); 804 } 805 } 806 } 807 808 /** 809 * Prepares step 5 of the update wizard.<p> 810 */ 811 public void prepareUpdateStep5b() { 812 813 if (!isInitialized()) { 814 return; 815 } 816 817 addSubscriptionDriver(); 818 819 if ((m_workplaceUpdateThread != null) && (m_workplaceUpdateThread.isFinished())) { 820 // update is already finished, just wait for client to collect final data 821 return; 822 } 823 824 if (m_workplaceUpdateThread == null) { 825 m_workplaceUpdateThread = new CmsUpdateThread(this); 826 } 827 828 if (!m_workplaceUpdateThread.isAlive()) { 829 m_workplaceUpdateThread.start(); 830 } 831 } 832 833 /** 834 * Generates the output for the update wizard.<p> 835 * 836 * @param out the JSP print stream 837 * 838 * @throws IOException in case errors occur while writing to "out" 839 */ 840 public void prepareUpdateStep5bOutput(JspWriter out) throws IOException { 841 842 if ((m_workplaceUpdateThread == null) || (m_workplaceUpdateThread.getLoggingThread() == null)) { 843 return; 844 } 845 m_oldLoggingOffset = m_newLoggingOffset; 846 m_newLoggingOffset = m_workplaceUpdateThread.getLoggingThread().getMessages().size(); 847 if (isInitialized()) { 848 for (int i = m_oldLoggingOffset; i < m_newLoggingOffset; i++) { 849 String str = m_workplaceUpdateThread.getLoggingThread().getMessages().get(i).toString(); 850 str = CmsEncoder.escapeWBlanks(str, CmsEncoder.ENCODING_UTF_8); 851 out.println("output[" + (i - m_oldLoggingOffset) + "] = \"" + str + "\";"); 852 } 853 } else { 854 out.println("output[0] = 'ERROR';"); 855 } 856 857 boolean threadFinished = m_workplaceUpdateThread.isFinished(); 858 boolean allWritten = m_oldLoggingOffset >= m_workplaceUpdateThread.getLoggingThread().getMessages().size(); 859 860 out.println("function initThread() {"); 861 if (isInitialized()) { 862 out.print("send();"); 863 if (threadFinished && allWritten) { 864 out.println("setTimeout('top.display.finish()', 500);"); 865 } else { 866 int timeout = 5000; 867 if (getWorkplaceUpdateThread().getLoggingThread().getMessages().size() < 20) { 868 timeout = 1000; 869 } 870 out.println("setTimeout('location.reload()', " + timeout + ");"); 871 } 872 } 873 out.println("}"); 874 } 875 876 /** 877 * Prepares step 6 of the update wizard.<p> 878 */ 879 public void prepareUpdateStep6() { 880 881 Set<String> forced = new HashSet<String>(); 882 forced.add("driver.subscription"); 883 forced.add("db.subscription.driver"); 884 forced.add("db.subscription.pool"); 885 forced.add("db.subscription.sqlmanager"); 886 addSubscriptionDriver(); 887 if (isInitialized()) { 888 // lock the wizard for further use 889 lockWizard(); 890 // save Properties to file "opencms.properties" 891 saveProperties(getProperties(), CmsSystemInfo.FILE_PROPERTIES, false, forced); 892 deleteEmptyJars(); 893 } 894 } 895 896 /** 897 * Sets the admin Pwd.<p> 898 * 899 * @param adminPwd the admin Pwd to set 900 */ 901 public void setAdminPwd(String adminPwd) { 902 903 m_adminPwd = adminPwd; 904 } 905 906 /** 907 * Sets the admin User.<p> 908 * 909 * @param adminUser the admin User to set 910 */ 911 public void setAdminUser(String adminUser) { 912 913 m_adminUser = adminUser; 914 } 915 916 /** 917 * Sets the detected mayor version.<p> 918 * 919 * @param detectedVersion the value to set 920 */ 921 public void setDetectedVersion(double detectedVersion) { 922 923 m_detectedVersion = detectedVersion; 924 } 925 926 /** 927 * Sets the keep History parameter value.<p> 928 * 929 * @param keepHistory the keep History parameter value to set 930 */ 931 public void setKeepHistory(boolean keepHistory) { 932 933 m_keepHistory = keepHistory; 934 } 935 936 /** 937 * Sets the list of modules where the included libs should be preserved during update.<p> 938 * Called from step_5_update_modules.jsp.<p> 939 * 940 * @param preserveLibModules the comma separated list of module names 941 */ 942 public void setPreserveLibModules(String preserveLibModules) { 943 944 if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(preserveLibModules)) { 945 String[] modules = preserveLibModules.split(","); 946 m_preserveLibModules = Arrays.asList(modules); 947 } else { 948 m_preserveLibModules = Collections.emptyList(); 949 } 950 } 951 952 /** 953 * Sets the update Project.<p> 954 * 955 * @param updateProject the update Project to set 956 */ 957 public void setUpdateProject(String updateProject) { 958 959 m_updateProject = updateProject; 960 } 961 962 /** 963 * Sets the update site.<p> 964 * 965 * @param site the update site to set 966 */ 967 public void setUpdateSite(String site) { 968 969 m_updateSite = site; 970 } 971 972 /** 973 * @see org.opencms.main.I_CmsShellCommands#shellExit() 974 */ 975 @Override 976 public void shellExit() { 977 978 System.out.println(); 979 System.out.println(); 980 System.out.println("The update is finished!\nThe OpenCms system used for the update will now shut down."); 981 } 982 983 /** 984 * @see org.opencms.main.I_CmsShellCommands#shellStart() 985 */ 986 @Override 987 public void shellStart() { 988 989 System.out.println(); 990 System.out.println("Starting Workplace update for OpenCms!"); 991 992 String[] copy = org.opencms.main.Messages.COPYRIGHT_BY_ALKACON; 993 for (int i = copy.length - 1; i >= 0; i--) { 994 System.out.println(copy[i]); 995 } 996 System.out.println( 997 "This is OpenCms " 998 + OpenCms.getSystemInfo().getVersionNumber() 999 + " [" 1000 + OpenCms.getSystemInfo().getVersionId() 1001 + "]"); 1002 System.out.println(); 1003 System.out.println(); 1004 } 1005 1006 /** 1007 * Updates the JDBC driver class names.<p> 1008 * Needs to be executed before any database access.<p> 1009 */ 1010 public void updateDBDriverProperties() { 1011 1012 Map<String, String> modifiedElements = new HashMap<String, String>(); 1013 // replace MySQL JDBC driver class name 1014 CmsParameterConfiguration properties = getProperties(); 1015 for (Entry<String, String> propertyEntry : properties.entrySet()) { 1016 if (MYSQL_DRIVER_CLASS_OLD.equals(propertyEntry.getValue()) 1017 || MYSQL_DRIVER_CLASS_NEW.equals(propertyEntry.getValue())) { 1018 modifiedElements.put(propertyEntry.getKey(), MYSQL_DRIVER_CLASS_MARIADB); 1019 } 1020 } 1021 1022 if (properties.containsValue(MYSQL_DRIVER_CLASS_MARIADB) 1023 || properties.containsValue(MYSQL_DRIVER_CLASS_NEW) 1024 || properties.containsValue(MYSQL_DRIVER_CLASS_OLD)) { 1025 for (Entry<String, String> propertyEntry : properties.entrySet()) { 1026 if (MYSQL_DRIVER_CLASS_OLD.equals(propertyEntry.getValue()) 1027 || MYSQL_DRIVER_CLASS_NEW.equals(propertyEntry.getValue()) 1028 || MYSQL_DRIVER_CLASS_MARIADB.equals(propertyEntry.getValue())) { 1029 1030 String mysqlkey = propertyEntry.getKey().substring(0, propertyEntry.getKey().lastIndexOf(".")); 1031 String parameterKey = mysqlkey + ".jdbcUrl.params"; 1032 String currentParameter = properties.get(parameterKey); 1033 String modifiedParameter = currentParameter; 1034 if (modifiedParameter == null) { 1035 modifiedParameter = ""; 1036 } 1037 if (!modifiedParameter.contains("serverTimezone")) { 1038 String parameterSeperator = "?"; 1039 if (modifiedParameter.contains("?")) { 1040 parameterSeperator = "&"; 1041 } 1042 modifiedParameter = currentParameter + parameterSeperator + "serverTimezone=UTC"; 1043 } 1044 if (modifiedParameter.contains("useSSL=false") 1045 && !modifiedParameter.contains("allowPublicKeyRetrieval")) { 1046 modifiedParameter = currentParameter + "&" + "allowPublicKeyRetrieval=true"; 1047 } 1048 if (!Objects.equal(modifiedParameter, currentParameter)) { 1049 modifiedElements.put(parameterKey, modifiedParameter); 1050 } 1051 parameterKey = mysqlkey + ".jdbcUrl"; 1052 currentParameter = properties.get(parameterKey); 1053 if ((currentParameter != null) && currentParameter.startsWith("jdbc:mysql:")) { 1054 modifiedParameter = "jdbc:mariadb:" + currentParameter.substring(11); 1055 modifiedElements.put(parameterKey, modifiedParameter); 1056 } 1057 } 1058 } 1059 } 1060 1061 for (String key : modifiedElements.keySet()) { 1062 properties.put(key, modifiedElements.get(key)); 1063 } 1064 1065 if (!modifiedElements.isEmpty()) { 1066 saveProperties(properties, CmsSystemInfo.FILE_PROPERTIES, false, modifiedElements.keySet()); 1067 } 1068 } 1069 1070 /** 1071 * Installed all modules that have been set using {@link #setInstallModules(String)}.<p> 1072 * 1073 * This method is invoked as a shell command.<p> 1074 * 1075 * @throws Exception if something goes wrong 1076 */ 1077 public void updateModulesFromUpdateBean() throws Exception { 1078 1079 // read here how the list of modules to be installed is passed from the setup bean to the 1080 // setup thread, and finally to the shell process that executes the setup script: 1081 // 1) the list with the package names of the modules to be installed is saved by setInstallModules 1082 // 2) the setup thread gets initialized in a JSP of the setup wizard 1083 // 3) the instance of the setup bean is passed to the setup thread by setAdditionalShellCommand 1084 // 4) the setup bean is passed to the shell by startSetup 1085 // 5) because the setup bean implements I_CmsShellCommands, the shell constructor can pass the shell's CmsObject back to the setup bean 1086 // 6) thus, the setup bean can do things with the Cms 1087 1088 if (m_cms != null) { 1089 1090 I_CmsReport report = new CmsShellReport(m_cms.getRequestContext().getLocale()); 1091 1092 // remove obsolete modules in any case 1093 for (String moduleToRemove : getModulesToDelete()) { 1094 removeModule(moduleToRemove, report); 1095 } 1096 1097 // check if there are any modules to install 1098 if (m_installModules != null) { 1099 Set<String> utdModules = new HashSet<String>(getUptodateModules()); 1100 List<String> installList = Lists.newArrayList(m_installModules); 1101 for (String name : installList) { 1102 if (!utdModules.contains(name)) { 1103 String filename = m_moduleFilenames.get(name); 1104 try { 1105 updateModule(name, filename, report); 1106 } catch (Exception e) { 1107 // log a exception during module import, but make sure the next module is still imported 1108 e.printStackTrace(System.err); 1109 } 1110 } else { 1111 report.println( 1112 Messages.get().container(Messages.RPT_MODULE_UPTODATE_1, name), 1113 I_CmsReport.FORMAT_HEADLINE); 1114 } 1115 } 1116 } 1117 } 1118 } 1119 1120 /** 1121 * Fills the relations db tables during the update.<p> 1122 * 1123 * @throws Exception if something goes wrong 1124 */ 1125 public void updateRelations() throws Exception { 1126 1127 if (m_detectedVersion > 6) { 1128 // skip if not updating from 6.x 1129 return; 1130 } 1131 I_CmsReport report = new CmsShellReport(m_cms.getRequestContext().getLocale()); 1132 1133 report.println(Messages.get().container(Messages.RPT_START_UPDATE_RELATIONS_0), I_CmsReport.FORMAT_HEADLINE); 1134 1135 String storedSite = m_cms.getRequestContext().getSiteRoot(); 1136 CmsProject project = null; 1137 try { 1138 String projectName = "Update relations project"; 1139 try { 1140 // try to read a (leftover) unlock project 1141 project = m_cms.readProject(projectName); 1142 } catch (@SuppressWarnings("unused") CmsException e) { 1143 // create a Project to unlock the resources 1144 project = m_cms.createProject( 1145 projectName, 1146 projectName, 1147 OpenCms.getDefaultUsers().getGroupAdministrators(), 1148 OpenCms.getDefaultUsers().getGroupAdministrators(), 1149 CmsProject.PROJECT_TYPE_TEMPORARY); 1150 } 1151 1152 m_cms.getRequestContext().setSiteRoot(""); // change to the root site 1153 m_cms.getRequestContext().setCurrentProject(project); 1154 1155 List<I_CmsResourceType> types = OpenCms.getResourceManager().getResourceTypes(); 1156 int n = types.size(); 1157 int m = 0; 1158 Iterator<I_CmsResourceType> itTypes = types.iterator(); 1159 while (itTypes.hasNext()) { 1160 I_CmsResourceType type = itTypes.next(); 1161 m++; 1162 report.print( 1163 org.opencms.report.Messages.get().container( 1164 org.opencms.report.Messages.RPT_SUCCESSION_2, 1165 String.valueOf(m), 1166 String.valueOf(n)), 1167 I_CmsReport.FORMAT_NOTE); 1168 report.print( 1169 org.opencms.report.Messages.get().container( 1170 org.opencms.report.Messages.RPT_ARGUMENT_1, 1171 type.getTypeName())); 1172 report.print(org.opencms.report.Messages.get().container(org.opencms.report.Messages.RPT_DOTS_0)); 1173 1174 if (type instanceof I_CmsLinkParseable) { 1175 try { 1176 CmsXmlContentRepairSettings settings = new CmsXmlContentRepairSettings(m_cms); 1177 settings.setIncludeSubFolders(true); 1178 settings.setVfsFolder("/"); 1179 settings.setForce(true); 1180 settings.setResourceType(type.getTypeName()); 1181 1182 CmsXmlContentRepairThread t = new CmsXmlContentRepairThread(m_cms, settings); 1183 t.start(); 1184 1185 synchronized (this) { 1186 t.join(); 1187 } 1188 report.println( 1189 org.opencms.report.Messages.get().container(org.opencms.report.Messages.RPT_OK_0), 1190 I_CmsReport.FORMAT_OK); 1191 } catch (Exception e) { 1192 report.println( 1193 org.opencms.report.Messages.get().container(org.opencms.report.Messages.RPT_ERROR_0), 1194 I_CmsReport.FORMAT_ERROR); 1195 report.addError(e); 1196 // log the error 1197 e.printStackTrace(System.err); 1198 } 1199 } else { 1200 report.println( 1201 org.opencms.report.Messages.get().container(org.opencms.report.Messages.RPT_SKIPPED_0), 1202 I_CmsReport.FORMAT_WARNING); 1203 } 1204 } 1205 } finally { 1206 try { 1207 if (project != null) { 1208 try { 1209 m_cms.unlockProject(project.getUuid()); // unlock everything 1210 OpenCms.getPublishManager().publishProject( 1211 m_cms, 1212 report, 1213 OpenCms.getPublishManager().getPublishList(m_cms)); 1214 OpenCms.getPublishManager().waitWhileRunning(); 1215 } finally { 1216 m_cms.getRequestContext().setCurrentProject(m_cms.readProject(CmsProject.ONLINE_PROJECT_ID)); 1217 } 1218 } 1219 } finally { 1220 m_cms.getRequestContext().setSiteRoot(storedSite); 1221 } 1222 report.println( 1223 Messages.get().container(Messages.RPT_FINISH_UPDATE_RELATIONS_0), 1224 I_CmsReport.FORMAT_HEADLINE); 1225 } 1226 } 1227 1228 /** 1229 * Returns the admin Group.<p> 1230 * 1231 * @return the admin Group 1232 */ 1233 protected String getAdminGroup() { 1234 1235 return m_adminGroup; 1236 } 1237 1238 /** 1239 * Computes a list of modules which need to be removed before updating the other modules, e.g. because of resource type 1240 * conflicts.<p> 1241 * 1242 * @return the list of names of modules which need to be removed 1243 */ 1244 protected List<String> getModulesToDelete() { 1245 1246 List<String> result = new ArrayList<String>(); 1247 for (int i = 0; i < OBSOLETE_MODULES.length; i++) { 1248 if (OpenCms.getModuleManager().hasModule(OBSOLETE_MODULES[i])) { 1249 result.add(OBSOLETE_MODULES[i]); 1250 } 1251 } 1252 return result; 1253 } 1254 1255 /** 1256 * Removes a module.<p> 1257 * 1258 * @param moduleName the name of the module to remove 1259 * @param report the report to write to 1260 * 1261 * @throws CmsException in case something goes wrong 1262 */ 1263 protected void removeModule(String moduleName, I_CmsReport report) throws CmsException { 1264 1265 if (OpenCms.getModuleManager().getModule(moduleName) != null) { 1266 OpenCms.getModuleManager().deleteModule( 1267 m_cms, 1268 moduleName, 1269 true, 1270 m_preserveLibModules.contains(moduleName), 1271 report); 1272 } 1273 } 1274 1275 /** 1276 * Sets the admin Group.<p> 1277 * 1278 * @param adminGroup the admin Group to set 1279 */ 1280 protected void setAdminGroup(String adminGroup) { 1281 1282 m_adminGroup = adminGroup; 1283 } 1284 1285 /** 1286 * Imports a module (zipfile) from the default module directory, 1287 * creating a temporary project for this.<p> 1288 * 1289 * @param moduleName the name of the module to replace 1290 * @param importFile the name of the import .zip file located in the update module directory 1291 * @param report the shell report to write the output 1292 * 1293 * @throws Exception if something goes wrong 1294 * 1295 * @see org.opencms.importexport.CmsImportExportManager#importData(org.opencms.file.CmsObject, I_CmsReport, org.opencms.importexport.CmsImportParameters) 1296 */ 1297 protected void updateModule(String moduleName, String importFile, I_CmsReport report) throws Exception { 1298 1299 String fileName = getModuleFolder() + importFile; 1300 1301 report.println( 1302 Messages.get().container(Messages.RPT_BEGIN_UPDATE_MODULE_1, moduleName), 1303 I_CmsReport.FORMAT_HEADLINE); 1304 removeModule(moduleName, report); 1305 OpenCms.getPublishManager().stopPublishing(); 1306 OpenCms.getPublishManager().startPublishing(); 1307 OpenCms.getPublishManager().waitWhileRunning(); 1308 OpenCms.getImportExportManager().importData(m_cms, report, new CmsImportParameters(fileName, "/", true)); 1309 report.println( 1310 Messages.get().container(Messages.RPT_END_UPDATE_MODULE_1, moduleName), 1311 I_CmsReport.FORMAT_HEADLINE); 1312 OpenCms.getPublishManager().stopPublishing(); 1313 OpenCms.getPublishManager().startPublishing(); 1314 OpenCms.getPublishManager().waitWhileRunning(); 1315 } 1316 1317 /** 1318 * Marks all empty jars for deletion on VM exit.<p> 1319 */ 1320 private void deleteEmptyJars() { 1321 1322 File libFolder = new File(getLibFolder()); 1323 if (libFolder.exists()) { 1324 File[] emptyJars = libFolder.listFiles(new FileFilter() { 1325 1326 public boolean accept(File pathname) { 1327 1328 if (pathname.getName().endsWith(".jar")) { 1329 FileInputStream fileInput = null; 1330 JarInputStream jarStream = null; 1331 try { 1332 fileInput = new FileInputStream(pathname); 1333 jarStream = new JarInputStream(fileInput); 1334 // check the manifest for the empty jar marker attribute 1335 Manifest mf = jarStream.getManifest(); 1336 Attributes att = mf.getMainAttributes(); 1337 if ((att != null) && "true".equals(att.getValue(EMPTY_JAR_ATTRIBUTE_KEY))) { 1338 return true; 1339 } 1340 } catch (Exception e) { 1341 LOG.warn(e.getMessage(), e); 1342 } finally { 1343 if (jarStream != null) { 1344 try { 1345 jarStream.close(); 1346 } catch (IOException e) { 1347 LOG.warn(e.getMessage(), e); 1348 } 1349 } 1350 if (fileInput != null) { 1351 try { 1352 fileInput.close(); 1353 } catch (IOException e) { 1354 LOG.warn(e.getMessage(), e); 1355 } 1356 } 1357 } 1358 } 1359 return false; 1360 } 1361 }); 1362 for (int i = 0; i < emptyJars.length; i++) { 1363 emptyJars[i].deleteOnExit(); 1364 } 1365 } 1366 } 1367 1368 /** 1369 * Gets the database package name part.<p> 1370 * 1371 * @param dbName the db name from the opencms.properties file 1372 * 1373 * @return the db package name part 1374 */ 1375 private String getDbPackage(String dbName) { 1376 1377 if (dbName.contains("mysql")) { 1378 return "mysql"; 1379 } else if (dbName.contains("oracle")) { 1380 return "oracle"; 1381 } else { 1382 return dbName; 1383 } 1384 } 1385}