org.eclipse.pde.api.tools.ui.internal.wizards.ApiToolingSetupWizardPage.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.pde.api.tools.ui.internal.wizards.ApiToolingSetupWizardPage.java

Source

/*******************************************************************************
 * Copyright (c) 2007, 2014 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:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.pde.api.tools.ui.internal.wizards;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map.Entry;
import java.util.Set;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.SubMonitor;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.CheckStateChangedEvent;
import org.eclipse.jface.viewers.CheckboxTableViewer;
import org.eclipse.jface.viewers.ICheckStateListener;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ViewerComparator;
import org.eclipse.jface.wizard.IWizardPage;
import org.eclipse.ltk.core.refactoring.CompositeChange;
import org.eclipse.ltk.core.refactoring.TextFileChange;
import org.eclipse.ltk.core.refactoring.resource.DeleteResourceChange;
import org.eclipse.ltk.ui.refactoring.UserInputWizardPage;
import org.eclipse.pde.api.tools.internal.ApiDescriptionProcessor;
import org.eclipse.pde.api.tools.internal.IApiCoreConstants;
import org.eclipse.pde.api.tools.internal.provisional.ApiPlugin;
import org.eclipse.pde.api.tools.internal.util.Util;
import org.eclipse.pde.api.tools.ui.internal.ApiUIPlugin;
import org.eclipse.pde.api.tools.ui.internal.IApiToolsConstants;
import org.eclipse.pde.api.tools.ui.internal.IApiToolsHelpContextIds;
import org.eclipse.pde.api.tools.ui.internal.SWTFactory;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.Text;
import org.eclipse.text.edits.MultiTextEdit;
import org.eclipse.text.edits.TextEdit;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkbenchSite;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.model.WorkbenchLabelProvider;
import org.eclipse.ui.progress.UIJob;
import org.eclipse.ui.progress.WorkbenchJob;

import com.ibm.icu.text.MessageFormat;

/**
 * The main page for the {@link ApiToolingSetupWizard}
 * 
 * @since 1.0.0
 */
public class ApiToolingSetupWizardPage extends UserInputWizardPage {

    /**
     * Job for updating the filtering on the table viewer
     */
    class UpdateJob extends WorkbenchJob {

        private String pattern = null;

        /**
         * Constructor
         */
        public UpdateJob() {
            super(WizardMessages.ApiToolingSetupWizardPage_filter_update_job);
            setSystem(true);
        }

        /**
         * Sets the current text filter to use
         * 
         * @param filter
         */
        public synchronized void setFilter(String pattern) {
            this.pattern = pattern;
        }

        /**
         * @see org.eclipse.ui.progress.UIJob#runInUIThread(org.eclipse.core.runtime.IProgressMonitor)
         */
        @Override
        public IStatus runInUIThread(IProgressMonitor monitor) {
            if (tableviewer != null) {
                try {
                    tableviewer.getTable().setRedraw(false);
                    synchronized (this) {
                        filter.setPattern(pattern + '*');
                    }
                    tableviewer.refresh(true);
                    tableviewer.setCheckedElements(checkedset.toArray());
                } finally {
                    tableviewer.getTable().setRedraw(true);
                }
            }
            return Status.OK_STATUS;
        }

    }

    private static final String SETTINGS_SECTION = "ApiToolingSetupWizardPage"; //$NON-NLS-1$
    private static final String SETTINGS_REMOVECXML = "remove_componentxml"; //$NON-NLS-1$

    CheckboxTableViewer tableviewer = null;
    HashSet<Object> checkedset = new HashSet<Object>();
    Button removecxml = null;
    UpdateJob updatejob = new UpdateJob();
    StringFilter filter = new StringFilter();
    private Text checkcount = null;

    /**
     * Constructor
     * 
     * @param pageName
     */
    protected ApiToolingSetupWizardPage() {
        super(WizardMessages.UpdateJavadocTagsWizardPage_4);
        setTitle(WizardMessages.UpdateJavadocTagsWizardPage_4);
        setMessage(WizardMessages.UpdateJavadocTagsWizardPage_7);
    }

