in juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlParserSession.java [246:441]
private <T> T parseAnything(ClassMeta<T> eType, XmlReader r, Object outer, boolean isRoot, BeanPropertyMeta pMeta) throws IOException, ParseException, ExecutableException, XMLStreamException {
if (eType == null)
eType = (ClassMeta<T>)object();
ObjectSwap<T,Object> swap = (ObjectSwap<T,Object>)eType.getSwap(this);
BuilderSwap<T,Object> builder = (BuilderSwap<T,Object>)eType.getBuilderSwap(this);
ClassMeta<?> sType = null;
if (builder != null)
sType = builder.getBuilderClassMeta(this);
else if (swap != null)
sType = swap.getSwapClassMeta(this);
else
sType = eType;
if (sType.isOptional())
return (T)optional(parseAnything(eType.getElementType(), r, outer, isRoot, pMeta));
setCurrentClass(sType);
int event = r.getEventType();
if (event != START_ELEMENT)
throw new ParseException(this, "parseAnything must be called on outer start element.");
if (! isRoot)
event = r.next();
boolean isEmpty = (event == END_ELEMENT);
// Skip until we find a start element, end document, or non-empty text.
if (! isEmpty)
event = skipWs(r);
if (event == END_DOCUMENT)
throw new ParseException(this, "Unexpected end of stream in parseAnything for type ''{0}''", eType);
// Handle @Html(asXml=true) beans.
HtmlClassMeta hcm = getHtmlClassMeta(sType);
if (hcm.getFormat() == HtmlFormat.XML)
return super.parseAnything(eType, null, r, outer, false, pMeta);
Object o = null;
boolean isValid = true;
HtmlTag tag = (event == CHARACTERS ? null : HtmlTag.forString(r.getName().getLocalPart(), false));
// If it's not a known tag, then parse it as XML.
// Allows us to parse stuff like "<div/>" into HTML5 beans.
if (tag == null && event != CHARACTERS)
return super.parseAnything(eType, null, r, outer, false, pMeta);
if (tag == HTML)
tag = skipToData(r);
if (isEmpty) {
o = "";
} else if (tag == null || tag.isOneOf(BR,BS,FF,SP)) {
String text = parseText(r);
if (sType.isObject() || sType.isCharSequence())
o = text;
else if (sType.isChar())
o = parseCharacter(text);
else if (sType.isBoolean())
o = Boolean.parseBoolean(text);
else if (sType.isNumber())
o = parseNumber(text, (Class<? extends Number>)eType.getInnerClass());
else if (sType.canCreateNewInstanceFromString(outer))
o = sType.newInstanceFromString(outer, text);
else
isValid = false;
} else if (tag == STRING || (tag == A && pMeta != null && getHtmlBeanPropertyMeta(pMeta).getLink() != null)) {
String text = getElementText(r);
if (sType.isObject() || sType.isCharSequence())
o = text;
else if (sType.isChar())
o = parseCharacter(text);
else if (sType.canCreateNewInstanceFromString(outer))
o = sType.newInstanceFromString(outer, text);
else
isValid = false;
skipTag(r, tag == STRING ? xSTRING : xA);
} else if (tag == NUMBER) {
String text = getElementText(r);
if (sType.isObject())
o = parseNumber(text, Number.class);
else if (sType.isNumber())
o = parseNumber(text, (Class<? extends Number>)sType.getInnerClass());
else
isValid = false;
skipTag(r, xNUMBER);
} else if (tag == BOOLEAN) {
String text = getElementText(r);
if (sType.isObject() || sType.isBoolean())
o = Boolean.parseBoolean(text);
else
isValid = false;
skipTag(r, xBOOLEAN);
} else if (tag == P) {
String text = getElementText(r);
if (! "No Results".equals(text))
isValid = false;
skipTag(r, xP);
} else if (tag == NULL) {
skipTag(r, NULL);
skipTag(r, xNULL);
} else if (tag == A) {
o = parseAnchor(r, swap == null ? eType : null);
skipTag(r, xA);
} else if (tag == TABLE) {
String typeName = getAttribute(r, getBeanTypePropertyName(eType), "object");
ClassMeta cm = getClassMeta(typeName, pMeta, eType);
if (cm != null) {
sType = eType = cm;
typeName = sType.isCollectionOrArray() ? "array" : "object";
} else if (! "array".equals(typeName)) {
// Type name could be a subtype name.
typeName = sType.isCollectionOrArray() ? "array" : "object";
}
if (typeName.equals("object")) {
if (sType.isObject()) {
o = parseIntoMap(r, newGenericMap(sType), sType.getKeyType(), sType.getValueType(),
pMeta);
} else if (sType.isMap()) {
o = parseIntoMap(r, (Map)(sType.canCreateNewInstance(outer) ? sType.newInstance(outer)
: newGenericMap(sType)), sType.getKeyType(), sType.getValueType(), pMeta);
} else if (builder != null) {
BeanMap m = toBeanMap(builder.create(this, eType));
o = builder.build(this, parseIntoBean(r, m).getBean(), eType);
} else if (sType.canCreateNewBean(outer)) {
BeanMap m = newBeanMap(outer, sType.getInnerClass());
o = parseIntoBean(r, m).getBean();
} else if (sType.getProxyInvocationHandler() != null) {
BeanMap m = newBeanMap(outer, sType.getInnerClass());
o = parseIntoBean(r, m).getBean();
} else {
isValid = false;
}
skipTag(r, xTABLE);
} else if (typeName.equals("array")) {
if (sType.isObject())
o = parseTableIntoCollection(r, (Collection)new JsonList(this), sType, pMeta);
else if (sType.isCollection())
o = parseTableIntoCollection(r, (Collection)(sType.canCreateNewInstance(outer)
? sType.newInstance(outer) : new JsonList(this)), sType, pMeta);
else if (sType.isArray() || sType.isArgs()) {
ArrayList l = (ArrayList)parseTableIntoCollection(r, list(), sType, pMeta);
o = toArray(sType, l);
}
else
isValid = false;
skipTag(r, xTABLE);
} else {
isValid = false;
}
} else if (tag == UL) {
String typeName = getAttribute(r, getBeanTypePropertyName(eType), "array");
ClassMeta cm = getClassMeta(typeName, pMeta, eType);
if (cm != null)
sType = eType = cm;
if (sType.isObject())
o = parseIntoCollection(r, new JsonList(this), sType, pMeta);
else if (sType.isCollection() || sType.isObject())
o = parseIntoCollection(r, (Collection)(sType.canCreateNewInstance(outer)
? sType.newInstance(outer) : new JsonList(this)), sType, pMeta);
else if (sType.isArray() || sType.isArgs())
o = toArray(sType, parseIntoCollection(r, list(), sType, pMeta));
else
isValid = false;
skipTag(r, xUL);
}
if (! isValid)
throw new ParseException(this, "Unexpected tag ''{0}'' for type ''{1}''", tag, eType);
if (swap != null && o != null)
o = unswap(swap, o, eType);
if (outer != null)
setParent(eType, o, outer);
skipWs(r);
return (T)o;
}