Package org.pentaho.reporting.engine.classic.core.layout.richtext

Source Code of org.pentaho.reporting.engine.classic.core.layout.richtext.HtmlRichTextConverter

/*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software
* Foundation.
*
* You should have received a copy of the GNU Lesser General Public License along with this
* program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
* or from the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Lesser General Public License for more details.
*
* Copyright (c) 2009 Pentaho Corporation..  All rights reserved.
*/

package org.pentaho.reporting.engine.classic.core.layout.richtext;

import java.awt.Color;
import java.awt.Font;
import java.io.IOException;
import java.io.StreamTokenizer;
import java.io.StringReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Set;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import javax.swing.text.MutableAttributeSet;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;
import javax.swing.text.html.CSS;
import javax.swing.text.html.HTML;
import javax.swing.text.html.HTMLDocument;
import javax.swing.text.html.HTMLEditorKit;
import javax.swing.text.html.StyleSheet;

import org.pentaho.reporting.engine.classic.core.AttributeNames;
import org.pentaho.reporting.engine.classic.core.Band;
import org.pentaho.reporting.engine.classic.core.Element;
import org.pentaho.reporting.engine.classic.core.filter.types.ContentType;
import org.pentaho.reporting.engine.classic.core.filter.types.LabelType;
import org.pentaho.reporting.engine.classic.core.modules.parser.base.ReportParserUtil;
import org.pentaho.reporting.engine.classic.core.style.BandStyleKeys;
import org.pentaho.reporting.engine.classic.core.style.BorderStyle;
import org.pentaho.reporting.engine.classic.core.style.ElementStyleKeys;
import org.pentaho.reporting.engine.classic.core.style.StyleKey;
import org.pentaho.reporting.engine.classic.core.style.TextStyleKeys;
import org.pentaho.reporting.engine.classic.core.style.TextWrap;
import org.pentaho.reporting.engine.classic.core.style.VerticalTextAlign;
import org.pentaho.reporting.engine.classic.core.style.WhitespaceCollapse;
import org.pentaho.reporting.libraries.base.util.StringUtils;
import org.pentaho.reporting.libraries.xmlns.parser.ParseException;

/**
* This handles HTML 3.2 with some CSS support. It uses the Swing HTML parser to process the document.
*
* @author Thomas Morgner.
*/
public class HtmlRichTextConverter implements RichTextConverter
{
  private HTMLEditorKit editorKit;
  private static final Set BLOCK_ELEMENTS;

  static
  {
    final HashSet blockElements = new HashSet();
    blockElements.add(HTML.Tag.IMPLIED);
    blockElements.add(HTML.Tag.APPLET);
    blockElements.add(HTML.Tag.BODY);
    blockElements.add(HTML.Tag.BLOCKQUOTE);
    blockElements.add(HTML.Tag.DIV);
    blockElements.add(HTML.Tag.FORM);
    blockElements.add(HTML.Tag.FRAME);
    blockElements.add(HTML.Tag.FRAMESET);
    blockElements.add(HTML.Tag.H1);
    blockElements.add(HTML.Tag.H2);
    blockElements.add(HTML.Tag.H3);
    blockElements.add(HTML.Tag.H4);
    blockElements.add(HTML.Tag.H5);
    blockElements.add(HTML.Tag.H6);
    blockElements.add(HTML.Tag.HR);
    blockElements.add(HTML.Tag.HTML);
    blockElements.add(HTML.Tag.LI);
    blockElements.add(HTML.Tag.NOFRAMES);
    blockElements.add(HTML.Tag.OBJECT);
    blockElements.add(HTML.Tag.OL);
    blockElements.add(HTML.Tag.P);
    blockElements.add(HTML.Tag.PRE);
    blockElements.add(HTML.Tag.TABLE);
    blockElements.add(HTML.Tag.TR);
    blockElements.add(HTML.Tag.UL);

    BLOCK_ELEMENTS = Collections.unmodifiableSet(blockElements);
  }

