/*
* eXist Open Source Native XML Database
* Copyright (C) 2001-06 The eXist Project
* http://exist-db.org
* http://exist.sourceforge.net
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id$
*/
package org.exist.xquery.value;
import java.util.Hashtable;
import java.util.Iterator;
import org.exist.xquery.GroupSpec;
import org.exist.xquery.XPathException;
import org.exist.xquery.XQueryContext;
/**
* An Hashtable that containts a GroupedValueSequence for each group.
* Groups are specified by the group specs of a "group by" clause. Used by
* {@link org.exist.xquery.ForExpr} et al.
*
* WARNING : don't use except for experimental "group by" clause
*
* @author Boris Verhaegen (boris.verhaegen@gmail.com)
*/
public class GroupedValueSequenceTable extends Hashtable {
private GroupSpec groupSpecs[];
private String toGroupVarName;
private XQueryContext context;
public GroupedValueSequenceTable(GroupSpec groupSpecs[], String varName, XQueryContext aContext) {
super(11,(float)0.75); //Hashtable parameters
this.groupSpecs = groupSpecs;
this.toGroupVarName = varName;
this.context = aContext;
}
public void setToGroupVarName(String varName){
toGroupVarName = varName;
}
public String getToGroupVarName(){
return toGroupVarName;
}
public Iterator iterate(){
Iterator it = this.keySet().iterator();
return it;
}
/**
* Add <code>item</code> in the correct <code>GroupedValueSequence</code>.
* Create correct GroupedValueSequence if needed. Insertion based on
* the group specs of a "group by" clause.
*
* @throws XPathException
*/
public void add(Item item) throws XPathException {
Sequence specEvaluation[] = new Sequence[groupSpecs.length];
ValueSequence keySequence = new ValueSequence();
for(int i = 0; i < groupSpecs.length ; i++){
//evaluates the values of the grouping keys
specEvaluation[i] = groupSpecs[i].getGroupExpression().eval(item.toSequence()); //TODO : too early evaluation !
keySequence.add(specEvaluation[i].itemAt(0));
}
String hashKey = keySequence.getHashKey();
if( this.containsKey(hashKey) ){
GroupedValueSequence currentGroup = (GroupedValueSequence)super.get(hashKey);
currentGroup.add(item);
}
else{
//this group doesn't exists, then creates this group
GroupedValueSequence newGroup = new GroupedValueSequence(groupSpecs, 1, keySequence,context);
newGroup.add(item);
super.put(hashKey,newGroup);
}
}
/**
* Add all items of a sequence
*
* @param sequence
* @throws XPathException
*/
public void addAll(Sequence sequence) throws XPathException{
for (SequenceIterator i = sequence.iterate(); i.hasNext(); ) {
this.add(i.nextItem());
}
}
}