![JAR search and dependency download from the Maven repository](/logo.png)
de.tsl2.nano.bean.BeanContainer Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of tsl2.nano.descriptor Show documentation
Show all versions of tsl2.nano.descriptor Show documentation
TSL2 Framework Descriptor (currency-handling, generic formatter, descriptors for beans, collections, actions and values)
The newest version!
/*
* File: $HeadURL$
* Id : $Id$
*
* created by: Thomas Schneider
* created on: Feb 4, 2010
*
* Copyright: (c) Thomas Schneider 2010, all rights reserved
*/
package de.tsl2.nano.bean;
import java.io.Serializable;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import org.apache.commons.logging.Log;
import de.tsl2.nano.action.CommonAction;
import de.tsl2.nano.action.IAction;
import de.tsl2.nano.bean.def.Bean;
import de.tsl2.nano.bean.def.BeanDefinition;
import de.tsl2.nano.bean.def.BeanValue;
import de.tsl2.nano.bean.def.IAttributeDefinition;
import de.tsl2.nano.core.ENV;
import de.tsl2.nano.core.ManagedException;
import de.tsl2.nano.core.Messages;
import de.tsl2.nano.core.cls.BeanAttribute;
import de.tsl2.nano.core.cls.BeanClass;
import de.tsl2.nano.core.cls.IAttribute;
import de.tsl2.nano.core.log.LogFactory;
import de.tsl2.nano.core.util.DateUtil;
import de.tsl2.nano.core.util.ListSet;
import de.tsl2.nano.core.util.NumberUtil;
import de.tsl2.nano.core.util.StringUtil;
/**
* class to be used as simple one instance bean container. initialize it with your service actions (through calls to
* specific service factories). it is a delegating class to avoid depending to a service factory and its services.
*
* @author Thomas Schneider
* @version $Revision$
*/
@SuppressWarnings({ "serial", "rawtypes", "unchecked" })
public class BeanContainer implements IBeanContainer {
/** we provide a thread invariant and a thread variant singelton instance - this is not secure but practicable. */
private static BeanContainer self = null;
private static ThreadLocal selfThread = new ThreadLocal();
private static final Log LOG = LogFactory.getLog(BeanContainer.class);
/** on initializing with {@link #initEmtpyServiceActions()} it is true */
private boolean emptyServices = false;
protected IAction> idFinderAction = null;
protected IAction> typeFinderAction = null;
protected IAction> exampleFinderAction = null;
protected IAction> betweenFinderAction = null;
protected IAction> queryAction = null;
protected IAction> queryMapAction = null;
protected IAction> lazyrelationInstantiateAction = null;
protected IAction> saveAction = null;
protected IAction> deleteAction = null;
protected IAction attrdefAction = null;
protected IAction> permissionAction = null;
protected IAction> persistableAction = null;
protected IAction executeAction = null;
private BeanContainer() {
super();
}
/**
* you must have called {@link #initServiceActions(IAction, IAction, IAction)} before you can use the instance.
*
* @return singelton instance
*/
public static final BeanContainer instance() {
assert self() != null : "beancontainer not initialized! call initServiceActions(...) before!";
return self();
}
private static BeanContainer self() {
return selfThread.get() != null ? selfThread.get() : self;
}
/**
* isInitialized
*
* @return true, if {@link #initEmtpyServiceActions()} or
* {@link #initServiceActions(IAction, IAction, IAction, IAction, IAction, IAction, IAction, IAction, IAction, IAction)}
* was called before.
*/
public static final boolean isInitialized() {
return self() != null;
}
/**
* call this method only on initializing your new application.
*
* @param relationFinder action to find beans through a service
* @param lazyRelationResolver to fetch all lazy relations
* @param saveAction action to save bean through service
* @param deleteAction action to delete bean through service
* @param exampleFinder action to find beans through a service
* @param betweenFinder action to find beans through a service
* @param attrdefAction action to evaluate attribute definitions
* @param permissionAction action to evaluate the permission (through roles)
* @param persistableAction asks, if the given bean is persistable
*/
public static final void initServiceActions(IAction> idFinder,
IAction> relationFinder,
IAction> lazyRelationResolver,
IAction> saveAction,
IAction> deleteAction,
IAction> exampleFinder,
IAction> betweenFinder,
IAction> queryFinder,
IAction> queryMapFinder,
IAction attrdefAction,
IAction permissionAction,
IAction persistableAction,
IAction executeAction) {
self = new BeanContainer();
selfThread.set(self);
self.idFinderAction = idFinder;
self.typeFinderAction = relationFinder;
self.lazyrelationInstantiateAction = lazyRelationResolver;
self.saveAction = saveAction;
self.deleteAction = deleteAction;
self.exampleFinderAction = exampleFinder;
self.betweenFinderAction = betweenFinder;
self.queryAction = queryFinder;
self.queryMapAction = queryMapFinder;
self.attrdefAction = attrdefAction;
self.permissionAction = permissionAction;
self.persistableAction = persistableAction;
self.executeAction = executeAction;
}
/**
* will call {@link #initServiceActions(IAction, IAction, IAction)} with simple actions, doing nothing. useful for
* testing.
*/
public static final Collection initEmtpyServiceActions(Object...testInstances) {
final Collection> EMPTY_LIST = new ListSet(testInstances);
final IAction idFinder = new CommonAction("empty.service.idFinder") {
@Override
public Object action() {
LOG.debug("call to '" + this.getId() + "' (parameter: " + StringUtil.toString(getParameter(), 80) + "): on empty service actions -> doing nothing!");
return EMPTY_LIST.size() > 0 ? EMPTY_LIST.iterator().next() : null;
}
};
final IAction> relationFinder = new CommonAction>("empty.service.relationFinder") {
@Override
public Collection> action() {
LOG.debug("call to '" + this.getId() + "' (parameter: " + StringUtil.toString(getParameter(), 80) + "): on empty service actions -> doing nothing!");
return EMPTY_LIST;
}
};
final IAction> exampleFinder = new CommonAction>("empty.service.exampleFinder") {
@Override
public Collection> action() {
LOG.debug("call to '" + this.getId() + "' (parameter: " + StringUtil.toString(getParameter(), 80) + "): on empty service actions -> doing nothing!");
return EMPTY_LIST;
}
};
final IAction> betweenFinder = new CommonAction>("empty.service.betweenFinder") {
@Override
public Collection> action() {
LOG.debug("call to '" + this.getId() + "' (parameter: " + StringUtil.toString(getParameter(), 80) + "): on empty service actions -> doing nothing!");
return EMPTY_LIST;
}
};
final IAction> queryFinder = new CommonAction>("empty.service.queryFinder") {
@Override
public Collection> action() {
LOG.debug("call to '" + this.getId() + "' (parameter: " + StringUtil.toString(getParameter(), 80) + "): on empty service actions -> doing nothing!");
return EMPTY_LIST;
}
};
final IAction> queryMapFinder = new CommonAction>("empty.service.queryMapFinder") {
@Override
public Collection> action() {
LOG.debug("call to '" + this.getId() + "' (parameter: " + StringUtil.toString(getParameter(), 80) + "): on empty service actions -> doing nothing!");
return EMPTY_LIST;
}
};
final IAction lazyRelationResolver = new CommonAction("empty.service.lazyRelationResolver") {
@Override
public Object action() {
LOG.debug("call to '" + this.getId() + "' (parameter: " + StringUtil.toString(getParameter(), 80) + "): on empty service actions -> doing nothing!");
return getParameter()[0];
}
};
final IAction saveAction = new CommonAction("empty.service.saveAction") {
@Override
public Object action() {
LOG.debug("call to '" + this.getId() + "' (parameter: " + StringUtil.toString(getParameter(), 80) + "): on empty service actions -> doing nothing!");
//do nothing, return the instance itself
return getParameter()[0];
}
};
final IAction deleteAction = new CommonAction("empty.service.deleteAction") {
@Override
public Object action() {
LOG.debug("call to '" + this.getId() + "' (parameter: " + StringUtil.toString(getParameter(), 80) + "): on empty service actions -> doing nothing!");
return null;
}
};
final IAction attrAction = new CommonAction("empty.service.attrAction") {
@Override
public IAttributeDef action() {
LOG.debug("call to '" + this.getId() + "' (parameter: " + StringUtil.toString(getParameter(), 80) + "): on empty service actions -> doing nothing!");
return null;
}
};
final IAction permissionAction = new CommonAction("empty.service.permissionAction") {
@Override
public Object action() {
LOG.debug("call to '" + this.getId() + "' (parameter: " + StringUtil.toString(getParameter(), 80) + "): on empty service actions -> doing nothing!");
return true;
}
};
final IAction persistableAction = new CommonAction("empty.service.persistableAction") {
@Override
public Object action() {
LOG.debug("call to '" + this.getId() + "' (parameter: " + StringUtil.toString(getParameter(), 80) + "): on empty service actions -> doing nothing!");
return Serializable.class.isAssignableFrom((Class>) getParameter()[0]);
}
};
final IAction executeAction = new CommonAction("empty.service.executeAction") {
@Override
public Integer action() {
LOG.debug("call to '" + this.getId() + "' (parameter: " + StringUtil.toString(getParameter(), 80) + "): on empty service actions -> doing nothing!");
return null;
}
};
BeanContainer.initServiceActions(idFinder,
relationFinder,
lazyRelationResolver,
saveAction,
deleteAction,
exampleFinder,
betweenFinder,
queryFinder,
queryMapFinder,
attrAction,
permissionAction,
persistableAction,
executeAction);
self.emptyServices = true;
return EMPTY_LIST;
}
/**
* @return see {@link #emptyServices}
*/
public static boolean isConnected() {
return isInitialized() && !self().emptyServices;
}
/**
* {@inheritDoc}
*/
@Override
public T createBean(Class type) {
return createBeanInstance(type);
}
/**
* createBeanInstance
*
* @param
* @param type
* @return
*/
public static T createBeanInstance(Class type) {
try {
T bean;
if (type.isInterface()) {
bean = BeanProxy.createBeanImplementation(type, null, null, Thread.currentThread()
.getContextClassLoader());
} else {
bean = BeanClass.createInstance(type);
}
initDefaults(bean);
return bean;
} catch (final Exception e) {
ManagedException.forward(e);
return null;
}
}
/**
* initializes collections not to be null.
* @param bean new created bean.
*/
public static void initDefaults(T bean) {
//to fulfill bindings on onetomany, we bind empty lists
final BeanClass clazz = BeanClass.getBeanClass(bean.getClass());
final Collection multiValueAttributes = clazz.getMultiValueAttributes();
for (final BeanAttribute beanAttribute : multiValueAttributes) {
if (Set.class.isAssignableFrom(beanAttribute.getType())) {
beanAttribute.setValue(bean, new LinkedHashSet());
} else if (Collection.class.isAssignableFrom(beanAttribute.getType())) {
beanAttribute.setValue(bean, new LinkedList());
} else if (Properties.class.isAssignableFrom(beanAttribute.getType())) {
beanAttribute.setValue(bean, new Properties());
} else if (Map.class.isAssignableFrom(beanAttribute.getType())) {
beanAttribute.setValue(bean, new LinkedHashMap());
}
}
}
/**
* {@inheritDoc}
*/
@Override
public void delete(T bean) {
deleteAction.setParameter(new Object[] { bean });
deleteAction.activate();
}
/**
* {@inheritDoc}
*/
@Override
public T save(T bean) {
saveAction.setParameter(new Object[] { bean });
return (T) saveAction.activate();
}
/**
* {@inheritDoc}
*/
@Override
public T getByID(Class type, Object id) {
idFinderAction.setParameter(new Object[] { type, id });
return (T) idFinderAction.activate();
}
/**
* {@inheritDoc}
*/
@Override
public Collection getBeans(Class type, int startIndex, int maxResult) {
typeFinderAction.setParameter(new Object[] { type, startIndex, maxResult });
return (Collection) typeFinderAction.activate();
}
@Override
public Collection getBeans(BeanFindParameters parameters) {
typeFinderAction.setParameter(new Object[] { parameters });
return (Collection) typeFinderAction.activate();
}
/**
* {@inheritDoc}
*/
@Override
public Collection getBeansByExample(T exampleBean) {
return getBeansByExample(exampleBean, false, 0, Integer.MAX_VALUE);
}
/**
* {@inheritDoc}
*/
@Override
public Collection getBeansByExample(T exampleBean, Boolean useLike, int startIndex, int maxResult) {
exampleFinderAction.setParameter(new Object[] { exampleBean, useLike, startIndex, maxResult });
return (Collection) exampleFinderAction.activate();
}
@Override
public Collection getBeansByExample(T exampleBean, Boolean useLike, BeanFindParameters parameters) {
exampleFinderAction.setParameter(new Object[] { exampleBean, useLike, parameters });
return (Collection) exampleFinderAction.activate();
}
/**
* {@inheritDoc}
*/
@Override
public Collection getBeansBetween(T firstExampleBean, T secondExampleBean, int startIndex, int maxResult) {
betweenFinderAction.setParameter(new Object[] { firstExampleBean, secondExampleBean, startIndex, maxResult });
return (Collection) betweenFinderAction.activate();
}
@Override
public Collection getBeansBetween(T firstBean, T secondBean, BeanFindParameters parameters) {
betweenFinderAction.setParameter(new Object[] { firstBean, secondBean, parameters });
return (Collection) betweenFinderAction.activate();
}
/**
* {@inheritDoc}
*/
@Override
public T resolveLazyRelations(T bean) {
lazyrelationInstantiateAction.setParameter(new Object[] { bean });
return (T) lazyrelationInstantiateAction.activate();
}
/**
* {@inheritDoc}
*/
@Override
public IAttributeDef getAttributeDef(Object bean, String attributeName) {
attrdefAction.setParameter(new Object[] { bean, attributeName });
return attrdefAction.activate();
}
@Override
public Boolean hasPermission(String roleName, String action) {
permissionAction.setParameter(new Object[] { roleName, action });
return (Boolean) permissionAction.activate();
}
/**
* {@inheritDoc}
*/
@Override
public boolean isPersistable(Class> beanClass) {
persistableAction.setParameter(new Object[] { beanClass });
return (Boolean) persistableAction.activate();
}
/**
* {@inheritDoc}
*/
@Override
public Collection getBeansByQuery(String query, Boolean nativeQuery, Object[] args, Class... lazyRelations) {
queryAction.setParameter(new Object[] { query, nativeQuery, args, lazyRelations });
return (Collection) queryAction.activate();
}
/**
* {@inheritDoc}
*/
@Override
public Collection getBeansByQuery(String query,
Boolean nativeQuery,
Map par,
Class... lazyRelations) {
queryMapAction.setParameter(new Object[] { query, nativeQuery, par, lazyRelations });
return (Collection) queryMapAction.activate();
}
/**
* {@inheritDoc}
*/
@Override
public Integer executeStmt(String query, Boolean nativeQuery, Object[] args) {
executeAction.setParameter(new Object[] { query, nativeQuery, args });
return executeAction.activate();
}
/**
* isConstraintError
*
* @param e server exception
* @return true, if error-cause contains a constraint violation
*/
public static boolean isConstraintError(Exception e) {
//etwas unsauber!
Throwable cause = e;
Throwable c = cause;
while (c != null) {
cause = c;
c = c.getCause();
}
if (cause.toString().contains("onstraint")) {
return true;
}
return false;
}
/**
* convenience method to ask for a user role depending on a bean presenters action.
*
* @param beanType bean class. this should be a specific class like an entity - no collection of entities!
* @param packedInList true, if the bean type is packed into a collection. e.g. in
* BeanContainerView/BeanContainerDialog.
* @param actionName translated action name.
* @return true, if user has role for that action, false otherwise
*/
public static final boolean hasPermission(Class> beanType, boolean packedInList, String actionName) {
return instance().hasPermission(getActionId(beanType, packedInList, actionName), null);
}
/**
* data rows for the given type
*
* @param beanType bean type
* @return count(*) for type
*/
public static final long getCount(Class> beanType) {
Collection
© 2015 - 2025 Weber Informatics LLC | Privacy Policy