package com.ycsoft.report.query.daq.translate; import java.util.HashMap; import java.util.Map; import com.ycsoft.commons.exception.ReportException; import com.ycsoft.report.query.cube.CubeHeadCell; import com.ycsoft.report.query.cube.Dimension; import com.ycsoft.report.query.cube.DimensionRolap; import com.ycsoft.report.query.cube.DimensionType; import com.ycsoft.report.query.cube.Measure; import com.ycsoft.report.query.cube.MeasureGather; import com.ycsoft.report.query.cube.impl.CubeHeadCellImpl; import com.ycsoft.report.query.key.Impl.QueryKeyValue; /** * cube内存计算用单元格 * @author new * */ public class CacheHeadCell extends CubeHeadCellImpl { protected Dimension dimension; /** * repcube.column_code * 维度和基础数据表的对应关系 * dimrolap.getCubeMappingKey */ protected String cubemappingkey; /** * 度量聚集方法 */ protected MeasureGather meagather; /** * 权限和切片影响下的层级取值 */ protected Map<Integer,Map<String,QueryKeyValue>> levelMap=new HashMap<Integer,Map<String,QueryKeyValue>>(); /** * 当前维度的各个层级的取值内容的顺序Map<level,Map<维度当前层的取值ID,排序大小>> */ protected Map<Integer,Map<String,Integer>> sortMap=new HashMap<Integer,Map<String,Integer>>(); /** * 表头使用标志 * 未使用的维度(有权限影响的),使用最低层判断,该值=false; */ protected boolean usesign=true; /** * 横向单元格=根据横向维度计算得到 * @param cell * @param rolap * @return * @throws ReportException */ public static CacheHeadCell createCrossHead(CubeHeadCell cell,DimensionRolap rolap,CacheMap cacheMap) throws ReportException{ if(!cell.getDim_type().equals(DimensionType.crosswise)) throw new ReportException("head is not crosswise."); CacheHeadCell cross=new CacheHeadCell(cell); cross.dimension=rolap.getDim(); cross.cubemappingkey=rolap.getCubeMappingKey(); if(cross.getLevel()>cross.getDimension().getLevelNum()){ cross.setLevel(cross.getDimension().getLevelNum()); } if(cacheMap.dimLevelMap.containsKey(cross.dimension)){ cross.levelMap=cacheMap.dimLevelMap.get(cross.dimension); cross.sortMap =cacheMap.dimSrotMap.get(cross.dimension); }else{ for(int i=1;i<=rolap.getDim().getLevelNum();i++){ Map<String,QueryKeyValue> lmap=new HashMap<String,QueryKeyValue>();//id-value的map层取值 Map<String,Integer> smap=new HashMap<String,Integer>();//层排序 int idx=0; for( QueryKeyValue vo: rolap.queryLevelValue(i)){ lmap.put(vo.getId(), vo); smap.put(vo.getId(), idx++); } cross.levelMap.put(i, lmap); cross.sortMap.put(i, smap); } cacheMap.dimLevelMap.put(cross.dimension, cross.levelMap); cacheMap.dimSrotMap.put(cross.dimension, cross.sortMap); } return cross; } /** * 纵向单元格=根据纵向维度计算得到 * @param cell * @param rolap * @param mea * @return * @throws ReportException */ public static CacheHeadCell createVerticalHead(CubeHeadCell cell,DimensionRolap rolap,Measure mea,CacheMap cacheMap) throws ReportException{ if(!cell.getDim_type().equals(DimensionType.vertical)) throw new ReportException("head is not vertical."); CacheHeadCell vertical=new CacheHeadCell(cell); vertical.dimension=rolap.getDim(); vertical.meagather=mea.getCalculation(); vertical.cubemappingkey=rolap.getCubeMappingKey(); if(vertical.getLevel()>vertical.getDimension().getLevelNum()){ vertical.setLevel(vertical.getDimension().getLevelNum()); } if(cacheMap.dimLevelMap.containsKey(vertical.dimension)){ vertical.levelMap=cacheMap.dimLevelMap.get(vertical.dimension); vertical.sortMap =cacheMap.dimSrotMap .get(vertical.dimension); }else{ for(int i=1;i<=rolap.getDim().getLevelNum();i++){ Map<String,QueryKeyValue> lmap=new HashMap<String,QueryKeyValue>(); Map<String,Integer> smap=new HashMap<String,Integer>();//层排序 int idx=0; for( QueryKeyValue vo: rolap.queryLevelValue(i)){ lmap.put(vo.getId(), vo); smap.put(vo.getId(), idx++); } vertical.levelMap.put(i, lmap); vertical.sortMap.put(i, smap); } cacheMap.dimLevelMap.put(vertical.dimension, vertical.levelMap); cacheMap.dimSrotMap.put(vertical.dimension, vertical.sortMap); } return vertical; } /** * 生成度量的单元格 * @param cell * @param mea * @return * @throws ReportException */ public static CacheHeadCell createMeasureHead(CubeHeadCell cell,Measure mea) throws ReportException{ if(!cell.getDim_type().equals(DimensionType.measure)) throw new ReportException("head is not vertical."); CacheHeadCell measure=new CacheHeadCell(cell); measure.meagather=mea.getCalculation(); measure.cubemappingkey=measure.getMea_code(); return measure; } /** * 虚拟单元格=维度在cube未使用但是存在权限控制 * @param rolap * @return * @throws ReportException */ public static CacheHeadCell createDummyHead(DimensionRolap rolap) throws ReportException{ CacheHeadCell dummy=new CacheHeadCell(); dummy.dimension=rolap.getDim(); dummy.cubemappingkey=rolap.getCubeMappingKey(); dummy.setLevel(rolap.getDim().getLevelNum()); Map<String,QueryKeyValue> lmap=new HashMap<String,QueryKeyValue>(); for( QueryKeyValue vo: rolap.queryLevelValue(dummy.getLevel())) lmap.put(vo.getId(), vo); dummy.levelMap.put(dummy.getLevel(), lmap); return dummy; } private CacheHeadCell(CubeHeadCell cell){ super(cell); } private CacheHeadCell(){}; /** * 根据最低层的id 提取当前层级键值 * @throws ReportException */ public QueryKeyValue translateKeyValue(String id) throws ReportException{ if(DimensionType.measure.equals(this.getDim_type())) throw new ReportException("measure cannot translateKeyValue."); for(int i=this.dimension.getLevelNum();i>this.getLevel();i--){ QueryKeyValue vo=this.levelMap.get(i).get(id); if(vo==null) return null; id=vo.getPid(); } return this.levelMap.get(this.getLevel()).get(id); } /** * 提取当前层键值的排序值 * @param id * @return * @throws ReportException */ public Integer translateSortValue(QueryKeyValue id) throws ReportException{ Map<String,Integer> map=this.sortMap.get(this.getLevel()); if(map==null) throw new ReportException(this.getDim()+"维度_"+this.getLevel()+"层:"+id.getId()+"找不到排序值"); Integer sort=map.get(id.getId()); if(sort==null) throw new ReportException(this.getDim()+"维度_"+this.getLevel()+"层:"+id.getId()+"找不到排序值"); return sort; } public Dimension getDimension() { return dimension; } public String getCubemappingkey() { return cubemappingkey; } public MeasureGather getMeagather() { return meagather; } public boolean isUsesign() { return usesign; } public Map<Integer,Map<String, Integer>> getSortMap() { return sortMap; } } /** * 计算维度取值和排序的缓存类 */ class CacheMap { //权限和切片影响下的层级取值的计算缓存 Map<Dimension,Map<Integer,Map<String,QueryKeyValue>>> dimLevelMap=new HashMap<Dimension,Map<Integer,Map<String,QueryKeyValue>>>(); //维度的层取值排序计算缓存 Map<Dimension,Map<Integer,Map<String,Integer>>> dimSrotMap=new HashMap<Dimension, Map<Integer,Map<String,Integer>>>(); }