package org.eclipse.buckminster.core.common.parser;
import java.util.ArrayList;
import org.eclipse.buckminster.core.common.model.Flow;
import org.eclipse.buckminster.core.common.model.FlowWithAttributes;
import org.eclipse.buckminster.core.common.model.Text;
import org.eclipse.buckminster.runtime.Trivial;
import org.eclipse.buckminster.sax.AbstractHandler;
import org.eclipse.buckminster.sax.ChildHandler;
import org.eclipse.buckminster.sax.ChildPoppedListener;
import org.eclipse.buckminster.sax.ISaxableElement;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
public class FlowHandler extends ChildHandler implements ChildPoppedListener {
private static final ISaxableElement[] noChildren = new ISaxableElement[0];
private final String localName;
private String[] keyValuePairs;
private ArrayList<ISaxableElement> elements;
private StringBuilder text;
protected FlowHandler(AbstractHandler parentHandler, String localName) {
super(parentHandler);
this.localName = localName;
}
@Override
public void characters(char[] chars, int start, int length) throws SAXException {
if (length == 0)
return;
if (text == null)
text = new StringBuilder();
text.append(chars, start, length);
}
@Override
public void childPopped(ChildHandler child) throws SAXException {
addElement(((FlowHandler) child).createElement());
}
public Flow createElement() {
addTextIfAny();
ISaxableElement[] children = (elements == null) ? noChildren : elements.toArray(new ISaxableElement[elements.size()]);
return createFlowElement(localName, keyValuePairs, children);
}
@Override
public ChildHandler createHandler(String uri, String name, Attributes attrs) throws SAXException {
addTextIfAny();
return new FlowHandler(this, name);
}
@Override
public String getTAG() {
return localName;
}
@Override
public void handleAttributes(Attributes attrs) {
int numAttrs = attrs.getLength();
if (elements != null)
elements.clear();
if (text != null)
text.setLength(0);
if (numAttrs > 0) {
keyValuePairs = new String[numAttrs * 2];
for (int idx = 0; idx < numAttrs; ++idx) {
int kaIdx = idx * 2;
keyValuePairs[kaIdx] = attrs.getLocalName(idx);
keyValuePairs[kaIdx + 1] = attrs.getValue(idx);
}
} else
keyValuePairs = Trivial.EMPTY_STRING_ARRAY;
}
Flow createFlowElement(String name, String[] keyValPairs, ISaxableElement[] children) {
return (keyValPairs.length == 0) ? new Flow(name, children) : new FlowWithAttributes(name, children, keyValPairs);
}
private void addElement(ISaxableElement element) {
if (elements == null)
elements = new ArrayList<ISaxableElement>();
elements.add(element);
}
private void addTextIfAny() {
if (text == null)
return;
int textLen = text.length();
if (textLen == 0)
return;
char[] buf = new char[textLen];
text.getChars(0, textLen, buf, 0);
addElement(new Text(buf));
text.setLength(0);
}
}