Search in sources :

Example 66 with CMNode

use of org.eclipse.wst.xml.core.internal.contentmodel.CMNode in project webtools.sourceediting by eclipse.

the class AbstractXMLModelQueryCompletionProposalComputer method addModelQueryAttributeDeclarations.

/**
 * <p>Adds model query attribute declaration proposals</p>
 *
 * @param node
 * @param elementDecl
 * @param allAttributes
 */
private void addModelQueryAttributeDeclarations(IDOMNode node, CMElementDeclaration elementDecl, CMNamedNodeMapImpl allAttributes) {
    if (node.getNodeType() == Node.ELEMENT_NODE) {
        List nodes = ModelQueryUtil.getModelQuery(node.getOwnerDocument()).getAvailableContent((Element) node, elementDecl, ModelQuery.INCLUDE_ATTRIBUTES);
        nodes = filterAvailableModelQueryCMNodes(nodes);
        for (int k = 0; k < nodes.size(); k++) {
            CMNode cmnode = (CMNode) nodes.get(k);
            if (cmnode.getNodeType() == CMNode.ATTRIBUTE_DECLARATION) {
                allAttributes.put(cmnode);
            }
        }
    }
}
Also used : List(java.util.List) ITextRegionList(org.eclipse.wst.sse.core.internal.provisional.text.ITextRegionList) ArrayList(java.util.ArrayList) CMNode(org.eclipse.wst.xml.core.internal.contentmodel.CMNode)

Example 67 with CMNode

use of org.eclipse.wst.xml.core.internal.contentmodel.CMNode in project webtools.sourceediting by eclipse.

the class AbstractXMLModelQueryCompletionProposalComputer method addAttributeValueProposals.

