org.opencms.gwt.client.ui.replace.CmsReplaceDialog.java Source code

Java tutorial

Introduction

Here is the source code for org.opencms.gwt.client.ui.replace.CmsReplaceDialog.java

Source

/*
 * This library is part of OpenCms -
 * the Open Source Content Management System
 *
 * Copyright (c) Alkacon Software GmbH & Co. KG (http://www.alkacon.com)
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * For further information about Alkacon Software, please see the
 * company website: http://www.alkacon.com
 *
 * For further information about OpenCms, please see the
 * project website: http://www.opencms.org
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

package org.opencms.gwt.client.ui.replace;

import org.opencms.file.CmsResource;
import org.opencms.gwt.client.CmsCoreProvider;
import org.opencms.gwt.client.Messages;
import org.opencms.gwt.client.rpc.CmsRpcAction;
import org.opencms.gwt.client.ui.CmsErrorDialog;
import org.opencms.gwt.client.ui.CmsListItemWidget;
import org.opencms.gwt.client.ui.CmsPopup;
import org.opencms.gwt.client.ui.CmsPushButton;
import org.opencms.gwt.client.ui.FontOpenCms;
import org.opencms.gwt.client.ui.I_CmsButton;
import org.opencms.gwt.client.ui.css.I_CmsConstantsBundle;
import org.opencms.gwt.client.ui.css.I_CmsLayoutBundle;
import org.opencms.gwt.client.ui.input.upload.CmsFileInfo;
import org.opencms.gwt.client.ui.input.upload.CmsFileInput;
import org.opencms.gwt.client.ui.input.upload.CmsUploadButton;
import org.opencms.gwt.client.ui.input.upload.CmsUploadProgressInfo;
import org.opencms.gwt.client.ui.input.upload.CmsUploader;
import org.opencms.gwt.client.ui.input.upload.I_CmsUploadDialog;
import org.opencms.gwt.shared.CmsIconUtil;
import org.opencms.gwt.shared.CmsListInfoBean;
import org.opencms.gwt.shared.CmsReplaceInfo;
import org.opencms.gwt.shared.CmsUploadProgessInfo;
import org.opencms.gwt.shared.I_CmsUploadConstants;
import org.opencms.gwt.shared.rpc.I_CmsUploadService;
import org.opencms.gwt.shared.rpc.I_CmsUploadServiceAsync;
import org.opencms.util.CmsStringUtil;
import org.opencms.util.CmsUUID;

import java.util.Collections;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.logical.shared.CloseHandler;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.json.client.JSONObject;
import com.google.gwt.json.client.JSONParser;
import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.rpc.ServiceDefTarget;
import com.google.gwt.user.client.ui.PopupPanel;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.Widget;

/**
 * The replace resource dialog.<p>
 */
public class CmsReplaceDialog extends CmsPopup implements I_CmsUploadDialog {

    /** The main content panel. */
    protected CmsReplaceContentWidget m_mainPanel;

    /** Signals that the upload dialog was canceled. */
    private boolean m_canceled;

    /** Flag indicating the client is waiting for a server response. */
    private boolean m_clientLoading;

    /** The close handler. */
    private CloseHandler<PopupPanel> m_closeHandler;

    /** The sum of all file sizes. */
    private long m_contentLength;

    /** The current file input. */
    private CmsFileInput m_fileInput;

    /** The file widget. */
    private CmsListItemWidget m_fileWidget;

    /** The action to execute when the upload dialog is finished. */
    private Runnable m_finishAction;

    /** The dialog handler. */
    private CmsReplaceHandler m_handler;

    /** The close handler registration. */
    private HandlerRegistration m_handlerReg;

    /** The loading timer. */
    private Timer m_loadingTimer;

    /** The OK button. */
    private CmsPushButton m_okButton;

    /** The upload progress widget. */
    private CmsUploadProgressInfo m_progressInfo;

    /** The replace resource information. */
    private CmsReplaceInfo m_replaceInfo;

    /** The progress timer. */
    private Timer m_updateProgressTimer;

