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.workplace.tools.content;
029
030import org.opencms.file.CmsFile;
031import org.opencms.file.CmsObject;
032import org.opencms.file.CmsPropertyDefinition;
033import org.opencms.file.CmsResource;
034import org.opencms.file.CmsResourceFilter;
035import org.opencms.file.types.CmsResourceTypeXmlPage;
036import org.opencms.i18n.CmsLocaleManager;
037import org.opencms.lock.CmsLock;
038import org.opencms.main.CmsException;
039import org.opencms.main.OpenCms;
040import org.opencms.report.A_CmsReportThread;
041import org.opencms.report.I_CmsReport;
042import org.opencms.util.CmsStringUtil;
043import org.opencms.xml.page.CmsXmlPage;
044import org.opencms.xml.page.CmsXmlPageFactory;
045
046import java.util.Iterator;
047import java.util.List;
048import java.util.Locale;
049
050/**
051 * Changes the element Locales of resources using the corresponding settings object.<p>
052 *
053 * @since 6.0.1
054 */
055public class CmsChangeElementLocaleThread extends A_CmsReportThread {
056
057    private CmsElementChangeLocaleSettings m_settings;
058
059    /**
060     * Creates a change element Locale Thread.<p>
061     *
062     * @param cms the current cms context
063     * @param settings the settings needed to perform the operation
064     */
065    public CmsChangeElementLocaleThread(CmsObject cms, CmsElementChangeLocaleSettings settings) {
066
067        super(cms, Messages.get().getBundle().key(Messages.GUI_CHANGEELEMENTLOCALE_THREAD_NAME_0));
068        initHtmlReport(cms.getRequestContext().getLocale());
069        m_settings = settings;
070    }
071
072    /**
073     * @see org.opencms.report.A_CmsReportThread#getReportUpdate()
074     */
075    @Override
076    public String getReportUpdate() {
077
078        return getReport().getReportUpdate();
079    }
080
081    /**
082     * @see java.lang.Runnable#run()
083     */
084    @Override
085    public void run() {
086
087        getReport().println(
088            Messages.get().container(
089                Messages.RPT_CHANGEELEMENTLOCALE_BEGIN_2,
090                m_settings.getOldLocale(),
091                m_settings.getNewLocale()),
092            I_CmsReport.FORMAT_HEADLINE);
093        try {
094            // change the element locales
095            changeElementLocales();
096        } catch (CmsException e) {
097            getReport().println(e);
098        }
099
100        // append runtime statistics to report
101        getReport().print(org.opencms.report.Messages.get().container(org.opencms.report.Messages.RPT_STAT_0));
102        getReport().println(
103            org.opencms.report.Messages.get().container(
104                org.opencms.report.Messages.RPT_STAT_DURATION_1,
105                getReport().formatRuntime()));
106        getReport().println(
107            Messages.get().container(Messages.RPT_CHANGEELEMENTLOCALE_END_0),
108            I_CmsReport.FORMAT_HEADLINE);
109    }
110
111    /**
112     * Performs the changing of the element Locales.<p>
113     *
114     * @throws CmsException if reading the list of resources to change fails
115     */
116    private void changeElementLocales() throws CmsException {
117
118        // create Locale objects to work with
119        Locale oldLocale = CmsLocaleManager.getLocale(m_settings.getOldLocale());
120        Locale newLocale = CmsLocaleManager.getLocale(m_settings.getNewLocale());
121        boolean checkTemplate = CmsStringUtil.isNotEmpty(m_settings.getTemplate());
122
123        // set the resource filter to filter xml pages
124        int xmlPageId = OpenCms.getResourceManager().getResourceType(
125            CmsResourceTypeXmlPage.getStaticTypeName()).getTypeId();
126        CmsResourceFilter filter = CmsResourceFilter.IGNORE_EXPIRATION.addRequireType(xmlPageId);
127        String path = CmsResource.getFolderPath(m_settings.getVfsFolder());
128        // get the list of resources to change
129        List resources = getCms().readResources(path, filter, m_settings.isIncludeSubFolders());
130
131        // set the report counters
132        int count = 0;
133        int resSize = resources.size();
134
135        // iterate the resources
136        Iterator i = resources.iterator();
137        while (i.hasNext()) {
138
139            count++;
140            CmsResource res = (CmsResource)i.next();
141
142            // generate report output
143            getReport().print(
144                org.opencms.report.Messages.get().container(
145                    org.opencms.report.Messages.RPT_SUCCESSION_2,
146                    String.valueOf(count),
147                    String.valueOf(resSize)),
148                I_CmsReport.FORMAT_NOTE);
149            getReport().print(Messages.get().container(Messages.RPT_PROCESSING_PAGE_0), I_CmsReport.FORMAT_NOTE);
150            getReport().print(
151                org.opencms.report.Messages.get().container(
152                    org.opencms.report.Messages.RPT_ARGUMENT_1,
153                    getCms().getSitePath(res)));
154            getReport().print(org.opencms.report.Messages.get().container(org.opencms.report.Messages.RPT_DOTS_0));
155
156            try {
157
158                if (checkTemplate) {
159                    // check the template property
160                    String template = getCms().readPropertyObject(
161                        res,
162                        CmsPropertyDefinition.PROPERTY_TEMPLATE,
163                        true).getValue("");
164                    if (!m_settings.getTemplate().equals(template)) {
165                        // template property does not match, report and continue with next resource
166                        getReport().println(
167                            Messages.get().container(Messages.RPT_CHANGEELEMENTLOCALE_TEMPLATE_0),
168                            I_CmsReport.FORMAT_NOTE);
169                        continue;
170                    }
171                }
172
173                // get the file contents
174                CmsFile file = getCms().readFile(res);
175                // get the page object
176                CmsXmlPage page = CmsXmlPageFactory.unmarshal(getCms(), file);
177                // write the report output
178
179                if (!page.hasLocale(oldLocale)) {
180                    // old Locale not present, report and continue with next resource
181                    getReport().println(
182                        Messages.get().container(
183                            Messages.RPT_CHANGEELEMENTLOCALE_OLDLOCALE_1,
184                            m_settings.getOldLocale()),
185                        I_CmsReport.FORMAT_NOTE);
186                    continue;
187                }
188
189                if (page.hasLocale(newLocale)) {
190                    // target Locale present, report and continue with next resource
191                    getReport().println(
192                        Messages.get().container(
193                            Messages.RPT_CHANGEELEMENTLOCALE_NEWLOCALE_1,
194                            m_settings.getNewLocale()),
195                        I_CmsReport.FORMAT_NOTE);
196                    continue;
197                }
198
199                // change the Locale of the elements
200                page.moveLocale(oldLocale, newLocale);
201
202                // set the file contents
203                file.setContents(page.marshal());
204
205                // check the lock state of the file to write
206                CmsLock lock = getCms().getLock(res);
207                boolean isLocked = false;
208                boolean canWrite = false;
209                if (lock.isNullLock()) {
210                    // file not locked, lock it
211                    getCms().lockResource(getCms().getSitePath(res));
212                    isLocked = true;
213                    canWrite = true;
214                } else if (lock.isOwnedBy(getCms().getRequestContext().getCurrentUser())) {
215                    // file locked by current user
216                    canWrite = true;
217                }
218
219                if (canWrite) {
220                    // write the file contents
221                    getCms().writeFile(file);
222                } else {
223                    // no write operation possible
224                    getReport().println(
225                        Messages.get().container(Messages.RPT_CHANGEELEMENTLOCALE_NOTLOCKED_0),
226                        I_CmsReport.FORMAT_NOTE);
227                }
228
229                if (isLocked) {
230                    // unlock previously locked resource
231                    getCms().unlockResource(getCms().getSitePath(res));
232                }
233
234                if (canWrite) {
235                    // successfully changed, report it
236                    getReport().println(
237                        org.opencms.report.Messages.get().container(org.opencms.report.Messages.RPT_OK_0),
238                        I_CmsReport.FORMAT_OK);
239                }
240
241            } catch (CmsException e) {
242                // an error occurred, show exception on report output
243                getReport().println(e);
244            }
245        }
246    }
247}