com.googlecode.gwt.test.uibinder.UiBinderParser Maven / Gradle / Ivy
package com.googlecode.gwt.test.uibinder;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiTemplate;
import com.googlecode.gwt.test.exceptions.GwtTestException;
import com.googlecode.gwt.test.exceptions.GwtTestUiBinderException;
import com.googlecode.gwt.test.internal.utils.XmlUtils;
import com.googlecode.gwt.test.utils.JavassistUtils;
import org.xml.sax.InputSource;
import org.xml.sax.XMLReader;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
/**
* Class in charge of parsing the .ui.xml file and filling both root element/widget and all
* {@link UiField} in the owner object.
*
* @author Gael Lazzari
*/
class UiBinderParser {
/**
* Parse the .ui.xml file to fill the corresponding objects.
*
* @param rootComponentClass the root component's class that UiBinder has to instanciated.
* @param uiBinderClass the UiBinder subinterface which is used
* @param owner The owner of the UiBinder template, with {@link UiField} fields.
*/
T createUiComponent(Class> uiBinderClass, Object owner) {
@SuppressWarnings("unchecked")
Class rootComponentClass = (Class) getRootElementClass(uiBinderClass);
InputStream uiXmlStream = getUiXmlFile(owner.getClass(), uiBinderClass);
if (uiXmlStream == null) {
throw new GwtTestUiBinderException("Cannot find the .ui.xml file corresponding to '"
+ owner.getClass().getName() + "'");
}
UiXmlContentHandler contentHandler = new UiXmlContentHandler(rootComponentClass, owner);
XMLReader saxReader = XmlUtils.newXMLReader();
try {
saxReader.setContentHandler(contentHandler);
saxReader.parse(new InputSource(uiXmlStream));
} catch (Exception e) {
if (GwtTestException.class.isInstance(e)) {
throw (GwtTestException) e;
} else {
throw new GwtTestUiBinderException("Error while parsing '"
+ owner.getClass().getSimpleName() + ".ui.xml'", e);
}
} finally {
try {
uiXmlStream.close();
} catch (IOException e) {
// do nothing
}
}
return contentHandler.getRootComponent();
}
/**
* Get the actual class of the parameter.
*
* @return The class of the root element or widget generated from UiBinder.
*/
private Class getRootElementClass(Class> uiBinderClass) {
for (Type type : uiBinderClass.getGenericInterfaces()) {
if (type instanceof ParameterizedType) {
ParameterizedType pType = (ParameterizedType) type;
return (Class) pType.getActualTypeArguments()[0];
}
}
throw new GwtTestUiBinderException("The UiBinder subinterface '" + uiBinderClass.getName()
+ "' is not parameterized. Please add its generic types.");
}
private InputStream getUiXmlFile(Class ownerClass, Class> uiBinderClass) {
InputStream is = ownerClass.getResourceAsStream(ownerClass.getSimpleName() + ".ui.xml");
if (is == null) {
String uiTemplateValue = JavassistUtils.getInvisibleAnnotationStringValue(uiBinderClass,
UiTemplate.class, "value");
if (uiTemplateValue != null) {
is = ownerClass.getResourceAsStream(uiTemplateValue);
}
}
if (is == null && ownerClass.getSuperclass() != Object.class) {
is = getUiXmlFile(ownerClass.getSuperclass(), uiBinderClass);
}
return is;
}
}