| /* |
| * 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; |
| |
| import org.eclipse.emf.cdo.spi.transfer.ResourceFactoryRegistryWithoutDefaults; |
| |
| import org.eclipse.net4j.util.event.Event; |
| import org.eclipse.net4j.util.event.IEvent; |
| import org.eclipse.net4j.util.event.IListener; |
| import org.eclipse.net4j.util.event.INotifier; |
| import org.eclipse.net4j.util.event.Notifier; |
| import org.eclipse.net4j.util.io.IOUtil; |
| import org.eclipse.net4j.util.lifecycle.ILifecycleEvent; |
| |
| import org.eclipse.emf.common.notify.Notification; |
| import org.eclipse.emf.common.notify.impl.AdapterImpl; |
| import org.eclipse.emf.common.util.EList; |
| import org.eclipse.emf.common.util.URI; |
| import org.eclipse.emf.ecore.EObject; |
| import org.eclipse.emf.ecore.resource.Resource; |
| import org.eclipse.emf.ecore.resource.ResourceSet; |
| import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl; |
| import org.eclipse.emf.ecore.util.EcoreUtil; |
| import org.eclipse.emf.ecore.util.EcoreUtil.Copier; |
| |
| import org.eclipse.core.runtime.IPath; |
| import org.eclipse.core.runtime.IProgressMonitor; |
| import org.eclipse.core.runtime.NullProgressMonitor; |
| import org.eclipse.core.runtime.OperationCanceledException; |
| import org.eclipse.core.runtime.Path; |
| import org.eclipse.core.runtime.SubProgressMonitor; |
| |
| import java.io.InputStream; |
| import java.util.Collection; |
| import java.util.HashMap; |
| import java.util.HashSet; |
| import java.util.Map; |
| import java.util.Set; |
| |
| /** |
| * Abstracts the transfer of a tree of {@link CDOTransferElement elements} for a |
| * {@link #getSourceSystem() source} to a {@link #getTargetSystem() target} {@link CDOTransferSystem system}. |
| * <p> |
| * The mappings of the source elements to their target elements is represented as a tree of {@link CDOTransferMapping transfer mappings}. |
| * <p> |
| * A transfer fires the following {@link IEvent events}: |
| * <ul> |
| * <li>{@link ChildrenChangedEvent} when the {@link CDOTransferMapping#getChildren() children} of a mapping have changed. |
| * <li>{@link RelativePathChangedEvent} when the {@link CDOTransferMapping#getRelativePath() relative path} of a mapping has changed. |
| * <li>{@link TransferTypeChangedEvent} when the {@link CDOTransferMapping#getTransferType() transfer type} of a mapping has changed. |
| * <li>{@link UnmappedModelsEvent} when the set of {@link CDOTransfer.ModelTransferContext#getUnmappedModels() unmapped models} has changed. |
| * </ul> |
| * |
| * @author Eike Stepper |
| * @since 4.2 |
| */ |
| public class CDOTransfer implements INotifier |
| { |
| protected final Notifier notifier = new Notifier(); |
| |
| private final CDOTransferSystem sourceSystem; |
| |
| private final CDOTransferSystem targetSystem; |
| |
| private final CDOTransferMapping rootMapping = new CDOTransferMappingImpl(this); |
| |
| private final Map<CDOTransferElement, CDOTransferMapping> mappings = new HashMap<CDOTransferElement, CDOTransferMapping>(); |
| |
| private CDOTransferType defaultTransferType = CDOTransferType.BINARY; |
| |
| private ModelTransferContext modelTransferContext = createModelTransferContext(); |
| |
| public CDOTransfer(CDOTransferSystem sourceSystem, CDOTransferSystem targetSystem) |
| { |
| this.sourceSystem = sourceSystem; |
| this.targetSystem = targetSystem; |
| } |
| |
| public void addListener(IListener listener) |
| { |
| notifier.addListener(listener); |
| } |
| |
| public void removeListener(IListener listener) |
| { |
| notifier.removeListener(listener); |
| } |
| |
| public boolean hasListeners() |
| { |
| return notifier.hasListeners(); |
| } |
| |
| public IListener[] getListeners() |
| { |
| return notifier.getListeners(); |
| } |
| |
| public final CDOTransferSystem getSourceSystem() |
| { |
| return sourceSystem; |
| } |
| |
| public final CDOTransferSystem getTargetSystem() |
| { |
| return targetSystem; |
| } |
| |
| public ModelTransferContext getModelTransferContext() |
| { |
| return modelTransferContext; |
| } |
| |
| public final CDOTransferType getDefaultTransferType() |
| { |
| return defaultTransferType; |
| } |
| |
| public final void setDefaultTransferType(CDOTransferType defaultTransferType) |
| { |
| if (defaultTransferType == CDOTransferType.FOLDER) |
| { |
| throw new IllegalArgumentException(); |
| } |
| |
| this.defaultTransferType = defaultTransferType; |
| } |
| |
| public Set<CDOTransferType> getUsedTransferTypes() |
| { |
| final Set<CDOTransferType> result = new HashSet<CDOTransferType>(); |
| rootMapping.accept(new CDOTransferMapping.Visitor() |
| { |
| public boolean visit(CDOTransferMapping mapping) |
| { |
| result.add(mapping.getTransferType()); |
| return true; |
| } |
| }); |
| |
| return result; |
| } |
| |
| public final CDOTransferMapping getRootMapping() |
| { |
| return rootMapping; |
| } |
| |
| public IPath getTargetPath() |
| { |
| return rootMapping.getRelativePath(); |
| } |
| |
| public void setTargetPath(IPath targetPath) |
| { |
| rootMapping.setRelativePath(targetPath); |
| } |
| |
| public void setTargetPath(String path) |
| { |
| rootMapping.setRelativePath(path); |
| } |
| |
| public int getMappingCount() |
| { |
| return mappings.size(); |
| } |
| |
| public CDOTransferMapping map(IPath sourcePath, IProgressMonitor monitor) |
| { |
| CDOTransferElement source = sourceSystem.getElement(sourcePath); |
| return map(source, monitor); |
| } |
| |
| public CDOTransferMapping map(String sourcePath, IProgressMonitor monitor) |
| { |
| return map(new Path(sourcePath), monitor); |
| } |
| |
| public CDOTransferMapping map(CDOTransferElement source, IProgressMonitor monitor) |
| { |
| return map(source, rootMapping, monitor); |
| } |
| |
| protected CDOTransferMapping map(CDOTransferElement source, CDOTransferMapping parent, IProgressMonitor monitor) |
| { |
| CDOTransferMapping mapping = mappings.get(source); |
| if (mapping == null) |
| { |
| mapping = createMapping(source, parent, monitor); |
| mappings.put(source, mapping); |
| } |
| else |
| { |
| if (mapping.getParent() != parent) |
| { |
| throw new IllegalStateException(); |
| } |
| } |
| |
| return mapping; |
| } |
| |
| protected void unmap(CDOTransferMapping mapping) |
| { |
| mappings.remove(mapping.getSource()); |
| mapping.getChildren(); |
| } |
| |
| protected CDOTransferMapping createMapping(CDOTransferElement source, CDOTransferMapping parent, |
| IProgressMonitor monitor) |
| { |
| return new CDOTransferMappingImpl(this, source, parent, monitor); |
| } |
| |
| protected ModelTransferContext createModelTransferContext() |
| { |
| return new ModelTransferContext(this); |
| } |
| |
| protected CDOTransferType getTransferType(CDOTransferElement source) |
| { |
| if (source.isDirectory()) |
| { |
| return CDOTransferType.FOLDER; |
| } |
| |
| CDOTransferType type = sourceSystem.getDefaultTransferType(source); |
| if (type != null) |
| { |
| return type; |
| } |
| |
| if (modelTransferContext.hasResourceFactory(source)) |
| { |
| return CDOTransferType.MODEL; |
| } |
| |
| return getDefaultTransferType(); |
| } |
| |
| protected void validate(CDOTransferMapping mapping, IProgressMonitor monitor) |
| { |
| if (monitor.isCanceled()) |
| { |
| throw new OperationCanceledException(); |
| } |
| |
| if (mapping.getStatus() == CDOTransferMapping.Status.CONFLICT) |
| { |
| throw new IllegalStateException("Conflict: " + mapping); |
| } |
| |
| monitor.worked(1); |
| for (CDOTransferMapping child : mapping.getChildren()) |
| { |
| validate(child, monitor); |
| } |
| } |
| |
| public void perform() |
| { |
| perform(new NullProgressMonitor()); |
| } |
| |
| public void perform(IProgressMonitor monitor) |
| { |
| try |
| { |
| int mappingCount = getMappingCount(); |
| monitor.beginTask("Perform transfer from " + getSourceSystem() + " to " + getTargetSystem(), 5 * mappingCount); |
| |
| monitor.subTask("Validating transfer"); |
| validate(rootMapping, new SubProgressMonitor(monitor, mappingCount)); |
| |
| perform(rootMapping, monitor); |
| modelTransferContext.performFinish(new SubProgressMonitor(monitor, 2 * mappingCount)); |
| } |
| finally |
| { |
| monitor.done(); |
| } |
| } |
| |
| protected void perform(CDOTransferMapping mapping, IProgressMonitor monitor) |
| { |
| monitor.subTask("Transferring " + mapping); |
| if (monitor.isCanceled()) |
| { |
| throw new OperationCanceledException(); |
| } |
| |
| CDOTransferType transferType = mapping.getTransferType(); |
| if (transferType == CDOTransferType.FOLDER) |
| { |
| performFolder(mapping, monitor); |
| } |
| else if (transferType == CDOTransferType.MODEL) |
| { |
| performModel(mapping, monitor); |
| } |
| else if (transferType == CDOTransferType.BINARY) |
| { |
| performBinary(mapping, monitor); |
| } |
| else if (transferType instanceof CDOTransferType.Text) |
| { |
| String encoding = ((CDOTransferType.Text)transferType).getEncoding(); |
| performText(mapping, encoding, monitor); |
| } |
| } |
| |
| protected void performFolder(CDOTransferMapping mapping, IProgressMonitor monitor) |
| { |
| if (mapping.getStatus() == CDOTransferMapping.Status.NEW) |
| { |
| targetSystem.createFolder(mapping.getFullPath()); |
| } |
| |
| monitor.worked(2); |
| for (CDOTransferMapping child : mapping.getChildren()) |
| { |
| perform(child, monitor); |
| } |
| } |
| |
| protected void performModel(CDOTransferMapping mapping, IProgressMonitor monitor) |
| { |
| modelTransferContext.perform(mapping, new SubProgressMonitor(monitor, 2)); |
| } |
| |
| protected void performBinary(CDOTransferMapping mapping, IProgressMonitor monitor) |
| { |
| IPath path = mapping.getFullPath(); |
| InputStream source = mapping.getSource().openInputStream(); |
| |
| try |
| { |
| targetSystem.createBinary(path, source, new SubProgressMonitor(monitor, 2)); |
| } |
| finally |
| { |
| IOUtil.close(source); |
| } |
| } |
| |
| protected void performText(CDOTransferMapping mapping, String encoding, IProgressMonitor monitor) |
| { |
| IPath path = mapping.getFullPath(); |
| InputStream source = mapping.getSource().openInputStream(); |
| |
| try |
| { |
| targetSystem.createText(path, source, encoding, new SubProgressMonitor(monitor, 2)); |
| } |
| finally |
| { |
| IOUtil.close(source); |
| } |
| } |
| |
| protected void childrenChanged(CDOTransferMapping mapping, CDOTransferMapping child, ChildrenChangedEvent.Kind kind) |
| { |
| if (child.getTransferType() == CDOTransferType.MODEL) |
| { |
| if (kind == ChildrenChangedEvent.Kind.MAPPED) |
| { |
| modelTransferContext.addModelMapping(child); |
| } |
| else |
| { |
| modelTransferContext.removeModelMapping(child); |
| } |
| } |
| |
| IListener[] listeners = notifier.getListeners(); |
| if (listeners != null) |
| { |
| notifier.fireEvent(new ChildrenChangedEvent(mapping, child, kind), listeners); |
| } |
| } |
| |
| protected void relativePathChanged(CDOTransferMapping mapping, IPath oldPath, IPath newPath) |
| { |
| IListener[] listeners = notifier.getListeners(); |
| if (listeners != null) |
| { |
| notifier.fireEvent(new RelativePathChangedEvent(mapping, oldPath, newPath), listeners); |
| } |
| } |
| |
| protected void transferTypeChanged(CDOTransferMapping mapping, CDOTransferType oldType, CDOTransferType newType) |
| { |
| if (oldType == CDOTransferType.MODEL) |
| { |
| modelTransferContext.removeModelMapping(mapping); |
| } |
| |
| if (newType == CDOTransferType.MODEL) |
| { |
| modelTransferContext.addModelMapping(mapping); |
| } |
| |
| IListener[] listeners = notifier.getListeners(); |
| if (listeners != null) |
| { |
| notifier.fireEvent(new TransferTypeChangedEvent(mapping, oldType, newType), listeners); |
| } |
| } |
| |
| /** |
| * An abstract base implementation of a {@link CDOTransferMapping mapping} {@link ILifecycleEvent event}. |
| * |
| * @author Eike Stepper |
| * @noextend This class is not intended to be subclassed by clients. |
| */ |
| public static abstract class MappingEvent extends Event |
| { |
| private static final long serialVersionUID = 1L; |
| |
| private CDOTransferMapping mapping; |
| |
| private MappingEvent(CDOTransferMapping mapping) |
| { |
| super(mapping.getTransfer()); |
| this.mapping = mapping; |
| } |
| |
| public CDOTransferMapping getMapping() |
| { |
| return mapping; |
| } |
| |
| public abstract boolean hasTreeImpact(); |
| } |
| |
| /** |
| * A {@link MappingEvent mapping event} fired from a {@link CDOTransfer transfer} when |
| * the {@link CDOTransferMapping#getChildren() children} of a mapping have changed. |
| * |
| * @author Eike Stepper |
| * @noextend This class is not intended to be subclassed by clients. |
| */ |
| public static class ChildrenChangedEvent extends MappingEvent |
| { |
| private static final long serialVersionUID = 1L; |
| |
| private CDOTransferMapping child; |
| |
| private Kind kind; |
| |
| ChildrenChangedEvent(CDOTransferMapping mapping, CDOTransferMapping child, Kind kind) |
| { |
| super(mapping); |
| this.child = child; |
| this.kind = kind; |
| } |
| |
| @Override |
| public boolean hasTreeImpact() |
| { |
| return true; |
| } |
| |
| public CDOTransferMapping getChild() |
| { |
| return child; |
| } |
| |
| public Kind getKind() |
| { |
| return kind; |
| } |
| |
| /** |
| * Enumerates the possible values of {@link ChildrenChangedEvent#getKind()}. |
| * |
| * @author Eike Stepper |
| */ |
| public enum Kind |
| { |
| MAPPED, UNMAPPED |
| } |
| } |
| |
| /** |
| * A {@link MappingEvent mapping event} fired from a {@link CDOTransfer transfer} when |
| * the {@link CDOTransferMapping#getRelativePath() relative path} of a mapping has changed. |
| * |
| * @author Eike Stepper |
| * @noextend This class is not intended to be subclassed by clients. |
| */ |
| public static class RelativePathChangedEvent extends MappingEvent |
| { |
| private static final long serialVersionUID = 1L; |
| |
| private IPath oldPath; |
| |
| private IPath newPath; |
| |
| RelativePathChangedEvent(CDOTransferMapping mapping, IPath oldPath, IPath newPath) |
| { |
| super(mapping); |
| this.oldPath = oldPath; |
| this.newPath = newPath; |
| } |
| |
| @Override |
| public boolean hasTreeImpact() |
| { |
| return true; |
| } |
| |
| public IPath getOldPath() |
| { |
| return oldPath; |
| } |
| |
| public IPath getNewPath() |
| { |
| return newPath; |
| } |
| } |
| |
| /** |
| * A {@link MappingEvent mapping event} fired from a {@link CDOTransfer transfer} when |
| * the {@link CDOTransferMapping#getTransferType() transfer type} of a mapping has changed. |
| * |
| * @author Eike Stepper |
| * @noextend This class is not intended to be subclassed by clients. |
| */ |
| public static class TransferTypeChangedEvent extends MappingEvent |
| { |
| private static final long serialVersionUID = 1L; |
| |
| private CDOTransferType oldType; |
| |
| private CDOTransferType newType; |
| |
| TransferTypeChangedEvent(CDOTransferMapping mapping, CDOTransferType oldType, CDOTransferType newType) |
| { |
| super(mapping); |
| this.oldType = oldType; |
| this.newType = newType; |
| } |
| |
| @Override |
| public boolean hasTreeImpact() |
| { |
| return false; |
| } |
| |
| public CDOTransferType getOldType() |
| { |
| return oldType; |
| } |
| |
| public CDOTransferType getNewType() |
| { |
| return newType; |
| } |
| } |
| |
| /** |
| * An {@link IEvent event} fired from a {@link CDOTransfer transfer} when |
| * the set of {@link CDOTransfer.ModelTransferContext#getUnmappedModels() unmapped models} has changed. |
| * |
| * @author Eike Stepper |
| * @noextend This class is not intended to be subclassed by clients. |
| */ |
| public static class UnmappedModelsEvent extends Event |
| { |
| private static final long serialVersionUID = 1L; |
| |
| private UnmappedModelsEvent(CDOTransfer transfer) |
| { |
| super(transfer); |
| } |
| } |
| |
| /** |
| * Encapsulates the model-specific aspects of a {@link CDOTransfer transfer}. |
| * |
| * @author Eike Stepper |
| */ |
| public static class ModelTransferContext |
| { |
| private final CDOTransfer transfer; |
| |
| private ResourceSet sourceResourceSet; |
| |
| private ResourceSet targetResourceSet; |
| |
| private Map<CDOTransferElement, Resource> elementResources = new HashMap<CDOTransferElement, Resource>(); |
| |
| private Map<Resource, CDOTransferElement> resourceElements = new HashMap<Resource, CDOTransferElement>(); |
| |
| private Set<Resource> unmappedModels; |
| |
| private Map<URI, ModelTransferResolution> resolutions = new HashMap<URI, ModelTransferResolution>(); |
| |
| private ResolveProxyAdapter resolveProxyAdapter; |
| |
| private Copier copier; |
| |
| protected ModelTransferContext(CDOTransfer transfer) |
| { |
| this.transfer = transfer; |
| resolveProxyAdapter = new ResolveProxyAdapter(); |
| copier = createCopier(); |
| } |
| |
| public final CDOTransfer getTransfer() |
| { |
| return transfer; |
| } |
| |
| public final ResourceSet getSourceResourceSet() |
| { |
| if (sourceResourceSet == null) |
| { |
| CDOTransferSystem sourceSystem = transfer.getSourceSystem(); |
| sourceResourceSet = sourceSystem.provideResourceSet(); |
| if (sourceResourceSet == null) |
| { |
| sourceResourceSet = createResourceSet(sourceSystem); |
| } |
| } |
| |
| return sourceResourceSet; |
| } |
| |
| public final ResourceSet getTargetResourceSet() |
| { |
| if (targetResourceSet == null) |
| { |
| CDOTransferSystem targetSystem = transfer.getTargetSystem(); |
| targetResourceSet = targetSystem.provideResourceSet(); |
| if (targetResourceSet == null) |
| { |
| targetResourceSet = createResourceSet(targetSystem); |
| } |
| } |
| |
| return targetResourceSet; |
| } |
| |
| public void registerSourceExtension(String extension, Resource.Factory factory) |
| { |
| Map<String, Object> map = getSourceResourceSet().getResourceFactoryRegistry().getExtensionToFactoryMap(); |
| map.put(extension, factory); |
| } |
| |
| public void registerSourceProtocol(String protocol, Resource.Factory factory) |
| { |
| Map<String, Object> map = getSourceResourceSet().getResourceFactoryRegistry().getProtocolToFactoryMap(); |
| map.put(protocol, factory); |
| } |
| |
| public void registerSourceContentType(String contentType, Resource.Factory factory) |
| { |
| Map<String, Object> map = getSourceResourceSet().getResourceFactoryRegistry().getContentTypeToFactoryMap(); |
| map.put(contentType, factory); |
| } |
| |
| public void registerTargetExtension(String extension, Resource.Factory factory) |
| { |
| Map<String, Object> map = getTargetResourceSet().getResourceFactoryRegistry().getExtensionToFactoryMap(); |
| map.put(extension, factory); |
| } |
| |
| public void registerTargetProtocol(String protocol, Resource.Factory factory) |
| { |
| Map<String, Object> map = getTargetResourceSet().getResourceFactoryRegistry().getProtocolToFactoryMap(); |
| map.put(protocol, factory); |
| } |
| |
| public void registerTargetContentType(String contentType, Resource.Factory factory) |
| { |
| Map<String, Object> map = getTargetResourceSet().getResourceFactoryRegistry().getContentTypeToFactoryMap(); |
| map.put(contentType, factory); |
| } |
| |
| public Set<Resource> getUnmappedModels() |
| { |
| if (unmappedModels == null) |
| { |
| unmappedModels = resolve(); |
| fireUnmappedModelsEvent(); |
| } |
| |
| return unmappedModels; |
| } |
| |
| public ModelTransferResolution getResolution(URI uri) |
| { |
| return resolutions.get(uri); |
| } |
| |
| public ModelTransferResolution setResolution(URI uri, ModelTransferResolution resolution) |
| { |
| ModelTransferResolution old = resolutions.put(uri, resolution); |
| if (resolution != old) |
| { |
| fireUnmappedModelsEvent(); |
| } |
| |
| return old; |
| } |
| |
| protected Set<Resource> resolve() |
| { |
| Set<Resource> mappedModels = resourceElements.keySet(); |
| |
| ResourceSet resourceSet = getSourceResourceSet(); |
| EList<Resource> resources = resourceSet.getResources(); |
| |
| Set<Resource> unmappedModels = new HashSet<Resource>(resources); |
| unmappedModels.removeAll(mappedModels); |
| return unmappedModels; |
| } |
| |
| protected void fireUnmappedModelsEvent() |
| { |
| transfer.notifier.fireEvent(new UnmappedModelsEvent(transfer)); |
| } |
| |
| protected void addModelMapping(CDOTransferMapping mapping) |
| { |
| CDOTransferElement element = mapping.getSource(); |
| URI uri = element.getURI(); |
| |
| ResourceSet resourceSet = getSourceResourceSet(); |
| Resource resource = resourceSet.getResource(uri, true); |
| elementResources.put(element, resource); |
| resourceElements.put(resource, element); |
| unmappedModels = null; |
| fireUnmappedModelsEvent(); |
| } |
| |
| protected void removeModelMapping(CDOTransferMapping mapping) |
| { |
| CDOTransferElement element = mapping.getSource(); |
| Resource resource = elementResources.remove(element); |
| if (resource != null) |
| { |
| resourceElements.remove(resource); |
| resource.unload(); |
| |
| ResourceSet resourceSet = getSourceResourceSet(); |
| resourceSet.getResources().remove(resource); |
| } |
| |
| unmappedModels = null; |
| fireUnmappedModelsEvent(); |
| } |
| |
| protected Resource getSourceResource(CDOTransferMapping mapping) |
| { |
| URI uri = mapping.getSource().getURI(); |
| ResourceSet sourceResourceSet = getSourceResourceSet(); |
| return sourceResourceSet.getResource(uri, true); |
| } |
| |
| protected Resource getTargetResource(CDOTransferMapping mapping) |
| { |
| IPath path = mapping.getFullPath(); |
| ResourceSet targetResourceSet = getTargetResourceSet(); |
| CDOTransferSystem targetSystem = transfer.getTargetSystem(); |
| return targetSystem.createModel(targetResourceSet, path); |
| } |
| |
| protected Copier createCopier() |
| { |
| return new Copier(); |
| } |
| |
| protected ResourceSet createResourceSet(CDOTransferSystem system) |
| { |
| ResourceSet resourceSet = new ResourceSetImpl(); |
| resourceSet.setResourceFactoryRegistry(new ResourceFactoryRegistryWithoutDefaults()); |
| resourceSet.eAdapters().add(resolveProxyAdapter); |
| |
| return resourceSet; |
| } |
| |
| protected boolean hasResourceFactory(CDOTransferElement source) |
| { |
| URI uri = source.getURI(); |
| |
| // TODO Derive resourceSet from element.getSystem()? |
| Resource.Factory.Registry registry = getSourceResourceSet().getResourceFactoryRegistry(); |
| return registry.getFactory(uri) != null; |
| } |
| |
| protected void perform(CDOTransferMapping mapping, IProgressMonitor monitor) |
| { |
| try |
| { |
| monitor.beginTask("", 2); |
| |
| Resource sourceResource = getSourceResource(mapping); |
| Resource targetResource = getTargetResource(mapping); // Create target resource |
| |
| EList<EObject> sourceContents = sourceResource.getContents(); |
| Collection<EObject> targetContents = copier.copyAll(sourceContents); |
| monitor.worked(1); |
| |
| EList<EObject> contents = targetResource.getContents(); |
| contents.addAll(targetContents); |
| monitor.worked(1); |
| } |
| finally |
| { |
| monitor.done(); |
| } |
| } |
| |
| protected void performFinish(IProgressMonitor monitor) |
| { |
| monitor.subTask("Copying model references"); |
| copier.copyReferences(); |
| |
| CDOTransferSystem targetSystem = getTransfer().getTargetSystem(); |
| targetSystem.saveModels(getTargetResourceSet().getResources(), monitor); |
| } |
| |
| /** |
| * An {@link AdapterImpl adapter} for a {@link ResourceSet resource set} that resolves all proxies in all resources when they are loaded. |
| * |
| * @author Eike Stepper |
| */ |
| public static class ResolveProxyAdapter extends AdapterImpl |
| { |
| private LoadResourceAdapter loadResourceAdapter; |
| |
| public ResolveProxyAdapter() |
| { |
| loadResourceAdapter = new LoadResourceAdapter(); |
| } |
| |
| @Override |
| public void notifyChanged(Notification msg) |
| { |
| int eventType = msg.getEventType(); |
| switch (eventType) |
| { |
| case Notification.SET: |
| { |
| Resource oldValue = (Resource)msg.getOldValue(); |
| if (oldValue != null) |
| { |
| removeResource(oldValue); |
| } |
| |
| Resource newValue = (Resource)msg.getNewValue(); |
| if (newValue != null) |
| { |
| addResource(newValue); |
| } |
| |
| break; |
| } |
| case Notification.ADD: |
| { |
| Resource newValue = (Resource)msg.getNewValue(); |
| if (newValue != null) |
| { |
| addResource(newValue); |
| } |
| break; |
| } |
| case Notification.ADD_MANY: |
| { |
| @SuppressWarnings("unchecked") |
| Collection<Resource> newValues = (Collection<Resource>)msg.getNewValue(); |
| for (Resource newValue : newValues) |
| { |
| addResource(newValue); |
| } |
| break; |
| } |
| case Notification.REMOVE: |
| { |
| Resource oldValue = (Resource)msg.getOldValue(); |
| if (oldValue != null) |
| { |
| removeResource(oldValue); |
| } |
| break; |
| } |
| case Notification.REMOVE_MANY: |
| { |
| @SuppressWarnings("unchecked") |
| Collection<Resource> oldValues = (Collection<Resource>)msg.getOldValue(); |
| for (Resource oldContentValue : oldValues) |
| { |
| removeResource(oldContentValue); |
| } |
| break; |
| } |
| } |
| } |
| |
| private void addResource(Resource resource) |
| { |
| EcoreUtil.resolveAll(resource); |
| resource.eAdapters().add(loadResourceAdapter); |
| } |
| |
| private void removeResource(Resource resource) |
| { |
| } |
| |
| /** |
| * An {@link AdapterImpl adapter} for a {@link Resource resource} that resolves all proxies in that resource when it's demand loaded. |
| * |
| * @author Eike Stepper |
| */ |
| public static class LoadResourceAdapter extends AdapterImpl |
| { |
| @Override |
| public void notifyChanged(Notification msg) |
| { |
| if (msg.getFeatureID(Resource.class) == Resource.RESOURCE__IS_LOADED) |
| { |
| int eventType = msg.getEventType(); |
| switch (eventType) |
| { |
| case Notification.SET: |
| { |
| boolean isLoaded = msg.getNewBooleanValue(); |
| if (isLoaded) |
| { |
| Resource resource = (Resource)msg.getNotifier(); |
| EcoreUtil.resolveAll(resource); |
| } |
| break; |
| } |
| } |
| } |
| } |
| } |
| } |
| } |
| |
| /** |
| * Reserved for future use. |
| * |
| * @author Eike Stepper |
| * @noextend This class is not intended to be subclassed by clients. |
| * @noimplement This interface is not intended to be implemented by clients. |
| */ |
| public interface ModelTransferResolution |
| { |
| } |
| } |