/******************************************************************************* * Copyright (c) 2006, 2008 Spring IDE Developers * 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: * Spring IDE Developers - initial API and implementation *******************************************************************************/ package org.springframework.ide.eclipse.beans.ui.editor.contentassist; import org.eclipse.jface.text.contentassist.ICompletionProposal; import org.eclipse.jface.text.contentassist.IContentAssistProcessor; import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegion; import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegion; import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegionList; import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode; import org.eclipse.wst.xml.core.internal.regions.DOMRegionContext; import org.eclipse.wst.xml.ui.internal.contentassist.ContentAssistRequest; import org.springframework.ide.eclipse.beans.ui.editor.namespaces.INamespaceContentAssistProcessor; import org.springframework.ide.eclipse.beans.ui.editor.templates.BeansTemplateCompletionProcessor; import org.springframework.ide.eclipse.beans.ui.editor.util.BeansEditorUtils; import org.w3c.dom.Node; /** * Abstract super class for content assist processors. * @author Christian Dupuis * @author Torsten Juergeleit * @since 2.0 */ @SuppressWarnings("restriction") public abstract class AbstractContentAssistProcessor implements INamespaceContentAssistProcessor { protected IContentAssistProcessor delegatingContextAssistProcessor; private BeansTemplateCompletionProcessor templateProcessor = null; public void init() { // nothing to do; } public void addAttributeNameProposals( IContentAssistProcessor delegatingContextAssistProcessor, ContentAssistRequest request) { this.delegatingContextAssistProcessor = delegatingContextAssistProcessor; IDOMNode node = (IDOMNode) request.getNode(); // Find the attribute region and name for which this position should // have a value proposed IStructuredDocumentRegion open = node .getFirstStructuredDocumentRegion(); ITextRegionList openRegions = open.getRegions(); int i = openRegions.indexOf(request.getRegion()); if (i < 0) { return; } ITextRegion nameRegion = null; while (i >= 0) { nameRegion = openRegions.get(i--); if (nameRegion.getType() == DOMRegionContext.XML_TAG_ATTRIBUTE_NAME) { break; } } String matchString = request.getMatchString(); if (matchString == null) { matchString = ""; } if (matchString.length() > 0 && (matchString.startsWith("\"") || matchString.startsWith("'"))) { matchString = matchString.substring(1); } // the name region is REQUIRED to do anything useful if (nameRegion != null) { String attributeName = open.getText(nameRegion); Node attribute = node.getAttributes().getNamedItem(attributeName); if (attribute != null) { String prefix = attribute.getPrefix(); String namespace = attribute.getNamespaceURI(); if (prefix != null) { attributeName = attributeName .substring(prefix.length() + 1); } computeAttributeNameProposals(request, attributeName, namespace, prefix, node); } } // super.addAttributeNameProposals(request); } public void addAttributeValueProposals( IContentAssistProcessor delegatingContextAssistProcessor, ContentAssistRequest request) { this.delegatingContextAssistProcessor = delegatingContextAssistProcessor; IDOMNode node = (IDOMNode) request.getNode(); // Find the attribute region and name for which this position should // have a value proposed IStructuredDocumentRegion open = node .getFirstStructuredDocumentRegion(); ITextRegionList openRegions = open.getRegions(); int i = openRegions.indexOf(request.getRegion()); if (i < 0) { return; } ITextRegion nameRegion = null; while (i >= 0) { nameRegion = openRegions.get(i--); if (nameRegion.getType() == DOMRegionContext.XML_TAG_ATTRIBUTE_NAME) { break; } } String matchString = BeansEditorUtils.prepareMatchString(request); // the name region is REQUIRED to do anything useful if (nameRegion != null) { String attributeName = open.getText(nameRegion); Node attribute = node.getAttributes().getNamedItem(attributeName); if (attribute != null) { String prefix = attribute.getPrefix(); String namespace = attribute.getNamespaceURI(); if (prefix != null) { attributeName = attributeName .substring(prefix.length() + 1); } if (prefix == null && namespace == null) { prefix = node.getPrefix(); namespace = node.getNamespaceURI(); } computeAttributeValueProposals(request, node, matchString, attributeName, namespace, prefix); } } } public void addTagCloseProposals( IContentAssistProcessor delegatingContextAssistProcessor, ContentAssistRequest request) { this.delegatingContextAssistProcessor = delegatingContextAssistProcessor; // add content assist proposals for incomplete tags this.addAttributeValueProposals(delegatingContextAssistProcessor, request); } public void addTagInsertionProposals( IContentAssistProcessor delegatingContextAssistProcessor, ContentAssistRequest request, int childPosition) { this.delegatingContextAssistProcessor = delegatingContextAssistProcessor; IDOMNode node = (IDOMNode) request.getNode(); computeTagInsertionProposals(request, node); } /** * Adds templates to the list of proposals * * @param contentAssistRequest * @param context */ protected void addTemplates(ContentAssistRequest contentAssistRequest, String context) { if (contentAssistRequest == null) return; // if already adding template proposals for a certain context type, do // not add again // if (!fTemplateContexts.contains(context)) { // fTemplateContexts.add(context); boolean useProposalList = !contentAssistRequest.shouldSeparate(); if (getTemplateCompletionProcessor() != null) { getTemplateCompletionProcessor().setContextType(context); ICompletionProposal[] proposals = getTemplateCompletionProcessor() .computeCompletionProposals( ((DelegatingContentAssistProcessor) this.delegatingContextAssistProcessor) .getTextViewer(), contentAssistRequest.getReplacementBeginPosition()); for (ICompletionProposal element : proposals) { if (useProposalList) contentAssistRequest.addProposal(element); else contentAssistRequest.addMacro(element); } } } protected abstract void computeAttributeNameProposals( ContentAssistRequest request, String prefix, String namespace, String namespacePrefix, Node attributeNode); protected abstract void computeAttributeValueProposals( ContentAssistRequest request, IDOMNode node, String matchString, String attributeName, String namespace, String prefix); protected abstract void computeTagInsertionProposals( ContentAssistRequest request, IDOMNode node); protected BeansTemplateCompletionProcessor getTemplateCompletionProcessor() { if (templateProcessor == null) { templateProcessor = new BeansTemplateCompletionProcessor(); } return templateProcessor; } }