package org.wikier.trioo.jtrioo;
import java.io.Writer;
import java.util.ArrayList;
import java.util.List;
import org.apache.log4j.Logger;
import org.wikier.trioo.jtrioo.exceptions.MappingNotFoundException;
import org.wikier.trioo.jtrioo.generators.ConstructQueryGenerator;
import org.wikier.trioo.jtrioo.generators.DescribeQueryGenerator;
import org.wikier.trioo.jtrioo.generators.InsertQueryGenerator;
import org.wikier.trioo.jtrioo.generators.InstanceGenerator;
import org.wikier.trioo.jtrioo.generators.QueryCodeGenerator;
import org.wikier.trioo.jtrioo.generators.QueryGeneratorFactory;
import org.wikier.trioo.jtrioo.generators.SelectQueryGenerator;
import org.wikier.trioo.jtrioo.helpers.JenaHelper;
import org.wikier.trioo.jtrioo.helpers.URIUtils;
import org.wikier.trioo.jtrioo.rdf.AbbrevRdfType;
import org.wikier.trioo.jtrioo.rdf.CURIE;
import org.wikier.trioo.jtrioo.rdf.NamespacesManager;
import org.wikier.trioo.jtrioo.rdf.meta.MetaURI;
import org.wikier.trioo.jtrioo.rdf.meta.RDFMetaResource;
import org.wikier.trioo.jtrioo.rdf.sparql.QueryExecutor;
import org.wikier.trioo.jtrioo.rdf.sparql.SelectQuery;
import org.wikier.trioo.jtrioo.rdf.sparql.TriplePattern;
import org.wikier.trioo.jtrioo.rdf.sparql.Variable;
import com.hp.hpl.jena.query.QuerySolution;
import com.hp.hpl.jena.query.ResultSet;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.RDFNode;
/**
* Default implementation of the Resource Manager
*
* @author sergio.fernandez@fundacionctic.org
*
*/
public class ResourceManagerImpl implements ResourceManager {
private static final Logger logger = Logger.getLogger(ResourceManagerImpl.class);
private String name;
private Session session;
public ResourceManagerImpl() {
this("default");
}
public ResourceManagerImpl(String name) {
this.name = name;
this.session = SessionFactory.getSession();
}
public String getURI(Object resource) {
if (resource != null) {
RDFMetaResource metaResource = this.session.getMetaRDFResource(resource.getClass());
if (metaResource != null) {
MetaURI metauri = metaResource.getMetaUri();
logger.debug("Trying to generate URI for " + resource + " based on the metauri: " + metauri);
return (metauri == null ? null : metauri.getURI(resource));
} else {
logger.debug(resource.getClass() + " has not any URI generator defined");
return null;
}
} else {
return null;
}
}
public String getURI(Object resource, String base) {
if (resource != null) {
RDFMetaResource metaResource = this.session.getMetaRDFResource(resource.getClass());
if (metaResource != null) {
MetaURI metauri = metaResource.getMetaUri();
logger.debug("Trying to generate URI for " + resource + " based on the metauri: " + metauri);
return (metauri == null ? null : metauri.getURI(resource, base));
} else {
logger.debug(resource.getClass() + " has not any URI generator defined");
return null;
}
} else {
return null;
}
}
@SuppressWarnings("rawtypes")
public Object find(Class resourceClass, String uri) {
RDFMetaResource metaResource = this.session.getMetaRDFResource(resourceClass);
if (metaResource == null) {
return null;
} else {
SelectQueryGenerator sqg = QueryGeneratorFactory.createSelectQueryGenerator();
sqg.setUri(uri);
sqg.visit(metaResource);
QueryCodeGenerator qg = new QueryCodeGenerator();
qg.visit(sqg.getQuery());
QueryExecutor qe = this.session.getQueryExecutor();
ResultSet rs = qe.execSelect(qg.toString());
Object obj = null;
if (rs.hasNext()) {
obj = InstanceGenerator.create(resourceClass, rs.next());
}
rs = null; //FIXME: how a ResultSet can be closed?
String uriDeclared = this.getURI(obj);
if (uriDeclared!= null && !uri.equals(uriDeclared)) {
logger.warn("Requested URI (" + uri + ") doesn't match with the URI declared by the class (" + uriDeclared + ")");
}
return this.addInterceptions(obj, metaResource);
}
}
@SuppressWarnings("rawtypes")
public Object find(String uri) {
SelectQuery q = new SelectQuery();
Variable x = new Variable("x");
q.addTriplePattern(new TriplePattern(x, new AbbrevRdfType(), new Variable("type")));
q.addFilter("str(" + x.toString() +") = \"" + uri + "\"");
QueryCodeGenerator qg = new QueryCodeGenerator();
qg.visit(q);
QueryExecutor qe = this.session.getQueryExecutor();
ResultSet rs = qe.execSelect(qg.toString());
RDFMetaResource metaResource = new RDFMetaResource(Object.class);
while (rs.hasNext()) {
QuerySolution qs = rs.nextSolution();
RDFNode node = qs.get("type");
if (node.isURIResource()) {
String ns = URIUtils.getNamespace(node.toString());
String prefix = NamespacesManager.getInstance().getPrefix(ns);
if (prefix == null) {
throw new MappingNotFoundException("namespace " + ns);
}
CURIE curie = new CURIE(prefix, URIUtils.getReference(node.toString()));
metaResource.addRdfType(curie);
}
}
rs = null; //FIXME: how a ResultSet can be closed?
Class cls = this.session.getAssociatedClass(metaResource);
if (cls == null) {
return null;
} else {
return this.find(cls, uri);
}
}
@SuppressWarnings("rawtypes")
public Object[] findAll(Class resourceClass) {
RDFMetaResource metaResource = this.session.getMetaRDFResource(resourceClass);
if (metaResource == null) {
return new Object[]{};
} else {
SelectQueryGenerator sqg = QueryGeneratorFactory.createSelectQueryGenerator();
sqg.visit(metaResource);
QueryCodeGenerator qg = new QueryCodeGenerator();
qg.visit(sqg.getQuery());
QueryExecutor qe = this.session.getQueryExecutor();
ResultSet rs = qe.execSelect(qg.toString());
List<Object> objs = new ArrayList<Object>();
while (rs.hasNext()) {
objs.add(InstanceGenerator.create(resourceClass, rs.next()));
}
rs = null; //FIXME: how a ResultSet can be closed?
return objs.toArray();
}
}
public boolean persist(Object resource) {
if (resource == null) {
return false;
} else {
RDFMetaResource metaResource = this.session.getMetaRDFResource(resource.getClass());
if (metaResource == null) {
return false;
} else {
InsertQueryGenerator iqg = QueryGeneratorFactory.createInsertQueryGenerator();
iqg.visit(metaResource);
QueryCodeGenerator qg = new QueryCodeGenerator();
qg.visit(iqg.getQuery());
QueryExecutor qe = this.session.getQueryExecutor();
return qe.execInsert(qg.toString());
}
}
}
public boolean persist(Object resource, String uri) {
if (resource == null) {
return false;
} else {
RDFMetaResource metaResource = this.session.getMetaRDFResource(resource.getClass());
if (metaResource == null) {
return false;
} else {
InsertQueryGenerator iqg = QueryGeneratorFactory.createInsertQueryGenerator();
iqg.setUri(uri);
iqg.visit(metaResource);
QueryCodeGenerator qg = new QueryCodeGenerator();
qg.visit(iqg.getQuery());
QueryExecutor qe = this.session.getQueryExecutor();
return qe.execInsert(qg.toString());
}
}
}
public void refresh(Object resource) {
logger.warn("unimplemented");
}
public void remove(Object resource) {
logger.warn("unimplemented");
}
public String getName(String name) {
return this.name;
}
public void load(String uri) {
this.session.load(uri);
}
@SuppressWarnings("rawtypes")
public Model describe(Class cls) {
RDFMetaResource metaResource = this.session.getMetaRDFResource(cls);
if (metaResource == null) {
return JenaHelper.createModel();
} else {
ConstructQueryGenerator cqg = QueryGeneratorFactory.createConstructQueryGenerator();
cqg.visit(metaResource);
QueryCodeGenerator qcg = new QueryCodeGenerator();
qcg.visit(cqg.getQuery());
QueryExecutor qe = this.session.getQueryExecutor();
return qe.execConstruct(qcg.toString());
}
}
@SuppressWarnings("rawtypes")
public void serialize(Class cls, Writer writer) {
this.serialize(cls, writer, "RDF/XML");
}
@SuppressWarnings("rawtypes")
public void serialize(Class cls, Writer writer, String serialization) {
Model model = this.describe(cls);
model.write(writer, serialization);
}
public Model describe(String uri) {
DescribeQueryGenerator dqg = QueryGeneratorFactory.createDescribeQueryGenerator();
dqg.visit(uri);
QueryCodeGenerator qcg = new QueryCodeGenerator();
qcg.visit(dqg.getQuery());
QueryExecutor qe = this.session.getQueryExecutor();
return qe.execDescribe(qcg.toString());
}
public Model describe(Object resource) {
// if (this.persist(resource)) {
// return this.describe(this.getURI(resource));
// } else {
// return JenaHelper.createModel();
// }
if (resource != null) {
RDFMetaResource metaResource = this.session.getMetaRDFResource(resource.getClass());
if (metaResource == null) {
return JenaHelper.createModel();
} else {
InsertQueryGenerator iqg = QueryGeneratorFactory.createInsertQueryGenerator();
iqg.setResourceManager(this);
iqg.setObj(resource);
iqg.visit(metaResource);
QueryCodeGenerator qcg = new QueryCodeGenerator();
qcg.visit(iqg.getQuery());
QueryExecutor qe = this.session.getQueryExecutor();
Model model = JenaHelper.createModel();
return qe.execInsert(qcg.toString(), model);
}
} else {
return JenaHelper.createModel();
}
}
public Model describe(Object resource, String uri) {
// if (this.persist(resource)) {
// return this.describe(uri);
// } else {
// return JenaHelper.createModel();
// }
if (resource != null) {
RDFMetaResource metaResource = this.session.getMetaRDFResource(resource.getClass());
if (metaResource == null) {
return JenaHelper.createModel();
} else {
InsertQueryGenerator iqg = QueryGeneratorFactory.createInsertQueryGenerator();
iqg.setResourceManager(this);
iqg.setObj(resource);
iqg.setUri(uri);
iqg.visit(metaResource);
QueryCodeGenerator qcg = new QueryCodeGenerator();
qcg.visit(iqg.getQuery());
QueryExecutor qe = this.session.getQueryExecutor();
Model model = JenaHelper.createModel();
return qe.execInsert(qcg.toString(), model);
}
} else {
return JenaHelper.createModel();
}
}
public void serialize(Object resource, Writer writer) {
this.serialize(resource, writer, "RDF/XML");
}
public void serialize(Object resource, Writer writer, String serialization) {
Model model = this.describe(resource);
model.write(writer, serialization);
}
private Object addInterceptions(Object obj, RDFMetaResource metaResource) {
// SessionMethodInterceptor interceptor = new SessionMethodInterceptor(this.session, obj);
// Enhancer enhacer = new Enhancer();
// enhacer.setSuperclass(obj.getClass());
// enhacer.setCallback(interceptor);
// return enhacer.create();
return obj;
}
}