    /** The upload button. */
    private CmsUploadButton m_uploadButton;

    /** The upload service. */
    private I_CmsUploadServiceAsync m_uploadService;

    /**
     * Constructor.<p>
     *
     * @param handler the dialog handler
     */
    public CmsReplaceDialog(CmsReplaceHandler handler) {

        super(Messages.get().key(Messages.GUI_REPLACE_TITLE_0));
        m_handler = handler;
        setModal(true);
        setGlassEnabled(true);
        catchNotifications();
        // create the main panel
        m_mainPanel = new CmsReplaceContentWidget();
        // set the main panel as content of the popup
        setMainContent(m_mainPanel);
        addDialogClose(new Command() {

            public void execute() {

                cancelReplace();
            }
        });

        CmsPushButton cancelButton = createButton(
                org.opencms.gwt.client.Messages.get().key(org.opencms.gwt.client.Messages.GUI_CANCEL_0));
        cancelButton.addClickHandler(new ClickHandler() {

            /**
             * @see com.google.gwt.event.dom.client.ClickHandler#onClick(com.google.gwt.event.dom.client.ClickEvent)
             */
            public void onClick(ClickEvent event) {

                cancelReplace();
            }
        });
        addButton(cancelButton);
    }

    /**
     * @see org.opencms.gwt.client.ui.CmsPopup#addCloseHandler(com.google.gwt.event.logical.shared.CloseHandler)
     */
    @Override
    public HandlerRegistration addCloseHandler(CloseHandler<PopupPanel> handler) {

        m_closeHandler = handler;
        m_handlerReg = super.addCloseHandler(handler);
        return m_handlerReg;
    }

    /**
     * Returns the action which should be executed when the upload dialog is finished.<p>
     *
     * @return an action to run when the upload dialog is finished
     */
    public Runnable getFinishAction() {

        return m_finishAction;
    }

    /**
     * @see org.opencms.gwt.client.ui.CmsPopup#hide()
     */
    @Override
    public void hide() {

        if (m_fileInput != null) {
            m_fileInput.removeFromParent();
        }
        super.hide();
    }

    /**
     * Parses the upload response of the server and decides what to do.<p>
     *
     * @param results a JSON Object
     */
    public void parseResponse(String results) {

        cancelUpdateProgress();
        stopLoadingAnimation();

        if ((!m_canceled) && CmsStringUtil.isNotEmptyOrWhitespaceOnly(results)) {
            JSONObject jsonObject = JSONParser.parseStrict(results).isObject();
            boolean success = jsonObject.get(I_CmsUploadConstants.KEY_SUCCESS).isBoolean().booleanValue();
            // If the upload is done so fast that we did not receive any progress information, then
            // the content length is unknown. For that reason take the request size to show how
            // much bytes were uploaded.
            double size = jsonObject.get(I_CmsUploadConstants.KEY_REQUEST_SIZE).isNumber().doubleValue();
            long requestSize = new Double(size).longValue();
            if (m_contentLength == 0) {
                m_contentLength = requestSize;
            }
            if (success) {
                m_mainPanel.displayDialogInfo(Messages.get().key(Messages.GUI_UPLOAD_INFO_FINISHING_0), false);
                m_progressInfo.finish();
                closeOnSuccess();
            } else {
                String message = jsonObject.get(I_CmsUploadConstants.KEY_MESSAGE).isString().stringValue();
                String stacktrace = jsonObject.get(I_CmsUploadConstants.KEY_STACKTRACE).isString().stringValue();
                showErrorReport(message, stacktrace);
            }
        }
    }

    /**
     * Sets an action that should be executed if the upload dialog is finished.<p>
     *
     * @param action the action to execute when finished
     */
    public void setFinishAction(Runnable action) {

        m_finishAction = action;
    }

