org.eclipse.linuxtools.changelog.core.actions.PrepareCommitAction.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.linuxtools.changelog.core.actions.PrepareCommitAction.java

Source

/*******************************************************************************
 * Copyright (c) 2006-2009 Red Hat Inc. 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:
 *    Kyu Lee <klee@redhat.com> - initial API and implementation
 *******************************************************************************/
package org.eclipse.linuxtools.changelog.core.actions;

import java.io.IOException;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.InvocationTargetException;

import org.eclipse.compare.rangedifferencer.RangeDifference;
import org.eclipse.compare.rangedifferencer.RangeDifferencer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IStorage;
import org.eclipse.core.resources.mapping.ResourceMapping;
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.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.dialogs.ProgressMonitorDialog;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.linuxtools.changelog.core.ChangelogPlugin;
import org.eclipse.linuxtools.changelog.core.LineComparator;
import org.eclipse.linuxtools.changelog.core.Messages;
import org.eclipse.swt.dnd.Clipboard;
import org.eclipse.swt.dnd.TextTransfer;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.team.core.RepositoryProvider;
import org.eclipse.team.core.diff.IDiff;
import org.eclipse.team.core.diff.IThreeWayDiff;
import org.eclipse.team.core.history.IFileRevision;
import org.eclipse.team.core.mapping.IResourceDiff;
import org.eclipse.team.core.subscribers.Subscriber;
import org.eclipse.team.core.synchronize.SyncInfo;
import org.eclipse.team.core.synchronize.SyncInfoSet;
import org.eclipse.ui.IContributorResourceAdapter;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IFileEditorInput;
import org.eclipse.ui.ide.IContributorResourceAdapter2;

/**
 * 
 * @author klee
 *
 */
public class PrepareCommitAction extends ChangeLogAction {

    protected void doRun() {

        IRunnableWithProgress code = new IRunnableWithProgress() {

            public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
                //   monitor.beginTask("Loading Clipboard", 1000);
                loadClipboard(monitor);
                //monitor.done();
            }
        };

        ProgressMonitorDialog pd = new ProgressMonitorDialog(getWorkbench().getActiveWorkbenchWindow().getShell());

        try {
            pd.run(false /* fork */, false /* cancelable */, code);
        } catch (InvocationTargetException e) {
            ChangelogPlugin.getDefault().getLog()
                    .log(new Status(IStatus.ERROR, ChangelogPlugin.PLUGIN_ID, IStatus.ERROR, e.getMessage(), e));
            return;
        } catch (InterruptedException e) {
            ChangelogPlugin.getDefault().getLog()
                    .log(new Status(IStatus.ERROR, ChangelogPlugin.PLUGIN_ID, IStatus.ERROR, e.getMessage(), e));
            return;
        }

