blob: 81fa806bfd3551f7c7c0bc39c0dfc7dd88fa33ef [file] [log] [blame]
/*
* Copyright (c) 2012, 2015 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;
import org.eclipse.net4j.util.ObjectUtil;
import org.eclipse.net4j.util.om.monitor.SubProgressMonitor;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Path;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* @author Eike Stepper
* @since 4.2
*/
class CDOTransferMappingImpl implements CDOTransferMapping
{
private final CDOTransfer transfer;
private final CDOTransferElement source;
private final CDOTransferMappingImpl parent;
private List<CDOTransferMapping> children;
private CDOTransferType transferType;
private IPath relativePath;
private Status status;
public CDOTransferMappingImpl(CDOTransfer transfer, CDOTransferElement source, CDOTransferMapping parent,
IProgressMonitor monitor)
{
this.transfer = transfer;
this.source = source;
this.parent = (CDOTransferMappingImpl)parent;
relativePath = new Path(source.getName());
CDOTransferType transferType = transfer.getTransferType(source);
this.transferType = transferType;
if (parent != null)
{
this.parent.addChild(this);
}
try
{
if (isDirectory())
{
CDOTransferElement[] children = source.getChildren();
monitor.beginTask("", 1 + children.length);
monitor.subTask("Mapping " + source);
monitor.worked(1);
for (CDOTransferElement child : children)
{
transfer.map(child, this, new SubProgressMonitor(monitor, 1));
}
}
else
{
monitor.beginTask("", 1);
monitor.subTask("Mapping " + source);
monitor.worked(1);
}
}
finally
{
monitor.done();
}
}
public CDOTransferMappingImpl(CDOTransfer transfer)
{
this.transfer = transfer;
source = null;
parent = null;
transferType = CDOTransferType.FOLDER;
relativePath = Path.EMPTY;
}
public CDOTransfer getTransfer()
{
return transfer;
}
public CDOTransferElement getSource()
{
return source;
}
public CDOTransferMapping getParent()
{
return parent;
}
public boolean isRoot()
{
return parent == null;
}
public boolean isDirectory()
{
if (source == null)
{
return true;
}
return source.isDirectory();
}
public String getName()
{
return relativePath.lastSegment();
}
public void setName(String name)
{
setRelativePath(relativePath.removeLastSegments(1).append(name));
}
public IPath getRelativePath()
{
return relativePath;
}
public void setRelativePath(IPath path)
{
if (!ObjectUtil.equals(relativePath, path))
{
IPath oldPath = relativePath;
relativePath = path;
unsetStatusRecursively();
transfer.relativePathChanged(this, oldPath, path);
}
}
public void setRelativePath(String path)
{
setRelativePath(new Path(path));
}
public void accept(Visitor visitor)
{
if (visitor.visit(this) && children != null)
{
for (CDOTransferMapping child : children)
{
child.accept(visitor);
}
}
}
public CDOTransferMapping[] getChildren()
{
if (children == null || children.isEmpty())
{
return NO_CHILDREN;
}
CDOTransferMapping[] result = children.toArray(new CDOTransferMapping[children.size()]);
Arrays.sort(result);
return result;
}
public CDOTransferMapping getChild(IPath path)
{
if (path.isEmpty())
{
return this;
}
String name = path.segment(0);
for (CDOTransferMapping child : getChildren())
{
if (name.equals(child.getName()))
{
return child.getChild(path.removeFirstSegments(1));
}
}
return null;
}
public CDOTransferMapping getChild(String path)
{
return getChild(new Path(path));
}
private void addChild(CDOTransferMapping child)
{
ensureChildrenList();
if (!children.contains(child))
{
children.add(child);
transfer.childrenChanged(this, child, CDOTransfer.ChildrenChangedEvent.Kind.MAPPED);
}
}
private void removeChild(CDOTransferMapping child)
{
if (children != null && children.remove(child))
{
transfer.childrenChanged(this, child, CDOTransfer.ChildrenChangedEvent.Kind.UNMAPPED);
}
}
private void ensureChildrenList()
{
if (children == null)
{
children = new ArrayList<CDOTransferMapping>();
}
}
public void unmap()
{
transfer.unmap(this);
if (parent != null)
{
parent.removeChild(this);
}
}
public CDOTransferType getTransferType()
{
return transferType;
}
public void setTransferType(CDOTransferType transferType)
{
if (!ObjectUtil.equals(this.transferType, transferType))
{
CDOTransferType oldType = this.transferType;
this.transferType = transferType;
transfer.transferTypeChanged(this, oldType, transferType);
}
}
public IPath getFullPath()
{
IPath relativePath = getRelativePath();
if (isRoot())
{
return relativePath;
}
IPath path = parent.getFullPath();
return path.append(relativePath);
}
public Status getStatus()
{
if (status == null)
{
status = calculateStatus();
}
return status;
}
private Status calculateStatus()
{
if (parent != null)
{
Status status = parent.getStatus();
if (status != Status.MERGE)
{
return status;
}
}
CDOTransferSystem targetSystem = transfer.getTargetSystem();
IPath fullPath = getFullPath();
int lastSegment = fullPath.segmentCount();
for (int i = 1; i <= lastSegment; i++)
{
IPath path = fullPath.uptoSegment(i);
CDOTransferElement target = targetSystem.getElement(path);
if (target == null)
{
return Status.NEW;
}
boolean sourceDirectory = i == lastSegment ? isDirectory() : true;
boolean targetDirectory = target.isDirectory();
if (!(sourceDirectory && targetDirectory))
{
return Status.CONFLICT;
}
}
return Status.MERGE;
}
private void unsetStatusRecursively()
{
if (status != null)
{
status = null;
if (children != null && !children.isEmpty())
{
for (CDOTransferMapping child : children)
{
((CDOTransferMappingImpl)child).unsetStatusRecursively();
}
}
}
}
public CDOTransferElement getTarget()
{
CDOTransferSystem targetSystem = transfer.getTargetSystem();
IPath fullPath = getFullPath();
return targetSystem.getElement(fullPath);
}
public int compareTo(CDOTransferMapping o)
{
boolean directory = isDirectory();
boolean oDirectory = o.isDirectory();
if (directory != oDirectory)
{
return directory ? -1 : 1;
}
return getName().compareTo(o.getName());
}
@Override
public String toString()
{
return getFullPath().toString();
}
}