package org.openlca.ilcd.util;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamReader;
import org.openlca.ilcd.commons.DataSetType;
import org.openlca.ilcd.commons.LangString;
import org.openlca.ilcd.commons.Ref;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Refs {
private Refs() {
}
/** Returns the data set reference of the ILCD format. */
public static Ref ilcd() {
Ref ref = new Ref();
ref.type = DataSetType.SOURCE;
ref.uri = "../sources/a97a0155-0234-4b87-b4ce-a45da52f2a40_01.01.000.xml";
ref.uuid = "a97a0155-0234-4b87-b4ce-a45da52f2a40";
ref.version = "01.01.000";
LangString.set(ref.name, "ILCD format", "en");
return ref;
}
public static Ref fetch(File file) {
if (file == null || !file.exists())
return null;
try (FileInputStream is = new FileInputStream(file)) {
return fetch(is);
} catch (Exception e) {
Logger log = LoggerFactory.getLogger(Refs.class);
log.error("Failed to read ref from " + file, e);
return null;
}
}
public static Ref fetch(InputStream is) {
try {
return new RefFetch().fetch(is);
} catch (Exception e) {
Logger log = LoggerFactory.getLogger(Refs.class);
log.error("Failed to read ref", e);
return null;
}
}
private static class RefFetch {
Ref ref;
XMLStreamReader reader;
StringBuilder sb;
String lang;
Ref fetch(InputStream is) throws Exception {
ref = new Ref();
reader = XMLInputFactory.newFactory()
.createXMLStreamReader(is);
boolean root = true;
boolean stop = false;
while (reader.hasNext()) {
reader.next();
switch (reader.getEventType()) {
case XMLStreamConstants.START_ELEMENT:
if (root) {
root = false;
ref.type = getType();
} else {
start();
}
break;
case XMLStreamConstants.CHARACTERS:
text();
break;
case XMLStreamConstants.END_ELEMENT:
stop = end();
break;
}
if (stop)
break;
}
return ref;
}
DataSetType getType() {
String element = reader.getLocalName();
if (element == null)
return null;
switch (element) {
case "LCIAMethodDataSet":
return DataSetType.LCIA_METHOD;
case "processDataSet":
return DataSetType.PROCESS;
case "contactDataSet":
return DataSetType.CONTACT;
case "sourceDataSet":
return DataSetType.SOURCE;
case "flowDataSet":
return DataSetType.FLOW;
case "flowPropertyDataSet":
return DataSetType.FLOW_PROPERTY;
case "unitGroupDataSet":
return DataSetType.UNIT_GROUP;
default:
return null;
}
}
void start() {
String element = reader.getLocalName();
if (element == null)
return;
switch (element) {
case "UUID":
case "dataSetVersion":
case "permanentDataSetURI":
sb = new StringBuilder();
return;
}
if (matchName(element)) {
lang = reader.getAttributeValue(
"http://www.w3.org/XML/1998/namespace", "lang");
sb = new StringBuilder();
}
}
void text() {
if (sb == null)
return;
int pos = reader.getTextStart();
int len = reader.getTextLength();
sb.append(reader.getTextCharacters(), pos, len);
}
/**
* Handles an element-ends-event and returns true if we can stop parsing
* the document.
*/
boolean end() {
if (sb == null)
return false;
String t = sb.toString().trim();
sb = null;
String element = reader.getLocalName();
if (element == null)
return false;
switch (element) {
case "UUID":
ref.uuid = t;
return false;
case "dataSetVersion":
ref.version = t;
return false;
case "permanentDataSetURI":
ref.uri = t;
return true;
}
if (matchName(element)) {
LangString.set(ref.name, t, lang);
}
return false;
}
private boolean matchName(String name) {
switch (name) {
case "name":
return ref.type == DataSetType.CONTACT
|| ref.type == DataSetType.FLOW_PROPERTY
|| ref.type == DataSetType.UNIT_GROUP
|| ref.type == DataSetType.LCIA_METHOD;
case "baseName":
return ref.type == DataSetType.FLOW
|| ref.type == DataSetType.PROCESS;
case "shortName":
return ref.type == DataSetType.SOURCE;
default:
return false;
}
}
}
}