    /**
     * Shows the error report.<p>
     *
     * @param message the message to show
     * @param stacktrace the stacktrace to show
     */
    public void showErrorReport(final String message, final String stacktrace) {

        if (!m_canceled) {
            CmsErrorDialog errDialog = new CmsErrorDialog(message, stacktrace);
            if (m_handlerReg != null) {
                m_handlerReg.removeHandler();
            }
            if (m_closeHandler != null) {
                errDialog.addCloseHandler(m_closeHandler);
            }
            hide();
            errDialog.center();
        }
    }

    /**
     * Cancels the replace process.<p>
     */
    protected void cancelReplace() {

        m_canceled = true;
        if (m_progressInfo != null) {
            cancelUpdateProgress();
            CmsRpcAction<Boolean> callback = new CmsRpcAction<Boolean>() {

                /**
                 * @see org.opencms.gwt.client.rpc.CmsRpcAction#execute()
                 */
                @Override
                public void execute() {

                    getUploadService().cancelUpload(this);
                }

                /**
                 * @see org.opencms.gwt.client.rpc.CmsRpcAction#onResponse(java.lang.Object)
                 */
                @Override
                protected void onResponse(Boolean result) {

                    hide();
                }
            };
            callback.execute();
        } else {
            hide();
        }
    }

    /**
     * Cancels the upload progress timer.<p>
     */
    protected void cancelUpdateProgress() {

        if (m_updateProgressTimer != null) {
            m_updateProgressTimer.cancel();
        }
    }

    /**
     * Returns the resource type name for a given filename.<p>
     *
     * @param file the file info
     *
     * @return the resource type name
     */
    protected String getResourceType(CmsFileInfo file) {

        return CmsCoreProvider.get().getResourceType(file);
    }

    /**
     * Returns the upload service instance.<p>
     *
     * @return the upload service instance
     */
    protected I_CmsUploadServiceAsync getUploadService() {

        if (m_uploadService == null) {
            m_uploadService = GWT.create(I_CmsUploadService.class);
            String serviceUrl = CmsCoreProvider.get().link("org.opencms.ade.upload.CmsUploadService.gwt");
            ((ServiceDefTarget) m_uploadService).setServiceEntryPoint(serviceUrl);
        }
        return m_uploadService;
    }

    /**
     * Returns the upload JSP uri.<p>
     *
     * @return the upload JSP uri
     */
    protected String getUploadUri() {

        return CmsCoreProvider.get().link(I_CmsUploadConstants.UPLOAD_ACTION_JSP_URI);
    }

    /**
     * Initializes the dialog content with the replace information.<p>
     *
     * @param replaceInfo the replace information
     */
    protected void initContent(CmsReplaceInfo replaceInfo) {

        m_replaceInfo = replaceInfo;
        CmsListItemWidget fileInfoItem = new CmsListItemWidget(m_replaceInfo.getFileInfo());
        m_mainPanel.setReplaceInfo(fileInfoItem);
        if (!m_replaceInfo.isLockable()) {
            m_mainPanel.displayDialogInfo(Messages.get().key(Messages.GUI_REPLACE_LOCKED_RESOURCE_0), true);
        } else {
            m_mainPanel.displayDialogInfo(Messages.get().key(Messages.GUI_REPLACE_INFO_0), false);
            checkFileType();
            createButtons();
        }
    }

    /**
     * Initializes the dialog content.<p>
     *
     * @param structureId the structure id of the file to replace
     */
    protected void initContent(final CmsUUID structureId) {

        CmsRpcAction<CmsReplaceInfo> action = new CmsRpcAction<CmsReplaceInfo>() {

            @Override
            public void execute() {

                start(0, true);
                CmsCoreProvider.getVfsService().getFileReplaceInfo(structureId, this);
            }

            @Override
            protected void onResponse(CmsReplaceInfo result) {

                initContent(result);
                stop(false);
            }
        };
        action.execute();
    }

    /**
     * Sets the file input.<p>
     *
     * @param fileInput the file input
     */
    protected void setFileInput(CmsFileInput fileInput) {

        // only accept file inputs with a single selected file
        if (fileInput.getFiles().length == 1) {
            if (m_okButton != null) {
                m_okButton.enable();
            }
            if (m_fileInput != null) {
                m_fileInput.removeFromParent();
            }
            m_fileInput = fileInput;
            RootPanel.get().add(m_fileInput);
            m_mainPanel.setContainerWidget(createFileWidget(m_fileInput.getFiles()[0]));
        }
    }

