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.module; 029 030import org.opencms.configuration.CmsConfigurationException; 031import org.opencms.file.CmsObject; 032import org.opencms.file.CmsProject; 033import org.opencms.file.types.I_CmsResourceType; 034import org.opencms.i18n.CmsMessageContainer; 035import org.opencms.importexport.CmsExport; 036import org.opencms.importexport.CmsExportParameters; 037import org.opencms.importexport.CmsImport; 038import org.opencms.importexport.CmsImportExportException; 039import org.opencms.importexport.CmsImportExportManager; 040import org.opencms.importexport.CmsImportHelper; 041import org.opencms.importexport.CmsImportParameters; 042import org.opencms.importexport.I_CmsImportExportHandler; 043import org.opencms.main.CmsException; 044import org.opencms.main.CmsLog; 045import org.opencms.main.CmsShell; 046import org.opencms.main.CmsSystemInfo; 047import org.opencms.main.OpenCms; 048import org.opencms.module.CmsModuleXmlHandler.XmlWriteMode; 049import org.opencms.report.CmsHtmlReport; 050import org.opencms.report.I_CmsReport; 051import org.opencms.security.CmsRole; 052import org.opencms.security.CmsRoleViolationException; 053import org.opencms.security.CmsSecurityException; 054import org.opencms.util.CmsFileUtil; 055import org.opencms.util.CmsMacroResolver; 056import org.opencms.util.CmsStringUtil; 057import org.opencms.xml.CmsXmlErrorHandler; 058import org.opencms.xml.CmsXmlException; 059 060import java.io.ByteArrayInputStream; 061import java.io.ByteArrayOutputStream; 062import java.io.File; 063import java.io.FileInputStream; 064import java.io.IOException; 065import java.io.InputStream; 066import java.io.PrintStream; 067import java.util.ArrayList; 068import java.util.Arrays; 069import java.util.Collections; 070import java.util.List; 071import java.util.zip.ZipEntry; 072import java.util.zip.ZipFile; 073 074import org.apache.commons.digester3.Digester; 075import org.apache.commons.digester3.Rule; 076import org.apache.commons.logging.Log; 077 078import org.dom4j.Document; 079import org.dom4j.Element; 080import org.xml.sax.SAXException; 081 082/** 083 * Import/export handler implementation for Cms modules.<p> 084 * 085 * @since 6.0.0 086 */ 087public class CmsModuleImportExportHandler implements I_CmsImportExportHandler { 088 089 /** The log object for this class. */ 090 private static final Log LOG = CmsLog.getLog(CmsModuleImportExportHandler.class); 091 092 /** The VFS resources to be exported additionally with the module.<p> */ 093 private List<String> m_additionalResources; 094 095 /** The description of this import/export handler.<p> */ 096 private String m_description; 097 098 /** The name of the export file in the real file system.<p> */ 099 private String m_fileName; 100 101 /** The module imported with the digester. */ 102 private CmsModule m_importedModule; 103 104 /** The import parameters. */ 105 private CmsImportParameters m_importParams; 106 107 /** The (package) name of the module to be exported.<p> */ 108 private String m_moduleName; 109 110 /** 111 * Creates a new Cms module import/export handler.<p> 112 */ 113 public CmsModuleImportExportHandler() { 114 115 super(); 116 m_description = org.opencms.importexport.Messages.get().getBundle().key( 117 org.opencms.importexport.Messages.GUI_CMSIMPORTHANDLER_DEFAULT_DESC_0); 118 } 119 120 /** 121 * Gets the module export handler containing all resources used in the module export.<p> 122 * @param cms the {@link CmsObject} used by to set up the handler. The object's site root might be adjusted to the import site of the module. 123 * @param module The module to export 124 * @param handlerDescription A description of the export handler, shown when the export thread using the handler runs. 125 * @return CmsModuleImportExportHandler with all module resources 126 */ 127 public static CmsModuleImportExportHandler getExportHandler( 128 CmsObject cms, 129 final CmsModule module, 130 final String handlerDescription) { 131 132 // check if all resources are valid 133 List<String> resListCopy = new ArrayList<String>(); 134 135 String moduleName = module.getName(); 136 137 try { 138 cms = OpenCms.initCmsObject(cms); 139 String importSite = module.getSite(); 140 if (!CmsStringUtil.isEmptyOrWhitespaceOnly(importSite)) { 141 cms.getRequestContext().setSiteRoot(importSite); 142 } 143 } catch (CmsException e) { 144 // should never happen 145 LOG.error(e.getLocalizedMessage(), e); 146 } 147 try { 148 resListCopy = CmsModule.calculateModuleResourceNames(cms, module); 149 } catch (CmsException e) { 150 // some resource did not exist / could not be read 151 if (LOG.isInfoEnabled()) { 152 LOG.warn(Messages.get().getBundle().key(Messages.ERR_READ_MODULE_RESOURCES_1, module.getName()), e); 153 } 154 } 155 resListCopy = CmsFileUtil.removeRedundancies(resListCopy); 156 String[] resources = new String[resListCopy.size()]; 157 158 for (int i = 0; i < resListCopy.size(); i++) { 159 resources[i] = resListCopy.get(i); 160 } 161 162 String filename = OpenCms.getSystemInfo().getAbsoluteRfsPathRelativeToWebInf( 163 OpenCms.getSystemInfo().getPackagesRfsPath() 164 + CmsSystemInfo.FOLDER_MODULES 165 + moduleName 166 + "_" 167 + "%(version)"); 168 169 CmsModuleImportExportHandler moduleExportHandler = new CmsModuleImportExportHandler(); 170 moduleExportHandler.setFileName(filename); 171 moduleExportHandler.setModuleName(moduleName.replace('\\', '/')); 172 moduleExportHandler.setAdditionalResources(resources); 173 moduleExportHandler.setDescription(handlerDescription); 174 175 return moduleExportHandler; 176 } 177 178 /** 179 * Reads a module object from an external file source.<p> 180 * 181 * @param importResource the name of the input source 182 * 183 * @return the imported module 184 * 185 * @throws CmsConfigurationException if the module could not be imported 186 */ 187 public static CmsModule readModuleFromImport(String importResource) throws CmsConfigurationException { 188 189 // instantiate Digester and enable XML validation 190 Digester digester = new Digester(); 191 digester.setUseContextClassLoader(true); 192 digester.setValidating(false); 193 digester.setRuleNamespaceURI(null); 194 digester.setErrorHandler(new CmsXmlErrorHandler(importResource)); 195 196 // add this class to the Digester 197 CmsModuleImportExportHandler handler = new CmsModuleImportExportHandler(); 198 final String[] version = new String[] {null}; 199 digester.push(handler); 200 201 digester.addRule("*/export_version", new Rule() { 202 203 @Override 204 public void body(String namespace, String name, String text) throws Exception { 205 206 version[0] = text.trim(); 207 } 208 209 }); 210 CmsModuleXmlHandler.addXmlDigesterRules(digester); 211 212 InputStream stream = null; 213 ZipFile importZip = null; 214 215 try { 216 File file = new File(importResource); 217 if (file.isFile()) { 218 importZip = new ZipFile(importResource); 219 ZipEntry entry = importZip.getEntry(CmsImportExportManager.EXPORT_MANIFEST); 220 if (entry != null) { 221 stream = importZip.getInputStream(entry); 222 } else { 223 CmsMessageContainer message = Messages.get().container( 224 Messages.ERR_NO_MANIFEST_MODULE_IMPORT_1, 225 importResource); 226 LOG.error(message.key()); 227 throw new CmsConfigurationException(message); 228 } 229 } else if (file.isDirectory()) { 230 file = new File(file, CmsImportExportManager.EXPORT_MANIFEST); 231 stream = new FileInputStream(file); 232 } 233 234 // start the parsing process 235 digester.parse(stream); 236 } catch (IOException e) { 237 CmsMessageContainer message = Messages.get().container(Messages.ERR_IO_MODULE_IMPORT_1, importResource); 238 LOG.error(message.key(), e); 239 throw new CmsConfigurationException(message, e); 240 } catch (SAXException e) { 241 CmsMessageContainer message = Messages.get().container(Messages.ERR_SAX_MODULE_IMPORT_1, importResource); 242 LOG.error(message.key(), e); 243 throw new CmsConfigurationException(message, e); 244 } finally { 245 try { 246 if (importZip != null) { 247 importZip.close(); 248 } 249 if (stream != null) { 250 stream.close(); 251 } 252 } catch (Exception e) { 253 // noop 254 } 255 } 256 257 CmsModule importedModule = handler.getModule(); 258 // the digester must have set the module now 259 if (importedModule == null) { 260 throw new CmsConfigurationException( 261 Messages.get().container(Messages.ERR_IMPORT_MOD_ALREADY_INSTALLED_1, importResource)); 262 } else { 263 importedModule.setExportVersion(version[0]); 264 } 265 266 return importedModule; 267 } 268 269 /** 270 * Reads a module object from an external file source.<p> 271 * 272 * @param manifest the manifest data 273 * 274 * @return the imported module 275 * 276 * @throws CmsConfigurationException if the module could not be imported 277 */ 278 public static CmsModule readModuleFromManifest(byte[] manifest) throws CmsConfigurationException { 279 280 // instantiate Digester and enable XML validation 281 Digester digester = new Digester(); 282 digester.setUseContextClassLoader(true); 283 digester.setValidating(false); 284 digester.setRuleNamespaceURI(null); 285 digester.setErrorHandler(new CmsXmlErrorHandler("manifest data")); 286 287 // add this class to the Digester 288 CmsModuleImportExportHandler handler = new CmsModuleImportExportHandler(); 289 final String[] version = new String[] {null}; 290 digester.push(handler); 291 292 digester.addRule("*/export_version", new Rule() { 293 294 @Override 295 public void body(String namespace, String name, String text) throws Exception { 296 297 version[0] = text.trim(); 298 } 299 300 }); 301 CmsModuleXmlHandler.addXmlDigesterRules(digester); 302 303 InputStream stream = new ByteArrayInputStream(manifest); 304 305 try { 306 digester.parse(stream); 307 } catch (IOException e) { 308 CmsMessageContainer message = Messages.get().container(Messages.ERR_IO_MODULE_IMPORT_1, "manifest data"); 309 LOG.error(message.key(), e); 310 throw new CmsConfigurationException(message, e); 311 } catch (SAXException e) { 312 CmsMessageContainer message = Messages.get().container(Messages.ERR_SAX_MODULE_IMPORT_1, "manifest data"); 313 LOG.error(message.key(), e); 314 throw new CmsConfigurationException(message, e); 315 } 316 CmsModule importedModule = handler.getModule(); 317 // the digester must have set the module now 318 if (importedModule == null) { 319 throw new CmsConfigurationException( 320 Messages.get().container(Messages.ERR_IMPORT_MOD_ALREADY_INSTALLED_1, "manifest data")); 321 } else { 322 importedModule.setExportVersion(version[0]); 323 } 324 325 return importedModule; 326 } 327 328 /** 329 * Writes the messages for starting an import to the given report.<p> 330 * 331 * @param report the report to write to 332 * @param modulePackageName the module name 333 */ 334 public static void reportBeginImport(I_CmsReport report, String modulePackageName) { 335 336 report.print(Messages.get().container(Messages.RPT_IMPORT_MODULE_BEGIN_0), I_CmsReport.FORMAT_HEADLINE); 337 if (report instanceof CmsHtmlReport) { 338 report.print( 339 org.opencms.report.Messages.get().container( 340 org.opencms.report.Messages.RPT_ARGUMENT_1, 341 "<i>" + modulePackageName + "</i>")); 342 } else { 343 report.print( 344 org.opencms.report.Messages.get().container( 345 org.opencms.report.Messages.RPT_ARGUMENT_1, 346 modulePackageName)); 347 } 348 report.println(org.opencms.report.Messages.get().container(org.opencms.report.Messages.RPT_DOTS_0)); 349 } 350 351 /** 352 * Writes the messages for finishing an import to the given report.<p> 353 * 354 * @param report the report to write to 355 */ 356 public static void reportEndImport(I_CmsReport report) { 357 358 report.println(Messages.get().container(Messages.RPT_IMPORT_MODULE_END_0), I_CmsReport.FORMAT_HEADLINE); 359 } 360 361 /** 362 * @see org.opencms.importexport.I_CmsImportExportHandler#exportData(org.opencms.file.CmsObject, org.opencms.report.I_CmsReport) 363 */ 364 public void exportData(CmsObject cms, I_CmsReport report) 365 throws CmsConfigurationException, CmsImportExportException, CmsRoleViolationException { 366 367 // check if the user has the required permissions 368 OpenCms.getRoleManager().checkRole(cms, CmsRole.DATABASE_MANAGER); 369 370 report.print(Messages.get().container(Messages.RPT_EXPORT_MODULE_BEGIN_0), I_CmsReport.FORMAT_HEADLINE); 371 if (report instanceof CmsHtmlReport) { 372 report.print( 373 org.opencms.report.Messages.get().container( 374 org.opencms.report.Messages.RPT_ARGUMENT_1, 375 "<i>" + getModuleName() + "</i>")); 376 377 } else { 378 report.print( 379 org.opencms.report.Messages.get().container( 380 org.opencms.report.Messages.RPT_ARGUMENT_1, 381 getModuleName())); 382 } 383 report.print(org.opencms.report.Messages.get().container(org.opencms.report.Messages.RPT_DOTS_0)); 384 385 if (!OpenCms.getModuleManager().hasModule(getModuleName())) { 386 // module not available 387 throw new CmsConfigurationException( 388 Messages.get().container(Messages.ERR_NO_MOD_FOR_EXPORT_1, getModuleName())); 389 } 390 391 // generate module XML 392 CmsModule module = OpenCms.getModuleManager().getModule(getModuleName()); 393 boolean shouldIncrementVersion; 394 try { 395 shouldIncrementVersion = module.isAutoIncrement() 396 && (module.getVersion().isUpdated() || module.shouldIncrementVersionBasedOnResources(cms)); 397 } catch (CmsException e) { 398 shouldIncrementVersion = false; 399 LOG.error(e.getLocalizedMessage(), e); 400 } 401 module.getVersion().setUpdated(false); 402 if (shouldIncrementVersion) { 403 module.getVersion().increment(); 404 module.setCheckpointTime(System.currentTimeMillis()); 405 OpenCms.getModuleManager().updateModuleConfiguration(); 406 } 407 408 Element moduleElement = CmsModuleXmlHandler.generateXml(module, XmlWriteMode.manifest); 409 410 CmsExportParameters params = new CmsExportParameters( 411 getFileName(), 412 moduleElement, 413 true, 414 false, 415 false, 416 getAdditionalResources(), 417 true, 418 true, 419 0, 420 true, 421 false, 422 module.getExportMode(), 423 // provide the extra resources only in case of excluded resources, otherwise not needed 424 ((null == module.getExcludeResources()) || module.getExcludeResources().isEmpty()) 425 ? null 426 : module.getResources()); 427 428 // export the module using the standard export 429 CmsObject exportCms = cms; 430 String importSite = module.getSite(); 431 if (!CmsStringUtil.isEmptyOrWhitespaceOnly(importSite)) { 432 try { 433 exportCms = OpenCms.initCmsObject(exportCms); 434 exportCms.getRequestContext().setSiteRoot(importSite); 435 } catch (Exception e) { 436 LOG.error(e.getLocalizedMessage(), e); 437 } 438 } 439 new CmsExport(exportCms, report).exportData(params); 440 report.println(Messages.get().container(Messages.RPT_EXPORT_MODULE_END_0), I_CmsReport.FORMAT_HEADLINE); 441 } 442 443 /** 444 * Returns the VFS resources to be exported additionally with the module.<p> 445 * 446 * @return the VFS resources to be exported additionally with the module 447 */ 448 public List<String> getAdditionalResources() { 449 450 return m_additionalResources; 451 } 452 453 /** 454 * @see org.opencms.importexport.I_CmsImportExportHandler#getDescription() 455 */ 456 public String getDescription() { 457 458 return m_description; 459 } 460 461 /** 462 * Returns the name of the export file in the real file system.<p> 463 * 464 * @return the name of the export file in the real file system 465 */ 466 public String getFileName() { 467 468 CmsMacroResolver resolver = new CmsMacroResolver(); 469 resolver.addMacro("version", OpenCms.getModuleManager().getModule(m_moduleName).getVersionStr()); 470 return resolver.resolveMacros(m_fileName); 471 } 472 473 /** 474 * Returns the import parameters.<p> 475 * 476 * @return the import parameters 477 */ 478 public CmsImportParameters getImportParameters() { 479 480 return m_importParams; 481 } 482 483 /** 484 * Returns the (package) name of the module to be exported.<p> 485 * 486 * @return the (package) name of the module to be exported 487 */ 488 public String getModuleName() { 489 490 return m_moduleName; 491 } 492 493 /** 494 * Returns the VFS resources to be exported additionally with the module as a list.<p> 495 * 496 * @return the VFS resources to be exported additionally with the module as a list 497 */ 498 public List<String> getResourcesAsList() { 499 500 return m_additionalResources; 501 } 502 503 /** 504 * @see org.opencms.importexport.I_CmsImportExportHandler#importData(CmsObject, I_CmsReport) 505 */ 506 public synchronized void importData(CmsObject cms, I_CmsReport report) 507 throws CmsXmlException, CmsImportExportException, CmsRoleViolationException, CmsException { 508 509 CmsImportParameters parameters = getImportParameters(); 510 CmsProject previousProject = cms.getRequestContext().getCurrentProject(); 511 try { 512 CmsProject importProject = null; 513 String modulePackageName = null; 514 String storedSiteRoot = cms.getRequestContext().getSiteRoot(); 515 CmsImportHelper helper = new CmsImportHelper(parameters); 516 try { 517 cms.getRequestContext().setSiteRoot("/"); 518 helper.openFile(); 519 modulePackageName = helper.getFileName(); 520 521 try { 522 // try to read a (leftover) module import project 523 importProject = cms.readProject( 524 Messages.get().getBundle(cms.getRequestContext().getLocale()).key( 525 Messages.GUI_IMPORT_MODULE_PROJECT_NAME_1, 526 new Object[] {modulePackageName})); 527 } catch (CmsException e) { 528 // create a Project to import the module 529 importProject = cms.createProject( 530 Messages.get().getBundle(cms.getRequestContext().getLocale()).key( 531 Messages.GUI_IMPORT_MODULE_PROJECT_NAME_1, 532 new Object[] {modulePackageName}), 533 Messages.get().getBundle(cms.getRequestContext().getLocale()).key( 534 Messages.GUI_IMPORT_MODULE_PROJECT_DESC_1, 535 new Object[] {modulePackageName}), 536 OpenCms.getDefaultUsers().getGroupAdministrators(), 537 OpenCms.getDefaultUsers().getGroupAdministrators(), 538 CmsProject.PROJECT_TYPE_TEMPORARY); 539 } 540 541 cms.getRequestContext().setCurrentProject(importProject); 542 543 // copy the root folder to the project 544 cms.copyResourceToProject("/"); 545 } catch (Exception e) { 546 throw new CmsImportExportException( 547 Messages.get().container(Messages.ERR_IO_MODULE_IMPORT_1, parameters.getPath()), 548 e); 549 } finally { 550 helper.closeFile(); 551 cms.getRequestContext().setSiteRoot(storedSiteRoot); 552 } 553 554 reportBeginImport(report, modulePackageName); 555 importModule(cms, report, parameters); 556 report.println(Messages.get().container(Messages.RPT_PUBLISH_PROJECT_BEGIN_0), I_CmsReport.FORMAT_HEADLINE); 557 // now unlock and publish the project 558 cms.unlockProject(importProject.getUuid()); 559 OpenCms.getPublishManager().publishProject(cms, report); 560 OpenCms.getPublishManager().waitWhileRunning(); 561 562 report.println(Messages.get().container(Messages.RPT_PUBLISH_PROJECT_END_0), I_CmsReport.FORMAT_HEADLINE); 563 reportEndImport(report); 564 } finally { 565 cms.getRequestContext().setCurrentProject(previousProject); 566 } 567 } 568 569 /** 570 * @see org.opencms.importexport.I_CmsImportExportHandler#importData(org.opencms.file.CmsObject, java.lang.String, java.lang.String, org.opencms.report.I_CmsReport) 571 * 572 * @deprecated use {@link #importData(CmsObject, I_CmsReport)} instead 573 */ 574 @Deprecated 575 public void importData(CmsObject cms, String importFile, String importPath, I_CmsReport report) 576 throws CmsXmlException, CmsImportExportException, CmsRoleViolationException, CmsException { 577 578 CmsImportParameters parameters = new CmsImportParameters(importFile, importPath, true); 579 setImportParameters(parameters); 580 581 importData(cms, report); 582 } 583 584 /** 585 * @see org.opencms.importexport.I_CmsImportExportHandler#matches(org.dom4j.Document) 586 */ 587 public boolean matches(Document manifest) { 588 589 Element rootElement = manifest.getRootElement(); 590 591 return (rootElement.selectNodes("./module/name").size() > 0); 592 } 593 594 /** 595 * Sets the VFS resources to be exported additionally with the module.<p> 596 * 597 * @param resources the VFS resources to be exported additionally with the module 598 */ 599 public void setAdditionalResources(String[] resources) { 600 601 m_additionalResources = Arrays.asList(resources); 602 } 603 604 /** 605 * @see org.opencms.importexport.I_CmsImportExportHandler#setDescription(java.lang.String) 606 */ 607 public void setDescription(String description) { 608 609 m_description = description; 610 } 611 612 /** 613 * Sets the name of the export file in the real file system.<p> 614 * 615 * @param fileName the name of the export file in the real file system 616 */ 617 public void setFileName(String fileName) { 618 619 m_fileName = fileName; 620 } 621 622 /** 623 * Sets the import parameters.<p> 624 * 625 * @param importParams the parameters to set 626 */ 627 public void setImportParameters(CmsImportParameters importParams) { 628 629 m_importParams = importParams; 630 } 631 632 /** 633 * Will be called by the digester if a module was imported.<p> 634 * 635 * @param moduleHandler contains the imported module 636 */ 637 public void setModule(CmsModuleXmlHandler moduleHandler) { 638 639 m_importedModule = moduleHandler.getModule(); 640 } 641 642 /** 643 * Sets the (package) name of the module to be exported.<p> 644 * 645 * @param moduleName the (package) name of the module to be exported 646 */ 647 public void setModuleName(String moduleName) { 648 649 m_moduleName = moduleName; 650 } 651 652 /** 653 * Returns the module imported with the digester.<p> 654 * 655 * @return the module imported with the digester 656 */ 657 private CmsModule getModule() { 658 659 return m_importedModule; 660 } 661 662 /** 663 * Imports a module from an external file source.<p> 664 * 665 * @param cms must have been initialized with {@link CmsRole#DATABASE_MANAGER} permissions 666 * @param report the report to print the progress information to 667 * @param parameters the import parameters 668 * 669 * @return the imported module 670 * 671 * @throws CmsSecurityException if no {@link CmsRole#DATABASE_MANAGER} permissions are available 672 * @throws CmsConfigurationException if the module is already installed or the 673 * dependencies are not fulfilled 674 * @throws CmsException if errors occur reading the module data 675 */ 676 private synchronized CmsModule importModule(CmsObject cms, I_CmsReport report, CmsImportParameters parameters) 677 throws CmsSecurityException, CmsConfigurationException, CmsException { 678 679 // check if the user has the required permissions 680 OpenCms.getRoleManager().checkRole(cms, CmsRole.DATABASE_MANAGER); 681 682 // read the module from the import file 683 CmsModule importedModule = readModuleFromImport(parameters.getPath()); 684 685 // check if the module is already installed 686 if (OpenCms.getModuleManager().hasModule(importedModule.getName())) { 687 throw new CmsConfigurationException( 688 Messages.get().container(Messages.ERR_MOD_ALREADY_INSTALLED_1, importedModule.getName())); 689 } 690 691 // check the module dependencies 692 List<CmsModuleDependency> dependencies = OpenCms.getModuleManager().checkDependencies( 693 importedModule, 694 CmsModuleManager.DEPENDENCY_MODE_IMPORT); 695 if (dependencies.size() > 0) { 696 // some dependencies not fulfilled 697 StringBuffer missingModules = new StringBuffer(); 698 for (CmsModuleDependency dependency : dependencies) { 699 missingModules.append(" ").append(dependency.getName()).append(", Version ").append( 700 dependency.getVersion()).append("\r\n"); 701 } 702 throw new CmsConfigurationException( 703 Messages.get().container( 704 Messages.ERR_MOD_DEPENDENCY_INFO_2, 705 importedModule.getName() + ", Version " + importedModule.getVersion(), 706 missingModules)); 707 } 708 709 // check the imported resource types for name / id conflicts 710 List<I_CmsResourceType> checkedTypes = new ArrayList<I_CmsResourceType>(); 711 for (I_CmsResourceType type : importedModule.getResourceTypes()) { 712 // first check against the already configured resource types 713 int externalConflictIndex = OpenCms.getResourceManager().getResourceTypes().indexOf(type); 714 if (externalConflictIndex >= 0) { 715 I_CmsResourceType conflictingType = OpenCms.getResourceManager().getResourceTypes().get( 716 externalConflictIndex); 717 if (!type.isIdentical(conflictingType)) { 718 // if name and id are identical, we assume this is a module replace operation 719 throw new CmsConfigurationException( 720 org.opencms.loader.Messages.get().container( 721 org.opencms.loader.Messages.ERR_CONFLICTING_MODULE_RESOURCE_TYPES_5, 722 new Object[] { 723 type.getTypeName(), 724 new Integer(type.getTypeId()), 725 importedModule.getName(), 726 conflictingType.getTypeName(), 727 new Integer(conflictingType.getTypeId())})); 728 } 729 } 730 // now check against the other resource types of the imported module 731 int internalConflictIndex = checkedTypes.indexOf(type); 732 if (internalConflictIndex >= 0) { 733 I_CmsResourceType conflictingType = checkedTypes.get(internalConflictIndex); 734 throw new CmsConfigurationException( 735 org.opencms.loader.Messages.get().container( 736 org.opencms.loader.Messages.ERR_CONFLICTING_RESTYPES_IN_MODULE_5, 737 new Object[] { 738 importedModule.getName(), 739 type.getTypeName(), 740 new Integer(type.getTypeId()), 741 conflictingType.getTypeName(), 742 new Integer(conflictingType.getTypeId())})); 743 } 744 // add the resource type for the next check 745 checkedTypes.add(type); 746 } 747 748 // import the module resources 749 CmsObject importCms = OpenCms.initCmsObject(cms); 750 String importSite = importedModule.getImportSite(); 751 if (!CmsStringUtil.isEmptyOrWhitespaceOnly(importSite)) { 752 importCms.getRequestContext().setSiteRoot(importSite); 753 } else { 754 String siteToSet = importCms.getRequestContext().getSiteRoot(); 755 if ("".equals(siteToSet)) { 756 siteToSet = "/"; 757 } 758 importedModule.setSite(siteToSet); 759 } 760 761 // add the imported module to the module manager 762 OpenCms.getModuleManager().addModule(cms, importedModule); 763 764 // reinitialize the resource manager with additional module resource types if necessary 765 if (importedModule.getResourceTypes() != Collections.EMPTY_LIST) { 766 OpenCms.getResourceManager().initialize(cms); 767 } 768 // reinitialize the workplace manager with additional module explorer types if necessary 769 if (importedModule.getExplorerTypes() != Collections.EMPTY_LIST) { 770 OpenCms.getWorkplaceManager().addExplorerTypeSettings(importedModule); 771 } 772 773 CmsImport cmsImport = new CmsImport(importCms, report); 774 cmsImport.importData(parameters); 775 String importScript = importedModule.getImportScript(); 776 if (!CmsStringUtil.isEmptyOrWhitespaceOnly(importScript)) { 777 LOG.info("Executing import script for module " + importedModule.getName()); 778 report.println(Messages.get().container(Messages.RPT_IMPORT_SCRIPT_HEADER_0), I_CmsReport.FORMAT_HEADLINE); 779 importScript = "echo on\n" + importScript; 780 ByteArrayOutputStream buffer = new ByteArrayOutputStream(); 781 PrintStream out = new PrintStream(buffer); 782 CmsShell shell = new CmsShell(cms, "${user}@${project}:${siteroot}|${uri}>", null, out, out); 783 shell.execute(importScript); 784 String outputString = buffer.toString(); 785 LOG.info("Shell output for import script was: \n" + outputString); 786 report.println(Messages.get().container(Messages.RPT_IMPORT_SCRIPT_OUTPUT_1, outputString)); 787 } 788 importedModule.setCheckpointTime(System.currentTimeMillis()); 789 OpenCms.getModuleManager().updateModuleConfiguration(); 790 return importedModule; 791 } 792}