/*******************************************************************************
* Copyright (c) 2015 Pivotal, Inc.
* 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:
* Pivotal, Inc. - initial API and implementation
*******************************************************************************/
package org.springframework.ide.eclipse.boot.dash.views.sections;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.regex.Pattern;
import org.eclipse.jface.fieldassist.IContentProposal;
import org.eclipse.jface.fieldassist.IContentProposalProvider;
import org.springframework.ide.eclipse.boot.dash.model.BootDashElement;
import org.springframework.ide.eclipse.boot.dash.model.BootDashModel;
import org.springframework.ide.eclipse.boot.dash.model.BootDashViewModel;
import org.springframework.ide.eclipse.boot.dash.model.TagUtils;
import org.springframework.ide.eclipse.editor.support.util.FuzzyMatcher;
/**
* Provider for tags content proposals
*
* @author Alex Boyko
*
*/
public class TagContentProposalProvider implements IContentProposalProvider {
private BootDashViewModel model;
public TagContentProposalProvider(BootDashViewModel model) {
this.model = model;
}
private Set<String> getAllTags() {
HashSet<String> tags = new HashSet<String>();
for (BootDashModel sectionModel : model.getSectionModels().getValue()) {
for (BootDashElement element : sectionModel.getElements().getValue()) {
tags.addAll(element.getTags());
}
}
return tags;
}
@Override
public IContentProposal[] getProposals(String contents, int position) {
Set<String> allTags = getAllTags();
int startPosition = getCurrentTagStartPosition(contents, position);
int endPosition = getCurrentTagEndPosition(contents, position);
String pattern = contents.substring(startPosition, position);
String tagUnderCursor = contents.substring(startPosition, endPosition);
HashSet<String> currentTags = new HashSet<String>(Arrays.asList(TagUtils.parseTags(contents)));
if (pattern.equals(tagUnderCursor)) {
currentTags.remove(tagUnderCursor);
}
allTags.removeAll(currentTags);
List<IContentProposal> proposals = new ArrayList<IContentProposal>(allTags.size());
for (String tag : allTags) {
if (FuzzyMatcher.matchScore(pattern, tag) != 0) {
proposals.add(tagProposal(tag, applyProposal(contents, tag, startPosition, position), startPosition + tag.length()));
}
}
return proposals.toArray(new IContentProposal[proposals.size()]);
}
private static int getCurrentTagStartPosition(String content, int position) {
int i = position - 1;
for (; i >= 0 && content.charAt(i) != TagUtils.SEPARATOR_SYMBOL; i--);
i++;
for (; i < content.length() && Pattern.matches("\\s", "" + content.charAt(i)); i++);
return i;
}
private static int getCurrentTagEndPosition(String content, int position) {
int i = position;
for (; i < content.length() && content.charAt(i) != TagUtils.SEPARATOR_SYMBOL; i++);
for (; i > position && Pattern.matches("\\s", "" + content.charAt(i - 1)); i--);
return i;
}
private static String applyProposal(String content, String proposal, int start, int end) {
StringBuilder sb = new StringBuilder(start + proposal.length() + content.length() - end);
sb.append(content.substring(0, start));
sb.append(proposal);
sb.append(content.substring(end));
return sb.toString();
}
private IContentProposal tagProposal(final String label, final String newContent, final int cursorPosition) {
return new IContentProposal() {
@Override
public String getLabel() {
return label;
}
@Override
public String getDescription() {
return null;
}
@Override
public int getCursorPosition() {
return cursorPosition;
}
@Override
public String getContent() {
return newContent;
}
};
}
}