| /******************************************************************************* |
| * Copyright (c) 2008 Standards for Technology in Automotive Retail and others. |
| * 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 |
| * |
| * Based on org.eclipse.wst.xml.ui.internal.contentassist.XMLTemplateCompletionProcessor |
| * Contributors: |
| * David Carver - STAR - bug 213849 - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.wst.xsl.ui.internal.contentassist; |
| |
| |
| //import java.util.Comparator; |
| import java.util.ArrayList; |
| import java.util.Collections; |
| import java.util.Comparator; |
| import java.util.List; |
| |
| import org.eclipse.jface.text.IDocument; |
| import org.eclipse.jface.text.IRegion; |
| import org.eclipse.jface.text.ITextSelection; |
| import org.eclipse.jface.text.Region; |
| |
| import org.eclipse.jface.text.ITextViewer; |
| import org.eclipse.jface.text.contentassist.ICompletionProposal; |
| import org.eclipse.jface.text.templates.ContextTypeRegistry; |
| import org.eclipse.jface.text.templates.Template; |
| import org.eclipse.jface.text.templates.TemplateCompletionProcessor; |
| import org.eclipse.jface.text.templates.TemplateContext; |
| import org.eclipse.jface.text.templates.TemplateContextType; |
| import org.eclipse.jface.text.templates.TemplateException; |
| import org.eclipse.jface.text.templates.TemplateProposal; |
| import org.eclipse.jface.text.templates.persistence.TemplateStore; |
| import org.eclipse.swt.graphics.Image; |
| import org.eclipse.wst.xml.ui.internal.contentassist.ReplaceNameTemplateContext; |
| import org.eclipse.wst.xsl.ui.internal.XSLUIPlugin; |
| import org.eclipse.wst.xsl.ui.internal.templates.TemplateContextTypeIdsXPath; |
| import org.eclipse.wst.xsl.ui.internal.util.XSLPluginImageHelper; |
| import org.eclipse.wst.xsl.ui.internal.util.XSLPluginImages; |
| |
| |
| /** |
| * Completion processor for XPath Templates. Most of the work is already done by |
| * the XSL Content Assist processor, so by the time the |
| * XPathTemplateCompletionProcessor is asked for content assist proposals, the |
| * XSL content assist processor has already set the context type for |
| * templates. |
| * |
| * @see org.eclipse.wst.xml.ui. |
| * @since 0.5M6 |
| */ |
| class XPathTemplateCompletionProcessor extends TemplateCompletionProcessor { |
| @SuppressWarnings("unchecked") |
| private static final class ProposalComparator implements Comparator { |
| public int compare(Object o1, Object o2) { |
| return ((TemplateProposal) o2).getRelevance() - ((TemplateProposal) o1).getRelevance(); |
| } |
| } |
| |
| private String fContextTypeId = null; |
| @SuppressWarnings("unchecked") |
| private static final Comparator fgProposalComparator= new ProposalComparator(); |
| |
| |
| protected ICompletionProposal createProposal(Template template, TemplateContext context, IRegion region, int relevance) { |
| return new XPathCustomTemplateProposal(template, context, region, getImage(template), relevance); |
| } |
| |
| protected TemplateContextType getContextType(ITextViewer viewer, IRegion region) { |
| TemplateContextType type = null; |
| |
| ContextTypeRegistry registry = getTemplateContextRegistry(); |
| if (registry != null) { |
| type = registry.getContextType(fContextTypeId); |
| } |
| |
| return type; |
| } |
| |
| protected Image getImage(Template template) { |
| // just return the same image for now |
| Image returnImage = null; |
| if (TemplateContextTypeIdsXPath.AXIS.equals(template.getContextTypeId())) { |
| returnImage = XSLPluginImageHelper.getInstance().getImage(XSLPluginImages.IMG_XPATH_AXIS); |
| } else if (TemplateContextTypeIdsXPath.XPATH.equals(template.getContextTypeId())) { |
| returnImage = XSLPluginImageHelper.getInstance().getImage(XSLPluginImages.IMG_XPATH_FUNCTION); |
| } else if (TemplateContextTypeIdsXPath.OPERATOR.equals(template.getContextTypeId())) { |
| returnImage = XSLPluginImageHelper.getInstance().getImage(XSLPluginImages.IMG_OPERATOR); |
| } |
| return returnImage; |
| } |
| |
| private ContextTypeRegistry getTemplateContextRegistry() { |
| return XSLUIPlugin.getDefault().getTemplateContextRegistry(); |
| } |
| |
| protected Template[] getTemplates(String contextTypeId) { |
| Template templates[] = null; |
| |
| TemplateStore store = getTemplateStore(); |
| if (store != null) { |
| templates = store.getTemplates(contextTypeId); |
| } |
| |
| return templates; |
| } |
| |
| private TemplateStore getTemplateStore() { |
| return XSLUIPlugin.getDefault().getTemplateStore(); |
| } |
| |
| void setContextType(String contextTypeId) { |
| fContextTypeId = contextTypeId; |
| } |
| |
| /* |
| * @see org.eclipse.jface.text.contentassist.IContentAssistProcessor#computeCompletionProposals(org.eclipse.jface.text.ITextViewer, |
| * int) |
| */ |
| @SuppressWarnings("unchecked") |
| @Override |
| public ICompletionProposal[] computeCompletionProposals(ITextViewer viewer, int offset) { |
| |
| ITextSelection selection= (ITextSelection) viewer.getSelectionProvider().getSelection(); |
| |
| // adjust offset to end of normalized selection |
| if (selection.getOffset() == offset) |
| offset= selection.getOffset() + selection.getLength(); |
| |
| String prefix= extractPrefix(viewer, offset); |
| Region region= new Region(offset - prefix.length(), prefix.length()); |
| TemplateContext context = createContext(viewer, region, offset); |
| if (context == null) |
| return new ICompletionProposal[0]; |
| |
| context.setVariable("selection", selection.getText()); // name of the selection variables {line, word}_selection //$NON-NLS-1$ |
| |
| Template[] templates= getTemplates(context.getContextType().getId()); |
| |
| List matches= new ArrayList(); |
| for (int i= 0; i < templates.length; i++) { |
| Template template= templates[i]; |
| try { |
| context.getContextType().validate(template.getPattern()); |
| } catch (TemplateException e) { |
| continue; |
| } |
| if (template.matches(prefix, context.getContextType().getId())) |
| matches.add(createProposal(template, context, (IRegion) region, getRelevance(template, prefix))); |
| } |
| |
| Collections.sort(matches, fgProposalComparator); |
| |
| return (ICompletionProposal[]) matches.toArray(new ICompletionProposal[matches.size()]); |
| } |
| |
| /** |
| * Creates a concrete template context for the given region in the |
| * document. This involves finding out which context type is valid at the |
| * given location, and then creating a context of this type. The default |
| * implementation returns a <code>SmartReplaceTemplateContext</code> for |
| * the context type at the given location. This takes the offset at which |
| * content assist was invoked into consideration. |
| * |
| * @param viewer |
| * the viewer for which the context is created |
| * @param region |
| * the region into <code>document</code> for which the |
| * context is created |
| * @param offset |
| * the original offset where content assist was invoked |
| * @return a template context that can handle template insertion at the |
| * given location, or <code>null</code> |
| */ |
| private TemplateContext createContext(ITextViewer viewer, IRegion region, int offset) { |
| // pretty much same code as super.createContext except create |
| // SmartReplaceTemplateContext |
| TemplateContextType contextType = getContextType(viewer, region); |
| if (contextType != null) { |
| IDocument document = viewer.getDocument(); |
| return new ReplaceNameTemplateContext(contextType, document, region.getOffset(), region.getLength(), offset); |
| } |
| return null; |
| } |
| |
| // /** |
| // * |
| // * @see org.eclipse.jface.text.contentassist.IContentAssistProcessor#getCompletionProposalAutoActivationCharacters() |
| // */ |
| // @Override |
| // public char[] getCompletionProposalAutoActivationCharacters() { |
| // char apostrophe = '\''; |
| // char quote = '"'; |
| // char[] autoProposal = {apostrophe, quote}; |
| // return autoProposal; |
| // } |
| |
| |
| } |