001package conexp.fx.core.importer; 002 003/* 004 * #%L 005 * Concept Explorer FX 006 * %% 007 * Copyright (C) 2010 - 2023 Francesco Kriegel 008 * %% 009 * This program is free software: you can redistribute it and/or modify 010 * it under the terms of the GNU General Public License as 011 * published by the Free Software Foundation, either version 3 of the 012 * License, or (at your option) any later version. 013 * 014 * This program is distributed in the hope that it will be useful, 015 * but WITHOUT ANY WARRANTY; without even the implied warranty of 016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 017 * GNU General Public License for more details. 018 * 019 * You should have received a copy of the GNU General Public 020 * License along with this program. If not, see 021 * <http://www.gnu.org/licenses/gpl-3.0.html>. 022 * #L% 023 */ 024 025import java.io.File; 026import java.io.IOException; 027import java.io.InputStream; 028import java.net.URL; 029import java.net.URLEncoder; 030import java.nio.file.Files; 031import java.util.ArrayList; 032import java.util.HashSet; 033import java.util.List; 034import java.util.Set; 035import java.util.stream.Collectors; 036 037import org.openrdf.model.Statement; 038import org.openrdf.model.ValueFactory; 039import org.openrdf.model.impl.StatementImpl; 040import org.openrdf.model.impl.ValueFactoryImpl; 041import org.openrdf.model.vocabulary.RDF; 042import org.openrdf.query.BindingSet; 043import org.openrdf.query.MalformedQueryException; 044import org.openrdf.query.QueryEvaluationException; 045import org.openrdf.query.QueryLanguage; 046import org.openrdf.query.QueryResultHandlerException; 047import org.openrdf.query.TupleQueryResultHandler; 048import org.openrdf.query.TupleQueryResultHandlerException; 049import org.openrdf.query.resultio.QueryResultParseException; 050import org.openrdf.query.resultio.sparqlxml.SPARQLResultsXMLParser; 051import org.openrdf.repository.Repository; 052import org.openrdf.repository.RepositoryConnection; 053import org.openrdf.repository.RepositoryException; 054import org.openrdf.repository.sail.SailRepository; 055import org.openrdf.rio.RDFFormat; 056import org.openrdf.rio.RDFParseException; 057import org.openrdf.sail.memory.MemoryStore; 058//import org.semanticweb.owlapi.model.IRI; 059 060import conexp.fx.core.collections.Pair; 061import conexp.fx.core.collections.setlist.HashSetArrayList; 062import conexp.fx.core.collections.setlist.SetList; 063import conexp.fx.core.context.MatrixContext; 064//import conexp.fx.core.dl.Signature; 065 066public class RDFImporter { 067 068 public static final void readCSV(final Repository repository, final File file) 069 throws RepositoryException, RDFParseException, IOException { 070 final RepositoryConnection connection = repository.getConnection(); 071 final ValueFactory f = new ValueFactoryImpl(); 072 Files 073 .lines(file.toPath()) 074 .map(line -> line.split(";")) 075 .map( 076 tuple -> new StatementImpl( 077 f.createURI(file.getName() + ":", tuple[0]), 078 f.createURI(file.getName() + ":", tuple[1]), 079 f.createURI(file.getName() + ":", tuple[2]))) 080 .forEach(statement -> { 081 try { 082 connection.add(statement); 083 } catch (RepositoryException e) { 084 throw new RuntimeException(e); 085 } 086 }); 087 connection.commit(); 088 connection.close(); 089 } 090 091 public static final Repository read(final File file) throws RepositoryException, RDFParseException, IOException { 092 final Repository repository = new SailRepository(new MemoryStore()); 093 read(repository, file); 094 return repository; 095 } 096 097 public static final void read(final Repository repository, final File file) 098 throws RepositoryException, RDFParseException, IOException { 099 final RepositoryConnection connection = repository.getConnection(); 100 connection.add(file, null, RDFFormat.forFileName(file.getName(), RDFFormat.RDFXML)); 101 connection.commit(); 102 connection.close(); 103 } 104 105 public static final Repository read(final URL url) throws RepositoryException, RDFParseException, IOException { 106 final Repository repository = new SailRepository(new MemoryStore()); 107 read(repository, url); 108 return repository; 109 } 110 111 public static final void read(final Repository repository, final URL url) 112 throws RepositoryException, RDFParseException, IOException { 113 final RepositoryConnection connection = repository.getConnection(); 114 connection.add(url, null, RDFFormat.forFileName(url.toString(), RDFFormat.RDFXML)); 115 connection.commit(); 116 connection.close(); 117 } 118 119 private static final class ContextTupleQueryResultHandler implements TupleQueryResultHandler { 120 121 private final MatrixContext<String, String> context; 122 private boolean objectTuples = true; 123 private boolean attributeTuples = true; 124 private final List<String> objectBindingNames = new ArrayList<String>(); 125 private final List<String> attributeBindingNames = new ArrayList<String>(); 126 private final SetList<String> objects = new HashSetArrayList<String>(); 127 private final SetList<String> attributes = new HashSetArrayList<String>(); 128 private final Set<Pair<String, String>> crosses = new HashSet<Pair<String, String>>(); 129 130 private ContextTupleQueryResultHandler(final MatrixContext<String, String> context) { 131 this.context = context; 132// context.lock(); 133 context.rowHeads().add("null"); 134 context.colHeads().add("null"); 135 } 136 137 public void handleBoolean(final boolean value) throws QueryResultHandlerException { 138 System.out.println("handle boolean " + value); 139 } 140 141 public void handleLinks(final List<String> linkUrls) throws QueryResultHandlerException { 142 System.out.println("handle links " + linkUrls); 143 } 144 145 public final void startQueryResult(final List<String> bindingNames) throws TupleQueryResultHandlerException { 146 for (String bindingName : bindingNames) 147 if (bindingName.toLowerCase().startsWith("object")) 148 objectBindingNames.add(bindingName); 149 else if (bindingName.toLowerCase().startsWith("attribute")) 150 attributeBindingNames.add(bindingName); 151 if (objectBindingNames.size() == 1) 152 objectTuples = false; 153 if (attributeBindingNames.size() == 1) 154 attributeTuples = false; 155 } 156 157 public final void endQueryResult() throws TupleQueryResultHandlerException { 158 System.out.println("adding " + objects.size() + " objects"); 159 context.rowHeads().addAll(0, objects); 160 System.out.println("adding " + attributes.size() + " attributes"); 161 context.colHeads().addAll(0, attributes); 162 context.rowHeads().remove("null"); 163 context.colHeads().remove("null"); 164 System.out.println("adding " + crosses.size() + " crosses"); 165 for (Pair<String, String> p : crosses) 166 context.addFastSilent(p.x(), p.y()); 167 // context.unlock(); 168 context.pushAllChangedEvent(); 169 } 170 171 public final void handleSolution(final BindingSet bindingSet) throws TupleQueryResultHandlerException { 172 String object = "", attribute = ""; 173 if (objectTuples) { 174 for (String objectBindingName : objectBindingNames) 175 object += bindingSet.getBinding(objectBindingName).getValue().stringValue() + "; "; 176 object = object.substring(0, object.length() - 2); 177 } else 178 object = bindingSet.getBinding(objectBindingNames.get(0)).getValue().stringValue(); 179 if (attributeTuples) { 180 for (String attributeBindingName : attributeBindingNames) 181 attribute += bindingSet.getBinding(attributeBindingName).getValue().stringValue() + "; "; 182 attribute = attribute.substring(0, attribute.length() - 2); 183 } else 184 attribute = bindingSet.getBinding(attributeBindingNames.get(0)).getValue().stringValue(); 185 objects.add(object); 186 attributes.add(attribute); 187 crosses.add(Pair.of(object, attribute)); 188 } 189 } 190 191 public static void importXML(final MatrixContext<String, String> context, String url, String query) { 192 try { 193 final SPARQLResultsXMLParser parser = new SPARQLResultsXMLParser(); 194 parser.setTupleQueryResultHandler(new ContextTupleQueryResultHandler(context)); 195 final String queryURL = new String(url).replace("<QUERY>", URLEncoder.encode(query, "UTF-8")); 196 System.out.println("reading " + queryURL); 197 final InputStream stream = new URL(queryURL).openStream(); 198 System.out.println("parsing results"); 199 parser.parseQueryResult(stream); 200 System.out.println("parse done"); 201 } catch (QueryResultParseException | QueryResultHandlerException | IOException e) { 202 e.printStackTrace(); 203 } 204 } 205 206 public static void importRepository(MatrixContext<String, String> context, Repository repo, String query) { 207 try { 208 final RepositoryConnection connection = repo.getConnection(); 209 connection.prepareTupleQuery(QueryLanguage.SPARQL, query).evaluate(new ContextTupleQueryResultHandler(context)); 210 connection.close(); 211 } catch (QueryEvaluationException | RepositoryException | MalformedQueryException 212 | TupleQueryResultHandlerException e) { 213 e.printStackTrace(); 214 } 215 } 216 217 public static void importFile(MatrixContext<String, String> context, File file, String query) { 218 try { 219 importRepository(context, read(file), query); 220 } catch (RepositoryException | RDFParseException | IOException e) { 221 e.printStackTrace(); 222 } 223 } 224 225 public static void importURL(MatrixContext<String, String> context, String url, String query) { 226 try { 227 importRepository(context, read(new URL(url)), query); 228 } catch (RepositoryException | RDFParseException | IOException e) { 229 e.printStackTrace(); 230 } 231 } 232 233// public static final OWLInterpretation extractInterpretation(final List<Statement> triples) { 234// return extractInterpretation(triples, IRI.create(RDF.TYPE.stringValue())); 235// } 236// 237// public static final OWLInterpretation 238// extractInterpretation(final List<Statement> triples, final IRI selectedIsARoleName) { 239// final List<IRI> roleNames = 240// triples.parallelStream().map(triple -> IRI.create(triple.getPredicate().stringValue())).distinct().collect( 241// Collectors.toList()); 242// if (!roleNames.contains(selectedIsARoleName)) 243// throw new IllegalArgumentException(); 244// roleNames.remove(selectedIsARoleName); 245// final List<IRI> conceptNames = triples 246// .parallelStream() 247// .filter(triple -> IRI.create(triple.getPredicate().stringValue()).equals(selectedIsARoleName)) 248// .map(triple -> IRI.create(triple.getObject().stringValue())) 249// .collect(Collectors.toList()); 250// return extractInterpretation(triples, conceptNames, roleNames, selectedIsARoleName); 251// } 252// 253// public static final OWLInterpretation extractInterpretation( 254// final List<Statement> triples, 255// final List<IRI> selectedConceptNames, 256// final List<IRI> selectedRoleNames, 257// final IRI selectedIsARoleName) { 258// final Signature signature = new Signature(null); 259// signature.getConceptNames().addAll(selectedConceptNames); 260// signature.getRoleNames().addAll(selectedRoleNames); 261// signature.getIndividualNames().addAll( 262// triples 263// .parallelStream() 264// .filter( 265// triple -> IRI.create(triple.getPredicate().stringValue()).equals(selectedIsARoleName) 266// && signature.getConceptNames().contains(IRI.create(triple.getObject().stringValue()))) 267// .map(triple -> IRI.create(triple.getSubject().stringValue())) 268// .collect(Collectors.toSet())); 269// final OWLInterpretation i = new OWLInterpretation(signature); 270// triples.stream().forEach(triple -> { 271// if (IRI.create(triple.getPredicate().stringValue()).equals(selectedIsARoleName)) { 272// if (signature.getConceptNames().contains(IRI.create(triple.getObject().stringValue())) 273// && signature.getIndividualNames().contains(IRI.create(triple.getSubject().stringValue()))) { 274// i.addConceptNameAssertion( 275// IRI.create(triple.getObject().stringValue()), 276// IRI.create(triple.getSubject().stringValue())); 277// } 278// } else if (signature.getRoleNames().contains(IRI.create(triple.getPredicate().stringValue())) 279// && signature.getIndividualNames().contains(IRI.create(triple.getSubject().stringValue())) 280// && signature.getIndividualNames().contains(IRI.create(triple.getObject().stringValue()))) { 281// i.addRoleNameAssertion( 282// IRI.create(triple.getPredicate().stringValue()), 283// IRI.create(triple.getSubject().stringValue()), 284// IRI.create(triple.getObject().stringValue())); 285// } 286// }); 287// return i; 288// } 289 290}