com.pureinfo.srm.reports.table.MyTabeleDataHelper.java Source code

Java tutorial

Introduction

Here is the source code for com.pureinfo.srm.reports.table.MyTabeleDataHelper.java

Source

/**
 * PureInfo QuakeCenter
 * @(#)MyTabeleDataHelper.java   1.0 2005-12-1
 * 
 * Copyright(c) 2004-2005, PureInfo Information Technology Corp. Ltd. 
 * All rights reserved, see the license file.
 * 
 * www.pureinfo.com.cn
 */

package com.pureinfo.srm.reports.table;

import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.commons.lang.ArrayUtils;

import com.pureinfo.ark.content.ArkContentHelper;
import com.pureinfo.ark.content.domain.IContentMgr;
import com.pureinfo.common.namedvalue.model.INamedValue;
import com.pureinfo.dolphin.DolphinHelper;
import com.pureinfo.dolphin.model.DolphinObject;
import com.pureinfo.dolphin.model.IObjects;
import com.pureinfo.dolphin.persister.IStatement;
import com.pureinfo.dolphin.query.logic.SQLCondition;
import com.pureinfo.force.exception.PureException;

/**
 * <P>
 * Created on 2005-12-1 14:32:57 <BR>
 * Last modified on 2005-12-1
 * </P>
 * MyTabeleDataHelper to help build statistic 
 * 
 * @author elmar.chen
 * @version 1.0, 2005-12-1
 * @since QuakeCenter 1.0
 */
public class MyTabeleDataHelper {

    public static final String STR_COL = "_COL";

    public static final String STR_ROW = "_ROW";

    public static final String OTHER = "{%~@.other.@~%}";

    public static final String TOTAL = "{%~@.total.@~%}";

    public static Map getRowMap(Class _contentClass, SQLCondition _condition, String _sGroupProp,
            String[] _caredValues) throws PureException {
        IContentMgr mgr = ArkContentHelper.getContentMgrOf(_contentClass);
        List params = new ArrayList();
        IObjects datas = null;
        IStatement query = null;
        Map row = null;
        try {
            String sCondion = "";
            if (_condition != null)
                sCondion = _condition.toSQL(params);
            String strSQL = "SELECT COUNT(*) AS _COUNT, {this." + _sGroupProp + "} FROM {this}"
                    + (sCondion == null || sCondion.trim().length() < 1 ? "" : " WHERE ") + sCondion
                    + " GROUP BY {this." + _sGroupProp + '}';
            query = mgr.createQuery(strSQL, 0);
            if (!params.isEmpty()) {
                query.setParameters(0, params);
            }
            datas = query.executeQuery();
            row = new HashMap(datas.getSize());
            do {
                DolphinObject data = datas.next();
                if (data == null) {
                    break;
                }
                row.put(data.getProperty(_sGroupProp), data.getProperty("_COUNT"));
            } while (true);
        } finally {
            params.clear();
            DolphinHelper.clear(datas, query);
        }
        if (_caredValues != null) {
            int caredTotal = 0;
            int total = 0;
            for (Iterator iter = row.entrySet().iterator(); iter.hasNext();) {
                Map.Entry entry = (Map.Entry) iter.next();
                String sName = (String) entry.getKey();
                Number num = (Number) entry.getValue();
                if (ArrayUtils.contains(_caredValues, sName)) {
                    caredTotal += num.intValue();
                }
                total += num.intValue();
            }
            row.put(OTHER, new Integer(total - caredTotal));
            row.put(TOTAL, new Integer(total));
        }
        return row;
    }

