/******************************************************************************* * Copyright (c) 2016 itemis AG 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 * * Contributors: * Tamas Miklossy (itemis AG) - initial API and implementation (bug #498324) *******************************************************************************/ package org.eclipse.gef.dot.internal.ui.language.contentassist; import java.io.InputStream; import java.util.ArrayList; import java.util.List; import org.eclipse.emf.common.util.URI; import org.eclipse.emf.ecore.util.EcoreUtil; import org.eclipse.gef.dot.internal.ui.language.internal.DotActivator; import org.eclipse.jface.text.BadLocationException; import org.eclipse.jface.text.contentassist.ICompletionProposal; import org.eclipse.jface.text.contentassist.IContentAssistProcessor; import org.eclipse.jface.text.contentassist.IContentAssistant; import org.eclipse.jface.text.source.ISourceViewer; import org.eclipse.swt.widgets.Shell; import org.eclipse.xtext.linking.lazy.LazyLinkingResource; import org.eclipse.xtext.resource.IResourceFactory; import org.eclipse.xtext.resource.XtextResource; import org.eclipse.xtext.resource.XtextResourceSet; import org.eclipse.xtext.ui.editor.XtextSourceViewer; import org.eclipse.xtext.ui.editor.XtextSourceViewerConfiguration; import org.eclipse.xtext.ui.editor.contentassist.ConfigurableCompletionProposal; import org.eclipse.xtext.ui.editor.model.DocumentPartitioner; import org.eclipse.xtext.ui.editor.model.IXtextDocument; import org.eclipse.xtext.ui.editor.model.XtextDocument; import org.eclipse.xtext.util.CancelIndicator; import org.eclipse.xtext.util.StringInputStream; import org.eclipse.xtext.util.Strings; import com.google.inject.Injector; /** * The implementation of this class is mainly taken from the * org.eclipse.xtext.junit4.ui.ContentAssistProcessorTestBuilder java class. * * @author miklossy * */ public class DotProposalProviderDelegator { private Injector injector; public DotProposalProviderDelegator(String language) { injector = DotActivator.getInstance().getInjector(language); } /** * Computes the configurable completion proposals considering the given text * and the given cursorPosition. * * @param text * The current text to parse. * @param cursorPosition * The cursor position within the given text. * @return The configurable completion proposals valid on the given cursor * position within the given text. Returns an empty list if the * proposals cannot be determined. */ public List<ConfigurableCompletionProposal> computeConfigurableCompletionProposals( final String text, int cursorPosition) { List<ConfigurableCompletionProposal> configurableCompletionProposal = new ArrayList<>(); ICompletionProposal[] completionProposals = {}; try { completionProposals = computeCompletionProposals(text, cursorPosition); } catch (Exception e) { e.printStackTrace(); } // convert the completionProposals into configurableCompletionProposals for (ICompletionProposal completionProposal : completionProposals) { if (completionProposal instanceof ConfigurableCompletionProposal) { configurableCompletionProposal.add( (ConfigurableCompletionProposal) completionProposal); } } return configurableCompletionProposal; } private ICompletionProposal[] computeCompletionProposals( final String currentModelToParse, int cursorPosition) throws Exception { final IXtextDocument xtextDocument = getDocument(currentModelToParse); return computeCompletionProposals(xtextDocument, cursorPosition); } private ICompletionProposal[] computeCompletionProposals( final IXtextDocument xtextDocument, int cursorPosition) throws BadLocationException { Shell shell = new Shell(); try { return computeCompletionProposals(xtextDocument, cursorPosition, shell); } finally { shell.dispose(); } } private ICompletionProposal[] computeCompletionProposals( final IXtextDocument xtextDocument, int cursorPosition, Shell shell) throws BadLocationException { XtextSourceViewerConfiguration configuration = get( XtextSourceViewerConfiguration.class); ISourceViewer sourceViewer = getSourceViewer(shell, xtextDocument, configuration); return computeCompletionProposals(xtextDocument, cursorPosition, configuration, sourceViewer); } private ICompletionProposal[] computeCompletionProposals( final IXtextDocument xtextDocument, int cursorPosition, XtextSourceViewerConfiguration configuration, ISourceViewer sourceViewer) throws BadLocationException { IContentAssistant contentAssistant = configuration .getContentAssistant(sourceViewer); String contentType = xtextDocument.getContentType(cursorPosition); IContentAssistProcessor processor = contentAssistant .getContentAssistProcessor(contentType); if (processor != null) { return processor.computeCompletionProposals(sourceViewer, cursorPosition); } return new ICompletionProposal[0]; } private IXtextDocument getDocument(final String currentModelToParse) throws Exception { XtextResource xtextResource = doGetResource( new StringInputStream(Strings.emptyIfNull(currentModelToParse)), URI.createURI("dummy:/example.mydsl")); //$NON-NLS-1$ return getDocument(xtextResource, currentModelToParse); } private IXtextDocument getDocument(final XtextResource xtextResource, final String model) { XtextDocument document = get(XtextDocument.class); document.set(model); document.setInput(xtextResource); DocumentPartitioner partitioner = get(DocumentPartitioner.class); partitioner.connect(document); document.setDocumentPartitioner(partitioner); return document; } private <T> T get(Class<T> clazz) { return injector.getInstance(clazz); } private ISourceViewer getSourceViewer(Shell shell, final IXtextDocument xtextDocument, XtextSourceViewerConfiguration configuration) { XtextSourceViewer.Factory factory = get( XtextSourceViewer.Factory.class); ISourceViewer sourceViewer = factory.createSourceViewer(shell, null, null, false, 0); sourceViewer.configure(configuration); sourceViewer.setDocument(xtextDocument); return sourceViewer; } private XtextResource doGetResource(InputStream in, URI uri) throws Exception { XtextResourceSet rs = get(XtextResourceSet.class); rs.setClasspathURIContext(getClass()); XtextResource resource = (XtextResource) getResourceFactory() .createResource(uri); rs.getResources().add(resource); resource.load(in, null); if (resource instanceof LazyLinkingResource) { ((LazyLinkingResource) resource) .resolveLazyCrossReferences(CancelIndicator.NullImpl); } else { EcoreUtil.resolveAll(resource); } return resource; } private IResourceFactory getResourceFactory() { return injector.getInstance(IResourceFactory.class); } }