  public HtmlRichTextConverter()
  {
    editorKit = new HTMLEditorKit();
  }

  public boolean isRecognizedType(final String mimeType)
  {
    if ("text/html".equals(mimeType))
    {
      return true;
    }
    return false;
  }

  public Object convert(final Element source, final Object value)
  {
    try
    {
      final Document doc = RichTextConverterUtilities.parseDocument(editorKit, value);
      if (doc == null)
      {
        return value;
      }

      final Element element = process(doc.getDefaultRootElement());
      return RichTextConverterUtilities.convertToBand(StyleKey.getDefinedStyleKeys(), source, element);
    }
    catch (Exception e)
    {
      return value;
    }
  }

  private static AttributeSet computeStyle(final javax.swing.text.Element elem, final StyleSheet styles)
  {
    final AttributeSet a = elem.getAttributes();
    final AttributeSet htmlAttr = styles.translateHTMLToCSS(a);
    final ArrayList muxList = new ArrayList();

    if (htmlAttr.getAttributeCount() != 0)
    {
      muxList.add(htmlAttr);
    }

    if (elem.isLeaf())
    {
      // The swing-parser has a very weird way of storing attributes for the HTML elements. The
      // tag-name is used as key for the attribute set, so you have to know the element type before
      // you can do anything sensible with it. Or as we do here, you have to search for the HTML.Tag
      // object. Arghh.
      final Enumeration keys = a.getAttributeNames();
      while (keys.hasMoreElements())
      {
        final Object key = keys.nextElement();
        if (!(key instanceof HTML.Tag))
        {
          continue;
        }

        if (key == HTML.Tag.A)
        {
          final Object o = a.getAttribute(key);
          if (o instanceof AttributeSet)
          {
            final AttributeSet attr = (AttributeSet) o;
            if (attr.getAttribute(HTML.Attribute.HREF) == null)
            {
              continue;
            }
          }
        }

        final AttributeSet cssRule = styles.getRule((HTML.Tag) key, elem);
        if (cssRule != null)
        {
          muxList.add(cssRule);
        }
      }
    }
    else
    {
      final HTML.Tag t = (HTML.Tag) a.getAttribute(StyleConstants.NameAttribute);
      final AttributeSet cssRule = styles.getRule(t, elem);
      if (cssRule != null)
      {
        muxList.add(cssRule);
      }
    }

    final MutableAttributeSet retval = new SimpleAttributeSet();
    for (int i = muxList.size() - 1; i >= 0; i--)
    {
      final AttributeSet o = (AttributeSet) muxList.get(i);
      retval.addAttributes(o);
    }
    return retval;
  }

  private Object convertURL(final String srcAttr)
  {
    try
    {
      return new URL(srcAttr);
    }
    catch (MalformedURLException e)
    {
      // ignore ..
      return srcAttr;
    }
  }

  private Element process(final javax.swing.text.Element textElement) throws BadLocationException
  {
    if (isInvisible(textElement))
    {
      return null;
    }

    if (textElement.isLeaf())
    {
      final AttributeSet attributes = textElement.getAttributes();
      if (HTML.Tag.IMG.equals(attributes.getAttribute(StyleConstants.NameAttribute)))
      {
        final Element result = new Element();
        result.setName(textElement.getName());
        result.setElementType(ContentType.INSTANCE);
        final String src = (String) attributes.getAttribute(HTML.Attribute.SRC);
        final String alt = (String) attributes.getAttribute(HTML.Attribute.TITLE);
        result.setAttribute(AttributeNames.Core.NAMESPACE, AttributeNames.Core.VALUE, convertURL(src));
        result.setAttribute(AttributeNames.Html.NAMESPACE, AttributeNames.Html.TITLE, alt);
        result.setAttribute(AttributeNames.Html.NAMESPACE, AttributeNames.Swing.TOOLTIP, alt);
        if (attributes.isDefined(HTML.Attribute.WIDTH) &&
            attributes.isDefined(HTML.Attribute.HEIGHT))
        {
          result.getStyle().setStyleProperty(ElementStyleKeys.SCALE, Boolean.TRUE);
          result.getStyle().setStyleProperty(ElementStyleKeys.KEEP_ASPECT_RATIO, Boolean.FALSE);
          result.getStyle().setStyleProperty(ElementStyleKeys.MIN_WIDTH,
              parseLength(String.valueOf(attributes.getAttribute(HTML.Attribute.WIDTH))));
          result.getStyle().setStyleProperty(ElementStyleKeys.MIN_HEIGHT,
              parseLength(String.valueOf(attributes.getAttribute(HTML.Attribute.HEIGHT))));
        }
        else if (attributes.isDefined(HTML.Attribute.WIDTH))
        {
          result.getStyle().setStyleProperty(ElementStyleKeys.SCALE, Boolean.TRUE);
          result.getStyle().setStyleProperty(ElementStyleKeys.KEEP_ASPECT_RATIO, Boolean.TRUE);
          result.getStyle().setStyleProperty(ElementStyleKeys.MIN_WIDTH,
              parseLength(String.valueOf(attributes.getAttribute(HTML.Attribute.WIDTH))));
          result.getStyle().setStyleProperty(ElementStyleKeys.DYNAMIC_HEIGHT, Boolean.TRUE);
        }
        else if (attributes.isDefined(HTML.Attribute.HEIGHT))
        {
          result.getStyle().setStyleProperty(ElementStyleKeys.SCALE, Boolean.TRUE);
          result.getStyle().setStyleProperty(ElementStyleKeys.KEEP_ASPECT_RATIO, Boolean.TRUE);
          result.getStyle().setStyleProperty(ElementStyleKeys.MIN_HEIGHT,
              parseLength(String.valueOf(attributes.getAttribute(HTML.Attribute.HEIGHT))));
          result.getStyle().setStyleProperty(ElementStyleKeys.DYNAMIC_HEIGHT, Boolean.TRUE);
        }
        else
        {
          result.getStyle().setStyleProperty(ElementStyleKeys.SCALE, Boolean.FALSE);
          result.getStyle().setStyleProperty(ElementStyleKeys.KEEP_ASPECT_RATIO, Boolean.TRUE);
          result.getStyle().setStyleProperty(ElementStyleKeys.DYNAMIC_HEIGHT, Boolean.TRUE);
        }
        configureStyle(textElement, result);
        return result;
      }

      final javax.swing.text.Element parent = textElement.getParentElement();
      final int endOffset = textElement.getEndOffset();
      final int startOffset = textElement.getStartOffset();
      final String text = textElement.getDocument().getText(startOffset, endOffset - startOffset);
      if (parent != null)
      {
        final HTML.Tag tag = findTag(parent.getAttributes());
        if ("\n".equals(text))
        {
          if (BLOCK_ELEMENTS.contains(tag) ||
              "paragraph".equals(textElement.getName()) ||
              "section".equals(textElement.getName()))
          {
            if (parent.getElementCount() > 0 && parent.getElement(parent.getElementCount() - 1) == textElement)
            {
              // Skipping an artificial \n at the end of paragraph element. This is generated by the swing
              // parser and really messes things up here.
              return null;
            }
          }
        }
      }
      final Element result = new Element();
      result.setName(textElement.getName());
      result.setElementType(LabelType.INSTANCE);
      result.setAttribute(AttributeNames.Core.NAMESPACE, AttributeNames.Core.VALUE, text);
      configureStyle(textElement, result);
      if (HTML.Tag.BR.equals(textElement.getAttributes().getAttribute(StyleConstants.NameAttribute)))
      {
        result.setAttribute(AttributeNames.Core.NAMESPACE, AttributeNames.Core.VALUE, "\n");
        result.getStyle().setStyleProperty(TextStyleKeys.TRIM_TEXT_CONTENT, Boolean.FALSE);
        result.getStyle().setStyleProperty(TextStyleKeys.WHITE_SPACE_COLLAPSE, WhitespaceCollapse.PRESERVE);
      }
      return result;
    }

    // we need to intercept for <UL> and <OL> here

    final Band band = new Band();
    configureStyle(textElement, band);
    configureBand(textElement, band);
    final boolean bandIsInline = isInlineElement(band);
    final int size = textElement.getElementCount();
    Band inlineContainer = null;
    for (int i = 0; i < size; i++)
    {
      final Element element = process(textElement.getElement(i));
      if (element == null)
      {
        continue;
      }

      if (isInlineElement(element) == bandIsInline)
      {
        band.addElement(element);
        continue;
      }

      if (band.getElementCount() == 0)
      {
        inlineContainer = new Band();
        inlineContainer.getStyle().setStyleProperty(BandStyleKeys.LAYOUT, "inline");
        inlineContainer.addElement(element);
        band.addElement(inlineContainer);
        continue;
      }

      final Element maybeInlineContainer = (Element) band.getElement(band.getElementCount() - 1);
      if (maybeInlineContainer == inlineContainer)
      {
        // InlineContainer cannot be null at this point, as band.getElement never returns null.
        //noinspection ConstantConditions
        inlineContainer.addElement(element);
        continue;
      }

      inlineContainer = new Band();
      inlineContainer.getStyle().setStyleProperty(BandStyleKeys.LAYOUT, "inline");
      inlineContainer.addElement(element);
      band.addElement(inlineContainer);
    }
    return band;
  }

  private boolean isInlineElement(final Element element)
  {
    if (element instanceof Band)
    {
      if ("inline".equals(element.getStyle().getStyleProperty(BandStyleKeys.LAYOUT, "inline")))
      {
        return true;
      }
      return false;
    }

    return true;
  }

  private boolean isInvisible(final javax.swing.text.Element textElement)
  {
    final HTMLDocument htmlDocument = (HTMLDocument) textElement.getDocument();
    final StyleSheet sheet = htmlDocument.getStyleSheet();
    final AttributeSet attr = computeStyle(textElement, sheet);
    final Object o = attr.getAttribute(CSS.Attribute.DISPLAY);
    if ("none".equals(String.valueOf(o)))
    {
      return true;
    }
    final Object tag = findTag(textElement.getAttributes());
    if (tag == HTML.Tag.COMMENT)
    {
      return true;
    }
    if (tag == HTML.Tag.SCRIPT)
    {
      return true;
    }
    if (tag == HTML.Tag.HEAD)
    {
      return true;
    }
    return false;
  }

  private void configureStyle(final javax.swing.text.Element textElement, final Element result)
  {
    final HTMLDocument htmlDocument = (HTMLDocument) textElement.getDocument();
    final StyleSheet sheet = htmlDocument.getStyleSheet();
    final AttributeSet attr = computeStyle(textElement, sheet);
    parseBorderAndBackgroundStyle(result, sheet, attr);
    parseBoxStyle(result, attr);

    final Font font = sheet.getFont(attr);
    if (font != null)
    {
      result.getStyle().setStyleProperty(TextStyleKeys.FONT, font.getFamily());
      result.getStyle().setStyleProperty(TextStyleKeys.FONTSIZE, new Integer(font.getSize()));
      result.getStyle().setBooleanStyleProperty(TextStyleKeys.ITALIC, font.isItalic());
      result.getStyle().setBooleanStyleProperty(TextStyleKeys.BOLD, font.isBold());
    }

    final Object letterSpacing = attr.getAttribute(CSS.Attribute.LETTER_SPACING);
    if (letterSpacing != null)
    {
      result.getStyle().setStyleProperty
          (TextStyleKeys.X_OPTIMUM_LETTER_SPACING, parseLength(String.valueOf(letterSpacing)));
    }

    final Object wordSpacing = attr.getAttribute(CSS.Attribute.WORD_SPACING);
    if (wordSpacing != null)
    {
      result.getStyle().setStyleProperty
          (TextStyleKeys.WORD_SPACING, parseLength(String.valueOf(wordSpacing)));
    }

    final Object lineHeight = attr.getAttribute(CSS.Attribute.LINE_HEIGHT);
    if (lineHeight != null)
    {
      result.getStyle().setStyleProperty
          (TextStyleKeys.LINEHEIGHT, parseLength(String.valueOf(lineHeight)));
    }
    final Object textAlign = attr.getAttribute(CSS.Attribute.TEXT_ALIGN);
    if (textAlign != null)
    {
      try
      {
        result.getStyle().setStyleProperty(ElementStyleKeys.ALIGNMENT,
            ReportParserUtil.parseHorizontalElementAlignment(String.valueOf(textAlign), null));
      }
      catch (ParseException e)
      {
        // ignore ..
      }
    }

    final Object textDecoration = attr.getAttribute(CSS.Attribute.TEXT_DECORATION);
    if (textDecoration != null)
    {
      final String[] strings = StringUtils.split(String.valueOf(textDecoration));
      result.getStyle().setStyleProperty(TextStyleKeys.STRIKETHROUGH, Boolean.FALSE);
      result.getStyle().setStyleProperty(TextStyleKeys.UNDERLINED, Boolean.FALSE);

      for (int i = 0; i < strings.length; i++)
      {
        final String value = strings[i];
        if ("line-through".equals(value))
        {
          result.getStyle().setStyleProperty(TextStyleKeys.STRIKETHROUGH, Boolean.TRUE);
        }
        if ("underline".equals(value))
        {
          result.getStyle().setStyleProperty(TextStyleKeys.UNDERLINED, Boolean.TRUE);
        }
      }
    }


    final Object valign = attr.getAttribute(CSS.Attribute.VERTICAL_ALIGN);
    if (valign != null)
    {
      final VerticalTextAlign valignValue = VerticalTextAlign.valueOf(String.valueOf(valign));
      result.getStyle().setStyleProperty(TextStyleKeys.VERTICAL_TEXT_ALIGNMENT, valignValue);
      try
      {
        result.getStyle().setStyleProperty(ElementStyleKeys.VALIGNMENT,
            ReportParserUtil.parseVerticalElementAlignment(String.valueOf(valign), null));
      }
      catch (ParseException e)
      {
        // ignore ..
      }
    }

    final Object whitespaceText = attr.getAttribute(CSS.Attribute.WHITE_SPACE);
    if (whitespaceText != null)
    {
      final String value = String.valueOf(whitespaceText);
      if ("pre".equals(value))
      {
        result.getStyle().setStyleProperty(TextStyleKeys.WHITE_SPACE_COLLAPSE, WhitespaceCollapse.PRESERVE);
        result.getStyle().setStyleProperty(TextStyleKeys.TEXT_WRAP, TextWrap.NONE);
      }
      else if ("nowrap".equals(value))
      {
        result.getStyle().setStyleProperty(TextStyleKeys.WHITE_SPACE_COLLAPSE, WhitespaceCollapse.PRESERVE_BREAKS);
        result.getStyle().setStyleProperty(TextStyleKeys.TEXT_WRAP, TextWrap.NONE);
      }
      else
      {
        result.getStyle().setStyleProperty(TextStyleKeys.WHITE_SPACE_COLLAPSE, WhitespaceCollapse.COLLAPSE);
        result.getStyle().setStyleProperty(TextStyleKeys.TEXT_WRAP, TextWrap.WRAP);
      }
    }
    else
    {
      result.getStyle().setStyleProperty(TextStyleKeys.WHITE_SPACE_COLLAPSE, WhitespaceCollapse.COLLAPSE);
      result.getStyle().setStyleProperty(TextStyleKeys.TEXT_WRAP, TextWrap.WRAP);
    }

    final Object alignAttribute = attr.getAttribute(HTML.Attribute.ALIGN);
    if (alignAttribute != null)
    {
      try
      {
        result.getStyle().setStyleProperty(ElementStyleKeys.ALIGNMENT,
            ReportParserUtil.parseHorizontalElementAlignment(String.valueOf(alignAttribute), null));
      }
      catch (ParseException e)
      {
        // ignore ..
      }
    }

    final Object titleAttribute = attr.getAttribute(HTML.Attribute.TITLE);
    if (titleAttribute != null)
    {
      result.setAttribute(AttributeNames.Html.NAMESPACE, AttributeNames.Html.TITLE,
          String.valueOf(titleAttribute));
    }

    final Object textIndentStyle = attr.getAttribute(CSS.Attribute.TEXT_INDENT);
    if (textIndentStyle != null)
    {
      result.getStyle().setStyleProperty
          (TextStyleKeys.FIRST_LINE_INDENT, parseLength(String.valueOf(textIndentStyle)));
    }

//    attr.getAttribute(CSS.Attribute.LIST_STYLE_TYPE);
//    attr.getAttribute(CSS.Attribute.LIST_STYLE_TYPE);
//    attr.getAttribute(CSS.Attribute.LIST_STYLE_POSITION);
  }

