![JAR search and dependency download from the Maven repository](/logo.png)
com.jsftoolkit.base.renderer.RenderEventsCollector Maven / Gradle / Ivy
package com.jsftoolkit.base.renderer;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.ListIterator;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import com.jsftoolkit.utils.Utils;
import com.jsftoolkit.utils.xmlpull.AttributeEvent;
import com.jsftoolkit.utils.xmlpull.BodyText;
import com.jsftoolkit.utils.xmlpull.PullEvent;
import com.jsftoolkit.utils.xmlpull.PullEventCollector;
/**
* Extends a {@link PullEventCollector} to provide more rendering specific
* events. Attributes and element text content matching the {@link #VAR_PATTERN}
* will be replaced with {@link VarAttribEvent}s and {@link VarTextEvent}s.
*
* @author noah
*
*/
public class RenderEventsCollector extends PullEventCollector {
public static final Pattern VAR_PATTERN = Pattern.compile(
"(^|[^\\\\])\\$\\{([^\\|&&\\S]+?)(\\|(([^\\}]|\\\\\\})*?))?\\}",
Pattern.DOTALL);
/**
*
* @param text
* the text to process.
* @throws IOException
* @throws SAXException
*/
public RenderEventsCollector(String text) throws IOException, SAXException {
super(text);
process();
}
/**
*
* @param reader
* the {@link XMLReader} instance to use.
* @param text
* the text to parse.
* @throws IOException
* @throws SAXException
*/
public RenderEventsCollector(XMLReader reader, String text)
throws IOException, SAXException {
super(reader, text);
process();
}
/**
* Process the events list, inserting/replacing events where appropriate due
* to variable substitutions.
*/
private void process() {
ListIterator lit = events.listIterator();
while (lit.hasNext()) {
PullEvent event = lit.next();
if (event instanceof AttributeEvent) {
AttributeEvent ae = (AttributeEvent) event;
if ("decode".equalsIgnoreCase(ae.getName())) {
lit.remove();
lit.add(new DecodeEvent(ae.getValue()));
} else if ("passThrough".equalsIgnoreCase(ae.getName())) {
// determine which attributes should be passed through
String value = Utils.toString(ae.getValue());
Set allowed = new HashSet(
HtmlRenderer.PASS_THROUGH);
if (value.startsWith("!")) {
allowed.removeAll(Arrays.asList(value.substring(1)
.split(",")));
} else if (!Utils.isEmpty(value)) {
allowed = new HashSet(Arrays.asList(value
.split(",")));
}
lit.remove();
lit.add(new PassThrough(allowed));
} else {
VarAttribEvent vae = convertToVarAttribute(ae);
if (vae != null) {
lit.remove();
lit.add(vae);
}
}
} else if (event instanceof BodyText) {
// replace the body text with a printf format string
Matcher matcher = VAR_PATTERN.matcher(((BodyText) event)
.getText().toString().replaceAll("%", "%%"));
boolean removed = false;
while (matcher.find()) {
if (!removed) {
lit.remove();
removed = true;
}
StringBuffer sb = new StringBuffer();
matcher.appendReplacement(sb, Utils.toString(matcher.group(1)));
// the one body text event gets broken into multiple body
// text and var text events
lit.add(new BodyText(sb));
lit.add(new VarTextEvent(matcher.group(2), matcher
.groupCount() > 3 ? matcher.group(4) : null));
}
StringBuffer sb = new StringBuffer();
matcher.appendTail(sb);
if (removed) {
lit.add(new BodyText(sb));
}
}
}
}
/**
* Parses the given {@link AttributeEvent} value for variable substitutions/
*
* @param ae
* the attribute event to parse.
* @return null if there are no substitutions, otherwise a replacement
* {@link VarAttribEvent}.
*/
public static VarAttribEvent convertToVarAttribute(AttributeEvent ae) {
VarAttribEvent vae = null;
// the attribute value may contain multiple attributes to
// insert, so we create a printf pattern, and determine what
// the attributes are.
Matcher matcher = VAR_PATTERN.matcher(ae.getValue().replaceAll("%",
"%%"));
if (matcher.find()) {
// found a var attribute, so remove the plain attribute
// event
List props = new ArrayList();
List defaults = new ArrayList();
StringBuffer pattern = new StringBuffer(ae.getValue().length());
do {
// replace variable occurrences with %s
matcher.appendReplacement(pattern, matcher.group(1) + "%s");
// save the attribute name and default
props.add(matcher.group(2));
defaults
.add(matcher.groupCount() > 3 ? matcher.group(4) : null);
} while (matcher.find());
matcher.appendTail(pattern);
vae = new VarAttribEvent(ae.getName(), pattern.toString(), props,
defaults);
}
return vae;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy