org.eclipse.ajdt.internal.ui.visualiser.AJDTContentProvider.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.ajdt.internal.ui.visualiser.AJDTContentProvider.java

Source

/*******************************************************************************
 * Copyright (c) 2005, 2006 IBM Corporation and others. 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: Sian January - initial version
 ******************************************************************************/
package org.eclipse.ajdt.internal.ui.visualiser;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import org.eclipse.ajdt.core.AJLog;
import org.eclipse.ajdt.core.BuildConfig;
import org.eclipse.ajdt.core.javaelements.AJCompilationUnit;
import org.eclipse.contribution.jdt.IsWovenTester;
import org.eclipse.contribution.visualiser.VisualiserPlugin;
import org.eclipse.contribution.visualiser.core.ProviderManager;
import org.eclipse.contribution.visualiser.interfaces.IGroup;
import org.eclipse.contribution.visualiser.interfaces.IMember;
import org.eclipse.contribution.visualiser.jdtImpl.JDTContentProvider;
import org.eclipse.contribution.visualiser.jdtImpl.JDTGroup;
import org.eclipse.contribution.visualiser.jdtImpl.JDTMember;
import org.eclipse.contribution.visualiser.simpleImpl.SimpleMember;
import org.eclipse.contribution.visualiser.utils.JDTUtils;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.ui.IWorkbenchPart;

/**
 * AJDT Content Provider for the Visualiser.
 */
public class AJDTContentProvider extends JDTContentProvider {

    List<IGroup> currentGroups;

    List<IMember> currentMembers;

    // Access this variable via its getter method, which handles initialisation
    private Set<IFile> includedFiles;

    /**
     * Get all the groups to display.
     * 
     * @see org.eclipse.contribution.visualiser.interfaces.IContentProvider#getAllGroups()
     */
    public List<IGroup> getAllGroups() {
        synchronized (this) {
            if (currentGroups == null) {
                updateData();
            }
        }
        return currentGroups;
    }

    /**
     * Get all the members to display.
     * 
     * @see org.eclipse.contribution.visualiser.interfaces.IContentProvider#getAllMembers()
     */
    public List<IMember> getAllMembers() {
        synchronized (this) {
            if (currentMembers == null) {
                updateData();
            }
        }
        return currentMembers;
    }

    /**
     * Keeps the currentJavaElement and currentProject information up to date in
     * this class, as this method is called whenever a user changes their
     * selection in the workspace.
     */
    public void selectionChanged(IWorkbenchPart workbenchPart, ISelection selection) {

        /*
         * What is the significance of this check?
         * 
         * 'If we are not the current content provider, we don't need to bother
         * updating to reflect the new selection'?
         * 
         * Yes, but what does it meant to be the current content provider? It's
         * not analagous to being the curerntly selected perspective.
         * 
         * Also, this code still gets called, even when the Visualiser
         * perspective has been closed. Guess it's still loaded.
         * 
         * -spyoung
         */

        if (!(ProviderManager.getContentProvider().equals(this))) {
            return;
        }

        boolean updateRequired = false;
        if (selection instanceof IStructuredSelection) {
            IStructuredSelection structuredSelection = (IStructuredSelection) selection;
            Object firstElement = structuredSelection.getFirstElement();

            if (firstElement != null) {
                if (firstElement instanceof IJavaElement) {
                    IJavaElement javaElement = (IJavaElement) firstElement;
                    if (currentlySelectedJE == javaElement) {
                        return;
                    }
                    currentlySelectedJE = javaElement;
                    updateRequired = true;
                    if (javaElement.getJavaProject() != null) {
                        setCurrentProject(javaElement.getJavaProject());
                    }
                }
            }
        }

        if (updateRequired) {
            reset();
            VisualiserPlugin.refresh();
        }
    }

