1 /*******************************************************************************
2 * Copyright (c) 2014 Obeo.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
9 * Obeo - initial API and implementation
10 *******************************************************************************/
11 package org
.eclipse
.emf
.compare
.rcp
.ui
.internal
.structuremergeviewer
.filters
.impl
;
13 import com
.google
.common
.base
.Function
;
14 import com
.google
.common
.base
.Joiner
;
15 import com
.google
.common
.base
.Preconditions
;
16 import com
.google
.common
.base
.Predicate
;
17 import com
.google
.common
.base
.Predicates
;
18 import com
.google
.common
.collect
.Collections2
;
19 import com
.google
.common
.collect
.Maps
;
20 import com
.google
.common
.collect
.Sets
;
21 import com
.google
.common
.collect
.Sets
.SetView
;
23 import java
.util
.Collection
;
24 import java
.util
.Collections
;
25 import java
.util
.LinkedHashMap
;
26 import java
.util
.LinkedHashSet
;
30 import org
.eclipse
.core
.runtime
.IStatus
;
31 import org
.eclipse
.emf
.compare
.rcp
.internal
.extension
.impl
.ItemUtil
;
32 import org
.eclipse
.emf
.compare
.rcp
.internal
.tracer
.TracingConstant
;
33 import org
.eclipse
.emf
.compare
.rcp
.ui
.EMFCompareRCPUIPlugin
;
34 import org
.eclipse
.emf
.compare
.rcp
.ui
.structuremergeviewer
.filters
.IDifferenceFilter
;
35 import org
.osgi
.service
.prefs
.Preferences
;
40 * This manager handle addition and removal of filters
43 * It also allow to override registered filters with preferences.
46 * @author <a href="mailto:arthur.daussy@obeo.fr">Arthur Daussy</a>
48 public class DifferenceFilterManager
{
50 /** Preference key for by default disabled filters. */
51 private static final String BY_DEFAULT_DISABLED_FILTER
= "org.eclipse.emf.compare.rcp.ui.filters.disabled"; //$NON-NLS-1$
53 /** A map that associates the class name to theirs {@link IDifferenceFilter}s. */
54 private final Map
<String
, DifferenceFilterDefaultConfiguration
> map
;
56 /** The {@link Preferences} holding the value for filter preferences. */
57 private final Preferences preferenceStore
;
59 /** Predicate use to transform {@link DifferenceFilterDefaultConfiguration} to {@link IDifferenceFilter}. */
60 private final static Function
<DifferenceFilterDefaultConfiguration
, IDifferenceFilter
> TO_FILTER
= new Function
<DifferenceFilterManager
.DifferenceFilterDefaultConfiguration
, IDifferenceFilter
>() {
62 public IDifferenceFilter
apply(DifferenceFilterDefaultConfiguration arg0
) {
64 return arg0
.getFilter();
73 * @param preferenceStore
74 * The {@link Preferences} holding the value for filter preferences.
76 public DifferenceFilterManager(Preferences preferenceStore
) {
77 map
= Collections
.synchronizedMap(new LinkedHashMap
<String
, DifferenceFilterDefaultConfiguration
>());
78 this.preferenceStore
= preferenceStore
;
85 * {@link IDifferenceFilter}
86 * @return The old {@link IDifferenceFilter} register with the same key.
88 IDifferenceFilter
add(IDifferenceFilter filter
) {
89 Preconditions
.checkNotNull(filter
);
90 DifferenceFilterDefaultConfiguration oldValue
= map
.put(filter
.getClass().getName(),
91 new DifferenceFilterDefaultConfiguration(filter
, filter
.defaultSelected()));
92 if (oldValue
!= null) {
93 return oldValue
.getFilter();
102 * The class name of the filter.
103 * @return The {@link IDifferenceFilter} that has been removed or <code>null</code> if none.
105 IDifferenceFilter
remove(String className
) {
106 DifferenceFilterDefaultConfiguration oldValue
= map
.remove(className
);
107 if (oldValue
!= null) {
108 return oldValue
.getFilter();
114 * Get all {@link IDifferenceFilter} that shall be used by default for next comparison.
116 * @return A {@link Set} of {@link IDifferenceFilter} that shall be used by default for next comparison.
118 public Set
<IDifferenceFilter
> getCurrentByDefaultFilters() {
119 Set
<IDifferenceFilter
> storedFilter
= getDisabledFilters();
120 if (storedFilter
== null) {
121 return getInitialByDefaultFilters();
123 return Sets
.difference(getAllFilters(), storedFilter
);
127 * {@link Set} of {@link IDifferenceFilter} that are initially activated by default.
129 * During the first addiction in the registry of these {@link IDifferenceFilter},
130 * {@link IDifferenceFilter#defaultSelected()} was equal to true
133 * @return {@link Set} of {@link IDifferenceFilter} that are original activated by default.
135 public Set
<IDifferenceFilter
> getInitialByDefaultFilters() {
136 Collection
<DifferenceFilterDefaultConfiguration
> enableFilter
= Collections2
.filter(map
.values(),
137 new Predicate
<DifferenceFilterDefaultConfiguration
>() {
139 public boolean apply(DifferenceFilterDefaultConfiguration arg0
) {
140 return arg0
.isDefaultSelectedInitialValue();
143 return Sets
.newLinkedHashSet(Collections2
.transform(enableFilter
, TO_FILTER
));
147 * Set filters that shall be used by default for next comparison.
149 * @param enabledFilter
150 * {@link Set} of {@link IDifferenceFilter} to set.
152 public void setCurrentByDefaultFilters(Set
<IDifferenceFilter
> enabledFilter
) {
153 final Set
<IDifferenceFilter
> disableFilter
;
154 if (enabledFilter
== null) {
155 disableFilter
= getAllFilters();
157 disableFilter
= Sets
.difference(getAllFilters(), enabledFilter
);
159 SetView
<IDifferenceFilter
> initialDisabledFilter
= Sets
.difference(getAllFilters(),
160 getInitialByDefaultFilters());
161 storeInPreferences(disableFilter
, initialDisabledFilter
);
162 // Trace preferences values
163 if (TracingConstant
.CONFIGURATION_TRACING_ACTIVATED
) {
164 StringBuilder builder
= new StringBuilder();
165 // Print each preferences
166 builder
.append("Preference ").append(BY_DEFAULT_DISABLED_FILTER
).append(":\n"); //$NON-NLS-1$ //$NON-NLS-2$
167 String preferenceValue
= preferenceStore
.get(BY_DEFAULT_DISABLED_FILTER
, ""); //$NON-NLS-1$
168 String
[] groups
= preferenceValue
.split(ItemUtil
.PREFERENCE_DELIMITER
);
169 for (int rank
= 0; rank
< groups
.length
; rank
++) {
170 builder
.append(rank
).append(". ").append(groups
[rank
]).append("\n"); //$NON-NLS-1$ //$NON-NLS-2$
172 builder
.append("\n\n"); //$NON-NLS-1$
173 EMFCompareRCPUIPlugin
.getDefault().log(IStatus
.INFO
, builder
.toString());
178 * Get all registered filter.
180 * @return {@link Set} of all filter.
182 public Set
<IDifferenceFilter
> getAllFilters() {
183 return Sets
.newLinkedHashSet(Collections2
.transform(map
.values(), TO_FILTER
));
187 * A {@link Set} of disabled by default {@link IDifferenceFilter} from preferences.
189 * Those filter will not be activated by default for next comparison
192 * @return A {@link Set} of disabled by default {@link IDifferenceFilter} from preferences.
194 private Set
<IDifferenceFilter
> getDisabledFilters() {
195 String diffEngineKey
= preferenceStore
.get(BY_DEFAULT_DISABLED_FILTER
, null);
196 Set
<IDifferenceFilter
> result
= null;
197 if (diffEngineKey
!= null) {
198 String
[] diffEngineKeys
= diffEngineKey
.split(ItemUtil
.PREFERENCE_DELIMITER
);
199 for (String nonTrimedKey
: diffEngineKeys
) {
200 String key
= nonTrimedKey
.trim();
201 DifferenceFilterDefaultConfiguration descriptor
= map
.get(key
);
202 if (descriptor
!= null) {
203 if (result
== null) {
204 result
= new LinkedHashSet
<IDifferenceFilter
>();
206 result
.add(descriptor
.getFilter());
214 * Store value in preferences.
216 * @param currentValue
221 private void storeInPreferences(Set
<IDifferenceFilter
> currentValue
, Set
<IDifferenceFilter
> defaultConf
) {
222 if (currentValue
!= null && !currentValue
.equals(defaultConf
)) {
223 Map
<String
, IDifferenceFilter
> toStore
= Maps
.filterValues(Maps
.transformValues(map
, TO_FILTER
),
224 Predicates
.in(currentValue
));
225 String preferenceValue
= Joiner
.on(ItemUtil
.PREFERENCE_DELIMITER
).join(toStore
.keySet());
226 preferenceStore
.put(BY_DEFAULT_DISABLED_FILTER
, preferenceValue
);
228 preferenceStore
.remove(BY_DEFAULT_DISABLED_FILTER
);
233 * Clear all registered {@link IDifferenceFilter}.
235 public void clear() {
240 * Wrapper of {@link IDifferenceFilter} used to keep track of the initial value of
241 * {@link IDifferenceFilter#defaultSelected()} to be able to restore it.
243 * @author <a href="mailto:arthur.daussy@obeo.fr">Arthur Daussy</a>
245 private static class DifferenceFilterDefaultConfiguration
{
247 /** Base {@link IDifferenceFilter} */
248 private IDifferenceFilter filter
;
250 /** Initial value of {@link IDifferenceFilter#defaultSelected()} during first addition. */
251 private boolean isDefaultSelectedInitialValue
;
258 * @param isByDefaultSelected
259 * Initial value of {@link IDifferenceFilter#defaultSelected()} during first addition.
261 public DifferenceFilterDefaultConfiguration(IDifferenceFilter filter
, boolean isByDefaultSelected
) {
263 this.filter
= filter
;
264 this.isDefaultSelectedInitialValue
= isByDefaultSelected
;
268 * @return Base filter.
270 public IDifferenceFilter
getFilter() {
275 * @return Initial value of {@link IDifferenceFilter#defaultSelected()} during first addition.
277 public boolean isDefaultSelectedInitialValue() {
278 return isDefaultSelectedInitialValue
;