    /**
     * @param _contentClass content classes that take parts in do statistic; has at least 1 element 
     * @param _alias alias for content classes,the fisrt one will be set to 'this' no matter what is passed in, 
     * must have the same size as <code>_contentClass</code>
     * @param _sToCalculate to calculate what? this will be set in SELECT clause,and its value will be contained 
     * in the data map returned
     * @param _condition conditions, that will be used in WHERE clause
     * @param _sGroupProp group by this
     * @param _caredValues what values are cared; if result is not in this array,it will be considered as "OTHER"
     * @return an map.contains <code>contentClass[0]._sGroupProp</code>->its result(a <code>java.lang.Number</code>)
     * @throws PureException if database access error or class metadata not found
     */
    public static Map getRowMap(Class[] _contentClass, String[] _alias, String _sToCalculate,
            SQLCondition _condition, String _sGroupProp, String[] _caredValues) throws PureException {
        IContentMgr mgr = ArkContentHelper.getContentMgrOf(_contentClass[0]);
        List params = new ArrayList();
        IObjects datas = null;
        IStatement query = null;
        Map row = null;
        if (_sToCalculate == null)
            _sToCalculate = "count( {this.*} )";
        try {
            String sCondion = "";
            if (_condition != null)
                sCondion = _condition.toSQL(params);
            String strSQL = "SELECT " + _sToCalculate + " AS _COUNT, {this." + _sGroupProp + "} FROM {this}";
            for (int i = 1; i < _alias.length; i++) {
                strSQL += (",{" + _alias[i] + '}');
            }
            strSQL += (sCondion == null || sCondion.trim().length() < 1 ? "" : " WHERE ") + sCondion
                    + " GROUP BY {this." + _sGroupProp + '}';
            query = mgr.createQuery(strSQL, 0);
            for (int i = 1; i < _contentClass.length; i++) {
                query.registerAlias(_alias[i], _contentClass[i]);
            }
            if (!params.isEmpty()) {
                query.setParameters(0, params);
            }
            datas = query.executeQuery();
            row = new HashMap(datas.getSize());
            do {
                DolphinObject data = datas.next();
                if (data == null) {
                    break;
                }
                row.put(data.getProperty(_sGroupProp), data.getProperty("_COUNT"));
            } while (true);
        } finally {
            params.clear();
            DolphinHelper.clear(datas, query);
        }

        int caredTotal = 0;
        int total = 0;
        for (Iterator iter = row.entrySet().iterator(); iter.hasNext();) {
            Map.Entry entry = (Map.Entry) iter.next();
            String sName = (String) entry.getKey();
            Number num = (Number) entry.getValue();
            if (_caredValues != null) {
                if (ArrayUtils.contains(_caredValues, sName)) {
                    caredTotal += num.intValue();
                }
            }
            total += num.intValue();
        }
        row.put(OTHER, new Integer(total - caredTotal));
        row.put(TOTAL, new Integer(total));
        return row;
    }

    public static Map getRowMap(Class[] _contentClass, String[] _alias, String[] _sToCalculate,
            SQLCondition _condition, String _sGroupProp, String[] _caredValues) throws PureException {
        IContentMgr mgr = ArkContentHelper.getContentMgrOf(_contentClass[0]);
        List params = new ArrayList();
        IObjects datas = null;
        IStatement query = null;
        Map row = null;
        if (_sToCalculate == null)
            _sToCalculate = new String[] { "count( {this.*} )" };
        try {
            String sCondion = "";
            if (_condition != null)
                sCondion = _condition.toSQL(params);
            String strSQL = "SELECT ";
            for (int i = 0; i < _sToCalculate.length; i++) {
                strSQL += (_sToCalculate[i] + " AS _RESULT" + i + ',');
            }

            strSQL += " {this." + _sGroupProp + "} FROM {this}";
            for (int i = 1; i < _alias.length; i++) {
                strSQL += (",{" + _alias[i] + '}');
            }
            strSQL += (sCondion == null || sCondion.trim().length() < 1 ? "" : " WHERE ") + sCondion
                    + " GROUP BY {this." + _sGroupProp + '}';
            query = mgr.createQuery(strSQL, 0);
            for (int i = 1; i < _contentClass.length; i++) {
                query.registerAlias(_alias[i], _contentClass[i]);
            }
            if (!params.isEmpty()) {
                query.setParameters(0, params);
            }
            datas = query.executeQuery();
            row = new HashMap(datas.getSize());
            do {
                DolphinObject data = datas.next();
                if (data == null) {
                    break;
                }
                Object[] result = new Object[_sToCalculate.length];
                for (int i = 0; i < result.length; i++) {
                    result[i] = data.getProperty("_RESULT" + i);
                }
                row.put(data.getProperty(_sGroupProp), result);
            } while (true);
        } finally {
            params.clear();
            DolphinHelper.clear(datas, query);
        }

        double[] caredTotal = new double[_sToCalculate.length];
        double[] total = new double[_sToCalculate.length];
        for (Iterator iter = row.entrySet().iterator(); iter.hasNext();) {
            Map.Entry entry = (Map.Entry) iter.next();
            String sName = (String) entry.getKey();
            Object[] num = (Object[]) entry.getValue();
            for (int i = 0; i < num.length; i++) {
                if (num[i] instanceof Number) {
                    if (_caredValues != null) {
                        if (ArrayUtils.contains(_caredValues, sName)) {
                            caredTotal[i] += ((Number) num[i]).doubleValue();
                        }
                    }
                    caredTotal[i] += ((Number) num[i]).doubleValue();
                }
            }
        }
        Object[] oOther = new Object[_sToCalculate.length];
        Object[] oTotal = new Object[_sToCalculate.length];
        for (int i = 0; i < total.length; i++) {
            oTotal[i] = new Double(total[i]);
            oOther[i] = new Double(total[i] - caredTotal[i]);
        }
        row.put(OTHER, oOther);
        row.put(TOTAL, oTotal);
        return row;
    }

