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.apps.dbmanager;
029
030import org.opencms.file.CmsObject;
031import org.opencms.importexport.CmsExportParameters;
032import org.opencms.importexport.CmsVfsImportExportHandler;
033import org.opencms.main.CmsException;
034import org.opencms.main.CmsLog;
035import org.opencms.main.OpenCms;
036import org.opencms.report.A_CmsReportThread;
037import org.opencms.ui.A_CmsUI;
038import org.opencms.ui.CmsVaadinUtils;
039import org.opencms.ui.apps.Messages;
040import org.opencms.ui.components.CmsBasicDialog;
041import org.opencms.ui.components.CmsBasicDialog.DialogWidth;
042import org.opencms.ui.components.CmsDateField;
043import org.opencms.ui.components.editablegroup.CmsEditableGroup;
044import org.opencms.ui.components.editablegroup.I_CmsEditableGroupRow;
045import org.opencms.ui.components.fileselect.CmsPathSelectField;
046import org.opencms.util.CmsUUID;
047import org.opencms.workplace.threads.CmsExportThread;
048
049import java.io.File;
050import java.util.ArrayList;
051import java.util.List;
052
053import org.apache.commons.logging.Log;
054
055import com.google.common.base.Supplier;
056import com.vaadin.ui.Button;
057import com.vaadin.ui.Button.ClickEvent;
058import com.vaadin.ui.Button.ClickListener;
059import com.vaadin.ui.Component;
060import com.vaadin.ui.FormLayout;
061import com.vaadin.ui.Window;
062import com.vaadin.v7.data.Property.ValueChangeEvent;
063import com.vaadin.v7.data.Property.ValueChangeListener;
064import com.vaadin.v7.data.Validator;
065import com.vaadin.v7.data.util.IndexedContainer;
066import com.vaadin.v7.ui.AbstractSelect.ItemCaptionMode;
067import com.vaadin.v7.ui.CheckBox;
068import com.vaadin.v7.ui.ComboBox;
069import com.vaadin.v7.ui.VerticalLayout;
070
071/**
072 * Class for the Export dialog.<p>
073 */
074public class CmsDbExportView extends VerticalLayout {
075
076    /**
077     * Validator for entered resources.<p>
078     */
079    class ResourceValidator implements Validator {
080
081        /**vaadin serial id.*/
082        private static final long serialVersionUID = -4341247963641286345L;
083
084        /**
085         * @see com.vaadin.data.Validator#validate(java.lang.Object)
086         */
087        public void validate(Object value) throws InvalidValueException {
088
089            String resourcePath = (String)value;
090            if ((value == null)) {
091                throw new InvalidValueException(
092                    CmsVaadinUtils.getMessageText(Messages.GUI_DATABASEAPP_EXPORT_INVALID_RESOURCE_EMPTY_0));
093            }
094
095            if (resourcePath.isEmpty()) {
096                throw new InvalidValueException(
097                    CmsVaadinUtils.getMessageText(Messages.GUI_DATABASEAPP_EXPORT_INVALID_RESOURCE_EMPTY_0));
098            }
099
100            if (!m_cms.existsResource(resourcePath)) {
101                throw new InvalidValueException(
102                    CmsVaadinUtils.getMessageText(Messages.GUI_DATABASEAPP_EXPORT_INVALID_RESOURCE_NOTFOUND_0));
103            }
104        }
105    }
106
107    /**
108     * Validator for the target field.<p>
109     */
110    class TargetValidator implements Validator {
111
112        /**vaadin serial id.*/
113        private static final long serialVersionUID = 7530400504930612299L;
114
115        /**
116         * @see com.vaadin.data.Validator#validate(java.lang.Object)
117         */
118        public void validate(Object value) throws InvalidValueException {
119
120            if (value == null) {
121                throw new InvalidValueException(
122                    CmsVaadinUtils.getMessageText(Messages.GUI_DATABASEAPP_EXPORT_INVALID_TARGET_0));
123            }
124        }
125    }
126
127    /** The logger for this class. */
128    static Log LOG = CmsLog.getLog(CmsDbExportView.class.getName());
129
130    /**vaadin serial id.*/
131    private static final long serialVersionUID = -2571459807662862053L;
132
133    /**Copy of current CmsObject.*/
134    protected CmsObject m_cms;
135
136    /**vaadin component.*/
137    private CheckBox m_asFiles;
138
139    /**vaadin component.*/
140    private CmsDateField m_changedSince;
141
142    /** The export parameters object that is edited on this dialog. */
143    private CmsExportParameters m_exportParams;
144
145    /**vaadin component.*/
146    private CheckBox m_includeAccount;
147
148    /**vaadin component.*/
149    private CheckBox m_includeProject;
150
151    /**vaadin component.*/
152    private CheckBox m_includeResource;
153
154    /**vaadin component.*/
155    private CheckBox m_includeSystem;
156
157    /**vaadin component.*/
158    private CheckBox m_includeUnchanged;
159
160    /**vaadin component.*/
161    private CheckBox m_modified;
162
163    /**vaadin component.*/
164    private Button m_ok;
165
166    /**vaadin component.*/
167    private CheckBox m_recursive;
168
169    /**vaadin component.*/
170    private VerticalLayout m_resources;
171
172    private CmsEditableGroup m_resourcesGroup;
173
174    /**vaadin component.*/
175    private ComboBox m_site;
176
177    /**vaadin component.*/
178    private ComboBox m_target;
179
180    private ComboBox m_project;
181
182    /**
183     * public constructor.<p>
184     */
185    public CmsDbExportView() {
186
187        CmsVaadinUtils.readAndLocalizeDesign(this, CmsVaadinUtils.getWpMessagesForCurrentLocale(), null);
188        try {
189            m_cms = OpenCms.initCmsObject(A_CmsUI.getCmsObject());
190        } catch (CmsException e) {
191            LOG.error("Failed to clone CmsObject", e);
192        }
193
194        m_resourcesGroup = new CmsEditableGroup(m_resources, new Supplier<Component>() {
195
196            public Component get() {
197
198                return getResourceRow("");
199
200            }
201
202        }, CmsVaadinUtils.getMessageText(Messages.GUI_DATABASEAPP_EXPORT_ADD_RESOURCE_0));
203        m_resourcesGroup.init();
204        m_resourcesGroup.addRow(getResourceRow(""));
205        m_exportParams = new CmsExportParameters();
206
207        setupCheckBoxes();
208        setupComboBoxFile();
209        setupComboBoxSite();
210
211        m_ok.addClickListener(new ClickListener() {
212
213            private static final long serialVersionUID = -4224924796312615674L;
214
215            public void buttonClick(ClickEvent event) {
216
217                addResourceIfEmpty();
218                addValidators();
219                if (isFormValid()) {
220                    startThread();
221                }
222            }
223        });
224    }
225
226    protected void addResourceIfEmpty() {
227
228        if (m_resourcesGroup.getRows().size() == 0) {
229            m_resourcesGroup.addRow(getResourceRow(""));
230        }
231    }
232
233    /**
234     * Adds all validators to the formular.<p>
235     */
236    protected void addValidators() {
237
238        //Target file ComboBox
239        m_target.removeAllValidators();
240        m_target.addValidator(new TargetValidator());
241
242        for (I_CmsEditableGroupRow row : m_resourcesGroup.getRows()) {
243            FormLayout layout = (FormLayout)(row.getComponent());
244            CmsPathSelectField field = (CmsPathSelectField)layout.getComponent(0);
245            field.removeAllValidators();
246            field.addValidator(new ResourceValidator());
247        }
248    }
249
250    /**
251     * Changes the site of the cms object.<p>
252     */
253    protected void changeSite() {
254
255        m_cms.getRequestContext().setSiteRoot((String)m_site.getValue());
256    }
257
258    protected Component getResourceRow(String path) {
259
260        FormLayout res = new FormLayout();
261        CmsPathSelectField field = new CmsPathSelectField();
262        field.setCaption(CmsVaadinUtils.getMessageText(Messages.GUI_DATABASEAPP_EXPORT_RESOURCES_0));
263        field.setDescription(CmsVaadinUtils.getMessageText(Messages.GUI_DATABASEAPP_EXPORT_RESOURCES_HELP_0));
264        field.setCmsObject(m_cms);
265        res.addComponent(field);
266        return res;
267    }
268
269    /**
270     * Checks if form is valid.<p>
271     *
272     * @return true if all fields are valid
273     */
274    protected boolean isFormValid() {
275
276        return m_target.isValid() & allResourcesValid();
277    }
278
279    /**
280     * Checks if resources exist in site. if not the row gets removed.<p>
281     */
282    protected void removeUnvalidPathFields() {
283
284        int counter = 0;
285        List<I_CmsEditableGroupRow> rowsToRemove = new ArrayList<I_CmsEditableGroupRow>();
286        for (I_CmsEditableGroupRow row : m_resourcesGroup.getRows()) {
287            FormLayout layout = (FormLayout)(row.getComponent());
288            CmsPathSelectField field = (CmsPathSelectField)layout.getComponent(0);
289            if (!m_cms.existsResource(field.getValue())) {
290                rowsToRemove.add(row);
291            }
292        }
293
294        for (I_CmsEditableGroupRow row : rowsToRemove) {
295            m_resourcesGroup.remove(row);
296        }
297    }
298
299    /**
300     * Starts the export thread and displays it's report.<p>
301     */
302    protected void startThread() {
303
304        try {
305            m_cms.getRequestContext().setCurrentProject(m_cms.readProject((CmsUUID)m_project.getValue()));
306        } catch (CmsException e) {
307            LOG.error("Unable to set project", e);
308        }
309        updateExportParams();
310
311        CmsVfsImportExportHandler handler = new CmsVfsImportExportHandler();
312        handler.setExportParams(m_exportParams);
313        A_CmsReportThread exportThread = new CmsExportThread(m_cms, handler, false);
314
315        Window window = CmsBasicDialog.prepareWindow(DialogWidth.max);
316        window.setContent(new CmsExportThreadDialog(exportThread, window));
317        A_CmsUI.get().addWindow(window);
318        exportThread.start();
319    }
320
321    /**
322     * Checks if all resources are valid.<p>
323     *
324     * @return true if resources are valid
325     */
326    private boolean allResourcesValid() {
327
328        boolean valid = true;
329
330        for (I_CmsEditableGroupRow row : m_resourcesGroup.getRows()) {
331            FormLayout layout = (FormLayout)(row.getComponent());
332            CmsPathSelectField field = (CmsPathSelectField)layout.getComponent(0);
333            if (!field.isValid()) {
334                valid = false;
335            }
336        }
337
338        return valid;
339    }
340
341    /**
342     * Reads out resources from form.<p>
343     *
344     * @return List with site-relative paths of resources
345     */
346    private List<String> getResources() {
347
348        List<String> res = new ArrayList<String>();
349
350        for (I_CmsEditableGroupRow row : m_resourcesGroup.getRows()) {
351            FormLayout layout = (FormLayout)(row.getComponent());
352            CmsPathSelectField field = (CmsPathSelectField)layout.getComponent(0);
353            if (!field.getValue().isEmpty() & !res.contains(field.getValue())) {
354                res.add(field.getValue());
355            }
356        }
357
358        return res;
359    }
360
361    /**
362     * Sets the init values for check boxes.<p>
363     */
364    private void setupCheckBoxes() {
365
366        m_includeResource.setValue(new Boolean(true));
367        m_includeUnchanged.setValue(new Boolean(true));
368        m_includeSystem.setValue(new Boolean(true));
369        m_recursive.setValue(new Boolean(true));
370    }
371
372    /**
373     * Sets up the combo box for the target file.<p>
374     */
375    private void setupComboBoxFile() {
376
377        m_target.setInputPrompt(CmsVaadinUtils.getMessageText(Messages.GUI_DATABASEAPP_EXPORT_FILE_NAME_EMPTY_0));
378        m_target.setNewItemsAllowed(true);
379        List<String> files = CmsDbManager.getFileListFromServer(true);
380        for (String file : files) {
381            m_target.addItem(file);
382        }
383    }
384
385    /**
386     * Sets up the combo box for the site choice.<p>
387     */
388    private void setupComboBoxSite() {
389
390        IndexedContainer container = CmsVaadinUtils.getAvailableSitesContainer(A_CmsUI.getCmsObject(), "title");
391        m_site.setContainerDataSource(container);
392        m_site.setItemCaptionMode(ItemCaptionMode.PROPERTY);
393        m_site.setItemCaptionPropertyId("title");
394        m_site.setNullSelectionAllowed(false);
395        m_site.setTextInputAllowed(false);
396        m_site.setValue(A_CmsUI.getCmsObject().getRequestContext().getSiteRoot());
397        m_site.addValueChangeListener(new ValueChangeListener() {
398
399            private static final long serialVersionUID = -1019243885633462477L;
400
401            public void valueChange(ValueChangeEvent event) {
402
403                changeSite();
404                removeUnvalidPathFields();
405            }
406        });
407
408        m_project.setContainerDataSource(CmsVaadinUtils.getProjectsContainer(A_CmsUI.getCmsObject(), "caption"));
409        m_project.setItemCaptionPropertyId("caption");
410        m_project.select(A_CmsUI.getCmsObject().getRequestContext().getCurrentProject().getUuid());
411        m_project.setNewItemsAllowed(false);
412        m_project.setNullSelectionAllowed(false);
413        m_project.setTextInputAllowed(false);
414    }
415
416    /**
417     * Updates the Export parameter based on user input.<p>
418     */
419    private void updateExportParams() {
420
421        m_exportParams.setExportAccountData(m_includeAccount.getValue().booleanValue());
422        m_exportParams.setExportAsFiles(m_asFiles.getValue().booleanValue());
423        m_exportParams.setExportProjectData(m_includeProject.getValue().booleanValue());
424        m_exportParams.setExportResourceData(m_includeResource.getValue().booleanValue());
425        m_exportParams.setInProject(m_modified.getValue().booleanValue());
426        m_exportParams.setIncludeSystemFolder(m_includeSystem.getValue().booleanValue());
427        m_exportParams.setIncludeUnchangedResources(m_includeUnchanged.getValue().booleanValue());
428        String exportFileName = OpenCms.getSystemInfo().getAbsoluteRfsPathRelativeToWebInf(
429            OpenCms.getSystemInfo().getPackagesRfsPath() + File.separator + (String)m_target.getValue());
430        m_exportParams.setPath(exportFileName);
431        m_exportParams.setRecursive(m_recursive.getValue().booleanValue());
432        m_exportParams.setResources(getResources());
433        if (m_changedSince.getValue() != null) {
434            m_exportParams.setContentAge(m_changedSince.getDate().getTime());
435        } else {
436            m_exportParams.setContentAge(0);
437        }
438    }
439
440}