        //   loadClipboard();

    }

    private ResourceMapping getResourceMapping(Object o) {
        if (o instanceof ResourceMapping) {
            return (ResourceMapping) o;
        }
        if (o instanceof IAdaptable) {
            IAdaptable adaptable = (IAdaptable) o;
            Object adapted = adaptable.getAdapter(ResourceMapping.class);
            if (adapted instanceof ResourceMapping) {
                return (ResourceMapping) adapted;
            }
            adapted = adaptable.getAdapter(IContributorResourceAdapter.class);
            if (adapted instanceof IContributorResourceAdapter2) {
                IContributorResourceAdapter2 cra = (IContributorResourceAdapter2) adapted;
                return cra.getAdaptedResourceMapping(adaptable);
            }
        } else {
            Object adapted = Platform.getAdapterManager().getAdapter(o, ResourceMapping.class);
            if (adapted instanceof ResourceMapping) {
                return (ResourceMapping) adapted;
            }
        }

        return null;
    }

    private void loadClipboard(IProgressMonitor monitor) {

        IEditorPart currentEditor;

        try {
            currentEditor = getWorkbench().getActiveWorkbenchWindow().getActivePage().getActiveEditor();
        } catch (Exception e) {
            // no editor is active now so do nothing

            return;
        }

        if (currentEditor == null)
            return;

        //   System.out.println(currentEditor.getTitle());
        String diffResult = "";
        IEditorInput input = currentEditor.getEditorInput();
        ResourceMapping mapping = getResourceMapping(input);
        IProject project = null;
        IResource[] resources = new IResource[1];

        if (mapping != null) {
            project = mapping.getProjects()[0];
            resources[0] = (IResource) mapping.getModelObject();
        } else if (input instanceof IFileEditorInput) {
            IFileEditorInput f = (IFileEditorInput) input;
            project = f.getFile().getProject();
            resources[0] = f.getFile();
        } else {
            return; // can't get what we need
        }

        RepositoryProvider r = RepositoryProvider.getProvider(project);
        if (r == null) {
            return; //There is no repository provider for this project, i.e it's not shared.
        }
        SyncInfoSet set = new SyncInfoSet();
        Subscriber s = r.getSubscriber();
        s.collectOutOfSync(resources, IResource.DEPTH_ZERO, set, monitor);
        SyncInfo[] infos = set.getSyncInfos();

        if (infos.length == 1) {
            int kind = SyncInfo.getChange(infos[0].getKind());
            if (kind == SyncInfo.CHANGE) {
                try {
                    IDiff d = s.getDiff(infos[0].getLocal());
                    if (d instanceof IThreeWayDiff
                            && ((IThreeWayDiff) d).getDirection() == IThreeWayDiff.OUTGOING) {
                        IThreeWayDiff diff = (IThreeWayDiff) d;
                        monitor.beginTask(null, 100);
                        IResourceDiff localDiff = (IResourceDiff) diff.getLocalChange();
                        IFile file = (IFile) localDiff.getResource();
                        monitor.subTask(Messages.getString("ChangeLog.MergingDiffs")); // $NON-NLS-1$
                        String osEncoding = file.getCharset();
                        IFileRevision ancestorState = localDiff.getBeforeState();
                        IStorage ancestorStorage;
                        if (ancestorState != null)
                            ancestorStorage = ancestorState.getStorage(monitor);
                        else
                            ancestorStorage = null;

                        try {
                            LineComparator left = new LineComparator(ancestorStorage.getContents(), osEncoding);
                            LineComparator right = new LineComparator(file.getContents(), osEncoding);
                            for (RangeDifference tmp : RangeDifferencer.findDifferences(left, right)) {
                                if (tmp.kind() == RangeDifference.CHANGE) {
                                    LineNumberReader l = new LineNumberReader(
                                            new InputStreamReader(file.getContents()));
                                    int rightLength = tmp.rightLength() > 0 ? tmp.rightLength()
                                            : tmp.rightLength() + 1;
                                    String line0 = null;
                                    String preDiffResult = "";
                                    for (int i = 0; i < tmp.rightStart(); ++i) {
                                        // We have equivalence at the start.  This could be due to a new entry with the
                                        // same date stamp as the subsequent entry.  In this case, we want the diff to
                                        // have the date stamp at the top so it forms a complete entry.  So, we cache
                                        // those equivalent lines for later usage if needed.
                                        try {
                                            String line = l.readLine();
                                            if (line0 == null)
                                                line0 = line;
                                            preDiffResult += line + "\n";
                                        } catch (IOException e) {
                                            break;
                                        }
                                    }
                                    for (int i = 0; i < rightLength; ++i) {
                                        try {
                                            String line = l.readLine();
                                            // If the last line of the diff matches the first line of the old file and
                                            // there was equivalence at the start of the ChangeLog, then we want to put
                                            // the equivalent section at top so as to give the best chance of forming
                                            // a ChangeLog entry that can be used as a commit comment.
                                            if (i == rightLength - tmp.rightStart()) {
                                                if (tmp.rightStart() != 0 && line.equals(line0)) {
                                                    diffResult = preDiffResult += diffResult;
                                                    i = rightLength; // stop loop
                                                } else
                                                    diffResult += line + "\n";
                                            } else
                                                diffResult += line + "\n"; // $NON-NLS-1$
                                        } catch (IOException e) {
                                            // do nothing
                                        }
                                    }
                                }
                            }
                        } catch (UnsupportedEncodingException e) {
                            // do nothing for now
                        }
                        monitor.done();
                    }
                } catch (CoreException e) {
                    // do nothing
                }
            }
        }

        if (!diffResult.equals(""))
            populateClipboardBuffer(diffResult);
    }

    private void populateClipboardBuffer(String input) {

        TextTransfer plainTextTransfer = TextTransfer.getInstance();
        Clipboard clipboard = new Clipboard(getWorkbench().getDisplay());
        clipboard.setContents(new String[] { input }, new Transfer[] { plainTextTransfer });
        clipboard.dispose();
    }

}