com.nextep.designer.vcs.ui.dialogs.VersionSettingsDialog.java Source code

Java tutorial

Introduction

Here is the source code for com.nextep.designer.vcs.ui.dialogs.VersionSettingsDialog.java

Source

/*******************************************************************************
 * Copyright (c) 2011 neXtep Software and contributors.
 * All rights reserved.
 *
 * This file is part of neXtep designer.
 *
 * NeXtep designer is free software: you can redistribute it 
 * and/or modify it under the terms of the GNU General Public 
 * License as published by the Free Software Foundation, either 
 * version 3 of the License, or any later version.
 *
 * NeXtep designer is distributed in the hope that it will be 
 * useful, but WITHOUT ANY WARRANTY; without even the implied
 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
 * See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Foobar.  If not, see <http://www.gnu.org/licenses/>.
 *
 * Contributors:
 *     neXtep Softwares - initial API and implementation
 *******************************************************************************/
package com.nextep.designer.vcs.ui.dialogs;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.SubMonitor;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.viewers.DecoratingStyledCellLabelProvider;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.SashForm;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.ui.PlatformUI;
import com.nextep.datadesigner.model.ChangeEvent;
import com.nextep.datadesigner.vcs.gui.VersionInfoEditor;
import com.nextep.datadesigner.vcs.services.VersionHelper;
import com.nextep.designer.ui.model.ITitleAreaComponent;
import com.nextep.designer.ui.model.IValidatableUI;
import com.nextep.designer.ui.model.base.AbstractUIComponent;
import com.nextep.designer.vcs.VCSPlugin;
import com.nextep.designer.vcs.model.IActivity;
import com.nextep.designer.vcs.model.IVersionContainer;
import com.nextep.designer.vcs.model.IVersionInfo;
import com.nextep.designer.vcs.model.IVersionStatus;
import com.nextep.designer.vcs.model.IVersionable;
import com.nextep.designer.vcs.model.IVersioningOperationContext;
import com.nextep.designer.vcs.model.IWorkspace;
import com.nextep.designer.vcs.services.IVersioningService;
import com.nextep.designer.vcs.ui.VCSImages;
import com.nextep.designer.vcs.ui.VCSUIMessages;
import com.nextep.designer.vcs.ui.jface.VersionableNewLabelProvider;
import com.nextep.designer.vcs.ui.jface.VersionableTableContentProvider;

public class VersionSettingsDialog extends AbstractUIComponent implements ITitleAreaComponent, IValidatableUI {

    private VersionInfoEditor editor;
    private IVersioningOperationContext context;
    private Composite editorPane;
    private Combo activityCombo;
    private Collection<IVersionable<?>> versionablesToReview = new ArrayList<IVersionable<?>>();

    public VersionSettingsDialog(IVersioningOperationContext context) {
        this.context = context;
    }

