/**
* Copyright (c) 2013-2014 Angelo ZERR.
* 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:
* 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) {
StringBuffer buffer = new StringBuffer();
ImageDescriptor descriptor = null;
IJSONValue value = pair.getValue();
if (value != null) {
descriptor = JSONEditorPluginImageHelper.getInstance()
.getImageDescriptor(value.getNodeType());
}
startPage(buffer, getTitleKey(value), descriptor);
startDefinitionList(buffer);
StringBuffer buff = new StringBuffer();
buff.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) {
buff.append(" - ");
buff.append(description);
}
}
}
} catch (IOException e) {
Logger.logException(e);
}
addDefinitionListItem(buffer, "Key", buff.toString());
addDefinitionListItem(buffer, "Type", getValueType(pair.getValue()));
endDefinitionList(buffer);
endPage(buffer);
return buffer.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) {
StringBuffer buffer = new StringBuffer();
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(StringBuffer buffer) {
buffer.append("<dl>"); //$NON-NLS-1$
}
public static void endDefinitionList(StringBuffer buffer) {
buffer.append("</dl>"); //$NON-NLS-1$
}
public static void addDefinitionListItem(StringBuffer buffer, String name,
String value) {
if (value != null) {
buffer.append("<dt><b>");
buffer.append(name);
buffer.append(":</b></dt>");
buffer.append("<dd>");
buffer.append(value);
buffer.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()));
StringBuffer buffer = new StringBuffer(1500);
String line = reader.readLine();
while (line != null) {
buffer.append(line);
buffer.append('\n');
line = reader.readLine();
}
FontData fontData = JFaceResources.getFontRegistry().getFontData(
JFaceResources.DIALOG_FONT)[0];
return HTMLPrinter.convertTopLevelFont(buffer.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(StringBuffer buf, String title,
ImageDescriptor descriptor) {
int imageWidth = 16;
int imageHeight = 16;
int labelLeft = 20;
int labelTop = 2;
// buf.append("<p>");
buf.append("<div style='word-wrap: break-word; position: relative; "); //$NON-NLS-1$
String imageSrcPath = getImageURL(descriptor);
if (imageSrcPath != null) {
buf.append("margin-left: ").append(labelLeft).append("px; "); //$NON-NLS-1$ //$NON-NLS-2$
buf.append("padding-top: ").append(labelTop).append("px; "); //$NON-NLS-1$ //$NON-NLS-2$
}
buf.append("'>"); //$NON-NLS-1$
if (imageSrcPath != null) {
String uri = ""; // HoverLocationListener.TERN_DEFINITION_PROTOCOL;
buf.append("<a href=\"");
buf.append(uri);
buf.append("\" >");
StringBuffer imageStyle = new StringBuffer(
"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 :
buf.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$
buf.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$
buf.append("<![endif]><![endif]-->\n"); //$NON-NLS-1$
buf.append("<!--[if !IE]>-->\n"); //$NON-NLS-1$
buf.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$
buf.append("<!--<![endif]-->\n"); //$NON-NLS-1$
buf.append("<!--[if gte IE 7]>\n"); //$NON-NLS-1$
buf.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$
buf.append("<![endif]-->\n"); //$NON-NLS-1$
// if (element != null) {
buf.append("</a>"); //$NON-NLS-1$
// }
}
buf.append(title);
buf.append("</div>"); //$NON-NLS-1$
buf.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(StringBuffer buffer) {
HTMLPrinter
.insertPageProlog(buffer, 0, HTMLJSONPrinter.getStyleSheet());
HTMLPrinter.addPageEpilog(buffer);
}
}