    /*
     * (non-Javadoc)
     * @see
     * org.eclipse.jface.dialogs.IDialogPage#createControl(org.eclipse.swt.widgets
     * .Composite)
     */
    @Override
    public void createControl(Composite parent) {
        Composite comp = SWTFactory.createComposite(parent, 1, 1, GridData.FILL_BOTH);
        setControl(comp);
        PlatformUI.getWorkbench().getHelpSystem().setHelp(comp,
                IApiToolsHelpContextIds.API_TOOLING_SETUP_WIZARD_PAGE);
        SWTFactory.createWrapLabel(comp, WizardMessages.UpdateJavadocTagsWizardPage_6, 1, 100);
        SWTFactory.createVerticalSpacer(comp, 1);
        SWTFactory.createWrapLabel(comp, WizardMessages.ApiToolingSetupWizardPage_6, 1, 50);

        final Text text = SWTFactory.createText(comp, SWT.BORDER, 1);
        text.addModifyListener(new ModifyListener() {
            @Override
            public void modifyText(ModifyEvent e) {
                updatejob.setFilter(text.getText().trim());
                updatejob.cancel();
                updatejob.schedule();
            }
        });
        text.addKeyListener(new KeyAdapter() {
            @Override
            public void keyPressed(KeyEvent e) {
                if (e.keyCode == SWT.ARROW_DOWN) {
                    if (tableviewer != null) {
                        tableviewer.getTable().setFocus();
                    }
                }
            }
        });

        SWTFactory.createWrapLabel(comp, WizardMessages.UpdateJavadocTagsWizardPage_8, 1, 50);

        Table table = new Table(comp, SWT.BORDER | SWT.FULL_SELECTION | SWT.CHECK | SWT.MULTI);
        GridData gd = new GridData(GridData.FILL_BOTH);
        gd.heightHint = 150;
        table.setLayoutData(gd);
        tableviewer = new CheckboxTableViewer(table);
        tableviewer.setLabelProvider(new WorkbenchLabelProvider());
        tableviewer.setContentProvider(new ArrayContentProvider());
        tableviewer.setInput(getInputProjects());
        tableviewer.setComparator(new ViewerComparator());
        tableviewer.addFilter(filter);
        tableviewer.addCheckStateListener(new ICheckStateListener() {
            @Override
            public void checkStateChanged(CheckStateChangedEvent event) {
                if (event.getChecked()) {
                    checkedset.add(event.getElement());
                } else {
                    checkedset.remove(event.getElement());
                }
                setPageComplete(pageValid());
            }
        });
        Composite bcomp = SWTFactory.createComposite(comp, 3, 1, GridData.FILL_HORIZONTAL | GridData.END, 0, 0);
        Button button = SWTFactory.createPushButton(bcomp, WizardMessages.UpdateJavadocTagsWizardPage_10, null);
        button.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                tableviewer.setAllChecked(true);
                checkedset.addAll(Arrays.asList(tableviewer.getCheckedElements()));
                setPageComplete(pageValid());
            }
        });
        button = SWTFactory.createPushButton(bcomp, WizardMessages.UpdateJavadocTagsWizardPage_11, null);
        button.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                tableviewer.setAllChecked(false);
                TableItem[] items = tableviewer.getTable().getItems();
                for (int i = 0; i < items.length; i++) {
                    checkedset.remove(items[i].getData());
                }
                setPageComplete(pageValid());
            }
        });

        checkcount = SWTFactory.createText(bcomp, SWT.FLAT | SWT.READ_ONLY, 1,
                GridData.HORIZONTAL_ALIGN_END | GridData.GRAB_HORIZONTAL);
        checkcount.setBackground(bcomp.getBackground());

        Object[] selected = getWorkbenchSelection();
        if (selected.length > 0) {
            tableviewer.setCheckedElements(selected);
            checkedset.addAll(Arrays.asList(selected));
        }
        setPageComplete(checkedset.size() > 0);

        SWTFactory.createVerticalSpacer(comp, 1);
        removecxml = SWTFactory.createCheckButton(comp, WizardMessages.ApiToolingSetupWizardPage_0, null, true, 1);

        IDialogSettings settings = ApiUIPlugin.getDefault().getDialogSettings().getSection(SETTINGS_SECTION);
        if (settings != null) {
            removecxml.setSelection(settings.getBoolean(SETTINGS_REMOVECXML));
        }
    }

    /**
     * @see org.eclipse.jface.wizard.WizardPage#setPageComplete(boolean)
     */
    @Override
    public void setPageComplete(boolean complete) {
        super.setPageComplete(complete);
        updateCheckStatus(checkedset.size());
    }

    /**
     * Updates the number of items that have been checked
     * 
     * @param count
     */
    private void updateCheckStatus(int count) {
        if (checkcount == null) {
            return;
        }
        checkcount.setText(MessageFormat.format(WizardMessages.ApiToolingSetupWizardPage_n_items_checked,
                new Object[] { Integer.toString(count) }));
    }

    /**
     * @return the complete listing of projects in the workspace that could have
     *         API Tools set-up on them
     * @throws CoreException
     */
    private IProject[] getInputProjects() {
        IProject[] projects = ResourcesPlugin.getWorkspace().getRoot().getProjects();
        ArrayList<IProject> pjs = new ArrayList<IProject>();
        for (int i = 0; i < projects.length; i++) {
            try {
                IProject project = projects[i];
                if (acceptProject(project)) {
                    pjs.add(project);
                }
            } catch (@SuppressWarnings("unused") CoreException ce) {
            }
        }
        return pjs.toArray(new IProject[pjs.size()]);
    }

    private boolean acceptProject(IProject project) throws CoreException {
        if (project == null) {
            return false;
        }
        return (project.hasNature(JavaCore.NATURE_ID) && project.hasNature("org.eclipse.pde.PluginNature")) //$NON-NLS-1$
                && !project.hasNature(ApiPlugin.NATURE_ID) && !Util.isBinaryProject(project);
    }

    /**
     * @return the current selection from the workbench as an array of objects
     */
    protected Object[] getWorkbenchSelection() {
        IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
        if (window != null) {
            IWorkbenchPage page = window.getActivePage();
            if (page != null) {
                IWorkbenchPart part = page.getActivePart();
                if (part != null) {
                    IWorkbenchSite site = part.getSite();
                    if (site != null) {
                        ISelectionProvider provider = site.getSelectionProvider();
                        if (provider != null) {
                            ISelection selection = provider.getSelection();
                            if (selection instanceof IStructuredSelection) {
                                Object[] jps = ((IStructuredSelection) provider.getSelection()).toArray();
                                ArrayList<IProject> pjs = new ArrayList<IProject>();
                                for (int i = 0; i < jps.length; i++) {
                                    if (jps[i] instanceof IAdaptable) {
                                        IAdaptable adapt = (IAdaptable) jps[i];
                                        IProject pj = (IProject) adapt.getAdapter(IProject.class);
                                        try {
                                            if (acceptProject(pj)) {
                                                pjs.add(pj);
                                            }
                                        } catch (@SuppressWarnings("unused") CoreException ce) {
                                        }
                                    }
                                }
                                return pjs.toArray();
                            }
                        }
                    }
                }
            }
        }
        return new Object[0];
    }

    /**
     * @return if the page is valid or not, this method also sets error messages
     */
    protected boolean pageValid() {
        if (checkedset.size() < 1) {
            setErrorMessage(WizardMessages.UpdateJavadocTagsWizardPage_12);
            return false;
        }
        setErrorMessage(null);
        return true;
    }

    /*
     * (non-Javadoc)
     * @see org.eclipse.ltk.ui.refactoring.UserInputWizardPage#getNextPage()
     */
    @Override
    public IWizardPage getNextPage() {
        // always have to collect changes again in the event the user goes back
        // and forth,
        // as a change cannot ever have more than one parent - EVER
        collectChanges();
        IWizardPage page = super.getNextPage();
        if (page != null) {
            page.setDescription(WizardMessages.ApiToolingSetupWizardPage_5);
        }
        return page;
    }

    /**
     * Creates all of the text edit changes collected from the processor. The
     * collected edits are arranged as multi-edits for the one file that they
     * belong to
     * 
     * @param projectchange
     * @param project
     * @param cxml
     */
    void createTagChanges(CompositeChange projectchange, IJavaProject project, File cxml) {
        try {
            HashMap<IFile, Set<TextEdit>> map = new HashMap<IFile, Set<TextEdit>>();
            ApiDescriptionProcessor.collectTagUpdates(project, cxml, map);
            IFile file = null;
            TextFileChange change = null;
            MultiTextEdit multiedit = null;
            Set<TextEdit> alledits = null;
            for (Entry<IFile, Set<TextEdit>> entry : map.entrySet()) {
                file = entry.getKey();
                change = new TextFileChange(MessageFormat.format(WizardMessages.JavadocTagRefactoring_2,
                        new Object[] { file.getName() }), file);
                multiedit = new MultiTextEdit();
                change.setEdit(multiedit);
                alledits = entry.getValue();
                if (alledits != null) {
                    for (TextEdit edit : alledits) {
                        multiedit.addChild(edit);
                    }
                }
                projectchange.add(change);
            }
        } catch (CoreException e) {
            ApiUIPlugin.log(e);
        } catch (IOException e) {
            ApiUIPlugin.log(e);
        }
    }

    /**
     * @return the mapping of text edits to the IFile they occur on
     */
    private void collectChanges() {
        final ApiToolingSetupRefactoring refactoring = (ApiToolingSetupRefactoring) getRefactoring();
        IRunnableWithProgress op = new IRunnableWithProgress() {
            @Override
            public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
                Object[] projects = checkedset.toArray(new IProject[checkedset.size()]);
                IProject project = null;
                SubMonitor localmonitor = SubMonitor.convert(monitor);
                localmonitor.beginTask(IApiToolsConstants.EMPTY_STRING, projects.length);
                localmonitor.setTaskName(WizardMessages.ApiToolingSetupWizardPage_7);
                refactoring.resetRefactoring();
                boolean remove = removecxml.getSelection();
                CompositeChange pchange = null;
                for (int i = 0; i < projects.length; i++) {
                    project = (IProject) projects[i];
                    pchange = new CompositeChange(project.getName());
                    refactoring.addChange(pchange);
                    pchange.add(new ProjectUpdateChange(project));
                    localmonitor.subTask(MessageFormat.format(WizardMessages.ApiToolingSetupWizardPage_4,
                            new Object[] { project.getName() }));
                    IResource cxml = project.findMember(IApiCoreConstants.COMPONENT_XML_NAME);
                    if (cxml != null) {
                        // collect the changes for doc
                        createTagChanges(pchange, JavaCore.create(project), new File(cxml.getLocationURI()));
                        if (remove) {
                            pchange.add(new DeleteResourceChange(cxml.getFullPath(), true));
                        }
                    }
                    Util.updateMonitor(localmonitor, 1);
                }
            }
        };
        try {
            getContainer().run(false, false, op);
        } catch (InvocationTargetException e) {
            ApiUIPlugin.log(e);
        } catch (InterruptedException e) {
            ApiUIPlugin.log(e);
        }
    }

    /*
     * (non-Javadoc)
     * @see org.eclipse.ltk.ui.refactoring.UserInputWizardPage#performFinish()
     */
    @Override
    protected boolean performFinish() {
        collectChanges();
        return super.performFinish();
    }

    /**
     * Called by the {@link ApiToolingSetupWizard} when finishing the wizard
     * 
     * @return true if the page finished normally, false otherwise
     */
    public boolean finish() {
        IDialogSettings settings = ApiUIPlugin.getDefault().getDialogSettings().addNewSection(SETTINGS_SECTION);
        settings.put(SETTINGS_REMOVECXML, removecxml.getSelection());
        notifyNoDefaultProfile();
        return true;
    }

    /**
     * Notifies the user that they have no default API profile
     */
    private void notifyNoDefaultProfile() {
        if (ApiPlugin.getDefault().getApiBaselineManager().getDefaultApiBaseline() == null) {
            UIJob job = new UIJob("No default API profile detected") { //$NON-NLS-1$
                @Override
                public IStatus runInUIThread(IProgressMonitor monitor) {
                    boolean doit = MessageDialog.openQuestion(getShell(),
                            WizardMessages.ApiToolingSetupWizardPage_1, WizardMessages.ApiToolingSetupWizardPage_2
                                    + WizardMessages.ApiToolingSetupWizardPage_3);
                    if (doit) {
                        SWTFactory.showPreferencePage(getShell(), IApiToolsConstants.ID_BASELINES_PREF_PAGE, null);
                    }
                    return Status.OK_STATUS;
                }
            };
            job.setSystem(true);
            job.schedule();
        }
    }
}