package org.openlca.io.ecospold1.output; import java.io.Closeable; import java.io.File; import java.io.IOException; import java.util.Collections; import java.util.Comparator; import java.util.Objects; import java.util.TreeSet; import javax.xml.bind.JAXB; import org.openlca.core.model.Exchange; import org.openlca.core.model.Flow; import org.openlca.core.model.FlowType; import org.openlca.core.model.Process; import org.openlca.ecospold.Category; import org.openlca.ecospold.CategoryDocument; import org.openlca.ecospold.SubCategory; import org.openlca.util.Strings; class CategoryWriter implements Closeable { private File file; private CategoryDocument doc; private TreeSet<Long> handled = new TreeSet<>(); public CategoryWriter(File file, ExportConfig config) { this.file = file; this.doc = new CategoryDocument(); } public void takeFrom(Process process) { if (process == null) return; for (Exchange exchange : process.getExchanges()) { Flow flow = exchange.getFlow(); int type = getType(flow); if (flow == null || type == -1) continue; org.openlca.core.model.Category category = flow.getCategory(); if (category == null || handled.contains(category.getId())) continue; register(convert(category, type)); handled.add(category.getId()); } } private void register(Category category) { boolean found = false; for (Category existing : doc.getCategories()) { if (!equal(category, existing)) continue; found = true; if (category.getSubCategories().isEmpty()) continue; SubCategory sub = category.getSubCategories().get(0); register(sub, existing); } if (!found) doc.getCategories().add(category); } private void register(SubCategory subCategory, Category existing) { boolean found = false; for (SubCategory existingSub : existing.getSubCategories()) { if (equal(subCategory, existingSub)) { found = true; break; } } if (!found) existing.getSubCategories().add(subCategory); } private Category convert( org.openlca.core.model.Category category, int type) { Category cat = new Category(); cat.setType(type); if (category.getCategory() == null) { cat.setName(category.getName()); cat.setLocalName(category.getName()); } else { org.openlca.core.model.Category parent = category .getCategory(); cat.setName(parent.getName()); cat.setLocalName(parent.getName()); SubCategory sub = new SubCategory(); cat.getSubCategories().add(sub); sub.setName(category.getName()); sub.setLocalName(category.getName()); } return cat; } private int getType(Flow flow) { if (flow == null) return -1; FlowType flowType = flow.getFlowType(); if (flowType == null) return -1; if (flowType == FlowType.ELEMENTARY_FLOW) return 1; else return 0; } private boolean equal(Category c1, Category c2) { if (c1 == c2) return true; if (c1 == null || c2 == null) return false; return c1.getType() == c2.getType() && Objects.equals(c1.getName(), c2.getName()); } private boolean equal(SubCategory c1, SubCategory c2) { if (c1 == c2) return true; if (c1 == null || c2 == null) return false; return Objects.equals(c1.getName(), c2.getName()); } /** * Finally writes the category file. * * @throws IOException */ @Override public void close() throws IOException { Collections.sort(doc.getCategories(), new Comparator<Category>() { @Override public int compare(Category o1, Category o2) { if (o1 == null || o2 == null) return 0; if (o1.getType() != o2.getType()) return o1.getType() - o2.getType(); else return Strings.compare(o1.getName(), o2.getName()); } }); JAXB.marshal(doc, file); } }