    @Override
    public Control create(Composite p) {
        for (IVersionable<?> v : context.getVersionables()) {
            if (v.getContainer() instanceof IWorkspace) {
                versionablesToReview.add(v);
            }
        }
        // Main composite
        Composite parent = new Composite(p, SWT.NONE);
        parent.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
        parent.setLayout(new GridLayout(2, false));
        // Activity controls
        Label activityLabel = new Label(parent, SWT.RIGHT);
        activityLabel.setText(VCSUIMessages.getString("dialog.versionSettings.activity")); //$NON-NLS-1$
        activityLabel.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false));
        activityCombo = new Combo(parent, SWT.BORDER);
        activityCombo.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
        activityCombo.setText(getActivityText());
        List<IActivity> activities = VCSPlugin.getService(IVersioningService.class).getRecentActivities();
        for (IActivity a : activities) {
            activityCombo.add(a.getName());
        }
        // Sash form
        SashForm editor = new SashForm(parent, SWT.HORIZONTAL);
        editor.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1));

        // Listing of versionables to review
        TableViewer viewer = new TableViewer(editor, SWT.BORDER);
        viewer.setLabelProvider(new DecoratingStyledCellLabelProvider(new VersionableNewLabelProvider(),
                PlatformUI.getWorkbench().getDecoratorManager().getLabelDecorator(), null));
        viewer.setContentProvider(new VersionableTableContentProvider());
        viewer.setInput(versionablesToReview);

        // Editor pane for version selection
        editorPane = new Composite(editor, SWT.BORDER);
        editorPane.setLayout(new GridLayout());
        viewer.addSelectionChangedListener(new ISelectionChangedListener() {

            @Override
            public void selectionChanged(SelectionChangedEvent event) {
                final ISelection s = event.getSelection();
                if (s instanceof IStructuredSelection && !s.isEmpty()) {
                    Object o = ((IStructuredSelection) s).getFirstElement();
                    if (o instanceof IVersionable<?>) {
                        editVersionable((IVersionable<?>) o);
                    }
                }
            }
        });
        viewer.setSelection(new StructuredSelection(versionablesToReview.iterator().next()));
        editor.setWeights(new int[] { 2, 5 });
        return parent;
    }

    /**
     * Displays the release editor for the specified versionable by creating a new editor or
     * replacing any current editor.
     * 
     * @param v the {@link IVersionable} to edit release for
     */
    private void editVersionable(IVersionable<?> v) {
        if (v != null) {
            if (editor != null) {
                editor.getSWTConnector().dispose();
            }
            final IVersionInfo editedVersion = context.getTargetVersionInfo(v);
            editor = new VersionInfoEditor(editedVersion, false);
            editor.create(editorPane);
            editor.getSWTConnector().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
            editor.refreshConnector();
            editorPane.layout();
        }
    }

    @Override
    public String getAreaTitle() {
        return VCSUIMessages.getString("dialog.versionSettings.title"); //$NON-NLS-1$
    }

    @Override
    public String getDescription() {
        return VCSUIMessages.getString("dialog.versionSettings.description"); //$NON-NLS-1$
    }

    @Override
    public Image getImage() {
        return VCSImages.ICON_VERSION_SETTINGS;
    }

    private String getActivityText() {
        return context.getActivity() == null ? "" : context.getActivity().getName(); //$NON-NLS-1$
    }

    @Override
    public boolean validate() {
        if (context.getActivity() == null || !context.getActivity().getName().equals(activityCombo.getText())) {
            // We set a new activity when selected text differs from context activity
            context.setActivity(getVersioningService().createActivity(activityCombo.getText()));
        } else {
            getVersioningService().setCurrentActivity(context.getActivity());
        }
        dispatchEditedRelease();
        return true;
    }

    @Override
    public void cancel() {
        // Nothing to cancel
    }

    /**
     * Dispatches any current edition to the context. It is mainly meant to propagate the currently
     * edited release updates to all children.
     */
    private void dispatchEditedRelease() {

        getUIComponentContainer().run(true, false, new IRunnableWithProgress() {

            @Override
            public void run(IProgressMonitor m) throws InvocationTargetException, InterruptedException {
                SubMonitor monitor = SubMonitor.convert(m);
                monitor.beginTask(VCSUIMessages.getString("dialog.versionSettings.adjustReleaseTask"), //$NON-NLS-1$
                        100 * versionablesToReview.size());
                for (IVersionable<?> v : versionablesToReview) {
                    final IVersionInfo targetVersion = context.getTargetVersionInfo(v);
                    targetVersion.setActivity(context.getActivity());
                    monitor.subTask(VCSUIMessages.getString("dialog.versionSettings.checkoutLookupTask")); //$NON-NLS-1$
                    // Initializing checked out elements list
                    Collection<IVersionable<?>> checkedOutChildren = new ArrayList<IVersionable<?>>();
                    fillCheckedOutChildren((IVersionContainer) v, checkedOutChildren);
                    monitor.worked(30);
                    // Aligning every checked out children with the target version defined by the
                    // user
                    alignChildren(checkedOutChildren, targetVersion, monitor.newChild(40));
                    monitor.setWorkRemaining(30);
                    // Notifying
                    monitor.subTask(VCSUIMessages.getString("dialog.versionSettings.workbenchNotificationTask")); //$NON-NLS-1$
                    v.notifyListeners(ChangeEvent.MODEL_CHANGED, null);
                }
                monitor.done();
            }
        });
    }

    /**
     * Fills the specified list with checked out elements of the provided container. This method
     * will recurse into sub containers when needed.
     * 
     * @param v the container to extract checkouts of
     * @param checkedOutChildren the collection of checked out elements to fill
     */
    private void fillCheckedOutChildren(IVersionContainer v, Collection<IVersionable<?>> checkedOutChildren) {
        for (IVersionable<?> child : v.getContents()) {
            if (child.getVersion().getStatus() != IVersionStatus.CHECKED_IN) {
                checkedOutChildren.add(child);
                if (child instanceof IVersionContainer) {
                    fillCheckedOutChildren((IVersionContainer) child, checkedOutChildren);
                }
            }
        }
    }

    /**
     * Aligns the versions of the specified versionables with the provided reference version.
     * 
     * @param versionables the collection of {@link IVersionable} objects to align
     * @param referenceVersion reference {@link IVersionInfo} that will be used to align elements.
     *        Informations from this reference release will be use to adjust versionables' version
     *        information
     * @param monitor a {@link IProgressMonitor} to report progress to
     */
    private void alignChildren(Collection<IVersionable<?>> versionables, IVersionInfo referenceVersion,
            IProgressMonitor monitor) {
        monitor.beginTask(VCSUIMessages.getString("dialog.versionSettings.alignReleaseTask"), versionables.size()); //$NON-NLS-1$
        final long referenceRelease = VersionHelper.computeVersion(referenceVersion);
        for (IVersionable<?> v : versionables) {
            IVersionInfo targetRelease = context.getTargetVersionInfo(v);
            targetRelease.setRelease(referenceRelease, true);
            targetRelease.setBranch(referenceVersion.getBranch());
            targetRelease.setActivity(context.getActivity());
            v.notifyListeners(ChangeEvent.MODEL_CHANGED, null);
            monitor.worked(1);
        }
    }

    private IVersioningService getVersioningService() {
        return VCSPlugin.getService(IVersioningService.class);
    }
}