package com.perpetumobile.bit.orm.xml;

import java.util.ArrayList;

import org.xml.sax.Attributes;

import com.perpetumobile.bit.orm.record.Record;
import com.perpetumobile.bit.orm.record.RecordConnection;
import com.perpetumobile.bit.orm.record.RecordConnectionManager;
import com.perpetumobile.bit.orm.record.StatementLogger;
import com.perpetumobile.bit.orm.record.field.Field;
import com.perpetumobile.bit.orm.record.field.FieldConfig;
import com.perpetumobile.bit.util.Util;


/**
 * 
 * @author Zoran Dukic
 */
public class XMLRecord extends Record {
	
	public XMLRecord() {
	}
	
	public XMLRecord(String configName) {
		init(configName);
	}
	
	public void init(String configName) {
		init(XMLRecordConfigFactory.getInstance().getRecordConfig(configName));
	}
	
	public String getLocalName() {
		return (config != null ? ((XMLRecordConfig)config).getLocalName() : null);
	}
	
	public boolean isParseAll() {
		return (config != null ? ((XMLRecordConfig)config).isParseAll() : true);
	}
	
	public void readRecord(Attributes attr) {
		if(isConfigFields()) {
			for(Field f : getFields()) {
				f.setFieldValue(attr.getValue(f.getFieldName()));
			}
		} else if(isParseAll()) {
			for(int i=0; i < attr.getLength(); i++) {
				FieldConfig fc = new FieldConfig(attr.getQName(i), "varchar");
				Field f = fc.createField();
				f.setFieldValue(attr.getValue(i));
				addField(f);
			}
		}
	}
	
	public void setContent(String content) {
		String value = content.trim();
		if(!Util.nullOrEmptyString(value)) {
			Field f = getField(getLocalName());
			if(f != null) {
				f.setFieldValue(value);
			} else if(isParseAll()) {
				FieldConfig fc = new FieldConfig(getLocalName(), "varchar");
				f = fc.createField();
				f.setFieldValue(value);
				addField(f);
			}
		}
	}
	
	@SuppressWarnings("unchecked")
	public void aggregate(XMLRecord rec) {
		Field f = getField(rec.getLocalName());
		if(f != null && !f.isSet()) {
			f.setFieldValue(rec.getFieldValue(rec.getLocalName()));
		} else {
			String key = rec.getConfigName();
			ArrayList<XMLRecord> list = (ArrayList<XMLRecord>)listRelationshipMap.get(key);
			if(list == null) {
				list = new ArrayList<XMLRecord>();
				listRelationshipMap.put(key, list);
			}
			list.add(rec);
		}
	}
	
	public ArrayList<XMLRecord> getXMLRecords(String... configNameArray) {
		ArrayList<XMLRecord> result = new ArrayList<XMLRecord>(); 
		
		StringBuilder buf = new StringBuilder();
		boolean isFirst = true;
		for(String s : configNameArray) {
			if(!isFirst) {
				buf.append(getConfigNameDelimiter());
			}
			buf.append(s);
			isFirst = false;
		}
		getXMLRecords(result, buf.toString());
		
		return result;
	}
	
	@SuppressWarnings("unchecked")
	protected void getXMLRecords(ArrayList<XMLRecord> result, String configName) {
		if(configName.startsWith(getConfigName())) {
			int index = configName.indexOf(getConfigNameDelimiter(), getConfigName().length()+1);
			if(index != -1) {
				// need to walk down relationship maps
				String key = configName.substring(0, index);
				
				// add records from listRelationshipMap
				ArrayList<XMLRecord> list = (ArrayList<XMLRecord>)listRelationshipMap.get(key);
				if(list != null) {
					for(XMLRecord rec : list) {
						rec.getXMLRecords(result, configName);
					}
				}
			} else {
				// add records from listRelationshipMap
				ArrayList<XMLRecord> list = (ArrayList<XMLRecord>)listRelationshipMap.get(configName);
				if(list != null) {
					result.addAll(list);
				}
			}
		} 
	}
	
	protected RecordConnectionManager<? extends RecordConnection<?>> getConnectionManager() {
		// lazy relationship loading not supported for XMLRecord
		return null;
	}

	protected Record readRecordRelationship(String configName, RecordConnection<?> connection, StatementLogger stmtLogger)
	throws Exception {
		// lazy relationship loading not supported for XMLRecord
		return null;
	}

	protected ArrayList<? extends Record> readListRelationship(String configName, RecordConnection<?> connection, StatementLogger stmtLogger)
	throws Exception {
		// lazy relationship loading not supported for XMLRecord
		return null;
	}
}

@@ -60,16 +60,66 @@
 rayList;
+%0Aimport java.util.Set;%0Aimport java.util.Map.Entry;
 %0A%0Aimport
@@ -2291,25 +2291,649 @@
 %0A%09%0A%09
-public ArrayList%3C
+/**%0A%09 * Get first level aggregated XMLRecords.%0A%09 */%0A%09@SuppressWarnings(%22unchecked%22)%0A%09public ArrayList%3C? extends XMLRecord%3E getXMLRecords() %7B%0A%09%09ArrayList%3CXMLRecord%3E result = new ArrayList%3CXMLRecord%3E();%0A%09%09%09%0A%09%09// add records from listRelationshipMap%0A%09%09Set%3CEntry%3CString, ArrayList%3C? extends Record%3E%3E%3E listSet = listRelationshipMap.entrySet();%0A%09%09for(Entry%3CString, ArrayList%3C? extends Record%3E%3E e : listSet) %7B%0A%09%09%09ArrayList%3CXMLRecord%3E list = (ArrayList%3CXMLRecord%3E)e.getValue();%0A%09%09%09result.addAll(list);%0A%09%09%7D%0A%09%09%0A%09%09return result;%0A%09%7D%0A%09%0A%09/**%0A%09 * Get deep level aggregated XMLRecords by walking down the relationship maps.%0A%09 */%0A%09public ArrayList%3C? extends 
 XMLR

Add getXMLRecords() to get first level aggregated XMLRecords.