org.spotter.eclipse.ui.view.ActiveRunView.java Source code

Java tutorial

Introduction

Here is the source code for org.spotter.eclipse.ui.view.ActiveRunView.java

Source

/**
 * Copyright 2014 SAP AG
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.spotter.eclipse.ui.view;

import java.net.ConnectException;
import java.util.Set;

import org.eclipse.core.resources.IProject;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.ViewerCell;
import org.eclipse.swt.SWT;
import org.eclipse.swt.SWTException;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.part.ViewPart;
import org.lpe.common.util.system.LpeSystemUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.spotter.eclipse.ui.Activator;
import org.spotter.eclipse.ui.ServiceClientWrapper;
import org.spotter.eclipse.ui.editors.HierarchyEditor;
import org.spotter.eclipse.ui.jobs.DynamicSpotterRunJob;
import org.spotter.eclipse.ui.jobs.JobsContainer;
import org.spotter.eclipse.ui.model.IExtensionItem;
import org.spotter.eclipse.ui.model.IExtensionItemFactory;
import org.spotter.eclipse.ui.model.ImmutableExtensionItemFactory;
import org.spotter.eclipse.ui.providers.RunExtensionsImageProvider;
import org.spotter.eclipse.ui.providers.SpotterExtensionsLabelProvider;
import org.spotter.eclipse.ui.util.WidgetUtils;
import org.spotter.eclipse.ui.viewers.ExtensionsGroupViewer;
import org.spotter.shared.hierarchy.model.XPerformanceProblem;
import org.spotter.shared.status.SpotterProgress;

/**
 * A view to display the progress of the current diagnosis run of
 * DynamicSpotter.
 * 
 * @author Denis Knoepfle
 * 
 */
public class ActiveRunView extends ViewPart {

    public static final String VIEW_ID = "org.spotter.eclipse.ui.view.activeRunView";

    private static final long SLEEP_TIME_MILLIS = 1000;
    private static final Logger LOGGER = LoggerFactory.getLogger(ActiveRunView.class);

    private static final String ACTIVE_RUN_VIEW_TITLE = "Active Run";
    private static final String ACTIVE_RUN_EMPTY_CONTENT_DESC = "No project selected.";
    private static final String ACTIVE_RUN_CONTENT_DESC_TEMPLATE = "DynamicSpotter diagnosis of project '%s'";
    private static final String ACTIVE_RUN_MULTI_CONTENT_DESC = "Selected multiple projects.";

    private final IExtensionItemFactory extensionItemFactory;
    private boolean isDisposed;
    private Label label;
    private TreeViewer treeViewer;
    private long currentViewerInputJobId;
    private SpotterProgress spotterProgress;

    private RunExtensionsImageProvider runExtensionsImageProvider;

    private class ViewUpdater implements Runnable {

        @Override
        public void run() {
            while (!isDisposed) {
                try {
                    Thread.sleep(SLEEP_TIME_MILLIS);
                } catch (InterruptedException e) {
                    LOGGER.warn("ViewUpdater was interrupted");
                }
                try {
                    updateView();
                } catch (SWTException e) {
                    LOGGER.debug("stop view updater as view is already disposed");
                    break;
                }
            }
        }

    }

    /**
     * The constructor.
     */
    public ActiveRunView() {
        this.extensionItemFactory = new ImmutableExtensionItemFactory(null);
        this.isDisposed = false;
        this.spotterProgress = null;
        this.currentViewerInputJobId = 0;
    }

    @Override
    public void createPartControl(Composite parent) {
        setPartName(ACTIVE_RUN_VIEW_TITLE);
        setContentDescription(ACTIVE_RUN_EMPTY_CONTENT_DESC);

        // ensure that the parent's layout is a FillLayout
        if (!(parent.getLayout() instanceof FillLayout)) {
            parent.setLayout(new FillLayout());
        }

        Composite composite = new Composite(parent, SWT.NONE);
        composite.setLayout(WidgetUtils.createGridLayout(1));

        label = new Label(composite, SWT.WRAP);
        label.setLayoutData(new GridData(SWT.TOP, SWT.FILL, true, false));
        createTreeViewer(composite);

        DisposeListener disposeListener = new DisposeListener() {
            @Override
            public void widgetDisposed(DisposeEvent e) {
                isDisposed = true;
            }
        };

        label.addDisposeListener(disposeListener);
        treeViewer.getTree().addDisposeListener(disposeListener);

        LpeSystemUtils.submitTask(new ViewUpdater());
    }

    private void createTreeViewer(Composite parent) {
        treeViewer = ExtensionsGroupViewer.createTreeViewer(parent, extensionItemFactory.createExtensionItem(),
                null, false);

        SpotterExtensionsLabelProvider labelProvider = new SpotterExtensionsLabelProvider() {
            @Override
            public void update(ViewerCell cell) {
                super.update(cell);
                Object element = cell.getElement();
                if (element instanceof IExtensionItem) {
                    String suffix = createSpotterProgressSuffix(element);
                    if (!suffix.isEmpty()) {
                        cell.setText(cell.getText() + suffix);
                    }
                }
            }

            private String createSpotterProgressSuffix(Object element) {
                String suffix = "";
                if (spotterProgress != null) {
                    Object xmlModel = ((IExtensionItem) element).getModelWrapper().getXMLModel();
                    if (xmlModel instanceof XPerformanceProblem) {
                        String problemId = ((XPerformanceProblem) xmlModel).getUniqueId();
                        String progressString = DynamicSpotterRunJob.createProgressString(spotterProgress,
                                problemId, true);
                        if (progressString != null) {
                            suffix = progressString;
                        }
                    }
                }
                return suffix;
            }
        };

        runExtensionsImageProvider = new RunExtensionsImageProvider();
        labelProvider.setImageProvider(runExtensionsImageProvider);
        treeViewer.setLabelProvider(labelProvider);
    }

    @Override
    public void setFocus() {
        treeViewer.getControl().setFocus();
    }

    @Override
    public void dispose() {
        this.isDisposed = true;
    }

    private void updateView() {
        if (isDisposed) {
            return;
        }

        Set<IProject> selected = Activator.getDefault().getSelectedProjects();
        final String description;
        if (selected.isEmpty()) {
            description = ACTIVE_RUN_EMPTY_CONTENT_DESC;
            clear();
        } else if (selected.size() == 1) {
            IProject project = selected.iterator().next();
            description = String.format(ACTIVE_RUN_CONTENT_DESC_TEMPLATE, project.getName());
            updateContent(project);
        } else {
            description = ACTIVE_RUN_MULTI_CONTENT_DESC;
            clear();
        }

        Shell shell = getSite() == null ? null : getSite().getShell();
        WidgetUtils.submitSyncExecIgnoreDisposed(shell, new Runnable() {
            @Override
            public void run() {
                setContentDescription(description);
            }
        });
    }

    private void updateContent(IProject project) {
        final String projectName = project.getName();
        ServiceClientWrapper client = Activator.getDefault().getClient(projectName);
        boolean hasClientConnection = client.testConnection(false);
        boolean hasConnectionErrorOccured = false;
        Long jobId = null;

        if (hasClientConnection) {
            try {
                jobId = JobsContainer.readCurrentJob(client, project);
            } catch (ConnectException e) {
                hasConnectionErrorOccured = true;
            }
        }

        if (!hasClientConnection || hasConnectionErrorOccured) {
            clear();
            WidgetUtils.submitSyncExecIgnoreDisposed(label, new Runnable() {
                @Override
                public void run() {
                    label.setText("No connection to DS service. Try again later.");
                }
            });
        } else if (jobId == null) {
            clear();
            WidgetUtils.submitSyncExecIgnoreDisposed(label, new Runnable() {
                @Override
                public void run() {
                    label.setText("Currently no running diagnosis.");
                }
            });
        } else {
            updateDiagnosisData(jobId, client, projectName);
        }
        WidgetUtils.submitSyncExecIgnoreDisposed(label, new Runnable() {
            @Override
            public void run() {
                label.getParent().layout();
            }
        });
    }

    private void updateDiagnosisData(final long jobId, ServiceClientWrapper client, String projectName) {
        if (jobId != currentViewerInputJobId) {
            runExtensionsImageProvider.setSpotterProgress(null);
            XPerformanceProblem rootProblem = client.getCurrentRootProblem(false);
            if (rootProblem == null) {
                WidgetUtils.submitSyncExecIgnoreDisposed(label, new Runnable() {
                    @Override
                    public void run() {
                        label.setText("Cannot fetch root problem!");
                        treeViewer.setInput(null);
                    }
                });
                return;
            }
            final IExtensionItem input = HierarchyEditor.createPerformanceProblemHierarchy(projectName,
                    extensionItemFactory, rootProblem);
            WidgetUtils.submitSyncExecIgnoreDisposed(treeViewer.getControl(), new Runnable() {
                @Override
                public void run() {
                    treeViewer.setInput(input);
                    treeViewer.expandAll();
                }
            });
            currentViewerInputJobId = jobId;
        }

        spotterProgress = client.getCurrentProgressReport();
        runExtensionsImageProvider.setSpotterProgress(spotterProgress);

        WidgetUtils.submitSyncExecIgnoreDisposed(label, new Runnable() {
            @Override
            public void run() {
                label.setText("Diagnosis with job id '" + jobId + "' is in progress!");
                treeViewer.refresh();
            }
        });
    }

    private void clear() {
        WidgetUtils.submitSyncExecIgnoreDisposed(label, new Runnable() {
            @Override
            public void run() {
                label.setText("");
                treeViewer.setInput(null);
                currentViewerInputJobId = 0;
            }
        });
    }

}