  private HTML.Tag findTag(final AttributeSet attr)
  {
    final Enumeration names = attr.getAttributeNames();
    while (names.hasMoreElements())
    {
      final Object name = names.nextElement();
      final Object o = attr.getAttribute(name);
      if (o instanceof HTML.Tag)
      {
        if (HTML.Tag.CONTENT == o)
        {
          continue;
        }
        if (HTML.Tag.COMMENT == o)
        {
          continue;
        }
        return (HTML.Tag) o;
      }
    }
    return null;
  }

  private void parseBoxStyle(final Element result, final AttributeSet attr)
  {
    final Object paddingText = attr.getAttribute(CSS.Attribute.PADDING);
    if (paddingText != null)
    {
      final Float padding = parseLength(String.valueOf(paddingText));
      result.getStyle().setStyleProperty(ElementStyleKeys.PADDING_TOP, padding);
      result.getStyle().setStyleProperty(ElementStyleKeys.PADDING_LEFT, padding);
      result.getStyle().setStyleProperty(ElementStyleKeys.PADDING_BOTTOM, padding);
      result.getStyle().setStyleProperty(ElementStyleKeys.PADDING_RIGHT, padding);
    }

    final Object paddingTop = attr.getAttribute(CSS.Attribute.PADDING_TOP);
    if (paddingTop != null)
    {
      final Float padding = parseLength(String.valueOf(paddingTop));
      result.getStyle().setStyleProperty(ElementStyleKeys.PADDING_TOP, padding);
    }
    final Object paddingLeft = attr.getAttribute(CSS.Attribute.PADDING_LEFT);
    if (paddingLeft != null)
    {
      final Float padding = parseLength(String.valueOf(paddingLeft));
      result.getStyle().setStyleProperty(ElementStyleKeys.PADDING_LEFT, padding);
    }
    final Object paddingBottom = attr.getAttribute(CSS.Attribute.PADDING_BOTTOM);
    if (paddingBottom != null)
    {
      final Float padding = parseLength(String.valueOf(paddingBottom));
      result.getStyle().setStyleProperty(ElementStyleKeys.PADDING_BOTTOM, padding);
    }
    final Object paddingRight = attr.getAttribute(CSS.Attribute.PADDING_RIGHT);
    if (paddingRight != null)
    {
      final Float padding = parseLength(String.valueOf(paddingRight));
      result.getStyle().setStyleProperty(ElementStyleKeys.PADDING_RIGHT, padding);
    }

    final Object heightText = attr.getAttribute(CSS.Attribute.HEIGHT);
    if (heightText != null)
    {
      result.getStyle().setStyleProperty(ElementStyleKeys.MIN_HEIGHT, parseLength(String.valueOf(heightText)));
    }
    final Object widthText = attr.getAttribute(CSS.Attribute.WIDTH);
    if (widthText != null)
    {
      result.getStyle().setStyleProperty(ElementStyleKeys.MIN_WIDTH, parseLength(String.valueOf(widthText)));
    }
  }

