![JAR search and dependency download from the Maven repository](/logo.png)
de.tsl2.nano.h5.collector.Statistic Maven / Gradle / Ivy
/*
* File: $HeadURL$
* Id : $Id$
*
* created by: Tom, Thomas Schneider
* created on: 15.08.2014
*
* Copyright: (c) Thomas Schneider 2014, all rights reserved
*/
package de.tsl2.nano.h5.collector;
import java.io.File;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.simpleframework.xml.Default;
import org.simpleframework.xml.DefaultType;
import org.simpleframework.xml.Transient;
import org.simpleframework.xml.core.Commit;
import de.tsl2.nano.bean.BeanContainer;
import de.tsl2.nano.bean.BeanUtil;
import de.tsl2.nano.bean.def.ArrayValue;
import de.tsl2.nano.bean.def.Attachment;
import de.tsl2.nano.bean.def.AttributeDefinition;
import de.tsl2.nano.bean.def.BeanCollector;
import de.tsl2.nano.bean.def.BeanDefinition;
import de.tsl2.nano.bean.def.IAttributeDefinition;
import de.tsl2.nano.core.ENV;
import de.tsl2.nano.core.cls.IAttribute;
import de.tsl2.nano.core.exception.Message;
import de.tsl2.nano.core.log.LogFactory;
import de.tsl2.nano.core.util.CollectionUtil;
import de.tsl2.nano.core.util.FileUtil;
import de.tsl2.nano.core.util.ListWrapper;
import de.tsl2.nano.core.util.NumberUtil;
import de.tsl2.nano.core.util.StringUtil;
import de.tsl2.nano.core.util.Util;
import de.tsl2.nano.graph.SVGChart;
import de.tsl2.nano.service.util.ServiceUtil;
/**
* Does a statistic by doing a group by on all columns. Set {@link #from} and {@link #toString()} on the constructor
* {@link #Statistic(Class, Object, Object)} to do a filtering. set the attribute filter (see
* {@link BeanDefinition#setAttributeFilter(String...)} to select the attributes to do a statistic on (creating a 'group
* by' select).
*
* @author Tom, Thomas Schneider
* @version $Revision$
*/
@SuppressWarnings("unchecked")
@Default(value = DefaultType.FIELD, required = false)
public class Statistic, T> extends BeanCollector {
/** serialVersionUID */
private static final long serialVersionUID = 1L;
private static final Log LOG = LogFactory.getLog(Statistic.class);
@Transient
Class beanType;
/** columnNames of the statistic table */
@Transient
//this Transient annotation marks the attribute as extension member
//@ElementList(name = "column", inline = true, required = false/*, type=ValueColumn.class*/)
ListWrapper columnNames;
@Transient
ListWrapper statColumns;
@Transient
//this Transient annotation marks the attribute as extension member
T from;
@Transient
//this Transient annotation marks the attribute as extension member
T to;
public Statistic() {
}
public Statistic(Class beanType) {
this(beanType, null, null);
}
/**
* constructor
*
* @param beanType
* @param workingMode
*/
public Statistic(Class beanType, T from, T to) {
super();
setMode(0);
name = "Statistics: " + beanType.getSimpleName();
columnNames = new ListWrapper();
this.from = from;
this.to = to;
this.beanType = beanType;
// collection = (COLLECTIONTYPE) create(beanType, columnNames.getList(), from, to);
isStaticCollection = true;
}
@SuppressWarnings({ "rawtypes" })
@Override
public List getAttributes(boolean readAndWriteAccess) {
if (Util.isEmpty(attributeDefinitions)) {
attributeDefinitions = new LinkedHashMap>();
List names = columnNames.getList();
IAttribute> attribute;
int i = 0;
for (String name : names) {
attribute = new ArrayValue(name, i++, i > 1 ? Number.class : null, null);
attributeDefinitions.put(name, new AttributeDefinition(attribute));
}
}
return new ArrayList(attributeDefinitions.values());
}
private Collection create(Class beanType, List attributeNames, T from, T to) {
if (attributeNames.size() == 0) {
attributeNames.add(ENV.translate("tsl2nano.name", true));
attributeNames.add(ENV.translate("tsl2nano.count", true));
}
BeanDefinition def = BeanDefinition.getBeanDefinition(beanType);
setName(ENV.translate("tsl2nano.statistic", true) + " (" + def.getName() + ")");
if (from != null && to != null) {
Map fromMap = BeanUtil.toFormattedMap(from);
Map toMap = BeanUtil.toFormattedMap(to);
CollectionUtil.removeEmptyEntries(fromMap);
CollectionUtil.removeEmptyEntries(toMap);
String strFrom = fromMap.size() > 0 ? fromMap.toString() : "(" + ENV.translate("tsl2nano.all", false) + ")";
String strTo = toMap.size() > 0 ? toMap.toString() : "(" + ENV.translate("tsl2nano.all", false) + ")";
searchStatus =
"" +
ENV.translate("tsl2nano.summary", true) + ": " + ENV.translate("tsl2nano.range.from", true) +
strFrom + " - " + ENV.translate("tsl2nano.range.to", true) + strTo
+ "";
}
String[] names = def.getAttributeNames();
List valueColumns = new ArrayList<>(names.length);
if (Util.isEmpty(statColumns)) {
statColumns = new ListWrapper(names.length);
/*
* check, which columns should be shown. if a column has more than 500 group by elements, its to big
* evaluate the number columns
*/
long maxcount = ENV.get("statistic.maxgroupcount", 500);
String sum = ENV.translate("tsl2nano.sum", true) + "(";
IAttributeDefinition> attrDef;
for (int i = 0; i < names.length; i++) {
attrDef = def.getAttribute(names[i]);
if (attrDef.id() || attrDef.generatedValue() || attrDef.isMultiValue() || attrDef.unique()
|| attrDef.isVirtual() || Attachment.isData(attrDef)) {
continue;
} else if (NumberUtil.isNumber(attrDef.getType())) {
valueColumns.add(names[i]);
attributeNames.add(sum + names[i] + ")");
} else if (groupByCount(def, names[i], from, to) <= maxcount) {
statColumns.add(names[i]);
}
}
}
/*
* do all group by selects
*/
Collection collection = new ArrayList<>();
int i=0, g=statColumns.getList().size();
for (String n : statColumns) {
Message.send("creating statistic groupby column: " + n + " (" + i + "/" + g + ")");
collection.addAll(createStatistics(def, n, valueColumns, from, to));
}
/*
* create an svg chart file without summary
*/
//first, remove the last graph data
searchStatus = StringUtil.substring(searchStatus, null, "" + createGraph(getName(), columnNames.getList(), (Collection";
collection.addAll(createSummary(def, valueColumns, from, to));
return collection;
}
private static Collection extends T> createSummary(BeanDefinition def,
List valueColumns,
T from,
T to) {
String summary =
ENV.translate("tsl2nano.all", true) + " " + ENV.translate("tsl2nano.elements", true);
String qstr = "select ''{0}'', count(*) {2} from {1} t {3}";
String strValueColumns = StringUtil.concatWrap(",sum({0})".toCharArray(), valueColumns.toArray());
Collection> parameter = new LinkedList<>();
String where = whereConstraints(from, to, parameter).toString();
Collection> result = (Collection extends T>) getBeansByQuery(
MessageFormat.format(qstr, summary, def, strValueColumns, where),
parameter);
return (Collection extends T>) (result != null ? result : new ArrayList<>());
}
private static Collection extends T> createStatistics(BeanDefinition def,
String column,
List valueColumns,
T from,
T to) {
String qstr = "select ''{3}: '' || {0}, count({0}) {2} from {1} t {4} group by {0} order by 1";
String strValueColumns = StringUtil.concatWrap(",sum({0})".toCharArray(), valueColumns.toArray());
String columnname = ENV.translate(def.getAttribute(column).getId(), true);
Collection> parameter = new LinkedList<>();
String where = whereConstraints(from, to, parameter).toString();
Collection> result = getBeansByQuery(
MessageFormat.format(qstr, column, def, strValueColumns, columnname, where),
parameter);
return (Collection extends T>) (result != null ? result : new ArrayList<>());
}
@SuppressWarnings("rawtypes")
private static int groupByCount(BeanDefinition def, String column, T from, T to) {
Collection parameter = new LinkedList<>();
String qstr =
"select count(" + column + ") from " + def.getName() + " t " + whereConstraints(from, to, parameter)
+ " group by "
+ column;
//JPA is not able to resolve the expression ..count(count(....)), so we have to use native sql
Collection
© 2015 - 2025 Weber Informatics LLC | Privacy Policy