|
@@ -0,0 +1,213 @@
|
|
|
+package r2rml;
|
|
|
+
|
|
|
+import java.io.File;
|
|
|
+import java.io.FileOutputStream;
|
|
|
+import java.io.IOException;
|
|
|
+import java.io.OutputStream;
|
|
|
+import java.net.URLEncoder;
|
|
|
+import java.sql.Connection;
|
|
|
+import java.sql.DriverManager;
|
|
|
+import java.sql.ResultSet;
|
|
|
+import java.util.ArrayList;
|
|
|
+import java.util.List;
|
|
|
+import java.util.Properties;
|
|
|
+
|
|
|
+import org.apache.commons.cli.CommandLine;
|
|
|
+import org.apache.commons.cli.CommandLineParser;
|
|
|
+import org.apache.commons.cli.DefaultParser;
|
|
|
+import org.apache.commons.cli.HelpFormatter;
|
|
|
+import org.apache.commons.cli.Options;
|
|
|
+import org.apache.commons.cli.ParseException;
|
|
|
+import org.apache.commons.io.FilenameUtils;
|
|
|
+import org.apache.jena.rdf.model.Model;
|
|
|
+import org.apache.jena.rdf.model.ModelFactory;
|
|
|
+import org.apache.jena.rdf.model.Resource;
|
|
|
+import org.apache.jena.rdf.model.ResourceFactory;
|
|
|
+import org.apache.jena.riot.Lang;
|
|
|
+import org.apache.jena.riot.RDFDataMgr;
|
|
|
+import org.apache.log4j.Logger;
|
|
|
+
|
|
|
+public class GenerateMapping {
|
|
|
+
|
|
|
+ private static Logger logger = Logger.getLogger(GenerateMapping.class.getName());
|
|
|
+
|
|
|
+ private static File csvFile = null;
|
|
|
+ private static File conFile = null;
|
|
|
+ private static File mapFile = null;
|
|
|
+
|
|
|
+ private static String NS = "http://adaptcentre.ie/ont/odef#";
|
|
|
+ private static Resource Record = ResourceFactory.createResource(NS + "Record");
|
|
|
+
|
|
|
+ private static Model mapping = ModelFactory.createDefaultModel();
|
|
|
+
|
|
|
+ public static void main(String[] args) {
|
|
|
+
|
|
|
+ try {
|
|
|
+ parseArguments(args);
|
|
|
+
|
|
|
+ createMappingFromCSVFile();
|
|
|
+
|
|
|
+ writeMappingFile();
|
|
|
+
|
|
|
+ writeConfigurationFile();
|
|
|
+ } catch (Exception e) {
|
|
|
+ logger.error(e.getMessage());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private static void createMappingFromCSVFile() throws GenMapException {
|
|
|
+ try {
|
|
|
+ String CSV = csvFile.getCanonicalPath() + "#";
|
|
|
+
|
|
|
+ mapping = ModelFactory.createDefaultModel();
|
|
|
+ mapping.setNsPrefix("rr", R2RML.NS);
|
|
|
+ mapping.setNsPrefix("odef", NS);
|
|
|
+ mapping.setNsPrefix("csv", CSV);
|
|
|
+
|
|
|
+ Resource triplesmap = mapping.createResource("#TriplesMap");
|
|
|
+
|
|
|
+ // create the TriplesMap with the logical table
|
|
|
+ Resource lt = mapping.createResource();
|
|
|
+ mapping.add(triplesmap, R2RML.logicalTable, lt);
|
|
|
+ String name = createTableNameForFile(csvFile);
|
|
|
+ mapping.add(lt, R2RML.sqlQuery, "SELECT rownum() AS ROW_NUM, * FROM " + name + ";");
|
|
|
+
|
|
|
+ // create the SubjectMap
|
|
|
+ Resource sm = mapping.createResource();
|
|
|
+ mapping.add(triplesmap, R2RML.subjectMap, sm);
|
|
|
+ mapping.add(sm, R2RML.template, "http://www.example.org/record/{ROW_NUM}");
|
|
|
+ mapping.add(sm, R2RML.clazz, Record);
|
|
|
+
|
|
|
+ for(String cname : getColumnNames()) {
|
|
|
+ // create PredicateObjectMaps
|
|
|
+ Resource pom = mapping.createResource();
|
|
|
+ mapping.add(triplesmap, R2RML.predicateObjectMap, pom);
|
|
|
+ Resource predicate = mapping.createResource(CSV + URLEncoder.encode(cname, "UTF-8"));
|
|
|
+ mapping.add(pom, R2RML.predicate, predicate);
|
|
|
+
|
|
|
+ Resource om = mapping.createResource();
|
|
|
+ mapping.add(pom, R2RML.objectMap, om);
|
|
|
+ mapping.add(om, R2RML.column, cname);
|
|
|
+ }
|
|
|
+
|
|
|
+ } catch (Exception e) {
|
|
|
+ throw new GenMapException("Problem processing CSV file: " + e .getMessage(), e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private static List<String> getColumnNames() throws GenMapException {
|
|
|
+ List<String> columnNames = new ArrayList<String>();
|
|
|
+
|
|
|
+ try {
|
|
|
+ String connectionURL = "jdbc:h2:mem:" + System.currentTimeMillis();
|
|
|
+ DriverManager.getConnection(connectionURL + ";create=true").close();
|
|
|
+
|
|
|
+ Connection connection = DriverManager.getConnection(connectionURL);
|
|
|
+ java.sql.Statement statement = connection.createStatement();
|
|
|
+
|
|
|
+ String sql = "SELECT rownum() AS ROW_NUM, * FROM CSVREAD('" + csvFile.getAbsolutePath() + "', NULL, NULL) LIMIT 1;";
|
|
|
+ ResultSet rs = statement.executeQuery(sql);
|
|
|
+ for(int i = 1; i <= rs.getMetaData().getColumnCount(); i++) {
|
|
|
+ columnNames.add(rs.getMetaData().getColumnName(i));
|
|
|
+ }
|
|
|
+
|
|
|
+ statement.close();
|
|
|
+ connection.close();
|
|
|
+ } catch(Exception e){
|
|
|
+ throw new GenMapException("Problem processing CSV file: " + e .getMessage(), e);
|
|
|
+ }
|
|
|
+
|
|
|
+ return columnNames;
|
|
|
+ }
|
|
|
+
|
|
|
+ private static void writeMappingFile() throws GenMapException {
|
|
|
+ try {
|
|
|
+ mapFile.createNewFile();
|
|
|
+ RDFDataMgr.write(new FileOutputStream(mapFile), mapping, Lang.TURTLE);
|
|
|
+ } catch (IOException e) {
|
|
|
+ throw new GenMapException("Problem writing R2RML mapping file: " + e .getMessage(), e);
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ private static void writeConfigurationFile() throws GenMapException {
|
|
|
+ Properties prop = new Properties();
|
|
|
+ prop.setProperty("CSVFiles", csvFile.toString());
|
|
|
+ prop.setProperty("mappingFile", mapFile.toString());
|
|
|
+ prop.setProperty("outputFile", csvFile.toString() + ".ttl");
|
|
|
+ prop.setProperty("format", "TURTLE");
|
|
|
+
|
|
|
+ OutputStream out = null;
|
|
|
+
|
|
|
+ try {
|
|
|
+ out = new FileOutputStream(conFile);
|
|
|
+ prop.store(out, "Generated with the generate-mapping tool.");
|
|
|
+ } catch (IOException e) {
|
|
|
+ throw new GenMapException("Error writing config file: " + e.getMessage(), e);
|
|
|
+ } finally {
|
|
|
+ if (out != null) {
|
|
|
+ try {
|
|
|
+ out.close();
|
|
|
+ } catch (IOException e) {
|
|
|
+ throw new GenMapException("Error closing config file: " + e.getMessage(), e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private static String createTableNameForFile(File file) {
|
|
|
+ String name = FilenameUtils.getBaseName(file.getAbsolutePath());
|
|
|
+ return name;
|
|
|
+ }
|
|
|
+
|
|
|
+ private static void parseArguments(String[] args) throws GenMapException {
|
|
|
+ Options options = new Options();
|
|
|
+ options.addOption("f", true, "The CSV file for which a R2RML mapping will be generated.");
|
|
|
+ options.addOption("c", true, "The filename for the R2RML configuration file (default = config.properties).");
|
|
|
+ options.addOption("m", true, "The filename for the R2RML mapping file (default = mapping.ttl).");
|
|
|
+ options.addOption("h", false, "Display help.");
|
|
|
+
|
|
|
+ try {
|
|
|
+ CommandLineParser parser = new DefaultParser();
|
|
|
+ CommandLine cmd = parser.parse(options, args);
|
|
|
+
|
|
|
+ // Display help
|
|
|
+ if(cmd.hasOption("h")) {
|
|
|
+ HelpFormatter formatter = new HelpFormatter();
|
|
|
+ formatter.printHelp("generate-mapping.jar", options);
|
|
|
+ System.exit(0);
|
|
|
+ }
|
|
|
+
|
|
|
+ String csv = null, con = null, map = null;
|
|
|
+
|
|
|
+ // Process CSV file
|
|
|
+ if(cmd.hasOption("f")) {
|
|
|
+ csv = cmd.getOptionValue("f");
|
|
|
+ logger.info("Using CSV file " + csv);
|
|
|
+ } else {
|
|
|
+ throw new GenMapException("Providing a CSV file is mandatory.");
|
|
|
+ }
|
|
|
+
|
|
|
+ csvFile = new File(csv);
|
|
|
+
|
|
|
+ if(!csvFile.exists()) {
|
|
|
+ throw new GenMapException("CSV file does not exist.");
|
|
|
+ }
|
|
|
+
|
|
|
+ // Process config file
|
|
|
+ con = cmd.getOptionValue("c", "config.properties");
|
|
|
+ logger.info("Using R2RML config file " + con);
|
|
|
+ conFile = new File(con);
|
|
|
+
|
|
|
+ // Process mapping file
|
|
|
+ map = cmd.getOptionValue("m", "mapping.ttl");
|
|
|
+ logger.info("Using R2RML mapping file " + map);
|
|
|
+ mapFile = new File(map);
|
|
|
+
|
|
|
+ } catch(ParseException e) {
|
|
|
+ throw new GenMapException("Parsing failed. Reason: " + e.getMessage(), e);
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+}
|