com.nokia.carbide.cpp.internal.pi.wizards.ui.ProfilerActivatorGroup.java Source code

Java tutorial

Introduction

Here is the source code for com.nokia.carbide.cpp.internal.pi.wizards.ui.ProfilerActivatorGroup.java

Source

/*
 * Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). 
 * All rights reserved.
 * This component and the accompanying materials are made available
 * under the terms of the License "Eclipse Public License v1.0"
 * which accompanies this distribution, and is available
 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
 *
 * Initial Contributors:
 * Nokia Corporation - initial contribution.
 *
 * Contributors:
 *
 * Description: 
 *
 */

package com.nokia.carbide.cpp.internal.pi.wizards.ui;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.MessageFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.eclipse.core.resources.WorkspaceJob;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.wizard.IWizardContainer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.DirectoryDialog;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.Text;

import com.nokia.carbide.cpp.internal.pi.plugin.model.ITrace;
import com.nokia.carbide.cpp.pi.PiPlugin;
import com.nokia.carbide.cpp.pi.export.ITraceProvider;
import com.nokia.carbide.cpp.pi.wizards.WizardsPlugin;
import com.nokia.s60tools.ui.preferences.PreferenceUtils;

/**
 * Provides functionality of the profiler activator
 */
public class ProfilerActivatorGroup extends AbstractBaseGroup {

    private TableViewer profileDataTable;
    private Composite rightButtonsComposite;
    private Label connectionNameInUseLabel;
    private IWizardContainer wizardContainer;
    private NewPIWizardPage wizardPage;
    private TraceHandler traceHandler;
    private PluginSelectionGroup pluginSelectionGroup;
    private Group settingsButtonGroup;
    private Button refreshListButton;
    private Button connectionSettingsButton;
    private Button tracingButton;

