package org.openlca.io; import java.util.List; import java.util.Objects; import java.util.UUID; import org.openlca.core.database.IDatabase; import org.openlca.core.model.Unit; import org.openlca.core.model.UnitGroup; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Synchronizes a set of unit-mappings with the database. New units are created * in the respective unit groups. */ public class UnitMappingSync { private Logger log = LoggerFactory.getLogger(getClass()); private IDatabase database; public UnitMappingSync(IDatabase database) { this.database = database; } /** * Runs the synchronization. The given entries are directly modified in the * synchronization and added to the unit mapping. */ public UnitMapping run(List<UnitMappingEntry> entries) { UnitMapping mapping = new UnitMapping(); for (UnitMappingEntry entry : entries) { UnitGroup unitGroup = entry.unitGroup; String unitName = entry.unitName; if (unitGroup.getUnit(unitName) != null) { mapping.put(unitName, entry); continue; } unitGroup = updateUnitGroup(entry, unitGroup); syncEntries(unitGroup, entries); mapping.put(unitName, entry); } return mapping; } /** * Add a new unit created from the given entry to the unit group. */ private UnitGroup updateUnitGroup(UnitMappingEntry entry, UnitGroup unitGroup) { log.trace("add new unit {} to group {}", entry.unitName, unitGroup); Unit unit = new Unit(); unit.setName(entry.unitName); unit.setRefId(UUID.randomUUID().toString()); double factor = entry.factor == null ? 1d : entry.factor; unit.setConversionFactor(factor); unitGroup.getUnits().add(unit); unitGroup = database.createDao(UnitGroup.class).update(unitGroup); entry.factor = factor; entry.unitGroup = unitGroup; entry.unit = unitGroup.getUnit(entry.unitName); return unitGroup; } /** * Replace the unit group and units in the entries with the last updated * versions. This ensures that all units and unit groups are synchronous * with the persistence layer. */ private void syncEntries(UnitGroup updatedGroup, List<UnitMappingEntry> entries) { for (UnitMappingEntry entry : entries) { if (!Objects.equals(updatedGroup, entry.unitGroup)) continue; Unit unit = updatedGroup.getUnit(entry.unitName); entry.unit = unit; entry.unitGroup = updatedGroup; } } }