/** * Copyright (c) 2010, 2014 Darmstadt University of Technology. * 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: * Johannes Dorn - initial API and implementation. */ package org.eclipse.recommenders.internal.completion.rcp; import java.util.Collection; import java.util.Iterator; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import javax.inject.Inject; import org.apache.commons.lang3.StringUtils; import org.eclipse.core.runtime.IConfigurationElement; import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer; import org.eclipse.core.runtime.preferences.InstanceScope; import org.eclipse.e4.core.di.extensions.Preference; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.recommenders.completion.rcp.processable.SessionProcessorDescriptor; import org.eclipse.ui.preferences.ScopedPreferenceStore; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Function; import com.google.common.base.Predicate; import com.google.common.collect.Maps; import com.google.common.collect.Sets; @SuppressWarnings("restriction") public class CompletionRcpPreferences extends AbstractPreferenceInitializer { private static final char DISABLED_FLAG = '!'; private static final char SEPARATOR = ';'; @Inject @Preference(Constants.PREF_SESSIONPROCESSORS) private String enabledSessionProcessorString; private final Set<SessionProcessorDescriptor> availableProcessors; public CompletionRcpPreferences() { this(readExtensionPoint()); } @VisibleForTesting public CompletionRcpPreferences(Set<SessionProcessorDescriptor> availableProcessors) { this.availableProcessors = availableProcessors; } private static Set<SessionProcessorDescriptor> readExtensionPoint() { IConfigurationElement[] elements = Platform.getExtensionRegistry().getConfigurationElementsFor( Constants.EXT_POINT_SESSION_PROCESSORS); Set<SessionProcessorDescriptor> descriptors = Sets.newHashSet(); for (final IConfigurationElement element : elements) { SessionProcessorDescriptor descriptor = new SessionProcessorDescriptor(element); descriptors.add(descriptor); } return descriptors; } @Override public void initializeDefaultPreferences() { // Due to reentrant-injection trouble, this method is *not* called on the singleton provided by // CompletionRcpModule. Thus, treat it as if called in a static context; do not write/read instance fields. IPreferenceStore store = new ScopedPreferenceStore(InstanceScope.INSTANCE, Constants.BUNDLE_NAME); store.setDefault(Constants.PREF_SESSIONPROCESSORS, toString(Maps.asMap(availableProcessors, new Function<SessionProcessorDescriptor, Boolean>() { @Override public Boolean apply(SessionProcessorDescriptor descriptor) { return descriptor.isEnabledByDefault(); } }))); } public Set<SessionProcessorDescriptor> getAvailableSessionProcessors() { return availableProcessors; } public Set<SessionProcessorDescriptor> getEnabledSessionProcessors() { return Maps.filterValues(fromString(availableProcessors, enabledSessionProcessorString), new Predicate<Boolean>() { @Override public boolean apply(Boolean input) { return input; } }).keySet(); } public SessionProcessorDescriptor getSessionProcessorDescriptor(String id) { return find(availableProcessors, id); } public void setSessionProcessorEnabled(Collection<SessionProcessorDescriptor> enabledDescriptors, Collection<SessionProcessorDescriptor> disabledDescriptors) { Map<SessionProcessorDescriptor, Boolean> result = fromString(availableProcessors, enabledSessionProcessorString); for (SessionProcessorDescriptor enabledDescriptor : enabledDescriptors) { result.put(enabledDescriptor, true); } for (SessionProcessorDescriptor disabledDescriptor : disabledDescriptors) { result.put(disabledDescriptor, false); } IPreferenceStore store = new ScopedPreferenceStore(InstanceScope.INSTANCE, Constants.BUNDLE_NAME); store.setValue(Constants.PREF_SESSIONPROCESSORS, toString(result)); } public boolean isEnabled(SessionProcessorDescriptor processor) { Map<SessionProcessorDescriptor, Boolean> map = fromString(availableProcessors, enabledSessionProcessorString); return map.containsKey(processor) ? map.get(processor) : false; } private static String toString(Map<SessionProcessorDescriptor, Boolean> descriptors) { StringBuilder sb = new StringBuilder(); Iterator<Entry<SessionProcessorDescriptor, Boolean>> it = descriptors.entrySet().iterator(); while (it.hasNext()) { Entry<SessionProcessorDescriptor, Boolean> entry = it.next(); SessionProcessorDescriptor descriptor = entry.getKey(); Boolean enabled = entry.getValue(); if (!enabled) { sb.append(DISABLED_FLAG); } sb.append(descriptor.getId()); if (it.hasNext()) { sb.append(SEPARATOR); } } return sb.toString(); } private static Map<SessionProcessorDescriptor, Boolean> fromString( Iterable<SessionProcessorDescriptor> descriptors, String string) { Map<SessionProcessorDescriptor, Boolean> result = Maps.newHashMap(); for (SessionProcessorDescriptor descriptor : descriptors) { result.put(descriptor, true); } for (String id : StringUtils.split(string, SEPARATOR)) { final boolean enabled; if (id.charAt(0) == DISABLED_FLAG) { enabled = false; id = id.substring(1); } else { enabled = true; } SessionProcessorDescriptor found = find(descriptors, id); if (found != null) { result.put(found, enabled); } } return result; } private static SessionProcessorDescriptor find(Iterable<SessionProcessorDescriptor> descriptors, String id) { for (SessionProcessorDescriptor descriptor : descriptors) { if (descriptor.getId().equals(id)) { return descriptor; } } return null; } @VisibleForTesting public void setEnabledSessionProcessorString(String enabledSessionProcessorString) { this.enabledSessionProcessorString = enabledSessionProcessorString; } }