![JAR search and dependency download from the Maven repository](/logo.png)
de.tsl2.nano.h5.configuration.BeanConfigurator Maven / Gradle / Ivy
/*
* File: $HeadURL$
* Id : $Id$
*
* created by: Tom, Thomas Schneider
* created on: 07.01.2014
*
* Copyright: (c) Thomas Schneider 2014, all rights reserved
*/
package de.tsl2.nano.h5.configuration;
import static de.tsl2.nano.h5.HtmlUtil.ATTR_BGCOLOR;
import static de.tsl2.nano.h5.HtmlUtil.COLOR_LIGHT_GRAY;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import de.tsl2.nano.action.CommonAction;
import de.tsl2.nano.action.IConstraint;
import de.tsl2.nano.bean.annotation.ConstraintValueSet;
import de.tsl2.nano.bean.def.AttributeDefinition;
import de.tsl2.nano.bean.def.Bean;
import de.tsl2.nano.bean.def.BeanDefinition;
import de.tsl2.nano.bean.def.Constraint;
import de.tsl2.nano.bean.def.IAttributeDefinition;
import de.tsl2.nano.bean.def.IPresentable;
import de.tsl2.nano.bean.def.IPresentableColumn;
import de.tsl2.nano.bean.def.Presentable;
import de.tsl2.nano.bean.def.ValueColumn;
import de.tsl2.nano.bean.def.ValueExpression;
import de.tsl2.nano.bean.def.ValueExpressionFormat;
import de.tsl2.nano.bean.def.ValueGroup;
import de.tsl2.nano.collection.Entry;
import de.tsl2.nano.core.ENV;
import de.tsl2.nano.core.ManagedException;
import de.tsl2.nano.core.cls.BeanClass;
import de.tsl2.nano.core.cls.IAttribute;
import de.tsl2.nano.core.cls.PrivateAccessor;
import de.tsl2.nano.core.util.ConcurrentUtil;
import de.tsl2.nano.core.util.FileUtil;
import de.tsl2.nano.core.util.MapUtil;
import de.tsl2.nano.core.util.StringUtil;
import de.tsl2.nano.core.util.Util;
import de.tsl2.nano.h5.Html5Presentable;
import de.tsl2.nano.h5.SpecifiedAction;
import de.tsl2.nano.h5.collector.CSheet;
import de.tsl2.nano.h5.collector.Compositor;
import de.tsl2.nano.h5.collector.Controller;
import de.tsl2.nano.h5.collector.Increaser;
import de.tsl2.nano.h5.expression.Query;
import de.tsl2.nano.h5.expression.WebClient;
import de.tsl2.nano.specification.Pool;
import de.tsl2.nano.specification.actions.Action;
import de.tsl2.nano.specification.rules.Rule;
import de.tsl2.nano.specification.rules.RuleScript;
/**
* wrapper class to handle presentation of a bean-definition. at a time, only one BeanConfigurator is active. this
* instance will be registered to the environment to be usable as something like a singleton from outside.
*
* @author Tom, Thomas Schneider
* @version $Revision$
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
public class BeanConfigurator implements Serializable {
/** serialVersionUID */
private static final long serialVersionUID = 1L;
BeanDefinition def;
private PrivateAccessor> defAccessor;
private transient List attrConfigurators;
/**
* factory method to create a bean configurator for the given instance type.
*
* @param instance to evaluate the type and {@link BeanDefinition} for.
* @return new bean configurator instance
*/
public static Bean> create(Class type) {
boolean autopersistEnv = ENV.isAutopersist();
BeanConfigurator> configurer = ConcurrentUtil.getCurrent(BeanConfigurator.class);
if (configurer == null || !configurer.def.getDeclaringClass().equals(type)) {
try {
ENV.setAutopersist(false);
Serializable layout = (Serializable) MapUtil.asMap(ATTR_BGCOLOR, COLOR_LIGHT_GRAY);
if (configurer == null)
prepareBeanDefinitionProperties(layout);
//wrap the bean-def into a bean-configurator and pack it into an own bean
configurer = new BeanConfigurator(BeanDefinition.getBeanDefinition(type));
//register it to be used by creating new AttributeConfigurators
ConcurrentUtil.setCurrent(configurer); //avoid stackoverflow
//define the presentation
Bean> configBean = Bean.getBean(configurer);
if (configBean.isDefault()) {
configBean.setAttributeFilter("name", "valueExpression", "presentable", "valueGroups", "attributes");
configBean.getPresentable().setLayout(layout);
((ValueExpressionFormat) configBean.getAttribute("attributes").getFormat())
.getValueExpression()
.setExpression("{name}");
// configBean.saveDefinition();
}
return (Bean>) configBean;
} finally {
ENV.setAutopersist(autopersistEnv);
}
}
return (Bean>) (Object)Bean.getBean(configurer);
}
private static void prepareBeanDefinitionProperties(Serializable layout) {
BeanDefinition configPres = BeanDefinition.getBeanDefinition(Html5Presentable.class, false);
configPres.setAttributeFilter("label", "description", "icon", "type", "style", "visible", "searchable",
"nesting", "width",
"height", "layout",
"layoutConstraints", "groups");
configPres.getPresentable().setLayout(layout);
configPres.getValueExpression();
// configPres.saveDefinition();
BeanDefinition configValueGroup = BeanDefinition.getBeanDefinition(ValueGroup.class, false);
configValueGroup.setAttributeFilter("label", "description", "icon", "type", "style", "width", "height",
"layout",
"layoutConstraints", "attributes");
configValueGroup.getPresentable().setLayout(layout);
configValueGroup.getValueExpression();
// configValueGroup.saveDefinition();
BeanDefinition configColDef = BeanDefinition.getBeanDefinition(ValueColumn.class, false);
configColDef.setAttributeFilter("name", "description", "index", "sortIndex", "sortUpDirection",
"format",
"width"
/* "standardSummary",
"presentable",
"minSearchValue",
"maxSearchValue"*/
);
configColDef.getPresentable().setLayout(layout);
BeanDefinition.getBeanDefinition(IPresentableColumn.class, false).setAttributeFilter(configColDef.getAttributeNames());
// configColDef.saveDefinition();
BeanDefinition configConstraint = BeanDefinition.getBeanDefinition(Constraint.class, false);
configConstraint.setAttributeFilter("type", "minimum", "maximum", "format", "length", "scale",
"precision",
"nullable");
configConstraint.getPresentable().setLayout(layout);
BeanDefinition.getBeanDefinition(IConstraint.class, false).setAttributeFilter(configConstraint.getAttributeNames());
// configConstraint.saveDefinition();
defineAction(layout);
BeanDefinition configEntry = BeanDefinition.getBeanDefinition(Entry.class, false);
configEntry.setAttributeFilter("key", "value");
configEntry.getPresentable().setLayout(layout);
configEntry.getValueExpression();
// configEntry.saveDefinition();
BeanDefinition configAttr =
BeanDefinition.getBeanDefinition(AttributeConfigurator.class, false);
configAttr.setAttributeFilter("name", "description", "type", "format",
"constraint"/*, "length", "min", "max"*/,
"presentable", "columnDefinition", "declaration", "valueExpression", "default", "listener");
configAttr.getPresentable().setLayout(layout);
configAttr.setValueExpression(new ValueExpression("{name}", AttributeConfigurator.class));
// configAttr.saveDefinition();
}
/**
* defineAction
*
* @param layout
*/
public static void defineAction(Serializable layout) {
BeanDefinition configAction = BeanDefinition.getBeanDefinition(CommonAction.class);
configAction.setAttributeFilter("id", "shortDescription", "longDescription", "keyStroke", "enabled", "default",
"imagePath");
configAction.setIdAttribute("id");
configAction.setValueExpression(new ValueExpression("{shortDescription}", CommonAction.class));
if (layout != null) {
configAction.getPresentable().setLayout(layout);
}
}
/**
* constructor
*
* @param def bean-def
*/
protected BeanConfigurator(BeanDefinition def) {
super();
this.def = def;
defAccessor = new PrivateAccessor>(def);
}
/**
* @return Returns the attributeDefinitions.
*/
public List getAttributes() {
if (attrConfigurators == null) {
//we know that there are attribute-defs inside!
List attributes = def.getAttributes();
attrConfigurators = new ArrayList(attributes.size());
for (IAttribute> a : attributes) {
attrConfigurators.add(new AttributeConfigurator((AttributeDefinition>) a));
}
}
return attrConfigurators;
}
/**
* @param attributes The attributeDefinitions to set.
*/
public void setAttributes(List attributes) {
Map definitions = defAccessor.call("getAttributeDefinitions", Map.class);
Map invisibles = new LinkedHashMap<>(definitions);
definitions.clear();
int i = 0;
for (AttributeConfigurator cattr : attributes) {
IAttributeDefinition a = cattr.unwrap();
if (a.getColumnDefinition() == null)
a.setColumnDefinition(++i, IPresentable.UNDEFINED, true, IPresentable.UNDEFINED);
else //IMPROVE: enhance interfaces to set index without reflection
new PrivateAccessor(a.getColumnDefinition()).set("columnIndex", ++i);
def.addAttribute(a);
invisibles.remove(a.getName());
}
//add not-selected attributes as invisibles at the end
for (IAttributeDefinition> a : invisibles.values()) {
//IMPROVE: enhance interfaces to set index without reflection
a.getPresentation().setVisible(false);
if (a.getColumnDefinition() != null) {
new PrivateAccessor(a.getColumnDefinition()).set("columnIndex", ++i);
a.getColumnDefinition().getPresentable().setVisible(false);
}
def.addAttribute(a);
}
attrConfigurators = null;
}
/**
* @return Returns the presentable.
*/
public Presentable getPresentable() {
return (Presentable) def.getPresentable();
}
/**
* @param presentable The presentable to set.
*/
public void setPresentable(Presentable presentable) {
def.setPresentable(presentable);
}
/**
* @return Returns the presentable.
*/
public Collection getValueGroups() {
return defAccessor.member("valueGroups", Collection.class);
}
/**
* @param valueGroups The presentable to set.
*/
public void setValueGroups(Collection valueGroups) {
defAccessor.set("valueGroups", valueGroups);
}
/**
* @return Returns the name.
*/
public String getName() {
return def.getName();
}
/**
* @return Returns the valueExpression.
*/
public String getValueExpression() {
return def.getValueExpression().getExpression();
}
/**
* @param valueExpression The valueExpression to set.
*/
public void setValueExpression(String valueExpression) {
def.setValueExpression(new ValueExpression(valueExpression, def.getClazz()));
}
/**
* saves the current bean configuration.
* this method will trigger the bean-framework to provide an action to be presented as button in a gui.
*
* @return null
*/
public Object actionSave() {
defAccessor.set("isdefault", false);
//WORKAROUND: doesn't call setAttributes(), so we do it here
if (attrConfigurators != null)
setAttributes(attrConfigurators);
def.saveDefinition();
ConcurrentUtil.removeCurrent(BeanConfigurator.class);
/*
* refresh all beans
*/
Bean.clearCache();
//return null to let the session-navigation return to the last element.
return null;
}
public Object actionReset() {
defAccessor.set("isdefault", true);
def.deleteDefinition();
ConcurrentUtil.removeCurrent(BeanConfigurator.class);
/*
* refresh all beans
*/
Bean.clearCache();
return null;
}
@Override
public int hashCode() {
return def.hashCode();
}
@Override
public boolean equals(Object obj) {
return obj instanceof BeanConfigurator ? def.equals(((BeanConfigurator) obj).def) : false;
}
@Override
public String toString() {
return Util.toString(getClass(), def);
}
@de.tsl2.nano.bean.annotation.Action(name = "createRuleOrAction", argNames = { "newActionName", "actionType",
"actionExpression" })
public void actionCreateRuleOrAction(String newActionName,
@de.tsl2.nano.bean.annotation.Constraint(defaultValue = "%: RuleScript (--> JavaScript)", allowed = {
"§: Rule (--> Operation)", "%: RuleScript (--> JavaScript)", "!: Action (--> Java)"
, "?: Query (--> SQL statement)", "@: Web (--> URL/REST)" }) String actionType,
/*@de.tsl2.nano.bean.annotation.Constraint(pattern = ".*") */String actionExpression) {
if (actionType.startsWith("%"))
ENV.get(Pool.class).add(new RuleScript<>(newActionName, actionExpression, null));
else if (actionType.startsWith("§"))
ENV.get(Pool.class).add(new Rule(newActionName, actionExpression, null));
else if (actionType.startsWith("!"))
ENV.get(Pool.class).add(new Action(newActionName, actionExpression));
else if (actionType.startsWith("@"))
ENV.get(Pool.class).add(WebClient.create(actionExpression, def.getDeclaringClass()));
else if (actionType.startsWith("?"))
ENV.get(Pool.class).add(new Query(newActionName, actionExpression, true, null));
}
@de.tsl2.nano.bean.annotation.Action(name = "addAction", argNames = { "specifiedAction" })
public void actionAddAction(
@de.tsl2.nano.bean.annotation.Constraint(allowed=ConstraintValueSet.ALLOWED_ENVFILES + ".*specification/action.*") String specifiedAction) {
//check, if action available
specifiedAction = StringUtil.substring(FileUtil.replaceToJavaSeparator(specifiedAction), "/", ".", true);
ENV.get(Pool.class).get(specifiedAction, Action.class);
SpecifiedAction
© 2015 - 2025 Weber Informatics LLC | Privacy Policy