xapi.ui.autoui.impl.AbstractUserInterfaceFactory Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of xapi-core-ui-autoui Show documentation
Show all versions of xapi-core-ui-autoui Show documentation
The core API for generating user interfaces from data models.
The newest version!
package xapi.ui.autoui.impl;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import javax.inject.Named;
import xapi.log.X_Log;
import xapi.source.write.MappedTemplate;
import xapi.ui.autoui.api.BeanValueProvider;
import xapi.ui.autoui.api.UiOptions;
import xapi.ui.autoui.api.UiRenderer;
import xapi.ui.autoui.api.UiRendererOptions;
import xapi.ui.autoui.api.UiRendererSelector;
import xapi.ui.autoui.api.UiRenderingContext;
import xapi.ui.autoui.api.UserInterface;
import xapi.ui.autoui.api.UserInterfaceFactory;
import xapi.ui.autoui.api.Validator;
import xapi.util.X_Debug;
import xapi.util.X_Util;
import xapi.util.api.ConvertsValue;
@SuppressWarnings("rawtypes")
public abstract class AbstractUserInterfaceFactory implements UserInterfaceFactory {
@SuppressWarnings("unchecked")
@Override
public > U createUi(Class extends T> type, Class super U> uiType) {
UiRenderingContext[] options = getOptions(type);
List
head = new ArrayList(),
body = new ArrayList(),
tail = new ArrayList()
;
for (UiRenderingContext ctx : options) {
(ctx.isHead()?head:ctx.isTail()?tail:body).add(ctx);
}
return (U) instantiateUi((Class)type, (Class)uiType, options);
}
protected abstract UiRenderingContext[] getOptions(Class> type);
protected UiRenderingContext createContext(Class extends UiRenderer> renderer, UiRendererOptions rendererOptions) {
// The default createContext method will simply instantiate all necessary instances immediately.
// This method is left protected so you can optionally implement caching or lazy loading.
UiRenderingContext ctx = new UiRenderingContext(create(renderer));
applyOptions(ctx, rendererOptions);
return ctx;
}
protected void applyOptions(UiRenderingContext ctx, UiRendererOptions rendererOptions) {
if (rendererOptions.isHead()) {
ctx.setHead(true);
} else if (rendererOptions.isTail()) {
ctx.setTail(true);
}
if (rendererOptions.isWrapper()) {
ctx.setWrapper(true);
}
ctx.setSelector(getSelector(ctx, rendererOptions));
ctx.setValidators(getValidators(ctx, rendererOptions));
}
protected Collection extractRenderingContext(UiOptions annotation, BeanValueProvider bean) {
List ctxes = new ArrayList();
for (UiRendererOptions rendererOption : annotation.renderers()) {
ctxes.addAll(extractRenderingContext(rendererOption, bean, null));
}
return ctxes;
}
protected Collection extractRenderingContext(UiRendererOptions rendererOption, BeanValueProvider bean, String methodName) {
List ctxes = new ArrayList();
for (Class extends UiRenderer> renderer : rendererOption.renderers()) {
UiRenderingContext ctx = createContext(renderer, rendererOption);
ctxes.add(ctx);
final BeanValueProvider ctxBean;
if (methodName == null) {
if (rendererOption.isWrapper()) {
// We must rebase $name and $value ad-hoc for each method
ctxBean = bean.rebaseAll();
} else {
ctxBean = bean;
}
} else {
// Rebase $name and $value to match the given method
ctxBean = bean.rebase(methodName);
}
ctx.setBeanProvider(ctxBean);
final String t = rendererOption.template();
if (t.length() > 0) {
// Assemble all the keys to be used in the template.
List replaceables = new ArrayList();
for (String key : rendererOption.templatekeys()) {
if (t.contains(key)) {
replaceables.add(key);
}
}
for (String key : ctxBean.getChildKeys()) {
if (t.contains("${"+key+"}")) {
replaceables.add("${"+key+"}");
}
if (t.contains("${"+key+".name()}")) {
replaceables.add("${"+key+".name()}");
}
}
ctx.setTemplate(new MappedTemplate(t, replaceables.toArray(new String[replaceables.size()])));
}
}
return ctxes;
}
protected Validator[] getValidators(UiRenderingContext ctx,
UiRendererOptions rendererOptions) {
return null;
}
protected UiRendererSelector getSelector(UiRenderingContext ctx,
UiRendererOptions rendererOptions) {
return create(rendererOptions.selector());
}
protected X create(Class extends X> renderer) {
try {
return renderer.newInstance();
} catch (InstantiationException e) {
throw X_Debug.rethrow(e.getCause() == null ? e : e.getCause());
} catch (IllegalAccessException e) {
throw X_Util.rethrow(e);
}
}
@Override
public BeanValueProvider getBeanProvider(Class> cls) {
BeanValueProvider bean = new BeanValueProvider();
ConvertsValue