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

de.tsl2.nano.bean.def.BeanFinder Maven / Gradle / Ivy

Go to download

TSL2 Framework Descriptor (currency-handling, generic formatter, descriptors for beans, collections, actions and values)

There is a newer version: 2.5.1
Show newest version
/*
 * File: $HeadURL$
 * Id  : $Id$
 * 
 * created by: Thomas Schneider
 * created on: Jul 20, 2012
 * 
 * Copyright: (c) Thomas Schneider 2012, all rights reserved
 */
package de.tsl2.nano.bean.def;

import java.io.Serializable;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;

import org.apache.commons.logging.Log;

import de.tsl2.nano.bean.BeanContainer;
import de.tsl2.nano.bean.BeanFindParameters;
import de.tsl2.nano.bean.BeanUtil;
import de.tsl2.nano.core.ENV;
import de.tsl2.nano.core.cls.BeanClass;
import de.tsl2.nano.core.log.LogFactory;
import de.tsl2.nano.core.util.Util;
import de.tsl2.nano.util.operation.IRange;
import de.tsl2.nano.util.operation.Range;

/**
 * @see IBeanFinder
 * @author Thomas Schneider
 * @version $Revision$
 */
@SuppressWarnings("unchecked")
public class BeanFinder implements IBeanFinder, Serializable {
    /** serialVersionUID */
    private static final long serialVersionUID = -1270111762126889953L;
    Class type;
    /** optional bean definition to present a search filter mask */
    Bean> rangeBean;
    /** if no {@link #rangeBean} can be created */
    boolean noRangeBean;

    transient String lastExpression = null;

    /** optional detail bean definition to present a selected bean in a detailed mask */
    Bean detailBean;
    transient int currentStartIndex = 0;
    int maxResultCount = ENV.get("collector.service.maxresult", 100);

    private static final Log LOG = LogFactory.getLog(BeanFinder.class);

    /**
     * constructor to be serializable
     */
    protected BeanFinder() {
        super();
        type = (Class) Serializable.class;
    }

    /**
     * constructor
     * 
     * @param type
     */
    public BeanFinder(Class type) {
        super();
        this.type = type;
    }

    /**
     * constructor
     * 
     * @param rangeBean
     */
    public BeanFinder(Bean> rangeBean) {
        super();
        this.rangeBean = rangeBean;
        type = (Class) Serializable.class;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public Class getType() {
        return type;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public Collection getData(F fromFilter, F toFilter, String...orderBy) {
        lastExpression = null;
        return superGetData(fromFilter, toFilter, orderBy);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public Collection getData() {
        if (lastExpression != null) {
            return getData(lastExpression);
        } else {
            Bean> range = getFilterRange();
            F from = range != null ? range.getInstance().getFrom() : null;
            F to = range != null ? range.getInstance().getTo() : null;
            return getData(from, to);
        }
    }

    @Override
    public Collection getData(String valueExpression) {
        lastExpression = valueExpression;
        return null;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public Collection next() {
        currentStartIndex += getMaxResultCount();
        return getData();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public Collection previous() {
        if (currentStartIndex >= getMaxResultCount()) {
            currentStartIndex -= getMaxResultCount();
        }
        return getData();
    }

    /**
     * to avoid cycle calling, we have the 'interface' method {@link #getData(Object, Object)} which may be overridden
     * (inline in views or dialogs) and the functional method {@link #superGetData(Object, Object)}. don't call or
     * override this method - it should only be called by the framework.
     */
    @SuppressWarnings("rawtypes")
    public  Collection superGetData(S fromFilter, S toFilter, String...orderBy) {
    	BeanFindParameters pars = new BeanFindParameters(getType(), currentStartIndex, getMaxResultCount());
    	if (!Util.isEmpty(orderBy))
    		pars.setOrderBy(Arrays.asList(orderBy));
        if (fromFilter == null || toFilter == null) {
            List result = new LinkedList(BeanContainer.instance().getBeans(pars));
//            Collections.sort(result, BeanDefinition.getBeanDefinition(type).getValueExpression().getComparator());
            return result;
        } else {
            List result = new LinkedList(BeanContainer.instance().getBeansBetween(fromFilter, toFilter, pars));
//            Collections.sort(result, BeanDefinition.getBeanDefinition(type).getValueExpression().getComparator());
            return result;
        }
    }

    @Override
    public Bean> getFilterRange() {
        if (rangeBean == null && !noRangeBean) {
            try {
                if (type.isInterface() || !BeanClass.hasDefaultConstructor(type)) {
                    LOG.warn("BeanFinder wont provide a range filter for type " + type);
                    noRangeBean = true;
                } else {
                    F from = (F) BeanClass.createInstance(type);
                    Range.setPrimitiveMinValues(from);
                    F to = BeanUtil.clone(from);
                    Range.setPrimitiveMaxValues(to);
                    rangeBean = new Bean>(new Range(from, to));
                }
            } catch (Exception ex) {
                noRangeBean = true;
                //ok, we don't provide a range filter
                LOG.warn("BeanFinder wont provide a range filter:" + ex.toString());
            }
        }
        return rangeBean;
    }

    /**
     * the filter range bean is used as presentation information for search masks.
     * 
     * @param rangeBean The rangeBean to set.
     */
    public void setFilterRange(Bean> rangeBean) {
        this.rangeBean = rangeBean;
        noRangeBean = false;
        lastExpression = null;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public Object wrapToDetailBean(T bean) {
        return detailBean != null ? detailBean.setInstance(bean) : bean;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public T unwrapToSelectableBean(Object obj) {
        return obj instanceof Bean ? ((Bean) obj).getInstance() : (T) obj;
    }

    /**
     * the detail bean will be used on creating a detail presentation of a selected bean. used by
     * {@link #wrapToDetailBean(Object)}.
     * 
     * @param detailBean The detailBean to set.
     */
    public void setDetailBean(Bean detailBean) {
        this.detailBean = detailBean;
    }

    /**
     * @return Returns the maxResult.
     */
    @Override
    public int getMaxResultCount() {
        return maxResultCount;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void setMaxResultCount(int maxresult) {
        this.maxResultCount = maxresult;
    }
    
    @Override
    public void reset() {
        rangeBean = null;
        lastExpression = null;
        currentStartIndex = 0;
        detailBean = null;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy