package org.openlca.io.olca;
import java.util.List;
import org.openlca.core.database.CategoryDao;
import org.openlca.core.database.IDatabase;
import org.openlca.core.model.Category;
import org.openlca.core.model.ModelType;
import org.openlca.util.Strings;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
class CategoryImport implements Runnable {
private Logger log = LoggerFactory.getLogger(getClass());
private CategoryDao sourceDao;
private CategoryDao destDao;
private Sequence seq;
public CategoryImport(IDatabase source, IDatabase destination, Sequence seq) {
this.sourceDao = new CategoryDao(source);
this.destDao = new CategoryDao(destination);
this.seq = seq;
}
@Override
public void run() {
ModelType[] rootTypes = { ModelType.PROJECT, ModelType.PRODUCT_SYSTEM,
ModelType.IMPACT_METHOD, ModelType.PROCESS, ModelType.FLOW,
ModelType.FLOW_PROPERTY, ModelType.UNIT_GROUP,
ModelType.SOURCE, ModelType.ACTOR };
for (ModelType type : rootTypes) {
synchCategories(type);
}
}
private void synchCategories(ModelType type) {
log.trace("synch categories for type {}", type);
List<Category> sourceRoots = sourceDao.getRootCategories(type);
List<Category> destRoots = destDao.getRootCategories(type);
for (Category sourceRoot : sourceRoots) {
Category destRoot = find(sourceRoot, destRoots);
if (destRoot != null) {
synchCategories(sourceRoot, destRoot);
destRoot = destDao.update(destRoot);
} else {
destRoot = copy(sourceRoot);
synchCategories(sourceRoot, destRoot);
destRoot = destDao.insert(destRoot);
}
index(sourceRoot, destRoot);
}
}
private void synchCategories(Category srcCat, Category destCat) {
for (Category srcChild : srcCat.getChildCategories()) {
Category destChild = find(srcChild, destCat.getChildCategories());
if (destChild == null) {
destChild = copy(srcChild);
destCat.getChildCategories().add(destChild);
destChild.setCategory(destCat);
}
synchCategories(srcChild, destChild);
}
}
private Category find(Category srcCat, List<Category> destCategories) {
for (Category destCat : destCategories) {
if (Strings.nullOrEqual(srcCat.getName(), destCat.getName())) {
return destCat;
}
}
return null;
}
/**
* Creates a flat copy of the given category. Note that the clone function
* in the category class creates a deep copy.
*/
private Category copy(Category srcCat) {
Category copy = new Category();
copy.setDescription(srcCat.getDescription());
copy.setName(srcCat.getName());
copy.setRefId(srcCat.getRefId());
copy.setModelType(srcCat.getModelType());
return copy;
}
private void index(Category srcRoot, Category destRoot) {
if (srcRoot == null || destRoot == null)
return;
seq.put(seq.CATEGORY, srcRoot.getRefId(), destRoot.getId());
for (Category srcChild : srcRoot.getChildCategories()) {
Category destChild = find(srcChild, destRoot.getChildCategories());
index(srcChild, destChild);
}
}
}