Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.googlecode.gwt.test.uibinder.UiResourceManager Maven / Gradle / Ivy
package com.googlecode.gwt.test.uibinder;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import com.google.gwt.dom.client.Element;
import com.google.gwt.resources.client.CssResource;
import com.google.gwt.resources.client.DataResource;
import com.google.gwt.resources.client.ImageResource;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.ui.IsWidget;
import com.google.gwt.user.client.ui.UIObject;
import com.googlecode.gwt.test.exceptions.GwtTestUiBinderException;
import com.googlecode.gwt.test.exceptions.ReflectionException;
import com.googlecode.gwt.test.internal.resources.ResourcePrototypeProxyBuilder;
import com.googlecode.gwt.test.utils.GwtReflectionUtils;
/**
* Class responsible for managing declared resources, e.g. , ,
* and tags.
*
* @author Gael Lazzari
*
*/
class UiResourceManager {
/**
* Handles tags.
*/
private static class UiBinderImage extends UiResourceTag {
UiBinderImage(ResourcePrototypeProxyBuilder builder, String alias, UiTag parentTag,
Object owner, Map resources, Map attributes) {
super(builder, alias, parentTag, owner, resources);
// handle "src" attribute
String src = (String) attributes.get("src");
builder.resourceURL(computeImageURLs(owner, src));
}
@Override
protected Object buildObject(ResourcePrototypeProxyBuilder builder) {
return builder.build();
}
private URL computeImageURLs(Object owner, String src) {
URL imageURL = owner.getClass().getResource(src);
if (imageURL == null) {
throw new GwtTestUiBinderException("Cannot find image file with src=\"" + src
+ "\" declared in " + owner.getClass().getSimpleName() + ".ui.xml");
}
return imageURL;
}
}
/**
* Handles tags.
*/
private static class UiDataTag extends UiResourceTag {
UiDataTag(ResourcePrototypeProxyBuilder builder, String alias, UiTag parentTag,
Object owner, Map resources, Map attributes) {
super(builder, alias, parentTag, owner, resources);
// handle "src" attribute
String src = (String) attributes.get("src");
builder.resourceURL(computeImageURL(owner, src));
}
@Override
protected Object buildObject(ResourcePrototypeProxyBuilder builder) {
return builder.build();
}
private URL computeImageURL(Object owner, String src) {
URL dataURL = owner.getClass().getResource(src);
if (dataURL == null) {
throw new GwtTestUiBinderException("Cannot find binary file with src=\"" + src
+ "\" declared in " + owner.getClass().getSimpleName() + ".ui.xml");
}
return dataURL;
}
}
/**
* Handles tags.
*/
private static class UiImportTag implements UiTag {
private final UiTag parentTag;
UiImportTag(Map attributes, UiTag parentTag,
Map resources, Object owner) {
this.parentTag = parentTag;
// collects single and multiple imports in UiBinderResourceManager
// inner
// map
collectObjectToImport(attributes, resources, owner);
}
public void addElement(Element element) {
// nothing to do
}
public void addUiObject(UIObject uiObject) {
// nothing to do
}
public void addWidget(IsWidget widget) {
// nothing to do
}
public void appendText(String text) {
// nothing to do
}
public Object endTag() {
// the result will not be used by UiBinderTagBuilder
return null;
}
public UiTag getParentTag() {
return parentTag;
}
private void collectMultipleImports(String importValue, Map resources,
Object owner) {
try {
String className = importValue.substring(0, importValue.lastIndexOf('.'));
Class clazz = GwtReflectionUtils.getClass(className);
// this code handles classes and enums fine
for (Field field : GwtReflectionUtils.getFields(clazz)) {
if (Modifier.isStatic(field.getModifiers())
&& !Modifier.isPrivate(field.getModifiers())
&& !Modifier.isProtected(field.getModifiers())) {
// register static field value in UiResourcesManager inner map
Object value = GwtReflectionUtils.getStaticFieldValue(clazz, field.getName());
resources.put(field.getName(), value);
}
}
} catch (Exception e) {
throw new GwtTestUiBinderException("Error while trying to import multiple ui fields '"
+ importValue + "'", e);
}
}
private Map collectObjectToImport(Map attributes,
Map resources, Object owner) {
Map result = new HashMap();
for (Map.Entry entry : attributes.entrySet()) {
String attrName = entry.getKey();
String attrValue = entry.getValue().toString().trim();
// ignore attributes other than
if (!"ui:field".equals(attrName)) {
continue;
}
// ignore empty attributes
if (attrValue.length() == 0) {
continue;
}
int token = attrValue.lastIndexOf('.');
if (token > -1 && token < attrValue.length() - 1
&& attrValue.substring(token).equals(".*")) {
// case of multiple import
collectMultipleImports(attrValue, resources, owner);
} else {
// case of single import
collectSingleImport(attrValue, resources, owner);
}
}
return result;
}
private void collectSingleImport(String importValue, Map resources,
Object owner) {
try {
int token = importValue.lastIndexOf('.');
String className = importValue.substring(0, token);
Class clazz = GwtReflectionUtils.getClass(className);
String fieldName = importValue.substring(token + 1);
Object objectToImport = GwtReflectionUtils.getStaticFieldValue(clazz, fieldName);
// register static field value in UiResourcesManager inner map
resources.put(fieldName, objectToImport);
} catch (Exception e) {
throw new GwtTestUiBinderException("Error while trying to import ui field '"
+ importValue + "'", e);
}
}
}
/**
* Handles tags.
*
* @author Gael Lazzari
*
*/
private static class UiMsgTag implements UiTag {
private final UiTag parentTag;
private final StringBuilder sb;
UiMsgTag(UiTag parent) {
this.parentTag = parent;
sb = new StringBuilder();
}
public void addElement(Element element) {
sb.append("<").append(element.getTagName());
// TODO : append attributes
sb.append(">").append(element.getInnerText()).append("");
}
public void addUiObject(UIObject uiObject) {
parentTag.addUiObject(uiObject);
}
public void addWidget(IsWidget isWidget) {
parentTag.addWidget(isWidget);
}
public void appendText(String data) {
sb.append(data);
}
public String endTag() {
return sb.toString();
}
public UiTag getParentTag() {
return parentTag;
}
}
/**
* Base class for resource tags : , and
*
*/
private static abstract class UiResourceTag implements UiTag {
private final String alias;
private final ResourcePrototypeProxyBuilder builder;
private final Object owner;
private final UiTag parentTag;
private final Map resources;
private Object wrappedObject;
UiResourceTag(ResourcePrototypeProxyBuilder builder, String alias, UiTag parentTag,
Object owner, Map resources) {
this.builder = builder;
this.owner = owner;
this.parentTag = parentTag;
this.alias = alias;
this.resources = resources;
}
public void addElement(Element element) {
// adapter method
}
public void addUiObject(UIObject uiObject) {
// adapter method
}
public void addWidget(IsWidget widget) {
// adapter method
}
public void appendText(String text) {
// adapter method
}
public Object endTag() {
if (wrappedObject == null) {
// delegate the creation to subclasses
wrappedObject = buildObject(builder);
// set the corresponding @UiField
Field resourceUiField = getUniqueUiField(alias);
if (resourceUiField != null) {
try {
resourceUiField.set(owner, wrappedObject);
} catch (Exception e) {
throw new ReflectionException(e);
}
}
// register the built resource to the resourceManager inner map
resources.put(alias, wrappedObject);
}
return wrappedObject;
}
public UiTag getParentTag() {
return parentTag;
}
protected abstract Object buildObject(ResourcePrototypeProxyBuilder builder);
private Field getUniqueUiField(String alias) {
Set resourceFields = GwtReflectionUtils.getFields(owner.getClass());
if (resourceFields.size() == 0) {
return null;
}
Field result = null;
for (Field f : resourceFields) {
if (alias.equals(f.getName()) && f.isAnnotationPresent(UiField.class)) {
if (result != null) {
throw new GwtTestUiBinderException("There are more than one '" + f.getName()
+ "' @UiField in class '" + owner.getClass().getName()
+ "' or its superclass");
}
result = f;
}
}
return result;
}
}
/**
* Handles tags with a "type" attribute to specify a {@link CssResource} subtype.
*/
private static class UiStyleTag extends UiResourceTag {
private final StringBuilder text;
UiStyleTag(ResourcePrototypeProxyBuilder builder, String alias, UiTag parentTag,
Object owner, Map resources) {
super(builder, alias, parentTag, owner, resources);
this.text = new StringBuilder();
}
@Override
public void appendText(String text) {
this.text.append(text.trim());
}
@Override
protected Object buildObject(ResourcePrototypeProxyBuilder builder) {
return builder.text(text.toString()).build();
}
}
/**
* Handles tags.
*/
private static class UiWithTag implements UiTag {
private final Object with;
public UiWithTag(Object with) {
this.with = with;
}
public void addElement(Element element) {
// nothing to do
}
public void addUiObject(UIObject uiObject) {
// nothing to do
}
public void addWidget(IsWidget isWidget) {
// nothing to do
}
public void appendText(String text) {
// nothing to do
}
public Object endTag() {
return with;
}
public UiTag getParentTag() {
// nothing to do
return null;
}
}
/**
* Constructs a new UiResourceManager associated with a widget.
*
* @param owner The {@link UiBinder} owner widget to be associated with the UiResourceManager,
* which calls the {@link UiBinder#createAndBindUi(Object)} method to initialize itself
* @return The new instance
*/
static final UiResourceManager newInstance(Object owner) {
return new UiResourceManager(owner);
}
private final Object owner;
private final Map resources = new HashMap();
private UiResourceManager(Object owner) {
this.owner = owner;
}
/**
* Get a resource declared in the .ui.xml file with the tag.
*
* @param alias The alias of the resource ('res' attribute in the .ui.xml file)
* @return The corresponding resource, or null if it does not exist
*/
@SuppressWarnings("unchecked")
T getUiResource(String alias) {
return (T) resources.get(alias);
}
/**
* Register some new resources which should correspond to a tag in the .ui.xml file.
*
* @param attributes Map of attributes parsed from the tag
* @param parentTag The parent tag if any
* @param owner The {@link UiBinder} owner widget, which calls the
* {@link UiBinder#createAndBindUi(Object)} method to initialize itself.
* @return The UiBinderTag which has registered the imported object instances in the
* {@link UiResourceManager}.
*/
UiTag registerImport(Map attributes, UiTag parentTag, Object owner) {
return new UiImportTag(attributes, parentTag, resources, owner);
}
/**
* Register a tag declared in the .ui.xml file.
*
* @param attributes Map of attributes parsed from the tag
* @param parentTag The parent tag if any
* @param owner The {@link UiBinder} owner widget, which calls the
* {@link UiBinder#createAndBindUi(Object)} method to initialize itself.
* @return The UiBinderTag which has registered the imported object instances in the
* {@link UiResourceManager}.
*/
UiTag registerMsg(Map attributes, UiTag parentTag, Object owner) {
return new UiMsgTag(parentTag);
}
/**
* Register a new resource which should correspond to a resource tag in the .ui.xml file.
*
* @param localName The type of the resource ('with', 'style', 'image' or 'data')
* @param attributes Map of attributes parsed from the tag
* @param parentTag The parent tag if any
* @param owner The {@link UiBinder} owner widget, which calls the
* {@link UiBinder#createAndBindUi(Object)} method to initialize itself.
* @return The UiBinderTag which wraps the Resource instance.
*
* @throws GwtTestUiBinderException If the localName is not managed or if the alias is already
* binded to another Resource object
*/
UiTag registerResource(String localName, Map attributes, UiTag parentTag,
Object owner) throws GwtTestUiBinderException {
String alias = getResourceAlias(localName, attributes);
if (resources.containsKey(alias)) {
throw new GwtTestUiBinderException("Two inner resources '" + alias + " are declared in "
+ owner.getClass().getSimpleName()
+ ".ui.xml. You should add a 'field' attribute to one of them");
}
Class type = getResourceType(alias, localName, attributes);
if ("with".equals(localName)) {
// special resource : the resource can be annotated with
// @UiConstructor, @UiFactory or @UiField(provided=true)
Object resource = UiBinderInstanciator.getInstance(type, attributes, owner);
resources.put(alias, resource);
return new UiWithTag(resource);
}
ResourcePrototypeProxyBuilder builder = ResourcePrototypeProxyBuilder.createBuilder(type,
owner.getClass());
// common properties
builder.name(alias);
if ("style".equals(localName)) {
//
return new UiStyleTag(builder, alias, parentTag, owner, resources);
} else if ("image".equals(localName)) {
//
return new UiBinderImage(builder, alias, parentTag, owner, resources, attributes);
} else if ("data".equals(localName)) {
//
return new UiDataTag(builder, alias, parentTag, owner, resources, attributes);
} else {
throw new GwtTestUiBinderException("resource <" + localName
+ "> element is not yet implemented by gwt-test-utils");
}
}
private String getResourceAlias(String localName, Map attributes) {
String alias;
alias = (String) attributes.get("ui:field");
if (alias == null && !"with".equals(localName)) {
alias = localName;
}
if (alias == null) {
throw new GwtTestUiBinderException("Cannot find the required 'field' value for tag <"
+ localName + "> in " + owner.getClass().getSimpleName() + ".ui.xml");
}
return alias;
}
private Class getResourceType(String alias, String localName, Map attributes) {
String type = (String) attributes.get("type");
if (type == null && "image".equals(localName)) {
// special code for with no 'type' attribute
return ImageResource.class;
} else if (type == null && "style".equals(localName)) {
// special code for with no 'type' attribute
return CssResource.class;
} else if (type == null && "data".equals(localName)) {
// special code for with no 'type' attribute
return DataResource.class;
} else if (type == null) {
throw new GwtTestUiBinderException("<" + localName + "> element declared in "
+ owner.getClass().getSimpleName() + ".ui.xml must specify a 'type' attribute");
}
try {
return GwtReflectionUtils.getClass(type);
} catch (ClassNotFoundException e2) {
throw new GwtTestUiBinderException("Cannot find class '" + type + "' for resource '"
+ alias + "' declared in file '" + owner.getClass().getSimpleName() + ".ui.xml'");
}
}
}