    /**
     * Get the data for the current selection.
     * 
     * @param members -
     *            add members to the List being returned if true, otherwise add
     *            groups
     * @return data
     */
    private void updateData() {

        if (ProviderManager.getMarkupProvider() instanceof AJDTMarkupProvider) {
            ((AJDTMarkupProvider) ProviderManager.getMarkupProvider()).resetMarkupsAndKinds();
        }
        long stime = System.currentTimeMillis();
        List<IGroup> newGroups = new ArrayList<IGroup>();
        List<IMember> newMembers = new ArrayList<IMember>();
        if (currentProject != null) {

            try {
                if (currentlySelectedJE.getElementType() == IJavaElement.JAVA_PROJECT) {
                    // Process contents of a Java project
                    IPackageFragment[] packageFragments = ((IJavaProject) currentlySelectedJE)
                            .getPackageFragments();
                    for (int i = 0; i < packageFragments.length; i++) {
                        if (!(packageFragments[i].isReadOnly())) {
                            addMembersAndGroups(newGroups, newMembers, packageFragments[i]);
                        }
                    }
                } else if (currentlySelectedJE.getElementType() == IJavaElement.PACKAGE_FRAGMENT) {
                    // Process contents of a Java package(fragment)
                    IPackageFragment packageFragment = (IPackageFragment) currentlySelectedJE;
                    addMembersAndGroups(newGroups, newMembers, packageFragment);
                } else if (currentlySelectedJE.getElementType() == IJavaElement.COMPILATION_UNIT) {
                    // Process individually selected compilation units
                    JDTMember member = null;

                    if (getIncludedFiles(currentProject.getProject()).contains(currentlySelectedJE.getResource())) {
                        String memberName = currentlySelectedJE.getElementName();
                        if (memberName.endsWith(".java")) { //$NON-NLS-1$
                            memberName = memberName.substring(0, memberName.length() - 5);
                        } else if (memberName.endsWith(".aj")) { //$NON-NLS-1$
                            memberName = memberName.substring(0, memberName.length() - 3);
                        }
                        member = new JDTMember(memberName, currentlySelectedJE);
                        member.setSize(getLength((ICompilationUnit) currentlySelectedJE));
                        newMembers.add(member);
                    }
                    if (member != null) {
                        IPackageFragment packageFrag = (IPackageFragment) ((ICompilationUnit) currentlySelectedJE)
                                .getParent();
                        boolean defaultPackage = packageFrag.isDefaultPackage();
                        // ?!? Need to confirm a group for the pkg frag is OK in
                        // the case of a selection like thiss
                        IGroup group = new JDTGroup(packageFrag.getElementName());
                        if (defaultPackage) {
                            group.setName("(default package)"); //$NON-NLS-1$
                            group.setTooltip("(default package)"); //$NON-NLS-1$
                        }
                        if (defaultPackage) {
                            member.setFullName(member.getName());
                        }
                        group.add(member);
                        newGroups.add(group);
                    }
                }

            } catch (JavaModelException jme) {
            }
            long etime = System.currentTimeMillis();

            AJLog.log("AJDTContentProvider.updateData() executed - took " + (etime - stime) + "ms"); //$NON-NLS-1$ //$NON-NLS-2$
        }
        currentMembers = newMembers;
        currentGroups = newGroups;
    }

    private void addMembersAndGroups(List<IGroup> newGroups, List<IMember> newMembers,
            IPackageFragment packageFragment) {
        List<IMember> classes = getMembersForPackage(packageFragment);
        if (classes.size() > 0) {
            boolean defaultPackage = packageFragment.isDefaultPackage();
            IGroup group = new JDTGroup(packageFragment.getElementName());
            if (defaultPackage) {
                group.setName("(default package)"); //$NON-NLS-1$
                group.setTooltip("(default package)"); //$NON-NLS-1$
            }

            for (IMember jdtMember : classes) {
                group.add(jdtMember);
                newMembers.add(jdtMember);
                if (defaultPackage) {
                    ((SimpleMember) jdtMember).setFullName(jdtMember.getName());
                }
            }
            newGroups.add(group);
        }
    }

