1 /*******************************************************************************
2  * Copyright (c) 2000, 2017 IBM Corporation and others.
3  *
4  * This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License 2.0
6  * which accompanies this distribution, and is available at
7  * https://www.eclipse.org/legal/epl-2.0/
8  *
9  * SPDX-License-Identifier: EPL-2.0
10  *
11  * Contributors:
12  *     IBM Corporation - initial API and implementation
13  *******************************************************************************/
14 package org.eclipse.team.core.synchronize;
15 
16 import org.eclipse.core.runtime.IProgressMonitor;
17 
18 /**
19  * A specialized <code>SyncInfoFilter</code> that does not require a progress monitor.
20  * This enables these filters to be used when determining menu enablement or other
21  * operations that must be short running.
22  *
23  * @see SyncInfo
24  * @see SyncInfoSet
25  * @see SyncInfoFilter
26  * @since 3.0
27  */
28 public class FastSyncInfoFilter extends SyncInfoFilter {
29 
30 	/**
31 	 * Selects <code>SyncInfo</code> that match the given change type and direction.
32 	 *
33 	 * @param direction the change direction (<code>SyncInfo.OUTGOING</code>,
34 	 * <code>SyncInfo.INCOMING</code> and <code>SyncInfo.CONFLICTING</code>) that this filter matches
35 	 * @param change the change type (<code>SyncInfo.ADDITION</code>,
36 	 * <code>SyncInfo.DELETION</code> and <code>SyncInfo.CHANGE</code>) that this filter matches
37 	 * @return a <code>FastSyncInfoFilter</code> that selects <code>SyncInfo</code> that match the given
38 	 * change type and direction.
39 	 */
getDirectionAndChangeFilter(int direction, int change)40 	public static FastSyncInfoFilter getDirectionAndChangeFilter(int direction, int change) {
41 		return new AndSyncInfoFilter(new FastSyncInfoFilter[]{new SyncInfoDirectionFilter(direction), new SyncInfoChangeTypeFilter(change)});
42 	}
43 
44 	/**
45 	 * An abstract class which contains a set of <code>FastSyncInfoFilter</code> instances.
46 	 * Subclasses must provide the <code>select(SyncInfo)</code> method for determining
47 	 * matches.
48 	 */
49 	public static abstract class CompoundSyncInfoFilter extends FastSyncInfoFilter {
50 		/**
51 		 * Instance variable which contains all the child filters for this compound filter.
52 		 */
53 		protected FastSyncInfoFilter[] filters;
54 		/**
55 		 * Create a compound filter that contains the provided filters.
56 		 * @param filters the child filters
57 		 */
CompoundSyncInfoFilter(FastSyncInfoFilter[] filters)58 		protected CompoundSyncInfoFilter(FastSyncInfoFilter[] filters) {
59 			this.filters = filters;
60 		}
61 	}
62 
63 	/**
64 	 * Selects <code>SyncInfo</code> which match all child filters.
65 	 */
66 	public static class AndSyncInfoFilter extends CompoundSyncInfoFilter {
67 		/**
68 		 * Create an AND filter from the given filters
69 		 * @param filters the filters to be ANDed
70 		 */
AndSyncInfoFilter(FastSyncInfoFilter[] filters)71 		public AndSyncInfoFilter(FastSyncInfoFilter[] filters) {
72 			super(filters);
73 		}
74 		@Override
select(SyncInfo info)75 		public boolean select(SyncInfo info) {
76 			for (FastSyncInfoFilter filter : filters) {
77 				if (!filter.select(info)) {
78 					return false;
79 				}
80 			}
81 			return true;
82 		}
83 	}
84 
85 	/**
86 	 * Selects <code>SyncInfo</code> instances that are auto-mergable.
87 	 */
88 	public static class AutomergableFilter extends FastSyncInfoFilter {
89 		@Override
select(SyncInfo info)90 		public boolean select(SyncInfo info) {
91 			return (info.getKind() & SyncInfo.AUTOMERGE_CONFLICT) != 0;
92 		}
93 	}
94 
95 	/**
96 	 * Selects <code>SyncInfo</code> instances that are pseudo-conflicts.
97 	 */
98 	public static class PseudoConflictFilter extends FastSyncInfoFilter {
99 		@Override
select(SyncInfo info)100 		public boolean select(SyncInfo info) {
101 			return info.getKind() != 0 && (info.getKind() & SyncInfo.PSEUDO_CONFLICT) == 0;
102 		}
103 	}
104 
105 	/**
106 	 * Selects <code>SyncInfo</code> that match any of the child filters.
107 	 */
108 	public static class OrSyncInfoFilter extends CompoundSyncInfoFilter {
109 		/**
110 		 * Create an OR filter from the given filters
111 		 * @param filters the filters to be ORed
112 		 */
OrSyncInfoFilter(FastSyncInfoFilter[] filters)113 		public OrSyncInfoFilter(FastSyncInfoFilter[] filters) {
114 			super(filters);
115 		}
116 		@Override
select(SyncInfo info)117 		public boolean select(SyncInfo info) {
118 			for (FastSyncInfoFilter filter : filters) {
119 				if (filter.select(info)) {
120 					return true;
121 				}
122 			}
123 			return false;
124 		}
125 	}
126 
127 	/**
128 	 * Selects <code>SyncInfo</code> whose change type match those of the filter.
129 	 */
130 	public static class SyncInfoChangeTypeFilter extends FastSyncInfoFilter {
131 		private int[] changeFilters = new int[]{SyncInfo.ADDITION, SyncInfo.DELETION, SyncInfo.CHANGE};
132 		/**
133 		 * Create a filter that will match <code>SyncInfo</code> whose change type
134 		 * match those passed as arguments to this constructor.
135 		 * @param changeFilters the array of change types (<code>SyncInfo.ADDITION</code>,
136 		 * <code>SyncInfo.DELETION</code> and <code>SyncInfo.CHANGE</code>) that this filter match
137 		 */
SyncInfoChangeTypeFilter(int[] changeFilters)138 		public SyncInfoChangeTypeFilter(int[] changeFilters) {
139 			this.changeFilters = changeFilters;
140 		}
141 		/**
142 		 * Create a filter that will match <code>SyncInfo</code> whose change type
143 		 * match that passed as an argument to this constructor.
144 		 * @param change the change type (<code>SyncInfo.ADDITION</code>,
145 		 * <code>SyncInfo.DELETION</code> and <code>SyncInfo.CHANGE</code>) that this filter matches
146 		 */
SyncInfoChangeTypeFilter(int change)147 		public SyncInfoChangeTypeFilter(int change) {
148 			this(new int[]{change});
149 		}
150 		@Override
select(SyncInfo info)151 		public boolean select(SyncInfo info) {
152 			int syncKind = info.getKind();
153 			for (int filter : changeFilters) {
154 				if ((syncKind & SyncInfo.CHANGE_MASK) == filter)
155 					return true;
156 			}
157 			return false;
158 		}
159 	}
160 
161 	/**
162 	 * Selects <code>SyncInfo</code> whose change direction match those of the filter.
163 	 */
164 	public static class SyncInfoDirectionFilter extends FastSyncInfoFilter {
165 		int[] directionFilters = new int[] {SyncInfo.OUTGOING, SyncInfo.INCOMING, SyncInfo.CONFLICTING};
166 		/**
167 		 * Create a filter that will match <code>SyncInfo</code> whose change direction
168 		 * match those passed as arguments to this constructor.
169 		 * @param directionFilters the array of change directions (<code>SyncInfo.OUTGOING</code>,
170 		 * <code>SyncInfo.INCOMING</code> and <code>SyncInfo.CONFLICTING</code>) that this filter match
171 		 */
SyncInfoDirectionFilter(int[] directionFilters)172 		public SyncInfoDirectionFilter(int[] directionFilters) {
173 			this.directionFilters = directionFilters;
174 		}
175 		/**
176 		 * Create a filter that will match <code>SyncInfo</code> whose change direction
177 		 * match that passed as arguments to this constructor.
178 		 * @param direction the change direction (<code>SyncInfo.OUTGOING</code>,
179 		 * <code>SyncInfo.INCOMING</code> and <code>SyncInfo.CONFLICTING</code>) that this filter matches
180 		 */
SyncInfoDirectionFilter(int direction)181 		public SyncInfoDirectionFilter(int direction) {
182 			this(new int[] { direction });
183 		}
184 		@Override
select(SyncInfo info)185 		public boolean select(SyncInfo info) {
186 			int syncKind = info.getKind();
187 			for (int filter : directionFilters) {
188 				if ((syncKind & SyncInfo.DIRECTION_MASK) == filter)
189 					return true;
190 			}
191 			return false;
192 		}
193 	}
194 
195 	/**
196 	 * Return whether the provided <code>SyncInfo</code> matches the filter. The default
197 	 * behavior it to include resources whose syncKind is non-zero.
198 	 *
199 	 * @param info the <code>SyncInfo</code> being tested
200 	 * @return <code>true</code> if the <code>SyncInfo</code> matches the filter
201 	 */
select(SyncInfo info)202 	public boolean select(SyncInfo info) {
203 		return info.getKind() != 0;
204 	}
205 
206 	@Override
select(SyncInfo info, IProgressMonitor monitor)207 	public final boolean select(SyncInfo info, IProgressMonitor monitor) {
208 		return select(info);
209 	}
210 }
211