use of org.eclipse.wst.xml.core.internal.contentmodel.CMElementDeclaration in project webtools.sourceediting by eclipse.
the class AbstractXMLModelQueryCompletionProposalComputer method addTagInsertionProposals.
protected void addTagInsertionProposals(ContentAssistRequest contentAssistRequest, int childPosition, CompletionProposalInvocationContext context) {
List cmnodes = null;
Node parent = contentAssistRequest.getParent();
String error = null;
// only valid if it's XML (check added 2/17/2004)
if ((parent != null) && (parent.getNodeType() == Node.DOCUMENT_NODE) && ((IDOMDocument) parent).isXMLType() && !isCursorAfterXMLPI(contentAssistRequest)) {
return;
}
// only want proposals if cursor is after doctype...
if (!isCursorAfterDoctype(contentAssistRequest)) {
return;
}
// have a content model (so can't propose any children..)
if ((parent != null) && (parent instanceof IDOMNode) && isCommentNode((IDOMNode) parent)) {
// loop and find non comment node?
while ((parent != null) && isCommentNode((IDOMNode) parent)) {
parent = parent.getParentNode();
}
}
if (parent.getNodeType() == Node.ELEMENT_NODE) {
CMElementDeclaration parentDecl = getCMElementDeclaration(parent);
if (parentDecl != null) {
// XSD-specific ability - no filtering
CMDataType childType = parentDecl.getDataType();
if (childType != null) {
String[] childStrings = childType.getEnumeratedValues();
String defaultValue = childType.getImpliedValue();
if (childStrings != null || defaultValue != null) {
// the content string is the sole valid child...so replace the rest
int begin = contentAssistRequest.getReplacementBeginPosition();
int length = contentAssistRequest.getReplacementLength();
if (parent instanceof IDOMNode) {
if (((IDOMNode) parent).getLastStructuredDocumentRegion() != ((IDOMNode) parent).getFirstStructuredDocumentRegion()) {
begin = ((IDOMNode) parent).getFirstStructuredDocumentRegion().getEndOffset();
length = ((IDOMNode) parent).getLastStructuredDocumentRegion().getStartOffset() - begin;
}
}
String proposedInfo = getAdditionalInfo(parentDecl, childType);
for (int i = 0; i < childStrings.length; i++) {
if (!childStrings[i].equals(defaultValue)) {
CustomCompletionProposal textProposal = new MarkupCompletionProposal(childStrings[i], begin, length, childStrings[i].length(), XMLEditorPluginImageHelper.getInstance().getImage(XMLEditorPluginImages.IMG_OBJ_ENUM), childStrings[i], null, proposedInfo, XMLRelevanceConstants.R_TAG_INSERTION);
contentAssistRequest.addProposal(textProposal);
}
}
if (defaultValue != null) {
CustomCompletionProposal textProposal = new MarkupCompletionProposal(defaultValue, begin, length, defaultValue.length(), XMLEditorPluginImageHelper.getInstance().getImage(XMLEditorPluginImages.IMG_OBJ_DEFAULT), defaultValue, null, proposedInfo, XMLRelevanceConstants.R_TAG_INSERTION);
contentAssistRequest.addProposal(textProposal);
}
}
}
}
if ((parentDecl != null) && (parentDecl.getContentType() == CMElementDeclaration.PCDATA)) {
addPCDATAProposal(parentDecl.getNodeName(), contentAssistRequest, context);
} else {
// retrieve the list of all possible children within this parent context
cmnodes = getAvailableChildElementDeclarations((Element) parent, childPosition, ModelQueryAction.INSERT);
// retrieve the list of the possible children within this
// parent context and at this index
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();
if (!nodeIterator.hasNext()) {
if (getCMElementDeclaration(parent) != null) {
error = NLS.bind(XMLUIMessages._Has_no_available_child, (new Object[] { parent.getNodeName() }));
} else {
error = NLS.bind(XMLUIMessages.Element__is_unknown, (new Object[] { parent.getNodeName() }));
}
}
String matchString = contentAssistRequest.getMatchString();
// 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);
}
while (nodeIterator.hasNext()) {
Object o = nodeIterator.next();
if (o instanceof CMElementDeclaration) {
CMElementDeclaration elementDecl = (CMElementDeclaration) o;
// only add proposals for the child element's that
// begin with the matchstring
String tagname = getRequiredName(parent, elementDecl);
boolean isStrictCMNodeSuggestion = strictCMNodeSuggestions != null ? strictCMNodeSuggestions.contains(elementDecl) : false;
// 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();
}
}
if (beginsWith(tagname, matchString)) {
String proposedText = getRequiredText(parent, elementDecl);
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=89811
// place cursor in first empty quotes
int markupAdjustment = getCursorPositionForProposedText(proposedText);
String proposedInfo = getAdditionalInfo(parentDecl, elementDecl);
int relevance = isStrictCMNodeSuggestion ? XMLRelevanceConstants.R_STRICTLY_VALID_TAG_INSERTION : XMLRelevanceConstants.R_TAG_INSERTION;
CustomCompletionProposal proposal = new MarkupCompletionProposal(proposedText, contentAssistRequest.getReplacementBeginPosition(), contentAssistRequest.getReplacementLength(), markupAdjustment, image, tagname, 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, (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) {
// Can only prompt with elements if the cursor position is past
// the XML processing
// instruction and DOCTYPE declaration
boolean xmlpiFound = false;
boolean doctypeFound = false;
int minimumOffset = -1;
for (Node child = parent.getFirstChild(); child != null; child = child.getNextSibling()) {
// $NON-NLS-1$
boolean xmlpi = ((child.getNodeType() == Node.PROCESSING_INSTRUCTION_NODE) && child.getNodeName().equals("xml"));
boolean doctype = child.getNodeType() == Node.DOCUMENT_TYPE_NODE;
if (xmlpi || (doctype && (minimumOffset < 0))) {
minimumOffset = ((IDOMNode) child).getFirstStructuredDocumentRegion().getStartOffset() + ((IDOMNode) child).getFirstStructuredDocumentRegion().getTextLength();
}
xmlpiFound = xmlpiFound || xmlpi;
doctypeFound = doctypeFound || doctype;
}
if (contentAssistRequest.getReplacementBeginPosition() >= minimumOffset) {
List childDecls = getAvailableRootChildren((Document) parent, childPosition);
for (int i = 0; i < childDecls.size(); i++) {
CMElementDeclaration ed = (CMElementDeclaration) childDecls.get(i);
if (ed != null) {
Image image = CMImageUtil.getImage(ed);
if (image == null) {
image = this.getGenericTagImage();
}
String proposedText = getRequiredText(parent, ed);
String tagname = getRequiredName(parent, ed);
// account for the < and >
int markupAdjustment = getContentGenerator().getMinimalStartTagLength(parent, ed);
String proposedInfo = getAdditionalInfo(null, ed);
CustomCompletionProposal proposal = new MarkupCompletionProposal(proposedText, contentAssistRequest.getReplacementBeginPosition(), contentAssistRequest.getReplacementLength(), markupAdjustment, image, tagname, null, proposedInfo, XMLRelevanceConstants.R_TAG_INSERTION);
contentAssistRequest.addProposal(proposal);
}
}
}
}
}
use of org.eclipse.wst.xml.core.internal.contentmodel.CMElementDeclaration in project webtools.sourceediting by eclipse.
the class AbstractXMLModelQueryCompletionProposalComputer method getAvailableModelQueryActionsAtIndex.
/**
* returns a list of ModelQueryActions
*
* @param parent
* @param index
* @param validityChecking
* @return
*/
private List getAvailableModelQueryActionsAtIndex(Element parent, int index, int validityChecking) {
List list = new ArrayList();
CMElementDeclaration parentDecl = getCMElementDeclaration(parent);
if (parentDecl != null) {
ModelQuery modelQuery = ModelQueryUtil.getModelQuery(parent.getOwnerDocument());
// taken from ActionManagers
// int editMode = modelQuery.getEditMode();
int editMode = ModelQuery.EDIT_MODE_UNCONSTRAINED;
int ic = (editMode == ModelQuery.EDIT_MODE_CONSTRAINED_STRICT) ? ModelQuery.INCLUDE_CHILD_NODES | ModelQuery.INCLUDE_SEQUENCE_GROUPS : ModelQuery.INCLUDE_CHILD_NODES;
modelQuery.getInsertActions(parent, parentDecl, index, ic, validityChecking, list);
}
list = filterAvailableModelQueryActions(list);
return list;
}
use of org.eclipse.wst.xml.core.internal.contentmodel.CMElementDeclaration in project webtools.sourceediting by eclipse.
the class AbstractXMLModelQueryCompletionProposalComputer method addAttributeNameProposals.
protected void addAttributeNameProposals(ContentAssistRequest contentAssistRequest, CompletionProposalInvocationContext context) {
IDOMNode node = (IDOMNode) contentAssistRequest.getNode();
IStructuredDocumentRegion sdRegion = contentAssistRequest.getDocumentRegion();
// retrieve the list of attributes
CMElementDeclaration elementDecl = getCMElementDeclaration(node);
if (elementDecl != null) {
CMNamedNodeMapImpl attributes = new CMNamedNodeMapImpl(elementDecl.getAttributes());
addModelQueryAttributeDeclarations(node, elementDecl, attributes);
String matchString = contentAssistRequest.getMatchString();
int cursorOffset = context.getInvocationOffset();
// check whether an attribute really exists for the replacement
// offsets AND if it possesses a value
boolean attrAtLocationHasValue = false;
boolean proposalNeedsSpace = false;
NamedNodeMap attrs = node.getAttributes();
for (int i = 0; i < attrs.getLength(); i++) {
AttrImpl existingAttr = (AttrImpl) attrs.item(i);
ITextRegion name = existingAttr.getNameRegion();
if (name != null && (sdRegion.getStartOffset(name) <= contentAssistRequest.getReplacementBeginPosition()) && (sdRegion.getStartOffset(name) + name.getLength() >= contentAssistRequest.getReplacementBeginPosition() + contentAssistRequest.getReplacementLength()) && (existingAttr.getValueRegion() != null)) {
// selected region is attribute name
if (cursorOffset >= sdRegion.getStartOffset(name) && contentAssistRequest.getReplacementLength() != 0)
attrAtLocationHasValue = true;
else // propose new attribute, cursor is at the start of another attribute name
if (cursorOffset == sdRegion.getStartOffset(name))
proposalNeedsSpace = true;
break;
}
}
// only add proposals for the attributes whose names begin with the matchstring
if (attributes != null) {
for (int i = 0; i < attributes.getLength(); i++) {
CMAttributeDeclaration attrDecl = (CMAttributeDeclaration) attributes.item(i);
if (validModelQueryNode(attrDecl)) {
int isRequired = 0;
if (attrDecl.getUsage() == CMAttributeDeclaration.REQUIRED) {
isRequired = XMLRelevanceConstants.R_REQUIRED;
}
boolean showAttribute = true;
showAttribute = showAttribute && beginsWith(getRequiredName(node, attrDecl), matchString.trim());
AttrImpl attr = (AttrImpl) node.getAttributes().getNamedItem(getRequiredName(node, attrDecl));
ITextRegion nameRegion = attr != null ? attr.getNameRegion() : null;
// nameRegion.getEndOffset() + 1 is required to allow for
// matches against the full name of an existing Attr
showAttribute = showAttribute && ((attr == null) || nameRegion == null || ((nameRegion != null) && (sdRegion.getStartOffset(nameRegion) < contentAssistRequest.getReplacementBeginPosition()) && (sdRegion.getStartOffset(nameRegion) + nameRegion.getLength() >= (contentAssistRequest.getReplacementBeginPosition() + contentAssistRequest.getReplacementLength()))));
if (showAttribute) {
// get the proposal image
Image attrImage = CMImageUtil.getImage(attrDecl);
if (attrImage == null) {
if (isRequired > 0) {
attrImage = this.getRequiredAttributeImage();
} else {
attrImage = this.getNotRequiredAttributeImage();
}
}
String proposedText = null;
String proposedInfo = getAdditionalInfo(elementDecl, attrDecl);
CustomCompletionProposal proposal = null;
// attribute is at this location and already exists
if (attrAtLocationHasValue) {
// only propose the name
proposedText = getRequiredName(node, attrDecl);
proposal = new MarkupCompletionProposal(proposedText, contentAssistRequest.getReplacementBeginPosition(), contentAssistRequest.getReplacementLength(), proposedText.length(), attrImage, proposedText, null, proposedInfo, XMLRelevanceConstants.R_XML_ATTRIBUTE_NAME + isRequired, true);
} else // no attribute exists or is elsewhere, generate
// minimally
{
Attr existingAttrNode = (Attr) node.getAttributes().getNamedItem(getRequiredName(node, attrDecl));
String value = null;
if (existingAttrNode != null && existingAttrNode.getSpecified()) {
value = existingAttrNode.getNodeValue();
}
int cursorPosition = 0;
if ((value != null) && (value.length() > 0)) {
proposedText = getRequiredName(node, attrDecl);
cursorPosition = proposedText.length() + 2;
} else {
proposedText = getRequiredText(node, attrDecl);
// skip the cursor past a fixed value
if (attrDecl.getAttrType() != null && attrDecl.getAttrType().getImpliedValueKind() == CMDataType.IMPLIED_VALUE_FIXED)
cursorPosition = proposedText.length();
else
cursorPosition = getRequiredName(node, attrDecl).length() + 2;
}
if (proposalNeedsSpace)
// $NON-NLS-1$
proposedText += " ";
proposal = new MarkupCompletionProposal(proposedText, contentAssistRequest.getReplacementBeginPosition(), contentAssistRequest.getReplacementLength(), cursorPosition, attrImage, // and there is no single quote that may be encasing a double quote
((proposedText.lastIndexOf('\"') - proposedText.indexOf('\"') == 1 && proposedText.indexOf('\'') == -1)) ? getRequiredName(node, attrDecl) : proposedText, null, proposedInfo, XMLRelevanceConstants.R_XML_ATTRIBUTE_NAME + isRequired);
}
contentAssistRequest.addProposal(proposal);
}
}
}
}
} else {
setErrorMessage(NLS.bind(XMLUIMessages.Element__is_unknown, (new Object[] { node.getNodeName() })));
}
}
use of org.eclipse.wst.xml.core.internal.contentmodel.CMElementDeclaration in project webtools.sourceediting by eclipse.
the class AbstractXMLModelQueryCompletionProposalComputer method addTagCloseProposals.
/**
* Close an unclosed start tag
*/
protected void addTagCloseProposals(ContentAssistRequest contentAssistRequest, CompletionProposalInvocationContext context) {
IDOMNode node = (IDOMNode) contentAssistRequest.getParent();
if (node.getNodeType() == Node.ELEMENT_NODE) {
CMElementDeclaration elementDecl = getCMElementDeclaration(node);
String proposedInfo = (elementDecl != null) ? getAdditionalInfo(null, elementDecl) : null;
int contentType = (elementDecl != null) ? elementDecl.getContentType() : CMElementDeclaration.ANY;
// if it's XML and content doesn't HAVE to be element, add "/>" proposal.
boolean endWithSlashBracket = (isXMLNode(node) && (contentType != CMElementDeclaration.ELEMENT));
// get the image
Image image = CMImageUtil.getImage(elementDecl);
if (image == null) {
image = this.getGenericTagImage();
}
// is the start tag ended properly?
if ((contentAssistRequest.getDocumentRegion() == node.getFirstStructuredDocumentRegion()) && !(node.getFirstStructuredDocumentRegion()).isEnded()) {
setErrorMessage(null);
// tell, we assume it's not.
if ((elementDecl != null) && (elementDecl.getContentType() == CMElementDeclaration.EMPTY)) {
// prompt with a self-closing end character if needed
// this is one of the few times to ignore the length -- always insert
// contentAssistRequest.getReplacementLength()
CustomCompletionProposal proposal = new MarkupCompletionProposal(getContentGenerator().getStartTagClose(node, elementDecl), contentAssistRequest.getReplacementBeginPosition(), 0, getContentGenerator().getStartTagClose(node, elementDecl).length(), image, NLS.bind(XMLUIMessages.Close_with___, (new Object[] { getContentGenerator().getStartTagClose(node, elementDecl) })), null, proposedInfo, XMLRelevanceConstants.R_CLOSE_TAG);
contentAssistRequest.addProposal(proposal);
} else {
// prompt with a close for the start tag
CustomCompletionProposal proposal = new // $NON-NLS-1$
MarkupCompletionProposal(// $NON-NLS-1$
">", contentAssistRequest.getReplacementBeginPosition(), // $NON-NLS-1$
0, // $NON-NLS-1$
1, // $NON-NLS-1$
image, // $NON-NLS-1$
NLS.bind(XMLUIMessages.Close_with__, (new Object[] { " '>'" })), null, proposedInfo, XMLRelevanceConstants.R_CLOSE_TAG);
contentAssistRequest.addProposal(proposal);
// prompt with the closer for the start tag and an end tag if one is not present
if (node.getEndStructuredDocumentRegion() == null) {
// make sure tag name is actually what it thinks it
// is...(eg. <%@ vs. <jsp:directive)
IStructuredDocumentRegion sdr = contentAssistRequest.getDocumentRegion();
// $NON-NLS-1$
String openingTagText = (sdr != null) ? sdr.getFullText() : "";
if ((openingTagText != null) && (openingTagText.indexOf(node.getNodeName()) != -1)) {
proposal = new // $NON-NLS-2$//$NON-NLS-1$
MarkupCompletionProposal(// $NON-NLS-2$//$NON-NLS-1$
"></" + node.getNodeName() + ">", contentAssistRequest.getReplacementBeginPosition(), // contentAssistRequest.getReplacementLength(),
0, 1, image, NLS.bind(XMLUIMessages.Close_with____, (new Object[] { node.getNodeName() })), null, proposedInfo, XMLRelevanceConstants.R_CLOSE_TAG);
contentAssistRequest.addProposal(proposal);
}
}
// prompt with slash bracket "/>" incase if it's a self ending tag
if (endWithSlashBracket) {
proposal = new // $NON-NLS-1$
MarkupCompletionProposal(// $NON-NLS-1$
"/>", contentAssistRequest.getReplacementBeginPosition(), // $NON-NLS-1$
0, // $NON-NLS-1$
2, // $NON-NLS-1$
image, // $NON-NLS-1$
NLS.bind(XMLUIMessages.Close_with__, (new Object[] { " \"/>\"" })), null, proposedInfo, // +1
XMLRelevanceConstants.R_CLOSE_TAG + 1);
// to bring to top of list
contentAssistRequest.addProposal(proposal);
}
}
} else if ((contentAssistRequest.getDocumentRegion() == node.getLastStructuredDocumentRegion()) && !node.getLastStructuredDocumentRegion().isEnded()) {
setErrorMessage(null);
// prompt with a closing end character for the end tag
CustomCompletionProposal proposal = new // $NON-NLS-1$
MarkupCompletionProposal(// $NON-NLS-1$
">", contentAssistRequest.getReplacementBeginPosition(), // $NON-NLS-1$
0, // $NON-NLS-1$
1, // $NON-NLS-1$
image, // $NON-NLS-1$
NLS.bind(XMLUIMessages.Close_with__, (new Object[] { " '>'" })), null, proposedInfo, XMLRelevanceConstants.R_CLOSE_TAG);
contentAssistRequest.addProposal(proposal);
}
} else if (node.getNodeType() == Node.DOCUMENT_NODE) {
setErrorMessage(XMLUIMessages.Content_Assist_not_availab_UI_);
}
}
use of org.eclipse.wst.xml.core.internal.contentmodel.CMElementDeclaration in project webtools.sourceediting by eclipse.
the class AbstractXMLModelQueryCompletionProposalComputer method addEndTagNameProposals.
/**
* Add the proposals for the name in an end tag
*/
protected void addEndTagNameProposals(ContentAssistRequest contentAssistRequest, CompletionProposalInvocationContext context) {
if (contentAssistRequest.getStartOffset() + contentAssistRequest.getRegion().getTextLength() < contentAssistRequest.getReplacementBeginPosition()) {
CustomCompletionProposal proposal = new // $NON-NLS-1$
MarkupCompletionProposal(// $NON-NLS-1$
">", // $NON-NLS-1$
contentAssistRequest.getReplacementBeginPosition(), // $NON-NLS-1$
contentAssistRequest.getReplacementLength(), // $NON-NLS-1$
1, // $NON-NLS-1$
XMLEditorPluginImageHelper.getInstance().getImage(XMLEditorPluginImages.IMG_OBJ_TAG_GENERIC), // $NON-NLS-1$
NLS.bind(XMLUIMessages.Close_with__, (new Object[] { " '>'" })), null, null, XMLRelevanceConstants.R_END_TAG_NAME);
contentAssistRequest.addProposal(proposal);
} else {
Node aNode = contentAssistRequest.getNode();
String matchString = contentAssistRequest.getMatchString();
if (matchString.startsWith("</")) {
// $NON-NLS-1$
matchString = matchString.substring(2);
}
while (aNode != null) {
if (aNode.getNodeType() == Node.ELEMENT_NODE) {
if (aNode.getNodeName().startsWith(matchString)) {
IDOMNode aXMLNode = (IDOMNode) aNode;
CMElementDeclaration ed = getCMElementDeclaration(aNode);
// declaration must be valid for this computer to make proposal
if ((aXMLNode.getEndStructuredDocumentRegion() == null) && (ed == null || (validModelQueryNode(ed) && ed.getContentType() != CMElementDeclaration.EMPTY))) {
String replacementText = aNode.getNodeName();
String displayText = replacementText;
String proposedInfo = (ed != null) ? getAdditionalInfo(null, ed) : null;
if (!contentAssistRequest.getDocumentRegion().isEnded()) {
// $NON-NLS-1$
replacementText += ">";
}
CustomCompletionProposal proposal = null;
// double check to see if the region acted upon is
// a tag name; replace it if so
Image image = CMImageUtil.getImage(ed);
if (image == null) {
image = this.getGenericTagImage();
}
if (contentAssistRequest.getRegion().getType() == DOMRegionContext.XML_TAG_NAME) {
proposal = new MarkupCompletionProposal(replacementText, contentAssistRequest.getStartOffset(), contentAssistRequest.getRegion().getTextLength(), replacementText.length(), image, displayText, null, proposedInfo, XMLRelevanceConstants.R_END_TAG_NAME);
} else {
proposal = new MarkupCompletionProposal(replacementText, contentAssistRequest.getReplacementBeginPosition(), contentAssistRequest.getReplacementLength(), replacementText.length(), image, NLS.bind(XMLUIMessages.Close_with__, // $NON-NLS-1$ //$NON-NLS-2$
(new Object[] { "'" + displayText + "'" })), null, proposedInfo, XMLRelevanceConstants.R_END_TAG_NAME);
}
contentAssistRequest.addProposal(proposal);
}
}
}
aNode = aNode.getParentNode();
}
}
}
Aggregations