com.collabnet.subversion.merge.wizards.MergeWizardStandardPage.java Source code

Java tutorial

Introduction

Here is the source code for com.collabnet.subversion.merge.wizards.MergeWizardStandardPage.java

Source

/*******************************************************************************
 * Copyright (c) 2009 CollabNet.
 * 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:
 *     CollabNet - initial API and implementation
 ******************************************************************************/
package com.collabnet.subversion.merge.wizards;

import java.lang.reflect.InvocationTargetException;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.List;

import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.viewers.ColumnLayoutData;
import org.eclipse.jface.viewers.ColumnWeightData;
import org.eclipse.jface.viewers.DecoratingLabelProvider;
import org.eclipse.jface.viewers.ILabelDecorator;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.TableLayout;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.swt.SWT;
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.events.SelectionListener;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.model.WorkbenchLabelProvider;
import org.tigris.subversion.subclipse.core.ISVNLocalResource;
import org.tigris.subversion.subclipse.core.resources.SVNWorkspaceRoot;
import org.tigris.subversion.subclipse.ui.dialogs.ChooseUrlDialog;
import org.tigris.subversion.svnclientadapter.ISVNClientAdapter;
import org.tigris.subversion.svnclientadapter.ISVNMergeInfo;
import org.tigris.subversion.svnclientadapter.SVNRevision;
import org.tigris.subversion.svnclientadapter.SVNUrl;

import com.collabnet.subversion.merge.Activator;
import com.collabnet.subversion.merge.Messages;

public class MergeWizardStandardPage extends WizardPage {
    private Combo fromCombo;
    private Button allButton;
    private Button selectButton;
    private Composite multipleGroup;
    private Button rootButton;
    private Button separateButton;

    private IResource resource;
    private IResource[] resources;
    private ISVNLocalResource svnResource;
    private String fromUrl;
    private String repositoryLocation;
    private ISVNMergeInfo mergeInfo;

    private String[] mergeInfoPaths;

    private String[] urlStrings;
    private String commonRoot;
    private MergeResource[] mergeResources;

    private Button relativeButton;
    private IDialogSettings settings;

    private Table table;
    private TableViewer viewer;

    private String message;
    private boolean showRevisionsButtons;
    private boolean unblock;

    private String[] columnHeaders = { Messages.MergeWizardStandardPage_resource };
    private ColumnLayoutData columnLayouts[] = { new ColumnWeightData(100, 100, true) };

    public MergeWizardStandardPage(String pageName, String title, ImageDescriptor titleImage, String message,
            boolean showRevisionsButtons, boolean unblock) {
        super(pageName, title, titleImage);
        this.message = message;
        this.showRevisionsButtons = showRevisionsButtons;
        settings = Activator.getDefault().getDialogSettings();
        this.unblock = unblock;
    }

    public MergeWizardStandardPage(String pageName, String title, ImageDescriptor titleImage) {
        this(pageName, title, titleImage, null, true, false);
    }

