package org.openlca.ilcd.util; import java.io.BufferedInputStream; import java.io.InputStream; import java.util.ArrayList; import java.util.Collections; import java.util.List; import javax.xml.stream.XMLInputFactory; import javax.xml.stream.XMLStreamConstants; import javax.xml.stream.XMLStreamReader; import org.openlca.ilcd.commons.Category; import org.openlca.ilcd.commons.Classification; import org.openlca.ilcd.commons.IDataSet; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public final class ClassList { private ClassList() { } static List<Category> sortedList(IDataSet ds) { if (ds == null) return Collections.emptyList(); List<Classification> list = ds.getClassifications(); if (list.isEmpty()) return Collections.emptyList(); Classification classification = list.get(0); List<org.openlca.ilcd.commons.Category> classes = classification.categories; Collections.sort(classes, (c1, c2) -> c1.level - c2.level); return classes; } /** * Efficiently reads the list of classifications from a data set. */ public static List<Classification> read(InputStream is) { List<Classification> list = new ArrayList<>(); try (BufferedInputStream buffer = new BufferedInputStream(is)) { XMLStreamReader reader = XMLInputFactory.newFactory() .createXMLStreamReader(buffer); Classification classification = null; Category category = null; while (reader.hasNext()) { int evt = reader.next(); if (evt == XMLStreamConstants.START_ELEMENT) { if (eq(reader, "classification")) classification = initClassification(reader); if (eq(reader, "class") && classification != null) category = initCategory(reader); } if (evt == XMLStreamConstants.END_ELEMENT) { if (reader.getLocalName().equals("classificationInformation")) break; if (eq(reader, "classification") && classification != null) { list.add(classification); classification = null; } if (eq(reader, "class") && category != null && classification != null) { classification.categories.add(category); category = null; } } if (evt == XMLStreamConstants.CHARACTERS && category != null) addValue(reader, category); } reader.close(); } catch (Exception e) { Logger log = LoggerFactory.getLogger(ClassList.class); log.error("failed to read classifications", e); } return list; } private static Classification initClassification(XMLStreamReader reader) { Classification classification; classification = new Classification(); classification.name = reader.getAttributeValue(null, "name"); classification.url = reader.getAttributeValue(null, "classes"); return classification; } private static Category initCategory(XMLStreamReader reader) { Category category; category = new Category(); category.classId = reader.getAttributeValue(null, "classId"); String level = reader.getAttributeValue(null, "level"); if (level == null) return category; try { category.level = Integer.parseInt(level); } catch (Exception e) { Logger log = LoggerFactory.getLogger(ClassList.class); log.error("No numeric level for class " + category.classId, e); } return category; } private static void addValue(XMLStreamReader reader, Category category) { String s = reader.getText(); if (s == null) return; s = s.trim(); if (s.isEmpty()) return; if (category.value == null) category.value = s; else category.value += " " + s; } private static boolean eq(XMLStreamReader reader, String tag) { return reader.getLocalName().equals(tag); } }