You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
AriadnePlus/dnet-ariadneplus-graphdb-pu.../src/main/java/eu/dnetlib/ariadneplus/reader/ResourceManager.java

199 lines
6.8 KiB
Java

package eu.dnetlib.ariadneplus.reader;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import javax.annotation.PostConstruct;
import eu.dnetlib.ariadneplus.reader.json.ParseRDFJSON;
import eu.dnetlib.ariadneplus.reader.utils.ClassSpec;
import eu.dnetlib.ariadneplus.reader.utils.Mappings;
import eu.dnetlib.ariadneplus.reader.utils.PropertiesMap;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import com.google.common.reflect.TypeToken;
import com.google.gson.Gson;
import net.minidev.json.JSONArray;
import net.minidev.json.JSONObject;
@Service
public class ResourceManager {
private static final Log log = LogFactory.getLog(ResourceManager.class);
@Value("${type.path:undefined}")
private String type_path;
@Value("${general.classpath:undefined}")
private String general_classpath;
@Value("${exclude.predicates:[]}")
private String exclude_predicates;
@Value("${class.map.specifications:undefined}")
private String spec;
private List<String> not_parsable;
private ParseRDFJSON parser;
private PropertiesMap propertiesMap;
public void setup(String type_path, String general_classpath, String exclude_predicates, String spec) {
this.type_path = type_path;
this.general_classpath = general_classpath;
this.exclude_predicates = exclude_predicates;
this.spec = spec;
init();
}
@PostConstruct
public void init(){
Type listType = new TypeToken<ArrayList<String>>(){}.getType();
not_parsable = new Gson().fromJson(exclude_predicates, listType);
propertiesMap = new PropertiesMap();
propertiesMap.fill(spec);
}
private String getFieldValue(Object value){
if (value instanceof LinkedHashMap)
return (String)((LinkedHashMap)value).get("value");
return (String)((JSONObject)value).get("value");
}
public void manage(ParseRDFJSON parser){
this.parser = parser;
}
public boolean hasNext(){
return parser.hasNextElement();
}
public Object next() throws ClassNotFoundException, NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException {
return manage(parser.getNextElement(),null);
}
private Object manage(Object entry, String class_name) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException, InstantiationException {
if (class_name == null){
if(entry instanceof LinkedHashMap){
LinkedHashMap tmp = (LinkedHashMap)((JSONArray)((LinkedHashMap)entry).get(type_path)).get(0);
class_name = (String)tmp.get("value");
//TODO: Use rdf:type instead of these values that are added statically by the CONSTRUCT queries (that need to be changed as well to include the rdf:type
if (class_name.equals("Record") || class_name.equals("Collection")) {
class_name = "AriadnePlusEntry";
}
}
}
if (entry == null) {
return null;
}
Class<?> c = Class.forName(general_classpath + class_name);
Object class_instance = c.newInstance();
ClassSpec class_spec = propertiesMap.get(class_name);
Set<?> keySet;
if(entry instanceof LinkedHashMap)
keySet = ((LinkedHashMap)entry).keySet();
else
keySet = ((JSONObject)entry).keySet();
for(Object predicate: keySet){//predicates in the json
if (not_parsable.contains(predicate))
continue;
Mappings map = class_spec.get((String)predicate);
if (map==null) {
continue;
}
JSONArray values;
if(entry instanceof LinkedHashMap)
values = (JSONArray)((LinkedHashMap)entry).get(predicate);
else
values = (JSONArray)((JSONObject)entry).get(predicate);
if (!map.hasExternalReference()){
Method setField = c.getMethod("set" + map.getClass_field(), Class.forName(map.getElement_type()));
//TODO: the current language seems not to support list of strings
if (map.getClass_field().equals("Description") ) {
setField.invoke(class_instance, values.stream().map(value -> {
return getFieldValue(value);
}).collect(Collectors.joining(" \n")));
}
else {
if(map.getClass_field().equals("OtherId")){
for (Object v : values) {
setField.invoke(class_instance, getFieldValue(v));
}
}
else {
setField.invoke(class_instance, getFieldValue(values.get(0)));
}
}
}
else{
if(propertiesMap.get(map.getExternal_reference()).getClass_type().equals("prototype")){
List<Object> value_list = new ArrayList<>();
for(Object value: values){
value_list.add(manage(ParseRDFJSON.get(getFieldValue(value)), map.getExternal_reference()));
}
Method setField = c.getMethod("set" + map.getClass_field(),List.class);
setField.invoke(class_instance, value_list);
}
else{
Class<?> ref = Class.forName(general_classpath + map.getExternal_reference());
Method setField = c.getMethod("set" + map.getClass_field(), ref);
setField.invoke(class_instance, manage (ParseRDFJSON.get(getFieldValue(values.get(0))),map.getExternal_reference()));
}
}
}
return class_instance;
}
public String getType_path() {
return type_path;
}
public void setType_path(String type_path) {
this.type_path = type_path;
}
public String getGeneral_classpath() {
return general_classpath;
}
public void setGeneral_classpath(String general_classpath) {
this.general_classpath = general_classpath;
}
public String getExclude_predicates() {
return exclude_predicates;
}
public void setExclude_predicates(String exclude_predicates) {
this.exclude_predicates = exclude_predicates;
}
public String getSpec() {
return spec;
}
public void setSpec(String spec) {
this.spec = spec;
}
}