de.lessvoid.nifty.html.NiftyVisitor Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of nifty-html Show documentation
Show all versions of nifty-html Show documentation
This module adds basic HTML support to Nifty. It creates Nifty elements from HTML directly. This is useful if you need to display messages or info boxes that contain more than simple elements.
package de.lessvoid.nifty.html;
import de.lessvoid.nifty.Nifty;
import de.lessvoid.nifty.builder.ElementBuilder;
import de.lessvoid.nifty.builder.ImageBuilder;
import de.lessvoid.nifty.builder.PanelBuilder;
import de.lessvoid.nifty.spi.render.RenderFont;
import org.htmlparser.Tag;
import org.htmlparser.Text;
import org.htmlparser.util.Translate;
import org.htmlparser.visitors.NodeVisitor;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;
/**
* A NodeVisitor for the HTML Parser project that will visit all HTML tags
* and translate them into Nifty elements using the Nifty Builder pattern.
* @author void
*/
public class NiftyVisitor extends NodeVisitor {
// errors in processing are added to that list
@Nonnull
private final List errors = new ArrayList();
// the PanelBuilder for the body tag
private PanelBuilder bodyPanel;
// helper class to create new builders
private final NiftyBuilderFactory niftyBuilderFactory;
// to allow nested block level elements later we must stack them
@Nonnull
private final Stack blockElementStack = new Stack();
// the current block level element
@Nullable
private PanelBuilder currentBlockElement;
// default font we use for generating text elements
@Nullable
private final String defaultFontName;
private final String defaultFontBoldName;
// current color
@Nullable
private String currentColor;
// this will be set to a different font name when a corresponding tag is being processed
@Nullable
private String differentFont;
// we collect all text nodes into this string buffer
@Nonnull
private final StringBuffer currentText = new StringBuffer();
// table
@Nullable
private PanelBuilder table;
// table row
@Nullable
private PanelBuilder tableRow;
// table data
@Nullable
private PanelBuilder tableData;
@Nonnull
private String fontHeight;
/**
* Create the NiftyVisitor.
* @param nifty the Nifty instance
* @param niftyBuilderFactory a helper class to create Nifty Builders
*/
public NiftyVisitor(@Nonnull final Nifty nifty, final NiftyBuilderFactory niftyBuilderFactory, @Nullable final String defaultFontName, final String defaultFontBoldName) {
this.niftyBuilderFactory = niftyBuilderFactory;
this.defaultFontName = defaultFontName;
this.defaultFontBoldName = defaultFontBoldName;
fontHeight = "0";
if (defaultFontName != null) {
RenderFont defaultFont = nifty.createFont(defaultFontName);
if (defaultFont != null) {
fontHeight = Integer.toString(defaultFont.getHeight());
}
}
}
/*
* (non-Javadoc)
* @see org.htmlparser.visitors.NodeVisitor#beginParsing()
*/
@Override
public void beginParsing () {
errors.clear();
}
/*
* (non-Javadoc)
* @see org.htmlparser.visitors.NodeVisitor#visitTag(org.htmlparser.Tag)
*/
@Override
public void visitTag(@Nonnull final Tag tag) {
try {
if (isBody(tag)) {
// we'll add a main panel for the body which will be the parent element for everything we generate
// this way we can decide the childLayout and other properties of the body panel.
bodyPanel = niftyBuilderFactory.createBodyPanelBuilder();
} else if (isParagraph(tag)) {
assertBodyPanelNotNull();
currentBlockElement = niftyBuilderFactory.createParagraphPanelBuilder();
blockElementStack.push(currentBlockElement);
} else if (isImageTag(tag)) {
ImageBuilder image = niftyBuilderFactory.createImageBuilder(
tag.getAttribute("src"),
tag.getAttribute("align"),
tag.getAttribute("width"),
tag.getAttribute("height"),
tag.getAttribute("bgcolor"),
tag.getAttribute("vspace"));
if (currentBlockElement != null) {
currentBlockElement.image(image);
} else {
bodyPanel.image(image);
}
} else if (isBreak(tag)) {
if (currentBlockElement != null) {
currentText.append("\n");
} else {
PanelBuilder breakPanelBuilder = niftyBuilderFactory.createBreakPanelBuilder(fontHeight);
bodyPanel.panel(breakPanelBuilder);
}
} else if (isTableTag(tag)) {
assertBodyPanelNotNull();
table = niftyBuilderFactory.createTableTagPanelBuilder(
tag.getAttribute("width"),
tag.getAttribute("bgcolor"),
tag.getAttribute("border"),
tag.getAttribute("bordercolor"));
} else if (isTableRowTag(tag)) {
assertTableNotNull();
tableRow = niftyBuilderFactory.createTableRowPanelBuilder(
tag.getAttribute("width"),
tag.getAttribute("bgcolor"),
tag.getAttribute("border"),
tag.getAttribute("bordercolor"));
} else if (isTableDataTag(tag)) {
assertTableRowNotNull();
tableData = niftyBuilderFactory.createTableDataPanelBuilder(
tag.getAttribute("width"),
tag.getAttribute("bgcolor"),
tag.getAttribute("border"),
tag.getAttribute("bordercolor"));
} else if (isFontTag(tag)) {
String color = tag.getAttribute("color");
if (color != null) {
currentColor = color;
}
} else if (isStrongTag(tag)) {
differentFont = defaultFontBoldName;
}
} catch (Exception e) {
addError(e);
}
}
/*
* (non-Javadoc)
* @see org.htmlparser.visitors.NodeVisitor#visitEndTag(org.htmlparser.Tag)
*/
@SuppressWarnings("StatementWithEmptyBody")
@Override
public void visitEndTag(@Nonnull final Tag tag) {
try {
if (isBody(tag)) {
// currently there is nothing to do when a body tag ends
} else if (isParagraph(tag)) {
if (bodyPanel == null) {
throw new Exception("This looks like HTML with a missing tag");
}
if (currentBlockElement == null) {
throw new Exception("This looks like broken HTML. currentBlockElement seems null. Maybe a duplicate close tag?");
}
String textElement = currentText.toString();
if (textElement.length() > 0) {
addTextElement(currentBlockElement, textElement);
currentText.setLength(0);
}
if (currentBlockElement.getElementBuilders().isEmpty()) {
currentBlockElement.height(fontHeight);
}
bodyPanel.panel(currentBlockElement);
currentBlockElement = blockElementStack.pop();
differentFont = null;
} else if (isImageTag(tag)) {
// nothing to do
} else if (isBreak(tag)) {
// nothing to do
} else if (isTableTag(tag)) {
if (bodyPanel == null || table == null) {
throw new Exception("This looks like HTML with a missing tag");
}
bodyPanel.panel(table);
table = null;
} else if (isTableRowTag(tag)) {
if (table == null || tableRow == null) {
throw new Exception("This looks like a element with a missing tag");
}
table.panel(tableRow);
tableRow = null;
} else if (isTableDataTag(tag)) {
if (tableRow == null) {
throw new Exception("This looks like a element with a missing tag");
}
if (tableData == null) {
throw new Exception("This looks like a element with a missing tag");
}
addTextElement(tableData, currentText.toString());
currentText.setLength(0);
tableRow.panel(tableData);
tableData = null;
differentFont = null;
} else if (isFontTag(tag)) {
currentColor = null;
}
} catch (Exception e) {
addError(e);
}
}
/*
* (non-Javadoc)
* @see org.htmlparser.visitors.NodeVisitor#visitStringNode(org.htmlparser.Text)
*/
@Override
public void visitStringNode(@Nonnull final Text textNode) {
if (tableData != null) {
appendText(textNode);
} else if (currentBlockElement != null) {
appendText(textNode);
}
}
private void appendText(@Nonnull final Text textNode) {
if (currentColor != null) {
currentText.append("\\");
currentText.append(currentColor);
currentText.append("#");
}
currentText.append(removeNewLineAndTabs(translateHTMLEntities(textNode.getText())));
}
public ElementBuilder builder() throws Exception {
try {
assertBodyPanelNotNull();
} catch (Exception e) {
addAsFirstError(e);
}
assertNoErrors();
return bodyPanel;
}
// private stuff
private void addError(@Nonnull final Exception e) {
if (!errors.contains(e.getMessage())) {
errors.add(e.getMessage());
}
}
private void addAsFirstError(@Nonnull final Exception e) {
if (!errors.contains(e.getMessage())) {
errors.add(0, e.getMessage());
}
}
private void assertBodyPanelNotNull() throws Exception {
if (bodyPanel == null) {
throw new Exception("This looks like HTML with a missing tag");
}
}
private void assertTableNotNull() throws Exception {
if (table == null) {
throw new Exception("This looks like a element with a missing tag");
}
}
private void assertTableRowNotNull() throws Exception {
if (tableRow == null) {
throw new Exception("This looks like a element with a missing tag");
}
}
private void addTextElement(@Nonnull final PanelBuilder panelBuilder, @Nonnull final String text) {
String font = defaultFontName;
if (differentFont != null) {
font = differentFont;
}
if (font == null) {
return;
}
panelBuilder.text(niftyBuilderFactory.createTextBuilder(text, font, currentColor));
}
private void assertNoErrors() throws Exception {
if (!errors.isEmpty()) {
StringBuilder message = new StringBuilder();
for (int i=0; i
© 2015 - 2025 Weber Informatics LLC | Privacy Policy