org.eclipse.cft.server.ui.internal.editor.CloudFoundryApplicationsEditorPage.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.cft.server.ui.internal.editor.CloudFoundryApplicationsEditorPage.java

Source

/*******************************************************************************
 * Copyright (c) 2012, 2015 Pivotal Software, Inc. 
 * 
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * and Apache License v2.0 which accompanies this distribution. 
 * 
 * The Eclipse Public License is available at 
 * 
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * and the Apache License v2.0 is available at 
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * You may elect to redistribute this code under either of these licenses.
 *  
 *  Contributors:
 *     Pivotal Software, Inc. - initial API and implementation
 ********************************************************************************/
package org.eclipse.cft.server.ui.internal.editor;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.cloudfoundry.client.lib.domain.CloudService;
import org.eclipse.cft.server.core.internal.CloudFoundryPlugin;
import org.eclipse.cft.server.core.internal.CloudFoundryServer;
import org.eclipse.cft.server.core.internal.CloudServerEvent;
import org.eclipse.cft.server.core.internal.CloudServerListener;
import org.eclipse.cft.server.core.internal.ServerEventHandler;
import org.eclipse.cft.server.core.internal.client.CloudFoundryApplicationModule;
import org.eclipse.cft.server.core.internal.client.CloudRefreshEvent;
import org.eclipse.cft.server.ui.internal.CloudFoundryImages;
import org.eclipse.cft.server.ui.internal.Messages;
import org.eclipse.cft.server.ui.internal.actions.RefreshEditorAction;
import org.eclipse.cft.server.ui.internal.actions.EditorAction.EditorCloudEvent;
import org.eclipse.cft.server.ui.internal.actions.EditorAction.RefreshArea;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.dialogs.IMessageProvider;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.forms.ManagedForm;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.forms.widgets.ScrolledForm;
import org.eclipse.ui.progress.UIJob;
import org.eclipse.ui.statushandlers.StatusManager;
import org.eclipse.wst.server.core.IModule;
import org.eclipse.wst.server.core.IServerListener;
import org.eclipse.wst.server.core.ServerEvent;
import org.eclipse.wst.server.ui.editor.ServerEditorPart;

/**
 * @author Terry Denney
 * @author Leo Dos Santos
 * @author Steffen Pingel
 * @author Christian Dupuis
 */
public class CloudFoundryApplicationsEditorPage extends ServerEditorPart {

    private CloudFoundryServer cloudServer;

    private ApplicationMasterDetailsBlock masterDetailsBlock;

    private ManagedForm mform;

    private ServerListener serverListener;

    private final List<CloudServerListener> cloudServerListeners = new ArrayList<CloudServerListener>();

    private List<CloudService> services;

    private ScrolledForm sform;

    private int[] applicationMemoryChoices;

    private final int MAX_ERROR_MESSAGE = 100;

    private UIJob refreshJob;

    private RefreshEditorOperation currentRefreshOp;

    @Override
    public void createPartControl(Composite parent) {

        mform = new ManagedForm(parent);
        FormToolkit toolkit = getFormToolkit(parent.getDisplay());

        sform = mform.getForm();
        sform.getForm().setText(Messages.COMMONTXT_APPLICATIONS);
        toolkit.decorateFormHeading(sform.getForm());

        cloudServer = (CloudFoundryServer) getServer().getOriginal().loadAdapter(CloudFoundryServer.class, null);

        masterDetailsBlock = new ApplicationMasterDetailsBlock(this, cloudServer);
        masterDetailsBlock.createContent(mform);

        sform.getForm().setImage(CloudFoundryImages.getImage(CloudFoundryImages.OBJ_APPLICATION));
        refresh(RefreshArea.MASTER);

        serverListener = new ServerListener();
        addCloudServerListener(serverListener);
        getServer().getOriginal().addServerListener(serverListener);
    }

    /**
     * 
     * @param listener to be notified of Cloud server and application changes.
     * The editor manages the lifecycle of the listener once it is added,
     * including removing it when the editor is disposed.
     */
    public void addCloudServerListener(CloudServerListener listener) {
        if (listener != null && !cloudServerListeners.contains(listener)) {
            ServerEventHandler.getDefault().addServerListener(listener);
            cloudServerListeners.add(listener);
        }
    }

    @Override
    public void dispose() {
        for (CloudServerListener listener : cloudServerListeners) {
            ServerEventHandler.getDefault().removeServerListener(listener);
        }

        getServer().getOriginal().removeServerListener(serverListener);

        if (mform != null) {
            mform.dispose();
            mform = null;
        }
        super.dispose();
    };

    public CloudFoundryServer getCloudServer() {
        return cloudServer;
    }

    public ApplicationMasterDetailsBlock getMasterDetailsBlock() {
        return masterDetailsBlock;
    }

    public List<CloudService> getServices() {
        return services;
    }

    public int[] getApplicationMemoryChoices() {
        return applicationMemoryChoices;
    }

    public boolean isDisposed() {
        return sform.isDisposed();
    }

    public void reflow() {
        mform.getForm().reflow(true);
    }

    public void refresh(RefreshArea area) {
        RefreshEditorAction.getRefreshAction(this, area).run();
    }

    public void selectAndReveal(IModule module) {
        // Refresh the UI immediately with the cached information for the module
        masterDetailsBlock.refreshUI(RefreshArea.MASTER);
        TableViewer viewer = masterDetailsBlock.getMasterPart().getApplicationsViewer();
        viewer.setSelection(new StructuredSelection(module));

        // Launch a fresh operation that will update the module. As this is
        // longer
        // running, it will eventually refresh the UI via events
        refresh(RefreshArea.DETAIL);
    }

    @Override
    public void setFocus() {
    }

    public void setMessage(String message, int messageType) {
        String messageToDisplay = message;
        if (messageToDisplay == null) {
            sform.setMessage(null, IMessageProvider.NONE);
        } else {
            // First replace all return carriages, or new lines with spaces
            StringBuffer buffer = new StringBuffer(messageToDisplay);
            for (int i = 0; i < buffer.length(); i++) {
                char ch = buffer.charAt(i);
                if (ch == '\r' || ch == '\n') {
                    buffer.replace(i, i + 1, " "); //$NON-NLS-1$
                }
            }

            if (buffer.length() > MAX_ERROR_MESSAGE) {
                String endingSegment = Messages.CloudFoundryApplicationsEditorPage_TEXT_SEE_ERRORLOG;

                messageToDisplay = buffer.substring(0, MAX_ERROR_MESSAGE).trim() + endingSegment;
                CloudFoundryPlugin.logError(message);
            } else {
                messageToDisplay = buffer.toString();
            }

            sform.setMessage(messageToDisplay, messageType);
        }
    }

    public void setServices(List<CloudService> services) {
        this.services = services;
    }

    public void setApplicationMemoryChoices(int[] applicationMemoryChoices) {
        this.applicationMemoryChoices = applicationMemoryChoices;
    }

    private synchronized void setRefreshOp(RefreshEditorOperation op) {
        this.currentRefreshOp = op;
    }

    private synchronized RefreshEditorOperation getRefreshOp() {
        return this.currentRefreshOp;
    }

    private class ServerListener implements CloudServerListener, IServerListener {
        public void serverChanged(final CloudServerEvent event) {

            if (event.getServer() == null) {
                CloudFoundryPlugin.logError(
                        "Internal error: unable to refresh editor. No Cloud server specified in the server event."); // $NON-NLS-1$
                return;
            }
            // Do not refresh if not from the same server
            if (!cloudServer.getServer().getId().equals(event.getServer().getServer().getId())) {
                return;
            }

            // Don't trigger editor refresh on instances update to avoid
            // multiple
            // refreshes as it is performed
            // as part of an application update operation which triggers
            // a separate module refresh event
            if (event.getType() != CloudServerEvent.EVENT_INSTANCES_UPDATED) {
                RefreshArea area = event instanceof EditorCloudEvent ? ((EditorCloudEvent) event).getRefreshArea()
                        : RefreshArea.ALL;
                launchRefresh(new RefreshEditorOperation(event, area));
            }
        }

        public void serverChanged(ServerEvent event) {
            // refresh when server is saved, e.g. due to add/remove of modules
            if (event.getKind() == ServerEvent.SERVER_CHANGE) {
                launchRefresh(new RefreshEditorOperation(CloudServerEvent.EVENT_SERVER_REFRESHED, RefreshArea.ALL,
                        event.getStatus()));
            }
        }
    }

    protected void launchRefresh(RefreshEditorOperation refreshOp) {

        setRefreshOp(refreshOp);

        // Only schedule one job per editor page session, in case multiple
        // refresh requests are received, only the one that is currently
        // scheduled should execute
        if (refreshJob == null) {
            refreshJob = new UIJob(Messages.CloudFoundryApplicationsEditorPage_JOB_REFRESH) {

                @Override
                public IStatus runInUIThread(IProgressMonitor monitor) {

                    RefreshEditorOperation op = getRefreshOp();
                    if (op != null) {
                        op.run(monitor);
                    }
                    return Status.OK_STATUS;
                }
            };
        }

        refreshJob.schedule();
    }

    protected void setMessageInPage(IStatus status) {
        String message = status != null ? status.getMessage() : null;
        if (message == null || status == null || status.isOK()) {
            setMessage(null, IMessageProvider.NONE);
        } else {
            int providerStatus = IMessageProvider.NONE;
            switch (status.getSeverity()) {
            case IStatus.INFO:
                providerStatus = IMessageProvider.INFORMATION;
                break;
            case IStatus.WARNING:
                providerStatus = IMessageProvider.WARNING;
                break;
            case IStatus.ERROR:
                providerStatus = IMessageProvider.ERROR;
                break;
            }

            setMessage(message, providerStatus);
        }

    }

    /**
     * Refresh operation that should only be run in UI thread.
     *
     */
    private class RefreshEditorOperation {

        private CloudServerEvent event;

        private final RefreshArea area;

        private final int type;

        private final IStatus status;

        public RefreshEditorOperation(CloudServerEvent event, RefreshArea area) {
            this.event = event;
            this.area = area;
            this.type = event.getType();
            this.status = event.getStatus() != null ? event.getStatus() : Status.OK_STATUS;
        }

        public RefreshEditorOperation(int eventType, RefreshArea area, IStatus status) {
            this.area = area;
            this.type = eventType;
            this.status = status != null ? status : Status.OK_STATUS;
        }

        public void run(IProgressMonitor monitor) {

            if (isDisposed() || mform == null || mform.getForm() == null || mform.getForm().isDisposed()
                    || masterDetailsBlock.getMasterPart().getManagedForm().getForm().isDisposed()) {
                return;
            }

            if (event instanceof CloudRefreshEvent
                    && (this.type == CloudServerEvent.EVENT_UPDATE_SERVICES
                            || this.type == CloudServerEvent.EVENT_SERVER_REFRESHED)
                    && status.getSeverity() != IStatus.ERROR) {
                List<CloudService> services = ((CloudRefreshEvent) event).getServices();
                if (services == null) {
                    services = Collections.emptyList();
                }
                setServices(services);
            }

            Throwable error = status.getException();

            // Refresh the UI before handing any errors
            masterDetailsBlock.refreshUI(area);

            // Process errors
            if (status.getSeverity() == IStatus.WARNING || status.getSeverity() == IStatus.INFO) {
                setMessageInPage(status);
            } else if (error != null || status.getSeverity() == IStatus.ERROR) {
                StatusManager.getManager().handle(status, StatusManager.LOG);
                setMessageInPage(status);
            } else {
                IModule currentModule = getMasterDetailsBlock().getCurrentModule();

                // If no error is found, be sure to set null for the
                // message to
                // clear any error messages
                IStatus status = null;
                if (currentModule != null) {
                    CloudFoundryApplicationModule appModule = getCloudServer()
                            .getExistingCloudModule(currentModule);
                    if (appModule != null) {
                        status = appModule.getStatus();
                    }
                }
                setMessageInPage(status);
            }
        }
    }

}