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.xml.templatemapper;
029
030import org.opencms.file.CmsObject;
031import org.opencms.file.CmsResource;
032import org.opencms.file.CmsResourceFilter;
033import org.opencms.file.types.CmsResourceTypeXmlContainerPage;
034import org.opencms.file.types.I_CmsResourceType;
035import org.opencms.i18n.CmsMessageContainer;
036import org.opencms.lock.CmsLockUtil;
037import org.opencms.main.CmsException;
038import org.opencms.main.CmsLog;
039import org.opencms.main.OpenCms;
040import org.opencms.module.CmsModule;
041import org.opencms.report.A_CmsReportThread;
042import org.opencms.report.I_CmsReport;
043import org.opencms.ui.Messages;
044import org.opencms.util.CmsExpiringValue;
045import org.opencms.xml.containerpage.CmsContainerPageBean;
046import org.opencms.xml.containerpage.CmsGroupContainerBean;
047import org.opencms.xml.containerpage.CmsXmlContainerPage;
048import org.opencms.xml.containerpage.CmsXmlContainerPageFactory;
049import org.opencms.xml.containerpage.CmsXmlGroupContainer;
050import org.opencms.xml.containerpage.CmsXmlGroupContainerFactory;
051
052import java.util.Collections;
053import java.util.List;
054import java.util.Locale;
055
056import org.apache.commons.logging.Log;
057
058/**
059 * Report thread for rewriting pages in a folder according to a given template mapper configuration.<p>
060 */
061public class CmsTemplateMappingContentRewriter extends A_CmsReportThread {
062
063    /** Cache for the status. */
064    private static CmsExpiringValue<Boolean> m_moduleCheckCache = new CmsExpiringValue<>(2000);
065
066    /** The logger instance for the class. */
067    private static final Log LOG = CmsLog.getLog(CmsTemplateMappingContentRewriter.class);
068
069    /** The folder path. */
070    private String m_folder;
071
072    /** The folder resource. */
073    private CmsResource m_folderRes;
074
075    /**
076     * Creates a new instance.<p>
077     *
078     * @param cms the CMS context
079     * @param folder the folder to process
080     *
081     * @throws CmsException if something goes wrong
082     */
083    protected CmsTemplateMappingContentRewriter(CmsObject cms, CmsResource folder)
084    throws CmsException {
085
086        super(
087            OpenCms.initCmsObject(cms),
088            CmsTemplateMappingContentRewriter.class.getName() + "-" + Thread.currentThread().getId());
089        m_folder = cms.getSitePath(folder);
090        m_folderRes = folder;
091        initHtmlReport(OpenCms.getWorkplaceManager().getWorkplaceLocale(cms));
092    }
093
094    /**
095     * Checks if template mapper is configured in modules.
096     *
097     * @return true if the template mapper is configured in modules
098     */
099    public static boolean checkConfiguredInModules() {
100
101        Boolean result = m_moduleCheckCache.get();
102        if (result == null) {
103            result = Boolean.valueOf(getConfiguredTemplateMapping() != null);
104            m_moduleCheckCache.set(result);
105        }
106        return result.booleanValue();
107    }
108
109    /**
110     * Tries to read the path to the template mapping file from module parameters.<p>
111     *
112     * @return the template mapping file path
113     */
114    public static String getConfiguredTemplateMapping() {
115
116        String param = null;
117        for (CmsModule module : OpenCms.getModuleManager().getAllInstalledModules()) {
118            param = module.getParameter("template-mapping");
119            if (param != null) {
120                break;
121            }
122        }
123        return param;
124    }
125
126    /**
127     * @see org.opencms.report.A_CmsReportThread#getReportUpdate()
128     */
129    @Override
130    public String getReportUpdate() {
131
132        return getReport().getReportUpdate();
133    }
134
135    /**
136     * @see java.lang.Thread#run()
137     */
138    @Override
139    public void run() {
140
141        CmsObject cms = getCms();
142        I_CmsReport report = getReport();
143        try {
144            String file = getConfiguredTemplateMapping();
145            cms.readResource(file);
146            CmsLockUtil.ensureLock(cms, m_folderRes);
147            CmsTemplateMapper mapper = new CmsTemplateMapper(file);
148            mapper.setForSave(true);
149            List<CmsResource> pages = resourcesForType(m_folder, CmsResourceTypeXmlContainerPage.getStaticTypeName());
150            int j = 0;
151            for (CmsResource page : pages) {
152                j++;
153                try {
154                    report.println(
155                        message(
156                            Messages.RPT_TEMPLATEMAPPER_PROCESSING_PAGE_2,
157                            "" + j + "/" + pages.size(),
158                            page.getRootPath()));
159                    CmsXmlContainerPage pageXml = CmsXmlContainerPageFactory.unmarshal(cms, cms.readFile(page));
160                    CmsContainerPageBean bean = pageXml.getContainerPage(cms);
161                    CmsContainerPageBean transformedBean = mapper.transformContainerpageBean(
162                        cms,
163                        bean,
164                        page.getRootPath());
165                    pageXml.save(cms, transformedBean);
166                } catch (Exception e) {
167                    LOG.error(e.getLocalizedMessage(), e);
168                    getReport().println(e);
169                }
170
171            }
172
173            List<CmsResource> groups = resourcesForType(
174                m_folder,
175                CmsResourceTypeXmlContainerPage.GROUP_CONTAINER_TYPE_NAME);
176            j = 0;
177            for (CmsResource group : groups) {
178                try {
179                    j++;
180                    report.println(
181                        message(
182                            Messages.RPT_TEMPLATEMAPPER_PROCESSING_GROUP_2,
183                            "" + j + "/" + groups.size(),
184                            group.getRootPath()));
185                    CmsXmlGroupContainer groupXml = CmsXmlGroupContainerFactory.unmarshal(cms, cms.readFile(group));
186                    CmsGroupContainerBean groupContainer = groupXml.getGroupContainer(cms);
187                    CmsGroupContainerBean transformedContainer = mapper.transformGroupContainer(
188                        cms,
189                        groupContainer,
190                        group.getRootPath());
191
192                    groupXml.save(cms, transformedContainer, Locale.ENGLISH);
193                } catch (Exception e) {
194                    LOG.error(e.getLocalizedMessage(), e);
195                    getReport().println(e);
196                }
197            }
198            CmsLockUtil.tryUnlock(cms, m_folderRes);
199            report.println(message(Messages.RPT_TEMPLATEMAPPER_DONE_0));
200        } catch (Exception e) {
201            LOG.error(e.getLocalizedMessage(), e);
202            getReport().println(e);
203        }
204
205    }
206
207    /**
208     * Gets a message container.<p>
209     *
210     * @param key the key
211     * @param args the message parameters
212     *
213     * @return the message container
214     */
215    CmsMessageContainer message(String key, String... args) {
216
217        return Messages.get().container(key, args);
218
219    }
220
221    /**
222     * Reads resources of some type in the given folder.<p>
223     *
224     * @param folder the folder
225     * @param name the type name
226     * @return the list of resources of the given type in the given folder
227     */
228    private List<CmsResource> resourcesForType(String folder, String name) {
229
230        try {
231            CmsObject cms = getCms();
232            I_CmsResourceType type = OpenCms.getResourceManager().getResourceType(name);
233            CmsResourceFilter filter = CmsResourceFilter.IGNORE_EXPIRATION.addRequireType(type);
234            return cms.readResources(folder, filter);
235        } catch (CmsException e) {
236            LOG.error(e.getLocalizedMessage(), e);
237            getReport().println(e);
238            return Collections.emptyList();
239        }
240
241    }
242
243}