org.eclipse.wst.json.ui.internal.text.hover.HTMLJSONPrinter.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.wst.json.ui.internal.text.hover.HTMLJSONPrinter.java

Source

/**
 *  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) //$NON-NLS-1$
                    .append("')\"></span>\n"); //$NON-NLS-1$
            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='") //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$
                    .append(imageSrcPath).append("'/>\n"); //$NON-NLS-1$
            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='") //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$
                    .append(imageSrcPath).append("'/>\n"); //$NON-NLS-1$
            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);
    }
}