protected void addAttributeValueProposals(ContentAssistRequest contentAssistRequest, CompletionProposalInvocationContext context) {
    IDOMNode node = (IDOMNode) contentAssistRequest.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(contentAssistRequest.getRegion());
    if (i < 0) {
        return;
    }
    ITextRegion nameRegion = null;
    while (i >= 0) {
        nameRegion = openRegions.get(i--);
        if (nameRegion.getType() == DOMRegionContext.XML_TAG_ATTRIBUTE_NAME) {
            break;
        }
    }
    // the name region is REQUIRED to do anything useful
    if (nameRegion != null) {
        // Retrieve the declaration
        CMElementDeclaration elementDecl = getCMElementDeclaration(node);
        // String attributeName = nameRegion.getText();
        String attributeName = open.getText(nameRegion);
        CMAttributeDeclaration attrDecl = null;
        // declaration for the attribute otherwise
        if (elementDecl != null) {
            CMNamedNodeMapImpl allAttributes = new CMNamedNodeMapImpl(elementDecl.getAttributes()) {

                private Map caseInsensitive;

                private Map getCaseInsensitiveMap() {
                    if (caseInsensitive == null)
                        caseInsensitive = new HashMap();
                    return caseInsensitive;
                }

                public CMNode getNamedItem(String name) {
                    CMNode node = super.getNamedItem(name);
                    if (node == null) {
                        node = (CMNode) getCaseInsensitiveMap().get(name.toLowerCase(Locale.US));
                    }
                    return node;
                }

                public void put(CMNode cmNode) {
                    super.put(cmNode);
                    getCaseInsensitiveMap().put(cmNode.getNodeName().toLowerCase(Locale.US), cmNode);
                }
            };
            this.addModelQueryAttributeDeclarations(node, elementDecl, allAttributes);
            String noprefixName = DOMNamespaceHelper.getUnprefixedName(attributeName);
            if (allAttributes != null) {
                attrDecl = (CMAttributeDeclaration) allAttributes.getNamedItem(attributeName);
                if (attrDecl == null) {
                    attrDecl = (CMAttributeDeclaration) allAttributes.getNamedItem(noprefixName);
                }
            }
            if (attrDecl == null) {
                setErrorMessage(XMLUIMessages.No_known_attribute__UI_ + attributeName);
            }
        }
        String currentValue = node.getAttributes().getNamedItem(attributeName).getNodeValue();
        String proposedInfo = null;
        // get proposal image
        Image image = CMImageUtil.getImage(attrDecl);
        if (image == null) {
            if ((attrDecl != null) && (attrDecl.getUsage() == CMAttributeDeclaration.REQUIRED)) {
                image = this.getRequiredAttributeImage();
            } else {
                image = this.getNotRequiredAttributeImage();
            }
        }
        if ((attrDecl != null) && (attrDecl.getAttrType() != null)) {
            // attribute is known, prompt with values from the declaration
            proposedInfo = getAdditionalInfo(elementDecl, attrDecl);
            List possibleValues = getPossibleDataTypeValues(node, attrDecl);
            String defaultValue = attrDecl.getAttrType().getImpliedValue();
            // $NON-NLS-1$
            String qualifiedDelimiter = (String) attrDecl.getProperty("qualified-delimiter");
            if (possibleValues.size() > 0 || defaultValue != null) {
                // ENUMERATED VALUES
                String matchString = contentAssistRequest.getMatchString();
                if (matchString == null) {
                    // $NON-NLS-1$
                    matchString = "";
                }
                if ((matchString.length() > 0) && (matchString.startsWith("\"") || matchString.startsWith("'"))) {
                    // $NON-NLS-1$ //$NON-NLS-2$
                    matchString = matchString.substring(1);
                }
                boolean currentValid = false;
                // create suggestions for enumerated values
                int rOffset = contentAssistRequest.getReplacementBeginPosition();
                int rLength = contentAssistRequest.getReplacementLength();
                for (Iterator j = possibleValues.iterator(); j.hasNext(); ) {
                    String possibleValue = (String) j.next();
                    String alternateMatch = null;
                    if (qualifiedDelimiter != null) {
                        int delimiter = possibleValue.lastIndexOf(qualifiedDelimiter);
                        if (delimiter >= 0 && delimiter < possibleValue.length() - 1) {
                            alternateMatch = possibleValue.substring(delimiter + 1);
                        }
                    }
                    if (!possibleValue.equals(defaultValue)) {
                        currentValid = currentValid || possibleValue.equals(currentValue);
                        if ((matchString.length() == 0) || possibleValue.startsWith(matchString)) {
                            // $NON-NLS-1$ //$NON-NLS-2$
                            String rString = "\"" + possibleValue + "\"";
                            // $NON-NLS-1$
                            alternateMatch = "\"" + alternateMatch;
                            CustomCompletionProposal proposal = new MarkupCompletionProposal(rString, rOffset, rLength, possibleValue.length() + 1, XMLEditorPluginImageHelper.getInstance().getImage(XMLEditorPluginImages.IMG_OBJ_ENUM), rString, alternateMatch, null, proposedInfo, XMLRelevanceConstants.R_XML_ATTRIBUTE_VALUE, true);
                            contentAssistRequest.addProposal(proposal);
                        }
                    }
                }
                if (defaultValue != null && ((matchString.length() == 0) || defaultValue.startsWith(matchString))) {
                    // $NON-NLS-1$ //$NON-NLS-2$
                    String rString = "\"" + defaultValue + "\"";
                    final String regionText = contentAssistRequest.getDocumentRegion().getText(contentAssistRequest.getRegion());
                    final int matchStringLength = contentAssistRequest.getMatchString().length();
                    if (matchString.length() > 0 && matchStringLength < regionText.length()) {
                        final String remaining = regionText.substring(matchStringLength).trim();
                        if (remaining.charAt(0) != '\'' && remaining.charAt(0) != '"') {
                            rLength = matchStringLength;
                        }
                    }
                    CustomCompletionProposal proposal = new MarkupCompletionProposal(rString, rOffset, rLength, defaultValue.length() + 1, XMLEditorPluginImageHelper.getInstance().getImage(XMLEditorPluginImages.IMG_OBJ_DEFAULT), rString, null, proposedInfo, XMLRelevanceConstants.R_XML_ATTRIBUTE_VALUE);
                    contentAssistRequest.addProposal(proposal);
                }
            } else if (((attrDecl.getUsage() == CMAttributeDeclaration.FIXED) || (attrDecl.getAttrType().getImpliedValueKind() == CMDataType.IMPLIED_VALUE_FIXED)) && (attrDecl.getAttrType().getImpliedValue() != null)) {
                // FIXED values
                String value = attrDecl.getAttrType().getImpliedValue();
                if ((value != null) && (value.length() > 0)) {
                    // $NON-NLS-2$//$NON-NLS-1$
                    String rValue = "\"" + value + "\"";
                    CustomCompletionProposal proposal = new MarkupCompletionProposal(rValue, contentAssistRequest.getReplacementBeginPosition(), contentAssistRequest.getReplacementLength(), rValue.length() + 1, image, rValue, null, proposedInfo, XMLRelevanceConstants.R_XML_ATTRIBUTE_VALUE);
                    contentAssistRequest.addProposal(proposal);
                    if ((currentValue.length() > 0) && !value.equals(currentValue)) {
                        // $NON-NLS-2$//$NON-NLS-1$
                        rValue = "\"" + currentValue + "\"";
                        proposal = new MarkupCompletionProposal(rValue, contentAssistRequest.getReplacementBeginPosition(), contentAssistRequest.getReplacementLength(), rValue.length() + 1, image, rValue, null, proposedInfo, XMLRelevanceConstants.R_XML_ATTRIBUTE_VALUE);
                        contentAssistRequest.addProposal(proposal);
                    }
                }
            }
        } else {
            // unknown attribute, so supply nice empty values
            proposedInfo = getAdditionalInfo(null, elementDecl);
            CustomCompletionProposal proposal = null;
            if ((currentValue != null) && (currentValue.length() > 0)) {
                final String regionText = open.getText(contentAssistRequest.getRegion());
                if (regionText.charAt(0) != '"' && regionText.charAt(0) != '\'') {
                    // $NON-NLS-2$//$NON-NLS-1$
                    String rValue = "\"" + currentValue + "\"";
                    proposal = new MarkupCompletionProposal(rValue, contentAssistRequest.getReplacementBeginPosition(), contentAssistRequest.getReplacementLength(), 1, image, rValue, null, proposedInfo, XMLRelevanceConstants.R_XML_ATTRIBUTE_VALUE);
                    contentAssistRequest.addProposal(proposal);
                }
            }
        }
    } else {
        setErrorMessage(XMLUIMessages.Content_Assist_not_availab_UI_);
    }
}
Also used : CMNamedNodeMapImpl(org.eclipse.wst.xml.core.internal.contentmodel.basic.CMNamedNodeMapImpl) IStructuredDocumentRegion(org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegion) HashMap(java.util.HashMap) CustomCompletionProposal(org.eclipse.wst.sse.ui.internal.contentassist.CustomCompletionProposal) Image(org.eclipse.swt.graphics.Image) ITextRegionList(org.eclipse.wst.sse.core.internal.provisional.text.ITextRegionList) CMElementDeclaration(org.eclipse.wst.xml.core.internal.contentmodel.CMElementDeclaration) IDOMNode(org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode) ITextRegion(org.eclipse.wst.sse.core.internal.provisional.text.ITextRegion) Iterator(java.util.Iterator) CMAttributeDeclaration(org.eclipse.wst.xml.core.internal.contentmodel.CMAttributeDeclaration) CMNode(org.eclipse.wst.xml.core.internal.contentmodel.CMNode) List(java.util.List) ITextRegionList(org.eclipse.wst.sse.core.internal.provisional.text.ITextRegionList) ArrayList(java.util.ArrayList) Map(java.util.Map) CMNamedNodeMap(org.eclipse.wst.xml.core.internal.contentmodel.CMNamedNodeMap) HashMap(java.util.HashMap) NamedNodeMap(org.w3c.dom.NamedNodeMap)