  private void parseBorderAndBackgroundStyle(final Element result, final StyleSheet sheet, final AttributeSet attr)
  {
    final Object backgroundColor = attr.getAttribute(CSS.Attribute.BACKGROUND_COLOR);
    if (backgroundColor != null)
    {
      result.getStyle().setStyleProperty
          (ElementStyleKeys.BACKGROUND_COLOR, sheet.stringToColor(String.valueOf(backgroundColor)));
    }
    final Object borderStyleText = attr.getAttribute(CSS.Attribute.BORDER_STYLE);
    if (borderStyleText != null)
    {
      final BorderStyle borderStyle = BorderStyle.getBorderStyle(String.valueOf(borderStyleText));
      if (borderStyle != null)
      {
        result.getStyle().setStyleProperty
            (ElementStyleKeys.BORDER_BOTTOM_STYLE, borderStyle);
        result.getStyle().setStyleProperty
            (ElementStyleKeys.BORDER_TOP_STYLE, borderStyle);
        result.getStyle().setStyleProperty
            (ElementStyleKeys.BORDER_LEFT_STYLE, borderStyle);
        result.getStyle().setStyleProperty
            (ElementStyleKeys.BORDER_RIGHT_STYLE, borderStyle);
      }
    }
    final Object borderWidthText = attr.getAttribute(CSS.Attribute.BORDER_WIDTH);
    if (borderWidthText != null)
    {
      final Float borderWidth = parseLength(String.valueOf(borderWidthText));
      result.getStyle().setStyleProperty
          (ElementStyleKeys.BORDER_BOTTOM_WIDTH, borderWidth);
      result.getStyle().setStyleProperty
          (ElementStyleKeys.BORDER_TOP_WIDTH, borderWidth);
      result.getStyle().setStyleProperty
          (ElementStyleKeys.BORDER_LEFT_WIDTH, borderWidth);
      result.getStyle().setStyleProperty
          (ElementStyleKeys.BORDER_RIGHT_WIDTH, borderWidth);
    }

    final Object borderBottomWidthText = attr.getAttribute(CSS.Attribute.BORDER_BOTTOM_WIDTH);
    if (borderBottomWidthText != null)
    {
      final Float borderWidth = parseLength(String.valueOf(borderBottomWidthText));
      result.getStyle().setStyleProperty
          (ElementStyleKeys.BORDER_BOTTOM_WIDTH, borderWidth);
    }

    final Object borderRightWidthText = attr.getAttribute(CSS.Attribute.BORDER_RIGHT_WIDTH);
    if (borderRightWidthText != null)
    {
      final Float borderWidth = parseLength(String.valueOf(borderRightWidthText));
      result.getStyle().setStyleProperty
          (ElementStyleKeys.BORDER_RIGHT_WIDTH, borderWidth);
    }

    final Object borderTopWidthText = attr.getAttribute(CSS.Attribute.BORDER_TOP_WIDTH);
    if (borderTopWidthText != null)
    {
      final Float borderWidth = parseLength(String.valueOf(borderTopWidthText));
      result.getStyle().setStyleProperty
          (ElementStyleKeys.BORDER_TOP_WIDTH, borderWidth);
    }

    final Object borderLeftWidth = attr.getAttribute(CSS.Attribute.BORDER_LEFT_WIDTH);
    if (borderLeftWidth != null)
    {
      final Float borderWidth = parseLength(String.valueOf(borderLeftWidth));
      result.getStyle().setStyleProperty
          (ElementStyleKeys.BORDER_LEFT_WIDTH, borderWidth);
    }

    final Object colorText = attr.getAttribute(CSS.Attribute.COLOR);
    if (colorText != null)
    {
      final Color color = sheet.stringToColor(String.valueOf(colorText));
      result.getStyle().setStyleProperty
          (ElementStyleKeys.BORDER_BOTTOM_COLOR, color);
      result.getStyle().setStyleProperty
          (ElementStyleKeys.BORDER_TOP_COLOR, color);
      result.getStyle().setStyleProperty
          (ElementStyleKeys.BORDER_LEFT_COLOR, color);
      result.getStyle().setStyleProperty
          (ElementStyleKeys.BORDER_RIGHT_COLOR, color);
      result.getStyle().setStyleProperty
          (ElementStyleKeys.PAINT, color);
    }

    final Object borderColorText = attr.getAttribute(CSS.Attribute.BORDER_COLOR);
    if (borderColorText != null)
    {
      final Color borderColor = sheet.stringToColor(String.valueOf(borderColorText));
      result.getStyle().setStyleProperty
          (ElementStyleKeys.BORDER_BOTTOM_COLOR, borderColor);
      result.getStyle().setStyleProperty
          (ElementStyleKeys.BORDER_TOP_COLOR, borderColor);
      result.getStyle().setStyleProperty
          (ElementStyleKeys.BORDER_LEFT_COLOR, borderColor);
      result.getStyle().setStyleProperty
          (ElementStyleKeys.BORDER_RIGHT_COLOR, borderColor);
    }
  }