    /**
     * Constructor
     * 
     * @param parent
     *            instance of the parent composite
     * @param wizardSettings
     *            instance of the INewPIWizardSettings
     * @param wizardPage
     *            instance of the NewPIWizardPage
     * @param wizardContainer
     *            instance of the IWizardContainer
     */
    public ProfilerActivatorGroup(Composite parent, INewPIWizardSettings wizardSettings, NewPIWizardPage wizardPage,
            IWizardContainer wizardContainer) {
        super(parent, wizardSettings, true);
        this.wizardContainer = wizardContainer;
        this.wizardPage = wizardPage;
        traceHandler = new TraceHandler(this);
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * com.nokia.carbide.cpp.internal.pi.wizards.ui.AbstractBaseGroup#createContent
     * ()
     */
    protected void createContent() {
        GridLayout gridLayout = new GridLayout();
        gridLayout.numColumns = 2;
        this.setLayout(gridLayout);
        this.setLayoutData(new GridData(GridData.FILL_BOTH));
        this.setText(Messages.getString("NewPIWizardPageInputTask.fromDevice")); //$NON-NLS-1$

        final Composite leftTables = new Composite(this, SWT.NONE);
        leftTables.setLayout(new GridLayout());
        leftTables.setLayoutData(new GridData(GridData.FILL_BOTH));
        pluginSelectionGroup = new PluginSelectionGroup(leftTables, wizardSettings, true);

        new Label(leftTables, SWT.NONE)
                .setText(Messages.getString("ProfilerActivatorGroup.profilerDataTableTitle")); //$NON-NLS-1$
        profileDataTable = new TableViewer(leftTables,
                SWT.BORDER | SWT.SINGLE | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION);

        TableColumn column = new TableColumn(profileDataTable.getTable(), SWT.NONE);
        column.setText(Messages.getString("ProfilerActivatorGroup.columnName")); //$NON-NLS-1$
        column.setWidth(200);
        column.setResizable(true);
        column.setMoveable(true);
        column.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent e) {
                if (!(e.widget instanceof TableColumn))
                    return;
                ((AbstractBaseSorter) profileDataTable.getSorter()).doSort(0);
                profileDataTable.refresh();

            }
        });

        column = new TableColumn(profileDataTable.getTable(), SWT.NONE);
        column.setText(Messages.getString("ProfilerActivatorGroup.columnTime")); //$NON-NLS-1$
        column.setWidth(120);
        column.setResizable(true);
        column.setMoveable(true);
        column.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent e) {
                if (!(e.widget instanceof TableColumn))
                    return;
                ((AbstractBaseSorter) profileDataTable.getSorter()).doSort(1);
                profileDataTable.refresh();

            }
        });

        column = new TableColumn(profileDataTable.getTable(), SWT.NONE);
        column.setText(Messages.getString("ProfilerActivatorGroup.columnSize")); //$NON-NLS-1$
        column.setWidth(120);
        column.setResizable(true);
        column.setMoveable(true);
        column.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent e) {
                if (!(e.widget instanceof TableColumn))
                    return;
                ((AbstractBaseSorter) profileDataTable.getSorter()).doSort(2);
                profileDataTable.refresh();

            }
        });

        GridData fileLogsTableGridData = new GridData(GridData.FILL_BOTH);
        fileLogsTableGridData.minimumHeight = 120;
        profileDataTable.getTable().setLayoutData(fileLogsTableGridData);
        profileDataTable.getTable().setHeaderVisible(true);
        profileDataTable.getTable().setLinesVisible(true);
        profileDataTable.setContentProvider(new IStructuredContentProvider() {
            public Object[] getElements(Object inputElement) {
                if (inputElement instanceof List<?>) {
                    return ((List<?>) inputElement).toArray();
                }
                return new Object[0];
            }

            public void dispose() {
            }

            public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
            }

        });

        profileDataTable.setSorter(new AbstractBaseSorter(profileDataTable.getTable(), 0) {
            @Override
            public int compare(Viewer viewer, Object e1, Object e2) {
                ProfilerDataPlugins pdp1 = (ProfilerDataPlugins) e1;
                ProfilerDataPlugins pdp2 = (ProfilerDataPlugins) e2;
                int returnCode = 0;
                switch (column) {
                case 0:
                    returnCode = pdp1.getProfilerDataPath().lastSegment()
                            .compareTo(pdp2.getProfilerDataPath().lastSegment());
                    break;
                case 1:
                    returnCode = compareNumber(pdp1.getTime(), pdp2.getTime());
                    break;
                case 2:
                    returnCode = compareNumber(pdp1.getSize(), pdp2.getSize());
                    break;

                default:

                    break;
                }
                if (!sortAscending)
                    returnCode = -returnCode;
                return returnCode;
            }
        });

        profileDataTable.setLabelProvider(new AbstractLabelProvider() {
            public String getColumnText(Object element, int columnIndex) {
                ProfilerDataPlugins plugins = (ProfilerDataPlugins) element;

                switch (columnIndex) {
                case 0:
                    return plugins.getProfilerDataPath().lastSegment();
                case 1:
                    SimpleDateFormat formatter = new SimpleDateFormat("mm:ss"); //$NON-NLS-1$
                    return formatter.format(new Date(plugins.getTime()));
                case 2:
                    return String.valueOf((plugins.getSize() + 512) / 1024);
                default:
                    break;
                }
                return ""; //$NON-NLS-1$
            }
        });

        rightButtonsComposite = new Composite(this, SWT.NONE);

        GridData rightButtonsCompositeGridData = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
        rightButtonsComposite.setLayoutData(rightButtonsCompositeGridData);
        rightButtonsComposite.setLayout(new GridLayout());

        // Connection settings button
        settingsButtonGroup = new Group(rightButtonsComposite, SWT.NONE);
        settingsButtonGroup.setLayout(new GridLayout());
        settingsButtonGroup.setLayoutData(new GridData(GridData.FILL_BOTH));

        refreshListButton = new Button(settingsButtonGroup, SWT.PUSH);
        refreshListButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
        refreshListButton.setText(Messages.getString("ProfilerActivatorGroup.refreshButtonName")); //$NON-NLS-1$
        refreshListButton.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                updatePlugins(traceHandler.fetchAvailablePlugins());
            }
        });

        connectionSettingsButton = new Button(settingsButtonGroup, SWT.PUSH);
        connectionSettingsButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
        connectionSettingsButton.setText(Messages.getString("ProfilerActivatorGroup.connectionSettingsButtonName")); //$NON-NLS-1$
        connectionSettingsButton.addSelectionListener(new SelectionAdapter() {

            @Override
            public void widgetSelected(SelectionEvent e) {
                Shell shell = PiPlugin.getCurrentlyActiveWbWindowShell();
                PreferenceUtils.openPreferencePage(PiPlugin.getTraceProvider().getTraceSourcePreferencePageId(),
                        shell);
                updateConnectionText();
            }
        });
        // Connection settings labels
        Label connectionTextLabel = new Label(settingsButtonGroup, SWT.LEFT);
        connectionTextLabel.setText(Messages.getString("ProfilerActivatorGroup.currentlyUsingTitle")); //$NON-NLS-1$
        connectionTextLabel.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_CENTER));

        connectionNameInUseLabel = new Label(settingsButtonGroup, SWT.NONE);
        connectionNameInUseLabel.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_CENTER));
        Group traceButtonGroup = new Group(rightButtonsComposite, SWT.NONE);
        traceButtonGroup.setLayout(new GridLayout());
        traceButtonGroup.setLayoutData(new GridData(GridData.FILL_BOTH));
        new Label(traceButtonGroup, SWT.LEFT).setText(Messages.getString("ProfilerActivatorGroup.filePrefixTitle")); //$NON-NLS-1$
        final Text filePrefixText = new Text(traceButtonGroup, SWT.BORDER);
        filePrefixText.setText("PIProfiler_#"); //$NON-NLS-1$
        filePrefixText.setLayoutData(new GridData(GridData.FILL_BOTH));

        // Start/Stop tracing button
        tracingButton = new Button(traceButtonGroup, SWT.PUSH);
        tracingButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
        tracingButton.setText(Messages.getString("ProfilerActivatorGroup.startTracingButtonName")); //$NON-NLS-1$
        tracingButton.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent e) {
                if (PiPlugin.getTraceProvider().isListening()) {
                    addTraceFile(traceHandler.stopTrace());
                } else {
                    traceHandler.startTrace(filePrefixText.getText(), pluginSelectionGroup.getSelectedPluginIds());
                }
                updateButtons();
            }
        });

    }

    /**
     * Compare two long number
     * 
     * @param one
     * @param two
     * @return result of the comparison
     */
    private int compareNumber(long one, long two) {
        if (one > two) {
            return 1;
        } else if (one < two) {
            return -1;
        } else {
            return 0;
        }
    }

    /**
     * updateConnectionText updates connection text to match used settings
     */
    private void updateConnectionText(boolean forceUpdate) {
        traceHandler.updateCurrenConnection();
        if (pluginSelectionGroup.getSelectedPluginIds().length <= 0 || forceUpdate) {
            updatePlugins(traceHandler.fetchAvailablePlugins());
        }
    }

    /**
     * updateConnectionText updates connection text to match used settings
     */
    private void updateConnectionText() {
        traceHandler.updateCurrenConnection();
    }

    /**
     * Set current connection name
     * 
     * @param connection
     *            the current connection name
     */
    public void setCurrentConnection(final String connection) {
        Display.getDefault().syncExec(new Runnable() {
            public void run() {
                connectionNameInUseLabel.setText(connection);
                getParent().layout(true, true);
            }
        });

    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * com.nokia.carbide.cpp.internal.pi.wizards.ui.AbstractBaseGroup#getTable()
     */
    @Override
    public Table getTable() {
        return profileDataTable.getTable();
    }

    @Override
    public IStatus validateContent(NewPIWizard wizardPage) {
        List<ProfilerDataPlugins> dataFiles = getProfilerDataFiles();
        if (dataFiles != null && dataFiles.size() > 0) {
            wizardPage.setProfilerDataFiles(getProfilerDataFiles());
            return Status.OK_STATUS;
        } else {
            return new Status(Status.INFO, WizardsPlugin.PLUGIN_ID,
                    Messages.getString("ProfilerActivatorGroup.profilerGroupDescription")); //$NON-NLS-1$
        }

    }

    @Override
    public void setVisible(boolean visible) {
        if (visible) {
            updateConnectionText(false);
        }
        super.setVisible(visible);

    }

    private void updatePlugins(final List<ITrace> plugins) {
        pluginSelectionGroup.updateTraceIds(new ProfilerDataPlugins(new Path(""), plugins)); //$NON-NLS-1$
        updateButtons();
    }

    /**
     * Add given trace data file to profiler data file table
     * 
     * @param path
     */
    private void addTraceFile(final IPath path) {
        if (path == null) {
            return;
        }
        ProfilerDataPlugins dataPlugins = removeWithPath(
                path.removeFileExtension().addFileExtension(ITraceProvider.BASE_FILE));
        if (dataPlugins != null) {
            try {
                addProfilerDataFile(path, dataPlugins.getTime(), path.toFile().length());
                refreshTable(profileDataTable, true);
            } catch (Exception e) {
                wizardPage.setErrorMessage(e.getMessage() + " " //$NON-NLS-1$
                        + Messages.getString("ProfilerActivatorGroup.tryDeselectPluginsFromList")); //$NON-NLS-1$
                wizardPage.setPageComplete(false);
                refreshTable(profileDataTable, false);
                path.toFile().delete();
            }
        }
    }

    public NewPIWizardPage getWizardPage() {
        return wizardPage;
    }

    public IWizardContainer getWizardContainer() {
        return wizardContainer;
    }

    /**
     * Update trace data files
     * 
     * @param path
     * @param time
     * @param size
     */
    public void updateTraceDataFile(final IPath path, final long time, final long size) {
        Display.getDefault().syncExec(new Runnable() {
            public void run() {
                // remove if both time and size are -1
                if (time == -1 && size == -1) {
                    removeWithPath(path);
                } else {
                    updateProfilerDataFile(path, time, size);
                }
                refreshTable(profileDataTable, false);
            }
        });
    }

    /**
     * Update buttons
     */
    public void updateButtons() {
        if (PiPlugin.getTraceProvider().isListening()) {
            wizardPage.setErrorMessage(null);
            refreshListButton.setEnabled(false);
            connectionSettingsButton.setEnabled(false);
            ((NewPIWizardPageInputTask) wizardPage).setButtonGroupEnabled(false);
            tracingButton.setText(Messages.getString("ProfilerActivatorGroup.stopTracingButtonName")); //$NON-NLS-1$
        } else {
            refreshListButton.setEnabled(true);
            connectionSettingsButton.setEnabled(true);
            ((NewPIWizardPageInputTask) wizardPage).setButtonGroupEnabled(true);
            tracingButton.setText(Messages.getString("ProfilerActivatorGroup.startTracingButtonName")); //$NON-NLS-1$
        }

        if (pluginSelectionGroup.getSelectedPluginIds().length <= 0) {
            tracingButton.setEnabled(false);
        } else {
            tracingButton.setEnabled(true);
        }
    }

    /**
     * Generate next dat file name
     * 
     * @param path
     * @return
     */
    private IPath generateDatFile(IPath path) {
        while (path.toFile().exists()) {
            String file = path.lastSegment();
            String fileExtension = path.getFileExtension();
            file = file.substring(0, file.lastIndexOf("." + fileExtension)); //$NON-NLS-1$
            int index = file.lastIndexOf("_"); //$NON-NLS-1$
            if (index != -1) {
                try {
                    int count = Integer.valueOf(file.substring(index + 1));
                    count++;
                    file = file.substring(0, index + 1) + count;
                    path = path.removeLastSegments(1).append(file + "." + fileExtension); //$NON-NLS-1$
                } catch (Exception e) {
                    path = path.removeLastSegments(1).append(file + "_0." + fileExtension); //$NON-NLS-1$
                }

            } else {
                path = path.removeLastSegments(1).append(file + "_0." + fileExtension); //$NON-NLS-1$
            }
        }
        return path;

    }

    /**
     * Handle temporary profiler data files in case user is tried to close
     * wizard and user has traced some data from device
     * 
     * @param forceRemove
     */
    public void handleTemporaryProfilerDataFiles(boolean forceRemove) {
        final List<ProfilerDataPlugins> plugins = new ArrayList<ProfilerDataPlugins>();
        plugins.addAll(getProfilerDataFiles());
        getProfilerDataFiles().clear();
        if (forceRemove) {
            deleteProfilerDataFiles(plugins);
        } else if (plugins.size() > 0) {
            boolean answer = MessageDialog.openQuestion(Display.getDefault().getActiveShell(),
                    Messages.getString("ProfilerActivatorGroup.questionDialogTitle"), //$NON-NLS-1$
                    Messages.getString("ProfilerActivatorGroup.questionDialogMessage")); //$NON-NLS-1$
            if (answer) {
                // open file dialog for selecting a crash file
                DirectoryDialog dialog = new DirectoryDialog(Display.getDefault().getActiveShell());
                dialog.setText(Messages.getString("ProfilerActivatorGroup.directorySelectionDialogTitle")); //$NON-NLS-1$
                final String result = dialog.open();
                if (result != null) {
                    WorkspaceJob job = new WorkspaceJob(
                            Messages.getString("ProfilerActivatorGroup.movingProfilerDataFilesJob") + result) { //$NON-NLS-1$
                        @Override
                        public IStatus runInWorkspace(IProgressMonitor monitor) throws CoreException {
                            monitor.beginTask("", IProgressMonitor.UNKNOWN); //$NON-NLS-1$
                            for (ProfilerDataPlugins plugin : plugins) {
                                IPath dataFile = plugin.getProfilerDataPath();
                                IPath targetFile = generateDatFile(new Path(result).append(dataFile.lastSegment()));
                                try {
                                    moveFile(dataFile, targetFile,
                                            new SubProgressMonitor(monitor, IProgressMonitor.UNKNOWN));
                                } catch (Exception e) {
                                    List<ProfilerDataPlugins> list = new ArrayList<ProfilerDataPlugins>();
                                    list.add(plugin);
                                    deleteProfilerDataFiles(list);
                                    e.printStackTrace();
                                    MessageDialog.openError(getShell(),
                                            Messages.getString("ProfilerActivatorGroup.errorDialogTitle"), //$NON-NLS-1$
                                            MessageFormat.format(
                                                    Messages.getString("ProfilerActivatorGroup.failedToMoveFileTo"), //$NON-NLS-1$
                                                    dataFile.lastSegment(), result));
                                }
                            }
                            monitor.done();
                            return Status.OK_STATUS;
                        }
                    };
                    job.schedule();
                } else {
                    deleteProfilerDataFiles(plugins);
                }
            } else {
                deleteProfilerDataFiles(plugins);
            }
        }
    }

    /**
     * Delete profiler data files
     * 
     * @param plugins
     */
    private void deleteProfilerDataFiles(final List<ProfilerDataPlugins> plugins) {
        WorkspaceJob job = new WorkspaceJob(
                Messages.getString("ProfilerActivatorGroup.removeProfilerDataFilesJob")) { //$NON-NLS-1$

            @Override
            public IStatus runInWorkspace(IProgressMonitor monitor) throws CoreException {
                monitor.beginTask("", IProgressMonitor.UNKNOWN); //$NON-NLS-1$
                for (ProfilerDataPlugins plugin : plugins) {
                    IPath dataFile = plugin.getProfilerDataPath();
                    monitor.setTaskName(MessageFormat.format(
                            Messages.getString("ProfilerActivatorGroup.deletingProfilerDataFiles"), //$NON-NLS-1$
                            dataFile.lastSegment()));
                    if (dataFile.toFile().exists()) {
                        while (!dataFile.toFile().delete()) {
                            if (monitor.isCanceled()) {
                                break;
                            }
                            try {
                                Thread.sleep(1000);
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        }
                    }

                }
                ;
                monitor.done();
                return Status.OK_STATUS;
            }

        };
        job.schedule();

    }

    /**
     * Move profiler data file from temporary location to user selected target
     * 
     * @param source
     * @param target
     * @param monitor
     * @throws IOException
     */
    private void moveFile(final IPath source, IPath target, IProgressMonitor monitor) throws IOException {
        if (monitor == null) {
            monitor = new NullProgressMonitor();
        }
        InputStream in = null;
        OutputStream out = null;
        try {
            monitor.beginTask(
                    MessageFormat.format(Messages.getString("ProfilerActivatorGroup.copyingProfilerDataFiles"), //$NON-NLS-1$
                            source.lastSegment(), target.removeLastSegments(1)),
                    IProgressMonitor.UNKNOWN);
            in = new FileInputStream(source.toFile());
            out = new FileOutputStream(target.toFile());
            int bufferSize = 1024;
            byte[] buf = new byte[bufferSize];
            int len;
            while ((len = in.read(buf)) > 0) {
                out.write(buf, 0, len);
                out.flush();
            }

        } finally {
            if (in != null) {
                in.close();
            }
            if (out != null) {
                out.close();
            }
            monitor.setTaskName(MessageFormat.format(
                    Messages.getString("ProfilerActivatorGroup.deletingProfilerDataFiles"), source.lastSegment())); //$NON-NLS-1$
            while (!source.toFile().delete()) {
                if (monitor.isCanceled()) {
                    break;
                }
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            monitor.done();
        }
    }
}