Skip to main content
summaryrefslogtreecommitdiffstats
blob: 4053b3813383de573138cbd3d9a1f9e7b91774a7 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
/*******************************************************************************
 * Copyright (c) 2016 Obeo 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:
 *     Obeo - initial API and implementation
 *     Philip Langer - bug 501864
 *******************************************************************************/
package org.eclipse.emf.compare.rcp.ui.internal.structuremergeviewer.filters.impl;

import static com.google.common.collect.Iterators.any;
import static org.eclipse.emf.compare.utils.EMFComparePredicates.hasDirectOrIndirectConflict;

import com.google.common.base.Predicate;

import org.eclipse.emf.compare.ConflictKind;
import org.eclipse.emf.compare.Diff;
import org.eclipse.emf.compare.FeatureMapChange;
import org.eclipse.emf.compare.Match;
import org.eclipse.emf.compare.MatchResource;
import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters.AbstractDifferenceFilter;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.util.FeatureMap;
import org.eclipse.emf.edit.tree.TreeNode;

/**
 * <p>
 * A filter used by default that rejects all 'technical' differences. The technical differences are the diffs
 * that apply on empty {@link MatchResource}s, on {@link FeatureMap} diffs, on identical elements and on
 * pseudo-conflicts.
 * </p>
 * This filter aggregates the former 4 corresponding filters.
 * 
 * @author <a href="mailto:mathieu.cartaud@obeo.fr">Mathieu Cartaud</a>
 */
public class TechnicalitiesFilter extends AbstractDifferenceFilter {

	/**
	 * The predicate use by this filter when it is selected.
	 */
	private static final Predicate<? super EObject> PREDICATE_WHEN_SELECTED = new Predicate<EObject>() {
		public boolean apply(EObject input) {
			return PREDICATE_EMPTY_MATCH_RESOURCES.apply(input) || PREDICATE_FEATURE_MAP.apply(input)
					|| PREDICATE_IDENTICAL_ELEMENTS.apply(input) || PREDICATE_PSEUDO_CONFLICT.apply(input);
		}
	};

	/**
	 * The predicate use to filter empty match resources.
	 */
	private static final Predicate<? super EObject> PREDICATE_EMPTY_MATCH_RESOURCES = new Predicate<EObject>() {
		public boolean apply(EObject input) {
			boolean ret = false;
			if (input instanceof TreeNode) {
				TreeNode treeNode = (TreeNode)input;
				if (treeNode.getData() instanceof MatchResource) {
					ret = treeNode.getChildren().isEmpty();
				}
			}
			return ret;
		}
	};

	/**
	 * The predicate use to filter feature maps.
	 */
	private static final Predicate<? super EObject> PREDICATE_FEATURE_MAP = new Predicate<EObject>() {
		public boolean apply(EObject input) {
			boolean ret = false;
			if (input instanceof TreeNode) {
				EObject data = ((TreeNode)input).getData();
				if (data instanceof FeatureMapChange) {
					ret = ((FeatureMapChange)data).getEquivalence() != null;
				}
			}
			return ret;
		}
	};

	/**
	 * The predicate use to filter pseudo conflicts.
	 */
	private static final Predicate<? super EObject> PREDICATE_PSEUDO_CONFLICT = new Predicate<EObject>() {
		public boolean apply(EObject input) {
			boolean ret = false;
			if (input instanceof TreeNode) {
				TreeNode treeNode = (TreeNode)input;
				EObject data = treeNode.getData();
				if (data instanceof Diff) {
					Diff diff = (Diff)data;
					if (diff.getMatch().getComparison().isThreeWay()) {
						ret = hasDirectOrIndirectPseudoConflictOnly(diff);
					}
				}
			}
			return ret;
		}
	};

	/**
	 * Specifies whether the given diff has a direct or indirect pseudo conflict, but not a direct or indirect
	 * real conflict.
	 * 
	 * @param diff
	 *            The diff to check.
	 * @return <code>true</code> if it only has a direct or indirect pseudo conflict, <code>false</code>
	 *         otherwise.
	 */
	private static boolean hasDirectOrIndirectPseudoConflictOnly(Diff diff) {
		return hasDirectOrIndirectConflict(ConflictKind.PSEUDO).apply(diff)
				&& !hasDirectOrIndirectConflict(ConflictKind.REAL).apply(diff);
	}

	/**
	 * The predicate use to filter identical elements.
	 */
	private static final Predicate<? super EObject> PREDICATE_IDENTICAL_ELEMENTS = new Predicate<EObject>() {
		public boolean apply(EObject input) {
			if (input instanceof TreeNode) {
				TreeNode treeNode = (TreeNode)input;
				EObject data = treeNode.getData();
				if (data instanceof Match) {
					return !any(treeNode.eAllContents(), DATA_IS_DIFF);
				}
			}
			return false;
		}
	};

	/**
	 * Predicate to know if the given TreeNode is a diff.
	 */
	private static final Predicate<EObject> DATA_IS_DIFF = new Predicate<EObject>() {
		public boolean apply(EObject treeNode) {
			return treeNode instanceof TreeNode && ((TreeNode)treeNode).getData() instanceof Diff;
		}
	};

	@Override
	public Predicate<? super EObject> getPredicateWhenSelected() {
		return PREDICATE_WHEN_SELECTED;
	}

}

Back to the top