package org.openlca.io.ecospold2.input;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import org.openlca.core.model.Category;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* An ISIC category tree which can be build from an ISIC text file (see the ISIC
* text file in this project resources which is available from
* http://unstats.un.org/unsd/cr/registry/isic-4.asp).
*/
class IsicTree {
private List<IsicNode> roots = new ArrayList<>();
public List<IsicNode> getRoots() {
return roots;
}
public IsicNode findNode(String code) {
if (code == null)
return null;
for (IsicNode root : roots) {
IsicNode node = findNode(code, root);
if (node != null)
return node;
}
return null;
}
private IsicNode findNode(String code, IsicNode root) {
for (IsicNode child : root.childs) {
if (code.equals(child.code))
return child;
if (code.startsWith(child.code))
return findNode(code, child);
}
return null;
}
public static IsicTree fromFile(InputStream in) {
IsicTree tree = new IsicTree();
try (InputStreamReader reader = new InputStreamReader(in);
BufferedReader buffer = new BufferedReader(reader)) {
String line = null;
while ((line = buffer.readLine()) != null) {
IsicNode node = makeNode(line);
if (node == null)
continue;
addNode(tree, node);
}
} catch (Exception e) {
Logger log = LoggerFactory.getLogger(IsicTree.class);
log.error("faile to build ISIC tree", e);
}
return tree;
}
private static void addNode(IsicTree tree, IsicNode node) {
if (node.code.length() == 1) {
tree.roots.add(node);
return;
}
IsicNode root = tree.roots.get(tree.roots.size() - 1);
IsicNode parent = findParent(node.code, root);
parent.childs.add(node);
node.parent = parent;
}
private static IsicNode findParent(String code, IsicNode root) {
for (IsicNode candidate : root.childs) {
if (code.startsWith(candidate.code))
return findParent(code, candidate);
}
return root;
}
private static IsicNode makeNode(String line) {
if (line == null || line.isEmpty() || line.length() < 1)
return null;
String[] parts = line.split("\",\"");
if (parts.length != 2)
return null;
if (!parts[0].startsWith("\"") || !parts[1].endsWith("\""))
return null;
String code = parts[0].substring(1);
String name = parts[1].substring(0, parts[1].length() - 1);
IsicNode node = new IsicNode();
node.code = code;
node.name = name;
return node;
}
static class IsicNode {
private String code;
private String name;
private IsicNode parent;
private List<IsicNode> childs = new ArrayList<>();
private Category category;
/** Set the corresponding openLCA category */
void setCategory(Category category) {
this.category = category;
}
/** Set the corresponding openLCA category */
Category getCategory() {
return category;
}
public IsicNode getParent() {
return parent;
}
public List<IsicNode> getChilds() {
return childs;
}
public String getCode() {
return code;
}
public String getName() {
return name;
}
@Override
public String toString() {
return "IsicNode [code=" + code + "]";
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((code == null) ? 0 : code.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
IsicNode other = (IsicNode) obj;
if (code == null) {
if (other.code != null)
return false;
} else if (!code.equals(other.code))
return false;
return true;
}
}
}