2020-01-28 16:53:59 +01:00
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 ;
2021-04-02 12:46:07 +02:00
import java.util.stream.Collectors ;
2020-01-28 16:53:59 +01:00
import javax.annotation.PostConstruct ;
2020-06-10 19:39:53 +02:00
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 ;
2020-06-12 18:14:41 +02:00
import org.apache.commons.logging.Log ;
import org.apache.commons.logging.LogFactory ;
2020-01-28 16:53:59 +01:00
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 {
2020-06-12 18:14:41 +02:00
private static final Log log = LogFactory . getLog ( ResourceManager . class ) ;
2020-01-28 16:53:59 +01:00
@Value ( " ${type.path:undefined} " )
private String type_path ;
@Value ( " ${general.classpath:undefined} " )
private String general_classpath ;
@Value ( " ${exclude.predicates:[]} " )
private String exclude_predicates ;
2020-06-10 19:39:53 +02:00
@Value ( " ${class.map.specifications:undefined} " )
private String spec ;
2020-01-28 16:53:59 +01:00
private List < String > not_parsable ;
private ParseRDFJSON parser ;
2020-06-10 19:39:53 +02:00
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 ;
2020-06-16 02:36:16 +02:00
this . spec = spec ;
init ( ) ;
2020-06-10 19:39:53 +02:00
}
2020-01-28 16:53:59 +01:00
@PostConstruct
public void init ( ) {
Type listType = new TypeToken < ArrayList < String > > ( ) { } . getType ( ) ;
not_parsable = new Gson ( ) . fromJson ( exclude_predicates , listType ) ;
2020-06-12 18:14:41 +02:00
propertiesMap = new PropertiesMap ( ) ;
propertiesMap . fill ( spec ) ;
2020-01-28 16:53:59 +01:00
}
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 " ) ;
2020-10-12 18:32:56 +02:00
//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 " ) ) {
2021-06-15 23:34:59 +02:00
class_name = " AriadnePlusEntry " ;
2020-06-10 19:39:53 +02:00
}
2020-10-13 00:31:17 +02:00
2020-01-28 16:53:59 +01:00
}
}
2020-06-10 19:39:53 +02:00
if ( entry = = null ) {
2020-06-12 18:14:41 +02:00
return null ;
2020-06-10 19:39:53 +02:00
}
2020-01-28 16:53:59 +01:00
Class < ? > c = Class . forName ( general_classpath + class_name ) ;
Object class_instance = c . newInstance ( ) ;
2020-06-10 19:39:53 +02:00
ClassSpec class_spec = propertiesMap . get ( class_name ) ;
2020-01-28 16:53:59 +01:00
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 ( ) ) ) ;
2022-11-22 13:47:04 +01:00
//TODO: the current language seems not to support list of strings
if ( map . getClass_field ( ) . equals ( " Description " ) ) {
2021-04-02 12:46:07 +02:00
setField . invoke ( class_instance , values . stream ( ) . map ( value - > {
return getFieldValue ( value ) ;
} ) . collect ( Collectors . joining ( " \ n " ) ) ) ;
}
else {
2022-11-22 13:47:04 +01:00
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 ) ) ) ;
}
2021-04-02 12:46:07 +02:00
}
2020-01-28 16:53:59 +01:00
}
else {
2020-06-10 19:39:53 +02:00
if ( propertiesMap . get ( map . getExternal_reference ( ) ) . getClass_type ( ) . equals ( " prototype " ) ) {
2020-01-28 16:53:59 +01:00
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 ;
}
2020-06-12 18:14:41 +02:00
public String getType_path ( ) {
return type_path ;
}
public void setType_path ( String type_path ) {
this . type_path = type_path ;
}
2020-01-28 16:53:59 +01:00
2020-06-12 18:14:41 +02:00
public String getGeneral_classpath ( ) {
return general_classpath ;
}
2020-01-28 16:53:59 +01:00
2020-06-12 18:14:41 +02:00
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 ;
}
2020-01-28 16:53:59 +01:00
}