Example 68 with CMNode

use of org.eclipse.wst.xml.core.internal.contentmodel.CMNode in project webtools.sourceediting by eclipse.

the class AbstractXMLModelQueryCompletionProposalComputer method addTagNameProposals.

protected void addTagNameProposals(ContentAssistRequest contentAssistRequest, int childPosition, CompletionProposalInvocationContext context) {
    List cmnodes = null;
    Node parent = contentAssistRequest.getParent();
    IDOMNode node = (IDOMNode) contentAssistRequest.getNode();
    String error = null;
    String matchString = contentAssistRequest.getMatchString();
    if (parent.getNodeType() == Node.ELEMENT_NODE) {
        // retrieve the list of children
        // validActions = getAvailableChildrenAtIndex((Element) parent,
        // childPosition);
        cmnodes = getAvailableChildElementDeclarations((Element) parent, childPosition, ModelQueryAction.INSERT);
        List strictCMNodeSuggestions = null;
        if (XMLUIPreferenceNames.SUGGESTION_STRATEGY_VALUE_STRICT.equals(XMLUIPlugin.getInstance().getPreferenceStore().getString(XMLUIPreferenceNames.SUGGESTION_STRATEGY))) {
            strictCMNodeSuggestions = getValidChildElementDeclarations((Element) parent, childPosition, ModelQueryAction.INSERT);
        }
        Iterator nodeIterator = cmnodes.iterator();
        // chop off any leading <'s and whitespace from the matchstring
        while ((matchString.length() > 0) && (Character.isWhitespace(matchString.charAt(0)) || beginsWith(matchString, "<"))) {
            // $NON-NLS-1$
            matchString = matchString.substring(1);
        }
        if (!nodeIterator.hasNext()) {
            error = NLS.bind(XMLUIMessages.__Has_no_known_child, (new Object[] { parent.getNodeName() }));
        }
        while (nodeIterator.hasNext()) {
            CMNode elementDecl = (CMNode) nodeIterator.next();
            if (elementDecl != null) {
                // only add proposals for the child element's that begin with the matchstring
                String proposedText = null;
                int cursorAdjustment = 0;
                // determine if strict suggestion
                boolean isStrictCMNodeSuggestion = strictCMNodeSuggestions != null ? strictCMNodeSuggestions.contains(elementDecl) : false;
                // do a check to see if partial attributes of partial tag names are in list
                if ((contentAssistRequest.documentRegion.getStartOffset() < context.getInvocationOffset()) && (((node != null) && (node.getAttributes() != null) && (node.getAttributes().getLength() > 0) && attributeInList(node, parent, elementDecl)) || ((node.getNodeType() != Node.TEXT_NODE) && node.getFirstStructuredDocumentRegion().isEnded()))) {
                    proposedText = getRequiredName(parent, elementDecl);
                    cursorAdjustment = proposedText.length();
                } else {
                    proposedText = getRequiredName(parent, elementDecl);
                    cursorAdjustment = proposedText.length();
                    if (elementDecl instanceof CMElementDeclaration) {
                        CMElementDeclaration ed = (CMElementDeclaration) elementDecl;
                        // https://bugs.eclipse.org/bugs/show_bug.cgi?id=89811
                        StringBuffer sb = new StringBuffer();
                        getContentGenerator().generateTag(parent, ed, sb);
                        // since it's a name proposal, assume '<' is already there
                        // only return the rest of the tag
                        proposedText = sb.toString().substring(1);
                        cursorAdjustment = getCursorPositionForProposedText(proposedText);
                    }
                }
                if (beginsWith(proposedText, matchString)) {
                    // get the proposal image
                    Image image = CMImageUtil.getImage(elementDecl);
                    if (image == null) {
                        if (strictCMNodeSuggestions != null) {
                            image = isStrictCMNodeSuggestion ? this.getEmphasizedTagImage() : this.getDeemphasizedTagImage();
                        } else {
                            image = this.getGenericTagImage();
                        }
                    }
                    int relevance = isStrictCMNodeSuggestion ? XMLRelevanceConstants.R_STRICTLY_VALID_TAG_NAME : XMLRelevanceConstants.R_TAG_NAME;
                    String proposedInfo = getAdditionalInfo(getCMElementDeclaration(parent), elementDecl);
                    CustomCompletionProposal proposal = new MarkupCompletionProposal(proposedText, contentAssistRequest.getReplacementBeginPosition(), contentAssistRequest.getReplacementLength(), cursorAdjustment, image, getRequiredName(parent, elementDecl), null, proposedInfo, relevance);
                    contentAssistRequest.addProposal(proposal);
                }
            }
        }
        if (contentAssistRequest.getProposals().size() == 0) {
            if (error != null) {
                setErrorMessage(error);
            } else if ((contentAssistRequest.getMatchString() != null) && (contentAssistRequest.getMatchString().length() > 0)) {
                setErrorMessage(NLS.bind(XMLUIMessages.No_known_child_tag_names, (new Object[] { parent.getNodeName(), contentAssistRequest.getMatchString() })));
            } else {
                setErrorMessage(NLS.bind(XMLUIMessages.__Has_no_known_child, (new Object[] { parent.getNodeName() })));
            }
        }
    } else if (parent.getNodeType() == Node.DOCUMENT_NODE) {
        List childElements = getAvailableRootChildren((Document) parent, childPosition);
        if (childElements.size() == 0) {
            // No doctype available , treat it as empty document
            addEmptyDocumentProposals(contentAssistRequest, context);
        }
        for (int i = 0; i < childElements.size(); i++) {
            CMNode ed = (CMNode) childElements.get(i);
            if (ed == null) {
                continue;
            }
            String proposedText = null;
            int cursorAdjustment = 0;
            if (ed instanceof CMElementDeclaration) {
                // proposedText = getRequiredName(parent, ed);
                StringBuffer sb = new StringBuffer();
                getContentGenerator().generateTag(parent, (CMElementDeclaration) ed, sb);
                // tag starts w/ '<', but we want to compare to name
                proposedText = sb.toString().substring(1);
                if (!beginsWith(proposedText, matchString)) {
                    continue;
                }
                cursorAdjustment = getCursorPositionForProposedText(proposedText);
                String proposedInfo = getAdditionalInfo(null, ed);
                Image image = CMImageUtil.getImage(ed);
                if (image == null) {
                    image = this.getGenericTagImage();
                }
                CustomCompletionProposal proposal = new MarkupCompletionProposal(proposedText, contentAssistRequest.getReplacementBeginPosition(), contentAssistRequest.getReplacementLength(), cursorAdjustment, image, getRequiredName(parent, ed), null, proposedInfo, XMLRelevanceConstants.R_TAG_NAME);
                contentAssistRequest.addProposal(proposal);
            }
        }
    }
}
Also used : IDOMNode(org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode) CMNode(org.eclipse.wst.xml.core.internal.contentmodel.CMNode) Node(org.w3c.dom.Node) Element(org.w3c.dom.Element) IDOMElement(org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement) CustomCompletionProposal(org.eclipse.wst.sse.ui.internal.contentassist.CustomCompletionProposal) Image(org.eclipse.swt.graphics.Image) Document(org.w3c.dom.Document) IDOMDocument(org.eclipse.wst.xml.core.internal.provisional.document.IDOMDocument) CMDocument(org.eclipse.wst.xml.core.internal.contentmodel.CMDocument) IStructuredDocument(org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument) CMElementDeclaration(org.eclipse.wst.xml.core.internal.contentmodel.CMElementDeclaration) IDOMNode(org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode) Iterator(java.util.Iterator) List(java.util.List) ITextRegionList(org.eclipse.wst.sse.core.internal.provisional.text.ITextRegionList) ArrayList(java.util.ArrayList) CMNode(org.eclipse.wst.xml.core.internal.contentmodel.CMNode)

Example 69 with CMNode

use of org.eclipse.wst.xml.core.internal.contentmodel.CMNode in project webtools.sourceediting by eclipse.

the class AbstractXMLModelQueryCompletionProposalComputer method filterAvailableModelQueryCMNodes.

/**
 * <p>Filters out any model query {@link CMNode}s that are not valid for this
 * implementation of the model query computer</p>
 *
 * @param modelQueryNodes
 * @return the filtered list of {@link CMNode}s
 */
private List filterAvailableModelQueryCMNodes(List modelQueryNodes) {
    List filtered = new ArrayList(modelQueryNodes.size());
    Iterator iterator = modelQueryNodes.iterator();
    while (iterator.hasNext()) {
        CMNode node = (CMNode) iterator.next();
        if (validModelQueryNode(node)) {
            filtered.add(node);
        }
    }
    return filtered;
}
Also used : ArrayList(java.util.ArrayList) Iterator(java.util.Iterator) List(java.util.List) ITextRegionList(org.eclipse.wst.sse.core.internal.provisional.text.ITextRegionList) ArrayList(java.util.ArrayList) CMNode(org.eclipse.wst.xml.core.internal.contentmodel.CMNode)

Example 70 with CMNode

use of org.eclipse.wst.xml.core.internal.contentmodel.CMNode in project webtools.sourceediting by eclipse.

