com.freescale.deadlockpreventer.agent.InstrumentedProcess.java Source code

Java tutorial

Introduction

Here is the source code for com.freescale.deadlockpreventer.agent.InstrumentedProcess.java

Source

/*******************************************************************************
 * Copyright (c) 2010 Freescale Semiconductor.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors:
 *     Serge Beauchamp (Freescale Semiconductor) - initial API and implementation
 *******************************************************************************/
package com.freescale.deadlockpreventer.agent;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.regex.Pattern;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.preferences.InstanceScope;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.dialogs.ProgressMonitorDialog;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.ui.IMemento;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.XMLMemento;

import com.freescale.deadlockpreventer.ILock;
import com.freescale.deadlockpreventer.NetworkServer.IService;
import com.freescale.deadlockpreventer.QueryService;
import com.freescale.deadlockpreventer.QueryService.ITransaction;
import com.freescale.deadlockpreventer.ReportService;
import com.freescale.deadlockpreventer.agent.IAgent.IProcess;
import com.freescale.deadlockpreventer.agent.StatisticsDialog.Row;

public class InstrumentedProcess implements ReportService.IListener, IProcess {
    private final class DownloadRunnable implements IRunnableWithProgress {
        private final ITransaction[] transactions;
        private final ArrayList<Row> locks;

        private DownloadRunnable(ITransaction[] transactions, ArrayList<Row> locks) {
            this.transactions = transactions;
            this.locks = locks;
        }

