001 /* 002 // $Id: //open/mondrian/src/main/mondrian/olap/fun/SubsetFunDef.java#1 $ 003 // This software is subject to the terms of the Common Public License 004 // Agreement, available at the following URL: 005 // http://www.opensource.org/licenses/cpl.html. 006 // Copyright (C) 2006-2006 Julian Hyde 007 // All Rights Reserved. 008 // You must accept the terms of that agreement to use this software. 009 */ 010 package mondrian.olap.fun; 011 012 import mondrian.olap.FunDef; 013 import mondrian.olap.Evaluator; 014 import mondrian.calc.Calc; 015 import mondrian.calc.ExpCompiler; 016 import mondrian.calc.ListCalc; 017 import mondrian.calc.IntegerCalc; 018 import mondrian.calc.impl.AbstractListCalc; 019 import mondrian.mdx.ResolvedFunCall; 020 021 import java.util.List; 022 import java.util.Collections; 023 024 /** 025 * Definition of the <code>Subset</code> MDX function. 026 * 027 * @author jhyde 028 * @version $Id: //open/mondrian/src/main/mondrian/olap/fun/SubsetFunDef.java#1 $ 029 * @since Mar 23, 2006 030 */ 031 class SubsetFunDef extends FunDefBase { 032 static final ReflectiveMultiResolver Resolver = new ReflectiveMultiResolver( 033 "Subset", 034 "Subset(<Set>, <Start>[, <Count>])", 035 "Returns a subset of elements from a set.", 036 new String[] {"fxxn", "fxxnn"}, 037 SubsetFunDef.class); 038 039 public SubsetFunDef(FunDef dummyFunDef) { 040 super(dummyFunDef); 041 } 042 043 public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) { 044 final ListCalc listCalc = 045 compiler.compileList(call.getArg(0)); 046 final IntegerCalc startCalc = 047 compiler.compileInteger(call.getArg(1)); 048 final IntegerCalc countCalc = 049 call.getArgCount() > 2 ? 050 compiler.compileInteger(call.getArg(2)) : 051 null; 052 return new AbstractListCalc(call, new Calc[] {listCalc, startCalc, countCalc}) { 053 public List evaluateList(Evaluator evaluator) { 054 final List list = 055 listCalc.evaluateList(evaluator); 056 final int start = 057 startCalc.evaluateInteger(evaluator); 058 int end; 059 if (countCalc != null) { 060 final int count = 061 countCalc.evaluateInteger(evaluator); 062 end = start + count; 063 } else { 064 end = list.size(); 065 } 066 if (end > list.size()) { 067 end = list.size(); 068 } 069 if (start >= end || start < 0) { 070 return Collections.EMPTY_LIST; 071 } 072 assert 0 <= start; 073 assert start < end; 074 assert end <= list.size(); 075 if (start == 0 && end == list.size()) { 076 return list; 077 } else { 078 return list.subList(start, end); 079 } 080 } 081 }; 082 } 083 } 084 085 // End SubsetFunDef.java