    public void createControl(Composite parent) {
        Composite outerContainer = new Composite(parent, SWT.NONE);
        GridLayout layout = new GridLayout();
        layout.numColumns = 3;
        outerContainer.setLayout(layout);
        outerContainer.setLayoutData(new GridData(GridData.FILL_BOTH));

        Label fromLabel = new Label(outerContainer, SWT.NONE);
        fromLabel.setText(Messages.MergeWizardStandardPage_from);
        if (unblock)
            fromCombo = new Combo(outerContainer, SWT.BORDER | SWT.READ_ONLY);
        else
            fromCombo = new Combo(outerContainer, SWT.BORDER);
        GridData data = new GridData(GridData.FILL_HORIZONTAL | GridData.GRAB_HORIZONTAL);
        fromCombo.setLayoutData(data);

        fromCombo.addModifyListener(new ModifyListener() {
            public void modifyText(ModifyEvent e) {
                if (fromCombo.getText().startsWith("/")) //$NON-NLS-1$
                    fromUrl = repositoryLocation + fromCombo.getText().trim();
                else
                    fromUrl = fromCombo.getText().trim();
                if (viewer != null)
                    viewer.refresh();
                setPageComplete(canFinish());
            }
        });
        Button selectFromButton = new Button(outerContainer, SWT.PUSH);
        selectFromButton.setText(Messages.MergeWizardStandardPage_select);
        selectFromButton.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent e) {
                ChooseUrlDialog dialog = new ChooseUrlDialog(getShell(), resource);
                dialog.setIncludeBranchesAndTags(resources.length == 1);
                if ((dialog.open() == ChooseUrlDialog.OK) && (dialog.getUrl() != null)) {
                    fromUrl = dialog.getUrl();
                    fromCombo.setText(fromUrl.substring(repositoryLocation.length()));
                }
            }
        });
        if (unblock)
            selectFromButton.setVisible(false);

        MergeWizard wizard = (MergeWizard) getWizard();
        resources = wizard.getResources();
        if (resources != null) {
            commonRoot = getCommonRoot();
            if (resources.length > 1) {
                relativeButton = new Button(outerContainer, SWT.CHECK);
                relativeButton.setText(Messages.MergeWizardStandardPage_relativeTo);
                data = new GridData();
                data.horizontalSpan = 3;
                relativeButton.setLayoutData(data);
                relativeButton.setSelection(true);
                relativeButton.addSelectionListener(new SelectionAdapter() {
                    public void widgetSelected(SelectionEvent e) {
                        settings.put(MergeWizard.LAST_RELATIVE_PATH_CHOICE, relativeButton.getSelection());
                        viewer.refresh();
                    }
                });

                Label label = new Label(outerContainer, SWT.NONE);
                label.setText(Messages.MergeWizardStandardPage_resources);
                data = new GridData();
                data.horizontalSpan = 3;
                label.setLayoutData(data);

                table = new Table(outerContainer, SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER);
                table.setLinesVisible(false);
                table.setHeaderVisible(false);
                data = new GridData(GridData.FILL_HORIZONTAL);
                data.heightHint = 85;
                data.horizontalSpan = 3;
                table.setLayoutData(data);
                TableLayout tableLayout = new TableLayout();
                table.setLayout(tableLayout);
                viewer = new TableViewer(table);
                viewer.setContentProvider(new MergeContentProvider());
                ILabelDecorator decorator = PlatformUI.getWorkbench().getDecoratorManager().getLabelDecorator();
                viewer.setLabelProvider(new TableDecoratingLabelProvider(new MergeLabelProvider(), decorator));
                for (int i = 0; i < columnHeaders.length; i++) {
                    tableLayout.addColumnData(columnLayouts[i]);
                    TableColumn tc = new TableColumn(table, SWT.NONE, i);
                    tc.setResizable(columnLayouts[i].resizable);
                    tc.setText(columnHeaders[i]);
                }
                viewer.setInput(this);
            }
        }

        Group revisionsGroup = new Group(outerContainer, SWT.NONE);
        revisionsGroup.setText(Messages.MergeWizardStandardPage_revisions);
        GridLayout revisionsLayout = new GridLayout();
        revisionsLayout.numColumns = 1;
        revisionsGroup.setLayout(revisionsLayout);
        data = new GridData(GridData.GRAB_HORIZONTAL | GridData.HORIZONTAL_ALIGN_FILL);
        data.horizontalSpan = 3;
        revisionsGroup.setLayoutData(data);

        allButton = new Button(revisionsGroup, SWT.RADIO);
        allButton.setText(Messages.MergeWizardStandardPage_allEligible);
        selectButton = new Button(revisionsGroup, SWT.RADIO);
        selectButton.setText(Messages.MergeWizardStandardPage_selectRevisions);

        boolean selectRevisions = false;
        try {
            selectRevisions = settings.getBoolean("MergeWizardStandardPage.selectRevisions"); //$NON-NLS-1$
        } catch (Exception e) {
        }
        if (selectRevisions)
            selectButton.setSelection(true);
        else
            allButton.setSelection(true);

        SelectionListener selectionListener = new SelectionAdapter() {
            public void widgetSelected(SelectionEvent e) {
                settings.put("MergeWizardStandardPage.selectRevisions", selectButton.getSelection()); //$NON-NLS-1$
                setPageComplete(canFinish());
                if (multipleGroup != null) {
                    multipleGroup.setEnabled(selectButton.getSelection());
                    rootButton.setEnabled(selectButton.getSelection());
                    separateButton.setEnabled(selectButton.getSelection());
                }
            }
        };

        allButton.addSelectionListener(selectionListener);
        selectButton.addSelectionListener(selectionListener);

        if (resources.length > 1) {
            multipleGroup = new Composite(revisionsGroup, SWT.NONE);
            GridLayout multipleLayout = new GridLayout();
            multipleLayout.numColumns = 1;
            multipleLayout.marginLeft = 20;
            multipleGroup.setLayout(multipleLayout);
            data = new GridData(GridData.GRAB_HORIZONTAL | GridData.HORIZONTAL_ALIGN_FILL);
            multipleGroup.setLayoutData(data);
            rootButton = new Button(multipleGroup, SWT.RADIO);
            rootButton.setText(Messages.MergeWizardStandardPage_0);
            separateButton = new Button(multipleGroup, SWT.RADIO);
            separateButton.setText(Messages.MergeWizardStandardPage_1);
            multipleGroup.setEnabled(selectButton.getSelection());
            rootButton.setEnabled(selectButton.getSelection());
            separateButton.setEnabled(selectButton.getSelection());
            boolean retrieveEligibleRevisionsSeparately = false;
            try {
                retrieveEligibleRevisionsSeparately = settings
                        .getBoolean(MergeWizard.LAST_RETRIEVE_ELIGIBLE_REVISIONS_SEPARATELY);
            } catch (Exception e) {
                settings.put(MergeWizard.LAST_RETRIEVE_ELIGIBLE_REVISIONS_SEPARATELY, false);
            }
            if (retrieveEligibleRevisionsSeparately)
                separateButton.setSelection(true);
            else
                rootButton.setSelection(true);
            SelectionListener multipleListener = new SelectionAdapter() {
                public void widgetSelected(SelectionEvent se) {
                    settings.put(MergeWizard.LAST_RETRIEVE_ELIGIBLE_REVISIONS_SEPARATELY,
                            separateButton.getSelection());
                    ((MergeWizard) getWizard()).setRetrieveRevisionsMethodChanged(true);
                }
            };
            rootButton.addSelectionListener(multipleListener);
            separateButton.addSelectionListener(multipleListener);
        }

        if (!showRevisionsButtons)
            revisionsGroup.setVisible(false);

        setPageComplete(canFinish());

        if (message == null)
            setMessage(Messages.MergeWizardStandardPage_specifyLocation);
        else
            setMessage(message);

        setControl(outerContainer);
    }

    public String getMergeFrom() {
        return fromCombo.getText().trim();
    }

    public boolean selectRevisions() {
        return selectButton.getSelection();
    }

    private boolean canFinish() {
        setErrorMessage(null);
        if (fromCombo.getText().trim().length() == 0)
            return false;
        if (!validateUrl()) {
            setErrorMessage(Messages.MergeWizardStandardPage_invalidUrl);
            return false;
        }
        return true;
    }

    private boolean validateUrl() {
        if (!fromCombo.getText().startsWith("/")) { //$NON-NLS-1$
            try {
                new SVNUrl(fromCombo.getText().trim());
            } catch (MalformedURLException e) {
                return false;
            }
        }
        return true;
    }

    public String getFromUrl() {
        return fromUrl;
    }

    public void setVisible(boolean visible) {
        if (visible && fromUrl == null) {
            initializeLocations();
        }
        super.setVisible(visible);
    }

    private void initializeLocations() {
        MergeWizard wizard = (MergeWizard) getWizard();
        resource = wizard.getResource();
        resources = wizard.getResources();
        svnResource = SVNWorkspaceRoot.getSVNResourceFor(resource);
        mergeInfoPaths = null;
        try {
            fromUrl = svnResource.getStatus().getUrlString();
        } catch (Exception e) {
            Activator.handleError(e);
        }
        repositoryLocation = svnResource.getRepository().getLocation();
        if (((MergeWizard) getWizard()).suggestMergeSources()) {
            IRunnableWithProgress runnable = new IRunnableWithProgress() {
                public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
                    monitor.setTaskName(Messages.MergeWizardStandardPage_retrievingMergeSourceInfo);
                    monitor.beginTask(Messages.MergeWizardStandardPage_retrievingMergeSourceInfo,
                            IProgressMonitor.UNKNOWN);
                    monitor.subTask(""); //$NON-NLS-1$
                    ISVNClientAdapter svnClient = null;
                    try {
                        svnClient = svnResource.getRepository().getSVNClient();
                        try {
                            if (unblock) {
                                try {
                                    mergeInfo = svnClient.getMergeInfo(new SVNUrl(commonRoot), SVNRevision.HEAD);
                                } catch (Exception e) {
                                }
                                if (mergeInfo != null)
                                    mergeInfoPaths = mergeInfo.getPaths();
                                if (mergeInfoPaths == null || mergeInfoPaths.length == 0) {
                                    Display.getDefault().asyncExec(new Runnable() {
                                        public void run() {
                                            setErrorMessage(Messages.MergeWizardStandardPage_noRevisionsToUnblock);
                                        }
                                    });
                                }
                            } else {
                                mergeInfoPaths = svnClient.suggestMergeSources(new SVNUrl(commonRoot),
                                        SVNRevision.HEAD);
                            }
                        } catch (Exception e1) {
                        }
                    } catch (Exception e) {
                        Activator.handleError(e);
                    } finally {
                        svnResource.getRepository().returnSVNClient(svnClient);
                    }
                    monitor.done();
                }
            };
            try {
                getContainer().run(true, false, runnable);
            } catch (Exception e2) {
                Activator.handleError(e2);
            }
        }
        boolean valueAdded = false;
        List<String> fromUrls = new ArrayList<String>();
        if (mergeInfoPaths != null) {
            for (int i = 0; i < mergeInfoPaths.length; i++) {
                String url = mergeInfoPaths[i].substring(repositoryLocation.length());
                if (!fromUrls.contains(url))
                    fromUrls.add(url);
                valueAdded = true;
            }
        }
        String previousFromUrls = null;
        String previousFromUrl = null;
        try {
            previousFromUrls = Activator.getDefault().getDialogSettings().get("mergeFromUrls_" + commonRoot);
        } catch (Exception e) {
        }
        if (previousFromUrls != null) {
            String[] urls = previousFromUrls.split("\\,");
            for (String url : urls) {
                if (!fromUrls.contains(url))
                    fromUrls.add(url);
                valueAdded = true;
            }
            if (urls.length > 0)
                previousFromUrl = urls[0];
        }

        if (!valueAdded && !unblock && commonRoot != null) {
            fromUrls.add(commonRoot.substring(repositoryLocation.length()));
        }

        for (String url : fromUrls) {
            fromCombo.add(url);
        }

        if (previousFromUrl != null)
            fromCombo.setText(previousFromUrl);
        else if (fromCombo.getItemCount() > 0)
            fromCombo.setText(fromCombo.getItem(0));
    }

    public IResource getResource() {
        return resource;
    }

    public IResource[] getResources() {
        return resources;
    }

    public SVNUrl getUrl() {
        SVNUrl url = null;
        try {
            url = new SVNUrl(fromUrl);
        } catch (MalformedURLException e) {
            Activator.handleError(e);
        }
        return url;
    }

    public SVNUrl[] getUrls() {
        if (resources.length == 1) {
            SVNUrl[] urls = { getUrl() };
            return urls;
        }
        final boolean[] useRelativePath = new boolean[1];
        Display.getDefault().syncExec(new Runnable() {

            public void run() {
                useRelativePath[0] = relativeButton != null && relativeButton.getSelection();
            }
        });
        SVNUrl[] urls = new SVNUrl[mergeResources.length];
        for (int i = 0; i < mergeResources.length; i++) {
            try {
                if (!useRelativePath[0]) {
                    urls[i] = new SVNUrl(fromUrl);
                } else {
                    if (fromUrl.endsWith("/")) //$NON-NLS-1$
                        urls[i] = new SVNUrl(fromUrl + mergeResources[i].getPartialPath());
                    else
                        urls[i] = new SVNUrl(fromUrl + "/" + mergeResources[i].getPartialPath()); //$NON-NLS-1$
                }
            } catch (MalformedURLException e) {
                Activator.handleError(e);
            }
        }
        return urls;
    }

    private String getCommonRoot() {
        commonRoot = ((MergeWizard) getWizard()).getCommonRoot();
        urlStrings = ((MergeWizard) getWizard()).getUrlStrings();
        mergeResources = new MergeResource[resources.length];
        for (int i = 0; i < resources.length; i++) {
            if (urlStrings[i].length() <= commonRoot.length())
                mergeResources[i] = new MergeResource(resources[i], commonRoot);
            else
                mergeResources[i] = new MergeResource(resources[i],
                        urlStrings[i].substring(commonRoot.length() + 1));
        }

        return commonRoot;
    }

    public String getCommonRoot(boolean calculateRoot) {
        if (calculateRoot)
            return getCommonRoot();
        else
            return commonRoot;
    }

    public ISVNMergeInfo getMergeInfo() {
        return mergeInfo;
    }

    private class MergeResource implements IAdaptable {
        private IResource resource;
        private String partialPath;

        public MergeResource(IResource resource, String partialPath) {
            this.resource = resource;
            this.partialPath = partialPath;
        }

        public IResource getResource() {
            return resource;
        }

        public void setResource(IResource resource) {
            this.resource = resource;
        }

        public String getPartialPath() {
            return partialPath;
        }

        public void setPartialPath(String partialPath) {
            this.partialPath = partialPath;
        }

        @SuppressWarnings("unchecked")
        public Object getAdapter(Class adapter) {
            if (IResource.class == adapter)
                return resource;
            return null;
        }
    }

    class MergeLabelProvider extends LabelProvider implements ITableLabelProvider {
        WorkbenchLabelProvider workbenchLabelProvider = new WorkbenchLabelProvider();

        public String getColumnText(Object element, int columnIndex) {
            return getText(element);
        }

        public String getText(Object element) {
            MergeResource mergeResource = (MergeResource) element;
            if (relativeButton.getSelection())
                return mergeResource.getPartialPath() + " [" + fromCombo.getText() + "/" //$NON-NLS-1$//$NON-NLS-2$
                        + mergeResource.getPartialPath() + "]"; //$NON-NLS-1$
            else
                return mergeResource.getPartialPath() + " [" + fromCombo.getText() + "]"; //$NON-NLS-1$ //$NON-NLS-2$
        }

        public Image getColumnImage(Object element, int columnIndex) {
            return getImage(element);
        }

        public Image getImage(Object element) {
            MergeResource mergeResource = (MergeResource) element;
            return workbenchLabelProvider.getImage(mergeResource.getResource());
        }

    }

    class MergeContentProvider implements IStructuredContentProvider {
        public void dispose() {
        }

        public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
        }

        public Object[] getElements(Object obj) {
            return mergeResources;
        }
    }

    class TableDecoratingLabelProvider extends DecoratingLabelProvider implements ITableLabelProvider {

        ITableLabelProvider provider;
        ILabelDecorator decorator;

        public TableDecoratingLabelProvider(ILabelProvider provider, ILabelDecorator decorator) {
            super(provider, decorator);
            this.provider = (ITableLabelProvider) provider;
            this.decorator = decorator;
        }

        public Image getColumnImage(Object element, int columnIndex) {
            Image image = provider.getColumnImage(element, columnIndex);
            if (decorator != null) {
                Image decorated = decorator.decorateImage(image, element);
                if (decorated != null) {
                    return decorated;
                }
            }
            return image;
        }

        public String getColumnText(Object element, int columnIndex) {
            String text = provider.getColumnText(element, columnIndex);
            return text;
        }
    }

}