        @Override
        public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
            transactions[0] = queryService.createTransaction();
            int count = transactions[0].getLockCount();
            monitor.beginTask("Downloading statistics...", count);
            int index = 0;
            int interval = 100;
            while (index < count) {
                ILock[] tmp = transactions[0].getLocks(index, Math.min(index + interval, count));
                monitor.worked(tmp.length);
                locks.addAll(Arrays.asList(StatisticsDialog.convert(index, tmp)));
                index += interval;
                if (monitor.isCanceled())
                    break;
            }
            monitor.done();
        }
    }

    private String label;
    private String reportKey;

    public String getLabel() {
        return label;
    }

    public void setLabel(String label) {
        this.label = label;
    }

    public String getReportKey() {
        return reportKey;
    }

    public String getQueryKey() {
        return queryKey;
    }

    public void setConflictList(ArrayList<Conflict> conflictList) {
        this.conflictList = conflictList;
    }

    private String queryKey;
    private QueryService queryService;
    private LauncherView launcherView;

    public InstrumentedProcess(LauncherView launcherView, String label) {
        this.label = label;
        this.launcherView = launcherView;
    }

    public String toString() {
        return label;
    }

    @Override
    public int report(String type, String threadID, String conflictThreadID, String lock, String[] lockStack,
            String precedent, String[] precedentStack, String conflict, String[] conflictStack,
            String conflictPrecedent, String[] conflictPrecedentStack, String message) {
        final Conflict conflictItem = new Conflict(this, type, threadID, conflictThreadID, lock, lockStack,
                precedent, precedentStack, conflict, conflictStack, conflictPrecedent, conflictPrecedentStack,
                message);
        conflictList.add(conflictItem);
        ConflictHandler handler = new ConflictHandler(launcherView, conflictItem);
        Display.getDefault().syncExec(handler);
        return handler.result;
    }

    protected Conflict[] getDisplayedConflicts() {
        String filtersString = InstanceScope.INSTANCE.getNode(Activator.PLUGIN_ID).get(IAgent.PREF_DISPLAY_FILTERS,
                launcherView.getDefaultFilters());

        String[] filters = filtersString.split(";");
        Pattern[] patterns = new Pattern[filters.length];
        for (int i = 0; i < filters.length; i++) {
            patterns[i] = Pattern.compile(filters[i]);
        }
        boolean showWarning = launcherView.shouldDisplayWarning();
        ArrayList<Conflict> list = new ArrayList<Conflict>();
        for (Conflict conflict : conflictList) {
            if (!showWarning && !conflict.isError())
                continue;

            boolean passFilters = true;
            for (Pattern pattern : patterns) {
                if (pattern.matcher(conflict.conflict).matches() || pattern.matcher(conflict.precedent).matches()) {
                    passFilters = false;
                    break;
                }
            }
            if (passFilters)
                list.add(conflict);
        }
        return list.toArray(new Conflict[0]);
    }

    private ArrayList<Conflict> conflictList = new ArrayList<Conflict>();

    public void setReportKey(String reportKey) {
        this.reportKey = reportKey;
    }

    public void setQueryKey(String queryKey) {
        this.queryKey = queryKey;
    }

    public void downloadGlobalLockState() {
        FileDialog dialog = new FileDialog(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(),
                SWT.SAVE);
        dialog.setFileName(label + ".lockState");
        final String filePath = dialog.open();
        if (filePath == null)
            return;
        try {
            new ProgressMonitorDialog(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell()).run(true,
                    true, new IRunnableWithProgress() {
                        @Override
                        public void run(IProgressMonitor monitor)
                                throws InvocationTargetException, InterruptedException {
                            XMLMemento root = XMLMemento.createWriteRoot("locks");
                            ITransaction transaction = null;
                            try {

                                IMemento locksRoot = root.createChild("root");

                                HashMap<String, QueryService.IBundleInfo> plugins = new HashMap<String, QueryService.IBundleInfo>();

                                transaction = queryService.createTransaction();
                                if (transaction == null)
                                    return;
                                int count = transaction.getLockCount();
                                monitor.beginTask("Saving state...", count);
                                int index = 0;
                                int interval = 100;
                                while (index < count) {
                                    ILock[] tmp = transaction.getLocks(index, Math.min(index + interval, count));
                                    monitor.worked(tmp.length);

                                    for (int i = 0; i < tmp.length; i++) {
                                        XMLUtil.write(locksRoot, tmp[i]);

                                        String[] stackTrace = tmp[i].getStackTrace();
                                        if (stackTrace.length > 0) {
                                            QueryService.IBundleInfo bundle = transaction.getBundleInfo(tmp[i]);
                                            if (!plugins.containsKey(bundle.getName()))
                                                plugins.put(bundle.getName(), bundle);
                                        }
                                    }
                                    index += interval;
                                    if (monitor.isCanceled())
                                        break;
                                }
                                XMLUtil.write(root, plugins.values());
                            } finally {
                                if (transaction != null)
                                    transaction.close();
                            }
                            File file = new File(filePath);
                            if (file.exists())
                                file.delete();
                            try {
                                FileWriter writer = new FileWriter(file);
                                root.save(writer);
                                writer.close();
                            } catch (IOException e) {
                                e.printStackTrace();
                            }
                            monitor.done();
                        }
                    });
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
        }
    }

    public void displayStatistics() {
        final ITransaction[] transactions = new ITransaction[1];
        final ArrayList<StatisticsDialog.Row> locks = downloadLocks(transactions);
        if (locks.size() != 0) {
            StatisticsDialog dialog = new StatisticsDialog(
                    PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(),
                    locks.toArray(new StatisticsDialog.Row[0]), transactions[0]);
            dialog.open();
        }
    }

    private ArrayList<StatisticsDialog.Row> downloadLocks(final ITransaction[] transactions) {
        final ArrayList<StatisticsDialog.Row> locks = new ArrayList<StatisticsDialog.Row>();
        if (!queryService.isConnected()) {
            try {
                new ProgressMonitorDialog(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell()).run(true,
                        true, new IRunnableWithProgress() {
                            @Override
                            public void run(IProgressMonitor monitor)
                                    throws InvocationTargetException, InterruptedException {
                                while (!queryService.isConnected()) {
                                    if (Display.getDefault().readAndDispatch())
                                        Thread.sleep(100);
                                    if (monitor.isCanceled())
                                        break;
                                }

                            }
                        });
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        if (queryService.isConnected()) {
            if (!queryService.isClosed()) {
                try {
                    new ProgressMonitorDialog(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell())
                            .run(true, true, new DownloadRunnable(transactions, locks));
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            if (locks.size() == 0)
                MessageDialog.openError(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(),
                        "Can't retrieve process information",
                        "Process need to be running to get lock information.");
            else {
                StatisticsDialog dialog = new StatisticsDialog(
                        PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(),
                        locks.toArray(new StatisticsDialog.Row[0]), transactions[0]);
                dialog.open();
            }
        }
        return locks;
    }

    public void setQueryService(QueryService queryService) {
        this.queryService = queryService;
    }

    public IService getQueryService() {
        return queryService;
    }

    public ArrayList<Conflict> getConflictList() {
        return conflictList;
    }
}