package jp.ac.osaka_u.sanken.sparql.edit; import java.util.ArrayList; import java.util.List; import org.openrdf.repository.RepositoryConnection; import com.franz.agraph.jena.AGGraph; import com.franz.agraph.jena.AGGraphMaker; import com.franz.agraph.jena.AGModel; import com.franz.agraph.repository.AGCatalog; import com.franz.agraph.repository.AGRepository; import com.franz.agraph.repository.AGRepositoryConnection; import com.franz.agraph.repository.AGServer; import com.hp.hpl.jena.rdf.model.Model; import com.hp.hpl.jena.rdf.model.Property; import com.hp.hpl.jena.rdf.model.RDFNode; import com.hp.hpl.jena.rdf.model.Resource; import com.hp.hpl.jena.rdf.model.impl.PropertyImpl; import jp.ac.osaka_u.sanken.sparql.AllegroAccessor; /** * SparqlEndpointとして公開されているAllegroGraphのRepositoryに対して編集を行うためのクラス * @author kato * */ public class AllegroEditor { private AllegroAccessor accessor; private String user; private String pass; private String url; private String repository; public AllegroEditor(AllegroAccessor sa, String user, String pass) throws Exception{ this.accessor = sa; this.user = user; this.pass = pass; init(); } public AllegroEditor(AllegroAccessor sa, String url, String repo, String user, String pass) throws Exception{ this.accessor = sa; this.url = url; this.repository = repo; this.user = user; this.pass = pass; try { getModel(); } catch(Exception e){ throw new Exception("AllegroGraphのrepository設定が不正です", e); } } private void init() throws Exception { String endpoint = this.accessor.getSetting().getEndpoint(); int index = endpoint.indexOf("/endpoint/"); if (index >= 0){ this.url = endpoint.substring(0, index); this.repository = endpoint.substring(index + "/endpoint/".length()); System.out.println("url:"+url); System.out.println("repo:"+repository); } else { throw new Exception("AllegroGraphサーバではありません"); } } public AllegroAccessor getAccessor(){ return this.accessor; } /** * 破棄時にcloseする */ public void close(){ closeAll(); } public boolean contains(RDFNode s, RDFNode p, RDFNode o) throws Exception{ Model model = getModel(); return contains(s, p, o, model); } private boolean isTriple(RDFNode s, RDFNode p, RDFNode o){ if (!s.isResource()){ return false; } if (!p.isResource()){ return false; } return true; } private boolean contains(RDFNode s, RDFNode p, RDFNode o, Model model){ if (!isTriple(s, p, o)){ return false; } Resource ss = s.asResource(); Property pp = new PropertyImpl(p.asResource().getURI()); return model.contains(ss, pp, o); } public boolean add(RDFNode s, RDFNode p, String o) throws Exception{ Model model = getModel(); RDFNode oo = model.createLiteral(o); return add(s, p, oo, model); } public boolean add(RDFNode s, RDFNode p, RDFNode o) throws Exception{ Model model = getModel(); return add(s, p, o, model); } private boolean add(RDFNode s, RDFNode p, RDFNode o, Model model){ if (!isTriple(s, p, o)){ return false; } Resource ss = s.asResource(); Property pp = new PropertyImpl(p.asResource().getURI()); if (!model.contains(ss, pp, o)){ model.add(ss, pp, o); return true; } return false; } public boolean delete(RDFNode s, RDFNode p, RDFNode o) throws Exception{ Model model = getModel(); return delete(s, p, o, model); } private boolean delete(RDFNode s, RDFNode p, RDFNode o, Model model){ if (!isTriple(s, p, o)){ return false; } Resource ss = s.asResource(); Property pp = new PropertyImpl(p.asResource().getURI()); if (model.contains(ss, pp, o)){ model.remove(ss, pp, o); return true; } return false; } public boolean edit(RDFNode s, RDFNode p, RDFNode o, RDFNode s2, RDFNode p2, RDFNode o2) throws Exception{ Model model = getModel(); return edit(s, p, o, s2, p2, o2, model); } private boolean edit(RDFNode s, RDFNode p, RDFNode o, RDFNode s2, RDFNode p2, RDFNode o2, Model model){ if (!isTriple(s, p, o) || !isTriple(s2, p2, o2)){ return false; } Resource ss = s.asResource(); Property pp = new PropertyImpl(p.asResource().getURI()); Resource ss2 = s2.asResource(); Property pp2 = new PropertyImpl(p2.asResource().getURI()); if (model.contains(ss, pp, o)){ model.remove(ss, pp, o); model.add(ss2, pp2, o2); return true; } return false; } public Model getModel() throws Exception { AGServer server = new AGServer(this.url, this.user, this.pass); AGCatalog catalog = server.getCatalog("/"); AGRepository myRepository = catalog.openRepository(this.repository); AGRepositoryConnection conn = myRepository.getConnection(); closeBeforeExit(conn); AGGraphMaker maker = new AGGraphMaker(conn); AGGraph graph = maker.getGraph(); AGModel model = new AGModel(graph); closeBeforeExit(myRepository, model); return model; } private void closeBeforeExit(AGRepository rep, AGModel model) { toCloseRep.add(rep); toCloseModel.add(model); } protected void closeAll() { while (toCloseRep.isEmpty() == false) { AGRepository conn = toCloseRep.get(0); close(conn); while (toCloseRep.remove(conn)) { } } while (toCloseModel.isEmpty() == false) { AGModel conn = toCloseModel.get(0); close(conn); while (toCloseModel.remove(conn)) { } } while (toClose.isEmpty() == false) { RepositoryConnection conn = toClose.get(0); close(conn); while (toClose.remove(conn)) { } } } static void close(RepositoryConnection conn) { try { conn.close(); } catch (Exception e) { System.err.println("Error closing repository connection: " + e); e.printStackTrace(); } } void close(AGRepository conn) { try { conn.shutDown(); } catch (Exception e) { System.err.println("Error closing repository repository: " + e); e.printStackTrace(); } } void close(AGModel conn) { try { conn.close(); } catch (Exception e) { System.err.println("Error closing repository model: " + e); e.printStackTrace(); } } private static List toClose = new ArrayList(); private static List toCloseRep = new ArrayList(); private static List toCloseModel = new ArrayList(); private static void closeBeforeExit(RepositoryConnection conn) { toClose.add(conn); } }