diff --git a/build.sbt b/build.sbt new file mode 100644 index 0000000..6332782 --- /dev/null +++ b/build.sbt @@ -0,0 +1,13 @@ +name := "RdfDiff" + +version := "1.2" + +scalaVersion := "2.12.4" + +// scalacOptions += "-target:jvm-1.6" + +libraryDependencies ++= Seq( + "org.apache.jena" % "jena-arq" % "3.6.0", + "com.github.scopt" %% "scopt" % "3.7.0" +) + diff --git a/project/build.properties b/project/build.properties new file mode 100644 index 0000000..8b697bb --- /dev/null +++ b/project/build.properties @@ -0,0 +1 @@ +sbt.version=1.1.0 diff --git a/project/plugins.sbt b/project/plugins.sbt new file mode 100644 index 0000000..09c90ca --- /dev/null +++ b/project/plugins.sbt @@ -0,0 +1 @@ +addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.14.6") \ No newline at end of file diff --git a/src/main/main.iml b/src/main/main.iml new file mode 100644 index 0000000..a0fde75 --- /dev/null +++ b/src/main/main.iml @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/log4j.properties b/src/main/resources/log4j.properties new file mode 100644 index 0000000..de56a2b --- /dev/null +++ b/src/main/resources/log4j.properties @@ -0,0 +1,52 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +log4j.rootLogger=INFO, stderr + +# Set up logging to include a file record of the output +# Note: the file is always created, even if there is +# no actual output. +# log4j.rootLogger=INFO, stderr, R + +# Base of all Jena classes +log4j.logger.com.hp.hpl.jena=INFO + +# Example of switching on debug level logging for part of tree +# log4j.logger.com.hp.hpl.jena.graph.test=debug +# log4j.logger.com.hp.hpl.jena.reasoner=debug +# log4j.logger.com.hp.hpl.jena.reasoner.test=debug + +# Log format to standard out +log4j.appender.stdout=org.apache.log4j.ConsoleAppender +log4j.appender.stdout.layout=org.apache.log4j.PatternLayout +# Pattern to output the caller's file name and line number. +log4j.appender.stdout.layout.ConversionPattern=%5p [%t] (%F:%L) - %m%n + +# Log format to standard error +log4j.appender.stderr=org.apache.log4j.ConsoleAppender +log4j.appender.stderr.target=System.err +log4j.appender.stderr.layout=org.apache.log4j.PatternLayout +# Pattern to output the caller's file name and line number. +log4j.appender.stderr.layout.ConversionPattern=%5p [%t] (%F:%L) - %m%n + +# File based log output +log4j.appender.R=org.apache.log4j.RollingFileAppender +log4j.appender.R.File=jena2.log +log4j.appender.R.MaxFileSize=5000KB +# Keep one backup file +log4j.appender.R.MaxBackupIndex=1 +log4j.appender.R.layout=org.apache.log4j.PatternLayout +log4j.appender.R.layout.ConversionPattern=%p %t %c - %m%n diff --git a/src/main/scala/uk/floop/org/RdfDiff.scala b/src/main/scala/uk/floop/org/RdfDiff.scala new file mode 100644 index 0000000..19aaa44 --- /dev/null +++ b/src/main/scala/uk/floop/org/RdfDiff.scala @@ -0,0 +1,45 @@ +package uk.org.floop + +import java.io.{File, StringWriter} +import java.net.URI +import org.apache.jena.riot.RDFDataMgr + +case class Config(uris: Seq[URI] = Seq.empty) + +object RdfDiff extends App { + val packageVersion: String = getClass.getPackage.getImplementationVersion() + val parser = new scopt.OptionParser[Config]("rdfdiff") { + head("rdfdiff", packageVersion) + arg[URI]("") minOccurs(1) maxOccurs(2) hidden() action { (x, c) => + c.copy(uris = c.uris :+ x) + } + help("help") text("Parses each file/URL as RDF and shows the differences between the resulting set of statements.") + } + parser.parse(args, Config()) match { + case Some(Config(Seq(uriA, uriB))) => + /* if (args.length < 2) { + println("""Usage: rdfdiff [fileA/URL_A] [fileB/URL_B] + Parses each file/URL as RDF and shows the differences between the resulting + set of statements. +""") + System.exit(2) + } */ + val a = RDFDataMgr.loadModel(uriA.toString) + val b = RDFDataMgr.loadModel(uriB.toString) + if (a isIsomorphicWith b) { + println("Graphs are isomorphic.") + System.exit(0) + } else { + val sw = new StringWriter() + sw.write("<<<<\n") + a.difference(b).write(sw, "TURTLE") + sw.write("\n----\n") + b.difference(a).write(sw, "TURTLE") + sw.write("\n>>>>\n") + println(sw.toString) + System.exit(1) + } + case _ => + System.exit(2) + } +}