/*******************************************************************************
* Copyright (c) 2009, 2010 Innovation Gate GmbH.
* 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:
* Innovation Gate GmbH - initial API and implementation
******************************************************************************/
package de.innovationgate.eclipse.editors.tml;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.ITypedRegion;
import org.eclipse.jface.text.contentassist.CompletionProposal;
import org.eclipse.jface.text.contentassist.ICompletionProposal;
import org.eclipse.jface.text.contentassist.IContentAssistProcessor;
import org.eclipse.jface.text.contentassist.IContextInformation;
import org.eclipse.jface.text.contentassist.IContextInformationValidator;
import de.innovationgate.eclipse.editors.helpers.CompletionProposalComparator;
/**
* create content assist proposals for tml comment partitions
*
*
*/
public class CloseTagContentAssistProcessor implements IContentAssistProcessor {
private String _errorMessage;
public CloseTagContentAssistProcessor() {
}
public ICompletionProposal[] computeCompletionProposals(ITextViewer viewer, int offset) {
setErrorMessage(null);
List<ICompletionProposal> proposals = new ArrayList<ICompletionProposal>();
try {
IDocument document = viewer.getDocument();
IRegion region = TMLContentAssistProcessor.determineRelatedRegion(offset, document);
if (isOpenPartition(region, document, "<tml:comment>", "</tml:comment>", TMLPartitionScanner.TML_COMMENT)) {
proposals.addAll(computeCompletionPropsals(document, region, offset, "<tml:comment>", "</tml:comment>"));
} else if (isOpenPartition(region, document, "<tml:disable>", "</tml:disable>", TMLPartitionScanner.TML_DISABLE)) {
proposals.addAll(computeCompletionPropsals(document, region, offset, "<tml:disable>", "</tml:disable>"));
} else {
proposals.addAll(TMLRegion.computeCloseTagProposals(document, offset));
}
} catch (BadLocationException e) {
setErrorMessage(e.getMessage());
}
Collections.sort(proposals, new CompletionProposalComparator());
return proposals.toArray(new ICompletionProposal[0]);
}
private boolean isOpenPartition(IRegion region, IDocument document, String start, String end, String type) throws BadLocationException {
ITypedRegion previousPartition = document.getPartition(region.getOffset() - 1);
// check if tml comment partition is open
String content = document.get(region.getOffset(), region.getLength());
if (!content.trim().endsWith(end) && content.trim().startsWith(start) ) {
return true;
}
return false;
}
private List<ICompletionProposal> computeCompletionPropsals(IDocument document, IRegion region, int offset, String start, String end) throws BadLocationException {
List<ICompletionProposal> proposals = new ArrayList<ICompletionProposal>();
String replacement = end;
if (!document.get(region.getOffset(), region.getLength()).endsWith(replacement)) {
String alreadyTyped = document.get(region.getOffset(), offset-region.getOffset());
if (alreadyTyped.contains("\n")) {
alreadyTyped = alreadyTyped.substring(alreadyTyped.lastIndexOf("\n"));
}
if (alreadyTyped.trim().startsWith(start)) {
alreadyTyped = alreadyTyped.substring(alreadyTyped.indexOf(start) + start.length());
}
boolean checkReplacementStart = false;
int endOfTypedTagBody = alreadyTyped.lastIndexOf("<");
int completionStartPos = -1;
if (endOfTypedTagBody != -1) {
alreadyTyped = alreadyTyped.substring(endOfTypedTagBody);
completionStartPos = offset - alreadyTyped.length();
checkReplacementStart = true;
} else {
checkReplacementStart = false;
completionStartPos = offset;
}
ICompletionProposal proposal = new CompletionProposal(replacement, completionStartPos, offset - completionStartPos, replacement.length());
if (checkReplacementStart) {
if (replacement.startsWith(alreadyTyped)) {
proposals.add(proposal);
}
} else {
proposals.add(proposal);
}
}
return proposals;
}
private void setErrorMessage(String message) {
_errorMessage = message;
}
public IContextInformation[] computeContextInformation(ITextViewer viewer,
int offset) {
return null;
}
public char[] getCompletionProposalAutoActivationCharacters() {
return null; //new char[] { '<' };
}
public char[] getContextInformationAutoActivationCharacters() {
return null;
}
public IContextInformationValidator getContextInformationValidator() {
return null;
}
public String getErrorMessage() {
return _errorMessage;
}
}