org.eclipse.mat.dtfj.InitDTFJ.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.mat.dtfj.InitDTFJ.java

Source

/*******************************************************************************
 * Copyright (c) 2009,2013 IBM Corporation.
 * 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:
 *    IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.mat.dtfj;

import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import org.eclipse.core.runtime.ContributorFactoryOSGi;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IContributor;
import org.eclipse.core.runtime.IExtension;
import org.eclipse.core.runtime.IExtensionDelta;
import org.eclipse.core.runtime.IExtensionPoint;
import org.eclipse.core.runtime.IExtensionRegistry;
import org.eclipse.core.runtime.IRegistryChangeEvent;
import org.eclipse.core.runtime.IRegistryChangeListener;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Plugin;
import org.eclipse.core.runtime.content.IContentType;
import org.eclipse.core.runtime.preferences.InstanceScope;
import org.eclipse.jface.preference.PreferenceStore;
import org.eclipse.ui.preferences.ScopedPreferenceStore;
import org.osgi.framework.BundleContext;

/**
 * Controls the loading of this plugin and finds the available DTFJ
 * implementations.
 * 
 * @author ajohnson
 */
public class InitDTFJ extends Plugin implements IRegistryChangeListener {

    private static final String DTFJ_NAMESPACE = "com.ibm.dtfj.api"; //$NON-NLS-1$
    private static final String DTFJ_IMAGEFACTORY = "imagefactory"; //$NON-NLS-1$

    private static final Map<String, Map<String, String>> allexts = new HashMap<String, Map<String, String>>();

    private static InitDTFJ plugin;

    /**
     * Start the bundle - find DTFJ implementations and convert to parsers.
     * Register listener for new DTFJ implementations.
     */
    public void start(BundleContext context) throws Exception {
        super.start(context);
        plugin = this;
        IExtensionRegistry reg = Platform.getExtensionRegistry();
        if (reg != null) {
            reg.addRegistryChangeListener(this, DTFJ_NAMESPACE);
            registerFileExtensions(reg);
        }
    }

    /**
     * Stop the bundle, deregister parsers associated with DTFJ. Deregister
     * listener for new DTFJ implementations.
     */
    public void stop(BundleContext context) throws Exception {
        IExtensionRegistry reg = Platform.getExtensionRegistry();
        if (reg != null) {
            removeAllExtensions(reg);
            reg.removeRegistryChangeListener(this);
        }
        plugin = null;
        super.stop(context);
    }

    /**
     * DTFJ implementation added/removed.
     */
    public void registryChanged(IRegistryChangeEvent event) {
        IExtensionRegistry reg = Platform.getExtensionRegistry();
        if (reg != null) {
            IContributor cont = getContributor(reg);
            // Find the standard Eclipse content types extension point
            IExtensionPoint contentPoint = contentExtensionPoint(reg);

            for (IExtensionDelta delta : event.getExtensionDeltas(DTFJ_NAMESPACE, DTFJ_IMAGEFACTORY)) {
                IExtension dtfjExtension = delta.getExtension();

                switch (delta.getKind()) {
                case IExtensionDelta.ADDED:
                    try {
                        contributeParserExtension(reg, cont, contentPoint, dtfjExtension);
                    } catch (UnsupportedEncodingException e2) {
                    }
                    break;
                case IExtensionDelta.REMOVED:
                    removeParserExtension(reg, cont, dtfjExtension);
                    break;
                default:
                    break;
                }
            }
        }
    }

    /**
     * Dynamically remove a plugin from the system
     * 
     * @param reg
     * @param cont
     * @param dtfjExtension
     */
    private void removeParserExtension(IExtensionRegistry reg, IContributor cont, IExtension dtfjExtension) {
        for (IConfigurationElement el : dtfjExtension.getConfigurationElements()) {
            if (el.getName().equals("factory")) //$NON-NLS-1$
            {
                String id = el.getAttribute("id"); //$NON-NLS-1$
                String fullid = cont.getName() + "." + id; //$NON-NLS-1$
                allexts.remove(fullid);
            }
        }
    }

    /**
     * Remove all the DTFJ parsers.
     * 
     * @param reg
     *            the extension registry
     */
    private void removeAllExtensions(IExtensionRegistry reg) {
        IContributor cont = getContributor(reg);

        IExtensionPoint dtfjPoint = dtfjExtensionPoint(reg);

        if (dtfjPoint != null) {
            // Look through each DTFJ implementation
            for (IExtension ex : dtfjPoint.getExtensions()) {
                removeParserExtension(reg, cont, ex);
            }
            // Only clear cached dumps if there was an extension point present, so we had the DTFJ interface present
            DTFJIndexBuilder.clearCachedDumps();
        }
        allexts.clear();
    }