the class QuickAssistProcessorXML method getRequiredAttrs.

protected List getRequiredAttrs(Node node) {
    List result = new ArrayList();
    ModelQuery modelQuery = getModelQuery(node);
    if (modelQuery != null) {
        CMElementDeclaration elementDecl = modelQuery.getCMElementDeclaration((Element) node);
        if (elementDecl != null) {
            CMNamedNodeMap attrMap = elementDecl.getAttributes();
            CMNamedNodeMapImpl allAttributes = new CMNamedNodeMapImpl(attrMap);
            List nodes = ModelQueryUtil.getModelQuery(node.getOwnerDocument()).getAvailableContent((Element) node, elementDecl, ModelQuery.INCLUDE_ATTRIBUTES);
            for (int k = 0; k < nodes.size(); k++) {
                CMNode cmnode = (CMNode) nodes.get(k);
                if (cmnode.getNodeType() == CMNode.ATTRIBUTE_DECLARATION) {
                    allAttributes.put(cmnode);
                }
            }
            attrMap = allAttributes;
            Iterator it = attrMap.iterator();
            CMAttributeDeclaration attr = null;
            while (it.hasNext()) {
                attr = (CMAttributeDeclaration) it.next();
                if (attr.getUsage() == CMAttributeDeclaration.REQUIRED) {
                    result.add(attr);
                }
            }
        }
    }
    return result;
}
Also used : CMNamedNodeMapImpl(org.eclipse.wst.xml.core.internal.contentmodel.basic.CMNamedNodeMapImpl) CMElementDeclaration(org.eclipse.wst.xml.core.internal.contentmodel.CMElementDeclaration) ArrayList(java.util.ArrayList) Iterator(java.util.Iterator) ArrayList(java.util.ArrayList) List(java.util.List) ModelQuery(org.eclipse.wst.xml.core.internal.contentmodel.modelquery.ModelQuery) CMNode(org.eclipse.wst.xml.core.internal.contentmodel.CMNode) CMAttributeDeclaration(org.eclipse.wst.xml.core.internal.contentmodel.CMAttributeDeclaration) CMNamedNodeMap(org.eclipse.wst.xml.core.internal.contentmodel.CMNamedNodeMap)

Aggregations

CMNode (org.eclipse.wst.xml.core.internal.contentmodel.CMNode)133 CMElementDeclaration (org.eclipse.wst.xml.core.internal.contentmodel.CMElementDeclaration)37 List (java.util.List)36 CMNamedNodeMap (org.eclipse.wst.xml.core.internal.contentmodel.CMNamedNodeMap)35 ArrayList (java.util.ArrayList)28 Iterator (java.util.Iterator)23 ITextRegionList (org.eclipse.wst.sse.core.internal.provisional.text.ITextRegionList)20 CMNodeList (org.eclipse.wst.xml.core.internal.contentmodel.CMNodeList)19 CMAttributeDeclaration (org.eclipse.wst.xml.core.internal.contentmodel.CMAttributeDeclaration)17 CMDocument (org.eclipse.wst.xml.core.internal.contentmodel.CMDocument)17 Element (org.w3c.dom.Element)16 NodeList (org.w3c.dom.NodeList)15 CMNamedNodeMapImpl (org.eclipse.wst.xml.core.internal.contentmodel.basic.CMNamedNodeMapImpl)14 ModelQuery (org.eclipse.wst.xml.core.internal.contentmodel.modelquery.ModelQuery)13 Node (org.w3c.dom.Node)13 NamedNodeMap (org.w3c.dom.NamedNodeMap)10 ModelQueryAction (org.eclipse.wst.xml.core.internal.contentmodel.modelquery.ModelQueryAction)9 IDOMNode (org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode)9 Image (org.eclipse.swt.graphics.Image)8 CustomCompletionProposal (org.eclipse.wst.sse.ui.internal.contentassist.CustomCompletionProposal)8