List<MultipleObjectsBundle> bundles = new ArrayList<MultipleObjectsBundle>(sources.size());
for(DatabaseConnection dbc : sources) {
bundles.add(dbc.loadData());
}
MultipleObjectsBundle first = bundles.get(0);
Map<String, Integer> labelmap = new HashMap<String, Integer>(first.dataLength());
// Process first bundle
{
// Identify a label column
final int lblcol;
{
int lblc = -1;
for(int i = 0; i < first.metaLength(); i++) {
if(TypeUtil.GUESSED_LABEL.isAssignableFromType(first.meta(i))) {
lblc = i;
break;
}
}
lblcol = lblc; // make static
}
if(lblcol == -1) {
throw new AbortException("No label column found in first source, cannot join (do you want to use " + ExternalIDJoinDatabaseConnection.class.getSimpleName() + " instead?)");
}
for(int i = 0; i < first.dataLength(); i++) {
Object data = first.data(i, lblcol);
if(data == null) {
logger.warning("Object without label encountered.");
continue;
}
if(data instanceof String) {
Integer old = labelmap.put((String) data, i);
if(old != null) {
logger.warning("Duplicate label encountered: " + data + " in rows " + old + " and " + i);
}
}
else if(data instanceof LabelList) {
for(String lbl : (LabelList) data) {
Integer old = labelmap.put(lbl, i);
if(old != null) {
logger.warning("Duplicate label encountered: " + lbl + " in rows " + old + " and " + i);
}
}
}
else {
String lbl = data.toString();
Integer old = labelmap.put(lbl, i);
if(old != null) {
logger.warning("Duplicate label encountered: " + lbl + " in rows " + old + " and " + i);
}
}
}
}
// Process additional columns
for(int c = 1; c < sources.size(); c++) {
MultipleObjectsBundle cur = bundles.get(c);
final int lblcol;
{
int lblc = -1;
for(int i = 0; i < cur.metaLength(); i++) {
if(TypeUtil.GUESSED_LABEL.isAssignableFromType(cur.meta(i))) {
lblc = i;
break;
}
}
lblcol = lblc; // make static
}
if(lblcol == -1) {
throw new AbortException("No label column found in source " + (c + 1) + ", cannot join (do you want to use " + ExternalIDJoinDatabaseConnection.class.getSimpleName() + " instead?)");
}
// Destination columns
List<ArrayList<Object>> dcol = new ArrayList<ArrayList<Object>>(cur.metaLength());
for(int i = 0; i < cur.metaLength(); i++) {
// Skip the label columns
if(i == lblcol) {
dcol.add(null);
continue;
}
ArrayList<Object> newcol = new ArrayList<Object>(first.dataLength());
// Pre-fill with nulls.
for(int j = 0; j < first.dataLength(); j++) {
newcol.add(null);
}
first.appendColumn(cur.meta(i), newcol);
dcol.add(newcol);
}
for(int i = 0; i < cur.dataLength(); i++) {
Object data = cur.data(i, lblcol);
if(data == null) {
logger.warning("Object without label encountered.");
continue;
}
Integer row = null;
if(data instanceof String) {
row = labelmap.get(data);
}
else if(data instanceof LabelList) {
for(String lbl : (LabelList) data) {
row = labelmap.get(lbl);
if(row != null) {
break;
}
}
}
else {
row = labelmap.get(data.toString());
}
if(row == null) {
logger.warning("Label not found for join: " + data + " in row " + i);
continue;
}
for(int d = 0; d < cur.metaLength(); d++) {
if(d == lblcol) {
continue;
}
List<Object> col = dcol.get(d);
assert (col != null);
col.set(row, cur.data(i, d));
}
}
}
for(int i = 0; i < first.dataLength(); i++) {
for(int d = 0; d < first.metaLength(); d++) {