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, 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.ui.actions.prefillpage; 029 030import org.opencms.ade.configuration.CmsADEConfigData; 031import org.opencms.file.CmsFile; 032import org.opencms.file.CmsObject; 033import org.opencms.file.CmsResource; 034import org.opencms.file.CmsResourceFilter; 035import org.opencms.lock.CmsLockUtil; 036import org.opencms.main.CmsLog; 037import org.opencms.main.OpenCms; 038import org.opencms.ui.I_CmsDialogContext; 039import org.opencms.util.CmsMacroResolver; 040import org.opencms.xml.containerpage.CmsContainerBean; 041import org.opencms.xml.containerpage.CmsContainerPageBean; 042import org.opencms.xml.containerpage.CmsXmlContainerPage; 043import org.opencms.xml.containerpage.CmsXmlContainerPageFactory; 044import org.opencms.xml.containerpage.mutable.CmsMutableContainerPage; 045 046import org.apache.commons.logging.Log; 047 048/** 049 * Pre-fills the page by adding contents from a template page into a specific container of the page to fill. 050 */ 051public class CmsStaticPrefillPageHandler implements I_CmsPrefillPageHandler { 052 053 /** Logger instance for this class. */ 054 private static final Log LOG = CmsLog.getLog(CmsStaticPrefillPageHandler.class); 055 056 /** The sitemap attribute used to configure the container which should be filled. */ 057 private static final String ATTR_PREFILL_CONTAINER = "template.prefill.container"; 058 059 /** The sitemap attribute used to configure the prefill template. */ 060 private static final String ATTR_PREFILL_TEMPLATE = "template.prefill.file"; 061 062 /** 063 * @see org.opencms.ui.actions.prefillpage.I_CmsPrefillPageHandler#execute(org.opencms.ui.I_CmsDialogContext) 064 */ 065 public void execute(I_CmsDialogContext context) { 066 067 CmsObject cms = context.getCms(); 068 CmsResource resource = context.getResources().get(0); 069 CmsADEConfigData config = OpenCms.getADEManager().lookupConfiguration(cms, resource.getRootPath()); 070 try (AutoCloseable c = CmsLockUtil.withLockedResources(cms, resource)) { 071 CmsFile file = cms.readFile(resource); 072 CmsXmlContainerPage pageXml = CmsXmlContainerPageFactory.unmarshal(cms, file); 073 CmsContainerPageBean page = pageXml.getContainerPage(cms); 074 String containerName = config.getAttribute(ATTR_PREFILL_CONTAINER, null); 075 CmsResource prefillTemplate = getPrefillTemplate(cms, resource); 076 if (prefillTemplate == null) { 077 // context menu option should not be available if prefill template is not available 078 throw new RuntimeException("Prefill template not found in subsitemap " + config.getBasePath()); 079 } 080 CmsContainerBean container = page.getContainers().get(containerName); 081 if (container == null) { 082 CmsFile templatePageFile = cms.readFile(prefillTemplate); 083 CmsXmlContainerPage templatePageXml = CmsXmlContainerPageFactory.unmarshal(cms, templatePageFile); 084 CmsContainerPageBean templatePage = templatePageXml.getContainerPage(cms); 085 CmsMutableContainerPage pageToRewrite = CmsMutableContainerPage.fromImmutable(page); 086 CmsMutableContainerPage templatePageBean = CmsMutableContainerPage.fromImmutable(templatePage); 087 pageToRewrite.containers().addAll(templatePageBean.containers()); 088 pageXml.save(cms, pageToRewrite.toImmutable()); 089 } 090 context.reload(); 091 } catch (Exception e) { 092 LOG.error(e.getLocalizedMessage(), e); 093 context.error(e); 094 } 095 096 } 097 098 /** 099 * @see org.opencms.ui.actions.prefillpage.I_CmsPrefillPageHandler#isExecutable(org.opencms.ui.I_CmsDialogContext) 100 */ 101 public boolean isExecutable(I_CmsDialogContext context) { 102 103 CmsObject cms = context.getCms(); 104 CmsResource resource = context.getResources().get(0); 105 CmsADEConfigData config = OpenCms.getADEManager().lookupConfiguration(cms, resource.getRootPath()); 106 String containerName = config.getAttribute(ATTR_PREFILL_CONTAINER, null); 107 if (containerName == null) { 108 return false; 109 } 110 CmsResource prefillTemplate = getPrefillTemplate(cms, resource); 111 if (prefillTemplate == null) { 112 return false; 113 } 114 115 try { 116 // check that the container doesn't exist yet in the container page 117 try { 118 CmsFile file = cms.readFile(resource); 119 CmsXmlContainerPage pageXml = CmsXmlContainerPageFactory.unmarshal(cms, file); 120 CmsContainerPageBean page = pageXml.getContainerPage(cms); 121 CmsContainerBean container = page.getContainers().get(containerName); 122 if (container != null) { 123 return false; 124 } 125 return true; 126 } catch (Exception e) { 127 LOG.error(e.getLocalizedMessage(), e); 128 return false; 129 } 130 } catch (Exception e) { 131 LOG.error(e.getLocalizedMessage(), e); 132 } 133 return false; 134 } 135 136 /** 137 * Gets the container page to use as a prefill template for the given page. 138 * 139 * @param cms the current CMS context 140 * @param resource the currently edited container page 141 * @return the prefill template resource, or null if none was configured or the configured one was not found 142 */ 143 private CmsResource getPrefillTemplate(CmsObject cms, CmsResource resource) { 144 145 try { 146 147 CmsADEConfigData config = OpenCms.getADEManager().lookupConfiguration(cms, resource.getRootPath()); 148 String prefillTemplateStr = config.getAttribute(ATTR_PREFILL_TEMPLATE, null); 149 if (prefillTemplateStr == null) { 150 return null; 151 } 152 CmsMacroResolver resolver = new CmsMacroResolver(); 153 resolver.setCmsObject(cms); 154 String subsite = cms.getRequestContext().removeSiteRoot( 155 OpenCms.getADEManager().getSubSiteRoot(cms, resource.getRootPath())); 156 if (subsite != null) { 157 resolver.addMacro("subsite", subsite); 158 } 159 // remove duplicate slashes in case subsite macro contains a trailing slash and is used as %(subsite)/xyz 160 prefillTemplateStr = resolver.resolveMacros(prefillTemplateStr).replace("//", "/"); 161 return cms.readResource(prefillTemplateStr, CmsResourceFilter.IGNORE_EXPIRATION); 162 } catch (Exception e) { 163 LOG.info(e.getLocalizedMessage(), e); 164 return null; 165 } 166 167 } 168 169}