    /**
     * Override super to reset the colour list when the project changes.
     * 
     * @see org.eclipse.contribution.visualiser.jdtImpl.JDTContentProvider#setCurrentProject(org.eclipse.jdt.core.IJavaProject)
     */
    protected void setCurrentProject(IJavaProject newProject) {
        if (currentProject == null || !currentProject.equals(newProject)) {
            if (ProviderManager.getMarkupProvider() instanceof AJDTMarkupProvider) {
                ((AJDTMarkupProvider) ProviderManager.getMarkupProvider()).resetColours();
            }
            currentProject = newProject;
        }
    }

    /**
     * Clear current cached project/package/file selections.
     */
    public void reset() {
        currentGroups = null;
        currentMembers = null;

        // clear currently included files
        includedFiles = null;
    }

    /**
     * Process a mouse click on a member
     * 
     * @see org.eclipse.contribution.visualiser.interfaces.IContentProvider#processMouseclick(IMember,
     *      boolean, int)
     */
    public boolean processMouseclick(IMember member, boolean markupWasClicked, int buttonClicked) {

        if (buttonClicked != 1) {
            return true;
        }
        if (markupWasClicked) {
            return false;
        }
        if (member instanceof JDTMember) {
            IJavaElement jEl = ((JDTMember) member).getResource();
            if (jEl != null) {
                JDTUtils.openInEditor(jEl.getResource(), JDTUtils.getClassDeclLineNum(jEl));
            }
        }

        return false;
    }

    /**
     * Get all JDT members for the given IPackageFragment (Java package)
     * 
     * @param packageFragment
     * @return List of JDTMembers
     */
    public List<IMember> getMembersForPackage(IPackageFragment packageFragment) {
        List<IMember> returningClasses = new ArrayList<IMember>();
        try {
            if (containsUsefulStuff(packageFragment)) {
                IJavaElement[] javaElements = packageFragment.getChildren();
                for (int j = 0; j < javaElements.length; j++) {
                    if (javaElements[j].getElementType() == IJavaElement.COMPILATION_UNIT) {
                        if (getIncludedFiles(packageFragment.getJavaProject().getProject())
                                .contains(javaElements[j].getResource())) {

                            // Bug 157776: Filter out duplicate compilation units here, not in calling methods
                            if (!IsWovenTester.isWeavingActive() && !(javaElements[j] instanceof AJCompilationUnit)
                                    && javaElements[j].getElementName() != null
                                    && javaElements[j].getElementName().endsWith(".aj")) { //$NON-NLS-1$
                                // Do nothing
                            } else {
                                String memberName = javaElements[j].getElementName();
                                if (!shouldIgnore(memberName)) {
                                    if (memberName.endsWith(".java")) { //$NON-NLS-1$
                                        memberName = memberName.substring(0, memberName.length() - 5);
                                    } else if (memberName.endsWith(".aj")) { //$NON-NLS-1$
                                        memberName = memberName.substring(0, memberName.length() - 3);
                                    }
                                    JDTMember member = new JDTMember(memberName, javaElements[j]);
                                    member.setSize(getLength((ICompilationUnit) javaElements[j]));

                                    returningClasses.add(member);
                                }
                            }
                        }
                    }
                }
            }
        } catch (JavaModelException jme) {
        }
        return returningClasses;
    }

    /**
     * Ignore package-info files
     * @param memberName
     * @return
     */
    protected boolean shouldIgnore(String memberName) {
        return memberName.equals("package-info.java");
    }

    /*
     * Lazy initialisation method added to avoid null pointer problem(s!) which
     * were occurring due to assumed state of includedFiles variable which was
     * then compounded by the assumed state of the currentProject variable (!).
     * 
     * -spyoung
     */
    private Set<IFile> getIncludedFiles(IProject project) {

        if (includedFiles == null) {
            includedFiles = BuildConfig.getIncludedSourceFiles(project);
        }

        return includedFiles;
    }
}