    public static Map getDataMap2d(Class _contentClass, SQLCondition _condition, String _sGroupPropRow,
            String _sGroupPropCol, String[] _caredValuesRow, String[] _caredValuesCol) throws PureException {
        IContentMgr mgr = ArkContentHelper.getContentMgrOf(_contentClass);
        List params = new ArrayList();
        IObjects datas = null;
        IStatement query = null;
        Map map2d = null;
        try {
            String sCondion = "";
            if (_condition != null)
                sCondion = _condition.toSQL(params);
            String strSQL = "SELECT COUNT(*) AS _COUNT, {this." + _sGroupPropRow + "} AS " + STR_ROW + ", {this."
                    + _sGroupPropCol + "} AS " + STR_COL + " FROM {this}"
                    + (sCondion == null || sCondion.trim().length() < 1 ? "" : " WHERE ") + sCondion
                    + " GROUP BY {this." + _sGroupPropRow + "},{this." + _sGroupPropCol + '}';
            query = mgr.createQuery(strSQL, 0);
            if (!params.isEmpty()) {
                query.setParameters(0, params);
            }
            datas = query.executeQuery();
            map2d = iObjectsToMap2D(datas);
        } finally {
            params.clear();
            DolphinHelper.clear(datas, query);
        }
        calculateMap2d(map2d, _caredValuesRow, _caredValuesCol);
        return map2d;
    }

    public static Map getDataMap2d(Class _contentClass[], String[] _alias, String _sToCalculate,
            SQLCondition _condition, String _sGroupPropRow, String _sGroupPropCol, String[] _caredValuesRow,
            String[] _caredValuesCol) throws PureException {
        IContentMgr mgr = ArkContentHelper.getContentMgrOf(_contentClass[0]);
        List params = new ArrayList();
        IObjects datas = null;
        IStatement query = null;
        Map map2d = null;
        if (_sToCalculate == null)
            _sToCalculate = "count( {this.id} )";
        try {
            String sCondion = "";
            if (_condition != null)
                sCondion = _condition.toSQL(params);
            String strSQL = "SELECT " + _sToCalculate + " AS _COUNT, {this." + _sGroupPropRow + "} AS " + STR_ROW
                    + ", {this." + _sGroupPropCol + "} AS " + STR_COL + " FROM {this}";
            for (int i = 1; i < _alias.length; i++) {
                strSQL += (",{" + _alias[i] + '}');
            }
            strSQL += (sCondion == null || sCondion.trim().length() < 1 ? "" : " WHERE ") + sCondion
                    + " GROUP BY {this." + _sGroupPropRow + "},{this." + _sGroupPropCol + '}';
            query = mgr.createQuery(strSQL, 0);
            for (int i = 1; i < _contentClass.length; i++) {
                query.registerAlias(_alias[i], _contentClass[i]);
            }
            if (!params.isEmpty()) {
                query.setParameters(0, params);
            }
            datas = query.executeQuery();
            map2d = iObjectsToMap2D(datas);
        } finally {
            params.clear();
            DolphinHelper.clear(datas, query);
        }
        calculateMap2d(map2d, _caredValuesRow, _caredValuesCol);
        return map2d;
    }

    private static void calculateMap2d(Map _map2d, String[] _sValuesRow, String[] _sValuesCol) {
        for (Iterator iter = _map2d.values().iterator(); iter.hasNext();) {
            calculateAndSetMapRow((Map) iter.next(), _sValuesCol);
            ;

        }
        calculateAndSetMap2dGeneral(_map2d, _sValuesRow);
    }

    /**
     * @param _map2d
     * @param _sValuesRow
     */
    private static void calculateAndSetMap2dGeneral(Map _map2d, String[] _sValuesRow) {
        if (_map2d == null)
            return;
        Map total = new HashMap(), cared = new HashMap();
        for (int i = 0; i < _sValuesRow.length; i++) {
            Map row = (Map) _map2d.get(_sValuesRow[i]);
            if (row == null)
                continue;
            for (Iterator iter = row.entrySet().iterator(); iter.hasNext();) {
                Map.Entry entry = (Entry) iter.next();
                int v = getInt((Number) cared.get(entry.getKey()));
                v += getInt((Number) entry.getValue());
                cared.put(entry.getKey(), new Integer(v));

            }
        }

        for (Iterator iter = _map2d.values().iterator(); iter.hasNext();) {
            Map row = (Map) iter.next();
            if (row == null)
                continue;

            for (Iterator iter1 = row.entrySet().iterator(); iter1.hasNext();) {
                Map.Entry entry = (Entry) iter1.next();
                int v = getInt((Number) total.get(entry.getKey()));
                v += getInt((Number) entry.getValue());
                total.put(entry.getKey(), new Integer(v));

            }
        }
        _map2d.put(TOTAL, total);
        _map2d.put(OTHER, subMap(total, cared));
    }

    /**
     * @param _total
     * @param _cared
     * @return
     */
    private static Object subMap(Map _total, Map _cared) {
        Map map = new HashMap(_total.size());
        for (Iterator iter = _total.entrySet().iterator(); iter.hasNext();) {
            Map.Entry entry = (Entry) iter.next();
            int total = getInt((Number) entry.getValue());
            int cared = getInt((Number) _cared.get(entry.getKey()));
            map.put(entry.getKey(), new Integer(total - cared));

        }
        return map;
    }

    /**
     * @param _sValuesCol
     * @param _sRow
     */
    public static void calculateAndSetMapRow(Map _row, String[] _sValuesCol) {
        if (_row == null)
            return;
        int total = 0, cared = 0;
        for (int i = 0; i < _sValuesCol.length; i++) {
            Number num = (Number) _row.get(_sValuesCol[i]);
            if (num != null) {
                cared += num.intValue();
            }
        }
        for (Iterator iter = _row.values().iterator(); iter.hasNext();) {
            Number num = (Number) iter.next();
            if (num != null) {
                total += num.intValue();
            }
        }
        _row.put(OTHER, new Integer(total - cared));
        _row.put(TOTAL, new Integer(total));
    }

    public static Map iObjectsToMap2D(IObjects datas) throws PureException {
        Map row;
        row = new HashMap(datas.getSize());
        do {
            DolphinObject data = datas.next();
            if (data == null) {
                break;
            }

            String sRowValue = data.getPropertyAsString(STR_ROW);
            String sColValue = data.getPropertyAsString(STR_COL);

            if (row.get(sRowValue) == null) {
                row.put(sRowValue, new HashMap());
            }
            Map map = (Map) row.get(sRowValue);
            map.put(sColValue, data.getProperty("_COUNT"));
        } while (true);
        return row;
    }

    public static String[] clearDupAndNull(String[] _before) {
        if (_before == null) {
            return null;
        }
        String[] medial = new String[_before.length];
        int n = 0;
        for (int i = 0; i < _before.length; i++) {
            if (_before[i] == null) {
                continue;
            }
            if (ArrayUtils.contains(medial, _before)) {
                continue;
            }
            medial[n++] = _before[i];
        }
        if (n == _before.length) {
            return medial;
        }
        String[] result = new String[n];
        for (int i = 0; i < n; i++) {
            result[i] = medial[i];
        }
        return result;
    }

    public static Object[][] renderData(Map map2d, String[][] _caredRow, String[][] _caredCol) {
        return renderData(map2d, _caredRow[0], _caredCol[0], _caredRow[1], _caredCol[1]);
    }

