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.
net.contextfw.web.application.internal.component.ComponentBuilderImpl Maven / Gradle / Ivy
package net.contextfw.web.application.internal.component;
import java.beans.IntrospectionException;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.WeakHashMap;
import net.contextfw.web.application.WebApplicationException;
import net.contextfw.web.application.component.Attribute;
import net.contextfw.web.application.component.Buildable;
import net.contextfw.web.application.component.Component;
import net.contextfw.web.application.component.CustomBuild;
import net.contextfw.web.application.component.DOMBuilder;
import net.contextfw.web.application.component.Element;
import net.contextfw.web.application.component.ScriptContext;
import net.contextfw.web.application.component.ScriptElement;
import net.contextfw.web.application.configuration.Configuration;
import net.contextfw.web.application.internal.util.AttributeHandler;
import net.contextfw.web.application.lifecycle.AfterBuild;
import net.contextfw.web.application.lifecycle.BeforeBuild;
import com.google.gson.Gson;
import com.google.inject.Inject;
import com.google.inject.Singleton;
@Singleton
public class ComponentBuilderImpl implements ComponentBuilder, ScriptContext {
private static class MetaModel {
public Set registeredNames = new HashSet();
public List beforeBuilds = new ArrayList();
public List afterBuilds = new ArrayList();
public List builders = new ArrayList();
public List updateBuilders = new ArrayList();
public List partialBuilders = new ArrayList();
public String buildName;
public Buildable annotation;
}
private static final Map, MetaModel> metaModels = new HashMap, MetaModel>();
private static final Map, Class>> actualClasses = new WeakHashMap, Class>>();
private final AttributeHandler attributeHandler;
private final Gson gson;
@Inject
public ComponentBuilderImpl(AttributeHandler attributeHandler, Gson gson,
Configuration properties) {
this.attributeHandler = attributeHandler;
this.gson = gson;
}
private MetaModel getMetaModel(final Class> cl) {
Class> actual = actualClasses.get(cl);
if (actual == null) {
actual = getActualClass(cl);
actualClasses.put(cl, actual);
}
MetaModel model = metaModels.get(actual);
if (model == null) {
model = createMetaModel(actual);
metaModels.put(actual, model);
}
return model;
}
private Buildable findBuildable(final Class> cl) {
Class> current = cl;
while (current instanceof Object) {
if (current.isAnnotationPresent(Buildable.class)) {
return current.getAnnotation(Buildable.class);
}
current = current.getSuperclass();
}
return null;
}
private MetaModel createMetaModel(final Class> cl) {
try {
MetaModel model = new MetaModel();
model.annotation = findBuildable(cl);
if (model.annotation != null) {
if (model.annotation.wrap()) {
model.buildName = ("".equals(model.annotation.name()) ? cl
.getSimpleName() : model.annotation.name());
}
addEmbeddeds(model, cl);
}
return model;
} catch (IllegalAccessException e) {
throw new WebApplicationException(e);
} catch (InvocationTargetException e) {
throw new WebApplicationException(e);
} catch (NoSuchMethodException e) {
throw new WebApplicationException(e);
} catch (IntrospectionException e) {
throw new WebApplicationException(e);
}
}
public void clean() {
metaModels.clear();
actualClasses.clear();
}
private void addEmbeddeds(MetaModel model, Class> cl)
throws IllegalAccessException, InvocationTargetException,
NoSuchMethodException, IntrospectionException {
Class> currentClass = cl;
while (currentClass instanceof Object) {
for (Field field : currentClass.getDeclaredFields()) {
PropertyAccess propertyAccess = new FieldPropertyAccess(
field);
String name = null;
Builder builder = null;
if (field.getAnnotation(Element.class) != null) {
Element element = field.getAnnotation(Element.class);
name = "".equals(element.name()) ? field.getName()
: element.name();
builder = new ElementBuilder(this, propertyAccess,
element.wrap() ? name : null, field.getName());
addToBuilders(model, field.getName(), element.onCreate(),
element.onUpdate(), builder);
} else if (field.getAnnotation(Attribute.class) != null) {
Attribute attribute = field.getAnnotation(Attribute.class);
name = "".equals(attribute.name()) ? field.getName()
: attribute.name();
builder = new AttributeBuilder(propertyAccess, name,
field.getName());
addToBuilders(model, field.getName(), attribute.onCreate(),
attribute.onUpdate(), builder);
} else if (field.getAnnotation(ScriptElement.class) != null) {
ScriptElement scriptElement = field
.getAnnotation(ScriptElement.class);
name = scriptElement.wrapper();
builder = new ScriptElementBuilder(this, gson,
propertyAccess, name, field.getName());
addToBuilders(model, field.getName(), scriptElement.onCreate(),
scriptElement.onUpdate(), builder);
}
}
for (Method method : currentClass.getDeclaredMethods()) {
String name = null;
Builder builder = null;
if (method.getAnnotation(Element.class) != null) {
Element annotation = method.getAnnotation(Element.class);
name = "".equals(annotation.name()) ? method.getName()
: annotation.name();
builder = new ElementBuilder(this, new MethodPropertyAccess(
method),
annotation.wrap() ? name : null, method.getName());
addToBuilders(model, method.getName(), annotation.onCreate(),
annotation.onUpdate(), builder);
} else if (method.getAnnotation(Attribute.class) != null) {
Attribute annotation = method
.getAnnotation(Attribute.class);
name = "".equals(annotation.name()) ? method.getName()
: annotation.name();
builder = new AttributeBuilder(new MethodPropertyAccess(
method), name,
method.getName());
addToBuilders(model, method.getName(), annotation.onCreate(),
annotation.onUpdate(), builder);
} else if (method.getAnnotation(CustomBuild.class) != null) {
CustomBuild annotation = method
.getAnnotation(CustomBuild.class);
name = "".equals(annotation.name()) ? method.getName()
: annotation.name();
builder = new MethodCustomBuilder(method,
annotation.wrap() ? name : null);
addToBuilders(model, method.getName(), annotation.onCreate(),
annotation.onUpdate(), builder);
} else if (method.getAnnotation(ScriptElement.class) != null) {
ScriptElement scriptElement = method
.getAnnotation(ScriptElement.class);
name = scriptElement.wrapper();
builder = new ScriptElementBuilder(this, gson,
new MethodPropertyAccess(
method), name, method.getName());
addToBuilders(model, method.getName(), scriptElement.onCreate(),
scriptElement.onUpdate(), builder);
} else if (method.getAnnotation(AfterBuild.class) != null) {
addAfterBuild(model, method);
} else if (method.getAnnotation(BeforeBuild.class) != null) {
addBeforeBuild(model, method);
}
}
currentClass = currentClass.getSuperclass();
}
}
private void addAfterBuild(MetaModel model, Method method) {
model.afterBuilds.add(method);
}
private void addBeforeBuild(MetaModel model, Method method) {
model.beforeBuilds.add(method);
}
private void addToBuilders(MetaModel model,
String actualName,
boolean onCreate,
boolean onUpdate,
Builder builder) {
if (model.registeredNames.contains(actualName)) {
return;
} else {
model.registeredNames.add(actualName);
}
if (onCreate) {
model.builders.add(builder);
}
if (onUpdate) {
model.updateBuilders.add(builder);
}
model.partialBuilders.add(builder);
}
public static Class> getActualClass(Object element) {
return getActualClass(element.getClass());
}
public static Class> getActualClass(Class> cl) {
Class> actual = actualClasses.get(cl);
if (actual != null) {
return actual;
} else {
actual = cl;
while (actual.getSimpleName().contains("EnhancerByGuice")) {
actual = actual.getSuperclass();
}
actualClasses.put(cl, actual);
return actual;
}
}
@Override
public String getBuildName(Class> cl) {
MetaModel model = getMetaModel(cl);
if (model.annotation != null) {
return model.buildName;
} else {
throw new WebApplicationException("Class " + cl.getName()
+ " is not buildable");
}
}
@Override
public void build(DOMBuilder sb, Object component, Object... buildins) {
MetaModel model = getMetaModel(component.getClass());
if (model.annotation != null) {
DOMBuilder b = model.buildName == null ? sb : sb
.descend(model.buildName);
build(model, b, component, model.builders, false, null, buildins);
} else {
sb.text(attributeHandler.serialize(component));
}
}
private void build(MetaModel model, DOMBuilder b, Object component,
List builders, boolean partial, Set updates,
Object... buildins) {
if (component instanceof Component) {
if (!((Component) component).isEnabled()) {
return;
}
}
for (Method method : model.beforeBuilds) {
try {
method.invoke(component);
} catch (IllegalArgumentException e) {
throw new WebApplicationException(e);
} catch (IllegalAccessException e) {
throw new WebApplicationException(e);
} catch (InvocationTargetException e) {
throw new WebApplicationException(e);
}
}
if (partial) {
for (Builder builder : builders) {
if (builder.isUpdateBuildable(updates)) {
builder.build(b, component);
}
}
} else {
for (Builder builder : builders) {
builder.build(b, component);
}
}
// Handling buildins
if (buildins != null) {
for (Object buildIn : buildins) {
if (buildIn != null) {
MetaModel bmodel = getMetaModel(buildIn.getClass());
if (bmodel.annotation != null) {
for (Builder builder : bmodel.builders) {
builder.build(b, buildIn);
}
}
}
}
}
for (Method method : model.afterBuilds) {
try {
method.invoke(component);
} catch (IllegalArgumentException e) {
throw new WebApplicationException(e);
} catch (IllegalAccessException e) {
throw new WebApplicationException(e);
} catch (InvocationTargetException e) {
throw new WebApplicationException(e);
}
}
}
@Override
public void buildUpdate(DOMBuilder sb, Component component,
String updateName) {
MetaModel model = getMetaModel(component.getClass());
if (model.annotation != null) {
DOMBuilder b = sb.descend(model.buildName + "." + updateName);
build(model, b, component, model.updateBuilders, false, null,
(Object[]) null);
}
}
@Override
public void buildPartialUpdate(DOMBuilder sb, Component component,
String updateName, Set updates) {
MetaModel model = getMetaModel(component.getClass());
if (model.annotation != null) {
DOMBuilder b = sb.descend(model.buildName + "." + updateName);
build(model, b, component, model.partialBuilders, true, updates,
(Object[]) null);
}
}
@Override
public boolean isBuildable(Class> cl) {
return getMetaModel(cl).annotation != null;
}
}