    /**
     * Retrieves the progress information from the server.<p>
     */
    protected void updateProgress() {

        CmsRpcAction<CmsUploadProgessInfo> callback = new CmsRpcAction<CmsUploadProgessInfo>() {

            /**
             * @see org.opencms.gwt.client.rpc.CmsRpcAction#execute()
             */
            @Override
            public void execute() {

                getUploadService().getUploadProgressInfo(this);
            }

            /**
             * @see org.opencms.gwt.client.rpc.CmsRpcAction#onFailure(java.lang.Throwable)
             */
            @Override
            public void onFailure(Throwable t) {

                super.onFailure(t);
                cancelUpdateProgress();
            }

            /**
             * @see org.opencms.gwt.client.rpc.CmsRpcAction#onResponse(java.lang.Object)
             */
            @Override
            protected void onResponse(CmsUploadProgessInfo result) {

                updateProgressBar(result);
            }
        };
        callback.execute();
    }

    /**
     * Updates the progress bar.<p>
     *
     * @param info the progress info
     */
    protected void updateProgressBar(CmsUploadProgessInfo info) {

        switch (info.getState()) {
        case notStarted:
            break;
        case running:
            m_progressInfo.setProgress(info);
            stopLoadingAnimation();
            break;
        case finished:
            m_progressInfo.finish();
            m_mainPanel.displayDialogInfo(Messages.get().key(Messages.GUI_UPLOAD_INFO_FINISHING_0), false);
            startLoadingAnimation(Messages.get().key(Messages.GUI_UPLOAD_INFO_CREATING_RESOURCES_0), 1500);
            break;
        default:
            break;
        }
    }

    /**
     * Uploads the selected file.<p>
     */
    protected void uploadFile() {

        hideOkAndUploadButtons();
        CmsUploader uploader = new CmsUploader();
        CmsFileInfo info = m_fileInput.getFiles()[0];
        info.setOverrideFileName(CmsResource.getName(m_replaceInfo.getSitepath()));
        uploader.uploadFiles(CmsCoreProvider.get().link(I_CmsUploadConstants.UPLOAD_ACTION_JSP_URI),
                CmsResource.getFolderPath(m_replaceInfo.getSitepath()), false, Collections.singletonList(info),
                Collections.<String>emptyList(), this);
        showProgress();
    }

    /**
     * Checks if the file suffix of the selected file matches the suffix of the resource to replace.<p>
     */
    private void checkFileType() {

        if ((m_fileInput != null) && (m_replaceInfo != null) && (m_fileWidget != null)) {
            CmsFileInfo file = m_fileInput.getFiles()[0];
            if (!m_replaceInfo.getSitepath().endsWith(file.getFileSuffix())) {
                Widget warningImage = FontOpenCms.WARNING.getWidget(20,
                        I_CmsConstantsBundle.INSTANCE.css().colorWarning());
                warningImage.setTitle(Messages.get().key(Messages.GUI_REPLACE_WRONG_FILE_EXTENSION_0));
                warningImage.addStyleName(org.opencms.gwt.client.ui.css.I_CmsLayoutBundle.INSTANCE
                        .listItemWidgetCss().permaVisible());
                m_fileWidget.addButton(warningImage);
            }
        }
    }

    /**
     * Closes the dialog after a delay.<p>
     */
    private void closeOnSuccess() {

        Timer closeTimer = new Timer() {

            /**
             * @see com.google.gwt.user.client.Timer#run()
             */
            @Override
            public void run() {

                CmsReplaceDialog.this.hide();
            }
        };
        closeTimer.schedule(1000);
    }

    /**
     * Creates a dialog text button.<p>
     *
     * @param buttonText the button text
     *
     * @return the button
     */
    private CmsPushButton createButton(String buttonText) {

        CmsPushButton button = new CmsPushButton();
        button.setTitle(buttonText);
        button.setText(buttonText);
        button.setSize(I_CmsButton.Size.medium);
        button.setUseMinWidth(true);
        return button;
    }

    /**
     * Creates the "OK", the "Cancel" and the "Change file" button.<p>
     */
    private void createButtons() {

        m_okButton = createButton(
                org.opencms.gwt.client.Messages.get().key(org.opencms.gwt.client.Messages.GUI_OK_0));
        m_okButton.addClickHandler(new ClickHandler() {

            /**
             * @see com.google.gwt.event.dom.client.ClickHandler#onClick(com.google.gwt.event.dom.client.ClickEvent)
             */
            public void onClick(ClickEvent event) {

                uploadFile();
            }
        });
        if (m_fileInput == null) {
            m_okButton.disable(Messages.get().key(Messages.GUI_REPLACE_NO_FILE_SELECTED_0));
        }
        addButton(m_okButton);

        // add a new upload button
        m_uploadButton = new CmsUploadButton(m_handler);
        m_uploadButton.addStyleName(I_CmsLayoutBundle.INSTANCE.uploadButton().uploadDialogButton());
        m_uploadButton.setText(Messages.get().key(Messages.GUI_REPLACE_CHANGE_FILE_0));
        addButton(m_uploadButton);
        m_handler.setButton(m_uploadButton);
    }

    /**
     * Creates the widget to display the selected file information.<p>
     *
     * @param file the file info
     *
     * @return the widget
     */
    private CmsListItemWidget createFileWidget(CmsFileInfo file) {

        String subTitle;
        String resourceType = getResourceType(file);
        if (file.getFileSize() > 0) {
            subTitle = CmsUploadButton.formatBytes(file.getFileSize()) + " (" + getResourceType(file) + ")";
        } else {
            subTitle = resourceType;
        }
        CmsListInfoBean infoBean = new CmsListInfoBean(file.getFileName(), subTitle, null);
        m_fileWidget = new CmsListItemWidget(infoBean);
        String icon = CmsIconUtil.getResourceIconClasses(resourceType, file.getFileName(), false);
        m_fileWidget.setIcon(icon);
        checkFileType();
        return m_fileWidget;
    }

    /**
     * Hides the OK and upload button while processing the upload.<p>
     */
    private void hideOkAndUploadButtons() {

        m_uploadButton.setVisible(false);
        m_okButton.setVisible(false);
    }

    /**
     * Starts the upload progress bar.<p>
     */
    private void showProgress() {

        CmsFileInfo fileInfo = m_fileInput.getFiles()[0];
        m_progressInfo = new CmsUploadProgressInfo(Collections.singletonList(fileInfo.getFileName()));
        m_progressInfo.setContentLength(fileInfo.getFileSize());
        m_mainPanel.setContainerWidget(m_progressInfo);
        m_updateProgressTimer = new Timer() {

            @Override
            public void run() {

                updateProgress();
            }
        };
        m_updateProgressTimer.scheduleRepeating(1000);

    }

    /**
     * Starts the loading animation.<p>
     *
     * Used while client is loading files from hard disk into memory.<p>
     *
     * @param msg the message that should be displayed below the loading animation (can also be HTML as String)
     * @param delayMillis the delay to start the animation with
     */
    private void startLoadingAnimation(final String msg, int delayMillis) {

        m_loadingTimer = new Timer() {

            @Override
            public void run() {

                m_mainPanel.showLoadingAnimation(msg);
            }
        };
        if (delayMillis > 0) {
            m_loadingTimer.schedule(delayMillis);
        } else {
            m_loadingTimer.run();
        }
    }

    /**
     * Stops the client loading animation.<p>
     */
    private void stopLoadingAnimation() {

        if (m_loadingTimer != null) {
            m_loadingTimer.cancel();
        }
        if (m_clientLoading) {
            m_mainPanel.removeLoadingAnimation();
            m_clientLoading = false;
        }
    }
}