  private Float parseLength(final String value)
  {
    if (value == null)
    {
      return null;
    }

    try
    {
      final StreamTokenizer strtok = new StreamTokenizer(new StringReader(value));
      strtok.parseNumbers();
      final int firstToken = strtok.nextToken();
      if (firstToken != StreamTokenizer.TT_NUMBER)
      {
        return null;
      }
      final double nval = strtok.nval;
      final int nextToken = strtok.nextToken();
      if (nextToken != StreamTokenizer.TT_WORD)
      {
        // yeah, this is against the standard, but we are dealing with deadly ugly non-standard documents here
        // maybe we will be able to integrate a real HTML processor at some point.
        return new Float(nval);
      }

      final String unit = strtok.sval;
      if ("%".equals(unit))
      {
        return new Float(-nval);
      }
      if ("cm".equals(unit))
      {
        return new Float(nval * 25.4 / 72);
      }

      if ("mm".equals(unit))
      {
        return new Float(nval * 2.54 / 72);
      }
      if ("pt".equals(unit))
      {
        return new Float(nval);
      }
      if ("in".equals(unit))
      {
        return new Float(nval * 72);
      }
      if ("px".equals(unit))
      {
        return new Float(nval * 72);
      }
      if ("pc".equals(unit))
      {
        return new Float(nval * 12);
      }
      return null;
    }
    catch (IOException ioe)
    {
      return null;
    }
  }