    /**
     * Convert DTFJ extensions into MAT parser extensions
     * 
     * @param reg
     *            the extension registry
     */
    void registerFileExtensions(IExtensionRegistry reg) {
        try {
            IContributor cont = getContributor(reg);

            IExtensionPoint dtfjPoint = dtfjExtensionPoint(reg);

            // Find the standard Eclipse content types extension point
            IExtensionPoint contentPoint = contentExtensionPoint(reg);

            if (dtfjPoint != null) {
                // Look through each DTFJ implementation
                for (IExtension ex : dtfjPoint.getExtensions()) {
                    contributeParserExtension(reg, cont, contentPoint, ex);
                }
            }
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
    }

    private IExtensionPoint contentExtensionPoint(IExtensionRegistry reg) {
        return reg.getExtensionPoint("org.eclipse.core.contenttype", "contentTypes"); //$NON-NLS-1$ //$NON-NLS-2$
    }

    private IExtensionPoint dtfjExtensionPoint(IExtensionRegistry reg) {
        // Find the DTFJ extension point
        IExtensionPoint dtfjPoint = reg.getExtensionPoint(DTFJ_NAMESPACE, DTFJ_IMAGEFACTORY);
        return dtfjPoint;
    }

    /**
     * Helper method - find the contributor for this bundle.
     * 
     * @param reg
     * @return
     */
    private IContributor getContributor(IExtensionRegistry reg) {
        // Find a predefined DTFJ Adapter Plugin extension - use this to set
        // the provider for the new plugin
        IExtension es = reg.getExtension("org.eclipse.ui.startup", "org.eclipse.mat.dtfj.dtfj"); //$NON-NLS-1$ //$NON-NLS-2$

        // Second go at finding an extension for this bundle - the first
        // might fail if there is no UI.
        if (es == null) {
            es = reg.getExtension("org.eclipse.core.contenttype.contentTypes", "com.ibm.dtfj.base"); //$NON-NLS-1$ //$NON-NLS-2$
        }

        IContributor cont;
        if (es != null) {
            cont = es.getContributor();
        } else {
            cont = ContributorFactoryOSGi.createContributor(getBundle());
        }
        return cont;
    }

    /**
     * Convert a DTFJ image factory to a parser extension.
     * 
     * @param reg
     * @param cont
     * @param contentPoint
     * @param dtfjExtension
     * @throws UnsupportedEncodingException
     */
    private void contributeParserExtension(IExtensionRegistry reg, IContributor cont, IExtensionPoint contentPoint,
            IExtension dtfjExtension) throws UnsupportedEncodingException {
        for (IConfigurationElement el : dtfjExtension.getConfigurationElements()) {
            if (el.getName().equals("factory")) //$NON-NLS-1$
            {
                // List of possible file types
                Set<String> done = new HashSet<String>();

                // Later used as $heapFormat so we can tell which
                // DTFJ to use for a dump
                String id = el.getAttribute("id"); //$NON-NLS-1$
                String name = el.getAttribute("label"); //$NON-NLS-1$

                String exts = null;

                for (IConfigurationElement el2 : el.getChildren()) {
                    String ref = el2.getAttribute("dump-type"); //$NON-NLS-1$
                    if (ref != null && done.add(ref)) {
                        exts = addExtension(exts, genParser(ref, contentPoint));
                    }

                    ref = el2.getAttribute("meta-type"); //$NON-NLS-1$
                    if (ref != null && done.add(ref)) {
                        exts = addExtension(exts, genParser(ref, contentPoint));
                    }
                }

                Map<String, String> vals = new HashMap<String, String>();
                vals.put("id", id); //$NON-NLS-1$
                vals.put("name", name); //$NON-NLS-1$
                vals.put("fileExtension", exts); //$NON-NLS-1$
                String fullid = cont.getName() + "." + id; //$NON-NLS-1$
                allexts.put(fullid, vals);
            }
        }
    }

    /**
     * Extract the description and the file extensions of a content type.
     * 
     * @param ref
     * @param point2
     * @param ow
     * @return extensions
     */
    private static String genParser(String ref, IExtensionPoint point2) {

        IContentType ct = Platform.getContentTypeManager().getContentType(ref);
        if (ct == null) {
            // System.out.println("Missing content-type "+ref);
            return null;
        }

        String exts = null;
        // Generate parser references for each content subtype
        for (IContentType ct1 : Platform.getContentTypeManager().getAllContentTypes()) {
            if (ct1.isKindOf(ct)) {
                String s1 = genParser(ct1);
                exts = addExtension(exts, s1);
            }
        }
        return exts;
    }

    private static String addExtension(String exts, String ext) {
        if (exts == null)
            exts = ext;
        else if (ext != null)
            exts += "," + ext; //$NON-NLS-1$
        return exts;
    }

    private static String genParser(IContentType ct) {
        String label = ct.getName();
        String exts = null;
        if (label != null) {
            String s[] = ct.getFileSpecs(IContentType.FILE_EXTENSION_SPEC);
            if (s.length > 0) {
                // Build a comma separated extensions list
                // MAT copes with comma separated list of extensions from the
                // content-type list
                for (String s1 : s) {
                    exts = addExtension(exts, s1);
                }
            }
        }
        return exts;
    }

    /**
     * This is created and called from the MAT parser handling code
     * It provides a list of parsers
     * E.g.
     * org.eclipse.mat.dtfj.DTFJ-J9
     *      id = "DTFJ-J9"
     *      name = "IBM SDK for Java (J9) system dump"
     *      exts = "zip,dmp,xml"
     * 
     *
     */
    public static class DynamicInfo extends HashMap<String, Map<String, String>> {
        /**
         * 
         */
        private static final long serialVersionUID = -5291159195829859576L;

        {
            super.putAll(allexts);
        }
    }

    /**
     * Storage for preferences.
     * Use Object instead of IPreferenceStore to avoid a hard dependency on org.eclipse.jface
     */
    private Object preferenceStore;

    public Object getPreferenceStore() {
        // Copied from AbstractUIPlugin, so that InitDTFJ doesn't have a hard dependency
        // on org.eclipse.ui
        // Create the preference store lazily.
        if (preferenceStore == null) {
            try {
                preferenceStore = new ScopedPreferenceStore(InstanceScope.INSTANCE, getBundle().getSymbolicName());

            } catch (LinkageError e) {
                preferenceStore = new PreferenceStore();
            }
        }
        return preferenceStore;
    }

    static InitDTFJ getDefault() {
        return plugin;
    }
}