    /**
     * @param map2d
     * @param _caredValuesRow
     * @param _caredValuesCol
     * @param _caredNamesRow
     * @param _caredNamesCol
     * @deprecated use <code>public static Object[][] renderData(Map map2d,String[][] _caredRow,String[][] _caredCol)</code>
     * @return
     */
    public static Object[][] renderData(Map map2d, String[] _caredValuesRow, String[] _caredValuesCol,
            String[] _caredNamesRow, String[] _caredNamesCol) {
        Object[][] datas = new Object[_caredValuesRow.length + 3][_caredValuesCol.length + 3];
        setTitle(datas, _caredNamesCol);
        int i = 0;
        for (; i < _caredValuesRow.length; i++) {
            datas[i + 1][0] = _caredNamesRow[i];
            renderEach(datas, i + 1, (Map) map2d.get(_caredValuesRow[i]), _caredValuesCol);
        }
        datas[i + 1][0] = "[]";
        renderEach(datas, i + 1, (Map) map2d.get(OTHER), _caredValuesCol);
        i++;
        datas[i + 1][0] = "";
        renderEach(datas, i + 1, (Map) map2d.get(TOTAL), _caredValuesCol);
        return datas;
    }

    private static void renderEach(Object[][] _datas, int _nPosition, Map row, String[] _sCaredValuesCol) {
        if (row == null) {
            for (int i = 1; i < _datas[_nPosition].length; i++) {
                _datas[_nPosition][i] = new Integer(0);
            }
            return;
        }
        int i = 0;
        for (; i < _sCaredValuesCol.length; i++) {
            _datas[_nPosition][i + 1] = new Integer(getInt((Number) row.get(_sCaredValuesCol[i])));
        }
        _datas[_nPosition][i + 1] = new Integer(getInt((Number) row.get(OTHER)));
        i++;
        _datas[_nPosition][i + 1] = new Integer(getInt((Number) row.get(TOTAL)));
    }

    private static void setTitle(Object[][] _datas, String[] _sCaredNamesCol) {
        int i = 0;
        for (; i < _sCaredNamesCol.length; i++) {
            _datas[0][i + 1] = _sCaredNamesCol[i];
        }
        _datas[0][i + 1] = "[]";
        i++;
        _datas[0][i + 1] = "";
    }

    public static String getRatioString(double n, double d) {
        if (d < 0.0001) {
            return "----";
        }
        DecimalFormat format = new DecimalFormat("#0.0%");
        return format.format(n / d);
    }

    public static int getInt(Number num) {
        if (num != null)
            return num.intValue();
        return 0;
    }

    /**
     * @param list list consists of <code>DolphinObject</code>
     * @param _sValueProp property of <code>DolphinObject</code> in the list which will be used as value
     * @param _sNameProp property of <code>DolphinObject</code> in the list which will be used as name
     * @return a n*2 array of String, which fisrt line is values and second is names 
     */
    public static String[][] list2Strings(List list, String _sValueProp, String _sNameProp) {
        String[][] arr = new String[2][list.size()];
        int i = 0;
        for (Iterator iter = list.iterator(); iter.hasNext();) {
            DolphinObject obj = (DolphinObject) iter.next();
            arr[0][i] = obj.getPropertyAsString(_sValueProp);
            arr[1][i] = obj.getPropertyAsString(_sNameProp);
            i++;
        }
        return arr;
    }

    /**
     * to insert an array to another array
     * @see void insertIntoLine(Object[] _des,Object[] _src, int beginIdx)
     */
    public void insertIntoLine(Object[] _des, Object[] _src) {
        insertIntoLine(_des, _src, 0);
    }

    /**
     * to insert an array to another array at a given position, if the destination dosen't have enough space,redundant element will be ignored
     * @param _des array to insert into
     * @param _src array to be inserted from
     * @param beginIdx begin index of <code>_des</code> 
     */
    public void insertIntoLine(Object[] _des, Object[] _src, int beginIdx) {
        for (int i = 0, j = beginIdx; j < _des.length && i < _src.length; i++, j++) {
            _des[j] = _src[i];
        }
    }

    public String[][] namdValueList2array(List list) {
        String[][] arr = new String[2][list.size()];
        int i = 0;
        for (Iterator iter = list.iterator(); iter.hasNext();) {
            INamedValue nv = (INamedValue) iter.next();
            arr[0][i] = nv.getValue();
            arr[1][i] = nv.getName();
            i++;
        }
        return arr;
    }

    public static Map List2Map(List objs, String _sKeyProp) {
        Map map = new HashMap(objs.size());
        for (Iterator iter = objs.iterator(); iter.hasNext();) {
            DolphinObject obj = (DolphinObject) iter.next();
            map.put(obj.getProperty(_sKeyProp), obj);
        }
        return map;
    }

}