Skip to content

Commit

Permalink
Hover for attribuite values using XSD
Browse files Browse the repository at this point in the history
Fixes eclipse#12

Signed-off-by: Nikolas Komonen <[email protected]>
  • Loading branch information
NikolasKomonen committed Mar 28, 2019
1 parent cb0c290 commit a959cb7
Show file tree
Hide file tree
Showing 7 changed files with 157 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,10 @@ public void setNodeAttrValue(DOMNode nodeAttrValue) {
this.nodeAttrValue = nodeAttrValue;
}

public boolean valueContainsOffset(int offset) {
return nodeAttrValue != null && offset >= nodeAttrValue.getStart() && offset < nodeAttrValue.getEnd();
}

public boolean isIncluded(int offset) {
return DOMNode.isIncluded(getStart(), getEnd(), offset);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ public interface CMAttributeDeclaration {

String getDocumentation();

String getValueDocumentation(String value);

/**
* Returns true if the attribute is required and false otherwise.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,42 @@ public Hover onAttributeName(IHoverRequest hoverRequest) throws Exception {
return null;
}

@Override
public Hover onAttributeValue(IHoverRequest hoverRequest) throws Exception {
DOMAttr attribute = (DOMAttr) hoverRequest.getNode();

//Attempts to compute specifically for XSI related attributes since
//the XSD itself does not have enough information. Should create a mock XSD eventually.
Hover temp = XSISchemaModel.computeHoverResponse(attribute, hoverRequest);
if(temp != null) {
return temp;
}

try {
ContentModelManager contentModelManager = hoverRequest.getComponent(ContentModelManager.class);

CMElementDeclaration cmElement = contentModelManager.findCMElement(attribute.getOwnerElement());
if (cmElement != null) {
String attributeName = attribute.getName();
CMAttributeDeclaration cmAttribute = cmElement.findCMAttribute(attributeName);

String attributeValue = attribute.getValue();
if (cmAttribute != null) {
String doc = cmAttribute.getValueDocumentation(attributeValue);
if (doc != null && doc.length() > 0) {
MarkupContent content = new MarkupContent();
content.setKind(MarkupKind.PLAINTEXT);
content.setValue(doc);
return new Hover(content);
}
}
}
} catch (CacheResourceDownloadingException e) {
return getCacheWarningHover(e);
}
return null;
}

private Hover getCacheWarningHover(CacheResourceDownloadingException e) {
// Here cache is enabled and some XML Schema, DTD, etc are loading
MarkupContent content = new MarkupContent();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,4 +53,9 @@ public boolean isRequired() {
return super.simpleType.defaultType == XMLSimpleType.DEFAULT_TYPE_REQUIRED;
}

@Override
public String getValueDocumentation(String value) {
return null;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import org.apache.xerces.xs.XSSimpleTypeDefinition;
import org.apache.xerces.xs.XSTypeDefinition;
import org.apache.xerces.xs.XSValue;
import org.apache.xerces.xs.datatypes.ObjectList;
import org.eclipse.lsp4xml.extensions.contentmodel.model.CMAttributeDeclaration;

/**
Expand Down Expand Up @@ -63,6 +64,17 @@ public String getDocumentation() {
return documentation;
}

@Override
public String getValueDocumentation(String value) {
if (documentation != null) {
return documentation;
}
// Try get xs:annotation from the element declaration or type
XSObjectList annotations = getValueAnnotations();
documentation = XSDAnnotationModel.getDocumentation(annotations, value);
return documentation;
}

/**
* Returns list of xs:annotation from the element declaration or type
* declaration.
Expand All @@ -74,6 +86,50 @@ private XSObjectList getAnnotations() {
// Try get xs:annotation from the element declaration
XSAttributeDeclaration attributeDeclaration = getAttrDeclaration();
XSObjectList annotation = attributeDeclaration.getAnnotations();

if (annotation != null && annotation.getLength() > 0) {
return annotation;
}
// Try get xs:annotation from the type of element declaration
XSTypeDefinition typeDefinition = attributeDeclaration.getTypeDefinition();
if (typeDefinition == null) {
return null;
}
if (typeDefinition.getTypeCategory() == XSTypeDefinition.COMPLEX_TYPE) {
return ((XSComplexTypeDecl) typeDefinition).getAnnotations();
} else if (typeDefinition.getTypeCategory() == XSTypeDefinition.SIMPLE_TYPE) {
return ((XSSimpleTypeDecl) typeDefinition).getAnnotations();
}
return null;
}

/**
* Returns list of xs:annotation from the element declaration or type
* declaration.
*
* @return list of xs:annotation from the element declaration or type
* declaration.
*/
private XSObjectList getValueAnnotations() {
// Try get xs:annotation from the element declaration
XSAttributeDeclaration attributeDeclaration = getAttrDeclaration();
XSSimpleTypeDefinition simpleTypeDefinition = attributeDeclaration.getTypeDefinition();
XSSimpleTypeDecl simpleTypeDecl;


XSObjectList annotation = null; // The XSD tag that holds the documentation tag

if(simpleTypeDefinition != null && simpleTypeDefinition instanceof XSSimpleTypeDecl) {
simpleTypeDecl = (XSSimpleTypeDecl) simpleTypeDefinition;
XSObjectList tempList = simpleTypeDecl.getMultiValueFacets();
if(!tempList.isEmpty()) {
// there is specific documentation for the value
annotation = tempList;
}
}
else if(annotation == null){ // There was no specific documentation for the value, so use the general attribute documentation
annotation = attributeDeclaration.getAnnotations();
}
if (annotation != null && annotation.getLength() > 0) {
return annotation;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,11 @@
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.apache.xerces.impl.dv.xs.XSSimpleTypeDecl;
import org.apache.xerces.xs.XSAnnotation;
import org.apache.xerces.xs.XSMultiValueFacet;
import org.apache.xerces.xs.XSObjectList;
import org.apache.xerces.xs.datatypes.ObjectList;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
Expand Down Expand Up @@ -47,13 +50,32 @@ public String getDocumentation() {
}

public static String getDocumentation(XSObjectList annotations) {
return getDocumentation(annotations, null);
}

public static String getDocumentation(XSObjectList annotations, String value) {
if (annotations == null) {
return "";
}
StringBuilder doc = new StringBuilder();
for (Object object : annotations) {
XSAnnotation annotation = (XSAnnotation) object;
XSDAnnotationModel annotationModel = XSDAnnotationModel.load(annotation);
XSAnnotation annotation = null;
if(object instanceof XSMultiValueFacet) {
XSMultiValueFacet dd = (XSMultiValueFacet) object;
ObjectList enumerationValues = dd.getEnumerationValues();
XSObjectList annotationValues = dd.getAnnotations();
for (int i = 0; i < enumerationValues.getLength(); i++) {
if(enumerationValues.get(i).equals(value)) {
annotation = (XSAnnotation) annotationValues.get(i);
}
}
}
else if(object instanceof XSAnnotation) {
annotation = (XSAnnotation) object;
}


XSDAnnotationModel annotationModel = null;//XSDAnnotationModel.load(annotation);
if (annotationModel != null) {
if (annotationModel.getAppInfo() != null) {
doc.append(annotationModel.getAppInfo());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import org.eclipse.lsp4j.Position;
import org.eclipse.lsp4j.Range;
import org.eclipse.lsp4xml.commons.BadLocationException;
import org.eclipse.lsp4xml.dom.DOMAttr;
import org.eclipse.lsp4xml.dom.DOMDocument;
import org.eclipse.lsp4xml.dom.DOMElement;
import org.eclipse.lsp4xml.dom.DOMNode;
Expand Down Expand Up @@ -69,8 +70,12 @@ public Hover doHover(DOMDocument xmlDocument, Position position) {
return getTagHover(hoverRequest, tagRange, true);
}
} else if (node.isAttribute()) {
DOMAttr attr = (DOMAttr) node;
if(attr.valueContainsOffset(offset)) {
return getAttrValueHover(hoverRequest, null);
}
// Attribute is hover
return getAttrHover(hoverRequest, null);
return getAttrNameHover(hoverRequest, null);
}
return null;
}
Expand Down Expand Up @@ -126,7 +131,7 @@ private Range getTagNameRange(TokenType tokenType, int startOffset, int offset,
* @param attrRange the attribute range
* @return the LSP hover from the hovered attribute.
*/
private Hover getAttrHover(HoverRequest hoverRequest, Range attrRange) {
private Hover getAttrNameHover(HoverRequest hoverRequest, Range attrRange) {
//hoverRequest.setTagRange(tagRange);
//hoverRequest.setOpen(open);
for (IHoverParticipant participant : extensionsRegistry.getHoverParticipants()) {
Expand All @@ -141,4 +146,27 @@ private Hover getAttrHover(HoverRequest hoverRequest, Range attrRange) {
}
return null;
}

/**
* Returns the LSP hover from the hovered attribute.
*
* @param hoverRequest the hover request.
* @param attrRange the attribute range
* @return the LSP hover from the hovered attribute.
*/
private Hover getAttrValueHover(HoverRequest hoverRequest, Range attrRange) {
//hoverRequest.setTagRange(tagRange);
//hoverRequest.setOpen(open);
for (IHoverParticipant participant : extensionsRegistry.getHoverParticipants()) {
try {
Hover hover = participant.onAttributeValue(hoverRequest);
if (hover != null) {
return hover;
}
} catch (Exception e) {
LOGGER.log(Level.SEVERE, "While performing IHoverParticipant#onTag", e);
}
}
return null;
}
}

0 comments on commit a959cb7

Please sign in to comment.