/** * 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: * Andreas Sewe - initial API and implementation. */ package org.eclipse.recommenders.internal.completion.rcp.tips; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IConfigurationElement; import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.preferences.IEclipsePreferences; import org.eclipse.core.runtime.preferences.InstanceScope; import org.eclipse.jface.text.contentassist.ICompletionProposal; import org.eclipse.recommenders.completion.rcp.IRecommendersCompletionContext; import org.eclipse.recommenders.completion.rcp.processable.SessionProcessor; import org.eclipse.recommenders.completion.rcp.tips.ICompletionTipProposal; import org.eclipse.recommenders.internal.completion.rcp.Constants; import org.eclipse.recommenders.internal.completion.rcp.l10n.LogMessages; import org.eclipse.recommenders.utils.Logs; import org.osgi.service.prefs.BackingStoreException; import com.google.common.base.Joiner; import com.google.common.base.Predicate; import com.google.common.base.Splitter; import com.google.common.collect.Collections2; import com.google.common.collect.Sets; public class TipsSessionProcessor extends SessionProcessor { private static final String PREF_NODE_ID_TIPS = "org.eclipse.recommenders.completion.rcp"; //$NON-NLS-1$ private static final String SEEN = "completion_tips_seen"; //$NON-NLS-1$ private static final String COMPLETION_TIP_ID = "id"; //$NON-NLS-1$ private static final String COMPLETION_TIP_CLASS = "class"; //$NON-NLS-1$ private final Map<ICompletionTipProposal, String> unseenTips = new HashMap<>(); private final Set<String> seenTips; private IRecommendersCompletionContext context; private boolean tipsSeen; public TipsSessionProcessor() { final IConfigurationElement[] elements = Platform.getExtensionRegistry() .getConfigurationElementsFor(Constants.EXT_POINT_COMPLETION_TIPS); Iterable<String> split = Splitter.on(':').omitEmptyStrings().split(getTipsPreferences().get(SEEN, "")); //$NON-NLS-1$ seenTips = Sets.newHashSet(split); for (final IConfigurationElement element : elements) { String id = element.getAttribute(COMPLETION_TIP_ID); if (!seenTips.contains(id)) { try { ICompletionTipProposal proposal = (ICompletionTipProposal) element .createExecutableExtension(COMPLETION_TIP_CLASS); unseenTips.put(proposal, id); } catch (CoreException e) { Logs.log(LogMessages.ERROR_FAILED_TO_INSTANTIATE_COMPLETION_TIP, e); } } } } @Override public boolean startSession(IRecommendersCompletionContext context) { this.context = context; if (unseenTips.isEmpty()) { return false; } if (preventsAutoComplete(context)) { return false; } for (ICompletionTipProposal tip : unseenTips.keySet()) { tip.setInvocationOffset(context.getInvocationOffset()); } return true; } private boolean preventsAutoComplete(IRecommendersCompletionContext context) { return context.getProposals().size() <= 1; } @Override public void endSession(List<ICompletionProposal> proposals) { proposals.addAll(Collections2.filter(unseenTips.keySet(), new Predicate<ICompletionTipProposal>() { @Override public boolean apply(ICompletionTipProposal input) { return input.isApplicable(context); } })); tipsSeen = false; } @Override public void selected(ICompletionProposal proposal) { if (unseenTips.containsKey(proposal)) { String id = unseenTips.remove(proposal); seenTips.add(id); tipsSeen = true; } } @Override public void aboutToClose() { if (tipsSeen) { persistSeenTips(seenTips); } } private static void persistSeenTips(Set<String> seenTips) { String joined = Joiner.on(':').join(seenTips); IEclipsePreferences store = getTipsPreferences(); store.put(SEEN, joined); try { store.flush(); } catch (BackingStoreException e) { Logs.log(LogMessages.ERROR_FAILED_TO_FLUSH_PREFERENCES, e); } } private static IEclipsePreferences getTipsPreferences() { return InstanceScope.INSTANCE.getNode(PREF_NODE_ID_TIPS); } }