/***************************************************************************** * Copyright (c) 2016 Dirk Fauth. * * 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: * Dirk Fauth <dirk.fauth@googlemail.com> - Initial API and implementation * *****************************************************************************/ package org.eclipse.nebula.widgets.nattable.extension.nebula.richtext; import java.io.StringReader; import java.util.regex.Pattern; import javax.xml.stream.XMLEventReader; import javax.xml.stream.XMLInputFactory; import javax.xml.stream.XMLStreamConstants; import javax.xml.stream.XMLStreamException; import javax.xml.stream.events.Characters; import javax.xml.stream.events.XMLEvent; import org.eclipse.nebula.widgets.richtext.RichTextPainter; /** * {@link MarkupProcessor} implementation that is able to process regular * expression values to identify content that should be surrounded by a markup. * The regular expression needs to contain one group so the replacement can be * done by using a placeholder. * * @since 1.1 */ public class RegexMarkupValue implements MarkupProcessor { private static final String GROUP_INDEX_PLACEHOLDER = "$1"; private String originalRegexValue; private String markupPrefix; private String markupSuffix; private String markupValue; private String markupRegexValue; private XMLInputFactory factory = XMLInputFactory.newInstance(); /** * * @param value * The regular expression that specifies the value that should be * surrounded by a markup. * @param markupPrefix * The String that should be added as prefix. * @param markupSuffix * The String that should be added as suffix. */ public RegexMarkupValue(String value, String markupPrefix, String markupSuffix) { this.originalRegexValue = value; this.markupPrefix = markupPrefix; this.markupSuffix = markupSuffix; this.markupValue = markupPrefix + GROUP_INDEX_PLACEHOLDER + markupSuffix; this.markupRegexValue = markupPrefix + value + markupSuffix; } @Override public String applyMarkup(String input) { String result = ""; if (getOriginalRegexValue() != null && !getOriginalRegexValue().isEmpty()) { XMLEventReader parser = null; try { parser = this.factory.createXMLEventReader( new StringReader(RichTextPainter.FAKE_ROOT_TAG_START + input + RichTextPainter.FAKE_ROOT_TAG_END)); while (parser.hasNext()) { XMLEvent event = parser.nextEvent(); switch (event.getEventType()) { case XMLStreamConstants.START_DOCUMENT: break; case XMLStreamConstants.END_DOCUMENT: parser.close(); break; case XMLStreamConstants.CHARACTERS: Characters characters = event.asCharacters(); String text = characters.getData(); result += Pattern.compile(getOriginalRegexValue(), Pattern.CASE_INSENSITIVE).matcher(text).replaceAll(this.markupValue); break; default: result += event.toString(); } } } catch (XMLStreamException e) { e.printStackTrace(); } finally { if (parser != null) { try { parser.close(); } catch (XMLStreamException e) { e.printStackTrace(); } } } result = result.replace(RichTextPainter.FAKE_ROOT_TAG_START, "").replace(RichTextPainter.FAKE_ROOT_TAG_END, ""); } else { result = input; } return result; } @Override public String removeMarkup(String input) { if (getOriginalRegexValue() != null && !getOriginalRegexValue().isEmpty()) { return input.replaceAll(getMarkupRegexValue(), GROUP_INDEX_PLACEHOLDER); } return input; } /** * Set the regular expression that specifies the value that should be * surrounded by a markup. * * @param value * The regular expression that specifies the value that should be * surrounded by a markup. */ public void setRegexValue(String value) { this.originalRegexValue = value; this.markupRegexValue = this.markupPrefix + value + this.markupSuffix; } /** * Returns the regular expression that specifies the value that should be * surrounded by a markup. Subclasses can override this method to provide a * dynamic markup value, e.g. for highlighting values inserted into a text * field. * * @return The regular expression that specifies the value that should be * surrounded by a markup. */ protected String getOriginalRegexValue() { return this.originalRegexValue; } /** * Returns the regular expression that specifies the value that should be * surrounded by a markup, with the applied markup. * * @return The original regex value with applied markup. */ protected String getMarkupRegexValue() { return this.markupRegexValue; } }