  private void configureBand(final javax.swing.text.Element textElement, final Band band)
  {
    final HTML.Tag tag = findTag(textElement.getAttributes());
    if (tag == null)
    {
      if ("paragraph".equals(textElement.getName()) ||
          "section".equals(textElement.getName()))
      {
        band.getStyle().setStyleProperty(BandStyleKeys.LAYOUT, "block");
        band.getStyle().setStyleProperty(ElementStyleKeys.MIN_WIDTH, new Float(-100));
        band.setName(textElement.getName());
      }
      else
      {
        band.getStyle().setStyleProperty(BandStyleKeys.LAYOUT, "inline");
        band.setName(textElement.getName());
      }
      return;
    }

    if (BLOCK_ELEMENTS.contains(tag))
    {
      band.getStyle().setStyleProperty(BandStyleKeys.LAYOUT, "block");
      band.getStyle().setStyleProperty(ElementStyleKeys.MIN_WIDTH, new Float(-100));
      band.setName(String.valueOf(tag));
    }
    else
    {
      band.getStyle().setStyleProperty(BandStyleKeys.LAYOUT, "inline");
      band.setName(String.valueOf(tag));
    }
  }
}
TOP

Related Classes of org.pentaho.reporting.engine.classic.core.layout.richtext.HtmlRichTextConverter

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.