/*
* Copyright (c) 2012 Eike Stepper (Berlin, Germany) 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:
* Eike Stepper - initial API and implementation
*/
package org.eclipse.emf.cdo.transfer.ui.swt;
import org.eclipse.emf.cdo.transfer.CDOTransfer;
import org.eclipse.emf.cdo.transfer.CDOTransfer.ModelTransferContext;
import org.eclipse.emf.cdo.transfer.CDOTransfer.ModelTransferResolution;
import org.eclipse.emf.cdo.transfer.CDOTransferElement;
import org.eclipse.emf.cdo.transfer.CDOTransferMapping;
import org.eclipse.emf.cdo.transfer.CDOTransferSystem;
import org.eclipse.emf.cdo.transfer.CDOTransferType;
import org.eclipse.emf.cdo.transfer.ui.TransferDialog;
import org.eclipse.emf.cdo.transfer.ui.TransferTypeContentProvider;
import org.eclipse.net4j.util.ObjectUtil;
import org.eclipse.net4j.util.StringUtil;
import org.eclipse.net4j.util.event.IEvent;
import org.eclipse.net4j.util.event.IListener;
import org.eclipse.net4j.util.ui.StructuredContentProvider;
import org.eclipse.net4j.util.ui.UIUtil;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.jface.viewers.ComboViewer;
import org.eclipse.jface.viewers.IColorProvider;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.ListViewer;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.StructuredViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.SWTException;
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.graphics.Color;
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.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
import org.eclipse.wb.swt.SWTResourceManager;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
/**
* A {@link Composite composite} that lays out {@link Control controls} for the details of a single {@link CDOTransferMapping}.
*
* @author Eike Stepper
* @since 4.2
*/
public class TransferDetailsComposite extends Composite implements IListener
{
private static final String UP = "..";
private static final Path UP_PATH = new Path(UP);
private CDOTransfer transfer;
private CDOTransferType[] transferTypes;
private CDOTransferMapping mapping;
private boolean handlingMappingEvent;
private Text sourcePath;
private Text targetPath;
private ComboViewer transferType;
private Text status;
private Text relativePath;
private Combo resolution;
private ListViewer unmappedModels;
private Button mapSource;
private Button replaceTarget;
private Button keepAsIs;
public TransferDetailsComposite(Composite parent, int style, final CDOTransfer transfer)
{
super(parent, style);
this.transfer = transfer;
this.transfer.addListener(this);
initTransferTypes(transfer);
GridLayout gl_composite = new GridLayout(4, false);
gl_composite.marginWidth = 10;
setLayout(gl_composite);
Label sourcePathLabel = new Label(this, SWT.NONE);
sourcePathLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
sourcePathLabel.setText("Source Path:");
sourcePath = new Text(this, SWT.BORDER | SWT.READ_ONLY);
sourcePath.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
Label transferTypeLabel = new Label(this, SWT.NONE);
transferTypeLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
transferTypeLabel.setText("Type:");
transferType = new ComboViewer(this, SWT.NONE);
transferType.getCombo().setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
transferType.setContentProvider(new TransferTypeContentProvider());
transferType.setLabelProvider(new LabelProvider());
transferType.addSelectionChangedListener(new ISelectionChangedListener()
{
public void selectionChanged(SelectionChangedEvent event)
{
if (mapping != null)
{
IStructuredSelection selection = (IStructuredSelection)transferType.getSelection();
CDOTransferType type = (CDOTransferType)selection.getFirstElement();
mapping.setTransferType(type);
}
}
});
Label targetPathLabel = new Label(this, SWT.NONE);
targetPathLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
targetPathLabel.setText("Target Path:");
targetPath = new Text(this, SWT.BORDER | SWT.READ_ONLY);
targetPath.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
Label statusLabel = new Label(this, SWT.NONE);
statusLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
statusLabel.setText("Status:");
status = new Text(this, SWT.BORDER | SWT.READ_ONLY);
status.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
Label relativePathLabel = new Label(this, SWT.NONE);
relativePathLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
relativePathLabel.setText("Relative Path:");
GridData gd_pathPane = new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1);
gd_pathPane.heightHint = 27;
GridLayout pathPaneLayout = new GridLayout(4, false);
pathPaneLayout.marginWidth = 0;
pathPaneLayout.marginHeight = 0;
Composite pathPane = new Composite(this, SWT.NONE);
pathPane.setLayoutData(gd_pathPane);
pathPane.setLayout(pathPaneLayout);
relativePath = new Text(pathPane, SWT.BORDER);
relativePath.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
relativePath.addModifyListener(new ModifyListener()
{
public void modifyText(ModifyEvent e)
{
if (mapping != null && !handlingMappingEvent)
{
String text = relativePath.getText();
mapping.setRelativePath(text);
}
}
});
Button leftButton = new Button(pathPane, SWT.NONE);
leftButton.setBounds(0, 0, 75, 25);
leftButton.setText("<");
leftButton.addSelectionListener(new SelectionAdapter()
{
@Override
public void widgetSelected(SelectionEvent e)
{
IPath path = new Path(relativePath.getText());
if (path.isEmpty() || UP.equals(path.segment(0)))
{
path = UP_PATH.append(path);
}
else
{
path = path.removeFirstSegments(1);
}
mapping.setRelativePath(path);
}
});
Button rightButton = new Button(pathPane, SWT.NONE);
rightButton.setBounds(0, 0, 75, 25);
rightButton.setText(">");
rightButton.addSelectionListener(new SelectionAdapter()
{
@Override
public void widgetSelected(SelectionEvent e)
{
IPath path = new Path(relativePath.getText());
if (UP.equals(path.segment(0)))
{
path = path.removeFirstSegments(1);
}
else if (path.isEmpty())
{
path = new Path(mapping.getSource().getName());
}
else
{
path = new Path("folder").append(path);
}
mapping.setRelativePath(path);
}
});
Button renameButton = new Button(pathPane, SWT.NONE);
renameButton.setText("+");
renameButton.addSelectionListener(new SelectionAdapter()
{
@Override
public void widgetSelected(SelectionEvent e)
{
String sourceName = mapping.getSource().getName();
IPath path = new Path(relativePath.getText());
if (path.isEmpty() || UP.equals(path.segment(0)))
{
path = new Path(sourceName);
}
String name = path.lastSegment();
int i = 1;
while (transfer.getTargetSystem().getElement(path) != null) // TODO This condition is still wrong
{
path = path.removeLastSegments(1).append(name + i);
}
mapping.setRelativePath(path);
}
});
Label resolutionLabel = new Label(this, SWT.NONE);
resolutionLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
resolutionLabel.setText("Resolution:");
resolutionLabel.setVisible(false);
resolution = new Combo(this, SWT.NONE);
resolution.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
resolution.setVisible(false);
Label unmappedModelsLabel = new Label(this, SWT.NONE);
unmappedModelsLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.TOP, false, false, 1, 1));
unmappedModelsLabel.setText("Unmapped Models:");
unmappedModels = new ListViewer(this, SWT.BORDER);
org.eclipse.swt.widgets.List list = unmappedModels.getList();
list.setForeground(SWTResourceManager.getColor(SWT.COLOR_RED));
list.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
unmappedModels.setContentProvider(new UnmappedModelsContentProvider());
unmappedModels.setLabelProvider(new UnmappedModelsLabelProvider(transfer));
unmappedModels.setInput(transfer);
unmappedModels.addSelectionChangedListener(new ISelectionChangedListener()
{
public void selectionChanged(SelectionChangedEvent event)
{
IStructuredSelection selection = (IStructuredSelection)unmappedModels.getSelection();
Resource resource = (Resource)selection.getFirstElement();
updateTransformationButtons(resource);
}
});
GridLayout transformationButtonsPaneLayout = new GridLayout(1, false);
transformationButtonsPaneLayout.marginWidth = 0;
transformationButtonsPaneLayout.marginHeight = 0;
Composite transformationButtonsPane = new Composite(this, SWT.NONE);
transformationButtonsPane.setLayout(transformationButtonsPaneLayout);
transformationButtonsPane.setLayoutData(new GridData(SWT.FILL, SWT.TOP, false, false, 2, 1));
mapSource = new Button(transformationButtonsPane, SWT.NONE);
mapSource.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
mapSource.setBounds(0, 0, 75, 25);
mapSource.setText("Map From Source");
mapSource.addSelectionListener(new SelectionAdapter()
{
@Override
public void widgetSelected(SelectionEvent e)
{
IStructuredSelection selection = (IStructuredSelection)unmappedModels.getSelection();
Resource resource = (Resource)selection.getFirstElement();
URI uri = resource.getURI();
CDOTransferElement element = transfer.getSourceSystem().getElement(uri);
TransferDialog.initializeTransfer(transfer, Collections.singleton(element));
}
});
replaceTarget = new Button(transformationButtonsPane, SWT.NONE);
replaceTarget.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
replaceTarget.setBounds(0, 0, 75, 25);
replaceTarget.setText("Replace With Target");
keepAsIs = new Button(transformationButtonsPane, SWT.NONE);
keepAsIs.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
keepAsIs.setBounds(0, 0, 75, 25);
keepAsIs.setText("Keep As Is");
keepAsIs.addSelectionListener(new SelectionAdapter()
{
@Override
public void widgetSelected(SelectionEvent e)
{
IStructuredSelection selection = (IStructuredSelection)unmappedModels.getSelection();
Resource resource = (Resource)selection.getFirstElement();
URI uri = resource.getURI();
transfer.getModelTransferContext().setResolution(uri, new ModelTransferResolution()
{
// XXX
});
}
});
Button refresh = new Button(transformationButtonsPane, SWT.NONE);
refresh.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
refresh.setBounds(0, 0, 75, 25);
refresh.setText("Refresh");
refresh.addSelectionListener(new SelectionAdapter()
{
@Override
public void widgetSelected(SelectionEvent e)
{
unmappedModels.refresh();
}
});
updateTransformationButtons(null);
}
@Override
public void dispose()
{
transfer.removeListener(this);
transfer = null;
mapping = null;
super.dispose();
}
public CDOTransfer getTransfer()
{
return transfer;
}
public CDOTransferMapping getMapping()
{
return mapping;
}
public void setMapping(CDOTransferMapping mapping)
{
if (!ObjectUtil.equals(this.mapping, mapping))
{
this.mapping = mapping;
if (mapping != null)
{
sourcePath.setText(mapping.getSource().getPath().toString());
targetPath.setText(mapping.getFullPath().makeAbsolute().toString());
status.setText(mapping.getStatus().toString());
relativePath.setText(mapping.getRelativePath().toString());
CDOTransferType type = mapping.getTransferType();
transferType.setInput(type != CDOTransferType.FOLDER ? transferTypes : CDOTransferType.FOLDER);
transferType.setSelection(new StructuredSelection(type));
transferType.getCombo().setEnabled(type != CDOTransferType.FOLDER);
}
else
{
sourcePath.setText(StringUtil.EMPTY);
targetPath.setText(StringUtil.EMPTY);
status.setText(StringUtil.EMPTY);
relativePath.setText(StringUtil.EMPTY);
transferType.setInput(TransferTypeContentProvider.NO_TANSFER_TYPES);
transferType.setSelection(StructuredSelection.EMPTY);
}
}
}
public Text getSourcePath()
{
return sourcePath;
}
public Text getTargetPath()
{
return targetPath;
}
public ComboViewer getTransferType()
{
return transferType;
}
public Text getStatus()
{
return status;
}
public Text getRelativePath()
{
return relativePath;
}
public Combo getResolution()
{
return resolution;
}
public ListViewer getUnmappedModels()
{
return unmappedModels;
}
@Override
public boolean setFocus()
{
return relativePath.setFocus();
}
public void notifyEvent(final IEvent event)
{
if (isDisposed())
{
return;
}
try
{
getDisplay().asyncExec(new Runnable()
{
public void run()
{
if (!isDisposed())
{
try
{
if (event instanceof CDOTransfer.MappingEvent)
{
CDOTransfer.MappingEvent e = (CDOTransfer.MappingEvent)event;
if (ObjectUtil.equals(e.getMapping(), mapping))
{
notifyMappingEvent(e);
}
}
else if (event instanceof CDOTransfer.UnmappedModelsEvent)
{
unmappedModels.refresh();
}
}
catch (SWTException ex)
{
// Ignoredd
}
}
}
});
}
catch (SWTException ex)
{
// Ignoredd
}
}
protected void notifyMappingEvent(CDOTransfer.MappingEvent event)
{
if (event instanceof CDOTransfer.TransferTypeChangedEvent)
{
CDOTransfer.TransferTypeChangedEvent e = (CDOTransfer.TransferTypeChangedEvent)event;
final CDOTransferType newType = e.getNewType();
Object currentType = ((IStructuredSelection)transferType.getSelection()).getFirstElement();
if (currentType != newType)
{
transferType.setSelection(new StructuredSelection(newType));
}
unmappedModels.refresh();
}
else if (event instanceof CDOTransfer.RelativePathChangedEvent)
{
CDOTransfer.RelativePathChangedEvent e = (CDOTransfer.RelativePathChangedEvent)event;
final String value = e.getNewPath().toString();
if (!ObjectUtil.equals(value, relativePath.getText()))
{
try
{
handlingMappingEvent = true;
relativePath.setText(value);
status.setText(mapping.getStatus().toString());
}
finally
{
handlingMappingEvent = false;
}
}
targetPath.setText(mapping.getFullPath().makeAbsolute().toString());
}
}
protected void initTransferTypes(final CDOTransfer transfer)
{
Set<CDOTransferType> set = new HashSet<CDOTransferType>(CDOTransferType.REGISTRY.values());
set.remove(CDOTransferType.FOLDER);
transferTypes = set.toArray(new CDOTransferType[set.size()]);
Arrays.sort(transferTypes);
}
protected void updateTransformationButtons(Resource resource)
{
if (resource == null)
{
mapSource.setEnabled(false);
replaceTarget.setEnabled(false);
keepAsIs.setEnabled(false);
return;
}
URI uri = resource.getURI();
CDOTransferSystem sourceSystem = transfer.getSourceSystem();
CDOTransferElement sourceElement = sourceSystem.getElement(uri);
mapSource.setEnabled(sourceElement != null);
ModelTransferContext context = transfer.getModelTransferContext();
ModelTransferResolution resolution = context.getResolution(uri);
keepAsIs.setEnabled(resolution == null); // TODO Test type of resolution
}
/**
* A reusable {@link StructuredContentProvider content provider} for the {@link ModelTransferContext#getUnmappedModels() unmapped models} of a {@link CDOTransfer transfer}.
* <p>
* The {@link StructuredViewer#setInput(Object) input} must be an instance of {@link CDOTransfer}.
*
* @author Eike Stepper
*/
public static class UnmappedModelsContentProvider extends StructuredContentProvider<CDOTransfer>
{
public Object[] getElements(Object inputElement)
{
CDOTransfer transfer = getInput();
ModelTransferContext context = transfer.getModelTransferContext();
Set<Resource> resources = context.getUnmappedModels();
return resources.toArray(new Resource[resources.size()]);
}
}
/**
* A reusable {@link LabelProvider label provider} for the {@link ModelTransferContext#getUnmappedModels() unmapped models} of a {@link CDOTransfer transfer}.
*
* @author Eike Stepper
*/
public static class UnmappedModelsLabelProvider extends LabelProvider implements IColorProvider
{
public static final Color GRAY = UIUtil.getDisplay().getSystemColor(SWT.COLOR_GRAY);
public static final Color RED = UIUtil.getDisplay().getSystemColor(SWT.COLOR_RED);
private CDOTransfer transfer;
public UnmappedModelsLabelProvider(CDOTransfer transfer)
{
this.transfer = transfer;
}
public CDOTransfer getTransfer()
{
return transfer;
}
@Override
public String getText(Object element)
{
if (element instanceof Resource)
{
Resource resource = (Resource)element;
return resource.getURI().toString();
}
return super.getText(element);
}
public Color getForeground(Object element)
{
if (element instanceof Resource)
{
Resource resource = (Resource)element;
URI uri = resource.getURI();
ModelTransferContext context = transfer.getModelTransferContext();
ModelTransferResolution resolution = context.getResolution(uri);
if (resolution != null) // TODO Test type of resolution
{
return GRAY;
}
}
return RED;
}
public Color getBackground(Object element)
{
return null;
}
}
}