blob: 23aba9f2f8f4483e7863db915f3d7cd8d7f55cd3 [file] [log] [blame]
/**
* Copyright (c) 2013-2018 Angelo ZERR and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
*/
package org.eclipse.wst.json.ui.internal.text.hover;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import org.eclipse.core.runtime.Platform;
import org.eclipse.jface.internal.text.html.HTMLPrinter;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.json.jsonpath.IJSONPath;
import org.eclipse.json.schema.IJSONSchemaDocument;
import org.eclipse.json.schema.IJSONSchemaProperty;
import org.eclipse.swt.graphics.FontData;
import org.eclipse.wst.json.core.JSONCorePlugin;
import org.eclipse.wst.json.core.document.IJSONNode;
import org.eclipse.wst.json.core.document.IJSONPair;
import org.eclipse.wst.json.core.document.IJSONValue;
import org.eclipse.wst.json.ui.internal.JSONUIPlugin;
import org.eclipse.wst.json.ui.internal.Logger;
import org.eclipse.wst.json.ui.internal.editor.JSONEditorPluginImageHelper;
import org.osgi.framework.Bundle;
/**
* Provides a set of convenience methods for creating HTML info for JSON content
* assist and hover.
*
*/
public class HTMLJSONPrinter {
/**
* Style sheets content.
*/
private static String fgStyleSheet;
public static String getAdditionalProposalInfo(IJSONPair pair) {
StringBuilder builder = new StringBuilder();
ImageDescriptor descriptor = null;
IJSONValue value = pair.getValue();
if (value != null) {
descriptor = JSONEditorPluginImageHelper.getInstance()
.getImageDescriptor(value.getNodeType());
}
startPage(builder, getTitleKey(value), descriptor);
startDefinitionList(builder);
StringBuilder build = new StringBuilder();
build.append(pair.getName());
try {
IJSONSchemaDocument schemaDocument = JSONCorePlugin.getDefault()
.getSchemaDocument(pair);
if (schemaDocument != null) {
IJSONPath path = pair.getPath();
IJSONSchemaProperty property = schemaDocument
.getProperty(path);
if (property != null) {
String description = property.getDescription();
if (description != null) {
build.append(" - ");
build.append(description);
}
}
}
} catch (IOException e) {
Logger.logException(e);
}
addDefinitionListItem(builder, "Key", build.toString());
addDefinitionListItem(builder, "Type", getValueType(pair.getValue()));
endDefinitionList(builder);
endPage(builder);
return builder.toString();
}
private static String getTitleKey(IJSONValue value) {
return new StringBuilder("<b>JSON ").append(getValueType(value))
.append("</b>").toString();
}
private static String getValueType(IJSONValue value) {
if (value == null) {
return "?";
}
switch (value.getNodeType()) {
case IJSONNode.ARRAY_NODE:
return "Array";
case IJSONNode.DOCUMENT_NODE:
return "Document";
case IJSONNode.OBJECT_NODE:
return "Object";
case IJSONNode.VALUE_BOOLEAN_NODE:
return "Boolean";
case IJSONNode.VALUE_NULL_NODE:
return "Null";
case IJSONNode.VALUE_NUMBER_NODE:
return "Number";
case IJSONNode.VALUE_STRING_NODE:
return "String";
}
return "?";
}
public static String getAdditionalProposalInfo(IJSONValue value) {
StringBuilder buffer = new StringBuilder();
ImageDescriptor descriptor = JSONEditorPluginImageHelper.getInstance()
.getImageDescriptor(value.getNodeType());
startPage(buffer, "<b>JSON Value</b>", descriptor);
startDefinitionList(buffer);
addDefinitionListItem(buffer, "Value", value.getSimpleValue());
addDefinitionListItem(buffer, "Type", getValueType(value));
endDefinitionList(buffer);
endPage(buffer);
return buffer.toString();
}
private static String getTitle(IJSONValue value) {
StringBuilder title = new StringBuilder("<b>");
title.append(getValueType(value));
title.append("</b>");
return title.toString();
}
public static void startDefinitionList(StringBuilder builder) {
builder.append("<dl>"); //$NON-NLS-1$
}
public static void endDefinitionList(StringBuilder builder) {
builder.append("</dl>"); //$NON-NLS-1$
}
public static void addDefinitionListItem(StringBuilder builder, String name,
String value) {
if (value != null) {
builder.append("<dt><b>");
builder.append(name);
builder.append(":</b></dt>");
builder.append("<dd>");
builder.append(value);
builder.append("</dd>");
}
}
/**
* Returns the Javadoc hover style sheet with the current JSON font from the
* preferences.
*
* @return the updated style sheet
*/
private static String getStyleSheet() {
if (fgStyleSheet == null) {
fgStyleSheet = loadStyleSheet("/JSONHoverStyleSheet.css"); //$NON-NLS-1$
}
String css = fgStyleSheet;
if (css != null) {
FontData fontData = JFaceResources.getFontRegistry().getFontData(
JFaceResources.DIALOG_FONT)[0];
css = HTMLPrinter.convertTopLevelFont(css, fontData);
}
return css;
}
/**
* Loads and returns the style sheet associated with either JSON hover or
* the view.
*
* @param styleSheetName
* the style sheet name of either the Javadoc hover or the view
* @return the style sheet, or <code>null</code> if unable to load
*/
private static String loadStyleSheet(String styleSheetName) {
Bundle bundle = Platform.getBundle(JSONUIPlugin.PLUGIN_ID);
URL styleSheetURL = bundle.getEntry(styleSheetName);
if (styleSheetURL == null)
return null;
BufferedReader reader = null;
try {
reader = new BufferedReader(new InputStreamReader(
styleSheetURL.openStream()));
StringBuilder builder = new StringBuilder(1500);
String line = reader.readLine();
while (line != null) {
builder.append(line);
builder.append('\n');
line = reader.readLine();
}
FontData fontData = JFaceResources.getFontRegistry().getFontData(
JFaceResources.DIALOG_FONT)[0];
return HTMLPrinter.convertTopLevelFont(builder.toString(), fontData);
} catch (IOException ex) {
Logger.logException("Error while loading style sheets", ex);
return ""; //$NON-NLS-1$
} finally {
try {
if (reader != null)
reader.close();
} catch (IOException e) {
// ignore
}
}
}
public static void startPage(StringBuilder builder, String title,
ImageDescriptor descriptor) {
int imageWidth = 16;
int imageHeight = 16;
int labelLeft = 20;
int labelTop = 2;
// buf.append("<p>");
builder.append("<div style='word-wrap: break-word; position: relative; "); //$NON-NLS-1$
String imageSrcPath = getImageURL(descriptor);
if (imageSrcPath != null) {
builder.append("margin-left: ").append(labelLeft).append("px; "); //$NON-NLS-1$ //$NON-NLS-2$
builder.append("padding-top: ").append(labelTop).append("px; "); //$NON-NLS-1$ //$NON-NLS-2$
}
builder.append("'>"); //$NON-NLS-1$
if (imageSrcPath != null) {
String uri = ""; // HoverLocationListener.TERN_DEFINITION_PROTOCOL;
builder.append("<a href=\"");
builder.append(uri);
builder.append("\" >");
StringBuilder imageStyle = new StringBuilder(
"border:none; position: absolute; "); //$NON-NLS-1$
imageStyle.append("width: ").append(imageWidth).append("px; "); //$NON-NLS-1$ //$NON-NLS-2$
imageStyle.append("height: ").append(imageHeight).append("px; "); //$NON-NLS-1$ //$NON-NLS-2$
imageStyle.append("left: ").append(-labelLeft - 1).append("px; "); //$NON-NLS-1$ //$NON-NLS-2$
// hack for broken transparent PNG support in IE 6, see
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=223900 :
builder.append("<!--[if lte IE 6]><![if gte IE 5.5]>\n"); //$NON-NLS-1$
String tooltip = "alt='" + "" + "' "; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
builder.append("<span ").append(tooltip).append("style=\"").append(imageStyle). //$NON-NLS-1$ //$NON-NLS-2$
append("filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='").append(imageSrcPath).append("')\"></span>\n"); //$NON-NLS-1$ //$NON-NLS-2$
builder.append("<![endif]><![endif]-->\n"); //$NON-NLS-1$
builder.append("<!--[if !IE]>-->\n"); //$NON-NLS-1$
builder.append("<img ").append(tooltip).append("style='").append(imageStyle).append("' src='").append(imageSrcPath).append("'/>\n"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
builder.append("<!--<![endif]-->\n"); //$NON-NLS-1$
builder.append("<!--[if gte IE 7]>\n"); //$NON-NLS-1$
builder.append("<img ").append(tooltip).append("style='").append(imageStyle).append("' src='").append(imageSrcPath).append("'/>\n"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
builder.append("<![endif]-->\n"); //$NON-NLS-1$
// if (element != null) {
builder.append("</a>"); //$NON-NLS-1$
// }
}
builder.append(title);
builder.append("</div>"); //$NON-NLS-1$
builder.append("<hr />");
}
private static String getImageURL(ImageDescriptor descriptor) {
if (descriptor == null) {
return null;
}
String imageName = null;
URL imageUrl = JSONEditorPluginImageHelper.getInstance().getImageURL(
descriptor);
if (imageUrl != null) {
imageName = imageUrl.toExternalForm();
}
return imageName;
}
public static void endPage(StringBuilder builder) {
HTMLPrinter
.insertPageProlog(builder, 0, HTMLJSONPrinter.getStyleSheet());
HTMLPrinter.addPageEpilog(builder);
}
}