|
22 | 22 |
|
23 | 23 | import org.eclipse.core.resources.IResource;
|
24 | 24 | import org.eclipse.core.resources.IStorage;
|
| 25 | +import org.eclipse.core.resources.ResourcesPlugin; |
| 26 | +import org.eclipse.core.runtime.CoreException; |
25 | 27 | import org.eclipse.core.runtime.IProgressMonitor;
|
| 28 | +import org.eclipse.core.runtime.SubMonitor; |
26 | 29 | import org.eclipse.emf.compare.ide.ui.logical.AbstractModelResolver;
|
27 | 30 | import org.eclipse.emf.compare.ide.ui.logical.IStorageProviderAccessor;
|
| 31 | +import org.eclipse.emf.compare.ide.ui.logical.IStorageProviderAccessor.DiffSide; |
28 | 32 | import org.eclipse.emf.compare.ide.ui.logical.SynchronizationModel;
|
| 33 | +import org.eclipse.emf.compare.ide.utils.ResourceUtil; |
29 | 34 | import org.eclipse.emf.compare.ide.utils.StorageTraversal;
|
30 | 35 |
|
31 | 36 | /**
|
|
36 | 41 | public class OmlModelResolver extends AbstractModelResolver {
|
37 | 42 |
|
38 | 43 | @Override
|
39 |
| - public SynchronizationModel resolveLocalModels(IResource left, IResource right, IResource origin, |
40 |
| - IProgressMonitor monitor) throws InterruptedException { |
41 |
| - return new SynchronizationModel(getTraversal(left), getTraversal(right), getTraversal(origin)); |
42 |
| - } |
43 |
| - |
44 |
| - @Override |
45 |
| - public SynchronizationModel resolveModels(IStorageProviderAccessor storageAccessor, IStorage left, IStorage right, |
46 |
| - IStorage origin, IProgressMonitor monitor) throws InterruptedException { |
47 |
| - return new SynchronizationModel(getTraversal(left), getTraversal(right), getTraversal(origin)); |
| 44 | + public boolean canResolve(IStorage sourceStorage) { |
| 45 | + return true; |
48 | 46 | }
|
49 |
| - |
| 47 | + |
| 48 | + // Local |
| 49 | + |
50 | 50 | @Override
|
51 | 51 | public StorageTraversal resolveLocalModel(IResource resource, IProgressMonitor monitor)
|
52 | 52 | throws InterruptedException {
|
53 |
| - return getTraversal(resource); |
| 53 | + return getLocalTraversal(resource); |
54 | 54 | }
|
55 | 55 |
|
56 | 56 | @Override
|
57 |
| - public boolean canResolve(IStorage sourceStorage) { |
58 |
| - return true; |
| 57 | + public SynchronizationModel resolveLocalModels(IResource left, IResource right, IResource origin, |
| 58 | + IProgressMonitor monitor) throws InterruptedException { |
| 59 | + return new SynchronizationModel(getLocalTraversal(left), getLocalTraversal(right), getLocalTraversal(origin)); |
59 | 60 | }
|
60 | 61 |
|
61 |
| - private static StorageTraversal getTraversal(Object resource) { |
| 62 | + /** |
| 63 | + * For local resources, include the given resource directly in the StorageTraversal. |
| 64 | + */ |
| 65 | + private static StorageTraversal getLocalTraversal(IResource resource) { |
62 | 66 | if (resource instanceof IStorage) {
|
63 | 67 | return new StorageTraversal(Collections.singleton((IStorage)resource));
|
64 | 68 | } else {
|
65 | 69 | return new StorageTraversal(Collections.emptySet());
|
66 | 70 | }
|
67 | 71 | }
|
| 72 | + |
| 73 | + // Remote |
| 74 | + |
| 75 | + @Override |
| 76 | + public SynchronizationModel resolveModels(IStorageProviderAccessor storageAccessor, IStorage left, IStorage right, |
| 77 | + IStorage origin, IProgressMonitor monitor) throws InterruptedException { |
| 78 | + var subMonitor = SubMonitor.convert(monitor, 3); |
| 79 | + return new SynchronizationModel( |
| 80 | + getRemoteTraversal(storageAccessor, left, DiffSide.SOURCE, subMonitor.split(1)), |
| 81 | + getRemoteTraversal(storageAccessor, right, DiffSide.REMOTE, subMonitor.split(1)), |
| 82 | + getRemoteTraversal(storageAccessor, origin, DiffSide.ORIGIN, subMonitor.split(1)) |
| 83 | + ); |
| 84 | + } |
| 85 | + |
| 86 | + /** |
| 87 | + * For remote traversals, the IStorage given to us may be a wrapper for an underlying IStorage object that |
| 88 | + * doesn't actually exist and is null; trying to load the contents of this IStorage results in an error. |
| 89 | + * |
| 90 | + * To prevent this, try to locate the storage object ourselves from the |
| 91 | + * storageAccessor using the given storage object's name to ensure it exists. |
| 92 | + */ |
| 93 | + private static StorageTraversal getRemoteTraversal(IStorageProviderAccessor storageAccessor, IStorage givenStorage, DiffSide side, IProgressMonitor monitor) { |
| 94 | + try { |
| 95 | + if (givenStorage != null) { |
| 96 | + var path = ResourceUtil.getAbsolutePath(givenStorage); |
| 97 | + var file = ResourcesPlugin.getWorkspace().getRoot().getFile(path); |
| 98 | + var storageProvider = storageAccessor.getStorageProvider(file, side); |
| 99 | + if (storageProvider != null) { |
| 100 | + var foundStorage = storageProvider.getStorage(monitor); |
| 101 | + if (foundStorage != null) { |
| 102 | + return new StorageTraversal(Collections.singleton(foundStorage)); |
| 103 | + } |
| 104 | + } |
| 105 | + } |
| 106 | + } catch (CoreException e) { |
| 107 | + // returns an empty traversal in the event of a CoreException |
| 108 | + e.printStackTrace(); |
| 109 | + } finally { |
| 110 | + monitor.done(); |
| 111 | + } |
| 112 | + return new StorageTraversal(Collections.emptySet()); |
| 113 | + } |
| 114 | + |
68 | 115 | }
|
0 commit comments