All Downloads are FREE. Search and download functionalities are using the official Maven repository.

de.naturzukunft.rdf4j.ommapper.ModelCreator Maven / Gradle / Ivy

package de.naturzukunft.rdf4j.ommapper;

import static org.eclipse.rdf4j.model.util.Values.iri;
import static org.eclipse.rdf4j.model.util.Values.literal;

import java.io.StringWriter;
import java.lang.reflect.Field;
import java.math.BigInteger;
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;

import javax.xml.datatype.DatatypeConfigurationException;
import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.XMLGregorianCalendar;

import org.apache.commons.lang3.ClassUtils;
import org.eclipse.rdf4j.model.IRI;
import org.eclipse.rdf4j.model.Model;
import org.eclipse.rdf4j.model.Namespace;
import org.eclipse.rdf4j.model.util.ModelBuilder;
import org.eclipse.rdf4j.model.vocabulary.RDF;
import org.eclipse.rdf4j.rio.RDFFormat;
import org.eclipse.rdf4j.rio.Rio;

import lombok.extern.slf4j.Slf4j;

@Slf4j
public class ModelCreator  {
	
	private T object;

	public ModelCreator(T object) {
		this.object = object;
		
	}
		
	public Model toModel(Namespace...namespace) {
		List submodels = new ArrayList<>();
		if(object.getSubject()==null) {
			throw new RuntimeException("subject is mandatory!");
		}
		ModelBuilder modelBuilder = new ModelBuilder();
		for (Namespace ns : namespace) {
			modelBuilder.setNamespace(ns);
		}
		List fields = getFields(object.getClass());
		
		for (Field field : fields) {
			field.setAccessible(true);
			Object value;
			try {
				value = field.get(object);
			} catch (Exception e) {
				throw new RuntimeException("error getting value of field " + field.getName(), e);
			}
			if(value!=null) {
				Iri iri = field.getAnnotation(Iri.class);
				if(iri!=null) {
					if(value instanceof Collection) {
						((Collection) value).forEach(item->modelBuilder.add(object.getSubject(), iri(iri.value()), item));
					} else if(isLiteral(value.getClass())){
						modelBuilder.add(object.getSubject(), iri(iri.value()), value);
					} else if(isIri(value)) {
						modelBuilder.add(object.getSubject(), iri(iri.value()), value);
					}  else if(value instanceof Duration) {
						try {
							javax.xml.datatype.Duration duration = DatatypeFactory.newInstance().newDuration(((Duration)value).toMillis());
							modelBuilder.add(object.getSubject(), iri(iri.value()), literal(duration.toString()));
						} catch (DatatypeConfigurationException e) {
							log.error("cannot convert duration '"+value.toString()+"'. ignoring it!", e);
						}					
					} else if(value instanceof LocalDateTime) {
						try {
							XMLGregorianCalendar xmlDateTime = DatatypeFactory.newInstance().newXMLGregorianCalendar(((LocalDateTime)value).format(DateTimeFormatter.ISO_DATE_TIME));
							modelBuilder.add(object.getSubject(), iri(iri.value()), literal(xmlDateTime.toString()));
						} catch (DatatypeConfigurationException e) {
							log.error("error converting dateTime: " + value, e);
						}
					} else if(BaseObject.class.isInstance(value)) 
					{
						ModelCreator creator = new ModelCreator((BaseObject)value);						
						submodels.add(creator.toModel());
						modelBuilder.add(object.getSubject(), iri(iri.value()), ((BaseObject)value).getSubject());
					} else {
						log.error("unknown field " + field);
					}					
				}
			} else {
				if(field.getAnnotation(NonNull.class)!=null) {
					throw new NonNullException(field.getName()  + " is annotated with NonNull, but is null!");
				}
			}
		}
		Model result = modelBuilder.build();
		if(result.filter(null, RDF.TYPE, null).size() < 1) {
			
			StringWriter sw = new StringWriter();
			Rio.write(result, sw, RDFFormat.TURTLE );			
			log.error("error processing: \n" + sw.toString());
			throw new RuntimeException(RDF.TYPE + " is mandatory! ("+object.getClass().getName()+")");
		}
		submodels.forEach(sub->result.addAll(sub));
		return result;
	}
	
	private List getFields(Class cls) {
//		return Arrays.asList(object.getClass().getDeclaredFields());
		return getAllFields(new LinkedList(), cls);
	}

	private List getAllFields(List fields, Class type) {
	    fields.addAll(Arrays.asList(type.getDeclaredFields()));

	    if (type.getSuperclass() != null) {
	        getAllFields(fields, type.getSuperclass());
	    }

	    return fields;
	}

	private boolean isIri(Object value) {
		return IRI.class.isInstance(value);
	}
	
	private boolean isLiteral(Class cls) {
		return ClassUtils.isPrimitiveOrWrapper(cls) || BigInteger.class.equals(cls) || String.class.equals(cls);
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy