/**
* Copyright (c) 2004-2011 Wang Jinbao(Julian Wong), http://www.ralasafe.com
* Licensed under the MIT license: http://www.opensource.org/licenses/mit-license.php
*/
package org.ralasafe.db;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import org.ralasafe.GeneralPK;
import org.ralasafe.util.Util;
/**
* Given a conditon, we query MainTable, SingleValueTables and MultiValueTables.
* Many values are returned. The combiner combine them into entities and don't disorder the entities.
*
*/
public class ComplexTableValueCombiner {
private ComplexTable complexTable;
private SingleValueTableAdapter[] singleValueTableAdapters;
private MultiValueTableAdapter[] multiValueTableAdapters;
private Collection mainTableValues;
private Collection[] singleValueTableValues;
private Collection[] multiValueTableValues;
// Store ComplexTable's attribute/attribute's value by order,key/value=pk< GeneralPK >/entity< Object >
private LinkedHashMap map=new LinkedHashMap();
public ComplexTableValueCombiner( ComplexTable complexTable ) {
this.complexTable=complexTable;
}
public SingleValueTableAdapter[] getSingleValueTableAdapters() {
return singleValueTableAdapters;
}
public void setSingleValueTableAdapters(
SingleValueTableAdapter[] singleValueTableAdapters ) {
this.singleValueTableAdapters=singleValueTableAdapters;
}
public MultiValueTableAdapter[] getMultiValueTableAdapters() {
return multiValueTableAdapters;
}
public void setMultiValueTableAdapters(
MultiValueTableAdapter[] multiValueTableAdapters ) {
this.multiValueTableAdapters=multiValueTableAdapters;
}
public Collection getMainTableValues() {
return mainTableValues;
}
public void setMainTableValues( Collection coll ) {
this.mainTableValues=coll;
Table mainTable=complexTable.getMainTable();
Column[] idColumns=mainTable.getIdColumns();
for( Iterator iter=coll.iterator(); iter.hasNext(); ) {
Object temp=(Object) iter.next();
Object[] keyFields=new Object[idColumns.length];
for( int j=0; j<idColumns.length; j++ ) {
keyFields[j]=idColumns[j].getAdapter().extractFieldValue( temp );
}
GeneralPK pk=new GeneralPK( keyFields );
map.put( pk, temp );
}
}
public Collection[] getSingleValueTableValues() {
return singleValueTableValues;
}
public void setSingleValueTableValues( Collection[] singleValueTableValues ) {
this.singleValueTableValues=singleValueTableValues;
}
public Collection[] getMultiValueTableValues() {
return multiValueTableValues;
}
public void setMultiValueTableValues( Collection[] multiValueTableValues ) {
this.multiValueTableValues=multiValueTableValues;
}
public Collection getGeneralPks() {
return map.keySet();
}
public Collection combine() {
combineSingleValueTables();
combineMultiValueTables();
return map.values();
}
private void combineSingleValueTables() {
if( Util.isEmpty( singleValueTableValues ) )
return;
for( int i=0; i<singleValueTableValues.length; i++ ) {
Collection coll=singleValueTableValues[i];
Table table=complexTable.getSingleValueTables()[i];
SingleValueTableAdapter adapter=singleValueTableAdapters[i];
for( Iterator iter=coll.iterator(); iter.hasNext(); ) {
Object obj=iter.next();
// extract pkFields to get pk, then read cached entity from map,
// combine obj into cached value.
Column[] idColumns2=table.getIdColumns();
Object[] pkFields=new Object[idColumns2.length];
for( int j=0; j<idColumns2.length; j++ ) {
Column column=idColumns2[j];
pkFields[j]=column.getAdapter().extractFieldValue( obj );
}
GeneralPK pk=new GeneralPK( pkFields );
Object mapValue=map.get( pk );
adapter.combine( mapValue, obj );
}
}
}
private void combineMultiValueTables() {
if( Util.isEmpty( multiValueTableValues ) ) {
return;
}
for( int i=0; i<multiValueTableValues.length; i++ ) {
// key/value=pk<GeneralPK>/multiValues<List>
Map pkCollectionMap=new HashMap();
Collection coll=multiValueTableValues[i];
Table table=complexTable.getMultiValueTables()[i];
MultiValueTableAdapter adapter=multiValueTableAdapters[i];
for( Iterator iter=coll.iterator(); iter.hasNext(); ) {
Object obj=iter.next();
// extract pkFields to get pk, then read cached entity from map,
// combine obj into cached value.
Column[] idColumns2=table.getIdColumns();
Object[] pkFields=new Object[idColumns2.length];
for( int j=0; j<idColumns2.length; j++ ) {
Column column=idColumns2[j];
pkFields[j]=column.getAdapter().extractFieldValue( obj );
}
GeneralPK pk=new GeneralPK( pkFields );
List values=(List) pkCollectionMap.get( pk );
if( values==null ) {
values=new LinkedList();
pkCollectionMap.put( pk, values );
}
values.add( obj );
}
for( Iterator iter=pkCollectionMap.entrySet().iterator(); iter.hasNext(); ) {
Map.Entry entry=(Map.Entry) iter.next();
GeneralPK pk=(GeneralPK) entry.getKey();
List values= (List) entry.getValue();
Object mapValue=map.get( pk );
adapter.combine( mapValue, values.toArray() );
}
}
}
}