All Downloads are FREE. Search and download functionalities are using the official Maven repository.

de.tsl2.nano.h5.collector.Controller Maven / Gradle / Ivy

Go to download

TSL2 Framework Html5 Extensions (WebServer, Html5Presentation, RuleCover, BeanConfigurator, LogicTable-Sheet, Expression-Descriptors for Actions, Rules, URLs, Queries)

There is a newer version: 2.5.2
Show newest version
/*
 * File: $HeadURL$
 * Id  : $Id$
 * 
 * created by: Tom, Thomas Schneider
 * created on: 26.02.2014
 * 
 * Copyright: (c) Thomas Schneider 2014, all rights reserved
 */
package de.tsl2.nano.h5.collector;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import org.simpleframework.xml.Transient;

import de.tsl2.nano.action.IAction;
import de.tsl2.nano.bean.BeanUtil;
import de.tsl2.nano.bean.def.Bean;
import de.tsl2.nano.bean.def.BeanCollector;
import de.tsl2.nano.bean.def.BeanDefinition;
import de.tsl2.nano.bean.def.ValueExpression;
import de.tsl2.nano.core.cls.IAttribute;
import de.tsl2.nano.core.util.NumberUtil;
import de.tsl2.nano.core.util.StringUtil;

/**
 * Special {@link BeanCollector} to show a list of beans providing their actions. the defined bean should have some
 * actions to change attributes in an easy way - like de- or increasing a value. The best use-case is to show a set of
 * buttons with pictures on a touch-screen.
 * 

* Through the bean-definition of {@link #name}, a special bean, holding the actions, can start a selected action * through {@link #doAction(String)}.

* The super class Compositor tries to build actions given by baseAttribute and targetAttribute. * The second possibility for creating actions is to set an itemProvider through {@link #setItemProvider(Increaser)}. * * @author Tom, Thomas Schneider * @version $Revision$ */ @SuppressWarnings({ "unchecked", "rawtypes" }) public class Controller, T> extends Compositor { /** serialVersionUID */ private static final long serialVersionUID = 1L; public static final String PREFIX_CTRLACTION = "CTRLROW("; public static final String POSTFIX_CTRLACTION = ")"; private static final String PREFIX_CONTROLLER = "controller"; /** the special bean-implementation holding all desired actions */ @Transient Increaser itemProvider; @Transient boolean showText; @Transient boolean isTransparent=true; /** if you want only one creation button/action per parent-instance, this should be true. * if you want to provide different actions on one bean, this should be false */ @Transient boolean creationOnly=false; transient List attributes; /** * constructor */ protected Controller() { super(); } public Controller(String beanName) { this(beanName, null, null, null, null); } /** * constructor * * @param beanType * @param workingMode */ public Controller(String beanName, String baseType, String baseAttribute, String targetAttribute, String iconAttribute) { this((BeanDefinition) BeanDefinition.getBeanDefinition(beanName), (BeanDefinition) (baseType != null ? BeanDefinition.getBeanDefinition(baseType) : null), baseAttribute, targetAttribute, iconAttribute); } /** * constructor * * @param beanType * @param workingMode */ public Controller(BeanDefinition beanDef, BeanDefinition baseType, String baseAttribute, String targetAttribute, String iconAttribute) { this(beanDef.getDeclaringClass(), baseType != null ? baseType.getDeclaringClass() : null, baseAttribute, targetAttribute, iconAttribute); } public Controller(Class beanDef, Class baseType, String baseAttribute, String targetAttribute, String iconAttribute) { super(beanDef, baseType, baseAttribute, targetAttribute, iconAttribute); this.name = createName(beanDef, baseType); } public String createName(Class beanDef, Class baseType) { return createBeanDefName(beanDef, baseType); } public static String createBeanDefName(Class beanDef, Class baseType) { return createBeanDefName("Controller", beanDef, baseType); } public Bean getBean(T instance) { return getBean(instance, null); } /** * gets the defined bean (see {@link #name} for the given instance. * * @param instance * @param collected (optional) to add actions only once per instance * @return bean holding instance */ public Bean getBean(T instance, Collection collected) { Bean bean = BeanUtil.copy((Bean) Bean.getBean(name)); bean.setValueExpression(getValueExpression()); bean.setInstance(instance); bean.setAddSaveAction(false); //if controlling from baseType (annotation on baseType), we want exactly one creation-action if (getDeclaringClass().equals(parentType) || isCreationOnly()) { if (parentType != null && !getDeclaringClass().equals(parentType)) { instance = getParentInstance(instance); } if (collected == null || !collected.contains(instance)) { if (collected != null) //only to avoid adding the same actions on several instances! collected.add(instance); Collection compActions = super.getActions(); String compositorActionId = createCompositorActionId(instance); for (IAction a : compActions) { if (a.getId().equals(compositorActionId)) { bean.setActions(Arrays.asList(a)); break; } } } } else {//on each row get all compositor actions bean.setActions(super.getActions()); //filter collector actions for (Iterator it = bean.getActions().iterator(); it.hasNext();) { IAction a = (IAction) it.next(); //TODO: internal name convention - is there a better way? if (!a.getId().startsWith(PREFIX_CONTROLLER)) it.remove(); } } return bean; } @Override public Collection getActions() { return new LinkedList<>(); //don't show the actions in the action panel again! } /** * extracts the bean-instance and the action id and starts it. * * @param actionIdWithRowNumber the row-number has to be one-based! * @param session * @return result of given action */ public Object doAction(String actionIdWithRowNumber, Map context) { String strRow = StringUtil.substring(actionIdWithRowNumber, PREFIX_CTRLACTION, POSTFIX_CTRLACTION); Number row = NumberUtil.extractNumber(strRow); assert row.intValue() > 0 : "row must be one-based!"; ArrayList list = new ArrayList(getCurrentData()); assert row.intValue() <= list.size() : "row=" + row + " (one-based) is outside of list size=" + list.size(); String id = StringUtil.substring(actionIdWithRowNumber, POSTFIX_CTRLACTION, null); IAction action = getBean(list.get(row.intValue() - 1)).getAction(id); assert action != null : "no action with id=" + id + " found on (one-based) row " + row + "! see: " + StringUtil.toString(list, 120); action.setParameter(context); return action.activate(); } @Override public boolean isVirtual() { return true; } @Override public ValueExpression getValueExpression() { if (valueExpression == null) { //use the expression of the standard definition valueExpression = BeanDefinition.getBeanDefinition(getType()).getValueExpression(); } return valueExpression; } @Override public Compositor refreshed() { if (isStale()) return new Controller(clazz, parentType, baseAttribute, targetAttribute, iconAttribute); return this; } @Override public > B onActivation(Map context) { if (itemProvider != null && itemProvider.getCount() > getCurrentData().size()) { //TODO: create only missing items getCurrentData().addAll(provideTransientData(context)); } return super.onActivation(context); } private Collection provideTransientData(Map context) { T item = createItem(null); if (context != null) fillContext(item, context.values().toArray()); return itemProvider.createItems(item, context); } /** * @return Returns the itemProvider. */ public Increaser getItemProvider() { return itemProvider; } /** * @param itemProvider The itemProvider to set. */ public Controller setItemProvider(Increaser itemProvider) { this.itemProvider = itemProvider; setValueExpression(new ValueExpression("{" + itemProvider.getName() + "}")); return this; } public static String createActionName(int row, String id) { assert row > 0 : "row must be one-based!"; return PREFIX_CTRLACTION + row + POSTFIX_CTRLACTION + id; } public boolean showText() { return showText; } public boolean isTransparent() { return isTransparent; } public boolean isCreationOnly() { return creationOnly; } public void setShowText(boolean showText) { this.showText = showText; } public void setTransparent(boolean isTransparent) { this.isTransparent = isTransparent; } public void setCreationOnly(boolean creationOnly) { this.creationOnly = creationOnly; } public void setPresentationValues(boolean showText, boolean transparent, boolean creationOnly) { setShowText(showText); setTransparent(transparent); setCreationOnly(creationOnly); } @Override protected long count() { //to guarantee an automatic search in onActivation() return 0; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy