Switch HTML hover tests to markdown tests
This commit is contained in:
@@ -1,137 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2016 Pivotal, Inc.
|
||||
* 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:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.application.properties.metadata.hover;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
import org.springframework.ide.vscode.commons.util.HtmlBuffer;
|
||||
import org.springframework.ide.vscode.commons.util.Renderable;
|
||||
import org.springframework.ide.vscode.commons.util.Renderables;
|
||||
import org.springframework.ide.vscode.commons.util.StringUtil;
|
||||
|
||||
public abstract class AbstractPropertyRenderableProvider {
|
||||
|
||||
/**
|
||||
* Fake host name that is used in 'action link' urls so that we can
|
||||
* recognize them as such.
|
||||
*/
|
||||
private static final String ACTION_HOST = "action";
|
||||
|
||||
public Renderable getRenderable() {
|
||||
return new Renderable() {
|
||||
|
||||
@Override
|
||||
public void renderAsHtml(HtmlBuffer buffer) {
|
||||
// JavaTypeLinks jtLinks = new JavaTypeLinks(this);
|
||||
|
||||
renderId(buffer);
|
||||
|
||||
String type = getType();
|
||||
if (type==null) {
|
||||
type = Object.class.getName();
|
||||
}
|
||||
// jtLinks.javaTypeLink(html, getJavaProject(), type);
|
||||
actionLink(buffer, type);
|
||||
|
||||
String deflt = formatDefaultValue(getDefaultValue());
|
||||
if (deflt!=null) {
|
||||
buffer.raw("<br><br>");
|
||||
buffer.text("Default: ");
|
||||
buffer.raw("<i>");
|
||||
buffer.text(deflt);
|
||||
buffer.raw("</i>");
|
||||
}
|
||||
|
||||
if (isDeprecated()) {
|
||||
buffer.raw("<br><br>");
|
||||
String reason = getDeprecationReason();
|
||||
if (StringUtil.hasText(reason)) {
|
||||
buffer.bold("Deprecated: ");
|
||||
buffer.text(reason);
|
||||
} else {
|
||||
buffer.bold("Deprecated!");
|
||||
}
|
||||
}
|
||||
|
||||
Renderable description = getDescription();
|
||||
if (description!=null) {
|
||||
buffer.raw("<br><br>");
|
||||
buffer.p(description.toHtml());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderAsMarkdown(StringBuilder buffer) {
|
||||
buffer.append(Renderables.getHtmlToMarkdownConverter().convert(toHtml()));
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
final protected void renderId(HtmlBuffer html) {
|
||||
boolean deprecated = isDeprecated();
|
||||
String tag = deprecated ? "s" : "b";
|
||||
String replacement = getDeprecationReplacement();
|
||||
|
||||
html.raw("<"+tag+">");
|
||||
html.text(getId());
|
||||
html.raw("</"+tag+">");
|
||||
if (StringUtil.hasText(replacement)) {
|
||||
html.text(" -> "+ replacement);
|
||||
}
|
||||
html.raw("<br>");
|
||||
}
|
||||
|
||||
protected abstract Object getDefaultValue();
|
||||
protected abstract IJavaProject getJavaProject();
|
||||
protected abstract Renderable getDescription();
|
||||
protected abstract String getType();
|
||||
protected abstract String getDeprecationReason();
|
||||
protected abstract String getId();
|
||||
protected abstract String getDeprecationReplacement();
|
||||
protected abstract boolean isDeprecated();
|
||||
|
||||
public static String formatDefaultValue(Object defaultValue) {
|
||||
if (defaultValue!=null) {
|
||||
if (defaultValue instanceof String) {
|
||||
return (String) defaultValue;
|
||||
} else if (defaultValue instanceof Number) {
|
||||
return ((Number)defaultValue).toString();
|
||||
} else if (defaultValue instanceof Boolean) {
|
||||
return Boolean.toString((Boolean) defaultValue);
|
||||
} else if (defaultValue instanceof Object[]) {
|
||||
return StringUtil.arrayToCommaDelimitedString((Object[]) defaultValue);
|
||||
} else if (defaultValue instanceof Collection<?>) {
|
||||
return StringUtil.collectionToCommaDelimitedString((Collection<?>) defaultValue);
|
||||
} else {
|
||||
//no idea what it is but try 'toString' and hope for the best
|
||||
return defaultValue.toString();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an 'action' link and adds it to the html buffer. When the user clicks the given
|
||||
* link then the provided runnable is to be executed.
|
||||
*/
|
||||
public void actionLink(HtmlBuffer html, String displayString/*, Runnable runnable*/) {
|
||||
// String actionId = registerAction(runnable);
|
||||
html.raw("<a href=\"http://"+ACTION_HOST+"/");
|
||||
html.url("action-id");
|
||||
html.raw("\">");
|
||||
html.text(displayString);
|
||||
html.raw("</a>");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,228 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2016 Pivotal, Inc.
|
||||
* 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:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.application.properties.metadata.hover;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.springframework.boot.configurationmetadata.ConfigurationMetadataProperty;
|
||||
import org.springframework.ide.vscode.application.properties.metadata.PropertyInfo;
|
||||
import org.springframework.ide.vscode.application.properties.metadata.PropertyInfo.PropertySource;
|
||||
import org.springframework.ide.vscode.commons.java.IJavaElement;
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
import org.springframework.ide.vscode.commons.java.IMethod;
|
||||
import org.springframework.ide.vscode.commons.java.IType;
|
||||
import org.springframework.ide.vscode.commons.util.Log;
|
||||
import org.springframework.ide.vscode.commons.util.Renderable;
|
||||
import org.springframework.ide.vscode.commons.util.Renderables;
|
||||
import org.springframework.ide.vscode.commons.util.StringUtil;
|
||||
|
||||
|
||||
/**
|
||||
* Information object that is displayed in SpringPropertiesTextHover's information
|
||||
* control.
|
||||
* <p>
|
||||
* Essentially this is a wrapper around {@link ConfigurationMetadataProperty}
|
||||
*
|
||||
* @author Kris De Volder
|
||||
*/
|
||||
public class PropertyRenderableProvider extends AbstractPropertyRenderableProvider {
|
||||
|
||||
/**
|
||||
* Java project which is used to find declaration for 'navigate to declaration' action
|
||||
*/
|
||||
private IJavaProject javaProject;
|
||||
|
||||
/**
|
||||
* Data object to display in 'hover text'
|
||||
*/
|
||||
private PropertyInfo data;
|
||||
|
||||
public PropertyRenderableProvider(IJavaProject project, PropertyInfo data) {
|
||||
this.javaProject = project;
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public PropertyInfo getElement() {
|
||||
return data;
|
||||
}
|
||||
|
||||
public boolean canOpenDeclaration() {
|
||||
return getJavaElements()!=null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Like 'getSources' but converts raw info into IJavaElements. Raw data which fails to be converted
|
||||
* is silenetly ignored.
|
||||
*/
|
||||
public List<IJavaElement> getJavaElements() {
|
||||
try {
|
||||
if (javaProject!=null) {
|
||||
List<PropertySource> sources = getSources();
|
||||
if (!sources.isEmpty()) {
|
||||
ArrayList<IJavaElement> elements = new ArrayList<IJavaElement>();
|
||||
for (PropertySource source : sources) {
|
||||
String typeName = source.getSourceType();
|
||||
if (typeName!=null) {
|
||||
IType type = javaProject.findType(typeName);
|
||||
IMethod method = null;
|
||||
if (type!=null) {
|
||||
String methodSig = source.getSourceMethod();
|
||||
if (methodSig!=null) {
|
||||
method = getMethod(type, methodSig);
|
||||
} else {
|
||||
method = getSetter(type, getElement());
|
||||
}
|
||||
}
|
||||
if (method!=null) {
|
||||
elements.add(method);
|
||||
} else if (type!=null) {
|
||||
elements.add(type);
|
||||
}
|
||||
}
|
||||
}
|
||||
return elements;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.log(e);
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to find corresponding setter method for a given property.
|
||||
* @return setter method, or null if not found.
|
||||
*/
|
||||
private IMethod getSetter(IType type, PropertyInfo propertyInfo) {
|
||||
try {
|
||||
String propName = propertyInfo.getName();
|
||||
String setterName = "set"
|
||||
+Character.toUpperCase(propName.charAt(0))
|
||||
+toCamelCase(propName.substring(1));
|
||||
String sloppySetterName = setterName.toLowerCase();
|
||||
|
||||
IMethod sloppyMatch = null;
|
||||
for (IMethod m : type.getMethods().collect(Collectors.toList())) {
|
||||
String mname = m.getElementName();
|
||||
if (setterName.equals(mname)) {
|
||||
//found 'exact' name match... done
|
||||
return m;
|
||||
} else if (mname.toLowerCase().equals(sloppySetterName)) {
|
||||
sloppyMatch = m;
|
||||
}
|
||||
}
|
||||
return sloppyMatch;
|
||||
} catch (Exception e) {
|
||||
Log.log(e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert hyphened name to camel case name. It is
|
||||
* safe to call this on an already camel-cased name.
|
||||
*/
|
||||
private String toCamelCase(String name) {
|
||||
if (name.isEmpty()) {
|
||||
return name;
|
||||
} else {
|
||||
StringBuilder camel = new StringBuilder();
|
||||
char[] chars = name.toCharArray();
|
||||
for (int i = 0; i < chars.length; i++) {
|
||||
char c = chars[i];
|
||||
if (c=='-') {
|
||||
i++;
|
||||
if (i<chars.length) {
|
||||
camel.append(Character.toUpperCase(chars[i]));
|
||||
}
|
||||
} else {
|
||||
camel.append(chars[i]);
|
||||
}
|
||||
}
|
||||
return camel.toString();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get 'raw' info about sources that define this property.
|
||||
*/
|
||||
public List<PropertySource> getSources() {
|
||||
return data.getSources();
|
||||
}
|
||||
|
||||
private IMethod getMethod(IType type, String methodSig) {
|
||||
int nameEnd = methodSig.indexOf('(');
|
||||
String name;
|
||||
if (nameEnd>=0) {
|
||||
name = methodSig.substring(0, nameEnd);
|
||||
} else {
|
||||
name = methodSig;
|
||||
}
|
||||
//TODO: This code assumes 0 arguments, which is the case currently for all
|
||||
// 'real' data in spring jars.
|
||||
IMethod m = type.getMethod(name, Stream.empty());
|
||||
if (m!=null) {
|
||||
return m;
|
||||
}
|
||||
//try find a method with the same name.
|
||||
return type.getMethods().filter(meth -> name.equals(meth.getElementName())).findFirst().orElse(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object getDefaultValue() {
|
||||
return data.getDefaultValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected IJavaProject getJavaProject() {
|
||||
return javaProject;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Renderable getDescription() {
|
||||
String desc = data.getDescription();
|
||||
if (StringUtil.hasText(desc)) {
|
||||
return Renderables.text(desc);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getType() {
|
||||
return data.getType();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getDeprecationReason() {
|
||||
return data.getDeprecationReason();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getId() {
|
||||
return data.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getDeprecationReplacement() {
|
||||
return data.getDeprecationReplacement();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isDeprecated() {
|
||||
return data.isDeprecated();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -11,8 +11,7 @@
|
||||
package org.springframework.ide.vscode.commons.util;
|
||||
|
||||
/**
|
||||
* Placeholder. Still need to figure out what exactly we should do with this in
|
||||
* vscode. TODO: rename to Renderable
|
||||
* Renderable can be rendered with various mark-up languages
|
||||
*/
|
||||
public interface Renderable {
|
||||
|
||||
|
||||
@@ -95,6 +95,44 @@ public class Renderables {
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static Renderable paragraph(Renderable text) {
|
||||
return new Renderable() {
|
||||
|
||||
@Override
|
||||
public void renderAsMarkdown(StringBuilder buffer) {
|
||||
buffer.append("\n");
|
||||
text.renderAsMarkdown(buffer);
|
||||
buffer.append("\n");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderAsHtml(HtmlBuffer buffer) {
|
||||
buffer.raw("<p>");
|
||||
text.renderAsHtml(buffer);
|
||||
buffer.raw("</p>");
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static Renderable strikeThrough(Renderable text) {
|
||||
return new Renderable() {
|
||||
|
||||
@Override
|
||||
public void renderAsMarkdown(StringBuilder buffer) {
|
||||
buffer.append("~~");
|
||||
text.renderAsMarkdown(buffer);
|
||||
buffer.append("~~");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderAsHtml(HtmlBuffer buffer) {
|
||||
buffer.raw("<s>");
|
||||
text.renderAsHtml(buffer);
|
||||
buffer.raw("</s>");
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static Renderable link(String text, String url) {
|
||||
return new Renderable() {
|
||||
@@ -127,7 +165,11 @@ public class Renderables {
|
||||
|
||||
@Override
|
||||
public void renderAsMarkdown(StringBuilder buffer) {
|
||||
buffer.append("\n\n");
|
||||
if (buffer.charAt(buffer.length() - 1) != '\n') {
|
||||
// 2 spaces and then new line would create a line break in text
|
||||
buffer.append(" ");
|
||||
}
|
||||
buffer.append("\n");
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -230,7 +272,7 @@ public class Renderables {
|
||||
|
||||
private Renderable[] pieces;
|
||||
|
||||
ConcatRenderables(Renderable[] pieces) {
|
||||
ConcatRenderables(Renderable... pieces) {
|
||||
this.pieces = pieces;
|
||||
}
|
||||
|
||||
|
||||
@@ -50,6 +50,7 @@ public class YPropertyHoverInfo {
|
||||
|
||||
Renderable description = prop.getDescription();
|
||||
if (description != null) {
|
||||
html.add(lineBreak());
|
||||
html.add(lineBreak());
|
||||
html.add(description);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user