From 8ea779342bac146740ef93577e97ef0be73d34f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Euzenat?= <Jerome.Euzenat@inria.fr> Date: Tue, 14 Jan 2014 14:34:59 +0000 Subject: [PATCH] - upgraded to slf4j 1.7.5 - all logging through slf4j - all command-line parameters through commons cli, duly tested --- README.AServ | 2 +- README.TXT | 14 +- build.xml | 11 +- examples/omwg/total.xml | 3 +- html/cli.html | 61 +- html/eval.html | 48 +- html/img/aserv-network.png | Bin 0 -> 21206 bytes html/labels.html | 2 +- html/lib.html | 15 +- html/relnotes.html | 19 +- html/testgen.html | 21 + lib/cli/commons-cli.jar | Bin 0 -> 41123 bytes lib/cli/commons-cli.pom | 21 + lib/slf4j/jcl-over-slf4j.jar | Bin 16457 -> 16517 bytes lib/slf4j/jcl-over-slf4j.pom | 4 +- lib/slf4j/log4j-over-slf4j.jar | Bin 20886 -> 21762 bytes lib/slf4j/log4j-over-slf4j.pom | 4 +- lib/slf4j/slf4j-api.jar | Bin 26083 -> 26084 bytes lib/slf4j/slf4j-api.pom | 4 +- plugins/android/build.xml | 1 + .../inrialpes/exmo/align/cli/CommonCLI.java | 147 +++ .../inrialpes/exmo/align/cli/EvalAlign.java | 152 +-- .../exmo/align/cli/ExtGroupEval.java | 235 ++-- src/fr/inrialpes/exmo/align/cli/GenPlot.java | 355 +++-- .../inrialpes/exmo/align/cli/GroupAlign.java | 238 ++-- .../inrialpes/exmo/align/cli/GroupEval.java | 235 ++-- .../inrialpes/exmo/align/cli/GroupOutput.java | 224 ++-- .../exmo/align/cli/ParserPrinter.java | 188 +-- .../inrialpes/exmo/align/cli/Procalign.java | 231 ++-- src/fr/inrialpes/exmo/align/cli/TestGen.java | 190 ++- .../inrialpes/exmo/align/cli/WGroupEval.java | 576 ++++----- .../exmo/align/gen/AlteratorFactory.java | 19 +- .../exmo/align/gen/BenchmarkGenerator.java | 13 +- .../exmo/align/gen/ClassHierarchy.java | 23 +- .../exmo/align/gen/DiscriminantGenerator.java | 11 +- .../align/gen/NetworkAlignmentDropper.java | 10 +- .../gen/NetworkCorrespondenceDropper.java | 10 +- .../exmo/align/gen/TestGenerator.java | 19 +- src/fr/inrialpes/exmo/align/gen/TestSet.java | 16 +- src/fr/inrialpes/exmo/align/gen/URITree.java | 9 +- .../exmo/align/gen/alt/AddClassLevel.java | 11 +- .../exmo/align/gen/alt/BasicAlterator.java | 24 +- .../exmo/align/gen/alt/EmptyModification.java | 8 +- .../exmo/align/gen/alt/FlattenLevel.java | 16 +- .../exmo/align/gen/alt/RemoveClassLevel.java | 8 +- .../exmo/align/gen/alt/RemoveProperties.java | 8 +- .../exmo/align/gen/alt/RenameThings.java | 12 +- .../exmo/align/impl/BasicAlignment.java | 23 +- .../exmo/align/impl/BasicParameters.java | 22 +- .../exmo/align/impl/BasicRelation.java | 10 +- .../exmo/align/impl/DistanceAlignment.java | 55 +- .../impl/InstanceBasedMatrixMeasure.java | 12 +- .../exmo/align/impl/MatrixMeasure.java | 26 +- .../exmo/align/impl/ObjectAlignment.java | 10 +- .../align/impl/aggr/ConsensusAggregator.java | 8 +- .../exmo/align/impl/edoal/EDOALAlignment.java | 98 +- .../impl/eval/AveragePRGraphEvaluator.java | 14 +- .../exmo/align/impl/eval/DiffEvaluator.java | 17 +- .../exmo/align/impl/eval/ExtPREvaluator.java | 16 +- .../exmo/align/impl/eval/GraphEvaluator.java | 8 +- .../align/impl/eval/PRGraphEvaluator.java | 14 +- .../exmo/align/impl/eval/PRecEvaluator.java | 9 +- .../align/impl/eval/SemPRecEvaluator.java | 10 +- .../impl/eval/ThresholdGraphEvaluator.java | 8 +- .../align/impl/eval/WeightedPREvaluator.java | 49 +- .../impl/method/ClassStructAlignment.java | 12 +- .../impl/method/NameAndPropertyAlignment.java | 21 +- .../impl/method/StringDistAlignment.java | 15 +- .../impl/method/StrucSubsDistAlignment.java | 22 +- .../renderer/COWLMappingRendererVisitor.java | 2 +- .../renderer/GenericReflectiveVisitor.java | 12 +- .../renderer/GraphPatternRendererVisitor.java | 6 +- .../renderer/OWLAxiomsRendererVisitor.java | 12 +- .../impl/renderer/RDFRendererVisitor.java | 12 +- .../renderer/SEKTMappingRendererVisitor.java | 2 +- .../SPARQLConstructRendererVisitor.java | 2 +- .../renderer/SPARQLSelectRendererVisitor.java | 2 +- .../impl/renderer/SWRLRendererVisitor.java | 89 +- .../impl/renderer/XSLTRendererVisitor.java | 14 +- .../exmo/align/ling/JWNLAlignment.java | 9 +- .../exmo/align/parser/AlignmentParser.java | 33 +- .../exmo/align/parser/RDFParser.java | 55 +- .../align/parser/TypeCheckingVisitor.java | 8 +- .../exmo/align/parser/XMLParser.java | 67 +- .../align/service/AServProtocolManager.java | 2 +- .../exmo/align/service/AlignmentService.java | 350 ++--- .../exmo/align/service/DBServiceImpl.java | 7 +- .../exmo/align/service/QueryMediator.java | 4 +- .../exmo/align/service/WSAlignment.java | 2 +- .../service/jade/JadeFIPAAServProfile.java | 21 +- .../service/jade/JadeFIPAAServiceAgent.java | 77 +- .../JADEFIPAAlignmentServerOntology.java | 30 +- .../exmo/align/service/msg/AlignmentIds.java | 10 +- .../exmo/ontowrap/OntologyCache.java | 19 +- .../exmo/ontowrap/OntologyFactory.java | 8 +- .../exmo/ontowrap/jena25/JENAOntology.java | 4 +- .../ontowrap/jena25/JENAOntologyFactory.java | 10 +- .../exmo/ontowrap/owlapi10/OWLAPIAnnotIt.java | 8 +- .../ontowrap/owlapi10/OWLAPIOntology.java | 20 +- .../owlapi10/OWLAPIOntologyFactory.java | 12 +- .../ontowrap/owlapi30/OWLAPI3Ontology.java | 3 - .../owlapi30/OWLAPI3OntologyFactory.java | 34 +- .../ontowrap/skosapi/SKOSOntologyFactory.java | 10 +- .../exmo/ontowrap/skosapi/SKOSThesaurus.java | 8 +- .../skoslite/SKOSLiteOntologyFactory.java | 9 +- .../ontowrap/skoslite/SKOSLiteThesaurus.java | 15 +- .../exmo/ontowrap/util/EntityFilter.java | 10 +- .../owl/align/AlignmentException.java | 11 +- test/clitest.sh | 1143 +++++++++++++++++ test/src/EDOALTest.java | 7 +- test/src/RendererTest.java | 2 +- 111 files changed, 3492 insertions(+), 2366 deletions(-) create mode 100644 html/img/aserv-network.png create mode 100644 lib/cli/commons-cli.jar create mode 100644 lib/cli/commons-cli.pom create mode 100644 src/fr/inrialpes/exmo/align/cli/CommonCLI.java create mode 100644 test/clitest.sh diff --git a/README.AServ b/README.AServ index 6fc9c4ab..1d1fbcc0 100644 --- a/README.AServ +++ b/README.AServ @@ -1,6 +1,6 @@ ####################################################################### # Alignment Server launch instructions # -# 30/03/2013, version 4.5 # +# 11/01/2014, version 4.5 # ####################################################################### Using the alignment server requires an SQL database server. diff --git a/README.TXT b/README.TXT index dfea4a95..445a22e4 100644 --- a/README.TXT +++ b/README.TXT @@ -1,10 +1,10 @@ ####################################################################### # Ontology alignment API and implementation # -# 01/01/2013, version 4.4 # +# 11/01/2014, version 4.5 # # http://alignapi.gforge.inria.fr # ####################################################################### -Copyright (C) 2003-2013 INRIA. +Copyright (C) 2003-2014 INRIA. Copyright (C) 2004-2005 Universit� de Montr�al. Copyright (C) 2005 CNR Pisa. Copyright (C) 2005 Konstantinos A. Nedas. @@ -91,16 +91,16 @@ LAST RELEASE The last release is available from: http://gforge.inria.fr/frs/?group_id=117 +DOCUMENTATION +------------- + +The documentation can be found online at http://alignapi.gforge.inria.fr + SOURCE REPOSITORY ----------------- See http://gforge.inria.fr/scm/?group_id=117 for SVN Access. -DOCUMENTATION -------------- - -The documentation can be found on http://gforge.inria.fr/docman/?group_id=117 - FILES ----- diff --git a/build.xml b/build.xml index c0136749..6d9bc8f0 100644 --- a/build.xml +++ b/build.xml @@ -55,7 +55,7 @@ <tstamp><format locale="fr,fr" pattern="dd/MM/yyyy" property="date"/></tstamp> <property name="version.major" value="4"/> <property name="version.minor" value="5"/> - <property name="copyyear" value="2003-2013"/> + <property name="copyyear" value="2003-2014"/> <!-- first attempt --> <exec executable="svnversion" outputproperty="svn.rev" failifexecutionfails="false"/> <condition property="svn.revision" value="${svn.rev}" else="nosvn"> @@ -224,7 +224,7 @@ group="fr.inrialpes.exmo.align" desc="Alignment API implementation" main="fr.inrialpes.exmo.align.cli.Procalign" - path="skosapi/skosapi.jar owlapi30/owlapi-bin.jar ontosim/ontosim.jar getopt/getopt.jar slf4j/jcl-over-slf4j.jar slf4j/log4j-over-slf4j.jar slf4j/slf4j-api.jar jwnl/jwnl.jar lucene/lucene-core.jar jena/jena.jar jena/iri.jar jena/icu4j.jar iddl/iddl.jar xerces/xercesImpl.jar xerces/resolver.jar xerces/xml-apis.jar hermit/hermit.jar align.jar ontowrap.jar procalign.jar"> + path="skosapi/skosapi.jar owlapi30/owlapi-bin.jar ontosim/ontosim.jar cli/commons-cli.jar slf4j/jcl-over-slf4j.jar slf4j/log4j-over-slf4j.jar slf4j/slf4j-api.jar jwnl/jwnl.jar lucene/lucene-core.jar jena/jena.jar jena/iri.jar jena/icu4j.jar iddl/iddl.jar xerces/xercesImpl.jar xerces/resolver.jar xerces/xml-apis.jar hermit/hermit.jar align.jar ontowrap.jar procalign.jar"> <files> <fileset dir="classes"> <include name="fr/inrialpes/exmo/align/impl/**/*.class"/> @@ -285,7 +285,7 @@ <attribute name="Built-Date" value="${date}"/> <attribute name="Main-Class" value="fr.inrialpes.exmo.align.service.AlignmentService"/> <!-- usually each MANIFEST knows what it needs, add here --> - <!-- semanticmapper-0.2.jar jwnl.jar sboa.jar TaxoMap.jar AROMA_aserv.jaroyster2.jar, semanticmapper-0.2.jar, sboalgorithms.jar --> + <!-- semanticmapper-0.2.jar jwnl.jar sboa.jar TaxoMap.jar AROMA_aserv.jar oyster2.jar, semanticmapper-0.2.jar, sboalgorithms.jar --> <!-- others should be there naturally --> <attribute name="Class-Path" value="alignsvc.jar"/> <attribute name="Implementation-Title" value="Alignment server custom launcher"/> @@ -313,6 +313,7 @@ <!-- tested --> <target name="test" depends="bind" description="Unit test code"> <echo message="Testing..."/> + <echo message="You may also want to try sh test/clitest.sh"/> <taskdef name="testng" classpath="${tooldir}/testng/testng.jar" classname="org.testng.TestNGAntTask" /> <javac srcdir="test/src" includeantruntime="false" destdir="test/classes" debug="on" classpath="tools/testng/testng.jar" encoding="iso8859-15"> @@ -344,7 +345,7 @@ <delete> <fileset dir="test/classes" includes="**/*.class"/> <fileset dir="test/output" includes="**/*.*"/> - <fileset dir="test/html" includes="**/*.html,**/*.xml,**/*.css"/> + <fileset dir="test/html" includes="**/*.*"/> </delete> <delete dir="test/html/Ant suite"/> </target> @@ -515,7 +516,7 @@ <echo message="@{file}" /> <onepom file="@{file}" /> </for--> - <onepom file="getopt/getopt" /> + <onepom file="cli/commons-cli" /> <onepom file="google-translate/google-api-translate-java" /> <onepom file="google-translate/json" /> <onepom file="hermit/hermit" /> diff --git a/examples/omwg/total.xml b/examples/omwg/total.xml index 43540d4a..322b38a6 100644 --- a/examples/omwg/total.xml +++ b/examples/omwg/total.xml @@ -40,8 +40,7 @@ <Ontology rdf:about="&vin;"> <location>http://www.scharffe.fr/ontologies/OntologieDuVin.wsml</location> <formalism> - <Formalism align:uri="http://www.wsmo.org/wsml/wsml-syntax/wsml-dl" - align:name="wsml" /> + <Formalism align:uri="http://www.wsmo.org/wsml/wsml-syntax/wsml-dl" align:name="wsml" /> </formalism> </Ontology> </onto2> diff --git a/html/cli.html b/html/cli.html index bd8c1603..76568591 100644 --- a/html/cli.html +++ b/html/cli.html @@ -33,7 +33,7 @@ the <tt>fr.inrialpes.exmo.align.cli</tt> package: These command line operations usually share switch conventions: <ul> <li>displaying help (-h);</li> -<li>displaying debug information (-d);</li> +<li>taking parameerst (-Dv=n) and parameter files (-P);</li> <li>directing the output to a file (-o);</li> </ul></p> @@ -46,7 +46,7 @@ the <tt>align</tt> method. <h2>Matching</h2> <p> -The implementation offers a stand-alone program (<tt>fr.inrialpes.exmo.align.util.Procalign</tt>) which: +The implementation offers a stand-alone program (<tt>fr.inrialpes.exmo.align.cli.Procalign</tt>) which: <ul> <li>Reads two OWL/RDF ontologies;</li> <li>Creates an alignment object;</li> @@ -65,21 +65,23 @@ Additional options are available: <p>Running the program is achieved through: <div class="terminal"> $ java -jar lib/procalign.jar -Two URIs required -usage: Procalign [options] URI1 URI2 -options are: - --impl=className -i classname Use the given alignment implementation. - --renderer=className -r className Specifies the alignment renderer - --output=filename -o filename Output the alignment in filename - --params=filename -p filename Reads parameters from filename - --alignment=filename -a filename Start from an XML alignment file - --threshold=double -t double Filters the similarities under threshold - --cutmethod=hard|perc|prop|best|span -T hard|perc|prop|best|span method for computing the threshold - --debug[=n] -d [n] Report debug info at level n - -Dparam=value Set parameter - --help -h Print this message +usage: java fr.inrialpes.exmo.align.cli.Procalign [options] ontoURI ontoURI + Matches the two ontologies identified by <ontoURI> -$Id$ +Options: + -a,--alignment <FILE> Use initial alignment FILE + -D <NAME=VALUE> Use value for given property + -d,--debug <LEVEL> debug argument is deprecated, use logging instead + See http://alignapi.gforge.inria.fr/logging.html + -h,--help Print this page + -i,--impl <CLASS> Use the given CLASS for matcher + -o,--output <FILENAME> Send output to FILENAME + -P,--params <FILE> Read parameters from FILE + -r,--renderer <CLASS> Use the given CLASS for output + -T,--cutmethod <METHOD> Method to use for triming (hard|perc|prop|best|span) + -t,--threshold <DOUBLE> Trim the alignment with regard to threshold + +Alignment API implementation 4.5 (1864M) </div> </p> <p> @@ -89,10 +91,33 @@ Parameters can be passed to all the command line interfaces through the "-Dname= <h2>Batch matching</h2> <p>There is a small utility (<tt>GroupAlign</tt>) which allows to implement batch matching. It starts with a directory containing a set of subdirectories. Each subdirectory contains an ontology to align (usually called <tt>onto.rdf</tt>) and there exist an ontology to be aligned againts these (-n argument, e.g., named <tt>./onto.rdf</tt>).</p> +<div class="terminal"> +$ java -cp lib/procalign.jar fr.inrialpes.exmo.align.cli.GroupAlign --help +usage: java fr.inrialpes.exmo.align.cli.GroupAlign [options] + Matches pairs of ontologies in subdirectories + +Options: + -a,--alignment <FILE> Use an initial alignment FILE + -D <NAME=VALUE> Use value for given property + -d,--debug <LEVEL> debug argument is deprecated, use logging instead + See http://alignapi.gforge.inria.fr/logging.html + -h,--help Print this page + -i,--impl <CLASS> Use the given Alignment implementation + -n,--name <URI> Use the given URI as common source ontology + -o,--output <FILENAME> Send output to FILENAME + -P,--params <FILE> Read parameters from FILE + -r,--renderer <CLASS> Use the given CLASS for rendering + -s,--source <FILE> Source ontology FILEname (default onto1.rdf) + -t,--target <FILE> Target ontology FILEname (default onto.rdf) + -u,--uriprefix <URI> URI prefix of the target + -w,--directory <DIR> The DIRectory containing the data to match + +Alignment API implementation 4.5 (1864M) +</div> -<p>Invoking <tt>GroupAlign</tt> with some implementation (-i argument), some set of parameters (-p argument), the name of the output file (-o argument) and optionally a renderer (-r argument) will output the resulting alignment in each of these directories: +<p>Invoking <tt>GroupAlign</tt> with some implementation (-i argument), some set of parameters (-P argument), the name of the output file (-o argument) and optionally a renderer (-r argument) will output the resulting alignment in each of these directories: <div class="terminal"> -$ java -cp $CWD/../lib/procalign.jar fr.inrialpes.exmo.align.util.GroupAlign +$ java -cp $CWD/../lib/procalign.jar fr.inrialpes.exmo.align.cli@.GroupAlign -o edna -n file://$CWD/101/onto.rdf -i fr.inrialpes.exmo.align.impl.method.EditDistNameAlignment </div> diff --git a/html/eval.html b/html/eval.html index 26e2af02..424fe9eb 100644 --- a/html/eval.html +++ b/html/eval.html @@ -60,15 +60,20 @@ See below for more graphical formats. <p> The option of <tt>EvalAlign</tt> are: <div class="terminal"> -$ java -cp lib/procalign.jar fr.inrialpes.exmo.align.cli.EvalAlign --help -usage: EvalAlign [options] file1 file2 -options are: - --debug[=n] -d [n] Report debug info at level n - --impl=className -i classname Use the given Evaluator implementation. - --output=filename -o filename Output the result in filename - --help -h Print this message +$ java -cp lib/procalign.jar fr.inrialpeS.exmo.align.cli.EvalAlign --help +usage: java fr.inrialpes.exmo.align.cli.EvalAlign [options] alignURI alignURI + Evaluate two alignments identified by <alignURI> -Alignment API implementation 4.3 (1698M) ($Id$) +Options: + -D <NAME=VALUE> Use value for given property + -d,--debug <LEVEL> debug argument is deprecated, use logging instead + See http://alignapi.gforge.inria.fr/logging.html + -h,--help Print this page + -i,--impl <CLASS> Use the given CLASS for evaluator + -o,--output <FILENAME> Send output to FILENAME + -P,--params <FILE> Read parameters from FILE + +Alignment API implementation 4.5 (1864M) </div> The <tt>-i</tt> switch enables changing the evaluator to be used (by default, <tt>PRecEvaluator</tt> is used). @@ -289,14 +294,25 @@ $ java -cp ../lib/procalign.jar fr.inrialpes.exmo.align.cli.GenPlot -l "refalign <tt>GenPlot</tt> accepts the following arguments: <div class="terminal"> $ java -cp /Java/alignapi/lib/procalign.jar fr.inrialpes.exmo.align.cli.GenPlot --help -usage: GenPlot [options] -options are: - --type=tsv|tex|html(|xml) -t tsv|tex|html(|xml) Specifies the output format - --graph=class -g class Specifies the class of Evaluator to be used - --evaluator=class -e class Specifies the class of GraphEvaluator (plotter) to be used - --list=algo1,...,algon -l algo1,...,algon Sequence of the filenames to consider - --debug[=n] -d [n] Report debug info at level n - --help -h Print this message +usage: java fr.inrialpes.exmo.align.cli.GenPlot [options] + Generate a graphic presentation of evaluation results + +Options: + -D <NAME=VALUE> Use value for given property + -d,--debug <LEVEL> debug argument is deprecated, use logging + instead + See + http://alignapi.gforge.inria.fr/logging.html + -e,--evaluator <CLASS> Use CLASS as evaluation plotter + -g,--grapher <CLASS> Use CLASS as graph generator + -h,--help Print this page + -l,--list <FILE> Consider this list of FILEs for inclusion in + the results + -o,--output <FILENAME> Send output to FILENAME + -P,--params <FILE> Read parameters from FILE + -t,--type <tsv|tex|html(|xml)> Output in the specified FORMAT (values + +Alignment API implementation 4.5 (1864M) </div> The <tt>-t</tt> switch specifies the type output. The plots are provided for PGF LaTeX as gnuplot tables. diff --git a/html/img/aserv-network.png b/html/img/aserv-network.png new file mode 100644 index 0000000000000000000000000000000000000000..9c54c093a22e3e0a70884a3c30588e8c6e3b139f GIT binary patch literal 21206 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 Z&#Aezz$m`2gn@y9!PC{xWt~$(69B7_oe}^5 literal 0 HcmV?d00001 diff --git a/html/labels.html b/html/labels.html index 0d2761d1..70935c17 100644 --- a/html/labels.html +++ b/html/labels.html @@ -64,7 +64,7 @@ <dt>http://knowledgeweb.semanticweb.org/heterogeneity/alignment#certificate</dd> <dd>STRING a certificate from an issuing source</dd> <dt>http://knowledgeweb.semanticweb.org/heterogeneity/alignment#time</dd> -<dd>DURATION of the matching process.</dd> +<dd>DURATION (default: INTEGER in milliseconds) of the matching process.</dd> <dt>http://knowledgeweb.semanticweb.org/heterogeneity/alignment#limitations</dd> <dd>STRING the validity range of the correspondence</dd> <dt>http://knowledgeweb.semanticweb.org/heterogeneity/alignment#properties</dd> diff --git a/html/lib.html b/html/lib.html index 176c3a25..536b7998 100644 --- a/html/lib.html +++ b/html/lib.html @@ -39,15 +39,14 @@ This is a simplified view: <a href="img/dependencies.png">click here <h2>Required for the API implementation (procalign)</h2> <dl> -<dt><a href="http://www.urbanophile.com/arenn/hacking/download.html">Gnu - getopt</a> 1.0.13: getopt.jar - [<a href="http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html">LGPL</a>]</dt> -<dd>Gnu library for parsing command line arguments. Required - everywhere (included by OWL-API).</dd> -<dt><a href="http://www.slf4j.org/">SLF4J</a> 1.7.2: +<dt><a href="http://commons.apache.org/proper/commons-cli/">Commons CLI</a> 1.2: commons-cli.jar + [<a href="http://www.apache.org/licenses/LICENSE-2.0.html">Apache</a>]</dt> +<dd>Library for parsing command line arguments. Required for the + command line use (cli package; included by OWL-API).</dd> +<dt><a href="http://www.slf4j.org/">SLF4J</a> 1.7.5: slf4j-api.jar log4j-over-slf4j.jar jcl-over-slf4j.jar [<a href="http://www.slf4j.org/license.html">MIT license</a>] </dt> -<dd>At last some clean-up in the Java logging realm.</dd> +<dd>Java unified logging library!</dd> </dl> <h3>Required for using EDOAL</h3> @@ -118,7 +117,7 @@ and this will compile again. <h2>Required for the Alignment server (alignsvc)</h2> <dl> -<dt><a href="http://dev.mysql.com/downloads/connector/j/3.0.html">MySQL +<dt><a href="http://dev.mysql.com/downloads/connector/j/">MySQL JDBC Connectors</a> 5.1.12: mysql-connector-java-5.0.3-bin.jar [<a href="http://www.gnu.org/licenses/old-licenses/gpl-2.0.html">GPL</a>] or <a href="http://jdbc.postgresql.org/">Postgres JDBC diff --git a/html/relnotes.html b/html/relnotes.html index eda8d866..eb504151 100644 --- a/html/relnotes.html +++ b/html/relnotes.html @@ -38,14 +38,13 @@ The development of 4 versions continues. <p><ul compact="1"> <li>Provide several URIs for the same alignment (server)</li> -<li>Adopt, overall, slf4j (impl/server)</li> <li>Implement database store for EDOAL (server)</li> <li>Add simple "harder" test generator (gen)</li> <li>Add simple "hidden" test generator (gen)</li> <li>Add a <tt>dependsOn</tt> alignment property (api)</li> <li>Consolidate alignment based on <tt>dependsOn</tt> (loop checking, cell ingestion) (impl)</li> -<li>Use the OWLReasoner interface and HermiT for adding inference to Ontowrap (ontowrap)</li> <li>Add a JSON interface (server)</li> +<li>Use the OWLReasoner interface and HermiT for adding inference to Ontowrap (ontowrap)</li> <li>Integrate tests from generator (test)</li> <li>Integrate some basic reasoning (impl).</li> <li>Complete tutorial4 with distributed reasoning.</li> @@ -74,9 +73,23 @@ with a warning: <!--h2>Version 4.9 (1xxx): ??/??/201X - Al pesto</h2--> <!--h2>Version 4.8 (1xxx): ??/??/201x - Ant�sine</h2--> <!--h2>Version 4.7 (1xxx): ??/??/201x - Letraset</h2--> -<!--h2>Version 4.6 (1xxx): ??/??/201X - Da lec'h all</h2--> +<!--h2>Version 4.6 (1xxx): ??/01/2014 - Da lec'h all</h2--> <p><ul compact="1"> +<li>Fixed a bug in <tt>EDOALAlignment.init()</tt> which would prohibit rendering (edoal)</li> +<li>Fixed a bug in <tt>OWLAxiomsRendererVisitor</tt>, <tt>SWRLRendererVisitor</tt>, <tt>SEKTMappingRendererVisitor</tt>, <tt>COWLMappingRendererVisitor</tt> <tt>SPARQLConstructRendererVisitor</tt>, and <tt>SPARQLSelectRendererVisitor</tt> which sometimes rendered alignments empty (impl)</li> +<li>All logging and signaling is now through slf4j (impl/server)</li> +<li>Replaced getopt by <span style="color: green">commons cli</span> 1.2 as command line interpreter (lib/cli)</li> +<li>Completed <tt>SWRLRendererVisitor</tt> to fill equivalence and subsumption statements (impl)</li> <li>Declared Alignment server as an OSGi service (server)</li> +<li>Made EDOAL vocabulary dereferenceable (edoal)</li> +<li>Fixed the build.xml file for using slf4j in microalign (android)</li> +<li>Fixed several bugs in <tt>WeightedPREvaluator</tt>, now two versions (impl)</li> +<li>Fixed display bugs in <tt>GroupEval</tt> and <tt>WGroupEval</tt> (cli)</li> +<li>Cancelled test <tt>EDOALTest.anotherRoundTripTest()</tt> because would try to load a WSMO ontology (test)</li> +<li>Changed <tt>-o</tt> option in <tt>GroupAlign</tt> to be homogeneous (cli)</li> +<li>Updated tutorial2 with deprecated <tt>BasicParameters</tt> (tutorial)</li> +<li>Added complete command line option tests in <tt>tests/clitest.sh</tt> (cli)</li> +<li>Upgraded to <span style="color: green">SLF4J</span> to 1.7.5 (lib)</li> </ul></p> <h2>Version 4.5 (1847): 25/03/2013 - Building 16</h2> diff --git a/html/testgen.html b/html/testgen.html index 600a6592..a78aa112 100644 --- a/html/testgen.html +++ b/html/testgen.html @@ -349,6 +349,27 @@ a test set altering regularly one or several dimensions (each one represented by an alterator). </p> +<h4>Definitely harder benchmarks</h4> + +<p> +Benchmark is a test set were a seed ontology is altered and any test +has to match the seed ontology with the altered ontology. However, we can also ask +to match two differently altered ontologies. Since altered ontologies +come from the same seed ontology and the generateed alignments are +equivalence alignment, the reference alignment can be generated +automatically. Indeed, if benchmark test <i>X</i> generates +alignment <i>A<sub>X</sub></i> and test <i>Y</i> generates +alignment <i>A<sub>Y</sub></i>, then for the task of matching +ontology <i>o<sub>X</sub></i> to ontology <i>o<sub>Y</sub></i>, the +reference alignment will be: +<center> +<i>A<sub>X-Y</sub></i> = <i>A<sub>X</sub></i><sup>-1</sup> o <i>A<sub>Y</sub></i> +</center> +The two operations (<sup>-1</sup> and o) being part of the Alignment +API, this is easy to generate. +</p> +<p>Not available yet.</p> + <h4>Hidden ontology generator</h4> <p>Not available yet.</p> diff --git a/lib/cli/commons-cli.jar b/lib/cli/commons-cli.jar new file mode 100644 index 0000000000000000000000000000000000000000..ce4b9fffe40c41669797cd806ac989471b2acd84 GIT binary patch literal 41123 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 literal 0 HcmV?d00001 diff --git a/lib/cli/commons-cli.pom b/lib/cli/commons-cli.pom new file mode 100644 index 00000000..0be86694 --- /dev/null +++ b/lib/cli/commons-cli.pom @@ -0,0 +1,21 @@ +<project> + <modelVersion>4.0.0</modelVersion> + + <groupId>org.apache.commons</groupId> + <artifactId>commons-cli</artifactId> + <version>1.2</version> + <name>Apache Commons CLI</name> + <inceptionYear>2002</inceptionYear> + <description> + Commons CLI provides a simple API for presenting, processing and validating a command line interface. + </description> + <packaging>jar</packaging> + <licenses> + <license> + <name>Apache License Version 2.0, January 2004</name> + <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url> + </license> + </licenses> + <url>http://commons.apache.org/cli/</url> + +</project> diff --git a/lib/slf4j/jcl-over-slf4j.jar b/lib/slf4j/jcl-over-slf4j.jar index 63888dc94b49d1608e89d797baab17757319d91b..a80e4f1c3cc5bf7d374837bb6c403565f68ad578 100644 GIT binary patch delta 3557 zcmX@vz}VWz$QR(v%)-S00tM?TohI@rbL6k9bh=jYH+Z6@e!YO{%#Tb3Qk)u$hu5yW zn<%oYY};+7{QTV~8B7iLzWVv^+|RU_)22I`)*Z0QEODt?(|z$mSMQnw^Ntm>{=PI( zx#8jsCVhp4i=AECEXAc2jN=-QWrTQzUMXg@zWGPk%Cqd?pSIHbzrzz(2(x}+oU_45 z|5eY)idT~V1ZO_wGP+<_-yk9HKJD`HgG)l^>Q<j#XIN!-snXyVf8FHPrjDG}MF(eF zZI#Q3et)xEd9COE)@ki;4r^$}Ra|=!d1146E%(3FeN1yDq)nf1xPCOaTj#;%DPof< z_!seHAKNwQ+KUa_@|W%J$?X4m?@?`Dj^p!~Hx;j%dweC=zfM1tGV@}e=HzAOLCecS zix1YuX131>HdL~|p%YT4xw8AWXqbG7+ZWz)KZfF+dsqw)z2HU!qv5(rr^#~}by&cR zvy5^O#(PFp2t$HN7sBvlG8F`=0fjvbD@>lCDL1*_niU=|91Ng%*?fRWj1jDD^DX8h zOkjNri{96XGBGf8Gczz4g7xv+vQ7SAEwK49n>-UlF&n3d0E8tcd6xyk`Y&6<0ydzI zcX#JoHU@^*d<+bxPy=`;SJ?8_PYwGWE|V@<$5v*1+MuzeMMcFl?~++8)0-&o%VL)_ z7OE)fi91Vqte%$m^TynivNUUBZpC}1Yo~|Zu3CNZo=@nW+1JVhFV6erUHpar!edLh z`mg%~=I571mQBw+ApdOlzVF{F@8|#fHQ#;@^MklOOBZrq*5cviosoAa@yrU3OpbbS z^Ua?kR?N73p(S&tr@1n7FyHi$n7p>uH8MGt7E(nOLCW)Q^Z0-IDfMYa_{If~y4q?Z zLJC6<*VRPbt6#=B|LF6Onz+M`KJFh_E$ai1PJi;}DaX2#KQ(#%A8QNNgr19^ELIcC zcYZ}hnB(N9OD-RhH7w$K=M`u4tk>n9`C6A#^&5jLuZwP*FQKFFdDVX!r*W=y-91sR zW!nxE?eR#KEVD9vxO>^$cm7s+R*6q~Lfj_k&MwW-SLA&dtMqcoZ~uVac{0|2kNnuV z@#Dhc=lWV1w>4Z3mT7&eIs8puA}r43125~Who8&T-gEmqR<~BB^XNa8HlC(%f7|0_ zxxds!OpeuC>1%NCT5T>_W}0~`$z=Xq!FQFO8dI$_5ARCYvFy%tKIgh)OWsuHKW~|N zHnOwx$;x}1OP)`e_(`@r@YfWve+OpOa`hcCv$`5tXku3ExuoV(YmTz_uenp-EVh}X zcg#wDy|~oTC+2Gua>QSjg|sMTRyAHZoix$BT05`pO-<O2w)%W4GtQ9kiptaKXV>kr znw5FJU_yh)+TH6f&2~Kf!NzK{=c3H`Q%39JmgY;(n0b1kw&uji$11e;tz57@Z;x5% z#hmWeQsc$Z2_M$%yyty#ff19y1Vsxkk@G5@$!FJ{?wRpaH93v*@Z^Fb*K0GyMSte4 zPq+WLygGElj^%te-9kK$)qmJ?q_(thisNEmi%N4<znMZ?c4r@un9gI>_mEL-yWhkY zFOL3od7<`H_hsZGt6ditKen`qSIs?8+Uv?`CcFGYQ&;}WA7=X&Ki>UAjxqA};x6&h z8u{y`e;Dki9EuD2xT!Dv!>Yc`65$_bH8pQPKetQ%<&MVdqB2qEXHGX3-qfdB-^V7# z6TU|E+do~g0@KwzxB5koY>WCk>7Tk)U6-n;{pF9vf0|UoU;jS2C-bb=>@q*TInr;t z=bi7!2>T(KZno<2^dD23j{Luwt8#n&%9rPa<dWxJWIfzH>)W2<$TP=E|FErJ^<!<{ z?1XY(v8#RTO9K5nGLC&OuI)T>=#Y~QM{-R4EB}rDRUdoiZ@qTJ?YWG3){VeIRrm5H zhrn;r6%NN|SHvBEzhTLPcem5mrW6|P{-_kY$3<NK;!)4zYz5VhN1o1^c~1Oy_|EbT zr#JgwExEl_X;rv|?8bB7b35Ob>PNhhJS<%pW0=yZ^ZF3?ylKaq?iC-^m)*pbTq?RP zWP92tsm=A9P2VP+O*q9<`7BgWLt>iC;nLJ?*R}+gsktSZRJgA?tFis_;o1A2vV`Os z>!h#m{B+%G^}o|$%lju4T=wFPimlF3-ffeA?&;r$I~yhSIX*O(I&C|;Cj8rC*Yo0$ zZZ}T;embAyvS-g_{`vPfl(p-XdSd);oC!X!cD^FC^ZWG+*Xs>ePP2PteRT2GXHmIa z#<M3|cN_4WkF3;pzTK72ADd87(D8qA?4QWoC&%4*Sqs-mO>khhI}#tkD$n=ryQ0c% zyX%7UKIT67p-?WbzWmV70~b>@+`}&x6iW8yD<4UnaXL5OxmH==gTQe!E=IqiIS$%v zKUe?a_*Jn;+;xHcaZBy`3JG<uNAhav%+HrC&R4t=>hL5j^2WA?Oe=v6%RNGb6vE{> zbHYCa@=S60+nRNFj(Ye-m(yF8h(tPk_V~_K!g_t<^6u4dx$e21=8BRw*!kstefipi z_9pv<sarlqtgyZE`5f<?*O~mKTie4nY<8UF7sIWo@+Q*!4aZgH>5>}U*7Xxo6>{6m zjxVtFERN|ZtP`nAsL=PV;wU#zYj(_0^VW0m_{!0i@r!THGw#Y+oB9nS(+y-;{^-~p zoBWEy&?cAl&8prDTfcV(2r2K8e`<B4Qb)ilPUx4u*3Dy;U4}uD&37+d{WkI4cY$~N zZhozP^OC!?<zLU<>l?F0f9sXC+&fx-FSVpcFY&k5x8nUh%!?WG&vU)Ym~y7}Vc!Sc z6}H|F7MVrpFKRtsEj@XIw7#I2zVOub0+s78-jd$(<?DfV<ABc7Zb|QCjz8v!F5Ei5 zVCI3!UlUcP$UU8T=5xr+>nnw%qFy{?y=N9uX&ZTLlSZQDM>V?*UCk^f*>5jmmATb= zn6>`S%`)-ntaoA$2;SR%H+T+r$JIyGl7VX!+CryYlGpw)SL1Otm$<i<|FliZr+&C= zxl_-VJMUg{Ltf~T0PWpNr#k+VkXv8iIPFv8yXXwv(<xC+rR9w7>e*-iN*~`Zoc2FK z=D(yymze7mQCSVmNvr)IOnwsfVWq<<;s4CwdYqGifq{boR5x#K)^vl`yJxkYLo3xC zx+?4}pjvtI0~1XMgV)p;!f-Kl;wV~O>6DnW&1Z6-sTb4XW0P;0M%0Hl|9(`N{G)vD zt&HO$J6pV3GdkQ4HwORP@;pT9b62Z}pxgb4*LJoUaDBI^{2*sjFzup-1mC9=J9nmF zQIXES5gU5+7dz}`nE6JHU4EKYw}aC}S+1$qBpRYwJ|rGaSm>^^M9*5H`Tc|0{N5Lr zw1&nhFVi`6@*0zmx?Rpoop-(Uzh+&PJ#-}1YI%0y++QV+A1Zfo_BJyMRoX7iSR=C3 zV#nXDMaLZK`8+F|f@2N(=Gd&*9I30e-Oj||u|T3E*P-Hh_a0t%k^b(Z;+X8~bJnuZ z?u>5bcQfweCWlN^BBmw(d$Q|Wd}=M%Dc7pm7w!BsAKSK=Y5e_jUyfzNtmkI?+3Izi zj}<OxbQgMfqP;aIyH)(?u63zDm8~7;d|8`j{o7sL)}{Zk=YNK7Ne!K=t3PYxEjhd` z@ZV{Vpsfcd`>bEH=CF8|*E^Gh`^}FEH|(4KcZ;=_9AB+c-op#Gr<HL^-koS6>|t7d zz>WL+laA<9f1U}dTHAJ5hAxVG&h{YPZ86L4`rB2{Crq%|WRzf}c0230)r0JVX}yP6 zPv244SGpqdxm)zZX-^Yp*UdJKyK_`DBVFpl*TRs?Q4?6qFU=@r&<VB)Hdflw)ww)< z$GrRZcbwkM8gu`SuK4G(wh{WTMAY26l`2k7<o~UC)jzfPq*vgr^1XM?KXi!hQfd|l zrzZvm0R|2Rqji-|%<W32vlti{3MboH1lNB%d!Bhyw@8nVXb;a?ADy*5z9MsCoke<h zczP>$o(k&jGXDHIhxhB5uRfJKFLi(N=C%pW`P_Z!Ygh3lpG_4zg}S|rE(=ZeZdep~ z(sI{N2iaW#nhXKnj7%cTh!#DpWeK7|=^8|X-1F9vVX}aw1iZCB*}&2Y+&-L~XK4dr zth3aEFdkT%LKu=(wh%^?l`Dj?*vbo%@IP85LPWx>!y$}~*3l4#fK4QXk!zC*VO+C` z;00wbcnfs0wQZO@NJP-ugN=icf#E(Q1A_|0tzdFV<HpGwY>gE_YLfoVTs@hIfkB9s zfx!wa3n7*?{??j2QBz^^Z!MY0_I5lFyZr5>n4al^#k=h!V?p^Aq8vi<LnsDNnEe0G zXUf3f>l)&y>*?pFpPN{gnx~I1KqXN$TboX1v{#1&hmO4zQxS+SJvq*TUk70b2Lr5l zh+|@4uw!Rn(1#nsz_6ro2TYUj<TLjC3Mh$&fq}scMRBslWJY_C4YFbZ-mGjOIdKMY N20wNN21QE{4*>P)0uulL delta 3400 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 diff --git a/lib/slf4j/jcl-over-slf4j.pom b/lib/slf4j/jcl-over-slf4j.pom index c5a6d2de..59979200 100644 --- a/lib/slf4j/jcl-over-slf4j.pom +++ b/lib/slf4j/jcl-over-slf4j.pom @@ -3,7 +3,7 @@ <parent> <groupId>org.slf4j</groupId> <artifactId>slf4j-parent</artifactId> - <version>1.7.2</version> + <version>1.7.5</version> </parent> <groupId>org.slf4j</groupId> <artifactId>jcl-over-slf4j</artifactId> @@ -14,7 +14,7 @@ <url>http://www.qos.ch</url> </organization> <inceptionYear>2005</inceptionYear> - <!-- Copyright (c) 2004-2011 QOS.ch --> + <!-- Copyright (c) 2004-2013 QOS.ch --> <licenses> <license> <name>MIT License</name> diff --git a/lib/slf4j/log4j-over-slf4j.jar b/lib/slf4j/log4j-over-slf4j.jar index cd04c46a124f2c17e71125e5a7e452b5bb199b9e..7caf77291dda4ce28cc3afb54be8786dd053a269 100644 GIT binary patch delta 7275 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�B9SRYt*>;JyK$0~f>x8<r%_uM~I{dwww2X7jZU(Wm7 z)1|+7@06n=hh$_8SywoGlw&>?{Nr&QulfP@e;F19*&n{>ct{sm%{}mPaofG0|0MoJ zxkro6R_+f_6znaO)i@E7QGX;!g>&(LhnMyDoHE+W=h*z}x3lO@5#eJO^$t+zTgkIJ zKXvJxsYkUqLpcO)<`r=yJT~GuqIz>-gjPRWMQIa56hB+lkr<7e4<%~Y<}=-xF-vUQ zo?B-kn>Np9TcFLEa6bIuobOL9w{7cL>LndKXCC9XFP5v`{oq{Mvg{$_M=!tRuzr!J z7Coy(>fdSU8_m&PX;Jt-)T&%sSN%To3dN}ECf75bfxah>2xzxO8k%j=Tk#|^V{PlS zsI%G)SGzO)+>(4)#eCy?bA6s(h)S!v@ow7NC!Sxg_4-Uv4Q<xfSSy=Zk+9|0wi`L( z_vT8q*qnCj;cGXm&hB)}ZsPV4_DR0<GPm~p+^+q4x9YcsI<xNFmVQC0;BM53|4VFD z{2!kbO==Z2)GpB27~s2Ve}2ZRogFWym;KlCyf!T;WoeYtMZqh5*Y;@~<XOM3O!)V< zMRmSk=R4@`4QG$h^=UoQ^UfoxNM-iot(%Tk7ag%pFFn#RX>QihCa-(F_nB&RGbbgk z-}#ci{))fDgCjQ@>N}^*ct4#Xt|4D_cC`6Yp=<jy5@MsKXWg^j-(B){?(3@DUbUwi zL(7<}F7p1Uv%Zz5>)EC&wU@79>L!h+a|)g&{rSndPMqI3e{1BSuQ{8e^tSOQ?0utA z(s!@p!EH&_4fa9D3vZb=@3qbLN$lGbdGVpc-YZsz!{M1m2;7>#{eRQV90mr4Vg?2V zi^&a6x|5H(s-%58d!Bhyw@8nVXb;a?ADy*5zM^wtoke<hczP>$o(k&jGXDHIhxhB5 zuRfJKFLi(N=C%pW`P_Z!Ygh3lpG_4zg}S|rE(=ZeZdhdb^QBtkuAdIJy8=8J0=yZS zM3@l+{FD9NjNv2vle^rkz&UU72{%0m<CmK$gkkJ%4Pod6NKEc>*M@NZxJymG><%60 z{^M>B5w-X5gfMzMg3w2+-*`Y3>3d2s&E=mg$Rs_vj-N*d;V?)S=f=!T(+!La3>?f1 z40^Cpa|Q;6C5?xL!J2k@Dncx|=PAXsUv#pex5#8ZFL4E<b(KzU<(EC?VPjy}%+0_c zgQEG27+7JXml#+fN{0wVp^)rkLvOLk?_@+L@ABe-*mTNEiiuMREdIw!6l?&;RCnh@ zCI$vGRt5$|6ax%YCmVX}gB4XtCVY6n$iVQ7nSntHMbQQI$%0J6lWo;GC(rSQ+Oo!5 zis^+WSp2p(#1?o9g^__l1;v1yx?qKFy26tsy?DU3wX}L^9b#c%Si;4?AdjM0Ngu2@ zN{<gCxD%_-C9*OxFx0U!FleJ_QZxZ;iZqs*eBYl-2@*RfH9v~-d^3=8Zls35<U9{4 zNcg?+kz(wb<R>v%-WNJY;^-^IwA*qrqo4TXTV_HSt^(H=3=9mijOd|z+X}4dmpNw2 zdHzWzXA=Vh1E@)7h~l<)){`0i?7@K~7cptub*v`8w*i~XXT<{#(KeTdYvwaBFkE0@ zV9-D@k<|{Y_?VwO*wl;a+_GC485kxpqle-vh(Z~EC9pzxg~rIhppIhV3kR@?>~@%; zfl}Y0XyR}J1^VP;{;H6A?!CVhlc?)t?f_W`Unf9{$;owcqmwjJ5Hm1<YDpw>7_{IV z0fztoD?u9cChra4Le!b(1H_mPg2Z(u3kM2=y@FDD!3_Xq)QKLG8=Z6}7X^y(sWGTA N%;aWZ2=)Z2003v8dtm?o delta 6371 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 diff --git a/lib/slf4j/log4j-over-slf4j.pom b/lib/slf4j/log4j-over-slf4j.pom index 94553cca..5399331c 100644 --- a/lib/slf4j/log4j-over-slf4j.pom +++ b/lib/slf4j/log4j-over-slf4j.pom @@ -3,7 +3,7 @@ <parent> <groupId>org.slf4j</groupId> <artifactId>slf4j-parent</artifactId> - <version>1.7.2</version> + <version>1.7.5</version> </parent> <groupId>org.slf4j</groupId> <artifactId>log4j-over-slf4j</artifactId> @@ -14,7 +14,7 @@ <url>http://www.qos.ch</url> </organization> <inceptionYear>2005</inceptionYear> - <!-- Copyright (c) 2004-2011 QOS.ch --> + <!-- Copyright (c) 2004-2013 QOS.ch --> <licenses> <license> <name>MIT License</name> diff --git a/lib/slf4j/slf4j-api.jar b/lib/slf4j/slf4j-api.jar index 73f38db9ce6973b8247c2cf267a5fd4a1464c7b3..8766455d8756ebdac09d36eea2c08db90c18b124 100644 GIT binary patch delta 1977 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 InrM&&07`2~uK)l5 delta 1962 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 Q!D!>j=TZgOR!4(m0O;#bNB{r; diff --git a/lib/slf4j/slf4j-api.pom b/lib/slf4j/slf4j-api.pom index 6e069f09..91928f15 100644 --- a/lib/slf4j/slf4j-api.pom +++ b/lib/slf4j/slf4j-api.pom @@ -3,7 +3,7 @@ <parent> <groupId>org.slf4j</groupId> <artifactId>slf4j-parent</artifactId> - <version>1.7.2</version> + <version>1.7.5</version> </parent> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> @@ -14,7 +14,7 @@ <url>http://www.qos.ch</url> </organization> <inceptionYear>2005</inceptionYear> - <!-- Copyright (c) 2004-2011 QOS.ch --> + <!-- Copyright (c) 2004-2013 QOS.ch --> <licenses> <license> <name>MIT License</name> diff --git a/plugins/android/build.xml b/plugins/android/build.xml index 784da804..18d38987 100644 --- a/plugins/android/build.xml +++ b/plugins/android/build.xml @@ -70,6 +70,7 @@ <condition property="tempdir" value="${tempdir}" else="/tmp"> <isset property="tempdit"/> </condition> + <!-- two first jars seem useless --> <property name="jarclasspath" value="slf4j/jcl-over-slf4j.jar slf4j/log4j-over-slf4j.jar slf4j/slf4j-api.jar jena/jena.jar jena/iri.jar jena/icu4j.jar xerces/xercesImpl.jar xerces/resolver.jar align.jar microalign.jar"/> <tstamp><format locale="fr,fr" pattern="dd/MM/yyyy" property="date"/></tstamp> <exec executable="svnversion" outputproperty="svn.rev" failifexecutionfails="false"/> diff --git a/src/fr/inrialpes/exmo/align/cli/CommonCLI.java b/src/fr/inrialpes/exmo/align/cli/CommonCLI.java new file mode 100644 index 00000000..442b46bf --- /dev/null +++ b/src/fr/inrialpes/exmo/align/cli/CommonCLI.java @@ -0,0 +1,147 @@ +/* + * $Id$ + * + * Copyright (C) 2013 INRIA + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + */ + +/* + * Common command line parameter parsing based on Apache commons cli wrt + */ + +package fr.inrialpes.exmo.align.cli; + +import java.util.Properties; +import java.io.FileInputStream; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import org.apache.commons.cli.CommandLine; +import org.apache.commons.cli.CommandLineParser; +import org.apache.commons.cli.PosixParser; +//import org.apache.commons.cli.GnuParser; +import org.apache.commons.cli.Options; +import org.apache.commons.cli.OptionBuilder; +import org.apache.commons.cli.ParseException; +import org.apache.commons.cli.HelpFormatter; + +/** + * For instanciating this class: + * - extends CommonCLI + * - call to super() in constructor + * - add options in constructor + * - CommandLine line = parseCommandLine( args ); in main + * - retrieve new options + * - retrieve remaining args + * - redefine usage() with specific first line + * - use parameters + */ + +public abstract class CommonCLI { + final static Logger logger = LoggerFactory.getLogger( CommonCLI.class ); + + protected Options options = null; + + protected String outputfilename = null; + + protected Properties parameters = null; + + public CommonCLI() { + parameters = new Properties(); + options = new Options(); + options.addOption( "h", "help", false, "Print this page" ); + options.addOption( OptionBuilder.withLongOpt( "output" ).hasArg().withDescription( "Send output to FILE" ).withArgName("FILE").create( 'o' ) ); + options.addOption( OptionBuilder.withLongOpt( "debug" ).hasOptionalArg().withDescription( "debug argument is deprecated, use logging instead\nSee http://alignapi.gforge.inria.fr/logging.html" ).withArgName("LEVEL").create( 'd' ) ); + options.addOption( OptionBuilder.withLongOpt( "params" ).hasArg().withDescription( "Read parameters from FILE" ).withArgName("FILE").create( 'P' ) ); + options.addOption( OptionBuilder.withArgName( "NAME=VALUE" ).hasArgs(2).withValueSeparator().withDescription( "Use value for given property" ).create( 'D' ) ); + } + + // This is an example of using the interface + private void run( String[] args ) { + parseSpecificCommandLine( args ); + // Usually do process here + } + + // This is an example of processing the arguments + // In principle, use super. + public void parseSpecificCommandLine( String[] args ) { + try { + CommandLine line = parseCommandLine( args ); + if ( line == null ) return; + // Here deal with command specific arguments + for ( Object o : line.getArgList() ) { + logger.info( " Arg: {}", o ); + } + for ( String k : parameters.stringPropertyNames() ) { + logger.info( " Param: {} = {}", k, parameters.getProperty( k ) ); + } + } catch( ParseException exp ) { + logger.error( exp.getMessage() ); + usage(); + } + } + + // In spirit, this is final + public CommandLine parseCommandLine( String[] args ) throws ParseException { + CommandLineParser parser = new PosixParser(); + CommandLine line = parser.parse( options, args ); + parameters = line.getOptionProperties( "D" ); + if ( line.hasOption( 'd' ) ) { + logger.warn( "debug command-line switch DEPRECATED, use logging" ); + } + if ( line.hasOption( 'o' ) ) { + outputfilename = line.getOptionValue( 'o' ); + } + if ( line.hasOption( 'P' ) ) { + try { + String paramfile = line.getOptionValue( 'P' ); + parameters.loadFromXML( new FileInputStream( paramfile ) ); + } catch ( Exception ex ) { + logger.warn( "Cannot parse parameter file", ex ); + } + } + if ( line.hasOption( 'h' ) ) { + usage(); + line = null; + } + return line; + } + + public void exit( int returnCode ) { + System.exit( returnCode ); + } + + // This is an example of using the interface + public abstract void usage(); + + /* + * The subclasses may define usage() by calling this: + * usage( "java "+this.getClass().getName()+" [options] alignfile\nParse the given <alignfile> and prints it\nOptions:" ); + * In spirit, this is final + */ + public void usage( String firstlines ) { + usage( firstlines, "" ); + } + public void usage( String firstlines, String footer ) { + Package pkg = this.getClass().getPackage(); + String rfooter = footer; + if ( pkg != null ) + rfooter += "\n"+pkg.getImplementationTitle()+" "+pkg.getImplementationVersion(); + new HelpFormatter().printHelp( 80, firstlines, "\nOptions:", options, rfooter ); + } +} diff --git a/src/fr/inrialpes/exmo/align/cli/EvalAlign.java b/src/fr/inrialpes/exmo/align/cli/EvalAlign.java index 6e56ca00..45a5c4c9 100644 --- a/src/fr/inrialpes/exmo/align/cli/EvalAlign.java +++ b/src/fr/inrialpes/exmo/align/cli/EvalAlign.java @@ -1,7 +1,7 @@ /* * $Id$ * - * Copyright (C) INRIA, 2003-2008, 2010-2013 + * Copyright (C) INRIA, 2003-2008, 2010-2014 * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License @@ -29,7 +29,6 @@ import fr.inrialpes.exmo.align.impl.eval.PRecEvaluator; import fr.inrialpes.exmo.align.impl.ObjectAlignment; import fr.inrialpes.exmo.align.impl.URIAlignment; -//Imported JAVA classes import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; @@ -44,8 +43,13 @@ import java.io.BufferedWriter; import java.io.OutputStreamWriter; import java.lang.reflect.InvocationTargetException; -import gnu.getopt.LongOpt; -import gnu.getopt.Getopt; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import org.apache.commons.cli.CommandLine; +import org.apache.commons.cli.Options; +import org.apache.commons.cli.OptionBuilder; +import org.apache.commons.cli.ParseException; /** A really simple utility that loads and alignment and prints it. A basic class for an OWL ontology alignment processing. The processor @@ -75,100 +79,62 @@ $Id$ @author J�r�me Euzenat */ -public class EvalAlign { +public class EvalAlign extends CommonCLI { + final static Logger logger = LoggerFactory.getLogger( EvalAlign.class ); - public static void main(String[] args) { - new EvalAlign().run( args ); + public EvalAlign() { + super(); + options.addOption( OptionBuilder.withLongOpt( "impl" ).hasArg().withDescription( "Use the given CLASS for evaluator" ).withArgName("CLASS").create( 'i' ) ); } + public static void main(String[] args) { + try { new EvalAlign().run( args ); } + catch ( Exception ex ) { ex.printStackTrace(); }; + } - public void run(String[] args) { - Properties params = new Properties(); + public void run(String[] args) throws Exception { Evaluator eval = null; String alignName1 = null; String alignName2 = null; - String filename = null; String classname = null; PrintWriter writer = null; - LongOpt[] longopts = new LongOpt[7]; - int debug = 0; - - // abcdefghijklmnopqrstuvwxyz? - // x x i x x x x x - longopts[0] = new LongOpt("help", LongOpt.NO_ARGUMENT, null, 'h'); - longopts[1] = new LongOpt("output", LongOpt.REQUIRED_ARGUMENT, null, 'o'); - longopts[2] = new LongOpt("debug", LongOpt.OPTIONAL_ARGUMENT, null, 'd'); - longopts[3] = new LongOpt("D", LongOpt.REQUIRED_ARGUMENT, null, 'D'); - longopts[4] = new LongOpt("impl", LongOpt.REQUIRED_ARGUMENT, null, 'i'); - - Getopt g = new Getopt("", args, "ho:d::i:D:", longopts); - int c; - String arg; - - while ((c = g.getopt()) != -1) { - switch(c) { - case 'h': - usage(); - return; - case 'o': - /* Output */ - filename = g.getOptarg(); - break; - case 'i': - /* Evaluator class */ - classname = g.getOptarg(); - break; - case 'd': - /* Debug level */ - arg = g.getOptarg(); - if ( arg != null ) debug = Integer.parseInt(arg.trim()); - else debug = 4; - break; - case 'D' : - /* Parameter definition */ - arg = g.getOptarg(); - int index = arg.indexOf('='); - if ( index != -1 ) { - params.setProperty( arg.substring( 0, index), - arg.substring(index+1)); - } else { - System.err.println("Bad parameter syntax: "+g); - usage(); - System.exit(0); - } - break; - } - } - - int i = g.getOptind(); + CommandLine line = null; - params.setProperty( "debug", Integer.toString( debug ) ); - // debug = Integer.parseInt( params.getProperty("debug") ); - - if (args.length > i+1 ) { - alignName1 = args[i]; - alignName2 = args[i+1]; + try { + line = parseCommandLine( args ); + if ( line == null ) return; // --help + } catch( ParseException exp ) { + logger.error( "Cannot parse command line", exp ); + usage(); + System.exit(-1); + } + if ( line.hasOption( 'i' ) ) classname = line.getOptionValue( 'i' ); + String[] argList = line.getArgs(); + if ( argList.length > 1 ) { + alignName1 = argList[0]; + alignName2 = argList[1]; } else { - System.err.println("Require two alignement filenames"); + logger.error( "Require the alignment URIs" ); usage(); - return; + System.exit(-1); } - if ( debug > 1 ) System.err.println(" Filename"+alignName1+"/"+alignName2); + logger.debug(" Filename: {}/{}", alignName1, alignName2); - Alignment align1=null, align2 = null; + Alignment align1 = null, align2 = null; try { // Load alignments - AlignmentParser aparser = new AlignmentParser( debug ); + AlignmentParser aparser = new AlignmentParser(); align1 = aparser.parse( alignName1 ); - if ( debug > 0 ) System.err.println(" Alignment structure1 parsed"); + //logger.trace(" Alignment structure1 parsed"); aparser.initAlignment( null ); align2 = aparser.parse( alignName2 ); - if ( debug > 0 ) System.err.println(" Alignment structure2 parsed"); - } catch ( Exception ex ) { ex.printStackTrace(); } + //logger.trace(" Alignment structure2 parsed"); + } catch ( Exception ex ) { + ex.printStackTrace(); + } - boolean totry = true; - try { + boolean totry = true; // 2013: This should not be necessary anymore while ( totry ) { totry = false; if ( classname != null ) { @@ -181,23 +147,23 @@ public class EvalAlign { java.lang.reflect.Constructor evaluatorConstructor = evaluatorClass.getConstructor(cparams); eval = (Evaluator)evaluatorConstructor.newInstance(mparams); } catch (ClassNotFoundException ex) { - ex.printStackTrace(); + logger.debug( "IGNORED Exception", ex ); } catch (InstantiationException ex) { - ex.printStackTrace(); + logger.debug( "IGNORED Exception", ex ); } catch (InvocationTargetException ex) { - ex.printStackTrace(); + logger.debug( "IGNORED Exception", ex ); } catch (IllegalAccessException ex) { - ex.printStackTrace(); + logger.debug( "IGNORED Exception", ex ); } catch (NoSuchMethodException ex) { - ex.printStackTrace(); + logger.error( "No such method: {}", classname ); usage(); - return; + throw( ex ); } } else { eval = new PRecEvaluator( align1, align2 ); }; // Compare try { - eval.eval(params) ; + eval.eval( parameters ) ; } catch ( AlignmentException aex ) { if ( align1 instanceof ObjectAlignment ) { throw aex; @@ -210,25 +176,24 @@ public class EvalAlign { } } } - } catch ( Exception ex ) { ex.printStackTrace(); } // Set output file try { OutputStream stream; - if (filename == null) { + if ( outputfilename == null ) { //writer = (PrintStream) System.out; stream = System.out; } else { //writer = new PrintStream(new FileOutputStream(filename)); - stream = new FileOutputStream(filename); + stream = new FileOutputStream( outputfilename ); } writer = new PrintWriter ( new BufferedWriter( new OutputStreamWriter( stream, "UTF-8" )), true); eval.write( writer ); } catch ( IOException ex ) { - ex.printStackTrace(); + logger.debug( "IGNORED Exception", ex ); } finally { writer.flush(); writer.close(); @@ -236,15 +201,6 @@ public class EvalAlign { } public void usage() { - System.err.println("usage: EvalAlign [options] file1 file2"); - System.err.println("options are:"); - System.err.println("\t--debug[=n] -d [n]\t\tReport debug info at level n"); - System.err.println("\t--impl=className -i classname\t\tUse the given evaluator implementation."); - System.err.println("\t--output=filename -o filename\tOutput the result in filename"); - System.err.println("\t-Dparam=value\t\t\tSet parameter"); - System.err.println("\t--help -h\t\t\tPrint this message"); - System.err.print("\n"+EvalAlign.class.getPackage().getImplementationTitle()+" "+EvalAlign.class.getPackage().getImplementationVersion()); - System.err.println(" ($Id$)\n"); - + usage( "java "+this.getClass().getName()+" [options] alignURI alignURI\nEvaluate two alignments identified by <alignURI>" ); } } diff --git a/src/fr/inrialpes/exmo/align/cli/ExtGroupEval.java b/src/fr/inrialpes/exmo/align/cli/ExtGroupEval.java index 200241ae..5547dfdf 100644 --- a/src/fr/inrialpes/exmo/align/cli/ExtGroupEval.java +++ b/src/fr/inrialpes/exmo/align/cli/ExtGroupEval.java @@ -1,9 +1,7 @@ /* * $Id$ * - * Copyright (C) 2003 The University of Manchester - * Copyright (C) 2003 The University of Karlsruhe - * Copyright (C) 2003-2005, 2007-2012 INRIA + * Copyright (C) 2003-2005, 2007-2014 INRIA * Copyright (C) 2004, Universit� de Montr�al * * This program is free software; you can redistribute it and/or @@ -52,8 +50,14 @@ import java.util.Properties; import org.xml.sax.SAXException; -import gnu.getopt.LongOpt; -import gnu.getopt.Getopt; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import org.apache.commons.cli.CommandLine; +import org.apache.commons.cli.Options; +import org.apache.commons.cli.Option; +import org.apache.commons.cli.OptionBuilder; +import org.apache.commons.cli.ParseException; /** A basic class for synthesizing the results of a set of alignments provided by different algorithms. The output is a table showing various generalisations @@ -68,7 +72,6 @@ import gnu.getopt.Getopt; <pre> -o filename --output=filename -f format = sepr (symetric/effort-based/precision-oriented/recall-oriented) --format=sepr - -d debug --debug=level -r filename --reference=filename -s algo/measure -l list of compared algorithms @@ -87,106 +90,64 @@ import gnu.getopt.Getopt; $Id$ </pre> -@author Sean K. Bechhofer -@author J�r�me Euzenat */ -public class ExtGroupEval { +public class ExtGroupEval extends CommonCLI { + final static Logger logger = LoggerFactory.getLogger( ExtGroupEval.class ); - Properties params = null; - String filename = null; String reference = "refalign.rdf"; String format = "s"; int fsize = 2; String type = "html"; boolean embedded = false; - String dominant = "s"; - Vector<String> listAlgo = null; - int debug = 0; + //String dominant = "s"; + String[] listAlgo = null; + int size = 0; String color = null; String ontoDir = null; + public ExtGroupEval() { + super(); + options.addOption( OptionBuilder.withLongOpt( "list" ).hasArgs().withValueSeparator(',').withDescription( "List of FILEs to be included in the results (required)" ).withArgName("FILE").create( 'l' ) ); + options.addOption( OptionBuilder.withLongOpt( "color" ).hasOptionalArg().withDescription( "Color even lines of the output in COLOR (default: lightblue)" ).withArgName("COLOR").create( 'c' ) ); + options.addOption( OptionBuilder.withLongOpt( "format" ).hasArg().withDescription( "Extended MEASures and order (symetric/effort-based/precision-oriented/recall-oriented) (default: "+format+")" ).withArgName("MEAS (sepr)").create( 'f' ) ); + //options.addOption( OptionBuilder.withLongOpt( "type" ).hasArg().withDescription( "Output TYPE (html|xml|tex|ascii|triangle; default: "+type+")" ).withArgName("TYPE").create( 't' ) ); + options.addOption( OptionBuilder.withLongOpt( "type" ).hasArg().withDescription( "Output TYPE (only html available so far)" ).withArgName("TYPE").create( 't' ) ); + //options.addOption( OptionBuilder.withLongOpt( "sup" ).hasArg().withDescription( "Are dominant columns algorithms or measure (default: s)" ).withArgName("algo").create( 's' ) ); + options.addOption( OptionBuilder.withLongOpt( "reference" ).hasArg().withDescription( "Name of the reference alignment FILE (default: "+reference+")" ).withArgName("FILE").create( 'r' ) ); + options.addOption( OptionBuilder.withLongOpt( "directory" ).hasOptionalArg().withDescription( "The DIRectory containing the data to evaluate" ).withArgName("DIR").create( 'w' ) ); + // .setRequired( true ) + Option opt = options.getOption( "list" ); + if ( opt != null ) opt.setRequired( true ); + } + public static void main(String[] args) { try { new ExtGroupEval().run( args ); } catch (Exception ex) { ex.printStackTrace(); }; } public void run(String[] args) throws Exception { - String listFile = ""; - LongOpt[] longopts = new LongOpt[10]; - - longopts[0] = new LongOpt("help", LongOpt.NO_ARGUMENT, null, 'h'); - longopts[1] = new LongOpt("output", LongOpt.REQUIRED_ARGUMENT, null, 'o'); - longopts[2] = new LongOpt("format", LongOpt.REQUIRED_ARGUMENT, null, 'f'); - longopts[3] = new LongOpt("type", LongOpt.REQUIRED_ARGUMENT, null, 't'); - longopts[4] = new LongOpt("debug", LongOpt.OPTIONAL_ARGUMENT, null, 'd'); - longopts[5] = new LongOpt("sup", LongOpt.REQUIRED_ARGUMENT, null, 's'); - longopts[6] = new LongOpt("list", LongOpt.REQUIRED_ARGUMENT, null, 'l'); - longopts[7] = new LongOpt("color", LongOpt.OPTIONAL_ARGUMENT, null, 'c'); - longopts[8] = new LongOpt("reference", LongOpt.REQUIRED_ARGUMENT, null, 'r'); - longopts[9] = new LongOpt("directory", LongOpt.REQUIRED_ARGUMENT, null, 'w'); + try { + CommandLine line = parseCommandLine( args ); + if ( line == null ) return; // --help - Getopt g = new Getopt("", args, "ho:a:d::l:f:t:r:w:c::", longopts); - int c; - String arg; - - while ((c = g.getopt()) != -1) { - switch (c) { - case 'h' : - usage(); - return; - case 'o' : - /* Write output here */ - filename = g.getOptarg(); - break; - case 'r' : - /* File name for the reference alignment */ - reference = g.getOptarg(); - break; - case 'f' : - /* Sequence of results to print */ - format = g.getOptarg(); - break; - case 't' : - /* Type of output (tex/html/xml/ascii) */ - type = g.getOptarg(); - break; - case 's' : - /* Print per type or per algo */ - dominant = g.getOptarg(); - break; - case 'c' : - /* Print colored lines */ - color = "lightblue"; - //dominant = g.getOptarg(); - break; - case 'l' : - /* List of filename */ - listFile = g.getOptarg(); - break; - case 'd' : - /* Debug level */ - arg = g.getOptarg(); - if ( arg != null ) debug = Integer.parseInt(arg.trim()); - else debug = 4; - break; - case 'w' : - /* Use the given ontology directory */ - arg = g.getOptarg(); - if ( arg != null ) ontoDir = g.getOptarg(); - else ontoDir = null; - break; + // Here deal with command specific arguments + if ( line.hasOption( 'f' ) ) format = line.getOptionValue( 'f' ); + if ( line.hasOption( 'r' ) ) reference = line.getOptionValue( 'r' ); + //if ( line.hasOption( 's' ) ) dominant = line.getOptionValue( 's' ); + if ( line.hasOption( 't' ) ) type = line.getOptionValue( 't' ); + if ( line.hasOption( 'c' ) ) color = line.getOptionValue( 'c', "lightblue" ); + if ( line.hasOption( 'l' ) ) { + listAlgo = line.getOptionValues( 'l' ); + size = listAlgo.length; } + if ( line.hasOption( 'w' ) ) ontoDir = line.getOptionValue( 'w' ); + } catch( ParseException exp ) { + logger.error( exp.getMessage() ); + usage(); + System.exit( -1 ); } - listAlgo = new Vector<String>(); - for ( String s : listFile.split(",") ) { - listAlgo.add( s ); - } - - params = new Properties(); - if (debug > 0) params.setProperty( "debug", Integer.toString( debug-1 ) ); - print( iterateDirectories() ); } @@ -200,7 +161,7 @@ public class ExtGroupEval { subdir = (new File(ontoDir)).listFiles(); } } catch (Exception e) { - System.err.println("Cannot stat dir "+ e.getMessage()); + logger.error("Cannot stat dir", e); usage(); } int size = subdir.length; @@ -209,7 +170,7 @@ public class ExtGroupEval { int i = 0; for ( int j=0 ; j < size; j++ ) { if( subdir[j].isDirectory() ) { - if ( debug > 0 ) System.err.println("\nEntering directory "+subdir[j]); + //logger.trace("Entering directory {}", subdir[j]); // eval the alignments in a subdirectory // store the result Vector vect = (Vector)iterateAlignments( subdir[j] ); @@ -234,7 +195,7 @@ public class ExtGroupEval { // call eval // store the result in a record // return the record. - if ( debug > 1) System.err.println(" Considering result "+i); + //logger.trace(" Considering result {}", i); Evaluator evaluator = eval( prefix+reference, prefix+m+".rdf"); if ( evaluator != null ) ok = true; result.add( i, evaluator ); @@ -242,8 +203,8 @@ public class ExtGroupEval { // Unload the ontologies. try { OntologyFactory.clear(); - } catch ( OntowrapException owex ) { // only report - owex.printStackTrace(); + } catch ( OntowrapException owex ) { + logger.debug( "INGORED Exception", owex ); } if ( ok == true ) return result; @@ -253,29 +214,20 @@ public class ExtGroupEval { public Evaluator eval( String alignName1, String alignName2 ) { Evaluator eval = null; try { - int nextdebug; - if ( debug < 2 ) nextdebug = 0; - else nextdebug = debug - 2; // Load alignments - AlignmentParser aparser = new AlignmentParser( nextdebug ); + AlignmentParser aparser = new AlignmentParser(); Alignment align1 = aparser.parse( alignName1 ); - if ( debug > 1 ) System.err.println(" Alignment structure1 parsed"); + //logger.trace(" Alignment structure1 parsed"); aparser.initAlignment( null ); Alignment align2 = aparser.parse( alignName2 ); - if ( debug > 1 ) System.err.println(" Alignment structure2 parsed"); + //logger.trace(" Alignment structure2 parsed"); // Create evaluator object eval = new ExtPREvaluator(ObjectAlignment.toObjectAlignment( (URIAlignment)align1 ), ObjectAlignment.toObjectAlignment( (URIAlignment)align2 ) ); // Compare - params.setProperty( "debug", Integer.toString( nextdebug ) ); - eval.eval( params ) ; + eval.eval( parameters ) ; } catch (Exception ex) { - if ( debug > 1 ) { - ex.printStackTrace(); - } else { - System.err.println("ExtGroupEval: "+ex); - System.err.println(alignName1+ " - "+alignName2 ); - } + logger.debug( "IGNORED Extension", ex ); }; return eval; } @@ -284,6 +236,23 @@ public class ExtGroupEval { * This does not only print the results but compute the average as well */ public void print( Vector<Vector> result ) { + PrintStream writer = null; + try { + if ( outputfilename == null ) { + writer = System.out; + } else { + writer = new PrintStream( new FileOutputStream( outputfilename ) ); + } + + printHTML( result, writer ); + } catch (Exception ex) { + logger.debug( "IGNORED Exception", ex ); + } finally { + writer.close(); + } + } + + public void printHTML( Vector<Vector> result, PrintStream writer ) { // variables for computing iterative harmonic means int expected = 0; // expected so far int foundVect[]; // found so far @@ -291,17 +260,10 @@ public class ExtGroupEval { double effVect[]; // effort-based similarity double precOrVect[]; // precision-oriented similarity double recOrVect[]; // recall-oriented similarity - PrintStream writer = null; fsize = format.length(); try { - // Print result - if ( filename == null ) { - writer = System.out; - } else { - writer = new PrintStream(new FileOutputStream( filename )); - } - Formatter formatter = new Formatter(writer); + Formatter formatter = new Formatter( writer ); // Print the header writer.println("<html><head></head><body>"); writer.println("<table border='2' frame='sides' rules='groups'>"); @@ -333,12 +295,12 @@ public class ExtGroupEval { //writer.println("<td>Prec.</td><td>Rec.</td>"); } writer.println("</tr></tbody><tbody>"); - foundVect = new int[ listAlgo.size() ]; - symVect = new double[ listAlgo.size() ]; - effVect = new double[ listAlgo.size() ]; - precOrVect = new double[ listAlgo.size() ]; - recOrVect = new double[ listAlgo.size() ]; - for( int k = listAlgo.size()-1; k >= 0; k-- ) { + foundVect = new int[ size ]; + symVect = new double[ size ]; + effVect = new double[ size ]; + precOrVect = new double[ size ]; + recOrVect = new double[ size ]; + for( int k = size-1; k >= 0; k-- ) { foundVect[k] = 0; symVect[k] = 0.; effVect[k] = 0.; @@ -376,29 +338,29 @@ public class ExtGroupEval { writer.print("<td>"); if ( format.charAt(i) == 's' ) { formatter.format("%1.2f", eval.getSymPrecision()); - System.out.print("</td><td>"); + writer.print("</td><td>"); formatter.format("%1.2f", eval.getSymRecall()); symVect[k] += eval.getSymSimilarity(); } else if ( format.charAt(i) == 'e' ) { formatter.format("%1.2f", eval.getEffPrecision()); - System.out.print("</td><td>"); + writer.print("</td><td>"); formatter.format("%1.2f", eval.getEffRecall()); effVect[k] += eval.getEffSimilarity(); } else if ( format.charAt(i) == 'p' ) { formatter.format("%1.2f", eval.getPrecisionOrientedPrecision()); - System.out.print("</td><td>"); + writer.print("</td><td>"); formatter.format("%1.2f", eval.getPrecisionOrientedRecall()); precOrVect[k] += eval.getPrecisionOrientedSimilarity(); } else if ( format.charAt(i) == 'r' ) { formatter.format("%1.2f", eval.getRecallOrientedPrecision()); - System.out.print("</td><td>"); + writer.print("</td><td>"); formatter.format("%1.2f", eval.getRecallOrientedRecall()); recOrVect[k] += eval.getRecallOrientedSimilarity(); } - writer.println("</td>"); + writer.print("</td>"); } } else { - writer.println("<td>n/a</td><td>n/a</td>"); + for ( int i = 0 ; i < fsize; i++) writer.print("<td>n/a</td>"); } } writer.println("</tr>"); @@ -411,19 +373,19 @@ public class ExtGroupEval { writer.print("<td>"); if ( format.charAt(i) == 's' ) { formatter.format("%1.2f", symVect[k]/foundVect[k]); - System.out.print("</td><td>"); + writer.print("</td><td>"); formatter.format("%1.2f", symVect[k]/expected); } else if ( format.charAt(i) == 'e' ) { formatter.format("%1.2f", effVect[k]/foundVect[k]); - System.out.print("</td><td>"); + writer.print("</td><td>"); formatter.format("%1.2f", effVect[k]/expected); } else if ( format.charAt(i) == 'p' ) { formatter.format("%1.2f", precOrVect[k]/foundVect[k]); - System.out.print("</td><td>"); + writer.print("</td><td>"); formatter.format("%1.2f", precOrVect[k]/expected); } else if ( format.charAt(i) == 'r' ) { formatter.format("%1.2f", recOrVect[k]/foundVect[k]); - System.out.print("</td><td>"); + writer.print("</td><td>"); formatter.format("%1.2f", recOrVect[k]/expected); } writer.println("</td>"); @@ -440,7 +402,7 @@ public class ExtGroupEval { writer.println("NaN: division per zero, likely due to empty alignent.</small></p>"); writer.println("</body></html>"); } catch (Exception ex) { - ex.printStackTrace(); + logger.debug( "IGNORED Exception", ex ); } finally { writer.flush(); writer.close(); @@ -448,19 +410,6 @@ public class ExtGroupEval { } public void usage() { - System.out.println("usage: ExtGroupEval [options]"); - System.out.println("options are:"); - System.out.println("\t--format=sepr -f sepr\tSpecifies the extended measures used (symetric/effort-based/precision-oriented/recall-oriented)"); - System.out.println("\t--reference=filename -r filename\tSpecifies the name of the reference alignment file (default: refalign.rdf)"); - System.out.println("\t--output=filename -o filename\tSpecifies a file to which the output will go"); - // Apparently not implemented - //System.out.println("\t--dominant=algo -s algo\tSpecifies if dominant columns are algorithms or measure"); - System.out.println("\t--type=html|xml|tex|ascii -t html|xml|tex|ascii\tSpecifies the output format"); - System.out.println("\t--list=algo1,...,algon -l algo1,...,algon\tSequence of the filenames to consider"); - System.out.println("\t--color=color -c color\tSpecifies if the output must color even lines of the output"); - System.out.println("\t--debug[=n] -d [n]\t\tReport debug info at level n"); - System.out.println("\t--help -h\t\t\tPrint this message"); - System.err.print("\n"+ExtGroupEval.class.getPackage().getImplementationTitle()+" "+ExtGroupEval.class.getPackage().getImplementationVersion()); - System.err.println(" ($Id$)\n"); + usage( "java "+this.getClass().getName()+" [options]\nEvaluates (with extended evaluators) in parallel several matching results on several tests in subdirectories" ); } } diff --git a/src/fr/inrialpes/exmo/align/cli/GenPlot.java b/src/fr/inrialpes/exmo/align/cli/GenPlot.java index 9d82165c..f2a92e13 100644 --- a/src/fr/inrialpes/exmo/align/cli/GenPlot.java +++ b/src/fr/inrialpes/exmo/align/cli/GenPlot.java @@ -1,7 +1,7 @@ /* * $Id$ * - * Copyright (C) 2003-2012, INRIA + * Copyright (C) 2003-2014, INRIA * Copyright (C) 2004, Universit� de Montr�al * * This program is free software; you can redistribute it and/or @@ -51,8 +51,14 @@ import java.lang.InstantiationException; import org.xml.sax.SAXException; -import gnu.getopt.LongOpt; -import gnu.getopt.Getopt; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import org.apache.commons.cli.CommandLine; +import org.apache.commons.cli.Options; +import org.apache.commons.cli.Option; +import org.apache.commons.cli.OptionBuilder; +import org.apache.commons.cli.ParseException; import fr.inrialpes.exmo.align.parser.AlignmentParser; @@ -71,7 +77,6 @@ import fr.inrialpes.exmo.align.parser.AlignmentParser; * where the options are: * <pre> * -o filename --output=filename - * -d debug --debug=level * -l list of compared algorithms * -t output --type=output: xml/tex/html/ascii * -e classname --evaluator=classname @@ -93,22 +98,33 @@ import fr.inrialpes.exmo.align.parser.AlignmentParser; * @author J�r�me Euzenat */ -public class GenPlot { +public class GenPlot extends CommonCLI { + final static Logger logger = LoggerFactory.getLogger( GenPlot.class ); int STEP = 10; - Properties params = new Properties(); - Vector<String> listAlgo; + String[] listAlgo = null; Vector<GraphEvaluator> listEvaluators; String fileNames = ""; - String outFile = null; Constructor evalConstructor = null; Constructor graphConstructor = null; String xlabel; String ylabel; - String type = "tsv"; - int debug = 0; + String type = "tex"; int size = 0; // the set of algo to compare - PrintWriter output = null; + String ontoDir = null; + + public GenPlot() { + super(); + options.addOption( OptionBuilder.withLongOpt( "list" ).hasArgs().withValueSeparator(',').withDescription( "List of FILEs to be included in the results (required)" ).withArgName("FILE").create( 'l' ) ); + options.addOption( OptionBuilder.withLongOpt( "type" ).hasArg().withDescription( "Output in the specified FORMAT (values" ).withArgName("tsv|tex|html(|xml)").create( 't' ) ); + options.addOption( OptionBuilder.withLongOpt( "evaluator" ).hasArg().withDescription( "Use CLASS as evaluation plotter" ).withArgName("CLASS").create( 'e' ) ); + options.addOption( OptionBuilder.withLongOpt( "grapher" ).hasArg().withDescription( "Use CLASS as graph generator" ).withArgName("CLASS").create( 'g' ) ); + //options.addOption( OptionBuilder.withLongOpt( "step" ).hasArg().withDescription( "" ).withArgName("").create( 's' ) ); + options.addOption( OptionBuilder.withLongOpt( "directory" ).hasOptionalArg().withDescription( "The DIRectory containing the data to match" ).withArgName("DIR").create( 'w' ) ); + // .setRequired( true ) + Option opt = options.getOption( "list" ); + if ( opt != null ) opt.setRequired( true ); + } public static void main(String[] args) { try { new GenPlot().run( args ); } @@ -116,74 +132,26 @@ public class GenPlot { } public void run(String[] args) throws Exception { - LongOpt[] longopts = new LongOpt[10]; - - longopts[0] = new LongOpt("help", LongOpt.NO_ARGUMENT, null, 'h'); - longopts[1] = new LongOpt("output", LongOpt.REQUIRED_ARGUMENT, null, 'o'); - longopts[3] = new LongOpt("type", LongOpt.REQUIRED_ARGUMENT, null, 't'); - longopts[4] = new LongOpt("debug", LongOpt.OPTIONAL_ARGUMENT, null, 'd'); - longopts[5] = new LongOpt("evaluator", LongOpt.REQUIRED_ARGUMENT, null, 'e'); - longopts[6] = new LongOpt("grapher", LongOpt.REQUIRED_ARGUMENT, null, 'g'); - longopts[7] = new LongOpt("list", LongOpt.REQUIRED_ARGUMENT, null, 'l'); - longopts[8] = new LongOpt("step", LongOpt.REQUIRED_ARGUMENT, null, 's'); - longopts[9] = new LongOpt("D", LongOpt.REQUIRED_ARGUMENT, null, 'D'); - - Getopt g = new Getopt("", args, "ho:d::l:D:e:g:s:t:", longopts); - int step = 10; - int c; - String arg; String evalCN = "fr.inrialpes.exmo.align.impl.eval.PRecEvaluator"; String graphCN = "fr.inrialpes.exmo.align.impl.eval.PRGraphEvaluator"; - while ((c = g.getopt()) != -1) { - switch (c) { - case 'h' : - usage(); - return; - case 'o' : - /* Write output here */ - outFile = g.getOptarg(); - break; - case 'e' : - /* Name of the evaluator to use */ - evalCN = g.getOptarg(); - break; - case 'g' : - /* Name of the graph display to use */ - graphCN = g.getOptarg(); - break; - case 't' : - /* Type of output (tex/tsv(/html/xml/ascii)) */ - type = g.getOptarg(); - break; - case 'l' : - /* List of filename */ - fileNames = g.getOptarg(); - break; - //case 's' : - /* Step */ - //fileNames = g.getOptarg(); - //break; - case 'd' : - /* Debug level */ - arg = g.getOptarg(); - if ( arg != null ) debug = Integer.parseInt(arg.trim()); - else debug = 4; - break; - case 'D' : - /* Parameter definition */ - arg = g.getOptarg(); - int index = arg.indexOf('='); - if ( index != -1 ) { - params.setProperty( arg.substring( 0, index), - arg.substring(index+1)); - } else { - System.err.println("Bad parameter syntax: "+g); - usage(); - System.exit(0); - } - break; + try { + CommandLine line = parseCommandLine( args ); + if ( line == null ) return; // --help + + // Here deal with command specific arguments + if ( line.hasOption( 'e' ) ) evalCN = line.getOptionValue( 'e' ); + if ( line.hasOption( 'g' ) ) graphCN = line.getOptionValue( 'g' ); + if ( line.hasOption( 't' ) ) type = line.getOptionValue( 't' ); + if ( line.hasOption( 'l' ) ) { + listAlgo = line.getOptionValues( 'l' ); + size = listAlgo.length; } + if ( line.hasOption( 'w' ) ) ontoDir = line.getOptionValue( 'w' ); + } catch( ParseException exp ) { + logger.error( exp.getMessage() ); + usage(); + System.exit(-1); } Class<?> graphClass = Class.forName(graphCN); @@ -193,14 +161,6 @@ public class GenPlot { //Class<?> evalClass = Class.forName(evalCN); //evalConstructor = evalClass.getConstructor( cparams ); - listAlgo = new Vector<String>(); - for ( String s : fileNames.split(",") ) { - size++; - listAlgo.add( s ); - } - - if (debug > 0) params.setProperty( "debug", Integer.toString( debug-1 ) ); - // Collect correspondences from alignments in all directories // . -> Vector<EvalCell> listEvaluators = iterateDirectories(); @@ -211,7 +171,7 @@ public class GenPlot { int n = e.nbCells(); if ( n > max ) max = n; } - params.setProperty( "scale", Integer.toString( max ) ); + parameters.setProperty( "scale", Integer.toString( max ) ); xlabel = listEvaluators.get(0).xlabel(); ylabel = listEvaluators.get(0).ylabel(); @@ -223,18 +183,18 @@ public class GenPlot { for( int i = 0; i < size ; i++ ) { // Convert it with the adequate GraphPlotter // Scale the point pairs to the current display (local) - toplot.add( i, listEvaluators.get(i).eval( params ) ); + toplot.add( i, listEvaluators.get(i).eval( parameters ) ); //scaleResults( STEP, } // Set output file OutputStream stream; - if (outFile == null) { + if ( outputfilename == null) { stream = System.out; } else { - stream = new FileOutputStream(outFile); + stream = new FileOutputStream( outputfilename ); } - output = new PrintWriter ( + PrintWriter writer = new PrintWriter ( new BufferedWriter( new OutputStreamWriter( stream, "UTF-8" )), true); @@ -242,12 +202,16 @@ public class GenPlot { // Display the required type of output // Vector<Pair> -> . if ( type.equals("tsv") ){ - printTSV( toplot ); + printTSV( toplot, writer ); } else if ( type.equals("html") ) { - printHTMLGGraph( toplot ); + printHTMLGGraph( toplot, writer ); } else if ( type.equals("tex") ) { - printPGFTex( toplot ); - } else System.err.println("Flag -t "+type+" : not implemented yet"); + printPGFTex( toplot, writer ); + } else { + logger.error( "Flag -t {} : not implemented yet", type ); + usage(); + System.exit(-1); + } } /** @@ -265,17 +229,22 @@ public class GenPlot { ev.setStep( STEP ); evaluators.add( i, ev ); } - } catch (Exception ex) { //InstantiationException, IllegalAccessException - ex.printStackTrace(); + } catch ( Exception ex ) { //InstantiationException, IllegalAccessException + logger.error( "FATAL Exception", ex ); System.exit(-1); } File [] subdir = null; try { - subdir = (new File(System.getProperty("user.dir"))).listFiles(); - } catch (Exception e) { - System.err.println("Cannot stat dir "+ e.getMessage()); + if (ontoDir == null) { + subdir = (new File(System.getProperty("user.dir"))).listFiles(); + } else { + subdir = (new File(ontoDir)).listFiles(); + } + } catch ( Exception e ) { + logger.error( "Cannot stat dir", e ); usage(); + System.exit(-1); } // Evaluate the results in each directory @@ -289,42 +258,31 @@ public class GenPlot { } public void iterateAlignments ( File dir, Vector<GraphEvaluator> evaluators ) { - if ( debug > 0 ) System.err.println("Directory : "+dir); + //logger.trace( "Directory : {}", dir ); String prefix = dir.toURI().toString()+"/"; - int nextdebug; - if ( debug < 2 ) nextdebug = 0; - else nextdebug = debug - 2; - AlignmentParser aparser = new AlignmentParser( nextdebug ); + AlignmentParser aparser = new AlignmentParser(); Alignment refalign = null; try { // Load the reference alignment... refalign = aparser.parse( prefix+"refalign.rdf" ); - if ( debug > 1 ) System.err.println(" Reference alignment parsed"); + //logger.trace(" Reference alignment parsed"); } catch ( Exception aex ) { - if ( debug > 1 ) { - aex.printStackTrace(); - } else { - System.err.println("GenPlot cannot parse refalign : "+aex); - }; - return; + logger.error( "GenPlot cannot parse refalign", aex ); + System.exit(-1); } // for all alignments there, for( int i = 0; i < size; i++ ) { - String algo = listAlgo.get(i); + String algo = listAlgo[i]; Alignment al = null; - if ( debug > 0 ) System.err.println(" Considering result "+algo+" ("+i+")"); + //logger.trace(" Considering result {} ({})", algo, i ); try { aparser.initAlignment( null ); al = aparser.parse( prefix+algo+".rdf" ); - if ( debug > 1 ) System.err.println(" Alignment "+algo+" parsed"); - } catch (Exception ex) { - if ( debug > 1 ) { - ex.printStackTrace(); - } else { - System.err.println("GenPlot: "+ex); - }; + //logger.trace(" Alignment {} parsed", algo ); + } catch ( Exception ex ) { + logger.error( "IGNORED Exception", ex ); } // even if empty, declare refalign evaluators.get(i).ingest( al, refalign ); @@ -333,7 +291,7 @@ public class GenPlot { try { OntologyFactory.clear(); } catch ( OntowrapException owex ) { // only report - owex.printStackTrace(); + logger.error( "IGNORED Exception", owex ); } } @@ -370,86 +328,86 @@ public class GenPlot { * This does average plus plot * */ - public void printPGFTex( Vector<Vector<Pair>> result ){ + public void printPGFTex( Vector<Vector<Pair>> result, PrintWriter writer ){ int i = 0; String marktable[] = { "+", "*", "x", "-", "|", "o", "asterisk", "star", "oplus", "oplus*", "otimes", "otimes*", "square", "square*", "triangle", "triangle*", "diamond", "diamond*", "pentagon", "pentagon*"}; String colortable[] = { "black", "red", "green!50!black", "blue", "cyan", "magenta" } ; - output.println("\\documentclass[11pt]{book}"); - output.println(); - output.println("\\usepackage{pgf}"); - output.println("\\usepackage{tikz}"); - output.println("\\usetikzlibrary{plotmarks}"); - output.println(); - output.println("\\begin{document}"); - output.println("\\date{today}"); - output.println(""); - output.println("\n%% Plot generated by GenPlot of alignapi"); - output.println("\\begin{tikzpicture}[cap=round]"); - output.println("% Draw grid"); - output.println("\\draw[step="+(STEP/10)+"cm,very thin,color=gray] (-0.2,-0.2) grid ("+STEP+","+STEP+");"); - output.println("\\draw[->] (-0.2,0) -- (10.2,0);"); - output.println("\\draw (5,-0.3) node {$"+xlabel+"$}; "); - output.println("\\draw (0,-0.3) node {0.}; "); - output.println("\\draw (10,-0.3) node {1.}; "); - output.println("\\draw[->] (0,-0.2) -- (0,10.2);"); - output.println("\\draw (-0.3,0) node {0.}; "); - output.println("\\draw (-0.3,5) node[rotate=90] {$"+ylabel+"$}; "); - output.println("\\draw (-0.3,10) node {1.}; "); - output.println("% Plots"); + writer.println("\\documentclass[11pt]{book}"); + writer.println(); + writer.println("\\usepackage{pgf}"); + writer.println("\\usepackage{tikz}"); + writer.println("\\usetikzlibrary{plotmarks}"); + writer.println(); + writer.println("\\begin{document}"); + writer.println("\\date{today}"); + writer.println(""); + writer.println("\n%% Plot generated by GenPlot of alignapi"); + writer.println("\\begin{tikzpicture}[cap=round]"); + writer.println("% Draw grid"); + writer.println("\\draw[step="+(STEP/10)+"cm,very thin,color=gray] (-0.2,-0.2) grid ("+STEP+","+STEP+");"); + writer.println("\\draw[->] (-0.2,0) -- (10.2,0);"); + writer.println("\\draw (5,-0.3) node {$"+xlabel+"$}; "); + writer.println("\\draw (0,-0.3) node {0.}; "); + writer.println("\\draw (10,-0.3) node {1.}; "); + writer.println("\\draw[->] (0,-0.2) -- (0,10.2);"); + writer.println("\\draw (-0.3,0) node {0.}; "); + writer.println("\\draw (-0.3,5) node[rotate=90] {$"+ylabel+"$}; "); + writer.println("\\draw (-0.3,10) node {1.}; "); + writer.println("% Plots"); i = 0; for ( String m : listAlgo ) { - output.print("\\draw["+colortable[i%6] ); - if ( !listEvaluators.get(i).isValid() ) output.print(",dotted"); - output.println("] plot[mark="+marktable[i%19]+"] file {"+m+".table};"); + writer.print("\\draw["+colortable[i%6] ); + if ( !listEvaluators.get(i).isValid() ) writer.print(",dotted"); + writer.println("] plot[mark="+marktable[i%19]+"] file {"+m+".table};"); //,smooth i++; } // And a legend - output.println("% Legend"); + writer.println("% Legend"); i = 0; for ( String m : listAlgo ) { - output.print("\\draw["+colortable[i%6] ); - if ( !listEvaluators.get(i).isValid() ) output.print(",dotted"); - output.println("] plot[mark="+marktable[i%19]+"] coordinates {("+((i%3)*3+1)+","+(-(i/3)*.8-1)+") ("+((i%3)*3+3)+","+(-(i/3)*.8-1)+")};"); + writer.print("\\draw["+colortable[i%6] ); + if ( !listEvaluators.get(i).isValid() ) writer.print(",dotted"); + writer.println("] plot[mark="+marktable[i%19]+"] coordinates {("+((i%3)*3+1)+","+(-(i/3)*.8-1)+") ("+((i%3)*3+3)+","+(-(i/3)*.8-1)+")};"); //,smooth - output.println("\\draw["+colortable[i%6]+"] ("+((i%3)*3+2)+","+(-(i/3)*.8-.8)+") node {"+m+"};"); - output.printf("\\draw["+colortable[i%6]+"] ("+((i%3)*3+2)+","+(-(i/3)*.8-1.2)+") node {%1.2f};\n", listEvaluators.get(i).getGlobalResult() ); + writer.println("\\draw["+colortable[i%6]+"] ("+((i%3)*3+2)+","+(-(i/3)*.8-.8)+") node {"+m+"};"); + writer.printf("\\draw["+colortable[i%6]+"] ("+((i%3)*3+2)+","+(-(i/3)*.8-1.2)+") node {%1.2f};\n", listEvaluators.get(i).getGlobalResult() ); i++; } - output.println("\\end{tikzpicture}"); - output.println(); - output.println("\\end{document}"); + writer.println("\\end{tikzpicture}"); + writer.println(); + writer.println("\\end{document}"); i = 0; for( Vector<Pair> table : result ) { - String algo = listAlgo.get(i); + String algo = listAlgo[i]; // Open one file - PrintWriter writer = null; + PrintWriter auxwriter = null; try { - writer = new PrintWriter ( + auxwriter = new PrintWriter ( new BufferedWriter( new OutputStreamWriter( new FileOutputStream(algo+".table"), "UTF-8" )), true); // Print header - writer.println("#Curve 0, "+(STEP+1)+" points"); - writer.println("#x y type"); - writer.println("%% Plot generated by GenPlot of alignapi"); - writer.println("%% Include in PGF tex by:\n"); - writer.println("%% \\begin{tikzpicture}[cap=round]"); - writer.println("%% \\draw[step="+(STEP/10)+"cm,very thin,color=gray] (-0.2,-0.2) grid ("+STEP+","+STEP+");"); - writer.println("%% \\draw[->] (-0.2,0) -- (10.2,0) node[right] {$"+xlabel+"$}; "); - writer.println("%% \\draw[->] (0,-0.2) -- (0,10.2) node[above] {$"+ylabel+"$}; "); - writer.println("%% \\draw plot[mark=+,smooth] file {"+algo+".table};"); - writer.println("%% \\end{tikzpicture}"); - writer.println(); + auxwriter.println("#Curve 0, "+(STEP+1)+" points"); + auxwriter.println("#x y type"); + auxwriter.println("%% Plot generated by GenPlot of alignapi"); + auxwriter.println("%% Include in PGF tex by:\n"); + auxwriter.println("%% \\begin{tikzpicture}[cap=round]"); + auxwriter.println("%% \\draw[step="+(STEP/10)+"cm,very thin,color=gray] (-0.2,-0.2) grid ("+STEP+","+STEP+");"); + auxwriter.println("%% \\draw[->] (-0.2,0) -- (10.2,0) node[right] {$"+xlabel+"$}; "); + auxwriter.println("%% \\draw[->] (0,-0.2) -- (0,10.2) node[above] {$"+ylabel+"$}; "); + auxwriter.println("%% \\draw plot[mark=+,smooth] file {"+algo+".table};"); + auxwriter.println("%% \\end{tikzpicture}"); + auxwriter.println(); for( Pair p : table ) { - if ( debug > 1 ) System.err.println( " >> "+p.getX()+" - "+p.getY() ); - writer.println( p.getX()*10+" "+ p.getY()*10 ); + //logger.trace( " >> {} - {}", p.getX(), p.getY() ); + auxwriter.println( p.getX()*10+" "+ p.getY()*10 ); } - } catch (Exception ex) { - ex.printStackTrace(); + } catch ( Exception ex ) { + logger.error( "IGNORED Exception", ex ); } finally { - if ( writer != null ) writer.close(); + if ( auxwriter != null ) auxwriter.close(); } // UnsupportedEncodingException + FileNotFoundException i++; @@ -460,30 +418,30 @@ public class GenPlot { * This does average plus generate the call for Google Chart API * */ - public void printHTMLGGraph( Vector<Vector<Pair>> result ){ - output.print("<img src=\"http://chart.apis.google.com/chart?"); - output.print("chs=600x500&cht=lxy&chg=10,10&chof=png"); - output.print("&chxt=x,x,y,y&chxr=0,0.0,1.0,0.1|2,0.0,1.0,0.1&chxl=1:|"+xlabel+"|3:|"+ylabel+"&chma=b&chxp=1,50|3,50&chxs=0N*sz1*|2N*sz1*"); - output.print("&chd=t:"); // data + public void printHTMLGGraph( Vector<Vector<Pair>> result, PrintWriter writer ){ + writer.print("<img src=\"http://chart.apis.google.com/chart?"); + writer.print("chs=600x500&cht=lxy&chg=10,10&chof=png"); + writer.print("&chxt=x,x,y,y&chxr=0,0.0,1.0,0.1|2,0.0,1.0,0.1&chxl=1:|"+xlabel+"|3:|"+ylabel+"&chma=b&chxp=1,50|3,50&chxs=0N*sz1*|2N*sz1*"); + writer.print("&chd=t:"); // data boolean firstalg = true; for( Vector<Pair> table : result ) { - if ( !firstalg ) output.print("|"); + if ( !firstalg ) writer.print("|"); firstalg = false; boolean firstpoint = true; String Yval = "|"; for( Pair p : table ) { if ( !firstpoint ) { - output.print(","); + writer.print(","); Yval += ","; } firstpoint = false; Yval += String.format("%1.2f", p.getY()*10); - if ( debug > 1 ) System.err.println( " >> "+p.getX()+" - "+p.getY() ); - output.printf( "%1.2f", p.getX()*10 ); + //logger.trace( " >> {} - {}", p.getX(), p.getY() ); + writer.printf( "%1.2f", p.getX()*10 ); } - output.print( Yval ); + writer.print( Yval ); } - output.print("&chdl="); // labels + writer.print("&chdl="); // labels int i = 0; //String marktable[] = { "+", "*", "x", "-", "|", "o", "asterisk", "star", "oplus", "oplus*", "otimes", "otimes*", "square", "square*", "triangle", "triangle*", "diamond", "diamond*", "pentagon", "pentagon*"}; //String colortable[] = { "black", "red", "green!50!black", "blue", "cyan", "magenta" }; @@ -492,11 +450,11 @@ public class GenPlot { String color = ""; for ( String m : listAlgo ) { if ( i > 0 ) { - output.print( "|" ); + writer.print( "|" ); color += ","; style += "|"; } - output.print( m ); + writer.print( m ); color += colortable[i%28]; if ( !listEvaluators.get(i).isValid() ) { style += "2,6,3"; @@ -505,39 +463,32 @@ public class GenPlot { } i++; } - //output.print("&chdlp=b"); // legend position (but ugly) - output.print("&chco="+color); // colors - output.print("&chls="+style); // linestyle - output.println("&chds=0,10\"/>"); + //writer.print("&chdlp=b"); // legend position (but ugly) + writer.print("&chco="+color); // colors + writer.print("&chls="+style); // linestyle + writer.println("&chds=0,10\"/>"); } // 2010: TSV output is not finished // It is supposed to provide // List of algo // List of STEP + points - public void printTSV( Vector<Vector<Pair>> points ) { + public void printTSV( Vector<Vector<Pair>> points, PrintWriter writer ) { // Print first line for ( String m : listAlgo ) { - output.print("\t"+m ); + writer.print("\t"+m ); } // Print others for ( int i= 0; i < 100 ; i += STEP ) { for( int j = 0; j < size; j++ ){ Pair precrec = points.get(j).get(i); - output.println( precrec.getX()+" "+precrec.getY() ); + writer.println( precrec.getX()+" "+precrec.getY() ); } } - output.println(); + writer.println(); } public void usage() { - System.out.println("usage: GenPlot [options]"); - System.out.println("options are:"); - System.out.println("\t--type=tsv|tex|html(|xml) -t tsv|tex|html(|xml)\tSpecifies the output format"); - System.out.println("\t--graph=class -g class\tSpecifies the class of Evaluator to be used"); - System.out.println("\t--evaluator=class -e class\tSpecifies the class of GraphEvaluator (plotter) to be used"); - System.out.println("\t--list=algo1,...,algon -l algo1,...,algon\tSequence of the filenames to consider"); - System.out.println("\t--debug[=n] -d [n]\t\tReport debug info at level n"); - System.out.println("\t--help -h\t\t\tPrint this message"); + usage( "java "+this.getClass().getName()+" [options]\nGenerate a graphic presentation of evaluation results" ); } } diff --git a/src/fr/inrialpes/exmo/align/cli/GroupAlign.java b/src/fr/inrialpes/exmo/align/cli/GroupAlign.java index f9480fed..01298e58 100644 --- a/src/fr/inrialpes/exmo/align/cli/GroupAlign.java +++ b/src/fr/inrialpes/exmo/align/cli/GroupAlign.java @@ -1,9 +1,7 @@ /* * $Id$ * - * Copyright (C) 2003 The University of Manchester - * Copyright (C) 2003 The University of Karlsruhe - * Copyright (C) 2003-2008, 2010-2013 INRIA + * Copyright (C) 2003-2008, 2010-2014 INRIA * Copyright (C) 2004, Universit� de Montr�al * * This program is free software; you can redistribute it and/or @@ -22,8 +20,6 @@ * USA. */ -/* This program evaluates the results of several ontology aligners in a row. -*/ package fr.inrialpes.exmo.align.cli; import org.semanticweb.owl.align.Alignment; @@ -38,7 +34,6 @@ import fr.inrialpes.exmo.ontowrap.OntologyFactory; import java.io.File; import java.io.FileOutputStream; -import java.io.FileInputStream; import java.io.PrintWriter; import java.io.BufferedWriter; import java.io.OutputStreamWriter; @@ -51,8 +46,14 @@ import java.util.Properties; import org.xml.sax.SAXException; -import gnu.getopt.LongOpt; -import gnu.getopt.Getopt; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import org.apache.commons.cli.CommandLine; +import org.apache.commons.cli.Options; +import org.apache.commons.cli.Option; +import org.apache.commons.cli.OptionBuilder; +import org.apache.commons.cli.ParseException; /** A batch class for an OWL ontology alignment processing. It aligns all the ontology pairs denoted @@ -69,32 +70,37 @@ import gnu.getopt.Getopt; --name=filename -n filename output results in filename.rdf --impl=className -i classname Use the given alignment implementation. --renderer=className -r className Specifies the alignment renderer - --debug=level -d level </pre> <pre> $Id$ </pre> +*/ -@author Sean K. Bechhofer -@author J�r�me Euzenat - */ - -public class GroupAlign { +public class GroupAlign extends CommonCLI { + final static Logger logger = LoggerFactory.getLogger( GroupAlign.class ); - Properties params = null; - String filename = "align"; - String paramfile = null; String urlprefix = null; String source = "onto1.rdf"; String target = "onto.rdf"; URI uri1 = null; String initName = null; - int debug = 0; String alignmentClassName = "fr.inrialpes.exmo.align.impl.method.StringDistAlignment"; String rendererClass = "fr.inrialpes.exmo.align.impl.renderer.RDFRendererVisitor"; String ontoDir = null; + public GroupAlign() { + super(); + options.addOption( OptionBuilder.withLongOpt( "alignment" ).hasArg().withDescription( "Use an initial alignment FILE" ).withArgName("FILE").create( 'a' ) ); + options.addOption( OptionBuilder.withLongOpt( "renderer" ).hasArg().withDescription( "Use the given CLASS for rendering" ).withArgName("CLASS").create( 'r' ) ); + options.addOption( OptionBuilder.withLongOpt( "impl" ).hasArg().withDescription( "Use the given Alignment implementation" ).withArgName("CLASS").create( 'i' ) ); + options.addOption( OptionBuilder.withLongOpt( "name" ).hasArg().withDescription( "Use the given URI as common source ontology" ).withArgName("URI").create( 'n' ) ); + options.addOption( OptionBuilder.withLongOpt( "uriprefix" ).hasArg().withDescription( "URI prefix of the target" ).withArgName("URI").create( 'u' ) ); + options.addOption( OptionBuilder.withLongOpt( "source" ).hasArg().withDescription( "Source ontology FILEname (default "+source+")" ).withArgName("FILE").create( 's' ) ); + options.addOption( OptionBuilder.withLongOpt( "target" ).hasArg().withDescription( "Target ontology FILEname (default "+target+")" ).withArgName("FILE").create( 't' ) ); + options.addOption( OptionBuilder.withLongOpt( "directory" ).hasOptionalArg().withDescription( "The DIRectory containing the data to match" ).withArgName("DIR").create( 'w' ) ); + } + public static void main(String[] args) { try { new GroupAlign().run( args ); } catch (Exception ex) { ex.printStackTrace(); }; @@ -102,109 +108,32 @@ public class GroupAlign { public void run(String[] args) throws Exception { - LongOpt[] longopts = new LongOpt[13]; - params = new Properties(); - - longopts[0] = new LongOpt("help", LongOpt.NO_ARGUMENT, null, 'h'); - longopts[1] = new LongOpt("output", LongOpt.REQUIRED_ARGUMENT, null, 'o'); - longopts[2] = new LongOpt("alignment", LongOpt.REQUIRED_ARGUMENT, null, 'a'); - longopts[3] = new LongOpt("renderer", LongOpt.REQUIRED_ARGUMENT, null, 'r'); - longopts[4] = new LongOpt("debug", LongOpt.OPTIONAL_ARGUMENT, null, 'd'); - longopts[5] = new LongOpt("impl", LongOpt.REQUIRED_ARGUMENT, null, 'i'); - longopts[6] = new LongOpt("params", LongOpt.REQUIRED_ARGUMENT, null, 'p'); - longopts[7] = new LongOpt("name", LongOpt.REQUIRED_ARGUMENT, null, 'n'); - longopts[8] = new LongOpt("prefix", LongOpt.REQUIRED_ARGUMENT, null, 'u'); - longopts[9] = new LongOpt("source", LongOpt.REQUIRED_ARGUMENT, null, 's'); - longopts[10] = new LongOpt("target", LongOpt.REQUIRED_ARGUMENT, null, 't'); - // Is there a way for that in LongOpt ??? - longopts[11] = new LongOpt("D", LongOpt.REQUIRED_ARGUMENT, null, 'D'); - longopts[12] = new LongOpt("directory", LongOpt.REQUIRED_ARGUMENT, null, 'w'); - - Getopt g = new Getopt("", args, "ho:a:d::n:u:r:i:s:t:p:D:w:", longopts); - int c; - String arg; - - while ((c = g.getopt()) != -1) { - switch (c) { - case 'h' : - usage(); - return; - case 'o' : - /* Write output in given filename */ - filename = g.getOptarg(); - break; - case 'n' : - arg = g.getOptarg(); - /* Use common ontology to compare */ - if(arg!=null){ - try { uri1 = new URI(g.getOptarg()); - } catch (Exception e) { e.printStackTrace(); } - } - else{uri1 = null;} - break; - case 'p' : - /* Read parameters from filename */ - paramfile = g.getOptarg(); - params.loadFromXML( new FileInputStream( paramfile ) ); - break; - case 'r' : - /* Use the given class for rendering */ - rendererClass = g.getOptarg(); - break; - case 'i' : - /* Use the given class for the alignment */ - alignmentClassName = g.getOptarg(); - break; - case 'a' : - /* Use the given file as a partial alignment */ - initName = g.getOptarg(); - break; - case 'u' : - /* Use the given url prefix for fetching the ontologies */ - urlprefix = g.getOptarg(); - break; - case 's' : - /* Use the given filename for source ontology */ - source = g.getOptarg(); - break; - case 't' : - /* Use the given filename for target ontology */ - target = g.getOptarg(); - break; - case 'D' : - /* Parameter definition */ - arg = g.getOptarg(); - int index = arg.indexOf('='); - if ( index != -1 ) { - params.setProperty( arg.substring( 0, index), - arg.substring(index+1)); - } else { - System.err.println("Bad parameter syntax: "+g); - usage(); - System.exit(0); - } - break; - case 'd' : - /* Debug level */ - arg = g.getOptarg(); - if ( arg != null ) debug = Integer.parseInt(arg.trim()); - else debug = 4; - break; - case 'w' : - /* Use the given ontology directory */ - arg = g.getOptarg(); - if ( arg != null ) ontoDir = g.getOptarg(); - else ontoDir = null; - break; - } - } + try { + outputfilename = "align"; + + CommandLine line = parseCommandLine( args ); + if ( line == null ) return; // --help - //int i = g.getOptind(); + // Here deal with command specific arguments - if (debug == 0 && params.getProperty("debug") != null) { - debug = Integer.parseInt(params.getProperty("debug")); + if ( line.hasOption( 'n' ) ) { + try { uri1 = new URI( line.getOptionValue('n') ); + } catch ( Exception e ) { + logger.debug( "IGNORED Exception (cannot create source URI)", e ); + } + } + if ( line.hasOption( 'r' ) ) rendererClass = line.getOptionValue( 'r' ); + if ( line.hasOption( 'i' ) ) alignmentClassName = line.getOptionValue( 'i' ); + if ( line.hasOption( 'a' ) ) initName = line.getOptionValue( 'a' ); + if ( line.hasOption( 'u' ) ) urlprefix = line.getOptionValue( 'u' ); + if ( line.hasOption( 's' ) ) source = line.getOptionValue( 's' ); + if ( line.hasOption( 't' ) ) target = line.getOptionValue( 't' ); + if ( line.hasOption( 'w' ) ) ontoDir = line.getOptionValue( 'w' ); + } catch( ParseException exp ) { + logger.error( exp.getMessage() ); + usage(); + System.exit(-1); } - if (debug > 0) params.setProperty( "debug", Integer.toString( debug-1 ) ); iterateDirectories(); } @@ -219,14 +148,14 @@ public class GroupAlign { subdir = (new File(ontoDir)).listFiles(); } } catch ( Exception e ) { - System.err.println("Cannot stat dir "+ e.getMessage()); + logger.error( "Cannot stat dir", e ); usage(); } int size = subdir.length; for ( int i=0 ; i < size; i++ ) { if( subdir[i].isDirectory() ) { // Align - if ( debug > 0 ) System.err.println("Directory: "+subdir[i]); + //logger.trace("Directory: {}", subdir[i]); align( subdir[i] ); } } @@ -250,56 +179,56 @@ public class GroupAlign { // file://localhost/localpath // Apparently should be file:///c:/localpath } - //System.err.println("Here it is "+prefix+" (end by /?)"); + //logger.trace{}("Here it is {} (end by /?)", prefix ); try { if ( !source.equalsIgnoreCase("onto1.rdf") && !target.equalsIgnoreCase("onto1.rdf") ) { - uri1 = new URI(prefix+source); - } else if ( uri1 == null ) uri1 = new URI(prefix+source); - URI uri2 = new URI(prefix+target); + uri1 = new URI( prefix+source ); + } else if ( uri1 == null ) uri1 = new URI( prefix+source ); + URI uri2 = new URI( prefix+target ); - if (debug > 1) System.err.println(" Handler set"); - if (debug > 1) System.err.println(" URI1: "+uri1); - if (debug > 1) System.err.println(" URI2: "+uri2); + //logger.trace(" Handler set"); + //logger.trace(" URI1: {}", uri1); + //logger.trace(" URI2: {}", uri2); try { - if (initName != null) { - AlignmentParser aparser = new AlignmentParser(debug-1); - init = aparser.parse( initName ); + if ( initName != null ) { + AlignmentParser aparser = new AlignmentParser(); + init = aparser.parse( prefix+initName ); uri1 = init.getFile1(); uri2 = init.getFile2(); - if (debug > 1) System.err.println(" Init parsed"); + logger.debug(" Init parsed"); } // Create alignment object Object[] mparams = {}; Class[] cparams = {}; - Class<?> alignmentClass = Class.forName(alignmentClassName); + Class<?> alignmentClass = Class.forName( alignmentClassName ); java.lang.reflect.Constructor alignmentConstructor = alignmentClass.getConstructor(cparams); - result = (AlignmentProcess)alignmentConstructor.newInstance(mparams); + result = (AlignmentProcess)alignmentConstructor.newInstance( mparams ); result.init( uri1, uri2 ); } catch (Exception ex) { - System.err.println("Cannot create alignment "+ alignmentClassName+ "\n"+ ex.getMessage()); + logger.debug( "Cannot create alignment {}", alignmentClassName ); throw ex; } - if (debug > 1) System.err.println(" Alignment structure created"); + logger.debug(" Alignment structure created"); // Compute alignment long time = System.currentTimeMillis(); - result.align(init, params); // add opts + result.align( init, parameters ); long newTime = System.currentTimeMillis(); result.setExtension( Namespace.ALIGNMENT.uri, Annotations.TIME, Long.toString(newTime - time) ); - if (debug > 1) System.err.println(" Alignment performed"); + logger.debug(" Alignment performed"); // Set output file writer = new PrintWriter ( new BufferedWriter( new OutputStreamWriter( - new FileOutputStream(dir+File.separator+filename+".rdf"), "UTF-8" )), true); + new FileOutputStream(dir+File.separator+outputfilename), "UTF-8" )), true); AlignmentVisitor renderer = null; try { @@ -309,41 +238,30 @@ public class GroupAlign { Class.forName(rendererClass).getConstructor(cparams); renderer = (AlignmentVisitor)rendererConstructor.newInstance(mparams); } catch (Exception ex) { - System.err.println("Cannot create renderer "+rendererClass+"\n"+ ex.getMessage()); + logger.debug( "Cannot create renderer {}", rendererClass ); throw ex; } - if (debug > 1) System.err.println(" Outputing result to "+dir+File.separator+filename+".rdf"); + logger.debug(" Outputing result to {}/{}", dir, outputfilename ); + // Output result.render( renderer); - if (debug > 1) System.err.println(" Done..."+renderer+"\n"); - } catch (Exception ex) { - if ( debug > 1 ) ex.printStackTrace(); + logger.debug(" Done...{}", renderer ); + } catch (Exception ex) { + logger.debug( "IGNORED Exception", ex ); } finally { // JE: This instruction is very important if ( writer != null ) writer.close(); // Unload the ontologies - try { OntologyFactory.clear(); } catch (Exception e) {}; + try { OntologyFactory.clear(); + } catch (Exception e) { + logger.debug( "IGNORED Exception on close", e ); + }; } } public void usage() { - System.err.println("usage: GroupAlign [options]"); - System.err.println("options are:"); - System.err.println("\t--name=uri -n uri\t\tUse the given uri to compare with."); - System.err.println("\t--source=filename -s filename Source filename (default onto1.rdf)"); - System.err.println("\t--target=filename -t filename Target filename (default onto.rdf)"); - System.err.println("\t--prefix=uriprefix -u uriprefix URI prefix of the target"); - System.err.println("\t--output=filename -o filename\tOutput the alignment in filename.rdf"); - System.err.println("\t--impl=className -i classname\t\tUse the given alignment implementation."); - System.err.println("\t--renderer=className -r className\tSpecifies the alignment renderer"); - System.err.println("\t--alignment=filename -a filename Start from an XML alignment file"); - System.err.println("\t--params=filename -p filename\tReads parameters from filename"); - System.err.println("\t-Dparam=value\t\t\tSet parameter"); - System.err.println("\t--debug[=n] -d [n]\t\tReport debug info at level n"); - System.err.println("\t--help -h\t\t\tPrint this message"); - System.err.print("\n"+GroupAlign.class.getPackage().getImplementationTitle()+" "+GroupAlign.class.getPackage().getImplementationVersion()); - System.err.println(" ($Id$)\n"); + usage( "java "+this.getClass().getName()+" [options]\nMatches pairs of ontologies in subdirectories" ); } } diff --git a/src/fr/inrialpes/exmo/align/cli/GroupEval.java b/src/fr/inrialpes/exmo/align/cli/GroupEval.java index 99448170..ec3acb6a 100644 --- a/src/fr/inrialpes/exmo/align/cli/GroupEval.java +++ b/src/fr/inrialpes/exmo/align/cli/GroupEval.java @@ -1,9 +1,7 @@ /* * $Id$ * - * Copyright (C) 2003 The University of Manchester - * Copyright (C) 2003 The University of Karlsruhe - * Copyright (C) 2003-2012, INRIA + * Copyright (C) 2003-2014, INRIA * Copyright (C) 2004, Universit� de Montr�al * * This program is free software; you can redistribute it and/or @@ -48,8 +46,14 @@ import java.util.Properties; import org.xml.sax.SAXException; -import gnu.getopt.LongOpt; -import gnu.getopt.Getopt; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import org.apache.commons.cli.CommandLine; +import org.apache.commons.cli.Options; +import org.apache.commons.cli.Option; +import org.apache.commons.cli.OptionBuilder; +import org.apache.commons.cli.ParseException; import fr.inrialpes.exmo.align.parser.AlignmentParser; @@ -65,7 +69,6 @@ import fr.inrialpes.exmo.align.parser.AlignmentParser; <pre> -o filename --output=filename -f format = prfot (precision/recall/f-measure/overall/time) --format=prfot - -d debug --debug=level -r filename --reference=filename -s algo/measure -l list of compared algorithms @@ -83,108 +86,65 @@ import fr.inrialpes.exmo.align.parser.AlignmentParser; $Id$ </pre> -@author Sean K. Bechhofer -@author J�r�me Euzenat */ -public class GroupEval { +public class GroupEval extends CommonCLI { + final static Logger logger = LoggerFactory.getLogger( GroupEval.class ); - Properties params = null; - String filename = null; String reference = "refalign.rdf"; String format = "pr"; int fsize = 2; String type = "html"; boolean embedded = false; String dominant = "s"; - Vector<String> listAlgo = null; - int debug = 0; + String[] listAlgo = null; + int size = 0; String color = null; String ontoDir = null; + public GroupEval() { + super(); + options.addOption( OptionBuilder.withLongOpt( "list" ).hasArgs().withValueSeparator(',').withDescription( "List of FILEs to be included in the results (required)" ).withArgName("FILE").create( 'l' ) ); + options.addOption( OptionBuilder.withLongOpt( "color" ).hasOptionalArg().withDescription( "Color even lines of the output in COLOR (default: lightblue)" ).withArgName("COLOR").create( 'c' ) ); + options.addOption( OptionBuilder.withLongOpt( "format" ).hasArg().withDescription( "Used MEASures and order (precision/recall/f-measure/overall/time) (default: "+format+")" ).withArgName("MEAS").create( 'f' ) ); + options.addOption( OptionBuilder.withLongOpt( "type" ).hasArg().withDescription( "Output TYPE (html|xml|tex|ascii|triangle; default: "+type+")" ).withArgName("TYPE").create( 't' ) ); + //options.addOption( OptionBuilder.withLongOpt( "sup" ).hasArg().withDescription( "Specifies if dominant columns are algorithms or measure" ).withArgName("algo").create( 's' ) ); + options.addOption( OptionBuilder.withLongOpt( "reference" ).hasArg().withDescription( "Name of the reference alignment FILE (default: "+reference+")" ).withArgName("FILE").create( 'r' ) ); + options.addOption( OptionBuilder.withLongOpt( "directory" ).hasOptionalArg().withDescription( "The DIRectory containing the data to evaluate" ).withArgName("DIR").create( 'w' ) ); + // .setRequired( true ) + Option opt = options.getOption( "list" ); + if ( opt != null ) opt.setRequired( true ); + } + + public static void main(String[] args) { try { new GroupEval().run( args ); } catch (Exception ex) { ex.printStackTrace(); }; } public void run(String[] args) throws Exception { - String listFile = ""; - LongOpt[] longopts = new LongOpt[10]; - - longopts[0] = new LongOpt("help", LongOpt.NO_ARGUMENT, null, 'h'); - longopts[1] = new LongOpt("output", LongOpt.REQUIRED_ARGUMENT, null, 'o'); - longopts[2] = new LongOpt("format", LongOpt.REQUIRED_ARGUMENT, null, 'f'); - longopts[3] = new LongOpt("type", LongOpt.REQUIRED_ARGUMENT, null, 't'); - longopts[4] = new LongOpt("debug", LongOpt.OPTIONAL_ARGUMENT, null, 'd'); - longopts[5] = new LongOpt("sup", LongOpt.REQUIRED_ARGUMENT, null, 's'); - longopts[6] = new LongOpt("list", LongOpt.REQUIRED_ARGUMENT, null, 'l'); - longopts[7] = new LongOpt("color", LongOpt.OPTIONAL_ARGUMENT, null, 'c'); - longopts[8] = new LongOpt("reference", LongOpt.REQUIRED_ARGUMENT, null, 'r'); - longopts[9] = new LongOpt("directory", LongOpt.REQUIRED_ARGUMENT, null, 'w'); - - Getopt g = new Getopt("", args, "ho:a:d::l:f:t:r:w:c::", longopts); - int c; - String arg; - - while ((c = g.getopt()) != -1) { - switch (c) { - case 'h' : - usage(); - return; - case 'o' : - /* Write output here */ - filename = g.getOptarg(); - break; - case 'r' : - /* File name for the reference alignment */ - reference = g.getOptarg(); - break; - case 'f' : - /* Sequence of results to print */ - format = g.getOptarg(); - break; - case 't' : - /* Type of output (tex/html/xml/ascii) */ - type = g.getOptarg(); - break; - case 's' : - /* Print per type or per algo */ - dominant = g.getOptarg(); - break; - case 'c' : - /* Print colored lines */ - arg = g.getOptarg(); - if ( arg != null ) { - color = arg.trim(); - } else color = "lightblue"; - break; - case 'l' : - /* List of filename */ - listFile = g.getOptarg(); - break; - case 'd' : - /* Debug level */ - arg = g.getOptarg(); - if ( arg != null ) debug = Integer.parseInt(arg.trim()); - else debug = 4; - break; - case 'w' : - /* Use the given ontology directory */ - arg = g.getOptarg(); - if ( arg != null ) ontoDir = g.getOptarg(); - else ontoDir = null; - break; - } - } - listAlgo = new Vector<String>(); - for ( String s : listFile.split(",") ) { - listAlgo.add( s ); + try { + CommandLine line = parseCommandLine( args ); + if ( line == null ) return; // --help + + // Here deal with command specific arguments + if ( line.hasOption( 'f' ) ) format = line.getOptionValue( 'f' ); + if ( line.hasOption( 'r' ) ) reference = line.getOptionValue( 'r' ); + if ( line.hasOption( 's' ) ) dominant = line.getOptionValue( 's' ); + if ( line.hasOption( 't' ) ) type = line.getOptionValue( 't' ); + if ( line.hasOption( 'c' ) ) color = line.getOptionValue( 'c', "lightblue" ); + if ( line.hasOption( 'l' ) ) { + listAlgo = line.getOptionValues( 'l' ); + size = listAlgo.length; + } + if ( line.hasOption( 'w' ) ) ontoDir = line.getOptionValue( 'w' ); + } catch( ParseException exp ) { + logger.error( exp.getMessage() ); + usage(); + System.exit( -1 ); } - params = new Properties(); - if (debug > 0) params.setProperty( "debug", Integer.toString( debug-1 ) ); - print( iterateDirectories() ); } @@ -192,13 +152,13 @@ public class GroupEval { Vector<Vector> result = null; File [] subdir = null; try { - if (ontoDir == null) { - subdir = (new File(System.getProperty("user.dir"))).listFiles(); - } else { - subdir = (new File(ontoDir)).listFiles(); - } - } catch (Exception e) { - System.err.println("Cannot stat dir "+ e.getMessage()); + if (ontoDir == null) { + subdir = (new File(System.getProperty("user.dir"))).listFiles(); + } else { + subdir = (new File(ontoDir)).listFiles(); + } + } catch ( Exception e ) { + logger.error( "Cannot stat dir ", e ); usage(); } int size = subdir.length; @@ -207,7 +167,7 @@ public class GroupEval { int i = 0; for ( int j=0 ; j < size; j++ ) { if( subdir[j].isDirectory() ) { - if ( debug > 0 ) System.err.println("\nEntering directory "+subdir[j]); + //logger.trace( "Entering directory {}", subdir[j] ); // eval the alignments in a subdirectory // store the result Vector vect = iterateAlignments( subdir[j] ); @@ -232,7 +192,7 @@ public class GroupEval { // call eval // store the result in a record // return the record. - if ( debug > 2) System.err.println(" Considering result "+i); + //logger.trace( " Considering result {}", i ); Evaluator evaluator = eval( prefix+reference, prefix+m+".rdf"); if ( evaluator != null ) ok = true; result.add( i, evaluator ); @@ -240,8 +200,8 @@ public class GroupEval { // Unload the ontologies. try { OntologyFactory.clear(); - } catch ( OntowrapException owex ) { // only report - owex.printStackTrace(); + } catch ( OntowrapException owex ) { + logger.debug( "IGNORED Exception", owex ); } if ( ok == true ) return result; @@ -251,28 +211,19 @@ public class GroupEval { public Evaluator eval( String alignName1, String alignName2 ) { Evaluator eval = null; try { - int nextdebug; - if ( debug < 2 ) nextdebug = 0; - else nextdebug = debug - 2; // Load alignments - AlignmentParser aparser = new AlignmentParser( nextdebug ); + AlignmentParser aparser = new AlignmentParser(); Alignment align1 = aparser.parse( alignName1 ); - if ( debug > 2 ) System.err.println(" Alignment structure1 parsed"); + //logger.trace(" Alignment structure1 parsed"); aparser.initAlignment( null ); Alignment align2 = aparser.parse( alignName2 ); - if ( debug > 2 ) System.err.println(" Alignment structure2 parsed"); + //logger.trace(" Alignment structure2 parsed"); // Create evaluator object eval = new PRecEvaluator( align1, align2 ); // Compare - params.setProperty( "debug", Integer.toString( nextdebug ) ); - eval.eval( params ) ; + eval.eval( parameters ) ; } catch (Exception ex) { - if ( debug > 1 ) { - ex.printStackTrace(); - } else { - System.err.println("GroupEval: "+ex); - System.err.println(alignName1+ " - "+alignName2 ); - } + logger.debug( "IGNORED Exception", ex ); }; return eval; } @@ -283,16 +234,16 @@ public class GroupEval { public void print( Vector<Vector> result ) { PrintStream writer = null; try { - if ( filename == null ) { + if ( outputfilename == null ) { writer = System.out; } else { - writer = new PrintStream(new FileOutputStream( filename )); + writer = new PrintStream( new FileOutputStream( outputfilename ) ); } if ( type.equals("html") ) printHTML( result, writer ); else if ( type.equals("tex") ) printLATEX( result, writer ); else if ( type.equals("triangle") ) printTRIANGLE( result, writer ); } catch ( FileNotFoundException fnfex) { - fnfex.printStackTrace(); + logger.error( "Cannot open file", fnfex ); } finally { writer.close(); } @@ -309,10 +260,10 @@ public class GroupEval { int foundVect[]; // found so far int correctVect[]; // correct so far long timeVect[]; // time so far - foundVect = new int[ listAlgo.size() ]; - correctVect = new int[ listAlgo.size() ]; - timeVect = new long[ listAlgo.size() ]; - for( int k = listAlgo.size()-1; k >= 0; k-- ) { + foundVect = new int[ size ]; + correctVect = new int[ size ]; + timeVect = new long[ size ]; + for( int k = size-1; k >= 0; k-- ) { foundVect[k] = 0; correctVect[k] = 0; timeVect[k] = 0; @@ -399,9 +350,11 @@ public class GroupEval { double prec2 = precision*precision; double a = ((prec2-(recall*recall)+1)/2); double b = java.lang.Math.sqrt( prec2 - (a*a) ); - a = a*10; b = b*10; //for printing scale 10. - writer.println("\\draw plot[mark=+,] coordinates {("+a+","+b+")};"); - writer.println("\\draw ("+(a+.01)+","+(b+.01)+") node[anchor=south west] {"+m+"};"); + if ( b == b ) { // Test if b is not NaN! Otherwise, no square root: the point is out of the triangle + a = a*10; b = b*10; //for printing scale 10. + writer.println("\\draw plot[mark=+,] coordinates {("+a+","+b+")};"); + writer.println("\\draw ("+(a+.01)+","+(b+.01)+") node[anchor=south west] {"+m+"};"); + } k++; } writer.println("\\end{tikzpicture}"); @@ -454,10 +407,10 @@ public class GroupEval { //writer.println("<td>Prec.</td><td>Rec.</td>"); } writer.println("</tr></tbody><tbody>"); - foundVect = new int[ listAlgo.size() ]; - correctVect = new int[ listAlgo.size() ]; - timeVect = new long[ listAlgo.size() ]; - for( int k = listAlgo.size()-1; k >= 0; k-- ) { + foundVect = new int[ size ]; + correctVect = new int[ size ]; + timeVect = new long[ size ]; + for( int k = size-1; k >= 0; k-- ) { foundVect[k] = 0; correctVect[k] = 0; timeVect[k] = 0; @@ -508,10 +461,10 @@ public class GroupEval { } else if ( format.charAt(i) == 'r' ) { formatter.format("%1.2f", eval.getRecall()); } - writer.println("</td>"); + writer.print("</td>"); } } else { - for ( int i = 0 ; i < fsize; i++) writer.println("<td>n/a</td>"); + for ( int i = 0 ; i < fsize; i++) writer.print("<td>n/a</td>"); } } writer.println("</tr>"); @@ -575,7 +528,7 @@ public class GroupEval { writer.println("\\setlength{\\tabcolsep}{3pt} % May be changed"); writer.println("\\begin{table}"); writer.print("\\begin{tabular}{|l||"); - for ( int i = listAlgo.size(); i > 0; i-- ) { + for ( int i = size; i > 0; i-- ) { for ( int j = fsize; j > 0; j-- ) writer.print("c"); writer.print("|"); } @@ -607,10 +560,10 @@ public class GroupEval { } } writer.println(" \\\\ \\hline"); - foundVect = new int[ listAlgo.size() ]; - correctVect = new int[ listAlgo.size() ]; - timeVect = new long[ listAlgo.size() ]; - for( int k = listAlgo.size()-1; k >= 0; k-- ) { + foundVect = new int[ size ]; + correctVect = new int[ size ]; + timeVect = new long[ size ]; + for( int k = size-1; k >= 0; k-- ) { foundVect[k] = 0; correctVect[k] = 0; timeVect[k] = 0; @@ -697,21 +650,7 @@ public class GroupEval { } public void usage() { - System.out.println("usage: GroupEval [options]"); - System.out.println("options are:"); - System.out.println("\t--format=prfot -r prfot\tSpecifies the output order (precision/recall/f-measure/overall/time)"); - // Apparently not implemented - //System.out.println("\t--sup=algo -s algo\tSpecifies if dominant columns are algorithms or measure"); - System.out.println("\t--output=filename -o filename\tSpecifies a file to which the output will go"); - System.out.println("\t--reference=filename -r filename\tSpecifies the name of the reference alignment file (default: refalign.rdf)"); - - System.out.println("\t--type=html|xml|tex|ascii|triangle -t html|xml|tex|ascii\tSpecifies the output format"); - System.out.println("\t--list=algo1,...,algon -l algo1,...,algon\tSequence of the filenames to consider"); - System.out.println("\t--color=color -c color\tSpecifies if the output must color even lines of the output"); - System.out.println("\t--debug[=n] -d [n]\t\tReport debug info at level n"); - System.out.println("\t--help -h\t\t\tPrint this message"); - System.err.print("\n"+GroupEval.class.getPackage().getImplementationTitle()+" "+GroupEval.class.getPackage().getImplementationVersion()); - System.err.println(" ($Id$)\n"); + usage( "java "+this.getClass().getName()+" [options]\nEvaluates in parallel several matching results on several tests in subdirectories" ); } /* diff --git a/src/fr/inrialpes/exmo/align/cli/GroupOutput.java b/src/fr/inrialpes/exmo/align/cli/GroupOutput.java index 33342e94..56e84b54 100644 --- a/src/fr/inrialpes/exmo/align/cli/GroupOutput.java +++ b/src/fr/inrialpes/exmo/align/cli/GroupOutput.java @@ -1,9 +1,7 @@ /* * $Id$ * - * Copyright (C) 2003 The University of Manchester - * Copyright (C) 2003 The University of Karlsruhe - * Copyright (C) 2003-2012, INRIA + * Copyright (C) 2003-2014, INRIA * Copyright (C) 2004, Universit� de Montr�al * * This program is free software; you can redistribute it and/or @@ -25,6 +23,7 @@ /* This program evaluates the results of several ontology aligners and generates a LaTeX diagram for each of these */ + package fr.inrialpes.exmo.align.cli; import org.semanticweb.owl.align.Alignment; @@ -49,12 +48,18 @@ import java.util.Vector; import java.util.Enumeration; import java.util.Properties; -import gnu.getopt.LongOpt; -import gnu.getopt.Getopt; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import org.apache.commons.cli.CommandLine; +import org.apache.commons.cli.Options; +import org.apache.commons.cli.OptionBuilder; +import org.apache.commons.cli.ParseException; import fr.inrialpes.exmo.align.parser.AlignmentParser; -/** A basic class for synthesizing the alignment results of an algorithm with +/** + * A basic class for synthesizing the alignment results of an algorithm with * regard to the ontology characteristics as a colored module. * * These modules are however computed on averaging the precision recall/graphs @@ -70,12 +75,11 @@ import fr.inrialpes.exmo.align.parser.AlignmentParser; * <pre> * -o filename --output=filename * -c --color - * -v --value + * -v --values * -e --labels * -m --measure - * -d debug --debug=level * -l list of compared algorithms - * -t output --type=output: xml/tex/html/ascii + * -t output --type=output: tex/html * </pre> * * The input is taken in the current directory in a set of subdirectories (one per @@ -123,7 +127,8 @@ But it is less informative than the above presentation. \end{tikzpicture} */ -public class GroupOutput { +public class GroupOutput extends CommonCLI { + final static Logger logger = LoggerFactory.getLogger( GroupOutput.class ); static int SIZE = 16;// Nb of cells = 2^ = 16 static int cellSpec[][] = { {101}, //liph=0 @@ -142,102 +147,78 @@ public class GroupOutput { {257},//h=13 {254,260,261},//i=14 {262,265,266} };//emptyset=15 - Properties params = null; - Vector<String> listAlgo; - String fileNames = ""; - String outFile = null; + String[] listAlgo; String type = "tex"; - String color = null; + String color = "blue"; boolean labels = false; - boolean value = false; - int debug = 0; + boolean values = false; int measure = 0; PrintWriter output = null; - + String ontoDir = null; + String prefix = null; + + public GroupOutput() { + super(); + options.addOption( "v", "values", false, "Displays the values" ); + options.addOption( "e", "labels", false, "Displays graph labels" ); + options.addOption( OptionBuilder.withLongOpt( "color" ).hasOptionalArg().withDescription( "Use COLOR to fill cells (default: "+color+")" ).withArgName("COLOR").create( 'c' ) ); + options.addOption( OptionBuilder.withLongOpt( "type" ).hasArg().withDescription( "Specifies the output TYPE (html|tex; default: "+type+")" ).withArgName("TYPE").create( 't' ) ); + options.addOption( OptionBuilder.withLongOpt( "list" ).hasArgs().withValueSeparator(',').withDescription( "Consider this list of FILEs for inclusion in the results" ).withArgName("FILE").create( 'l' ) ); + options.addOption( OptionBuilder.withLongOpt( "format" ).hasArg().withDescription( "Display MEASure (prof; default: f)" ).withArgName("MEAS").create( 'f' ) ); + options.addOption( OptionBuilder.withLongOpt( "directory" ).hasOptionalArg().withDescription( "The DIRectory containing the data to match" ).withArgName("DIR").create( 'w' ) ); + } public static void main(String[] args) { try { new GroupOutput().run( args ); } catch (Exception ex) { ex.printStackTrace(); }; } public void run(String[] args) throws Exception { - LongOpt[] longopts = new LongOpt[10]; - - longopts[0] = new LongOpt("help", LongOpt.NO_ARGUMENT, null, 'h'); - longopts[1] = new LongOpt("output", LongOpt.REQUIRED_ARGUMENT, null, 'o'); - longopts[2] = new LongOpt("color", LongOpt.OPTIONAL_ARGUMENT, null, 'c'); - longopts[3] = new LongOpt("type", LongOpt.REQUIRED_ARGUMENT, null, 't'); - longopts[4] = new LongOpt("debug", LongOpt.OPTIONAL_ARGUMENT, null, 'd'); - longopts[6] = new LongOpt("list", LongOpt.REQUIRED_ARGUMENT, null, 'l'); - longopts[7] = new LongOpt("value", LongOpt.NO_ARGUMENT, null, 'v'); - longopts[8] = new LongOpt("labels", LongOpt.NO_ARGUMENT, null, 'e'); - longopts[9] = new LongOpt("measure", LongOpt.REQUIRED_ARGUMENT, null, 'm'); - - Getopt g = new Getopt("", args, "hveo:c::d::l:t:m:", longopts); - int c; - String arg; - - while ((c = g.getopt()) != -1) { - switch (c) { - case 'h' : - usage(); - return; - case 'v' : - value = true; - break; - case 'e' : - labels = true; - break; - case 'o' : - /* Write output here */ - outFile = g.getOptarg(); - break; - case 'c' : - /* Cell color */ - arg = g.getOptarg(); - if ( arg != null ) { - color = arg.trim(); - } else color = "blue"; - break; - case 't' : - /* Type of output (tex/tsv(/html/xml/ascii)) */ - type = g.getOptarg(); - break; - case 'l' : - /* List of filename */ - fileNames = g.getOptarg(); - break; - case 'm' : - /* measure to be used */ - String s = g.getOptarg(); + + try { + CommandLine line = parseCommandLine( args ); + if ( line == null ) return; // --help + + // Here deal with command specific arguments + if ( line.hasOption( 'v' ) ) values = true; + if ( line.hasOption( 'e' ) ) labels = true; + if ( line.hasOption( 'c' ) ) color = line.getOptionValue( 'c', "blue" ); + if ( line.hasOption( 't' ) ) type = line.getOptionValue( 't' ); + if ( line.hasOption( 'l' ) ) listAlgo = line.getOptionValues( 'l' ); + if ( line.hasOption( 'f' ) ) { + String s = line.getOptionValue( 'f' ); if ( s.equals("p") ) measure = 1; else if ( s.equals("r") ) measure = 2; else if ( s.equals("o") ) measure = 3; - break; - case 'd' : - /* Debug level */ - arg = g.getOptarg(); - if ( arg != null ) debug = Integer.parseInt(arg.trim()); - else debug = 4; - break; } + if ( line.hasOption( 'w' ) ) ontoDir = line.getOptionValue( 'w' ); + } catch( ParseException exp ) { + logger.error( exp.getMessage() ); + usage(); + System.exit(-1); } - listAlgo = new Vector<String>(); - for ( String s : fileNames.split(",") ) { - listAlgo.add( s ); - } + parameters.setProperty( "step", Integer.toString(SIZE) ); - params = new Properties(); - if (debug > 0) params.setProperty( "debug", Integer.toString(debug-1) ); - - params.setProperty( "step", Integer.toString(SIZE) ); + try { + File dir = null; + if ( ontoDir == null ) { + dir = new File( System.getProperty("user.dir") ); + } else { + dir = new File( ontoDir ); + } + prefix = dir.toURI().toString(); + } catch ( Exception e ) { + logger.error( "Cannot stat dir ", e ); + usage(); + System.exit(-1); + } // Set output file OutputStream stream; - if (outFile == null) { + if ( outputfilename == null) { stream = System.out; } else { - stream = new FileOutputStream(outFile); + stream = new FileOutputStream( outputfilename ); } output = new PrintWriter ( new BufferedWriter( @@ -268,11 +249,13 @@ public class GroupOutput { public void iterateAlgorithm(){ // for all alignments there, for ( String algo : listAlgo ) { - if ( debug > 0 ) System.err.println("Algorithm: "+algo); + //logger.trace("Algorithm: {}", algo); // type if ( type.equals("tex") ) { printPGFTeX( algo, iterateCells( algo ) ); - } else System.err.println("Flag -t "+type+" : not implemented yet"); + } else { + logger.warn( "Flag -t {} : not implemented yet", type ); + } } } @@ -285,53 +268,46 @@ public class GroupOutput { } public double iterateTests( String algo, int[] tests ){ - File dir = (new File(System.getProperty("user.dir"))); double result = 0.0; int nbtests = 0; for ( int i=0; i<tests.length; i++ ){//size() or length - if ( debug > 1 ) System.err.println(" tests: "+tests[i]); - String prefix = dir.toURI().toString()+"/"+tests[i]+"/"; + //logger.trace(" tests: {}", tests[i]); + String testdir = prefix+"/"+tests[i]+"/"; try { - PRecEvaluator evaluator = (PRecEvaluator)eval( prefix+"refalign.rdf", prefix+algo+".rdf"); + PRecEvaluator evaluator = (PRecEvaluator)eval( testdir+"refalign.rdf", testdir+algo+".rdf"); result += getMeasure( evaluator ); nbtests++; // Only the tests that succeed - } catch ( AlignmentException aex ) { // simple error message - if ( aex.getCause() != null ) - System.err.println( aex.getCause().getMessage() ); - else System.err.println( aex ); + } catch ( AlignmentException aex ) { + logger.debug( "IGNORED Exception", aex ); } } // Unload the ontologies. try { OntologyFactory.clear(); - } catch ( OntowrapException owex ) { // only report - owex.printStackTrace(); + } catch ( OntowrapException owex ) { + logger.debug( "IGNORED Exception", owex ); } return result/(double)nbtests; } public Evaluator eval( String alignName1, String alignName2 ) throws AlignmentException { Evaluator eval = null; - int nextdebug; - if ( debug < 3 ) nextdebug = 0; - else nextdebug = debug - 3; // Load alignments Alignment align1=null, align2=null; try { - AlignmentParser aparser = new AlignmentParser( nextdebug ); + AlignmentParser aparser = new AlignmentParser(); align1 = aparser.parse( alignName1 ); - if ( debug > 2 ) System.err.println(" Alignment structure1 parsed"); + //logger.trace(" Alignment structure1 parsed"); aparser.initAlignment( null ); align2 = aparser.parse( alignName2 ); - if ( debug > 2 ) System.err.println(" Alignment structure2 parsed"); + //logger.trace(" Alignment structure2 parsed"); } catch (Exception ex) { throw new AlignmentException( "Cannot parse ", ex ); } // Create evaluator object eval = new PRecEvaluator( align1, align2 ); // Compare - params.setProperty( "debug", Integer.toString( nextdebug ) ); - eval.eval( params ) ; + eval.eval( parameters ) ; return eval; } @@ -350,35 +326,35 @@ public class GroupOutput { } output.println("\\draw (0,2.) node[diamond"+colorFormat(cells[11])+"] {}; % l"); - if (value) output.println("\\draw (0,2.) node {"+stringFormat(cells[11])+"}; % l"); + if (values) output.println("\\draw (0,2.) node {"+stringFormat(cells[11])+"}; % l"); output.println("\\draw (0,1.) node[diamond"+colorFormat(cells[5])+"] {}; % lp"); - if (value) output.println("\\draw (0,1.) node {"+stringFormat(cells[5])+"}; % lp"); + if (values) output.println("\\draw (0,1.) node {"+stringFormat(cells[5])+"}; % lp"); output.println("\\draw (0.5,1.5) node[diamond"+colorFormat(cells[2])+"] {}; % lip"); - if (value) output.println("\\draw (0.5,1.5) node {"+stringFormat(cells[2])+"}; % lip"); + if (values) output.println("\\draw (0.5,1.5) node {"+stringFormat(cells[2])+"}; % lip"); output.println("\\draw (1.,2.) node[diamond"+colorFormat(cells[6])+"] {}; %li"); - if (value) output.println("\\draw (1.,2.) node {"+stringFormat(cells[6])+"}; %li"); + if (values) output.println("\\draw (1.,2.) node {"+stringFormat(cells[6])+"}; %li"); output.println("\\draw (-0.5,-0.5) node[diamond"+colorFormat(cells[9])+"] {}; % ip"); - if (value) output.println("\\draw (-0.5,-0.5) node {"+stringFormat(cells[9])+"}; % ip"); + if (values) output.println("\\draw (-0.5,-0.5) node {"+stringFormat(cells[9])+"}; % ip"); output.println("\\draw (0,0) node[diamond"+colorFormat(cells[12])+"] {}; %p"); - if (value) output.println("\\draw (0,0) node {"+stringFormat(cells[12])+"}; %p"); + if (values) output.println("\\draw (0,0) node {"+stringFormat(cells[12])+"}; %p"); output.println("\\draw (.5,.5) node[diamond"+colorFormat(cells[3])+"] {}; % lph"); - if (value) output.println("\\draw (.5,.5) node {"+stringFormat(cells[3])+"}; % lph"); + if (values) output.println("\\draw (.5,.5) node {"+stringFormat(cells[3])+"}; % lph"); output.println("\\draw (1.,1.) node[diamond"+colorFormat(cells[0])+"] {}; % liph"); - if (value) output.println("\\draw (1.,1.) node {"+stringFormat(cells[0])+"}; % liph"); + if (values) output.println("\\draw (1.,1.) node {"+stringFormat(cells[0])+"}; % liph"); output.println("\\draw (1.5,1.5) node[diamond"+colorFormat(cells[4])+"] {}; %hil"); - if (value) output.println("\\draw (1.5,1.5) node {"+stringFormat(cells[4])+"}; %hil"); + if (values) output.println("\\draw (1.5,1.5) node {"+stringFormat(cells[4])+"}; %hil"); output.println("\\draw (2.,2.) node[diamond"+colorFormat(cells[14])+"] {}; %i"); - if (value) output.println("\\draw (2.,2.) node {"+stringFormat(cells[14])+"}; %i"); + if (values) output.println("\\draw (2.,2.) node {"+stringFormat(cells[14])+"}; %i"); output.println("\\draw (2.,1.) node[diamond"+colorFormat(cells[10])+"] {}; % hi"); - if (value) output.println("\\draw (2.,1.) node {"+stringFormat(cells[10])+"}; % hi"); + if (values) output.println("\\draw (2.,1.) node {"+stringFormat(cells[10])+"}; % hi"); output.println("\\draw (1.5,0.5) node[diamond"+colorFormat(cells[1])+"] {}; % phi"); - if (value) output.println("\\draw (1.5,0.5) node {"+stringFormat(cells[1])+"}; % phi"); + if (values) output.println("\\draw (1.5,0.5) node {"+stringFormat(cells[1])+"}; % phi"); output.println("\\draw (1.,0) node[diamond"+colorFormat(cells[8])+"] {}; % ph"); - if (value) output.println("\\draw (1.,0) node {"+stringFormat(cells[8])+"}; % ph"); + if (values) output.println("\\draw (1.,0) node {"+stringFormat(cells[8])+"}; % ph"); output.println("\\draw (2.,0) node[diamond"+colorFormat(cells[13])+"] {}; % h"); - if (value) output.println("\\draw (2.,0) node {"+stringFormat(cells[13])+"}; % h"); + if (values) output.println("\\draw (2.,0) node {"+stringFormat(cells[13])+"}; % h"); output.println("\\draw (2.5,-0.5) node[diamond"+colorFormat(cells[7])+"] {}; % hl"); - if (value) output.println("\\draw (2.5,-0.5) node {"+stringFormat(cells[7])+"}; % hl"); + if (values) output.println("\\draw (2.5,-0.5) node {"+stringFormat(cells[7])+"}; % hl"); output.println("\\end{scope}"); @@ -422,14 +398,6 @@ public class GroupOutput { } public void usage() { - System.out.println("usage: GenPlot [options]"); - System.out.println("options are:"); - System.out.println("\t--values -v\tSpecifies if the values should be displayed"); - System.out.println("\t--label -e\tSpecifies if the labels should be displayed"); - System.out.println("\t--measure=[prf] -c [prf]\tThe measure to display [F-measure]"); - System.out.println("\t--color=color -c color\tSpecifies the color to use [blue]"); - System.out.println("\t--list=algo1,...,algon -l algo1,...,algon\tSequence of the filenames to consider"); - System.out.println("\t--debug[=n] -d [n]\t\tReport debug info at level n"); - System.out.println("\t--help -h\t\t\tPrint this message"); + usage( "java "+this.getClass().getName()+" [options]\nDisplays matcher results in a topological display" ); } } diff --git a/src/fr/inrialpes/exmo/align/cli/ParserPrinter.java b/src/fr/inrialpes/exmo/align/cli/ParserPrinter.java index ff336caa..33247689 100644 --- a/src/fr/inrialpes/exmo/align/cli/ParserPrinter.java +++ b/src/fr/inrialpes/exmo/align/cli/ParserPrinter.java @@ -18,14 +18,12 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* -*/ package fr.inrialpes.exmo.align.cli; -//Imported JAVA classes import java.lang.Integer; import java.lang.Double; import java.util.Hashtable; +import java.util.List; import java.util.Properties; import java.io.File; @@ -37,8 +35,13 @@ import java.io.OutputStreamWriter; import org.xml.sax.SAXException; -import gnu.getopt.LongOpt; -import gnu.getopt.Getopt; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import org.apache.commons.cli.CommandLine; +import org.apache.commons.cli.Options; +import org.apache.commons.cli.OptionBuilder; +import org.apache.commons.cli.ParseException; import org.semanticweb.owl.align.Alignment; import org.semanticweb.owl.align.AlignmentVisitor; @@ -64,7 +67,6 @@ import fr.inrialpes.exmo.align.parser.AlignmentParser; --inverse -i Inverse first and second ontology --threshold=threshold -t threshold Trim the alugnment with regard to threshold --cutmethod=hard|perc|prop|best|span -T hard|perc|prop|best|span Method to use for triming - --debug[=n] -d [n] Report debug info at level n, --output=filename -o filename Output the alignment in filename --help -h Print this message </pre> @@ -79,7 +81,19 @@ $Id$ */ -public class ParserPrinter { +public class ParserPrinter extends CommonCLI { + final static Logger logger = LoggerFactory.getLogger( ParserPrinter.class ); + + public ParserPrinter() { + super(); + options.addOption( "i", "inverse", false, "Inverse first and second ontology" ); + options.addOption( "e", "embedded", false, "Read the alignment as embedded in a XML file" ); + options.addOption( OptionBuilder.withLongOpt( "renderer" ).hasArg().withDescription( "Use the given CLASS for rendering" ).withArgName("CLASS").create( 'r' ) ); + options.addOption( OptionBuilder.withLongOpt( "parser" ).hasArg().withDescription( "Use the given CLASS for parsing" ).withArgName("CLASS").create( 'p' ) ); + options.addOption( OptionBuilder.withLongOpt( "threshold" ).hasArg().withDescription( "Trim the alignment with regard to threshold" ).withArgName("DOUBLE").create( 't' ) ); + options.addOption( OptionBuilder.withLongOpt( "cutmethod" ).hasArg().withDescription( "Method to use for triming (hard|perc|prop|best|span)" ).withArgName("METHOD").create( 'T' ) ); + options.addOption( OptionBuilder.withLongOpt( "outputDir" ).hasArg().withDescription( "Split the output in a DIRectory (SPARQL)" ).withArgName("DIR").create( 'w' ) ); + } public static void main(String[] args) { try { new ParserPrinter().run( args ); } @@ -89,118 +103,57 @@ public class ParserPrinter { public void run(String[] args) throws Exception { Alignment result = null; String initName = null; - String filename = null; String dirName = null; PrintWriter writer = null; AlignmentVisitor renderer = null; - LongOpt[] longopts = new LongOpt[11]; - int debug = 0; String rendererClass = null; String parserClass = null; boolean inverse = false; boolean embedded = false; double threshold = 0; String cutMethod = "hard"; - Properties params = new Properties(); - - longopts[0] = new LongOpt("help", LongOpt.NO_ARGUMENT, null, 'h'); - longopts[1] = new LongOpt("output", LongOpt.REQUIRED_ARGUMENT, null, 'o'); - longopts[2] = new LongOpt("debug", LongOpt.OPTIONAL_ARGUMENT, null, 'd'); - longopts[3] = new LongOpt("renderer", LongOpt.REQUIRED_ARGUMENT, null, 'r'); - longopts[4] = new LongOpt("parser", LongOpt.REQUIRED_ARGUMENT, null, 'p'); - longopts[5] = new LongOpt("inverse", LongOpt.NO_ARGUMENT, null, 'i'); - longopts[6] = new LongOpt("threshold", LongOpt.REQUIRED_ARGUMENT, null, 't'); - longopts[7] = new LongOpt("cutmethod", LongOpt.REQUIRED_ARGUMENT, null, 'T'); - longopts[8] = new LongOpt("embedded", LongOpt.NO_ARGUMENT, null, 'e'); - longopts[9] = new LongOpt("dirName", LongOpt.REQUIRED_ARGUMENT, null, 'c'); - // Is there a way for that in LongOpt ??? - longopts[10] = new LongOpt("D", LongOpt.REQUIRED_ARGUMENT, null, 'D'); - - Getopt g = new Getopt("", args, "ehio:t:T:d::r:p:c:D:", longopts); - int c; - String arg; - while ((c = g.getopt()) != -1) { - switch(c) { - case 'h': + try { + CommandLine line = parseCommandLine( args ); + if ( line == null ) return; // --help + + // Here deal with command specific arguments + if ( line.hasOption( 'i' ) ) inverse = true; + if ( line.hasOption( 'e' ) ) embedded = true; + if ( line.hasOption( 'c' ) ) dirName = line.getOptionValue( 'c' ); + if ( line.hasOption( 'r' ) ) rendererClass = line.getOptionValue( 'r' ); + if ( line.hasOption( 'p' ) ) parserClass = line.getOptionValue( 'p' ); + if ( line.hasOption( 't' ) ) threshold = Double.parseDouble(line.getOptionValue( 't' )); + if ( line.hasOption( 'T' ) ) cutMethod = line.getOptionValue( 'T' ); + String[] argList = line.getArgs(); + if ( argList.length > 0 ) { + initName = argList[0]; + } else { + logger.error("Require the alignement filename"); usage(); - return; - case 'i': - inverse = true; - break; - case 'e': - embedded = true; - break; - case 'o': - /* Write warnings to stdout rather than stderr */ - filename = g.getOptarg(); - break; - case 'c': - dirName = g.getOptarg(); - break; - case 'r': - /* Use the given class for rendernig */ - rendererClass = g.getOptarg(); - break; - case 'p': - /* Use the given class for rendernig */ - parserClass = g.getOptarg(); - break; - case 't' : - /* Threshold */ - threshold = Double.parseDouble(g.getOptarg()); - break; - case 'T' : - /* Cut method */ - cutMethod = g.getOptarg(); - break; - case 'd': - /* Debug level */ - arg = g.getOptarg(); - if ( arg != null ) debug = Integer.parseInt(arg.trim()); - else debug = 4; - break; - case 'D' : - /* Parameter definition */ - arg = g.getOptarg(); - int index = arg.indexOf('='); - if ( index != -1 ) { - params.setProperty( arg.substring( 0, index), - arg.substring(index+1)); - } else { - System.err.println("Bad parameter syntax: "+g); - usage(); - System.exit(0); - } - break; + System.exit(-1); } - } - - int i = g.getOptind(); - - if (args.length > i ) { - initName = args[i]; - } else { - System.out.println("Require the alignement filename"); + } catch( ParseException exp ) { + logger.error( exp.getMessage() ); usage(); - return; + System.exit(-1); } - if ( debug > 1 ) System.err.println(" Filename"+initName); + //logger.trace("Filename: {}", initName); try { // Create parser AlignmentParser aparser = null; - if ( parserClass == null ) aparser = new AlignmentParser( debug ); + if ( parserClass == null ) aparser = new AlignmentParser(); else { try { - Object[] mparams = { (Object)debug }; - java.lang.reflect.Constructor[] parserConstructors = - Class.forName(parserClass).getConstructors(); - aparser = (AlignmentParser) parserConstructors[0].newInstance(mparams); + Class[] cparams = {}; + java.lang.reflect.Constructor parserConstructor = + Class.forName(parserClass).getConstructor(cparams); + Object[] mparams = {}; + aparser = (AlignmentParser) parserConstructor.newInstance(mparams); } catch (Exception ex) { - System.err.println("Cannot create parser " + - parserClass + "\n" + ex.getMessage() ); + logger.error("Cannot create parser {}", parserClass ); usage(); return; } @@ -208,22 +161,21 @@ public class ParserPrinter { aparser.setEmbedded( embedded ); result = aparser.parse( initName ); - if ( debug > 0 ) System.err.println(" Alignment structure parsed"); + logger.debug(" Alignment structure parsed"); // Set output file OutputStream stream; - if (filename == null) { + if ( outputfilename == null ) { //writer = (PrintStream) System.out; stream = System.out; - } - else { - //writer = new PrintStream(new FileOutputStream(filename)); - stream = new FileOutputStream(filename); + } else { + //writer = new PrintStream(new FileOutputStream(outputfilename)); + stream = new FileOutputStream( outputfilename ); } if ( dirName != null ) { File f = new File(dirName); f.mkdir(); - params.setProperty( "dir", dirName ); - params.setProperty( "split", "true" ); + parameters.setProperty( "dir", dirName ); + parameters.setProperty( "split", "true" ); } writer = new PrintWriter ( new BufferedWriter( @@ -239,19 +191,19 @@ public class ParserPrinter { else { try { Object[] mparams = {(Object) writer }; + // JE: Not terrible: use the right constructor java.lang.reflect.Constructor[] rendererConstructors = Class.forName(rendererClass).getConstructors(); renderer = (AlignmentVisitor) rendererConstructors[0].newInstance(mparams); } catch (Exception ex) { - System.err.println("Cannot create renderer " + - rendererClass + "\n" + ex.getMessage() ); + logger.error( "Cannot create renderer {}", rendererClass ); usage(); return; } } - renderer.init( params ); + renderer.init( parameters ); // Render the alignment try { @@ -264,27 +216,11 @@ public class ParserPrinter { } } catch (Exception ex) { - ex.printStackTrace(); + logger.debug( "IGNORED Exception", ex ); } } public void usage() { - System.out.println("usage: ParserPrinter [options] URI"); - System.out.println("options are:"); - //System.out.println("\t--alignment=filename -a filename Start from an XML alignment file"); - System.out.println("\t--debug[=n] -d [n]\t\tReport debug info at level ,"); - System.out.println("\t--renderer=className -r\t\tUse the given class for output."); - System.out.println("\t--parser=className -p\t\tUse the given class for input."); - System.out.println("\t--embedded -e\t\tRead the alignment as embedded in XML file"); - System.out.println("\t--inverse -i\t\tInverse first and second ontology"); - System.out.println("\t--threshold=threshold -t threshold\t\tTrim the alugnment with regard to threshold"); - System.out.println("\t--cutmethod=hard|perc|prop|best|span -T hard|perc|prop|best|span\t\tMethod to use for triming"); - System.out.println("\t--output=filename -o filename\tOutput the alignment in filename"); - System.out.println("\t--outputDir=dirName -c dirName\tSplit the output in a directory (SPARQL)"); - System.out.println("\t--help -h\t\t\tPrint this message"); - System.err.println("\t-Dparam=value\t\t\tSet parameter"); - System.err.print("\n"+ParserPrinter.class.getPackage().getImplementationTitle()+" "+ParserPrinter.class.getPackage().getImplementationVersion()); - System.err.println(" ($Id$)\n"); - + usage( "java "+this.getClass().getName()+" [options] alignfile\nParse the given <alignfile> and prints it" ); } } diff --git a/src/fr/inrialpes/exmo/align/cli/Procalign.java b/src/fr/inrialpes/exmo/align/cli/Procalign.java index 7a3103d1..7bac26a6 100644 --- a/src/fr/inrialpes/exmo/align/cli/Procalign.java +++ b/src/fr/inrialpes/exmo/align/cli/Procalign.java @@ -1,8 +1,6 @@ /* * $Id$ * - * Copyright (C) 2003 The University of Manchester - * Copyright (C) 2003 The University of Karlsruhe * Copyright (C) 2003-2008, 2010-2013 INRIA * Copyright (C) 2004, Universit� de Montr�al * @@ -22,9 +20,6 @@ * USA. */ -/* This program is an adaptation of the Processor.java class of the - initial release of the OWL-API -*/ package fr.inrialpes.exmo.align.cli; import org.semanticweb.owl.align.Alignment; @@ -36,21 +31,27 @@ import fr.inrialpes.exmo.align.impl.Namespace; import java.io.OutputStream; import java.io.FileOutputStream; -import java.io.FileInputStream; import java.io.PrintWriter; import java.io.BufferedWriter; import java.io.OutputStreamWriter; import java.net.URI; +import java.net.URISyntaxException; import java.util.Hashtable; import java.util.Properties; import java.lang.Double; import java.lang.Integer; import java.lang.Long; +import java.lang.reflect.Constructor; import org.xml.sax.SAXException; -import gnu.getopt.LongOpt; -import gnu.getopt.Getopt; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import org.apache.commons.cli.CommandLine; +import org.apache.commons.cli.Options; +import org.apache.commons.cli.OptionBuilder; +import org.apache.commons.cli.ParseException; import fr.inrialpes.exmo.align.parser.AlignmentParser; @@ -71,7 +72,6 @@ import fr.inrialpes.exmo.align.parser.AlignmentParser; <pre> --alignment=filename -a filename Start from an XML alignment file --params=filename -p filename Read the parameters in file - --debug[=n] -d [n] Report debug info at level n, --output=filename -o filename Output the alignment in filename --impl=className -i classname Use the given alignment implementation. --renderer=className -r className Specifies the alignment renderer @@ -86,15 +86,27 @@ import fr.inrialpes.exmo.align.parser.AlignmentParser; $Id$ </pre> -@author Sean K. Bechhofer @author J�r�me Euzenat - */ +*/ -public class Procalign { +public class Procalign extends CommonCLI { + final static Logger logger = LoggerFactory.getLogger( Procalign.class ); - public static void main(String[] args) { + public Procalign() { + super(); + options.addOption( OptionBuilder.withLongOpt( "renderer" ).hasArg().withDescription( "Use the given CLASS for output" ).withArgName("CLASS").create( 'r' ) ); + options.addOption( OptionBuilder.withLongOpt( "impl" ).hasArg().withDescription( "Use the given CLASS for matcher" ).withArgName("CLASS").create( 'i' ) ); + options.addOption( OptionBuilder.withLongOpt( "alignment" ).hasArg().withDescription( "Use initial alignment FILE" ).withArgName("FILE").create( 'a' ) ); + options.addOption( OptionBuilder.withLongOpt( "threshold" ).hasArg().withDescription( "Trim the alignment with regard to threshold" ).withArgName("DOUBLE").create( 't' ) ); + options.addOption( OptionBuilder.withLongOpt( "cutmethod" ).hasArg().withDescription( "Method to use for triming (hard|perc|prop|best|span)" ).withArgName("METHOD").create( 'T' ) ); + } + + public static void main( String[] args ) { try { new Procalign().run( args ); } - catch ( Exception ex ) { ex.printStackTrace(); }; + catch ( Exception ex ) { + ex.printStackTrace(); + System.exit(-1); + }; } public Alignment run(String[] args) throws Exception { @@ -105,152 +117,84 @@ public class Procalign { String initName = null; Alignment init = null; String alignmentClassName = "fr.inrialpes.exmo.align.impl.method.StringDistAlignment"; - String filename = null; - String paramfile = null; String rendererClass = "fr.inrialpes.exmo.align.impl.renderer.RDFRendererVisitor"; PrintWriter writer = null; AlignmentVisitor renderer = null; - int debug = 0; double threshold = 0; - Properties params = new Properties(); - - LongOpt[] longopts = new LongOpt[10]; - - longopts[0] = new LongOpt("help", LongOpt.NO_ARGUMENT, null, 'h'); - longopts[1] = new LongOpt("output", LongOpt.REQUIRED_ARGUMENT, null, 'o'); - longopts[2] = new LongOpt("alignment", LongOpt.REQUIRED_ARGUMENT, null, 'a'); - longopts[3] = new LongOpt("renderer", LongOpt.REQUIRED_ARGUMENT, null, 'r'); - longopts[4] = new LongOpt("debug", LongOpt.OPTIONAL_ARGUMENT, null, 'd'); - longopts[5] = new LongOpt("impl", LongOpt.REQUIRED_ARGUMENT, null, 'i'); - longopts[6] = new LongOpt("threshold", LongOpt.REQUIRED_ARGUMENT, null, 't'); - longopts[7] = new LongOpt("cutmethod", LongOpt.REQUIRED_ARGUMENT, null, 'T'); - longopts[8] = new LongOpt("params", LongOpt.REQUIRED_ARGUMENT, null, 'p'); - // Is there a way for that in LongOpt ??? - longopts[9] = new LongOpt("D", LongOpt.REQUIRED_ARGUMENT, null, 'D'); - - Getopt g = new Getopt("", args, "ho:a:p:d::r:t:T:i:D:", longopts); - int c; - String arg; - - while ((c = g.getopt()) != -1) { - switch (c) { - case 'h' : + CommandLine line = null; + + try { + line = parseCommandLine( args ); + } catch( ParseException exp ) { + logger.error( "Cannot parse command line", exp ); + usage(); + exit( -1 ); + } + if ( line == null ) exit(1); // --help + if ( line.hasOption( 'r' ) ) rendererClass = line.getOptionValue( 'r' ); + if ( line.hasOption( 'i' ) ) alignmentClassName = line.getOptionValue( 'i' ); + if ( line.hasOption( 'a' ) ) initName = line.getOptionValue( 'a' ); + if ( line.hasOption( 't' ) ) threshold = Double.parseDouble(line.getOptionValue( 't' )); + if ( line.hasOption( 'T' ) ) cutMethod = line.getOptionValue( 'T' ); + String[] argList = line.getArgs(); + if ( argList.length > 1 ) { + try { + onto1 = new URI( argList[0] ); + onto2 = new URI( argList[1] ); + } catch( URISyntaxException usex ) { + logger.error( "Error in ontology URIs", usex ); usage(); - return null; - case 'o' : - /* Use filename instead of stdout */ - filename = g.getOptarg(); - break; - case 'p' : - /* Read parameters from filename */ - paramfile = g.getOptarg(); - params.loadFromXML( new FileInputStream( paramfile ) ); - break; - case 'r' : - /* Use the given class for rendering */ - rendererClass = g.getOptarg(); - break; - case 'i' : - /* Use the given class for the alignment */ - alignmentClassName = g.getOptarg(); - break; - case 'a' : - /* Use the given file as a partial alignment */ - initName = g.getOptarg(); - break; - case 't' : - /* Threshold */ - threshold = Double.parseDouble(g.getOptarg()); - break; - case 'T' : - /* Cut method */ - cutMethod = g.getOptarg(); - break; - case 'd' : - /* Debug level */ - arg = g.getOptarg(); - if ( arg != null ) debug = Integer.parseInt(arg.trim()); - else debug = 4; - break; - case 'D' : - /* Parameter definition */ - arg = g.getOptarg(); - int index = arg.indexOf('='); - if ( index != -1 ) { - params.setProperty( arg.substring( 0, index), - arg.substring(index+1)); - } else { - System.err.println("Bad parameter syntax: "+g); - usage(); - System.exit(0); - } - break; + exit( -1 ); } + } else { + logger.error( "Require the ontology URIs" ); + usage(); + exit(-1); } - - int i = g.getOptind(); - if (debug > 0) { - params.setProperty( "debug", Integer.toString(debug) ); - } else if ( params.getProperty("debug") != null ) { - debug = Integer.parseInt( params.getProperty("debug") ); - } + logger.debug( "Ready to match {} and {}", onto1, onto2 ); try { - URI uri1 = null; - URI uri2 = null; - - if (args.length > i + 1) { - uri1 = new URI(args[i++]); - uri2 = new URI(args[i]); - } else if (initName == null) { - System.err.println("Two URIs required"); - usage(); - System.exit(0); + if (initName != null) { + AlignmentParser aparser = new AlignmentParser(); + Alignment al = aparser.parse( initName ); + init = al; + logger.debug("Init parsed"); } - if (debug > 0) System.err.println(" Ready"); + // Create alignment object + Class<?> alignmentClass = Class.forName( alignmentClassName ); + Class[] cparams = {}; + Constructor alignmentConstructor = alignmentClass.getConstructor(cparams); + Object[] mparams = {}; + result = (AlignmentProcess)alignmentConstructor.newInstance(mparams); + result.init( onto1, onto2 ); + } catch ( Exception ex ) { + logger.error( "Cannot create alignment {}", alignmentClassName ); + usage(); + throw ex; + } - try { - if (initName != null) { - AlignmentParser aparser = new AlignmentParser(debug); - Alignment al = aparser.parse( initName ); - init = al; - if (debug > 0) System.err.println(" Init parsed"); - } + logger.debug("Alignment structure created"); - // Create alignment object - Object[] mparams = {}; - Class<?> alignmentClass = Class.forName(alignmentClassName); - Class[] cparams = {}; - java.lang.reflect.Constructor alignmentConstructor = alignmentClass.getConstructor(cparams); - result = (AlignmentProcess)alignmentConstructor.newInstance(mparams); - result.init( uri1, uri2 ); - } catch (Exception ex) { - System.err.println("Cannot create alignment "+alignmentClassName+"\n" - +ex.getMessage()); - usage(); - throw ex; - } - - if (debug > 0) System.err.println(" Alignment structure created"); + try { // Compute alignment long time = System.currentTimeMillis(); - result.align( init, params ); // add opts + result.align( init, parameters ); // add opts long newTime = System.currentTimeMillis(); result.setExtension( Namespace.ALIGNMENT.uri, Annotations.TIME, Long.toString(newTime - time) ); // Thresholding if (threshold != 0) result.cut( cutMethod, threshold ); - if (debug > 0) System.err.println(" Matching performed"); + logger.debug( "Matching performed" ); // Set output file OutputStream stream; - if (filename == null) { + if ( outputfilename == null ) { stream = System.out; } else { - stream = new FileOutputStream(filename); + stream = new FileOutputStream( outputfilename ); } writer = new PrintWriter ( new BufferedWriter( @@ -261,18 +205,19 @@ public class Procalign { Object[] mparams = {(Object) writer }; java.lang.reflect.Constructor[] rendererConstructors = Class.forName(rendererClass).getConstructors(); + // JE: Not terrible: use the right constructor renderer = (AlignmentVisitor) rendererConstructors[0].newInstance(mparams); } catch (Exception ex) { - System.err.println("Cannot create renderer "+rendererClass+"\n" - + ex.getMessage()); + logger.error( "Cannot create renderer {}", rendererClass ); usage(); throw ex; } // Output result.render(renderer); - } catch (Exception ex) { + logger.debug( "Output printed" ); + } catch ( Exception ex ) { throw ex; } finally { if ( writer != null ) { @@ -284,18 +229,6 @@ public class Procalign { } public void usage() { - System.err.println(Procalign.class.getPackage().getImplementationTitle()+" "+Procalign.class.getPackage().getImplementationVersion()); - System.err.println("\nusage: Procalign [options] URI1 URI2"); - System.err.println("options are:"); - System.err.println("\t--impl=className -i classname\t\tUse the given alignment implementation."); - System.err.println("\t--renderer=className -r className\tSpecifies the alignment renderer"); - System.err.println("\t--output=filename -o filename\tOutput the alignment in filename"); - System.err.println("\t--params=filename -p filename\tReads parameters from filename"); - System.err.println("\t--alignment=filename -a filename Start from an XML alignment file"); - System.err.println("\t--threshold=double -t double\tFilters the similarities under threshold"); - System.err.println("\t--cutmethod=hard|perc|prop|best|span -T hard|perc|prop|best|span\tmethod for computing the threshold"); - System.err.println("\t--debug[=n] -d [n]\t\tReport debug info at level n"); - System.err.println("\t-Dparam=value\t\t\tSet parameter"); - System.err.println("\t--help -h\t\t\tPrint this message"); + usage( "java "+this.getClass().getName()+" [options] ontoURI ontoURI\nMatches the two ontologies identified by <ontoURI>" ); } } diff --git a/src/fr/inrialpes/exmo/align/cli/TestGen.java b/src/fr/inrialpes/exmo/align/cli/TestGen.java index 33be1e29..b5077d29 100644 --- a/src/fr/inrialpes/exmo/align/cli/TestGen.java +++ b/src/fr/inrialpes/exmo/align/cli/TestGen.java @@ -1,7 +1,7 @@ /* * $Id$ * - * Copyright (C) 2011-2012, INRIA + * Copyright (C) 2011-2013, INRIA * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License @@ -21,11 +21,17 @@ package fr.inrialpes.exmo.align.cli; -import gnu.getopt.Getopt; -import gnu.getopt.LongOpt; - import java.util.Properties; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import org.apache.commons.cli.CommandLine; +import org.apache.commons.cli.Options; +import org.apache.commons.cli.Option; +import org.apache.commons.cli.OptionBuilder; +import org.apache.commons.cli.ParseException; + import fr.inrialpes.exmo.align.gen.TestGenerator; import fr.inrialpes.exmo.align.gen.BenchmarkGenerator; import fr.inrialpes.exmo.align.gen.TestSet; @@ -40,23 +46,29 @@ import fr.inrialpes.exmo.align.gen.ParametersIds; </pre> where filename is the seed ontology, - and the options are: - <pre> - --debug[=n] -d [n] --> Report debug info at level n, - </pre> */ -public class TestGen { - private Properties params = null; - private String methodName = null; //the name of the method - private String fileName = null; //the name of the input file - private String dir = "."; // - private String url; // - private int debug = 0; +public class TestGen extends CommonCLI { + final static Logger logger = LoggerFactory.getLogger( TestGen.class ); + + private String methodName = null; //the name of the method + private String fileName = "onto.rdf"; //the name of the input file + private String dir = "."; // + private String url; // public TestGen() { - fileName = "onto.rdf"; + super(); + options.addOption( OptionBuilder.withLongOpt( "testset" ).hasArg().withDescription( "Use CLASS for generating the test set" ).withArgName("CLASS").create( 't' ) ); + options.addOption( OptionBuilder.withLongOpt( "outdir" ).hasArg().withDescription( "Output DIRectory (default: current)" ).withArgName("DIR").create( 'w' ) ); + options.addOption( OptionBuilder.withLongOpt( "uriprefix" ).hasArg().withDescription( "URI prefix of the seed ontology (REQUIRED)" ).withArgName("URI").create( 'u' ) ); + options.addOption( OptionBuilder.withLongOpt( "alignname" ).hasArg().withDescription( "FILEname of generated alignment (default: refalign.rdf)" ).withArgName("FILE").create( 'a' ) ); + // .setRequired( true ) + Option opt = options.getOption( "uriprefix" ); + if ( opt != null ) opt.setRequired( true ); + // We redefine the message for -o + opt = options.getOption( "output" ); + if ( opt != null ) opt.setDescription( "FILEname of the generated ontology (default: "+fileName+")" ); } public static void main(String[] args) { @@ -65,83 +77,49 @@ public class TestGen { } public void run(String[] args) throws Exception { - LongOpt[] longopts = new LongOpt[10]; - params = new Properties(); - - longopts[0] = new LongOpt("testset", LongOpt.REQUIRED_ARGUMENT, null, 't'); - longopts[1] = new LongOpt("help", LongOpt.NO_ARGUMENT, null, 'h'); - longopts[2] = new LongOpt("debug", LongOpt.OPTIONAL_ARGUMENT, null, 'd'); - longopts[3] = new LongOpt("outdir", LongOpt.REQUIRED_ARGUMENT, null, 'o'); - longopts[4] = new LongOpt("urlprefix", LongOpt.REQUIRED_ARGUMENT, null, 'u'); - longopts[5] = new LongOpt("ontoname", LongOpt.REQUIRED_ARGUMENT, null, 'n'); - longopts[6] = new LongOpt("alignname", LongOpt.REQUIRED_ARGUMENT, null, 'a'); - longopts[7] = new LongOpt("D", LongOpt.REQUIRED_ARGUMENT, null, 'D'); - - Getopt g = new Getopt("", args, "d::o:u:m:n:a:D:t:h", longopts); - int c; - String arg; - - while ((c = g.getopt()) != -1) { - switch (c) { - case 'h': + try { + CommandLine line = parseCommandLine( args ); + if ( line == null ) return; // --help + + outputfilename = fileName; // likely useless + + // Here deal with command specific arguments + if ( line.hasOption( 't' ) ) methodName = line.getOptionValue( 't' ); + if ( line.hasOption( 'o' ) ) parameters.setProperty( "ontoname", line.getOptionValue( 'o' ) ); + if ( line.hasOption( 'a' ) ) parameters.setProperty( "alignname", line.getOptionValue( 'a' ) ); + if ( line.hasOption( 'w' ) ) { + dir = line.getOptionValue( 'w' ); + parameters.setProperty( "outdir", dir ); + } + if ( line.hasOption( 'u' ) ) { + url = line.getOptionValue( 'u' ); + parameters.setProperty( "urlprefix", url ); // JE: Danger urlprefix/uriprefix + } + String[] argList = line.getArgs(); + if ( argList.length > 0 ) { + fileName = argList[0]; + parameters.setProperty( "filename", fileName ); + } else { + logger.error("Require the seed ontology filename"); usage(); - return; - case 't': - methodName = g.getOptarg(); - break; - case 'n': - params.setProperty( "ontoname", g.getOptarg() ); - break; - case 'a': - params.setProperty( "alignname", g.getOptarg() ); - break; - case 'o' : /* Use output directory */ - dir = g.getOptarg(); - params.setProperty( "outdir", dir ); - break; - case 'u' : /* URLPrefix */ - url = g.getOptarg(); - params.setProperty( "urlprefix", url ); - break; - case 'd' : /* Debug level */ - arg = g.getOptarg(); - if ( arg != null ) params.setProperty( "debug", arg.trim() ); - else params.setProperty( "debug", "4" ); - break; - case 'D' : /* Parameter definition: could be used for all parameters */ - arg = g.getOptarg(); - int index = arg.indexOf('='); - if ( index != -1 ) { - params.setProperty( arg.substring( 0, index), - arg.substring(index+1)); - } else { - System.err.println("Bad parameter syntax: "+g); - usage(); - System.exit(0); - } - break; + System.exit(-1); } - } - - // We need an ontology - int i = g.getOptind(); - - if ( args.length > i ) { - fileName = args[i]; - params.setProperty( "filename", fileName ); - } else { - System.out.println("Require the seed ontology filename"); + } catch( ParseException exp ) { + logger.error( exp.getMessage() ); usage(); - return; + System.exit(-1); } - if ( debug > 0 ) System.err.println( " >>>> "+methodName+" from "+fileName ); + logger.debug( " >>>> {} from {}", methodName, fileName ); if ( methodName == null ) { // generate one test TestGenerator tg = new TestGenerator(); + // It would certainly be better to initialise the generator with parameters tg.setDirPrefix( dir ); tg.setURLPrefix( url ); - tg.modifyOntology( fileName, (Properties)null, (String)null, params ); + if ( parameters.getProperty( "ontoname" ) != null ) tg.setOntoFilename( parameters.getProperty( "ontoname" ) ); + if ( parameters.getProperty( "alignname" ) != null ) tg.setAlignFilename( parameters.getProperty( "alignname" ) ); + tg.modifyOntology( fileName, (Properties)null, (String)null, parameters ); } else { // generate a test set TestSet tset = null; try { @@ -151,38 +129,30 @@ public class TestGen { java.lang.reflect.Constructor testSetConstructor = testSetClass.getConstructor(cparams); tset = (TestSet)testSetConstructor.newInstance(mparams); } catch (Exception ex) { - System.err.println("Cannot create TestSet "+methodName+"\n"+ex.getMessage()); + logger.error("Cannot create TestSet {}", methodName ); + logger.error("Caught error", ex ); usage(); - throw ex; + System.exit(-1); } - tset.generate( params ); + tset.generate( parameters ); } } public void usage() { - System.out.println("TestGen [options] filename"); - System.out.println("such that filename is the filename of the seed ontology\n"); - System.out.println("options are:"); - System.out.println("\t--urlprefix=url"); - System.out.println("\t--testset=classname, where classname is the name of an implementation of TestSet"); - System.out.println("\t--alignname=filename [default: refalign.rdf]"); - System.out.println("\t--ontoname=filename [default: onto.rdf]"); - System.out.println("\t--outdir=directory [default: .]"); - System.out.println("\t--help"); - System.out.println("\t--debug=number [default: 0]"); - System.out.println("\t-Dparameter=value"); - System.out.println("where the parameters are"); - System.out.println( "\tRemove percentage subclasses \""+ParametersIds.REMOVE_CLASSES+"\"" ); - System.out.println( "\tRemove percentage properties \""+ParametersIds.REMOVE_PROPERTIES+"\"" ); - System.out.println( "\tRemove percentage comments \""+ParametersIds.REMOVE_COMMENTS+"\"" ); - System.out.println( "\tRemove percentage restrictions \""+ParametersIds.REMOVE_RESTRICTIONS+"\"" ); - System.out.println( "\tRemove individuals \""+ParametersIds.REMOVE_INDIVIDUALS+"\"" ); - System.out.println( "\tAdd percentage subclasses \""+ParametersIds.ADD_CLASSES+"\"" ); - System.out.println( "\tAdd percentage properties \""+ParametersIds.ADD_PROPERTIES+"\"" ); - System.out.println( "\tRename percentage classes \""+ParametersIds.RENAME_CLASSES+"\"" ); - System.out.println( "\tRename percentage properties \""+ParametersIds.RENAME_PROPERTIES+"\"" ); - System.out.println( "\tnoHierarchy \""+ParametersIds.NO_HIERARCHY+"\"" ); - System.out.println( "\tLevel flattened \""+ParametersIds.LEVEL_FLATTENED+"\"" ); - System.out.println( "\tAdd nbClasses to a specific level \""+ParametersIds.ADD_CLASSESLEVEL+"\"" ); + usage( "java "+this.getClass().getName()+" [options] -u uriprefix filename\nGenerate ontology matching tests from the seed ontology file", + "Such that parameters may be:"+ + "\tRemove percentage subclasses \""+ParametersIds.REMOVE_CLASSES+"\""+ + "\tRemove percentage properties \""+ParametersIds.REMOVE_PROPERTIES+"\""+ + "\tRemove percentage comments \""+ParametersIds.REMOVE_COMMENTS+"\""+ + "\tRemove percentage restrictions \""+ParametersIds.REMOVE_RESTRICTIONS+"\""+ + "\tRemove individuals \""+ParametersIds.REMOVE_INDIVIDUALS+"\""+ + "\tAdd percentage subclasses \""+ParametersIds.ADD_CLASSES+"\""+ + "\tAdd percentage properties \""+ParametersIds.ADD_PROPERTIES+"\""+ + "\tRename percentage classes \""+ParametersIds.RENAME_CLASSES+"\""+ + "\tRename percentage properties \""+ParametersIds.RENAME_PROPERTIES+"\""+ + "\tnoHierarchy \""+ParametersIds.NO_HIERARCHY+"\""+ + "\tLevel flattened \""+ParametersIds.LEVEL_FLATTENED+"\""+ + "\tAdd nbClasses to a specific level \""+ParametersIds.ADD_CLASSESLEVEL+"\"" + ); } } diff --git a/src/fr/inrialpes/exmo/align/cli/WGroupEval.java b/src/fr/inrialpes/exmo/align/cli/WGroupEval.java index efc5656f..4dc2580f 100644 --- a/src/fr/inrialpes/exmo/align/cli/WGroupEval.java +++ b/src/fr/inrialpes/exmo/align/cli/WGroupEval.java @@ -1,9 +1,7 @@ /* * $Id$ * - * Copyright (C) 2003 The University of Manchester - * Copyright (C) 2003 The University of Karlsruhe - * Copyright (C) 2003-2012, INRIA + * Copyright (C) 2003-2014, INRIA * Copyright (C) 2004, Universit� de Montr�al * * This program is free software; you can redistribute it and/or @@ -47,8 +45,14 @@ import java.util.Properties; import org.xml.sax.SAXException; -import gnu.getopt.LongOpt; -import gnu.getopt.Getopt; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import org.apache.commons.cli.CommandLine; +import org.apache.commons.cli.Options; +import org.apache.commons.cli.Option; +import org.apache.commons.cli.OptionBuilder; +import org.apache.commons.cli.ParseException; import fr.inrialpes.exmo.align.parser.AlignmentParser; @@ -64,7 +68,6 @@ import fr.inrialpes.exmo.align.parser.AlignmentParser; <pre> -o filename --output=filename -f format = prfot (precision/recall/f-measure/overall/time) --format=prfot - -d debug --debug=level -r filename --reference=filename -s algo/measure -l list of compared algorithms @@ -82,108 +85,65 @@ import fr.inrialpes.exmo.align.parser.AlignmentParser; $Id$ </pre> -@author Sean K. Bechhofer -@author J�r�me Euzenat - */ +*/ -public class WGroupEval { +public class WGroupEval extends CommonCLI { + final static Logger logger = LoggerFactory.getLogger( WGroupEval.class ); - Properties params = null; - String filename = null; String reference = "refalign.rdf"; String format = "pr"; int fsize = 2; String type = "html"; boolean embedded = false; String dominant = "s"; - Vector<String> listAlgo = null; - int debug = 0; + String[] listAlgo = null; + int size = 0; String color = null; String ontoDir = null; + public WGroupEval() { + super(); + options.addOption( OptionBuilder.withLongOpt( "list" ).hasArgs().withValueSeparator(',').withDescription( "List of FILEs to be included in the results (required)" ).withArgName("FILE").create( 'l' ) ); + options.addOption( OptionBuilder.withLongOpt( "color" ).hasOptionalArg().withDescription( "Color even lines of the output in COLOR (default: lightblue)" ).withArgName("COLOR").create( 'c' ) ); + options.addOption( OptionBuilder.withLongOpt( "format" ).hasArg().withDescription( "Used (weighted) MEASures and order (precision/recall/f-measure/overall/time) (default: "+format+")" ).withArgName("MEAS (prfot)").create( 'f' ) ); + options.addOption( OptionBuilder.withLongOpt( "type" ).hasArg().withDescription( "Output TYPE (html|xml|tex|ascii|triangle; default: "+type+")" ).withArgName("TYPE").create( 't' ) ); + //options.addOption( OptionBuilder.withLongOpt( "sup" ).hasArg().withDescription( "Specifies if dominant columns are algorithms or measure" ).withArgName("algo").create( 's' ) ); + options.addOption( OptionBuilder.withLongOpt( "reference" ).hasArg().withDescription( "Name of the reference alignment FILE (default: "+reference+")" ).withArgName("FILE").create( 'r' ) ); + options.addOption( OptionBuilder.withLongOpt( "directory" ).hasOptionalArg().withDescription( "The DIRectory containing the data to evaluate" ).withArgName("DIR").create( 'w' ) ); + // .setRequired( true ) + Option opt = options.getOption( "list" ); + if ( opt != null ) opt.setRequired( true ); + } + + public static void main(String[] args) { try { new WGroupEval().run( args ); } catch (Exception ex) { ex.printStackTrace(); }; } public void run(String[] args) throws Exception { - String listFile = ""; - LongOpt[] longopts = new LongOpt[10]; - - longopts[0] = new LongOpt("help", LongOpt.NO_ARGUMENT, null, 'h'); - longopts[1] = new LongOpt("output", LongOpt.REQUIRED_ARGUMENT, null, 'o'); - longopts[2] = new LongOpt("format", LongOpt.REQUIRED_ARGUMENT, null, 'f'); - longopts[3] = new LongOpt("type", LongOpt.REQUIRED_ARGUMENT, null, 't'); - longopts[4] = new LongOpt("debug", LongOpt.OPTIONAL_ARGUMENT, null, 'd'); - longopts[5] = new LongOpt("sup", LongOpt.REQUIRED_ARGUMENT, null, 's'); - longopts[6] = new LongOpt("list", LongOpt.REQUIRED_ARGUMENT, null, 'l'); - longopts[7] = new LongOpt("color", LongOpt.OPTIONAL_ARGUMENT, null, 'c'); - longopts[8] = new LongOpt("reference", LongOpt.REQUIRED_ARGUMENT, null, 'r'); - longopts[9] = new LongOpt("directory", LongOpt.REQUIRED_ARGUMENT, null, 'w'); - - Getopt g = new Getopt("", args, "ho:a:d::l:f:t:r:w:c::", longopts); - int c; - String arg; - - while ((c = g.getopt()) != -1) { - switch (c) { - case 'h' : - usage(); - return; - case 'o' : - /* Write output here */ - filename = g.getOptarg(); - break; - case 'r' : - /* File name for the reference alignment */ - reference = g.getOptarg(); - break; - case 'f' : - /* Sequence of results to print */ - format = g.getOptarg(); - break; - case 't' : - /* Type of output (tex/html/xml/ascii) */ - type = g.getOptarg(); - break; - case 's' : - /* Print per type or per algo */ - dominant = g.getOptarg(); - break; - case 'c' : - /* Print colored lines */ - arg = g.getOptarg(); - if ( arg != null ) { - color = arg.trim(); - } else color = "lightblue"; - break; - case 'l' : - /* List of filename */ - listFile = g.getOptarg(); - break; - case 'd' : - /* Debug level */ - arg = g.getOptarg(); - if ( arg != null ) debug = Integer.parseInt(arg.trim()); - else debug = 4; - break; - case 'w' : - /* Use the given ontology directory */ - arg = g.getOptarg(); - if ( arg != null ) ontoDir = g.getOptarg(); - else ontoDir = null; - break; - } - } - listAlgo = new Vector<String>(); - for ( String s : listFile.split(",") ) { - listAlgo.add( s ); + try { + CommandLine line = parseCommandLine( args ); + if ( line == null ) return; // --help + + // Here deal with command specific arguments + if ( line.hasOption( 'f' ) ) format = line.getOptionValue( 'f' ); + if ( line.hasOption( 'r' ) ) reference = line.getOptionValue( 'r' ); + if ( line.hasOption( 's' ) ) dominant = line.getOptionValue( 's' ); + if ( line.hasOption( 't' ) ) type = line.getOptionValue( 't' ); + if ( line.hasOption( 'c' ) ) color = line.getOptionValue( 'c', "lightblue" ); + if ( line.hasOption( 'l' ) ) { + listAlgo = line.getOptionValues( 'l' ); + size = listAlgo.length; + } + if ( line.hasOption( 'w' ) ) ontoDir = line.getOptionValue( 'w' ); + } catch( ParseException exp ) { + logger.error( exp.getMessage() ); + usage(); + System.exit( -1 ); } - params = new Properties(); - if (debug > 0) params.setProperty( "debug", Integer.toString( debug-1 ) ); - print( iterateDirectories() ); } @@ -197,8 +157,9 @@ public class WGroupEval { subdir = (new File(ontoDir)).listFiles(); } } catch (Exception e) { - System.err.println("Cannot stat dir "+ e.getMessage()); + logger.error("Cannot stat dir ", e); usage(); + System.exit(-1); } int size = subdir.length; Arrays.sort(subdir); @@ -206,7 +167,7 @@ public class WGroupEval { int i = 0; for ( int j=0 ; j < size; j++ ) { if( subdir[j].isDirectory() ) { - if ( debug > 0 ) System.err.println("\nEntering directory "+subdir[j]); + //logger.trace("Entering directory {}", subdir[j]); // eval the alignments in a subdirectory // store the result Vector vect = iterateAlignments( subdir[j] ); @@ -231,7 +192,7 @@ public class WGroupEval { // call eval // store the result in a record // return the record. - if ( debug > 2) System.err.println(" Considering result "+i); + //logger.trace(" Considering result {}", i); Evaluator evaluator = eval( prefix+reference, prefix+m+".rdf"); if ( evaluator != null ) ok = true; result.add( i, evaluator ); @@ -239,8 +200,8 @@ public class WGroupEval { // Unload the ontologies. try { OntologyFactory.clear(); - } catch ( OntowrapException owex ) { // only report - owex.printStackTrace(); + } catch ( OntowrapException owex ) { + logger.debug( "IGNORED Exception", owex ); } if ( ok == true ) return result; @@ -250,57 +211,69 @@ public class WGroupEval { public Evaluator eval( String alignName1, String alignName2 ) { Evaluator eval = null; try { - int nextdebug; - if ( debug < 2 ) nextdebug = 0; - else nextdebug = debug - 2; // Load alignments - AlignmentParser aparser = new AlignmentParser( nextdebug ); + AlignmentParser aparser = new AlignmentParser(); Alignment align1 = aparser.parse( alignName1 ); - if ( debug > 2 ) System.err.println(" Alignment structure1 parsed"); + //logger.trace(" Alignment structure1 parsed"); aparser.initAlignment( null ); Alignment align2 = aparser.parse( alignName2 ); - if ( debug > 2 ) System.err.println(" Alignment structure2 parsed"); + //logger.trace(" Alignment structure2 parsed"); // Create evaluator object eval = new WeightedPREvaluator( align1, align2 ); // Compare - params.setProperty( "debug", Integer.toString( nextdebug ) ); - eval.eval( params ) ; + eval.eval( parameters ) ; } catch (Exception ex) { - if ( debug > 1 ) { - ex.printStackTrace(); - } else { - System.err.println("WGroupEval: "+ex); - System.err.println(alignName1+ " - "+alignName2 ); - } + logger.debug( "IGNORED Exception", ex ); }; return eval; } + /** + * The writer used to print the result + */ + PrintStream writer = null; + /** * This does not only print the results but compute the average as well */ public void print( Vector<Vector> result ) { - if ( type.equals("html") ) printHTML( result ); - else if ( type.equals("tex") ) printLATEX( result ); - else if ( type.equals("triangle") ) printTRIANGLE( result ); + PrintStream writer = null; + try { + if ( outputfilename == null ) { + writer = System.out; + } else { + writer = new PrintStream( new FileOutputStream( outputfilename ) ); + } + + if ( type.equals("html") ) printHTML( result, writer ); + else if ( type.equals("tex") ) printLATEX( result, writer ); + else if ( type.equals("triangle") ) printTRIANGLE( result, writer ); + } catch (Exception ex) { + logger.debug( "IGNORED Exception", ex ); + } finally { + writer.close(); + } } - public void printTRIANGLE( Vector<Vector> result ) { + public void printTRIANGLE( Vector<Vector> result, PrintStream writer ) { // variables for computing iterative harmonic means double expected = 0.; // expected so far double foundVect[]; // found so far - double correctVect[]; // correct so far + double correctFoundVect[]; // correct so far + double correctExpVect[]; // correct so far long timeVect[]; // time so far - foundVect = new double[ listAlgo.size() ]; - correctVect = new double[ listAlgo.size() ]; - timeVect = new long[ listAlgo.size() ]; - for( int k = listAlgo.size()-1; k >= 0; k-- ) { + foundVect = new double[ size ]; + correctFoundVect = new double[ size ]; + correctExpVect = new double[ size ]; + timeVect = new long[ size ]; + for( int k = size-1; k >= 0; k-- ) { foundVect[k] = 0.; - correctVect[k] = 0.; + correctFoundVect[k] = 0.; + correctExpVect[k] = 0.; timeVect[k] = 0; } for ( Vector test : result ) { - int nexpected = -1; + double newexpected = -1.; Enumeration f = test.elements(); // Too bad the first element must be skipped f.nextElement(); @@ -308,56 +281,59 @@ public class WGroupEval { WeightedPREvaluator eval = (WeightedPREvaluator)f.nextElement(); if ( eval != null ){ // iterative H-means computation - if ( nexpected == -1 ){ - nexpected = 0; - expected += eval.getExpected(); + if ( newexpected == -1. ){ + newexpected = eval.getExpected(); + expected += newexpected; } foundVect[k] += eval.getFound(); - correctVect[k] += eval.getCorrect(); + correctFoundVect[k] += eval.getCorrectFound(); + correctExpVect[k] += eval.getCorrectExpected(); timeVect[k] += eval.getTime(); + } else { + correctExpVect[k] += newexpected; } } } - System.out.println("\\documentclass[11pt]{book}"); - System.out.println(); - System.out.println("\\usepackage{pgf}"); - System.out.println("\\usepackage{tikz}"); - System.out.println(); - System.out.println("\\begin{document}"); - System.out.println("\\date{today}"); - System.out.println(""); - System.out.println("\n%% Plot generated by GenPlot of alignapi"); - System.out.println("\\begin{tikzpicture}[cap=round]"); - System.out.println("% Draw grid"); - System.out.println("\\draw[step=1cm,very thin,color=gray] (-0.2,-0.2) grid (10.0,9.0);"); - System.out.println("\\draw[|-|] (-0,0) -- (10,0);"); - System.out.println("%\\draw[dashed,very thin] (0,0) -- (5,8.66) -- (10,0);"); - System.out.println("\\draw[dashed,very thin] (10,0) arc (0:60:10cm);"); - System.out.println("\\draw[dashed,very thin] (0,0) arc (180:120:10cm);"); - - System.out.println("\\draw (0,-0.3) node {$recall$}; "); - System.out.println("\\draw (10,-0.3) node {$precision$}; "); - //System.out.println("\\draw (0,-0.3) node {0.}; "); - //System.out.println("\\draw (10,-0.3) node {1.}; "); - System.out.println("% Plots"); + writer.println("\\documentclass[11pt]{book}"); + writer.println(); + writer.println("\\usepackage{pgf}"); + writer.println("\\usepackage{tikz}"); + writer.println(); + writer.println("\\begin{document}"); + writer.println("\\date{today}"); + writer.println(""); + writer.println("\n%% Plot generated by GenPlot of alignapi"); + writer.println("\\begin{tikzpicture}[cap=round]"); + writer.println("% Draw grid"); + writer.println("\\draw[step=1cm,very thin,color=gray] (-0.2,-0.2) grid (10.0,9.0);"); + writer.println("\\draw[|-|] (-0,0) -- (10,0);"); + writer.println("%\\draw[dashed,very thin] (0,0) -- (5,8.66) -- (10,0);"); + writer.println("\\draw[dashed,very thin] (10,0) arc (0:60:10cm);"); + writer.println("\\draw[dashed,very thin] (0,0) arc (180:120:10cm);"); + + writer.println("\\draw (0,-0.3) node {$recall$}; "); + writer.println("\\draw (10,-0.3) node {$precision$}; "); + //writer.println("\\draw (0,-0.3) node {0.}; "); + //writer.println("\\draw (10,-0.3) node {1.}; "); + writer.println("% Plots"); int k = 0; for ( String m: listAlgo ) { - double precision = correctVect[k]/foundVect[k]; - double recall = correctVect[k]/expected; + double precision = 1. - correctFoundVect[k]/foundVect[k]; + double recall = 1. - correctExpVect[k]/expected; double prec2 = precision*precision; double a = ((prec2-(recall*recall)+1)/2); double b = java.lang.Math.sqrt( prec2 - (a*a) ); a = a*10; b = b*10; //for printing scale 10. - System.out.println("\\draw plot[mark=+,] coordinates {("+a+","+b+")};"); - System.out.println("\\draw ("+(a+.01)+","+(b+.01)+") node[anchor=south west] {"+m+"};"); + writer.println("\\draw plot[mark=+,] coordinates {("+a+","+b+")};"); + writer.println("\\draw ("+(a+.01)+","+(b+.01)+") node[anchor=south west] {"+m+"};"); k++; } - System.out.println("\\end{tikzpicture}"); - System.out.println(); - System.out.println("\\end{document}"); + writer.println("\\end{tikzpicture}"); + writer.println(); + writer.println("\\end{document}"); } - public void printLATEX( Vector result ) { + public void printLATEX( Vector result, PrintStream writer ) { } /* A few comments on how and why computing "weighted harmonic means" @@ -406,182 +382,162 @@ and which the program does... */ - public void printHTML( Vector<Vector> result ) { + public void printHTML( Vector<Vector> result, PrintStream writer ) { // variables for computing iterative harmonic means int expected = 0; // expected so far int foundVect[]; // found so far - int correctVect[]; // correct so far + int correctFoundVect[]; // correct so far + int correctExpVect[]; // correct so far long timeVect[]; // time so far - PrintStream writer = null; fsize = format.length(); // JE: the writer should be put out // JE: the h-means computation should be put out as well - try { - // Print result - if ( filename == null ) { - writer = System.out; - } else { - writer = new PrintStream(new FileOutputStream( filename )); - } - Formatter formatter = new Formatter(writer); - - // Print the header - if ( embedded != true ) writer.println("<html><head></head><body>"); - writer.println("<table border='2' frame='sides' rules='groups'>"); - writer.println("<colgroup align='center' />"); - // for each algo <td spancol='2'>name</td> - for ( String m : listAlgo ) { - writer.println("<colgroup align='center' span='"+fsize+"' />"); - } - // For each file do a - writer.println("<thead valign='top'><tr><th>algo</th>"); - // for each algo <td spancol='2'>name</td> - for ( String m : listAlgo ) { - writer.println("<th colspan='"+fsize+"'>"+m+"</th>"); - } - writer.println("</tr></thead><tbody><tr><td>test</td>"); - // for each algo <td>Prec.</td><td>Rec.</td> - for ( String m : listAlgo ) { - for ( int i = 0; i < fsize; i++){ - writer.print("<td>"); - if ( format.charAt(i) == 'p' ) { - writer.print("Prec."); - } else if ( format.charAt(i) == 'f' ) { - writer.print("FMeas."); - } else if ( format.charAt(i) == 'o' ) { - writer.print("Over."); - } else if ( format.charAt(i) == 't' ) { - writer.print("Time"); - } else if ( format.charAt(i) == 'r' ) { - writer.print("Rec."); - } - writer.println("</td>"); + Formatter formatter = new Formatter( writer ); + + // Print the header + if ( embedded != true ) writer.println("<html><head></head><body>"); + writer.println("<table border='2' frame='sides' rules='groups'>"); + writer.println("<colgroup align='center' />"); + // for each algo <td spancol='2'>name</td> + for ( String m : listAlgo ) { + writer.println("<colgroup align='center' span='"+fsize+"' />"); + } + // For each file do a + writer.println("<thead valign='top'><tr><th>algo</th>"); + // for each algo <td spancol='2'>name</td> + for ( String m : listAlgo ) { + writer.println("<th colspan='"+fsize+"'>"+m+"</th>"); + } + writer.println("</tr></thead><tbody><tr><td>test</td>"); + // for each algo <td>Prec.</td><td>Rec.</td> + for ( String m : listAlgo ) { + for ( int i = 0; i < fsize; i++){ + writer.print("<td>"); + if ( format.charAt(i) == 'p' ) { + writer.print("Prec."); + } else if ( format.charAt(i) == 'f' ) { + writer.print("FMeas."); + } else if ( format.charAt(i) == 'o' ) { + writer.print("Over."); + } else if ( format.charAt(i) == 't' ) { + writer.print("Time"); + } else if ( format.charAt(i) == 'r' ) { + writer.print("Rec."); } - //writer.println("<td>Prec.</td><td>Rec.</td>"); + writer.println("</td>"); } - writer.println("</tr></tbody><tbody>"); - foundVect = new int[ listAlgo.size() ]; - correctVect = new int[ listAlgo.size() ]; - timeVect = new long[ listAlgo.size() ]; - for( int k = listAlgo.size()-1; k >= 0; k-- ) { - foundVect[k] = 0; - correctVect[k] = 0; - timeVect[k] = 0; - } - // </tr> - // For each directory <tr> - boolean colored = false; - for ( Vector test : result ) { - int nexpected = -1; - if ( colored == true && color != null ){ - colored = false; - writer.println("<tr bgcolor=\""+color+"\">"); - } else { - colored = true; - writer.println("<tr>"); - }; - // Print the directory <td>bla</td> - writer.println("<td>"+(String)test.get(0)+"</td>"); - // For each record print the values <td>bla</td> - Enumeration f = test.elements(); - f.nextElement(); - for( int k = 0 ; f.hasMoreElements() ; k++) { - WeightedPREvaluator eval = (WeightedPREvaluator)f.nextElement(); - if ( eval != null ){ - // iterative H-means computation - if ( nexpected == -1 ){ - expected += eval.getExpected(); - nexpected = 0; - } - foundVect[k] += eval.getFound(); - correctVect[k] += eval.getCorrect(); - timeVect[k] += eval.getTime(); - - for ( int i = 0 ; i < fsize; i++){ - writer.print("<td>"); - if ( format.charAt(i) == 'p' ) { - formatter.format("%1.2f", eval.getPrecision()); - } else if ( format.charAt(i) == 'f' ) { - formatter.format("%1.2f", eval.getFmeasure()); - } else if ( format.charAt(i) == 'o' ) { - formatter.format("%1.2f", eval.getOverall()); - } else if ( format.charAt(i) == 't' ) { - if ( eval.getTime() == 0 ){ - writer.print("-"); - } else { - formatter.format("%1.2f", eval.getTime()); - } - } else if ( format.charAt(i) == 'r' ) { - formatter.format("%1.2f", eval.getRecall()); + //writer.println("<td>Prec.</td><td>Rec.</td>"); + } + writer.println("</tr></tbody><tbody>"); + foundVect = new int[ size ]; + correctFoundVect = new int[ size ]; + correctExpVect = new int[ size ]; + timeVect = new long[ size ]; + for( int k = size-1; k >= 0; k-- ) { + foundVect[k] = 0; + correctFoundVect[k] = 0; + correctExpVect[k] = 0; + timeVect[k] = 0; + } + // </tr> + // For each directory <tr> + boolean colored = false; + for ( Vector test : result ) { + double newexpected = -1.; + if ( colored == true && color != null ){ + colored = false; + writer.println("<tr bgcolor=\""+color+"\">"); + } else { + colored = true; + writer.println("<tr>"); + }; + // Print the directory <td>bla</td> + writer.println("<td>"+(String)test.get(0)+"</td>"); + // For each record print the values <td>bla</td> + Enumeration f = test.elements(); + f.nextElement(); + for( int k = 0 ; f.hasMoreElements() ; k++) { + WeightedPREvaluator eval = (WeightedPREvaluator)f.nextElement(); + if ( eval != null ) { + // iterative H-means computation + if ( newexpected == -1. ){ + newexpected = eval.getExpected(); + expected += newexpected; + } + foundVect[k] += eval.getFound(); + correctFoundVect[k] += eval.getCorrectFound(); + correctExpVect[k] += eval.getCorrectExpected(); + timeVect[k] += eval.getTime(); + + for ( int i = 0 ; i < fsize; i++){ + writer.print("<td>"); + if ( format.charAt(i) == 'p' ) { + formatter.format("%1.2f", eval.getPrecision()); + } else if ( format.charAt(i) == 'f' ) { + formatter.format("%1.2f", eval.getFmeasure()); + } else if ( format.charAt(i) == 'o' ) { + formatter.format("%1.2f", eval.getOverall()); + } else if ( format.charAt(i) == 't' ) { + if ( eval.getTime() == 0 ){ + writer.print("-"); + } else { + formatter.format("%1.2f", eval.getTime()); } - writer.println("</td>"); + } else if ( format.charAt(i) == 'r' ) { + formatter.format("%1.2f", eval.getRecall()); } - } else { - writer.println("<td>n/a</td><td>n/a</td>"); + writer.println("</td>"); } + } else { // JE 2013: will break if the previous tests are all NULL + correctExpVect[k] += newexpected; + // Nothing needs to be incremented for precision + for ( int i = 0 ; i < fsize; i++) writer.print("<td>n/a</td>"); + writer.println(); } - writer.println("</tr>"); - } - writer.print("<tr bgcolor=\"yellow\"><td>H-mean</td>"); - // Here we are computing a sheer average. - // While in the column results we print NaN when the returned - // alignment is empty, - // here we use the real values, i.e., add 0 to both correctVect and - // foundVect, so this is OK for computing the average. - int k = 0; - // ??? - for ( String m : listAlgo ) { - double precision = (double)correctVect[k]/foundVect[k]; - double recall = (double)correctVect[k]/expected; - for ( int i = 0 ; i < fsize; i++){ - writer.print("<td>"); - if ( format.charAt(i) == 'p' ) { - formatter.format("%1.2f", precision); - } else if ( format.charAt(i) == 'f' ) { - formatter.format("%1.2f", 2 * precision * recall / (precision + recall)); - } else if ( format.charAt(i) == 'o' ) { - formatter.format("%1.2f", recall * (2 - (1 / precision))); - } else if ( format.charAt(i) == 't' ) { - if ( timeVect[k] == 0 ){ - writer.print("-"); - } else { - formatter.format("%1.2f", timeVect[k]); - } - } else if ( format.charAt(i) == 'r' ) { - formatter.format("%1.2f", recall); - } - writer.println("</td>"); - }; - k++; } writer.println("</tr>"); - writer.println("</tbody></table>"); - writer.println("<p><small>n/a: result alignment not provided or not readable<br />"); - writer.println("NaN: division per zero, likely due to empty alignment.</small></p>"); - if ( embedded != true ) writer.println("</body></html>"); - } catch (Exception ex) { - ex.printStackTrace(); - } finally { - writer.close(); } - } + writer.print("<tr bgcolor=\"yellow\"><td>H-mean</td>"); + // Here we are computing a sheer average. + // While in the column results we print NaN when the returned + // alignment is empty, + // here we use the real values, i.e., add 0 to both correctVect and + // foundVect, so this is OK for computing the average. + int k = 0; + // ??? + for ( String m : listAlgo ) { + double precision = 1. - (double)correctFoundVect[k]/foundVect[k]; + double recall = 1. - (double)correctExpVect[k]/expected; + for ( int i = 0 ; i < fsize; i++){ + writer.print("<td>"); + if ( format.charAt(i) == 'p' ) { + formatter.format("%1.2f", precision); + } else if ( format.charAt(i) == 'f' ) { + formatter.format("%1.2f", 2 * precision * recall / (precision + recall)); + } else if ( format.charAt(i) == 'o' ) { + formatter.format("%1.2f", recall * (2 - (1 / precision))); + } else if ( format.charAt(i) == 't' ) { + if ( timeVect[k] == 0 ){ + writer.print("-"); + } else { + formatter.format("%1.2f", timeVect[k]); + } + } else if ( format.charAt(i) == 'r' ) { + formatter.format("%1.2f", recall); + } + writer.println("</td>"); + }; + k++; + } + writer.println("</tr>"); + writer.println("</tbody></table>"); + writer.println("<p><small>n/a: result alignment not provided or not readable<br />"); + writer.println("NaN: division per zero, likely due to empty alignment.</small></p>"); + if ( embedded != true ) writer.println("</body></html>"); + } public void usage() { - System.out.println("usage: WGroupEval [options]"); - System.out.println("options are:"); - System.out.println("\t--format=prfot -f prfot\tSpecifies the output order (precision/recall/f-measure/overall/time)"); - // Apparently not implemented - //System.out.println("\t--sup=algo -s algo\tSpecifies if dominant columns are algorithms or measure"); - System.out.println("\t--output=filename -o filename\tSpecifies a file to which the output will go"); - System.out.println("\t--reference=filename -r filename\tSpecifies the name of the reference alignment file (default: refalign.rdf)"); - - System.out.println("\t--type=html|xml|tex|ascii|triangle -t html|xml|tex|ascii\tSpecifies the output format"); - System.out.println("\t--list=algo1,...,algon -l algo1,...,algon\tSequence of the filenames to consider"); - System.out.println("\t--color=color -c color\tSpecifies if the output must color even lines of the output"); - System.out.println("\t--debug[=n] -d [n]\t\tReport debug info at level n"); - System.out.println("\t--help -h\t\t\tPrint this message"); - System.err.print("\n"+WGroupEval.class.getPackage().getImplementationTitle()+" "+WGroupEval.class.getPackage().getImplementationVersion()); - System.err.println(" ($Id$)\n"); + usage( "java "+this.getClass().getName()+" [options]\nEvaluates (with weighted measures) in parallel several matching results on several tests in subdirectories" ); } } diff --git a/src/fr/inrialpes/exmo/align/gen/AlteratorFactory.java b/src/fr/inrialpes/exmo/align/gen/AlteratorFactory.java index d80cd615..a3277c3b 100644 --- a/src/fr/inrialpes/exmo/align/gen/AlteratorFactory.java +++ b/src/fr/inrialpes/exmo/align/gen/AlteratorFactory.java @@ -1,7 +1,7 @@ /** * $Id$ * - * Copyright (C) INRIA, 2011 + * Copyright (C) INRIA, 2011, 2013 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -23,10 +23,13 @@ package fr.inrialpes.exmo.align.gen; import java.util.Map; import java.util.HashMap; import java.util.Properties; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.lang.reflect.InvocationTargetException; public class AlteratorFactory { + final static Logger logger = LoggerFactory.getLogger( AlteratorFactory.class ); // The parameter Ids should be here //public static final int ANY = 0; @@ -35,7 +38,7 @@ public class AlteratorFactory { private static Map<String,String> alterators = null; public static Alterator newInstance( String id, Alterator om ) { - //System.err.println( ">>>>>>>> "+id ); + //logger.trace( ">>>>>>>> {}", id ); if ( alterators == null ) init(); String classname = alterators.get( id ); Alterator alt = null; @@ -48,15 +51,15 @@ public class AlteratorFactory { Object[] mparams = { om }; alt = (Alterator)altConstructor.newInstance(mparams); } catch (ClassNotFoundException cnfex ) { - cnfex.printStackTrace(); // better raise errors + logger.debug( "IGNORED Exception", cnfex ); // better raise errors } catch (NoSuchMethodException nsmex) { - nsmex.printStackTrace(); + logger.debug( "IGNORED Exception", nsmex ); } catch (InstantiationException ieex) { - ieex.printStackTrace(); + logger.debug( "IGNORED Exception", ieex ); } catch (IllegalAccessException iaex) { - iaex.printStackTrace(); + logger.debug( "IGNORED Exception", iaex ); } catch (InvocationTargetException itex) { - itex.printStackTrace(); + logger.debug( "IGNORED Exception", itex ); } } return alt; @@ -151,7 +154,7 @@ public class AlteratorFactory { /* for( String key : params.stringPropertyNames() ) { String value = params.getProperty(key); - //if ( debug ) System.out.println( "[" +key + "] => [" + value + "]"); + //logger.trace( "[{}] = [{}]", key, value ); modifier.modifyOntology( key, value ); //modify the ontology according to it } */ diff --git a/src/fr/inrialpes/exmo/align/gen/BenchmarkGenerator.java b/src/fr/inrialpes/exmo/align/gen/BenchmarkGenerator.java index 10a35ea5..5bcad129 100644 --- a/src/fr/inrialpes/exmo/align/gen/BenchmarkGenerator.java +++ b/src/fr/inrialpes/exmo/align/gen/BenchmarkGenerator.java @@ -1,7 +1,7 @@ /* * $Id$ * - * Copyright (C) 2011, INRIA + * Copyright (C) 2011, 2013, INRIA * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License @@ -29,11 +29,14 @@ package fr.inrialpes.exmo.align.gen; import java.util.Properties; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + public class BenchmarkGenerator extends TestSet { + final static Logger logger = LoggerFactory.getLogger( BenchmarkGenerator.class ); public void initTestCases( Properties params ) { // Process params - debug = ( params.getProperty( "debug" ) != null ); // JE: ugly secondOntoFile = params.getProperty( "outdir" )+"/101/onto.rdf"; @@ -47,11 +50,11 @@ public class BenchmarkGenerator extends TestSet { try { if ( hard != null && !hard.equals("") ) incr = Float.parseFloat( hard ); } catch ( Exception ex ) { - ex.printStackTrace(); // continue with the default + logger.debug( "IGNORED Exception (continue with default)", ex ); } String max = params.getProperty( "maximum" ); if ( max != null ) maximum = Integer.parseInt( max ); - if ( debug ) System.err.println( " Mod: "+mod+" / Incr: "+incr+" / Max: "+maximum ); + logger.trace( " Mod: {} / Incr: {} / Max: {}", mod, incr, maximum ); /* Test 101 Generate the initial situation */ initTests( "101" ); @@ -65,7 +68,7 @@ public class BenchmarkGenerator extends TestSet { if ( i > 0 ) PREVTEST = "201"+SUFFIX; // The previous suffix if ( !multModality ) i1 += incr; // traditional else i1 += (1. - i1) * incr; // hardened - //if ( debug ) System.err.println( " ******************************************************** "+i+": i1 = "+i1 ); + //logger.trace( " ******************************************************** {}: i1 = {}", i, i1 ); if ( i1 < 1.0f ) { SUFFIX = "-"+(i+1)*2; //((Float)i1).toString().substring(2, 3); // 2 4 6 8 diff --git a/src/fr/inrialpes/exmo/align/gen/ClassHierarchy.java b/src/fr/inrialpes/exmo/align/gen/ClassHierarchy.java index 5a57f078..d5aeea90 100644 --- a/src/fr/inrialpes/exmo/align/gen/ClassHierarchy.java +++ b/src/fr/inrialpes/exmo/align/gen/ClassHierarchy.java @@ -1,7 +1,7 @@ /* * $Id$ * - * Copyright (C) 2011-2012, INRIA + * Copyright (C) 2011-2013, INRIA * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License @@ -43,7 +43,12 @@ import java.util.ArrayList; import java.util.Random; import java.util.Iterator; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + public class ClassHierarchy { + final static Logger logger = LoggerFactory.getLogger( ClassHierarchy.class ); + private URITree root; //the root of the tree private Map<AnonId,String> m_anonIDs = new HashMap<AnonId,String>(); private int m_anonCount = 0; @@ -119,23 +124,23 @@ public class ClassHierarchy { } /* if ( childClasses.get(childClasses.size()-1) != null ) { - System.err.print( childClasses.get(childClasses.size()-1).getURI() ); + logger.trace( childClasses.get(childClasses.size()-1).getURI() ); } else { - System.err.print( "**NULL**" ); + logger.trace( "**NULL**" ); } System.err.print( " < "); if ( parentClasses.get(childClasses.size()-1) != null ) { - System.err.print( parentClasses.get(childClasses.size()-1).getURI() ); + logger.trace( parentClasses.get(childClasses.size()-1).getURI() ); } else { - System.err.print( "**NULL**" ); + logger.trace( "**NULL**" ); } - System.err.print( " < "); + logger.trace( " < "); if ( superLevelClasses.get(childClasses.size()-1) != null ) { - System.err.print( superLevelClasses.get(childClasses.size()-1).getURI() ); + logger.trace( superLevelClasses.get(childClasses.size()-1).getURI() ); } else { - System.err.print( "**NULL**" ); + logger.trace( "**NULL**" ); } - System.err.println(); + logger.trace("------------------"); */ childNode.setParent( superNode ); //change the parent of my superclass to the [parent of the "parent node"] // JE : likely wrong in multiple inheritance diff --git a/src/fr/inrialpes/exmo/align/gen/DiscriminantGenerator.java b/src/fr/inrialpes/exmo/align/gen/DiscriminantGenerator.java index 54a9347a..412bfc27 100644 --- a/src/fr/inrialpes/exmo/align/gen/DiscriminantGenerator.java +++ b/src/fr/inrialpes/exmo/align/gen/DiscriminantGenerator.java @@ -1,7 +1,7 @@ /* * $Id$ * - * Copyright (C) 2012, INRIA + * Copyright (C) 2012-2013, INRIA * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License @@ -29,6 +29,9 @@ package fr.inrialpes.exmo.align.gen; import java.util.Properties; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + /** * This class serves as an example for systematically generating the * alteration space at a particular resolution. @@ -38,10 +41,10 @@ import java.util.Properties; * All this could be achieved by using the parameters which could be Alterator/Step */ public class DiscriminantGenerator extends TestSet { + final static Logger logger = LoggerFactory.getLogger( DiscriminantGenerator.class ); public void initTestCases( Properties params ) { // Process params - debug = ( params.getProperty( "debug" ) != null ); // JE: ugly secondOntoFile = params.getProperty( "outdir" )+"/000/onto.rdf"; @@ -52,10 +55,10 @@ public class DiscriminantGenerator extends TestSet { try { if ( stepval != null && !stepval.equals("") ) STEP = Integer.parseInt( stepval ); } catch ( Exception ex ) { - ex.printStackTrace(); // continue with the default + logger.debug( "IGNORED Exception (continue with defaults)", ex ); } final float INCR = 1.0f/(STEP-1); - if ( debug ) System.err.println( " STEP: "+STEP+" / INCR: "+INCR ); + //logger.trace( " STEP: {} / INCR: {}", STEP, INCR ); /* Test 000 Generate the initial situation */ initTests( "000" ); diff --git a/src/fr/inrialpes/exmo/align/gen/NetworkAlignmentDropper.java b/src/fr/inrialpes/exmo/align/gen/NetworkAlignmentDropper.java index 98437ff3..fe068502 100644 --- a/src/fr/inrialpes/exmo/align/gen/NetworkAlignmentDropper.java +++ b/src/fr/inrialpes/exmo/align/gen/NetworkAlignmentDropper.java @@ -1,7 +1,7 @@ /* * $Id$ * - * Copyright (C) INRIA, 2009-2011 + * Copyright (C) INRIA, 2009-2011, 2013 * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License @@ -34,6 +34,9 @@ import java.util.Set; import java.util.Collections; import java.util.ArrayList; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + /** * NetworkAlignmentDropper * @@ -42,9 +45,10 @@ import java.util.ArrayList; * Returns a brand new BasicOntologyNetwork (with the initial alignments) */ public class NetworkAlignmentDropper implements OntologyNetworkWeakener { + final static Logger logger = LoggerFactory.getLogger( NetworkAlignmentDropper.class ); public OntologyNetwork weaken( OntologyNetwork on, double n, Properties p ) throws AlignmentException { - //System.err.println( " >>>> "+n ); + //logger.trace( " >>>> {}", n ); if ( on == null ) throw new AlignmentException( "cannot weaken null ontology network" ); if ( n < 0. || n > 1. ) throw new AlignmentException( "Argument must be between 0 and 1.: "+n ); @@ -52,7 +56,7 @@ public class NetworkAlignmentDropper implements OntologyNetworkWeakener { } public OntologyNetwork weaken( OntologyNetwork on, int n, Properties p ) throws AlignmentException { - //System.err.println( " >>>> "+n ); + //logger.trace( " >>>> {}", n ); if ( on == null ) throw new AlignmentException( "cannot weaken null ontology network" ); if ( n < 0 ) throw new AlignmentException( "Argument must be a positive integer: "+n ); diff --git a/src/fr/inrialpes/exmo/align/gen/NetworkCorrespondenceDropper.java b/src/fr/inrialpes/exmo/align/gen/NetworkCorrespondenceDropper.java index 2efb03f8..54bc4f80 100644 --- a/src/fr/inrialpes/exmo/align/gen/NetworkCorrespondenceDropper.java +++ b/src/fr/inrialpes/exmo/align/gen/NetworkCorrespondenceDropper.java @@ -1,7 +1,7 @@ /* * $Id$ * - * Copyright (C) INRIA, 2009-2011 + * Copyright (C) INRIA, 2009-2011, 2013 * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License @@ -35,6 +35,9 @@ import java.util.TreeSet; import java.util.ArrayList; import java.util.Properties; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + /** * NetworkCorrespondenceDropper * @@ -45,6 +48,7 @@ import java.util.Properties; */ public class NetworkCorrespondenceDropper implements OntologyNetworkWeakener { + final static Logger logger = LoggerFactory.getLogger( NetworkCorrespondenceDropper.class ); public OntologyNetwork weaken( OntologyNetwork on, int n, Properties p ) throws AlignmentException { throw new AlignmentException( "Cannot weaken alignments by fixed number of correspondences" ); @@ -74,14 +78,14 @@ public class NetworkCorrespondenceDropper implements OntologyNetworkWeakener { newon.addAlignment( newal ); } // Select these correspondences to delete: either shuffle or order - //System.err.println( n+" * "+corresp.size()+" = "+n*(double)(corresp.size()) ); + //logger.trace( "{} * {} = {}", n, corresp.size(), n*(double)(corresp.size()) ); int q = (int)(n*(double)(corresp.size())); if ( !threshold ) Collections.shuffle( (ArrayList)corresp ); // Suppress the n*size() last ones or those which are under threshold for ( LCell c : corresp ) { if ( q == 0 ) break; q--; - //System.err.println( "Cell ["+c.getCell().getStrength()+"] : "+c ); + //logger.trace( "Cell [{}]: {}", c.getCell().getStrength(), c ); c.getAlignment().remCell( c.getCell() ); } // Cut diff --git a/src/fr/inrialpes/exmo/align/gen/TestGenerator.java b/src/fr/inrialpes/exmo/align/gen/TestGenerator.java index 044a75ed..37242c79 100644 --- a/src/fr/inrialpes/exmo/align/gen/TestGenerator.java +++ b/src/fr/inrialpes/exmo/align/gen/TestGenerator.java @@ -1,7 +1,7 @@ /* * $Id$ * - * Copyright (C) 2011-2012, INRIA + * Copyright (C) 2011-2013, INRIA * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License @@ -49,6 +49,9 @@ import java.io.OutputStreamWriter; import java.nio.charset.Charset; import java.util.Properties; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + //Jena API classes import com.hp.hpl.jena.ontology.OntModel; import com.hp.hpl.jena.ontology.OntModelSpec; @@ -61,6 +64,8 @@ import fr.inrialpes.exmo.align.gen.alt.EmptyModification; import java.util.Properties; public class TestGenerator { + final static Logger logger = LoggerFactory.getLogger( TestGenerator.class ); + private String urlprefix = "http://example.com/"; // Prefix (before testnumber) of test URL private String dirprefix = ""; // Prefix (idem) of directory private String ontoname = "onto.rdf"; // name of ontology to generate @@ -69,7 +74,6 @@ public class TestGenerator { private OntModel modifiedOntology; //modified ontology private Alignment resultAlignment; //the reference alignment private Alterator modifier = null; //the modifier - private boolean debug = false; public TestGenerator() {} @@ -82,8 +86,6 @@ public class TestGenerator { public void setAlignFilename( String a ) { alignname = a; } - public void setDebug( boolean d ) { debug = d; } - //returns the modified ontology public OntModel getModifiedOntology() { return modifiedOntology; } @@ -191,7 +193,7 @@ public class TestGenerator { * Generate a test from an ontology */ public Properties modifyOntology( String file, Properties al, String dirName, Properties params) { - if ( debug ) System.err.println( "Source: "+file+" Target "+dirName ); + logger.trace( "Source: {}; Target {}", file, dirName ); //set the TestGenerator ontology OntModel onto = loadOntology( file ); Alterator modifier = generate( onto, params, al ); @@ -209,13 +211,10 @@ public class TestGenerator { // ******************************************************* GENERATOR //generate the alingnment public Alterator generate( OntModel onto, Properties params, Properties initalign ) { - if ( debug ) { - System.err.println( "[-------------------------------------------------]" ); - System.err.println( urlprefix+" / "+dirprefix+" / "+ontoname+" / "+alignname ); - } + logger.debug( "[-------------------------------------------------]" ); + logger.debug( "{} / {} / {} / {}", urlprefix, dirprefix, ontoname, alignname ); // Load the ontology Alterator modifier = new EmptyModification( onto ); - ((EmptyModification)modifier).setDebug( debug ); // Initialize the reference alignment if ( initalign != null ) ((EmptyModification)modifier).initializeAlignment( initalign ); modifier.modify( params ); diff --git a/src/fr/inrialpes/exmo/align/gen/TestSet.java b/src/fr/inrialpes/exmo/align/gen/TestSet.java index de5b7e5d..d05f33a0 100644 --- a/src/fr/inrialpes/exmo/align/gen/TestSet.java +++ b/src/fr/inrialpes/exmo/align/gen/TestSet.java @@ -1,7 +1,7 @@ /* * $Id$ * - * Copyright (C) 2011-2012, INRIA + * Copyright (C) 2011-2013, INRIA * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License @@ -28,6 +28,10 @@ * or generate tests independently. * * Variations can also be obtained. + * + * The API is: + * initTestCases: creates the test structure (abstract) made of TestCases + * generate: generates the actual tests using a TestGenerator */ package fr.inrialpes.exmo.align.gen; @@ -37,12 +41,15 @@ import java.util.HashMap; import java.util.Set; import java.util.HashSet; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + public abstract class TestSet { + final static Logger logger = LoggerFactory.getLogger( TestSet.class ); private String initOntoFile; //the initial ontology file protected String secondOntoFile; //the secondary ontology file protected boolean continuous = false; - protected boolean debug = false; private TestGenerator generator; // a TestGenerator @@ -59,7 +66,7 @@ public abstract class TestSet { addTestChild( tests.get( from ), name, params ); } public void addTestChild( TestCase father, String name, Properties params ) { - //System.err.println( name + " ["+father+"]" ); + //logger.trace( "{} [{}]", name, father ); TestCase c = father.addSubTest( name, params ); tests.put( name, c ); } @@ -89,7 +96,6 @@ public abstract class TestSet { // Generates the test set public void generate( Properties params ) { // Generator parameters... are these OK? - generator.setDebug( debug ); initOntoFile = params.getProperty( "filename" ); // If no filename error if ( params.getProperty( "urlprefix" ) != null ) generator.setURLPrefix( params.getProperty( "urlprefix" ) ); if ( params.getProperty( "outdir" ) != null ) generator.setDirPrefix( params.getProperty( "outdir" ) ); @@ -105,7 +111,7 @@ public abstract class TestSet { // Initialises test cases tree initTestCases( params ); // Print it - if ( debug ) printTestHierarchy( root, 0 ); + // printTestHierarchy( root, 0 ); if ( params.getProperty( "alignname" ) != null ) generator.setAlignFilename( params.getProperty( "alignname" ) ); // Generate all tests startTestGeneration(); diff --git a/src/fr/inrialpes/exmo/align/gen/URITree.java b/src/fr/inrialpes/exmo/align/gen/URITree.java index fdb77700..15266226 100644 --- a/src/fr/inrialpes/exmo/align/gen/URITree.java +++ b/src/fr/inrialpes/exmo/align/gen/URITree.java @@ -1,7 +1,7 @@ /* * $Id$ * - * Copyright (C) 2011-2012, INRIA + * Copyright (C) 2011-2013, INRIA * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License @@ -29,9 +29,14 @@ import java.util.ArrayList; import java.util.List; import java.util.Properties; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import fr.inrialpes.exmo.align.gen.alt.BasicAlterator; public class URITree { + final static Logger logger = LoggerFactory.getLogger( URITree.class ); + private String URI; //the URI of the node private ArrayList<URITree> children;//the list of children private URITree parent; //the parent of the node @@ -208,7 +213,7 @@ public class URITree { public void print( int depth ) { indent( getDepth() ); - System.err.println( "[" + getURI() + "]" + "->" + getDepth() ); + //logger.trace( "[{}] -> {}", getURI(), getDepth() ); for( URITree n : getChildrenList() ) { n.print( depth+1 ); } diff --git a/src/fr/inrialpes/exmo/align/gen/alt/AddClassLevel.java b/src/fr/inrialpes/exmo/align/gen/alt/AddClassLevel.java index 6e9116a9..50e754f1 100755 --- a/src/fr/inrialpes/exmo/align/gen/alt/AddClassLevel.java +++ b/src/fr/inrialpes/exmo/align/gen/alt/AddClassLevel.java @@ -1,7 +1,7 @@ /* * $Id$ * - * Copyright (C) 2011-2012, INRIA + * Copyright (C) 2011-2013, INRIA * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License @@ -27,11 +27,14 @@ import java.util.Properties; import java.util.List; import java.util.ArrayList; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import fr.inrialpes.exmo.align.gen.Alterator; import fr.inrialpes.exmo.align.gen.ParametersIds; - public class AddClassLevel extends BasicAlterator { + final static Logger logger = LoggerFactory.getLogger( AddClassLevel.class ); public AddClassLevel( Alterator om ) { initModel( om ); @@ -44,8 +47,8 @@ public class AddClassLevel extends BasicAlterator { int index = p.indexOf("."); int level = Integer.valueOf( p.substring(0, index) ); int nbClasses = Integer.valueOf( p.substring(index+1, p.length()) ); - if ( debug ) System.err.println( "level " + level ); - if ( debug ) System.err.println( "nbClasses " + nbClasses ); + logger.trace( "level : {}", level ); + logger.trace( "nbClasses : {}", nbClasses ); //float percentage = 1.00f; //the parent class -> if level is 1 then we create a new class //else we get a random class from the level : level-1 to be the parent of the class diff --git a/src/fr/inrialpes/exmo/align/gen/alt/BasicAlterator.java b/src/fr/inrialpes/exmo/align/gen/alt/BasicAlterator.java index 2475e307..14d850a7 100644 --- a/src/fr/inrialpes/exmo/align/gen/alt/BasicAlterator.java +++ b/src/fr/inrialpes/exmo/align/gen/alt/BasicAlterator.java @@ -1,7 +1,7 @@ /** * $Id$ * - * Copyright (C) 2011-2012, INRIA + * Copyright (C) 2011-2013, INRIA * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License @@ -48,7 +48,9 @@ import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.OutputStream; import java.io.StringWriter; -import com.hp.hpl.jena.rdf.model.RDFWriter; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; //Alignment API classes import org.semanticweb.owl.align.Alignment; @@ -57,6 +59,7 @@ import org.semanticweb.owl.align.AlignmentException; import fr.inrialpes.exmo.align.impl.URIAlignment; //JENA classes +import com.hp.hpl.jena.rdf.model.RDFWriter; import com.hp.hpl.jena.rdf.model.ModelFactory; import com.hp.hpl.jena.rdf.model.Property; import com.hp.hpl.jena.rdf.model.RDFNode; @@ -75,14 +78,13 @@ import com.hp.hpl.jena.ontology.Restriction; import com.hp.hpl.jena.ontology.AllValuesFromRestriction; import com.hp.hpl.jena.ontology.SomeValuesFromRestriction; - //gen import fr.inrialpes.exmo.align.gen.Alterator; import fr.inrialpes.exmo.align.gen.ClassHierarchy; import fr.inrialpes.exmo.align.gen.ParametersIds; public abstract class BasicAlterator implements Alterator { - protected boolean debug = false; + final static Logger logger = LoggerFactory.getLogger( BasicAlterator.class ); protected ClassHierarchy classHierarchy; // the class hierarchy protected OntModel modifiedModel; // the modified Ontology @@ -142,8 +144,6 @@ public abstract class BasicAlterator implements Alterator { // ------------------------- // Accessors - public void setDebug( boolean d ) { debug = d; } - //returns the modified ontology after changing the namespace public OntModel getModifiedOntology () { return modifiedModel; } @@ -383,9 +383,9 @@ public abstract class BasicAlterator implements Alterator { public Alignment extractAlignment( String base1, String base2 ) { Alignment extractedAlignment = new URIAlignment(); - //System.err.println( "\n-----> "+initOntologyNS ); - //System.err.println( "-----> "+base1 ); - //System.err.println( "-----> "+base2 ); + //logger.trace( "-----> {}", initOntologyNS ); + //logger.trace( "-----> {}", base1 ); + //logger.trace( "-----> {}", base2 ); try { URI onto1 = new URI( getNameSpace( base1 ) ); URI onto2 = new URI( getNameSpace( base2 ) ); @@ -398,13 +398,13 @@ public abstract class BasicAlterator implements Alterator { for ( String key : alignment.stringPropertyNames() ) { if ( !key.equals("##") ) { String value = alignment.getProperty(key); - //if ( debug ) System.err.println( "[" + source + "][" + target + "]" ); + //logger.trace( "[{} --> {}]", source, target ); extractedAlignment.addAlignCell( URI.create( base1+key ), URI.create( base2+value ) ); } } alignment.setProperty( "##", base1 ); } catch ( Exception ex ) { - ex.printStackTrace(); + logger.debug( "IGNORED Exception", ex ); } return extractedAlignment; } @@ -481,7 +481,7 @@ public abstract class BasicAlterator implements Alterator { ByteArrayInputStream in = new ByteArrayInputStream( sout.getBytes("UTF8") ); model.read( in, null ); } catch ( Exception ex ) { //UnsupportedEncodingException; - ex.printStackTrace(); + logger.debug( "IGNORED Exception", ex ); } return model; } diff --git a/src/fr/inrialpes/exmo/align/gen/alt/EmptyModification.java b/src/fr/inrialpes/exmo/align/gen/alt/EmptyModification.java index 6edcb002..dd7e2649 100755 --- a/src/fr/inrialpes/exmo/align/gen/alt/EmptyModification.java +++ b/src/fr/inrialpes/exmo/align/gen/alt/EmptyModification.java @@ -1,7 +1,7 @@ /* * $Id$ * - * Copyright (C) 2011-2012, INRIA + * Copyright (C) 2011-2013, INRIA * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License @@ -33,12 +33,16 @@ import java.util.List; import java.util.ArrayList; import java.util.HashMap; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import fr.inrialpes.exmo.align.gen.Alterator; import fr.inrialpes.exmo.align.gen.ParametersIds; import org.semanticweb.owl.align.Alignment; public class EmptyModification extends BasicAlterator { + final static Logger logger = LoggerFactory.getLogger( EmptyModification.class ); protected boolean relocateSource = false; @@ -51,7 +55,7 @@ public class EmptyModification extends BasicAlterator { // Clearly here setDebug, setNamespace are important public Alterator modify( Properties params ) { - //System.err.println( "********************************************************************************************" ); + //logger.trace( "NEW MODIFICATION ------------------------------------" ); relocateSource = ( params.getProperty( "copy101" ) != null ); if ( alignment == null ) { diff --git a/src/fr/inrialpes/exmo/align/gen/alt/FlattenLevel.java b/src/fr/inrialpes/exmo/align/gen/alt/FlattenLevel.java index 632065fd..8b221041 100755 --- a/src/fr/inrialpes/exmo/align/gen/alt/FlattenLevel.java +++ b/src/fr/inrialpes/exmo/align/gen/alt/FlattenLevel.java @@ -1,7 +1,7 @@ /* * $Id$ * - * Copyright (C) 2011-2012, INRIA + * Copyright (C) 2011-2013, INRIA * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License @@ -30,10 +30,14 @@ import java.util.List; import java.util.ArrayList; import java.util.HashMap; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import fr.inrialpes.exmo.align.gen.Alterator; import fr.inrialpes.exmo.align.gen.ParametersIds; public class FlattenLevel extends BasicAlterator { + final static Logger logger = LoggerFactory.getLogger( FlattenLevel.class ); public FlattenLevel( Alterator om ) { initModel( om ); @@ -81,10 +85,10 @@ public class FlattenLevel extends BasicAlterator { restr.add(r); if ( r.isSomeValuesFromRestriction() ) restr.add(r); - //if ( debug ) System.err.println( cls.getURI() ); + //logger.trace( "Class {}", cls.getURI() ); } } - //if ( debug ) System.err.println( restr.size() ); + //logger.trace( "Size: {}", restr.size() ); if ( !restrictions.containsKey( parentClass.getURI() ) ) { restrictions.put( parentClass.getURI(), restr ); @@ -93,9 +97,9 @@ public class FlattenLevel extends BasicAlterator { OntClass superClass = superLevelClasses.get( i ); //parent class of the child class parents if ( superClass == null ) superClass = modifiedModel.createClass( OWL.Thing.getURI() ); //Thing class - //if ( debug ) System.err.println("SuperClass class [" + superClass.getURI() + "]"); - //if ( debug ) System.err.println("Parent class [" + parentClass.getURI() + "]"); - //if ( debug ) System.err.println("Child class [" + childClass.getURI() + "]"); + //logger.trace("SuperClass class [{}]", superClass.getURI() ); + //logger.trace("Parent class [{}]", parentClass.getURI() ); + //logger.trace("Child class [{}]", childClass.getURI() ); if ( modifiedModel.containsResource( parentClass ) ) { //to check if the class appears as unionOf, someValuesFrom, allValuesFrom .. unionOf.put( parentClass.getURI(), superClass.getURI() ); diff --git a/src/fr/inrialpes/exmo/align/gen/alt/RemoveClassLevel.java b/src/fr/inrialpes/exmo/align/gen/alt/RemoveClassLevel.java index c38b5d22..84dc6e7d 100755 --- a/src/fr/inrialpes/exmo/align/gen/alt/RemoveClassLevel.java +++ b/src/fr/inrialpes/exmo/align/gen/alt/RemoveClassLevel.java @@ -1,7 +1,7 @@ /* * $Id$ * - * Copyright (C) 2011-2012, INRIA + * Copyright (C) 2011-2013, INRIA * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License @@ -28,10 +28,14 @@ import java.util.List; import java.util.ArrayList; import java.util.HashMap; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import fr.inrialpes.exmo.align.gen.Alterator; import fr.inrialpes.exmo.align.gen.ParametersIds; public class RemoveClassLevel extends BasicAlterator { + final static Logger logger = LoggerFactory.getLogger( RemoveClassLevel.class ); public RemoveClassLevel( Alterator om ) { initModel( om ); @@ -42,7 +46,7 @@ public class RemoveClassLevel extends BasicAlterator { if ( p == null ) return null; int level = Integer.parseInt( p ); HashMap<String, String> uris = new HashMap<String, String>(); - //if ( debug ) System.err.println( "Level " + level ); + //logger.trace( "Level {}", level ); buildClassHierarchy(); //build the class hierarchy if necessary for ( OntClass cl : classHierarchy.getClassesFromLevel( modifiedModel, level ) ) { //remove the classes from the hierarchy String parentURI = removeClass( cl ); diff --git a/src/fr/inrialpes/exmo/align/gen/alt/RemoveProperties.java b/src/fr/inrialpes/exmo/align/gen/alt/RemoveProperties.java index 2cda9180..ebb35822 100755 --- a/src/fr/inrialpes/exmo/align/gen/alt/RemoveProperties.java +++ b/src/fr/inrialpes/exmo/align/gen/alt/RemoveProperties.java @@ -1,7 +1,7 @@ /* * $Id$ * - * Copyright (C) 2011-2012, INRIA + * Copyright (C) 2011-2013, INRIA * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License @@ -36,11 +36,15 @@ import java.util.List; import java.util.ArrayList; import java.util.Iterator; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import fr.inrialpes.exmo.align.gen.Alterator; import fr.inrialpes.exmo.align.gen.ParametersIds; public class RemoveProperties extends BasicAlterator { + final static Logger logger = LoggerFactory.getLogger( RemoveProperties.class ); public RemoveProperties( Alterator om ) { initModel( om ); @@ -60,7 +64,7 @@ public class RemoveProperties extends BasicAlterator { int nbProperties = properties.size(); //the number of properties - //System.err.println( percentage ); + //logger.trace( "Percentage {}", percentage ); int toBeRemoved = Math.round( percentage*nbProperties ); //the number of properties to be removed //build the list of classes to be removed diff --git a/src/fr/inrialpes/exmo/align/gen/alt/RenameThings.java b/src/fr/inrialpes/exmo/align/gen/alt/RenameThings.java index 72c83853..9c95208e 100755 --- a/src/fr/inrialpes/exmo/align/gen/alt/RenameThings.java +++ b/src/fr/inrialpes/exmo/align/gen/alt/RenameThings.java @@ -1,7 +1,7 @@ /* * $Id$ * - * Copyright (C) 2011-2012, INRIA + * Copyright (C) 2011-2013, INRIA * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License @@ -52,6 +52,9 @@ import java.util.List; import java.util.ArrayList; import java.util.HashMap; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import fr.inrialpes.exmo.align.gen.Alterator; import fr.inrialpes.exmo.align.gen.ParametersIds; @@ -59,6 +62,7 @@ import fr.inrialpes.exmo.align.gen.ParametersIds; * This is only an abstract class gathering the renaming routines */ public abstract class RenameThings extends BasicAlterator { + final static Logger logger = LoggerFactory.getLogger( RenameThings.class ); // ------------------------- // Label replacement @@ -203,7 +207,7 @@ public abstract class RenameThings extends BasicAlterator { renamedClasses = nbClasses - notRenamedClasses.size(); //the number of renamed classes toBeRenamed = Math.round(percentage*nbClasses) - renamedClasses; // -renamedClasses -> for Benchmark - //System.err.println( "NbClasses = "+nbClasses+ " YetToRename = "+notRenamedClasses.size()+" I will rename = "+toBeRenamed ); + //logger.trace( "NbClasses = {}; YetToRename = {}; I will rename = {};", nbClasses, notRenamedClasses.size(), toBeRenamed ); // toBeRenamed is negative when classes have been added to the model if ( toBeRenamed < 0 ) toBeRenamed = 0; @@ -451,7 +455,7 @@ public abstract class RenameThings extends BasicAlterator { try { translatedText = Translate.execute(source, Language.ENGLISH, Language.FRENCH); } catch (Exception e) { - System.err.println( "Exception " + e.getMessage() ); + logger.debug( "IGNORED Exception", e ); } return removeSpaces ( translatedText ); } @@ -486,7 +490,7 @@ public abstract class RenameThings extends BasicAlterator { */ public String parseString (String str, boolean activeTranslateString, boolean activeSynonym) { - // if ( debug ) System.err.println ( "str = [" + str + "]" ); + // logger.trace( "str = [{}]", str ); char [] parsed = str.toCharArray(); String newString = ""; diff --git a/src/fr/inrialpes/exmo/align/impl/BasicAlignment.java b/src/fr/inrialpes/exmo/align/impl/BasicAlignment.java index 31979f25..1a464575 100644 --- a/src/fr/inrialpes/exmo/align/impl/BasicAlignment.java +++ b/src/fr/inrialpes/exmo/align/impl/BasicAlignment.java @@ -34,6 +34,9 @@ import java.util.Set; import java.util.ArrayList; import java.net.URI; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import org.xml.sax.ContentHandler; import org.semanticweb.owl.align.Alignment; @@ -54,11 +57,12 @@ import fr.inrialpes.exmo.ontowrap.OntowrapException; * In version 3.0 this class is virtually abstract. * But it cannot be declared abstract because it uses its own constructor. * - * @author J�r�me Euzenat, David Loup, Rapha�l Troncy + * @author J�r�me Euzenat, David Loup, Rapha�l Troncy * @version $Id$ */ public class BasicAlignment implements Alignment { + final static Logger logger = LoggerFactory.getLogger( BasicAlignment.class ); public void accept( AlignmentVisitor visitor ) throws AlignmentException { visitor.visit( this ); @@ -67,8 +71,6 @@ public class BasicAlignment implements Alignment { protected Ontology<Object> onto1 = null; protected Ontology<Object> onto2 = null; - protected int debug = 0; - protected String level = "0"; protected String type = "**"; @@ -676,8 +678,10 @@ public class BasicAlignment implements Alignment { if ( pretty != null ){ newext.setExtension( Namespace.ALIGNMENT.uri, Annotations.PRETTY, pretty+"/"+label ); }; - newext.setExtension( Namespace.ALIGNMENT.uri, Annotations.PROVENANCE, - extensions.getExtension( Namespace.ALIGNMENT.uri, Annotations.PROVENANCE )+"" ); + if ( extensions.getExtension( Namespace.ALIGNMENT.uri, Annotations.PROVENANCE ) != null ) { + newext.setExtension( Namespace.ALIGNMENT.uri, Annotations.PROVENANCE, + extensions.getExtension( Namespace.ALIGNMENT.uri, Annotations.PROVENANCE ) ); + } newext.setExtension( Namespace.ALIGNMENT.uri, Annotations.METHOD, method ); return newext; } @@ -731,7 +735,10 @@ public class BasicAlignment implements Alignment { public Object clone() { BasicAlignment align; try { align = createNewAlignment( onto1, onto2 ); } - catch (AlignmentException ae) { ae.printStackTrace(); return null; } + catch (AlignmentException ae) { + logger.debug( "IGNORED Exception: alignment not cloned", ae ); + return null; + } align.setType( getType() ); align.setLevel( getLevel() ); align.setFile1( getFile1() ); @@ -743,7 +750,9 @@ public class BasicAlignment implements Alignment { align.setXNamespace( label, getXNamespace( label ) ); } try { align.ingest( this ); } - catch (AlignmentException ex) { ex.printStackTrace(); } + catch (AlignmentException ex) { + logger.debug( "IGNORED Exception: alignment not ingested", ex ); + } return align; } diff --git a/src/fr/inrialpes/exmo/align/impl/BasicParameters.java b/src/fr/inrialpes/exmo/align/impl/BasicParameters.java index 837c7d3d..0cbaa053 100644 --- a/src/fr/inrialpes/exmo/align/impl/BasicParameters.java +++ b/src/fr/inrialpes/exmo/align/impl/BasicParameters.java @@ -1,7 +1,7 @@ /* * $Id$ * - * Copyright (C) INRIA, 2004-2005, 2008-2010, 2012 + * Copyright (C) INRIA, 2004-2005, 2008-2010, 2012-2014 * Copyright (C) University of Montr�al, 2004 * * This program is free software; you can redistribute it and/or @@ -30,6 +30,9 @@ import java.util.Properties; import java.io.PrintStream; import java.io.File; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import org.w3c.dom.Document; import org.w3c.dom.NodeList; import org.w3c.dom.Element; @@ -63,8 +66,9 @@ import org.semanticweb.owl.align.Parameters; * @version $Id$ */ -//@Deprecated +@Deprecated public class BasicParameters extends Properties implements Parameters, Cloneable { + final static Logger logger = LoggerFactory.getLogger( BasicParameters.class ); static final long serialVersionUID = 400L; @@ -153,13 +157,13 @@ public class BasicParameters extends Properties implements Parameters, Cloneable String paramValue = paramContent.item(0).getNodeValue().trim(); p.setParameter(paramName, paramValue); } - } catch (SAXParseException err) { - System.err.println("** Parsing error: ["+ err.getLineNumber()+"]: "+err.getSystemId()); - System.err.println(" " + err.getMessage()); - } catch (SAXException e) { - Exception x = e.getException(); - ((x == null) ? e : x).printStackTrace(); - } catch (Throwable t) { t.printStackTrace(); } + } catch ( SAXParseException err ) { + logger.debug( "IGNORED SAX Parsing exception", err ); + } catch ( SAXException e ) { + logger.debug( "IGNORED SAX exception", e ); + } catch ( Throwable t ) { + logger.debug( "IGNORED Exception", t ); + } return p; } diff --git a/src/fr/inrialpes/exmo/align/impl/BasicRelation.java b/src/fr/inrialpes/exmo/align/impl/BasicRelation.java index 1370d674..f1dc9691 100644 --- a/src/fr/inrialpes/exmo/align/impl/BasicRelation.java +++ b/src/fr/inrialpes/exmo/align/impl/BasicRelation.java @@ -1,7 +1,7 @@ /* * $Id$ * - * Copyright (C) INRIA, 2003-2005, 2007, 2009-2012 + * Copyright (C) INRIA, 2003-2005, 2007, 2009-2013 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -35,6 +35,9 @@ import java.io.PrintWriter; import java.util.HashMap; import java.util.Map; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + /** * Represents an ontology alignment relation. * @@ -43,6 +46,7 @@ import java.util.Map; */ public class BasicRelation implements Relation { + final static Logger logger = LoggerFactory.getLogger( BasicRelation.class ); private static Map<String, Class<?>> classIndex = null; @@ -87,7 +91,7 @@ public class BasicRelation implements Relation { classIndex.put( "~>", nti ); classIndex.put( "~>", nti ); } catch ( ClassNotFoundException cnfe ) { - cnfe.printStackTrace(); // should never occur + logger.debug( "IGNORED Exception (should never occur)", cnfe ); } } return classIndex.get(label); @@ -150,7 +154,7 @@ public class BasicRelation implements Relation { Constructor relationConstructor = relationClass.getConstructor((Class[])null); return (Relation)relationConstructor.newInstance((Object[])null); } catch ( Exception ex ) { - //ex.printStackTrace(); + logger.debug( "IGNORED Exception: created Basic Relation)", ex ); //Otherwise, just create a Basic relation return new BasicRelation( rel ); } diff --git a/src/fr/inrialpes/exmo/align/impl/DistanceAlignment.java b/src/fr/inrialpes/exmo/align/impl/DistanceAlignment.java index 76385ec7..fd124508 100644 --- a/src/fr/inrialpes/exmo/align/impl/DistanceAlignment.java +++ b/src/fr/inrialpes/exmo/align/impl/DistanceAlignment.java @@ -1,7 +1,7 @@ /* * $Id$ * - * Copyright (C) INRIA, 2003-2011 + * Copyright (C) INRIA, 2003-2011, 2013 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -28,6 +28,9 @@ import java.util.SortedSet; import java.util.Comparator; import java.util.Properties; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import org.semanticweb.owl.align.Alignment; import org.semanticweb.owl.align.AlignmentProcess; import org.semanticweb.owl.align.AlignmentException; @@ -51,6 +54,7 @@ import fr.inrialpes.exmo.ontosim.util.HungarianAlgorithm; */ public abstract class DistanceAlignment extends ObjectAlignment implements AlignmentProcess { + final static Logger logger = LoggerFactory.getLogger( DistanceAlignment.class ); Similarity sim; /** Creation **/ @@ -134,7 +138,7 @@ public abstract class DistanceAlignment extends ObjectAlignment implements Align if ( params.getProperty("threshold") != null ) threshold = Double.parseDouble( params.getProperty("threshold") ); - //System.err.println("The type is "+type+" with length = "+type.length()); + //logger.trace("The type is {} with length = {}", type, type.length() ); if ( type.equals("?*") || type.equals("1*") || type.equals("?+") || type.equals("1+") ) return extractqs( threshold, params ); else if ( type.equals("??") || type.equals("1?") || type.equals("?1") || type.equals("11") ) return extractqq( threshold, params ); else if ( type.equals("*?") || type.equals("+?") || type.equals("*1") || type.equals("+1") ) return extractqs( threshold, params ); @@ -209,8 +213,11 @@ public abstract class DistanceAlignment extends ObjectAlignment implements Align } } } - } catch (OntowrapException owex) { owex.printStackTrace(); //} - } catch (AlignmentException alex) { alex.printStackTrace(); } + } catch (OntowrapException owex) { + logger.debug( "IGNORED Exception", owex ); + } catch (AlignmentException alex) { + logger.debug( "IGNORED Exception", alex ); + } return((Alignment)this); } @@ -259,8 +266,11 @@ public abstract class DistanceAlignment extends ObjectAlignment implements Align } } } - } catch (OntowrapException owex) { owex.printStackTrace(); //} - } catch (AlignmentException alex) { alex.printStackTrace(); } + } catch (OntowrapException owex) { + logger.debug( "IGNORED Exception", owex ); + } catch (AlignmentException alex) { + logger.debug( "IGNORED Exception", alex ); + } return((Alignment)this); } @@ -316,8 +326,11 @@ public abstract class DistanceAlignment extends ObjectAlignment implements Align } } } - } catch ( AlignmentException alex) { alex.printStackTrace(); } - catch ( OntowrapException owex) { owex.printStackTrace(); } + } catch (OntowrapException owex) { + logger.debug( "IGNORED Exception", owex ); + } catch (AlignmentException alex) { + logger.debug( "IGNORED Exception", alex ); + } // For properties try{ int nbprop1 = ontology1().nbProperties(); @@ -358,8 +371,11 @@ public abstract class DistanceAlignment extends ObjectAlignment implements Align } } } - } catch (AlignmentException alex) { alex.printStackTrace(); } - catch (OntowrapException owex) { owex.printStackTrace(); } + } catch (OntowrapException owex) { + logger.debug( "IGNORED Exception", owex ); + } catch (AlignmentException alex) { + logger.debug( "IGNORED Exception", alex ); + } // For individuals if ( params.getProperty("noinst") == null ){ try { @@ -405,8 +421,11 @@ public abstract class DistanceAlignment extends ObjectAlignment implements Align } } } - } catch (AlignmentException alex) { alex.printStackTrace(); //} - } catch (OntowrapException owex) { owex.printStackTrace(); } + } catch (OntowrapException owex) { + logger.debug( "IGNORED Exception", owex ); + } catch (AlignmentException alex) { + logger.debug( "IGNORED Exception", alex ); + } } return((Alignment)this); } @@ -451,7 +470,7 @@ public abstract class DistanceAlignment extends ObjectAlignment implements Align public int compare( Cell o1, Cell o2 ) throws ClassCastException{ try { - //System.err.println(o1.getObject1()+" -- "+o1.getObject2()+" // "+o2.getObject1()+" -- "+o2.getObject2()); + //logger.trace("{} -- {} // {}�-- {}", o1.getObject1(), o1.getObject2(), o2.getObject1(), o2.getObject2()); if ( o1.getStrength() > o2.getStrength() ){ return -1; } else if ( o1.getStrength() < o2.getStrength() ){ @@ -533,11 +552,11 @@ public abstract class DistanceAlignment extends ObjectAlignment implements Align } }; - } catch (AlignmentException alex) { - alex.printStackTrace(); - } catch (OntowrapException owex) { - owex.printStackTrace(); - }; + } catch (OntowrapException owex) { + logger.debug( "IGNORED Exception", owex ); + } catch (AlignmentException alex) { + logger.debug( "IGNORED Exception", alex ); + } return((Alignment)this); } diff --git a/src/fr/inrialpes/exmo/align/impl/InstanceBasedMatrixMeasure.java b/src/fr/inrialpes/exmo/align/impl/InstanceBasedMatrixMeasure.java index 72fd167a..e1de26d8 100644 --- a/src/fr/inrialpes/exmo/align/impl/InstanceBasedMatrixMeasure.java +++ b/src/fr/inrialpes/exmo/align/impl/InstanceBasedMatrixMeasure.java @@ -1,7 +1,7 @@ /* * $Id$ * - * Copyright (C) INRIA, 2010 + * Copyright (C) INRIA, 2010, 2013 * * Modifications to the initial code base are copyright of their * respective authors, or their employers as appropriate. Authorship @@ -43,6 +43,9 @@ import java.util.Set; import java.util.Properties; import java.util.Vector; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + /** * InstanceBasedMatrixMeasure * @@ -59,6 +62,7 @@ import java.util.Vector; */ public abstract class InstanceBasedMatrixMeasure extends MatrixMeasure { + final static Logger logger = LoggerFactory.getLogger( InstanceBasedMatrixMeasure.class ); Set<Object>[] classinst1 = null; Set<Object>[] classinst2 = null; @@ -89,9 +93,9 @@ public abstract class InstanceBasedMatrixMeasure extends MatrixMeasure { classinst2[ classlist2.get( cl2 ).intValue() ] = ontology2.getInstances( cl2, OntologyFactory.LOCAL, OntologyFactory.FULL, OntologyFactory.NAMED ); } } catch (OntowrapException owex) { - owex.printStackTrace(); + logger.debug( "IGNORED Exception", owex ); } catch (AlignmentException alex) { - alex.printStackTrace(); + logger.debug( "IGNORED Exception", alex ); } } @@ -208,7 +212,7 @@ public abstract class InstanceBasedMatrixMeasure extends MatrixMeasure { return 0.; } public double individualMeasure( Object id1, Object id2 ) throws Exception { - //if ( debug > 4 ) System.err.println( "ID:"+id1+" -- "+id2); + //logger.trace( "ID: {} -- {}", id1, id2 ); // compute edit distance between both norms //norm1[indlist1.get(ob1).intValue()], norm2[indlist2.get(ob2).intValue()] return 0.; diff --git a/src/fr/inrialpes/exmo/align/impl/MatrixMeasure.java b/src/fr/inrialpes/exmo/align/impl/MatrixMeasure.java index 04d3002c..5c844fdb 100644 --- a/src/fr/inrialpes/exmo/align/impl/MatrixMeasure.java +++ b/src/fr/inrialpes/exmo/align/impl/MatrixMeasure.java @@ -1,7 +1,7 @@ /* * $Id$ * - * Copyright (C) INRIA, 2003-2010 + * Copyright (C) INRIA, 2003-2010, 2013 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -26,6 +26,9 @@ import java.util.Properties; import java.util.Set; import java.text.NumberFormat; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import org.semanticweb.owl.align.Alignment; import org.semanticweb.owl.align.AlignmentProcess; import org.semanticweb.owl.align.AlignmentException; @@ -47,6 +50,7 @@ import fr.inrialpes.exmo.align.impl.ObjectAlignment; public abstract class MatrixMeasure implements Similarity { + final static Logger logger = LoggerFactory.getLogger( MatrixMeasure.class ); public boolean similarity = true; @@ -126,7 +130,7 @@ public abstract class MatrixMeasure implements Similarity { proplist1 = new HashMap<Object,Integer>(); // onto1 properties indlist2 = new HashMap<Object,Integer>(); // onto2 instances indlist1 = new HashMap<Object,Integer>(); // onto1 instances - //System.err.println(" >> "+onto1+"/"+onto2 ); + //logger.trace(" >> {}/{}", onto1, onto2 ); try { // Create class lists @@ -136,7 +140,7 @@ public abstract class MatrixMeasure implements Similarity { for( Object cl : onto1.getClasses() ){ classlist1.put( cl, new Integer(nbclass1++) ); } - //System.err.println(" >> NbClasses: "+nbclass1+"/"+nbclass2 ); + //logger.trace(" >> NbClasses: {}/{}", nbclass1, nbclass2 ); clmatrix = new double[nbclass1+1][nbclass2+1]; // Create property lists @@ -152,7 +156,7 @@ public abstract class MatrixMeasure implements Similarity { for( Object pr : onto1.getDataProperties() ){ proplist1.put( pr, new Integer(nbprop1++) ); } - //System.err.println(" >> NbProp: "+nbprop1+"/"+nbprop2 ); + //logger.trace(" >> NbProp: {}/{}", nbprop1, nbprop2 ); prmatrix = new double[nbprop1+1][nbprop2+1]; // Create individual lists @@ -168,9 +172,11 @@ public abstract class MatrixMeasure implements Similarity { indlist1.put( ind, new Integer(nbind1++) ); } } - //System.err.println(" >> NbInd: "+nbind1+"/"+nbind2 ); + //logger.trace(" >> NbInd: {}/{}", nbind1, nbind2 ); indmatrix = new double[nbind1+1][nbind2+1]; - } catch (OntowrapException e) { e.printStackTrace(); }; + } catch (OntowrapException e) { + logger.debug( "IGNORED Exception", e ); + }; } @SuppressWarnings("unchecked") //ConcatenatedIterator @@ -206,7 +212,9 @@ public abstract class MatrixMeasure implements Similarity { } } // What is caught is really Exceptions - } catch (Exception e) { e.printStackTrace(); } + } catch (Exception e) { + logger.debug( "IGNORED Exception", e ); + } } public double getIndividualSimilarity( Object i1, Object i2 ){ @@ -241,7 +249,9 @@ public abstract class MatrixMeasure implements Similarity { } System.out.println("\\\\"); } - } catch (OntowrapException e) { e.printStackTrace(); }; + } catch (OntowrapException e) { + logger.debug( "IGNORED Exception", e ); + }; System.out.println("\n\\end{tabular}"); } diff --git a/src/fr/inrialpes/exmo/align/impl/ObjectAlignment.java b/src/fr/inrialpes/exmo/align/impl/ObjectAlignment.java index 37a43cc5..ab3334af 100644 --- a/src/fr/inrialpes/exmo/align/impl/ObjectAlignment.java +++ b/src/fr/inrialpes/exmo/align/impl/ObjectAlignment.java @@ -28,6 +28,9 @@ import java.util.Set; import java.util.Collection; import java.net.URI; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import org.xml.sax.SAXException; import org.semanticweb.owl.align.Alignment; @@ -52,13 +55,14 @@ import fr.inrialpes.exmo.ontowrap.OntowrapException; */ public class ObjectAlignment extends BasicAlignment { + final static Logger logger = LoggerFactory.getLogger( ObjectAlignment.class ); protected ObjectAlignment init = null; public ObjectAlignment() {} - public void init(Object onto1, Object onto2) throws AlignmentException { - if ( (onto1 instanceof LoadedOntology && onto2 instanceof LoadedOntology) ){ + public void init( Object onto1, Object onto2 ) throws AlignmentException { + if ( (onto1 instanceof LoadedOntology) && (onto2 instanceof LoadedOntology) ){ super.init( onto1, onto2 ); } else if ( onto1 instanceof URI && onto2 instanceof URI ) { super.init( loadOntology( (URI)onto1 ), @@ -161,7 +165,7 @@ public class ObjectAlignment extends BasicAlignment { } catch ( NullPointerException npe ) { throw new AlignmentException( "Cannot dereference entity "+c.getObject2AsURI( alignment ), npe ); } - //System.err.println( obj1+" "+obj2+" "+c.getRelation()+" "+c.getStrength() ); + //logger.trace( "{} {} {} {}", obj1, obj2, c.getRelation(), c.getStrength() ); if ( obj1 == null ) throw new AlignmentException( "Cannot dereference entity "+c.getObject1AsURI( alignment ) ); if ( obj2 == null ) throw new AlignmentException( "Cannot dereference entity "+c.getObject2AsURI( alignment ) ); Cell newc = alignment.addAlignCell( c.getId(), obj1, obj2, diff --git a/src/fr/inrialpes/exmo/align/impl/aggr/ConsensusAggregator.java b/src/fr/inrialpes/exmo/align/impl/aggr/ConsensusAggregator.java index f29e7021..154cb29f 100644 --- a/src/fr/inrialpes/exmo/align/impl/aggr/ConsensusAggregator.java +++ b/src/fr/inrialpes/exmo/align/impl/aggr/ConsensusAggregator.java @@ -1,7 +1,7 @@ /* * $Id$ * - * Copyright (C) INRIA, 2010 + * Copyright (C) INRIA, 2010, 2013 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -24,6 +24,9 @@ import java.util.Hashtable; import java.util.Set; import java.util.HashSet; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import org.semanticweb.owl.align.Alignment; import org.semanticweb.owl.align.AlignmentException; import org.semanticweb.owl.align.Cell; @@ -54,6 +57,7 @@ import fr.inrialpes.exmo.align.impl.BasicAlignment; */ public class ConsensusAggregator extends BasicAlignment { + final static Logger logger = LoggerFactory.getLogger( ConsensusAggregator.class ); int nbAlignments = 0; Hashtable<Cell, CountCell> count; @@ -144,7 +148,7 @@ public class ConsensusAggregator extends BasicAlignment { } } } catch (Exception ex) { - ex.printStackTrace(); + logger.debug( "IGNORED Exception", ex ); } return null; } diff --git a/src/fr/inrialpes/exmo/align/impl/edoal/EDOALAlignment.java b/src/fr/inrialpes/exmo/align/impl/edoal/EDOALAlignment.java index 095151a1..108771a9 100644 --- a/src/fr/inrialpes/exmo/align/impl/edoal/EDOALAlignment.java +++ b/src/fr/inrialpes/exmo/align/impl/edoal/EDOALAlignment.java @@ -2,7 +2,7 @@ * $Id$ * * Sourceforge version 1.6 - 2008 - was OMWGAlignment - * Copyright (C) INRIA, 2007-2012 + * Copyright (C) INRIA, 2007-2013 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -29,12 +29,16 @@ import java.util.Collection; import java.util.Set; import java.net.URI; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import org.semanticweb.owl.align.AlignmentException; import org.semanticweb.owl.align.AlignmentVisitor; import org.semanticweb.owl.align.Alignment; import org.semanticweb.owl.align.Cell; import org.semanticweb.owl.align.Relation; +import fr.inrialpes.exmo.ontowrap.OntologyFactory; import fr.inrialpes.exmo.ontowrap.Ontology; import fr.inrialpes.exmo.ontowrap.LoadedOntology; import fr.inrialpes.exmo.ontowrap.OntologyFactory; @@ -56,6 +60,7 @@ import fr.inrialpes.exmo.align.parser.TypeCheckingVisitor; * */ public class EDOALAlignment extends BasicAlignment { + final static Logger logger = LoggerFactory.getLogger( EDOALAlignment.class ); /* * An eventual initial alignment @@ -82,20 +87,13 @@ public class EDOALAlignment extends BasicAlignment { public void init( Object onto1, Object onto2 ) throws AlignmentException { if ( (onto1 == null) || (onto2 == null) ) throw new AlignmentException("The source and target ontologies must not be null"); - if ( (onto1 instanceof Ontology && onto2 instanceof Ontology) ){ - super.init( onto1, onto2 ); - } - else if ((onto1 instanceof URI && onto2 instanceof URI)) { - OntologyFactory fact = OntologyFactory.getFactory(); - try { - super.init(fact.loadOntology((URI) onto1), fact.loadOntology((URI) onto2)); - } catch (OntowrapException e) { - throw new AlignmentException("Could not load ontologies",e); - } - } - else { - throw new AlignmentException("arguments must be LoadedOntology or deferencable URIs"); - }; + Ontology o1 = null; + if ( onto1 instanceof Ontology ) o1 = (Ontology)onto1; + else o1 = loadOntology( (URI)onto1 ); + Ontology o2 = null; + if ( onto2 instanceof Ontology ) o2 = (Ontology)onto2; + else o2 = loadOntology( (URI)onto2 ); + super.init( o1, o2 ); } public void loadInit( Alignment al ) throws AlignmentException { @@ -259,30 +257,61 @@ public class EDOALAlignment extends BasicAlignment { // It would be better to implement this for ObjectAlignment // and to use return toEDOALAlignment( ObjectAlignment.toObjectAlignment( al ) ); // for URIAlignment + // + // Basic -> URI + // -> Object + // -> EDOAL + public static LoadedOntology loadOntology( URI onto ) throws AlignmentException { + if ( onto == null ) throw new AlignmentException("The source and target ontologies must not be null"); + try { + OntologyFactory fact = OntologyFactory.getFactory(); + return fact.loadOntology( onto ); + } catch ( OntowrapException owex ) { + throw new AlignmentException( "Cannot load ontologies", owex ); + } + } + public static LoadedOntology loadOntology( Ontology onto ) throws AlignmentException { + if ( onto == null ) throw new AlignmentException("The source and target ontologies must not be null"); + if ( onto instanceof LoadedOntology ) return (LoadedOntology)onto; + try { + OntologyFactory fact = OntologyFactory.getFactory(); + return fact.loadOntology( onto ); + } catch ( OntowrapException owex ) { + throw new AlignmentException( "Cannot load ontologies", owex ); + } + } + public static EDOALAlignment toEDOALAlignment( URIAlignment al ) throws AlignmentException { return toEDOALAlignment( (BasicAlignment)al ); } public static EDOALAlignment toEDOALAlignment( ObjectAlignment al ) throws AlignmentException { - return toEDOALAlignment( (BasicAlignment)al ); + logger.debug( "Converting ObjectAlignment to EDOALAlignment" ); + EDOALAlignment alignment = new EDOALAlignment(); + // They are obviously loaded + alignment.init( al.getOntologyObject1(), al.getOntologyObject2() ); + alignment.convertToEDOAL( al ); + return alignment; } public static EDOALAlignment toEDOALAlignment( BasicAlignment al ) throws AlignmentException { + logger.debug( "Converting BasicAlignment to EDOALAlignment" ); EDOALAlignment alignment = new EDOALAlignment(); - try { - alignment.init( al.getFile1(), al.getFile2() ); - } catch ( AlignmentException aex ) { - try { // Really a friendly fallback - alignment.init( al.getOntology1URI(), al.getOntology2URI() ); - } catch ( AlignmentException xx ) { - throw aex; - } - } - alignment.setType( al.getType() ); - alignment.setExtensions( al.convertExtension( "EDOALConverted", "fr.inrialpes.exmo.align.edoal.EDOALAlignment#toEDOAL" ) ); - LoadedOntology<Object> o1 = (LoadedOntology<Object>)alignment.getOntologyObject1(); // [W:unchecked] - LoadedOntology<Object> o2 = (LoadedOntology<Object>)alignment.getOntologyObject2(); // [W:unchecked] + LoadedOntology onto1 = loadOntology( al.getOntologyObject1() ); + LoadedOntology onto2 = loadOntology( al.getOntologyObject2() ); + alignment.init( onto1, onto2 ); + alignment.convertToEDOAL( al ); + return alignment; + } + /** + * The EDOALAlignment has LoadedOntologies as ontologies + */ + public void convertToEDOAL( BasicAlignment al ) throws AlignmentException { + setType( al.getType() ); + setExtensions( al.convertExtension( "toEDOAL", "fr.inrialpes.exmo.align.edoal.EDOALAlignment#toEDOAL" ) ); + LoadedOntology<Object> o1 = (LoadedOntology<Object>)getOntologyObject1(); // [W:unchecked] + LoadedOntology<Object> o2 = (LoadedOntology<Object>)getOntologyObject2(); // [W:unchecked] for ( Cell c : al ) { try { - Cell newc = alignment.addAlignCell( c.getId(), + Cell newc = addAlignCell( c.getId(), createEDOALExpression( o1, c.getObject1AsURI( al ) ), createEDOALExpression( o2, c.getObject2AsURI( al ) ), c.getRelation(), @@ -294,12 +323,11 @@ public class EDOALAlignment extends BasicAlignment { } } } catch ( AlignmentException aex ) { - aex.printStackTrace(); // continue to concert the rest + logger.debug( "IGNORED Exception (continue importing)", aex ); } catch ( OntowrapException owex ) { throw new AlignmentException( "Cannot dereference entity", owex ); } } - return alignment; } private static Id createEDOALExpression( LoadedOntology<Object> o, URI u ) throws OntowrapException, AlignmentException { @@ -312,7 +340,7 @@ public class EDOALAlignment extends BasicAlignment { return new RelationId( u ); } else if ( o.isIndividual( e ) ) { return new InstanceId( u ); - } else throw new AlignmentException( "Cannot interpret URI" ); + } else throw new AlignmentException( "Cannot interpret URI "+u ); } @@ -335,7 +363,9 @@ public class EDOALAlignment extends BasicAlignment { align.setExtensions( convertExtension( "cloned", this.getClass().getName()+"#clone" ) ); try { align.ingest( this ); - } catch (AlignmentException ex) { ex.printStackTrace(); } + } catch (AlignmentException ex) { + logger.debug( "IGNORED Exception", ex ); + } return align; } diff --git a/src/fr/inrialpes/exmo/align/impl/eval/AveragePRGraphEvaluator.java b/src/fr/inrialpes/exmo/align/impl/eval/AveragePRGraphEvaluator.java index 2fce4974..afbb08a9 100644 --- a/src/fr/inrialpes/exmo/align/impl/eval/AveragePRGraphEvaluator.java +++ b/src/fr/inrialpes/exmo/align/impl/eval/AveragePRGraphEvaluator.java @@ -1,7 +1,7 @@ /* * $Id: AveragePRGraphEvaluator.java 1196 2010-01-10 19:58:52Z euzenat $ * - * Copyright (C) INRIA, 2004-2005, 2007-2010 + * Copyright (C) INRIA, 2004-2005, 2007-2010, 2013 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -36,6 +36,9 @@ import java.util.Vector; import java.io.PrintWriter; import java.net.URI; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + /** * Compute the precision recall graph on 11 points * The first alignment is thus the expected one. @@ -72,6 +75,7 @@ import java.net.URI; */ public class AveragePRGraphEvaluator extends GraphEvaluator { + final static Logger logger = LoggerFactory.getLogger( AveragePRGraphEvaluator.class ); private int size = 0; // for averaging @@ -93,10 +97,10 @@ public class AveragePRGraphEvaluator extends GraphEvaluator { public Vector<Pair> eval(){ Vector<Pair> result = new Vector<Pair>(STEP+1); // Compute the average and build the vector pair - //System.err.println( " Size: "+size ); + //logger.trace( " Size: {}", size ); for( int j = 0; j <= STEP; j++ ) { // JE: better with j/10 - //System.err.println( " prec at "+j+" : "+precisions[j] ); + //logger.trace( " prec at {} : {}�", j, precisions[j] ); result.add( new Pair( ((double)j)/10, precisions[j] / size ) ); } map = rawmap / size; // average map @@ -115,7 +119,7 @@ public class AveragePRGraphEvaluator extends GraphEvaluator { try { evalAlignment( reference, al ); } catch ( AlignmentException aex ) { - aex.printStackTrace(); + logger.debug( "IGNORED Exception", aex ); } } @@ -166,7 +170,7 @@ public class AveragePRGraphEvaluator extends GraphEvaluator { // It works backward in the vector, // (in the same spirit as before, the maximum value so far -best- is retained) int j = inflexion.size()-1; // index in recall-ordered vector of points - //System.err.println( "Inflexion: "+j); + //logger.trace( "Inflexion: {}", j); int i = STEP; // index of the current recall interval double level = (double)i/STEP; // max level of that interval double best = 0.; // best value found for that interval diff --git a/src/fr/inrialpes/exmo/align/impl/eval/DiffEvaluator.java b/src/fr/inrialpes/exmo/align/impl/eval/DiffEvaluator.java index 5d35ff1d..a3c73934 100644 --- a/src/fr/inrialpes/exmo/align/impl/eval/DiffEvaluator.java +++ b/src/fr/inrialpes/exmo/align/impl/eval/DiffEvaluator.java @@ -1,7 +1,7 @@ /* * $Id$ * - * Copyright (C) INRIA, 2010, 2012 + * Copyright (C) INRIA, 2010, 2012-2013 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -39,16 +39,25 @@ import java.util.HashSet; import java.io.PrintWriter; import java.net.URI; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Evaluate proximity between two alignments. * This function implements Precision/Recall/Fallout. The first alignment * is thus the expected one. * + * @author: Cassia Trojahn dos Santos * @version $Id$ + * + * Possible improvements: + * (1) make it work with EDOAL + * (2) write a tool that is able to pair falsenegative and falsepositive (this has been returned instead of ...) + * */ public class DiffEvaluator extends BasicEvaluator implements Evaluator { + final static Logger logger = LoggerFactory.getLogger( DiffEvaluator.class ); Set<Cell> truepositive; Set<Cell> falsenegative; @@ -103,7 +112,7 @@ public class DiffEvaluator extends BasicEvaluator implements Evaluator { } } } catch (Exception e) { - e.printStackTrace(); + logger.debug( "IGNORED Exception", e ); } // False negative @@ -133,7 +142,7 @@ public class DiffEvaluator extends BasicEvaluator implements Evaluator { } } } catch (Exception e) { - e.printStackTrace(); + logger.debug( "IGNORED Exception", e ); } } @@ -167,7 +176,7 @@ public class DiffEvaluator extends BasicEvaluator implements Evaluator { } result += "</dd>\n"; } catch (AlignmentException e) { - e.printStackTrace(); + logger.debug( "IGNORED Exception", e ); } return result; } diff --git a/src/fr/inrialpes/exmo/align/impl/eval/ExtPREvaluator.java b/src/fr/inrialpes/exmo/align/impl/eval/ExtPREvaluator.java index f2a41482..34dd560d 100644 --- a/src/fr/inrialpes/exmo/align/impl/eval/ExtPREvaluator.java +++ b/src/fr/inrialpes/exmo/align/impl/eval/ExtPREvaluator.java @@ -43,6 +43,9 @@ import java.io.PrintWriter; import java.net.URI; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + /** * Implements extended precision and recall between alignments. * These are the measures corresponding to [Ehrig&Euzenat2005]. @@ -75,6 +78,7 @@ import java.net.URI; */ public class ExtPREvaluator extends BasicEvaluator implements Evaluator { + final static Logger logger = LoggerFactory.getLogger( ExtPREvaluator.class ); private HeavyLoadedOntology<Object> onto1; private HeavyLoadedOntology<Object> onto2; @@ -194,8 +198,9 @@ public class ExtPREvaluator extends BasicEvaluator implements Evaluator { if ( nbexpected != 0 ) precorientrec = orientPrecsimilarity / (double) nbexpected; if ( nbfound != 0 ) recorientprec = orientRecsimilarity / (double) nbfound; if ( nbexpected != 0 ) recorientrec = orientRecsimilarity / (double) nbexpected; - //System.err.println(">>>> " + nbcorrect + " : " + nbfound + " : " + nbexpected); - //System.err.println(">>>> " + symsimilarity + " : " + effsimilarity + " : " + orientRecsimilarity + " : " + orientPrecsimilarity); + //logger.trace(">>>> {}�: {}�: {}", nbcorrect, nbfound, nbexpected); + //logger.trace(">>>> {} : {}", symsimilarity, effsimilarity ); + //logger.trace(">>>> {} : {}", orientRecsimilarity, orientPrecsimilarity); return (result); } @@ -216,19 +221,20 @@ public class ExtPREvaluator extends BasicEvaluator implements Evaluator { val1 = 0; } else { val1 = Math.abs( relativePosition( c1.getObject1(), c2.getObject1(), onto1 ) ); - //System.err.println( c1.getObject1()+" -- "+c2.getObject1()+" = "+val1 ); + //logger.trace( "{} -- {} = {}", c1.getObject1(), c2.getObject1(), val1 ); if ( val1 == 0 ) continue; } if ( onto2.getEntityURI( c1.getObject2() ).equals( onto2.getEntityURI(c2.getObject2()) ) ){ val2 = 0; } else { val2 = Math.abs( relativePosition( c1.getObject2(), c2.getObject2(), onto2 ) ); - //System.err.println( c1.getObject2()+" -- "+c2.getObject2()+" = "+val2 ); + //logger.trace( "{} -- {} = {}", c1.getObject2(), c2.getObject2(), val2 ); if ( val2 == 0 ) continue; } double val = Math.pow( symALPHA, val1 + val2 ); if ( withConfidence ) val *= 1. - Math.abs( c1.getStrength() - c2.getStrength() ); - //System.err.println( " => "+symALPHA+"^"+val1+"+"+val2+" * "+(1. - Math.abs( c1.getStrength() - c2.getStrength() ))+" = "+val ); + // Does not write 5 {} + //logger.trace( " => {}^{}+{}*{} = {}", symALPHA, val1, val2, (1. - Math.abs( c1.getStrength() - c2.getStrength() )), val ); if ( relsensitive && !c1.getRelation().equals( c2.getRelation() ) ) { if ( ( c1.getRelation().getRelation().equals("=") && ( c2.getRelation().getRelation().equals("<") || c2.getRelation().getRelation().equals(">") )) diff --git a/src/fr/inrialpes/exmo/align/impl/eval/GraphEvaluator.java b/src/fr/inrialpes/exmo/align/impl/eval/GraphEvaluator.java index e96157ca..821cc294 100644 --- a/src/fr/inrialpes/exmo/align/impl/eval/GraphEvaluator.java +++ b/src/fr/inrialpes/exmo/align/impl/eval/GraphEvaluator.java @@ -1,7 +1,7 @@ /* * $Id$ * - * Copyright (C) INRIA, 2004-2005, 2007-2010 + * Copyright (C) INRIA, 2004-2005, 2007-2010, 2013 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -38,6 +38,9 @@ import java.util.Comparator; import java.io.PrintWriter; import java.net.URI; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + /** * GraphEvaluator: an abstraction that is used for providing evaluation curves * instead of values (or sets of values) @@ -57,6 +60,7 @@ import java.net.URI; */ public abstract class GraphEvaluator { + final static Logger logger = LoggerFactory.getLogger( GraphEvaluator.class ); /** * The resolution of the provided result: by STEP steps @@ -181,7 +185,7 @@ public abstract class GraphEvaluator { } } } catch ( AlignmentException aex ) { - aex.printStackTrace(); + logger.debug( "IGNORED Exception", aex ); } return false; } diff --git a/src/fr/inrialpes/exmo/align/impl/eval/PRGraphEvaluator.java b/src/fr/inrialpes/exmo/align/impl/eval/PRGraphEvaluator.java index 5fb62cbc..1b321b8e 100644 --- a/src/fr/inrialpes/exmo/align/impl/eval/PRGraphEvaluator.java +++ b/src/fr/inrialpes/exmo/align/impl/eval/PRGraphEvaluator.java @@ -1,7 +1,7 @@ /* * $Id$ * - * Copyright (C) INRIA, 2004-2005, 2007-2010 + * Copyright (C) INRIA, 2004-2005, 2007-2010, 2013 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -39,6 +39,9 @@ import java.util.Vector; import java.io.PrintWriter; import java.net.URI; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + /** * Compute the precision recall graph on 11 points * @@ -65,6 +68,7 @@ import java.net.URI; */ public class PRGraphEvaluator extends GraphEvaluator { + final static Logger logger = LoggerFactory.getLogger( PRGraphEvaluator.class ); private int STEP = 10; @@ -105,7 +109,7 @@ public class PRGraphEvaluator extends GraphEvaluator { int nbcorrect = 0; int nbfound = 0; int increment = (STEP*nbexpected)/100; // 2010 should be computed with the total expected (in negrapheval) - //System.err.println(" INCREMENT SET "+increment ); + //logger.trace(" INCREMENT SET {}", increment ); int next = 0; points.add( new Pair( 0., 1. ) ); // [R=0%] next += increment; @@ -148,7 +152,7 @@ public class PRGraphEvaluator extends GraphEvaluator { int nbfound = 0; int increment = (STEP*nbexpected)/100; // 2010 should be computed with the total expected (in negrapheval) Vector<Pair> inflexion = new Vector<Pair>(); - //System.err.println(" INCREMENT SET "+increment ); + //logger.trace(" INCREMENT SET {}", increment ); int next = 0; // Collect the points that change recall // (the other provide lower precision from the same recall and are not considered) @@ -181,7 +185,7 @@ public class PRGraphEvaluator extends GraphEvaluator { // It works backward in the vector, // (in the same spirit as before, the maximum value so far -best- is retained) int j = inflexion.size()-1; // index in recall-ordered vector of points - //System.err.println( "Inflexion: "+j); + //logger.trace( "Inflexion: {}", j); int i = STEP; // index of the current recall interval double level = (double)i/STEP; // max level of that interval double best = 0.; // best value found for that interval @@ -199,7 +203,7 @@ public class PRGraphEvaluator extends GraphEvaluator { for( i = 0; i <= STEP; i++ ) { // JE: better with j/10 - //System.err.println( " prec at "+j+" : "+precisions[j] ); + //logger.trace( " prec at {} : {}", j, precisions[j] ); points.add( new Pair( ((double)i)/10, precisions[i] ) ); } diff --git a/src/fr/inrialpes/exmo/align/impl/eval/PRecEvaluator.java b/src/fr/inrialpes/exmo/align/impl/eval/PRecEvaluator.java index c5faa40d..0817f36b 100644 --- a/src/fr/inrialpes/exmo/align/impl/eval/PRecEvaluator.java +++ b/src/fr/inrialpes/exmo/align/impl/eval/PRecEvaluator.java @@ -38,6 +38,8 @@ import java.util.Set; import java.io.PrintWriter; import java.net.URI; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Evaluate proximity between two alignments. @@ -51,6 +53,7 @@ import java.net.URI; */ public class PRecEvaluator extends BasicEvaluator implements Evaluator { + final static Logger logger = LoggerFactory.getLogger( PRecEvaluator.class ); protected double precision = 1.; @@ -148,7 +151,7 @@ public class PRecEvaluator extends BasicEvaluator implements Evaluator { } else { result = 0.; } String timeExt = align2.getExtension( Namespace.ALIGNMENT.uri, Annotations.TIME ); if ( timeExt != null ) time = Long.parseLong(timeExt); - //System.err.println(">>>> " + nbcorrect + " : " + nbfound + " : " + nbexpected); + //logger.trace(">>>> {}�: {} : {}", nbcorrect, nbfound, nbexpected); return (result); } @@ -162,7 +165,9 @@ public class PRecEvaluator extends BasicEvaluator implements Evaluator { try { result += " <dt>input1</dt><dd rel=\""+Namespace.ATLMAP.shortCut+":input1\" href=\""+align1.getOntology1URI()+"\">"+align1.getOntology1URI()+"</dd>"; result += " <dt>input2</dt><dd rel=\""+Namespace.ATLMAP.shortCut+":input2\" href=\""+align1.getOntology2URI()+"\">"+align1.getOntology2URI()+"</dd>"; - } catch (AlignmentException e) { e.printStackTrace(); }; + } catch (AlignmentException e) { + logger.debug( "IGNORED Exception", e ); + }; // Other missing items (easy to get) // result += " <"+Namespace.ATLMAP.shortCut+":falseNegative>"); // result += " <"+Namespace.ATLMAP.shortCut+":falsePositive>"); diff --git a/src/fr/inrialpes/exmo/align/impl/eval/SemPRecEvaluator.java b/src/fr/inrialpes/exmo/align/impl/eval/SemPRecEvaluator.java index 58f9281a..7faad399 100644 --- a/src/fr/inrialpes/exmo/align/impl/eval/SemPRecEvaluator.java +++ b/src/fr/inrialpes/exmo/align/impl/eval/SemPRecEvaluator.java @@ -264,8 +264,9 @@ public class SemPRecEvaluator extends PRecEvaluator implements Evaluator { manager.addIRIMapper(new SimpleIRIMapper( IRI.create( align.getOntology2URI() ), IRI.create( align.getFile2() ) ) ); try { - manager.loadOntologyFromOntologyDocument( IRI.create( align.getFile1() ) ); - manager.loadOntologyFromOntologyDocument( IRI.create( align.getFile2() ) ); + // JE: The two next lines should be useless + //manager.loadOntologyFromOntologyDocument( IRI.create( align.getFile1() ) ); + //manager.loadOntologyFromOntologyDocument( IRI.create( align.getFile2() ) ); // Load the ontology stream OWLOntology ontology = manager.loadOntologyFromOntologyDocument( in ); reasoner = new Reasoner( ontology ); @@ -310,8 +311,9 @@ public class SemPRecEvaluator extends PRecEvaluator implements Evaluator { manager.addIRIMapper(new SimpleIRIMapper( IRI.create( align.getOntology2URI() ), IRI.create( align.getFile2() ) ) ); try { - manager.loadOntologyFromOntologyDocument( IRI.create( align.getFile1() ) ); - manager.loadOntologyFromOntologyDocument( IRI.create( align.getFile2() ) ); + // JE: The two next lines should be useless + //manager.loadOntologyFromOntologyDocument( IRI.create( align.getFile1() ) ); + //manager.loadOntologyFromOntologyDocument( IRI.create( align.getFile2() ) ); OWLOntology ontology = manager.loadOntologyFromOntologyDocument( merged ); reasoner = new Reasoner( ontology ); } catch ( OWLOntologyCreationException ooce ) { diff --git a/src/fr/inrialpes/exmo/align/impl/eval/ThresholdGraphEvaluator.java b/src/fr/inrialpes/exmo/align/impl/eval/ThresholdGraphEvaluator.java index 76e260f8..6b7c332a 100644 --- a/src/fr/inrialpes/exmo/align/impl/eval/ThresholdGraphEvaluator.java +++ b/src/fr/inrialpes/exmo/align/impl/eval/ThresholdGraphEvaluator.java @@ -1,7 +1,7 @@ /* * $Id$ * - * Copyright (C) INRIA, 2004-2005, 2007-2010 + * Copyright (C) INRIA, 2004-2005, 2007-2010, 2013 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -39,6 +39,9 @@ import java.util.Vector; import java.io.PrintWriter; import java.net.URI; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + /** * Compute the F-measure/precision/recall at various thresholds * @@ -48,6 +51,7 @@ import java.net.URI; */ public class ThresholdGraphEvaluator extends GraphEvaluator { + final static Logger logger = LoggerFactory.getLogger( ThresholdGraphEvaluator.class ); private int STEP = 50; @@ -106,7 +110,7 @@ public class ThresholdGraphEvaluator extends GraphEvaluator { // This is the version with increment // Determine what the increment is double increment = 1./(double)STEP; - //System.err.println(" INCREMENT SET "+increment ); + //logger.trace(" INCREMENT SET {}", increment ); double next = 1.; next -= increment; for ( EvalCell c : cellSet ) { diff --git a/src/fr/inrialpes/exmo/align/impl/eval/WeightedPREvaluator.java b/src/fr/inrialpes/exmo/align/impl/eval/WeightedPREvaluator.java index 6d22c9e0..e91fbed1 100644 --- a/src/fr/inrialpes/exmo/align/impl/eval/WeightedPREvaluator.java +++ b/src/fr/inrialpes/exmo/align/impl/eval/WeightedPREvaluator.java @@ -38,11 +38,13 @@ import java.util.Set; import java.io.PrintWriter; import java.net.URI; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Evaluate proximity between two alignments. - * This function implements Precision/Recall. The first alignment - * is thus the expected one. + * This function implements weighted Precision/Recall. + * The first alignment is thus the expected one. * * Basic relation sensitivity has been implemented * @@ -51,10 +53,11 @@ import java.net.URI; */ public class WeightedPREvaluator extends BasicEvaluator implements Evaluator { + final static Logger logger = LoggerFactory.getLogger( WeightedPREvaluator.class ); protected double precision = 1.; - protected double recall = 1.; + protected double recall = 0.; protected double overall = 0.; @@ -85,7 +88,7 @@ public class WeightedPREvaluator extends BasicEvaluator implements Evaluator { public void init(){ precision = 1.; - recall = 1.; + recall = 0.; overall = 0.; fmeasure = 0.; time = 0; @@ -117,39 +120,51 @@ public class WeightedPREvaluator extends BasicEvaluator implements Evaluator { for ( Cell c1 : align1 ) { URI uri1 = c1.getObject2AsURI(); - nbexpected += c1.getStrength(); + // measure 1 + nbexpected += 1.; + // measure 2 + //nbexpected += c1.getStrength(); Set<Cell> s2 = align2.getAlignCells1( c1.getObject1() ); - double diff = -1.0; + double diff = -2.0; if( s2 != null ){ for( Cell c2 : s2 ) { URI uri2 = c2.getObject2AsURI(); if ( uri1.equals( uri2 ) && ( !relsensitive || c1.getRelation().equals( c2.getRelation() ) ) ) { diff = c1.getStrength() - c2.getStrength(); - nbcorrect1 += ((diff>0.)?diff:-diff); //1. - + // measure 1 + nbcorrect1 += ((diff>0.)?diff:-diff); + // measure 2 + //nbcorrect1 += Math.min( c1.getStrength(), ((diff>0.)?diff:-diff) ); break; } } } - if ( diff == -1.0 ) nbcorrect1 += c1.getStrength(); // the c1 not found + if ( diff == -2.0 ) nbcorrect1 += c1.getStrength(); // the c1 not found } for ( Cell c2 : align2 ) { URI uri2 = c2.getObject2AsURI(); - nbfound += c2.getStrength(); + // measure 1 + nbfound += 1.; + // measure 2 + //nbfound += c2.getStrength(); Set<Cell> s1 = align1.getAlignCells1( c2.getObject1() ); - double diff = -1.0; + double diff = -2.0; if( s1 != null ){ for( Cell c1 : s1 ) { URI uri1 = c1.getObject2AsURI(); if ( uri2.equals( uri1 ) && ( !relsensitive || c1.getRelation().equals( c2.getRelation() ) ) ) { diff = c1.getStrength() - c2.getStrength(); - nbcorrect2 += ((diff>0.)?diff:-diff); //1. - + // measure 1 + nbcorrect2 += ((diff>0.)?diff:-diff); + // measure 2 + //nbcorrect2 += Math.min( c2.getStrength(), ((diff>0.)?diff:-diff) ); break; } } } - if ( diff == -1.0 ) nbcorrect2 += c2.getStrength(); // the c2 not found + if ( diff == -2.0 ) nbcorrect2 += c2.getStrength(); // the c2 not found } // What is the definition if: @@ -159,6 +174,7 @@ public class WeightedPREvaluator extends BasicEvaluator implements Evaluator { // precision is 0 [= nbcorrect is 0] if ( nbfound != 0. ) precision = 1. - (nbcorrect2 / nbfound); if ( nbexpected != 0. ) recall = 1. - (nbcorrect1 / nbexpected); + else { recall = 1.; precision = 0.; } return computeDerived(); } public double eval( Properties params, Object cache ) throws AlignmentException { @@ -173,7 +189,7 @@ public class WeightedPREvaluator extends BasicEvaluator implements Evaluator { } else { result = 0.; } String timeExt = align2.getExtension( Namespace.ALIGNMENT.uri, Annotations.TIME ); if ( timeExt != null ) time = Long.parseLong(timeExt); - //System.err.println(">>>> " + nbcorrect + " : " + nbfound + " : " + nbexpected); + //logger.trace(">>>> {} : {} : {}", nbcorrect, nbfound, nbexpected); return (result); } @@ -187,7 +203,8 @@ public class WeightedPREvaluator extends BasicEvaluator implements Evaluator { try { result += " <dt>input1</dt><dd rel=\""+Namespace.ATLMAP.shortCut+":input1\" href=\""+align1.getOntology1URI()+"\">"+align1.getOntology1URI()+"</dd>"; result += " <dt>input2</dt><dd rel=\""+Namespace.ATLMAP.shortCut+":input2\" href=\""+align1.getOntology2URI()+"\">"+align1.getOntology2URI()+"</dd>"; - } catch (AlignmentException e) { e.printStackTrace(); }; + } catch (AlignmentException e) { + logger.debug( "IGNORED exception", e ); }; // Other missing items (easy to get) // result += " <"+Namespace.ATLMAP.shortCut+":falseNegative>"); // result += " <"+Namespace.ATLMAP.shortCut+":falsePositive>"); @@ -256,8 +273,8 @@ return result; public double getFound() { return nbfound; } // JE 2013: does not fit in WGroupEval anymore public double getCorrect() { return nbcorrect1; } - public double getCorrect1() { return nbcorrect1; } - public double getCorrect2() { return nbcorrect2; } + public double getCorrectExpected() { return nbcorrect1; } + public double getCorrectFound() { return nbcorrect2; } public long getTime() { return time; } } diff --git a/src/fr/inrialpes/exmo/align/impl/method/ClassStructAlignment.java b/src/fr/inrialpes/exmo/align/impl/method/ClassStructAlignment.java index 294d042d..9c91fb02 100644 --- a/src/fr/inrialpes/exmo/align/impl/method/ClassStructAlignment.java +++ b/src/fr/inrialpes/exmo/align/impl/method/ClassStructAlignment.java @@ -1,7 +1,7 @@ /* * $id: ClassStructAlignment.java 1189 2010-01-03 17:57:13Z euzenat $ * - * Copyright (C) INRIA, 2003-2004, 2007-2010 + * Copyright (C) INRIA, 2003-2004, 2007-2010, 2013 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -24,6 +24,9 @@ import java.util.Vector; import java.util.Set; import java.util.Properties; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import org.semanticweb.owl.align.Alignment; import org.semanticweb.owl.align.AlignmentProcess; import org.semanticweb.owl.align.Cell; @@ -54,11 +57,12 @@ import fr.inrialpes.exmo.ontosim.string.StringDistances; * - pia3 [ignored=0]: weigth for property domain * - pia4 [ignored=0]: weigth for property range * - * @author J�r�me Euzenat + * @author J�r�me Euzenat * @version $Id$ */ public class ClassStructAlignment extends DistanceAlignment implements AlignmentProcess { + final static Logger logger = LoggerFactory.getLogger( ClassStructAlignment.class ); private HeavyLoadedOntology<Object> honto1 = null; private HeavyLoadedOntology<Object> honto2 = null; @@ -109,7 +113,7 @@ public class ClassStructAlignment extends DistanceAlignment implements Alignment } classmatrix = new double[nbclass1+1][nbclass2+1]; - if (debug > 0) System.err.println("Initializing class distances"); + logger.debug("Initializing class distances"); // Initialize class distances // JE: Here AlignmentException is raised if cl or classlist2.get(j) @@ -126,7 +130,7 @@ public class ClassStructAlignment extends DistanceAlignment implements Alignment throw new AlignmentException( "Cannot find entity URI", owex ); } - if (debug > 0) System.err.print("Computing class distances\n"); + logger.debug("Computing class distances"); // Compute classes distances // -- for all of its attribute, find the best match if possible... easy // -- simply replace in the matrix the value by the value plus the diff --git a/src/fr/inrialpes/exmo/align/impl/method/NameAndPropertyAlignment.java b/src/fr/inrialpes/exmo/align/impl/method/NameAndPropertyAlignment.java index d5092eab..c7abb0bc 100644 --- a/src/fr/inrialpes/exmo/align/impl/method/NameAndPropertyAlignment.java +++ b/src/fr/inrialpes/exmo/align/impl/method/NameAndPropertyAlignment.java @@ -1,7 +1,7 @@ /* * $id: NameAndPropertyAlignment.java 1189 2010-01-03 17:57:13Z euzenat $ * - * Copyright (C) INRIA, 2003-2004, 2007-2010 + * Copyright (C) INRIA, 2003-2004, 2007-2010, 2013 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -26,6 +26,9 @@ import java.util.Vector; import java.util.Set; import java.util.Properties; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import org.semanticweb.owl.align.Alignment; import org.semanticweb.owl.align.AlignmentProcess; import org.semanticweb.owl.align.AlignmentException; @@ -50,11 +53,12 @@ import fr.inrialpes.exmo.ontosim.string.StringDistances; * - pia3 [ignored=0]: weigth for property domain * - pia4 [ignored=0]: weigth for property range * - * @author J�r�me Euzenat / Jerome Pierson + * @author J�r�me Euzenat / J�r�me Pierson * @version $Id$ */ public class NameAndPropertyAlignment extends DistanceAlignment implements AlignmentProcess { + final static Logger logger = LoggerFactory.getLogger( NameAndPropertyAlignment.class ); private HeavyLoadedOntology<Object> honto1 = null; private HeavyLoadedOntology<Object> honto2 = null; @@ -97,9 +101,6 @@ public class NameAndPropertyAlignment extends DistanceAlignment implements Align double pia1 = 1.; // relation weight for name double epsillon = 0.05; // stoping condition - if ( params.getProperty("debug") != null ) - debug = Integer.parseInt( params.getProperty("debug") ); - try { // Create property lists and matrix for ( Object prop : honto1.getObjectProperties() ){ @@ -131,7 +132,7 @@ public class NameAndPropertyAlignment extends DistanceAlignment implements Align } classmatrix = new double[nbclass1+1][nbclass2+1]; - if (debug > 0) System.err.println("Initializing property distances"); + logger.debug("Initializing property distances"); for ( i=0; i<nbprop1; i++ ){ Object cl1 = proplist1.get(i); String st1 = honto1.getEntityName( cl1 ); @@ -149,7 +150,7 @@ public class NameAndPropertyAlignment extends DistanceAlignment implements Align } // Initialize class distances - if (debug > 0) System.err.println("Initializing class distances"); + logger.debug("Initializing class distances"); for ( i=0; i<nbclass1; i++ ){ Object cl1 = classlist1.get(i); for ( j=0; j<nbclass2; j++ ){ @@ -168,7 +169,7 @@ public class NameAndPropertyAlignment extends DistanceAlignment implements Align // Here create the best matches for property distance already // -- FirstExp: goes directly in the alignment structure // since it will never be refined anymore... - if (debug > 0) System.err.print("Storing property alignment\n"); + logger.debug("Storing property alignment"); for ( i=0; i<nbprop1; i++ ){ boolean found = false; int best = 0; @@ -182,7 +183,7 @@ public class NameAndPropertyAlignment extends DistanceAlignment implements Align } if ( found && max < 0.5) { addAlignCell( proplist1.get(i), proplist2.get(best), "=", 1.-max ); } } - if (debug > 0) System.err.print("Computing class distances\n"); + logger.debug("Computing class distances"); // Compute classes distances // -- for all of its attribute, find the best match if possible... easy // -- simply replace in the matrix the value by the value plus the @@ -230,7 +231,7 @@ public class NameAndPropertyAlignment extends DistanceAlignment implements Align // 1:1: get the best discard lines and columns and iterate // Here we basically implement ?:* because the algorithm // picks up the best matching object above threshold for i. - if (debug > 0) System.err.print("Storing class alignment\n"); + logger.debug("Storing class alignment"); for ( i=0; i<nbclass1; i++ ){ boolean found = false; diff --git a/src/fr/inrialpes/exmo/align/impl/method/StringDistAlignment.java b/src/fr/inrialpes/exmo/align/impl/method/StringDistAlignment.java index 39dc7813..78b76d4a 100644 --- a/src/fr/inrialpes/exmo/align/impl/method/StringDistAlignment.java +++ b/src/fr/inrialpes/exmo/align/impl/method/StringDistAlignment.java @@ -1,7 +1,7 @@ /* * $Id$ * - * Copyright (C) INRIA, 2003-2011 + * Copyright (C) INRIA, 2003-2011, 2013 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -24,6 +24,9 @@ import java.net.URI; import java.util.Properties; import java.lang.reflect.Method; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import org.semanticweb.owl.align.Alignment; import org.semanticweb.owl.align.AlignmentProcess; import org.semanticweb.owl.align.AlignmentException; @@ -45,6 +48,7 @@ import fr.inrialpes.exmo.align.impl.MatrixMeasure; */ public class StringDistAlignment extends DistanceAlignment implements AlignmentProcess { + final static Logger logger = LoggerFactory.getLogger( StringDistAlignment.class ); Method dissimilarity = null; String methodName = "equalDistance"; @@ -59,14 +63,13 @@ public class StringDistAlignment extends DistanceAlignment implements AlignmentP try { s1 = ontology1().getEntityName( o1 ); s2 = ontology2().getEntityName( o2 ); - } catch ( Exception owex ) { // dealt with below - if ( debug > 1 ) owex.printStackTrace(); + } catch ( Exception owex ) { + logger.debug( "IGNORED (returned 1. instead)", owex ); }; // Unnamed entity = max distance if ( s1 == null || s2 == null ) return 1.; Object[] params = { s1.toLowerCase(), s2.toLowerCase() }; - if ( debug > 4 ) - System.err.println( "OB:"+s1+" ++ "+s2+" ==> "+dissimilarity.invoke( null, params )); + //logger.trace( "OB:{} ++ {} ==> {}", s1, s2, dissimilarity.invoke( null, params ) ); return ((Double)dissimilarity.invoke( null, params )).doubleValue(); } public double classMeasure( Object cl1, Object cl2 ) throws Exception { @@ -103,7 +106,7 @@ public class StringDistAlignment extends DistanceAlignment implements AlignmentP Class[] mParams = { sClass, sClass }; dissimilarity = Class.forName("fr.inrialpes.exmo.ontosim.string.StringDistances").getMethod( methodName, mParams ); } catch (ClassNotFoundException e) { - e.printStackTrace(); // never happens + logger.debug( "IGNORED (never happens)", e ); // never happens } catch (NoSuchMethodException e) { throw new AlignmentException( "Unknown method for StringDistAlignment : "+params.getProperty("stringFunction"), e ); } diff --git a/src/fr/inrialpes/exmo/align/impl/method/StrucSubsDistAlignment.java b/src/fr/inrialpes/exmo/align/impl/method/StrucSubsDistAlignment.java index 05844d77..7c529114 100644 --- a/src/fr/inrialpes/exmo/align/impl/method/StrucSubsDistAlignment.java +++ b/src/fr/inrialpes/exmo/align/impl/method/StrucSubsDistAlignment.java @@ -1,7 +1,7 @@ /* * $Id$ * - * Copyright (C) INRIA, 2003-2004, 2007-2010 + * Copyright (C) INRIA, 2003-2004, 2007-2010, 2013 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -18,7 +18,6 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - package fr.inrialpes.exmo.align.impl.method; import java.util.Vector; @@ -26,6 +25,9 @@ import java.util.Set; import java.util.Properties; import java.lang.Integer; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import org.semanticweb.owl.align.Alignment; import org.semanticweb.owl.align.AlignmentProcess; import org.semanticweb.owl.align.Cell; @@ -51,11 +53,12 @@ import fr.inrialpes.exmo.ontosim.string.StringDistances; * - pia3 [ignored=0]: weigth for property domain * - pia4 [ignored=0]: weigth for property range * - * @author J�r�me Euzenat + * @author J�r�me Euzenat * @version $Id$ */ public class StrucSubsDistAlignment extends DistanceAlignment implements AlignmentProcess { + final static Logger logger = LoggerFactory.getLogger( StrucSubsDistAlignment.class ); private HeavyLoadedOntology<Object> honto1 = null; private HeavyLoadedOntology<Object> honto2 = null; @@ -99,9 +102,6 @@ public class StrucSubsDistAlignment extends DistanceAlignment implements Alignme double pia1 = 1.; // relation weight for name double epsillon = 0.05; // stoping condition - if ( params.getProperty("debug") != null ) - debug = Integer.parseInt( params.getProperty("debug") ); - try { // Create property lists and matrix for ( Object prop : honto1.getObjectProperties() ){ @@ -133,7 +133,7 @@ public class StrucSubsDistAlignment extends DistanceAlignment implements Alignme } classmatrix = new double[nbclass1+1][nbclass2+1]; - if (debug > 0) System.err.println("Initializing property distances"); + logger.debug("Initializing property distances"); for ( i=0; i<nbprop1; i++ ){ Object cl1 = proplist1.get(i); @@ -152,7 +152,7 @@ public class StrucSubsDistAlignment extends DistanceAlignment implements Alignme } // Initialize class distances - if (debug > 0) System.err.println("Initializing class distances"); + logger.debug("Initializing class distances"); for ( i=0; i<nbclass1; i++ ){ Object cl1 = classlist1.get(i); for ( j=0; j<nbclass2; j++ ){ @@ -171,7 +171,7 @@ public class StrucSubsDistAlignment extends DistanceAlignment implements Alignme // Here create the best matches for property distance already // -- FirstExp: goes directly in the alignment structure // since it will never be refined anymore... - if (debug > 0) System.err.print("Storing property alignment\n"); + logger.debug("Storing property alignment"); for ( i=0; i<nbprop1; i++ ){ boolean found = false; int best = 0; @@ -186,7 +186,7 @@ public class StrucSubsDistAlignment extends DistanceAlignment implements Alignme if ( found ) { addAlignCell( proplist1.get(i), proplist2.get(best), "=", 1.-max ); } } - if (debug > 0) System.err.print("Computing class distances\n"); + logger.debug("Computing class distances"); // Compute classes distances // -- for all of its attribute, find the best match if possible... easy // -- simply replace in the matrix the value by the value plus the @@ -242,7 +242,7 @@ public class StrucSubsDistAlignment extends DistanceAlignment implements Alignme // 1:1: get the best discard lines and columns and iterate // Here we basically implement ?:* because the algorithm // picks up the best matching object above threshold for i. - if (debug > 0) System.err.print("Storing class alignment\n"); + logger.debug("Storing class alignment"); for ( i=0; i<nbclass1; i++ ){ boolean found = false; diff --git a/src/fr/inrialpes/exmo/align/impl/renderer/COWLMappingRendererVisitor.java b/src/fr/inrialpes/exmo/align/impl/renderer/COWLMappingRendererVisitor.java index 8604a6d0..57551611 100644 --- a/src/fr/inrialpes/exmo/align/impl/renderer/COWLMappingRendererVisitor.java +++ b/src/fr/inrialpes/exmo/align/impl/renderer/COWLMappingRendererVisitor.java @@ -93,7 +93,7 @@ public class COWLMappingRendererVisitor extends GenericReflectiveVisitor impleme writer.print(" <cowl:targetOntology>\n"); writer.print(" <owl:Ontology rdf:about=\""+onto2.getURI()+"\"/>\n"); writer.print(" </cowl:targetOntology>\n"); - for( Cell c : align ){ + for( Cell c : alignment ){ c.accept( this ); } //end for writer.print(" </cowl:Mapping>\n"); diff --git a/src/fr/inrialpes/exmo/align/impl/renderer/GenericReflectiveVisitor.java b/src/fr/inrialpes/exmo/align/impl/renderer/GenericReflectiveVisitor.java index ea9bd4fd..7c773f15 100644 --- a/src/fr/inrialpes/exmo/align/impl/renderer/GenericReflectiveVisitor.java +++ b/src/fr/inrialpes/exmo/align/impl/renderer/GenericReflectiveVisitor.java @@ -1,7 +1,7 @@ /* * $Id$ * - * Copyright (C) INRIA, 2012 + * Copyright (C) INRIA, 2012-2013 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -23,6 +23,9 @@ package fr.inrialpes.exmo.align.impl.renderer; import java.lang.reflect.Method; import java.lang.reflect.InvocationTargetException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import org.semanticweb.owl.align.AlignmentException; /** @@ -34,6 +37,7 @@ import org.semanticweb.owl.align.AlignmentException; * and Relation may be extended. */ public class GenericReflectiveVisitor { + final static Logger logger = LoggerFactory.getLogger( GenericReflectiveVisitor.class ); /** * Finds the visit(X) method corresponding to the object class (subclass of a root class) @@ -54,7 +58,7 @@ public class GenericReflectiveVisitor { } } if ( m == null ) {//newc == Object.class ) { - // System.out.println( "Searching for interfaces" ); + // logger.trace( "Searching for interfaces" ); Class[] interfaces = c.getInterfaces(); for ( int i=0; i < interfaces.length; i++ ) { if ( interfaces[i] != root ) { @@ -83,12 +87,12 @@ public class GenericReflectiveVisitor { method.invoke( visitor, new Object[] {o} ); return true; } catch ( IllegalAccessException iaex ) { - iaex.printStackTrace(); + logger.debug( "IGNORED Exception", iaex ); } catch ( InvocationTargetException itex ) { if ( itex.getCause() instanceof AlignmentException ) { throw (AlignmentException)itex.getCause(); } else { - itex.printStackTrace(); + logger.debug( "IGNORED Exception", itex ); } } } diff --git a/src/fr/inrialpes/exmo/align/impl/renderer/GraphPatternRendererVisitor.java b/src/fr/inrialpes/exmo/align/impl/renderer/GraphPatternRendererVisitor.java index 2d0f4ec7..bd40289c 100644 --- a/src/fr/inrialpes/exmo/align/impl/renderer/GraphPatternRendererVisitor.java +++ b/src/fr/inrialpes/exmo/align/impl/renderer/GraphPatternRendererVisitor.java @@ -32,6 +32,9 @@ import java.util.Iterator; import java.util.List; import java.util.Set; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import org.semanticweb.owl.align.Alignment; import org.semanticweb.owl.align.AlignmentException; import org.semanticweb.owl.align.Cell; @@ -71,6 +74,7 @@ import fr.inrialpes.exmo.align.parser.SyntaxElement.Constructor; // JE: create a string... problem with increment. public abstract class GraphPatternRendererVisitor extends IndentedRendererVisitor implements EDOALVisitor { + final static Logger logger = LoggerFactory.getLogger( GraphPatternRendererVisitor.class ); Alignment alignment = null; Cell cell = null; @@ -163,7 +167,7 @@ public abstract class GraphPatternRendererVisitor extends IndentedRendererVisito if ( out != null ) // there was at least one file out.close(); } catch(IOException ioe) { - System.err.println( ioe ); + logger.debug( "IGNORED Exception", ioe ); } } diff --git a/src/fr/inrialpes/exmo/align/impl/renderer/OWLAxiomsRendererVisitor.java b/src/fr/inrialpes/exmo/align/impl/renderer/OWLAxiomsRendererVisitor.java index e6ab0b18..4506a4d6 100644 --- a/src/fr/inrialpes/exmo/align/impl/renderer/OWLAxiomsRendererVisitor.java +++ b/src/fr/inrialpes/exmo/align/impl/renderer/OWLAxiomsRendererVisitor.java @@ -25,6 +25,9 @@ import java.util.Properties; import java.io.PrintWriter; import java.net.URI; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import org.semanticweb.owl.align.Alignment; import org.semanticweb.owl.align.AlignmentVisitor; import org.semanticweb.owl.align.AlignmentException; @@ -87,6 +90,7 @@ import fr.inrialpes.exmo.align.impl.edoal.EDOALVisitor; */ public class OWLAxiomsRendererVisitor extends IndentedRendererVisitor implements AlignmentVisitor, EDOALVisitor { + final static Logger logger = LoggerFactory.getLogger( OWLAxiomsRendererVisitor.class ); boolean heterogeneous = false; boolean edoal = false; Alignment alignment = null; @@ -108,6 +112,7 @@ public class OWLAxiomsRendererVisitor extends IndentedRendererVisitor implements public void visit( Alignment align ) throws AlignmentException { if ( subsumedInvocableMethod( this, align, Alignment.class ) ) return; // default behaviour + //logger.trace( "Alignment: {}", align ); if ( align instanceof ObjectAlignment ) { alignment = align; onto1 = (LoadedOntology)((ObjectAlignment)alignment).getOntologyObject1(); @@ -139,10 +144,10 @@ public class OWLAxiomsRendererVisitor extends IndentedRendererVisitor implements writer.print(" </owl:Ontology>"+NL+NL); try { - for( Cell c : align ){ + for( Cell c : alignment ){ Object ob1 = c.getObject1(); Object ob2 = c.getObject2(); - + //logger.trace( "Rendering {} -- {}", ob1, ob2 ); if ( heterogeneous || edoal || ( onto1.isClass( ob1 ) && onto2.isClass( ob2 ) ) || ( onto1.isDataProperty( ob1 ) && onto2.isDataProperty( ob2 ) ) || @@ -154,6 +159,9 @@ public class OWLAxiomsRendererVisitor extends IndentedRendererVisitor implements } catch ( OntowrapException owex ) { throw new AlignmentException( "Error accessing ontology", owex ); } + //logger.trace( "Heterogeneous: {}", heterogeneous); + //logger.trace( "EDOAL: {}", edoal); + //logger.trace( "onto1: {}", onto1); writer.print("</rdf:RDF>"+NL); } diff --git a/src/fr/inrialpes/exmo/align/impl/renderer/RDFRendererVisitor.java b/src/fr/inrialpes/exmo/align/impl/renderer/RDFRendererVisitor.java index c7433db0..59ff583e 100644 --- a/src/fr/inrialpes/exmo/align/impl/renderer/RDFRendererVisitor.java +++ b/src/fr/inrialpes/exmo/align/impl/renderer/RDFRendererVisitor.java @@ -1,7 +1,7 @@ /* * $Id$ * - * Copyright (C) INRIA, 2003-2010, 2012 + * Copyright (C) INRIA, 2003-2010, 2012-2013 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -28,6 +28,9 @@ import java.util.Properties; import java.io.PrintWriter; import java.net.URI; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import org.semanticweb.owl.align.Alignment; import org.semanticweb.owl.align.AlignmentVisitor; import org.semanticweb.owl.align.AlignmentException; @@ -87,6 +90,7 @@ import fr.inrialpes.exmo.align.impl.edoal.EDOALVisitor; */ public class RDFRendererVisitor extends IndentedRendererVisitor implements AlignmentVisitor,EDOALVisitor { + final static Logger logger = LoggerFactory.getLogger( RDFRendererVisitor.class ); Alignment alignment = null; Cell cell = null; @@ -111,6 +115,7 @@ public class RDFRendererVisitor extends IndentedRendererVisitor implements Align } public void visit( Alignment align ) throws AlignmentException { + //logger.trace( "Processing alignment {}", align ); if ( subsumedInvocableMethod( this, align, Alignment.class ) ) return; // default behaviour String extensionString = ""; @@ -224,6 +229,7 @@ public class RDFRendererVisitor extends IndentedRendererVisitor implements Align } public void visit( Cell cell ) throws AlignmentException { + //logger.trace( "Processing cell {}", cell ); if ( subsumedInvocableMethod( this, cell, Cell.class ) ) return; // default behaviour this.cell = cell; @@ -242,6 +248,7 @@ public class RDFRendererVisitor extends IndentedRendererVisitor implements Align if ( alignment.getLevel().startsWith("2EDOAL") ) { indentedOutputln("<"+SyntaxElement.ENTITY1.print(DEF)+">"); increaseIndent(); + //logger.trace( "Processing ob1 {}", cell.getObject1() ); ((Expression)(cell.getObject1())).accept( this ); decreaseIndent(); writer.print(NL); @@ -249,6 +256,7 @@ public class RDFRendererVisitor extends IndentedRendererVisitor implements Align indentedOutputln("<"+SyntaxElement.ENTITY2.print(DEF)+">"); increaseIndent(); ((Expression)(cell.getObject2())).accept( this ); + //logger.trace( "Processing ob2 {}", cell.getObject2() ); decreaseIndent(); writer.print(NL); indentedOutputln("</"+SyntaxElement.ENTITY2.print(DEF)+">"); @@ -644,7 +652,7 @@ public class RDFRendererVisitor extends IndentedRendererVisitor implements Align indentedOutput("</"+SyntaxElement.TRANSF.print(DEF)+">"); } - public void visit( final Datatype e ) throws AlignmentException { + public void visit( final Datatype e ) { indentedOutput("<"+SyntaxElement.EDATATYPE.print(DEF)+">"); writer.print("<"+SyntaxElement.DATATYPE.print(DEF)+" "+SyntaxElement.RDF_ABOUT.print(DEF)+"=\""+e.getType()+"\"/>"); writer.print("</"+SyntaxElement.EDATATYPE.print(DEF)+">"); diff --git a/src/fr/inrialpes/exmo/align/impl/renderer/SEKTMappingRendererVisitor.java b/src/fr/inrialpes/exmo/align/impl/renderer/SEKTMappingRendererVisitor.java index 2b3fe349..d24d75a9 100644 --- a/src/fr/inrialpes/exmo/align/impl/renderer/SEKTMappingRendererVisitor.java +++ b/src/fr/inrialpes/exmo/align/impl/renderer/SEKTMappingRendererVisitor.java @@ -80,7 +80,7 @@ public class SEKTMappingRendererVisitor extends GenericReflectiveVisitor impleme writer.print(" source(<\""+onto1.getURI()+"\">)\n"); writer.print(" target(<\""+onto2.getURI()+"\">)\n"); - for( Cell c : align ){ + for( Cell c : alignment ){ c.accept( this ); } //end for writer.print(")\n"); diff --git a/src/fr/inrialpes/exmo/align/impl/renderer/SPARQLConstructRendererVisitor.java b/src/fr/inrialpes/exmo/align/impl/renderer/SPARQLConstructRendererVisitor.java index dbf00e2b..3f810dfa 100644 --- a/src/fr/inrialpes/exmo/align/impl/renderer/SPARQLConstructRendererVisitor.java +++ b/src/fr/inrialpes/exmo/align/impl/renderer/SPARQLConstructRendererVisitor.java @@ -99,7 +99,7 @@ public class SPARQLConstructRendererVisitor extends GraphPatternRendererVisitor content_Corese += "<!ENTITY rul \"http://ns.inria.fr/edelweiss/2011/rule#\">" + NL; content_Corese += "]>" + NL; content_Corese += "<rdf:RDF xmlns:rdfs=\"&rdfs;\" xmlns:rdf=\"&rdf;\" xmlns = \'&rul;\' >" + NL + NL + NL; - for( Cell c : align ){ c.accept( this ); }; + for( Cell c : alignment ){ c.accept( this ); }; content_Corese += "</rdf:RDF>" + NL; if ( corese ) { if( split ) { diff --git a/src/fr/inrialpes/exmo/align/impl/renderer/SPARQLSelectRendererVisitor.java b/src/fr/inrialpes/exmo/align/impl/renderer/SPARQLSelectRendererVisitor.java index 916f5688..058936d9 100644 --- a/src/fr/inrialpes/exmo/align/impl/renderer/SPARQLSelectRendererVisitor.java +++ b/src/fr/inrialpes/exmo/align/impl/renderer/SPARQLSelectRendererVisitor.java @@ -80,7 +80,7 @@ public class SPARQLSelectRendererVisitor extends GraphPatternRendererVisitor imp throw new AlignmentException("SPARQLSELECTRenderer: cannot render simple alignment. Need an EDOALAlignment", alex ); } } - for( Cell c : align ){ c.accept( this ); }; + for( Cell c : alignment ){ c.accept( this ); }; } public void visit( Cell cell ) throws AlignmentException { diff --git a/src/fr/inrialpes/exmo/align/impl/renderer/SWRLRendererVisitor.java b/src/fr/inrialpes/exmo/align/impl/renderer/SWRLRendererVisitor.java index babf4464..b4c2d42c 100644 --- a/src/fr/inrialpes/exmo/align/impl/renderer/SWRLRendererVisitor.java +++ b/src/fr/inrialpes/exmo/align/impl/renderer/SWRLRendererVisitor.java @@ -25,6 +25,9 @@ import java.util.Properties; import java.io.PrintWriter; import java.net.URI; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import org.semanticweb.owl.align.Alignment; import org.semanticweb.owl.align.AlignmentVisitor; import org.semanticweb.owl.align.AlignmentException; @@ -47,6 +50,7 @@ import fr.inrialpes.exmo.ontowrap.OntowrapException; */ public class SWRLRendererVisitor extends GenericReflectiveVisitor implements AlignmentVisitor { + final static Logger logger = LoggerFactory.getLogger( SWRLRendererVisitor.class ); PrintWriter writer = null; Alignment alignment = null; LoadedOntology onto1 = null; @@ -90,7 +94,7 @@ public class SWRLRendererVisitor extends GenericReflectiveVisitor implements Ali } writer.print("\n"); writer.println(" <owlx:Imports rdf:resource=\""+onto1.getURI()+"\"/>\n"); - for( Cell c : align ){ + for( Cell c : alignment ){ c.accept( this ); } writer.println("</swrlx:Ontology>"); @@ -104,13 +108,23 @@ public class SWRLRendererVisitor extends GenericReflectiveVisitor implements Ali } public void visit( EquivRelation rel ) throws AlignmentException { - // JE: We should send warnings when dataproperties are mapped to individual properties and vice versa... Object ob1 = cell.getObject1(); Object ob2 = cell.getObject2(); - URI uri1; - URI uri2; + generateImplication( ob1, ob2 ); + generateImplication( ob2, ob1 ); + } + + public void visit( SubsumeRelation rel ) throws AlignmentException { + generateImplication( cell.getObject2(), cell.getObject1() ); + }; + public void visit( SubsumedRelation rel ) throws AlignmentException { + generateImplication( cell.getObject1(), cell.getObject2() ); + }; + + public void generateImplication( Object ob1, Object ob2 ) throws AlignmentException { + // JE: We should send warnings when dataproperties are mapped to individual properties and vice versa... try { - uri1 = onto1.getEntityURI( ob1 ); + URI uri1 = onto1.getEntityURI( ob1 ); writer.println(" <ruleml:imp>"); writer.println(" <ruleml:_body>"); if ( onto1.isClass( ob1 ) ){ @@ -131,7 +145,7 @@ public class SWRLRendererVisitor extends GenericReflectiveVisitor implements Ali } writer.println(" </ruleml:_body>"); writer.println(" <ruleml:_head>"); - uri2 = onto2.getEntityURI( ob2 ); + URI uri2 = onto2.getEntityURI( ob2 ); if ( onto2.isClass( ob2 ) ){ writer.println(" <swrlx:classAtom>"); writer.println(" <owllx:Class owllx:name=\""+uri2+"\"/>"); @@ -155,9 +169,66 @@ public class SWRLRendererVisitor extends GenericReflectiveVisitor implements Ali } } - public void visit( SubsumeRelation rel ){}; - public void visit( SubsumedRelation rel ){}; - public void visit( IncompatRelation rel ){}; + public void visit( IncompatRelation rel ) throws AlignmentException { + // JE: We should send warnings when dataproperties are mapped to individual properties and vice versa... + Object ob1 = cell.getObject1(); + Object ob2 = cell.getObject2(); + try { + URI uri1 = onto1.getEntityURI( ob1 ); + URI uri2 = onto2.getEntityURI( ob2 ); + writer.println(" <ruleml:imp>"); + if ( onto1.isClass( ob1 ) && onto2.isClass( ob2 ) ){ + writer.println(" <ruleml:_body>"); + writer.println(" <swrl:classAtom>"); + writer.println(" <owllx:Class owllx:name=\""+uri1+"\"/>"); + writer.println(" <ruleml:var>x</ruleml:var>"); + writer.println(" </swrl:classAtom>"); + writer.println(" <swrlx:classAtom>"); + writer.println(" <owllx:Class owllx:name=\""+uri2+"\"/>"); + writer.println(" <ruleml:var>x</ruleml:var>"); + writer.println(" </swrl:classAtom>"); + writer.println(" </ruleml:_body>"); + writer.println(" <ruleml:_head>"); + writer.println(" <swrlx:classAtom>"); + writer.println(" <owllx:Class owllx:name=\"owl:Nothing\"/>"); + writer.println(" <ruleml:var>x</ruleml:var>"); + writer.println(" </swrl:classAtom>"); + writer.println(" </ruleml:_head>"); + } else if ( onto1.isDataProperty( ob1 ) && onto2.isDataProperty( ob2 ) ) { + writer.println(" <ruleml:_body>"); + writer.println(" <swrl:datavaluedPropertyAtom swrlx:property=\""+uri1+"\"/>"); + writer.println(" <ruleml:var>x</ruleml:var>"); + writer.println(" <ruleml:var>y</ruleml:var>"); + writer.println(" <swrl:datavaluedPropertyAtom>"); + writer.println(" <swrl:datavaluedPropertyAtom swrlx:property=\""+uri2+"\"/>"); + writer.println(" <ruleml:var>x</ruleml:var>"); + writer.println(" <ruleml:var>y</ruleml:var>"); + writer.println(" </swrl:datavaluedPropertyAtom>"); + writer.println(" </ruleml:_body>"); + writer.println(" <ruleml:_head>"); + writer.println(" </ruleml:_head>"); + } else if ( onto1.isObjectProperty( ob1 ) && onto2.isObjectProperty( ob2 ) ) { + writer.println(" <ruleml:_body>"); + writer.println(" <swrl:individualPropertyAtom swrlx:property=\""+uri1+"\"/>"); + writer.println(" <ruleml:var>x</ruleml:var>"); + writer.println(" <ruleml:var>y</ruleml:var>"); + writer.println(" </swrl:individualPropertyAtom>"); + writer.println(" <swrl:individualPropertyAtom swrlx:property=\""+uri2+"\"/>"); + writer.println(" <ruleml:var>x</ruleml:var>"); + writer.println(" <ruleml:var>y</ruleml:var>"); + writer.println(" </swrl:individualPropertyAtom>"); + writer.println(" </ruleml:_body>"); + writer.println(" <ruleml:_head>"); + writer.println(" </ruleml:_head>"); + } else { + logger.warn( "Cannot generate heterogeneous rules" ); + } + writer.println(" </ruleml:imp>\n"); + } catch ( OntowrapException owex ) { + throw new AlignmentException( "Error accessing ontology", owex ); + } + } + public void visit( Relation rel ) throws AlignmentException { if ( subsumedInvocableMethod( this, rel, Relation.class ) ) return; // default behaviour diff --git a/src/fr/inrialpes/exmo/align/impl/renderer/XSLTRendererVisitor.java b/src/fr/inrialpes/exmo/align/impl/renderer/XSLTRendererVisitor.java index ab197073..c13dc989 100644 --- a/src/fr/inrialpes/exmo/align/impl/renderer/XSLTRendererVisitor.java +++ b/src/fr/inrialpes/exmo/align/impl/renderer/XSLTRendererVisitor.java @@ -1,7 +1,7 @@ /* * $Id$ * - * Copyright (C) INRIA, 2003-2004, 2006-2010, 2012 + * Copyright (C) INRIA, 2003-2004, 2006-2010, 2012-2013 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -78,7 +78,7 @@ public class XSLTRendererVisitor extends GenericReflectiveVisitor implements Ali onto1 = (LoadedOntology)((ObjectAlignment)align).getOntologyObject1(); onto2 = (LoadedOntology)((ObjectAlignment)align).getOntologyObject2(); } - for( Cell c : align ){ + for( Cell c : alignment ){ collectURIs( c ); } alignment = align; @@ -98,7 +98,7 @@ public class XSLTRendererVisitor extends GenericReflectiveVisitor implements Ali } writer.print("\n"); - for ( Enumeration e = align.getElements() ; e.hasMoreElements(); ){ + for ( Enumeration e = alignment.getElements() ; e.hasMoreElements(); ){ Cell c = (Cell)e.nextElement(); c.accept( this ); } @@ -136,8 +136,8 @@ public class XSLTRendererVisitor extends GenericReflectiveVisitor implements Ali throw new AlignmentException( "Cannot find entity URI", owex ); } } else { - entity1URI = cell.getObject1AsURI(alignment); - entity2URI = cell.getObject2AsURI(alignment); + entity1URI = cell.getObject1AsURI( alignment ); + entity2URI = cell.getObject2AsURI( alignment ); } if ( entity1URI != null ) { String ns1 = entity1URI.getScheme()+":"+entity1URI.getSchemeSpecificPart()+"#"; @@ -163,8 +163,8 @@ public class XSLTRendererVisitor extends GenericReflectiveVisitor implements Ali throw new AlignmentException( "Cannot find entity URI", owex ); } } else { - writer.println(" <xsl:template match=\""+namespacify(cell.getObject1AsURI(alignment))+"\">"); - writer.println(" <xsl:element name=\""+namespacify(cell.getObject2AsURI(alignment))+"\">"); + writer.println(" <xsl:template match=\""+namespacify(cell.getObject1AsURI( alignment ))+"\">"); + writer.println(" <xsl:element name=\""+namespacify(cell.getObject2AsURI( alignment ))+"\">"); } writer.println(" <xsl:apply-templates select=\"*|@*|text()\"/>"); writer.println(" </xsl:element>"); diff --git a/src/fr/inrialpes/exmo/align/ling/JWNLAlignment.java b/src/fr/inrialpes/exmo/align/ling/JWNLAlignment.java index 45511c63..29f07beb 100644 --- a/src/fr/inrialpes/exmo/align/ling/JWNLAlignment.java +++ b/src/fr/inrialpes/exmo/align/ling/JWNLAlignment.java @@ -1,7 +1,7 @@ /* * $Id$ * - * Copyright (C) INRIA, 2003-2005, 2007, 2009-2010 + * Copyright (C) INRIA, 2003-2005, 2007, 2009-2010, 2013 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -32,12 +32,17 @@ import org.semanticweb.owl.align.AlignmentException; import java.util.Properties; import java.net.URI; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + /** * This Class uses JWNLDistances to align two ontologies. * @version $Id$ */ public class JWNLAlignment extends DistanceAlignment implements AlignmentProcess { + final static Logger logger = LoggerFactory.getLogger( JWNLAlignment.class ); + final static String WNVERS = "3.0"; final static int BASICSYNDIST = 0; @@ -93,7 +98,7 @@ public class JWNLAlignment extends DistanceAlignment implements AlignmentProcess return measure( pr1, pr2 ); } public double individualMeasure( Object id1, Object id2 ) throws Exception { - if ( debug > 4 ) System.err.println( "ID:"+id1+" -- "+id2); + //logger.trace( "ID: {} -- {}", id1, id2 ); return measure( id1, id2 ); } } diff --git a/src/fr/inrialpes/exmo/align/parser/AlignmentParser.java b/src/fr/inrialpes/exmo/align/parser/AlignmentParser.java index c84d9d15..ce0a5cc4 100644 --- a/src/fr/inrialpes/exmo/align/parser/AlignmentParser.java +++ b/src/fr/inrialpes/exmo/align/parser/AlignmentParser.java @@ -1,7 +1,7 @@ /* * $Id$ * - * Copyright (C) INRIA, 2003-2005, 2007-2010, 2012 + * Copyright (C) INRIA, 2003-2005, 2007-2010, 2012-2013 * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License @@ -33,6 +33,9 @@ import java.lang.Integer; import java.lang.Double; import java.util.Hashtable; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import org.semanticweb.owl.align.Alignment; import org.semanticweb.owl.align.Cell; import org.semanticweb.owl.align.AlignmentException; @@ -47,7 +50,7 @@ import fr.inrialpes.exmo.align.impl.Annotations; /** * This class allows the creation of a parser for an Alignment file. * The class is called by: - * AlignmentParser parser = new AlignmentParser( debugLevel ); + * AlignmentParser parser = new AlignmentParser(); * Alignment alignment = parser.parse( input ); * input can be a URI as a String, an InputStream * This new version (January 2004) parses the alignment description in @@ -56,12 +59,8 @@ import fr.inrialpes.exmo.align.impl.Annotations; */ public class AlignmentParser { + final static Logger logger = LoggerFactory.getLogger( AlignmentParser.class ); - /** - * level of debug/warning information - */ - protected int debugMode = 0; - /** * a URI to a process */ @@ -97,11 +96,11 @@ public class AlignmentParser { /** * Creates a Parser. - * @param debugMode The value of the debug mode + * @param debugMode The value of the debug mode DEPRECATED */ - public AlignmentParser( int debugMode ) { - this.debugMode = debugMode; - } + public AlignmentParser( int debugMode ) {} + + public AlignmentParser() {} public void setEmbedded( boolean b ){ embedded = b; @@ -129,21 +128,19 @@ public class AlignmentParser { */ private Alignment callParser( Object o ) throws AlignmentException { try { - XMLParser parser = new XMLParser( debugMode ); + XMLParser parser = new XMLParser(); if ( embedded ) parser.setEmbedded( embedded ); //alignment = parser.parse( o ); alignment = callParser( parser, o ); } catch ( Exception e ) { - if ( debugMode > 0 ) { - System.err.println("XMLParser failed to parse alignment (INFO)"); - e.printStackTrace(); - } + logger.debug( "XMLParser failed to parse alignment (INFO)", e ); + logger.debug( "Using RDFParser instead" ); try { if ( !embedded ) { - RDFParser rparser = new RDFParser( debugMode ); + RDFParser rparser = new RDFParser(); alignment = callParser( rparser, o ); } else { - throw new AlignmentException( "Cannot parse "+o+" (use debug>0 for more info)", e ); + throw new AlignmentException( "Cannot parse "+o+" (use logging for more info)", e ); } } catch ( Exception ex ) { // JE: should contain both ex and e diff --git a/src/fr/inrialpes/exmo/align/parser/RDFParser.java b/src/fr/inrialpes/exmo/align/parser/RDFParser.java index 8ab22b29..c88cfe04 100644 --- a/src/fr/inrialpes/exmo/align/parser/RDFParser.java +++ b/src/fr/inrialpes/exmo/align/parser/RDFParser.java @@ -3,7 +3,7 @@ * * Copyright (C) 2006 Digital Enterprise Research Insitute (DERI) Innsbruck * Sourceforge version 1.7 - 2008 - * Copyright (C) INRIA, 2008-2010, 2012 + * Copyright (C) INRIA, 2008-2010, 2012-2013 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -84,8 +84,8 @@ import java.util.HashSet; import java.util.List; import java.util.LinkedList; -import java.util.logging.Logger; -import java.util.logging.Level; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; // Yes we are relying on Jena for parsing RDF import com.hp.hpl.jena.rdf.model.Model; @@ -116,13 +116,10 @@ import com.hp.hpl.jena.vocabulary.RDF; * @version $Revision: 1.7 $ */ public class RDFParser { - - private static Logger logger = Logger.getLogger(RDFParser.class.toString()); + final static Logger logger = LoggerFactory.getLogger( RDFParser.class ); private static Model rDFModel; - private int debug = 0; - private boolean isPattern = false; // I contain variables private boolean speedparse = false; // skip all checks @@ -131,17 +128,13 @@ public class RDFParser { /** * Creates an RDF Parser. */ - public RDFParser() { - this(0); - } + public RDFParser() {} /** * Creates an RDF Parser. - * @param debugMode The value of the debug mode + * @param debugMode The value of the debug mode (DEPRECATED) */ - public RDFParser( int debugMode ) { - debug = debugMode; - } + public RDFParser( int debugMode ) {} /** * Initialisation of the structures @@ -172,7 +165,7 @@ public class RDFParser { // Initialize the syntax description initSyntax(); // Shut up logging handling - com.hp.hpl.jena.rdf.model.impl.RDFDefaultErrorHandler.silent = true; + //com.hp.hpl.jena.rdf.model.impl.RDFDefaultErrorHandler.silent = true; // Get the statement including alignment resource as rdf:type StmtIterator stmtIt = rdfmodel.listStatements(null, RDF.type,(Resource)SyntaxElement.getResource("Alignment")); // Take the first one if it exists @@ -283,11 +276,10 @@ public class RDFParser { stmtIt = node.listProperties((Property)SyntaxElement.MAP.resource ); while (stmtIt.hasNext()) { Statement stmt = stmtIt.nextStatement(); - if ( debug > 0 ) System.err.println( " ---------------> "+stmt ); + //logger.trace( " ---------------> {}", stmt ); try { alignment.addAlignCell( parseCell( stmt.getResource() ) ); } catch ( AlignmentException ae ) { - System.err.println( "Error "+ae ); - ae.printStackTrace(); + logger.debug( "IGNORED Exception", ae ); } } @@ -394,10 +386,8 @@ public class RDFParser { Expression s = parseExpression( entity1 ); Expression t = parseExpression( entity2 ); - if ( debug > 0 ) { - System.err.println(" s : "+s); - System.err.println(" t : "+t); - } + //logger.trace(" s : {}", s); + //logger.trace(" t : {}", t); EDOALCell cell = new EDOALCell( id, s, t, type, m ); // Parse the possible transformations @@ -406,13 +396,11 @@ public class RDFParser { Statement stmt = stmtIt.nextStatement(); try { cell.addTransformation( parseTransformation( stmt.getResource() ) ); } catch ( AlignmentException ae ) { - System.err.println( "Error "+ae ); - ae.printStackTrace(); + logger.debug( "INGORED Exception", ae ); } } return cell; } catch (Exception e) { //wrap other type exception - logger.log(java.util.logging.Level.SEVERE, "The cell isn't correct: " + node.getLocalName() + " "+e.getMessage()); throw new AlignmentException("Cannot parse correspondence " + node.getLocalName(), e); } } @@ -429,13 +417,10 @@ public class RDFParser { Resource entity2 = node.getProperty((Property)SyntaxElement.TRENT2.resource).getResource(); ValueExpression s = parseValue( entity1 ); ValueExpression t = parseValue( entity2 ); - if ( debug > 0 ) { - System.err.println(" (Transf)s : "+s); - System.err.println(" (Transf)t : "+t); - } + //logger.trace(" (Transf)s : {}", s); + //logger.trace(" (Transf)t : {}", t); return new Transformation( type, s, t ); } catch (Exception e) { //wrap other type exception - logger.log(java.util.logging.Level.SEVERE, "The cell isn't correct:" + node.getLocalName() + " "+e.getMessage()); throw new AlignmentException("Cannot parse transformation " + node, e); } } @@ -476,10 +461,8 @@ public class RDFParser { } protected ClassExpression parseClass( final Resource node ) throws AlignmentException { - if ( debug > 1 ) { - StmtIterator it = node.listProperties(); - while ( it.hasNext() ) System.err.println( " > "+it.next() ); - } + //StmtIterator it = node.listProperties(); + //while ( it.hasNext() ) logger.trace( " > {}", it.next() ); Resource rdfType = node.getProperty(RDF.type).getResource(); if ( rdfType.equals( SyntaxElement.CLASS_EXPR.resource ) ) { URI id = getNodeId( node ); @@ -696,7 +679,7 @@ public class RDFParser { protected Datatype parseDatatype ( final RDFNode nn ) throws AlignmentException { String uri = null; if ( nn.isLiteral() ) { // Legacy - System.err.println( "Warning: datatypes must be Datatype objects ("+((Literal)nn).getString()+")" ); + logger.warn( "Datatypes must be Datatype objects ({})", ((Literal)nn).getString() ); uri = ((Literal)nn).getString(); } else if ( nn.isResource() ) { if ( !((Resource)nn).getProperty(RDF.type).getResource().equals( SyntaxElement.DATATYPE.resource ) ) @@ -824,7 +807,7 @@ public class RDFParser { u = new URI( ((Resource)node).getProperty( (Property)SyntaxElement.ETYPE.resource ).getLiteral().getString() ); } catch (URISyntaxException urisex) { //throw new AlignmentException( "Incorect URI for edoal:type : "+ ((Resource)node).getProperty( (Property)SyntaxElement.TYPE.resource ).getLiteral().getString() ); - urisex.printStackTrace(); + logger.debug( "IGNORED Exception", urisex ); } } if ( u != null ) { diff --git a/src/fr/inrialpes/exmo/align/parser/TypeCheckingVisitor.java b/src/fr/inrialpes/exmo/align/parser/TypeCheckingVisitor.java index 7b485fbd..3a416e58 100644 --- a/src/fr/inrialpes/exmo/align/parser/TypeCheckingVisitor.java +++ b/src/fr/inrialpes/exmo/align/parser/TypeCheckingVisitor.java @@ -1,7 +1,7 @@ /* * $Id$ * - * Copyright (C) INRIA, 2010-2012 + * Copyright (C) INRIA, 2010-2013 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -24,6 +24,9 @@ import java.util.Hashtable; import java.util.Properties; import java.net.URI; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import org.semanticweb.owl.align.Alignment; import org.semanticweb.owl.align.AlignmentVisitor; import org.semanticweb.owl.align.Cell; @@ -73,6 +76,7 @@ import fr.inrialpes.exmo.align.impl.edoal.Comparator; */ public class TypeCheckingVisitor { + final static Logger logger = LoggerFactory.getLogger( TypeCheckingVisitor.class ); public enum TYPE { CLASS, PROPERTY, RELATION, INSTANCE, VALUE, DATATYPE, ANY, ERROR }; @@ -352,7 +356,7 @@ public class TypeCheckingVisitor { public TYPE raiseError( final URI u, TYPE expT, TYPE foundT ) { error = true; - if ( print ) System.err.println( "Incorrectly typed expression "+u+": Type "+foundT+" ("+expT+" expected)"); + if ( print ) logger.error( "Incorrectly typed expression {}: Type {} ({} expected)", u, foundT, expT ); return TYPE.ERROR; } diff --git a/src/fr/inrialpes/exmo/align/parser/XMLParser.java b/src/fr/inrialpes/exmo/align/parser/XMLParser.java index 2c26e142..9d48978d 100644 --- a/src/fr/inrialpes/exmo/align/parser/XMLParser.java +++ b/src/fr/inrialpes/exmo/align/parser/XMLParser.java @@ -1,7 +1,7 @@ /* * $Id$ * - * Copyright (C) INRIA, 2003-2005, 2007-2012 + * Copyright (C) INRIA, 2003-2005, 2007-2013 * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License @@ -43,6 +43,9 @@ import java.lang.Integer; import java.lang.Double; import java.util.Hashtable; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import org.semanticweb.owl.align.Alignment; import org.semanticweb.owl.align.Cell; import org.semanticweb.owl.align.AlignmentException; @@ -60,7 +63,7 @@ import fr.inrialpes.exmo.align.impl.Extensions; /** * This class allows the creation of a parser for an Alignment file. * The class is called by: - * AlignmentParser parser = new AlignmentParser( debugLevel ); + * AlignmentParser parser = new AlignmentParser(); * Alignment alignment = parser.parse( input ); * input can be a URI as a String, an InputStream * This new version (January 2004) parses the alignment description in @@ -69,12 +72,8 @@ import fr.inrialpes.exmo.align.impl.Extensions; */ public class XMLParser extends DefaultHandler { + final static Logger logger = LoggerFactory.getLogger( XMLParser.class ); - /** - * level of debug/warning information - */ - protected int debugMode = 0; - /** * a URI to a process */ @@ -171,22 +170,22 @@ public class XMLParser extends DefaultHandler { * Creates an XML Parser. */ public XMLParser() throws ParserConfigurationException, SAXException { - this(0); + this(false); } /** * Creates an XML Parser. - * @param debugMode The value of the debug mode + * @param validate 0 if non validating, more otherwise + * This should become a boolean */ - public XMLParser( int debugMode ) throws ParserConfigurationException, SAXException { - this.debugMode = debugMode; + public XMLParser( int validate ) throws ParserConfigurationException, SAXException { + this( (validate > 0) ); + } + + public XMLParser( boolean validate ) throws ParserConfigurationException, SAXException { SAXParserFactory parserFactory = SAXParserFactory.newInstance(); - if (debugMode > 0) { - parserFactory.setValidating(true); - } else { - parserFactory.setValidating(false); - } - parserFactory.setNamespaceAware(true); + parserFactory.setValidating( validate ); + parserFactory.setNamespaceAware( true ); parser = parserFactory.newSAXParser(); } @@ -264,7 +263,7 @@ public class XMLParser extends DefaultHandler { * @param atts The attributes name of the current element */ public void startElement(String namespaceURI, String pName, String qname, Attributes atts) throws SAXException { - if(debugMode > 2) System.err.println("startElement XMLParser : " + pName); + logger.debug( "startElement XMLParser : {}", pName ); parseLevel++; if( namespaceURI.equals( Namespace.ALIGNMENT.uri+"#" ) || namespaceURI.equals( Namespace.ALIGNMENT.uri ) ) { @@ -272,16 +271,14 @@ public class XMLParser extends DefaultHandler { } else if (pName.equals( SyntaxElement.SEMANTICS.name )) { } else if (pName.equals( SyntaxElement.MEASURE.name )) { } else if (pName.equals( SyntaxElement.ENTITY2.name )) { - if(debugMode > 2) - System.err.println(" resource = " + atts.getValue(SyntaxElement.RDF_RESOURCE.print())); + //logger.trace( " resource = {}", atts.getValue(SyntaxElement.RDF_RESOURCE.print()) ); try { cl2 = new URI( atts.getValue(SyntaxElement.RDF_RESOURCE.print()) ); } catch (URISyntaxException e) { throw new SAXException("Malformed URI: "+atts.getValue(SyntaxElement.RDF_RESOURCE.print())); } } else if (pName.equals( SyntaxElement.ENTITY1.name )) { - if(debugMode > 2) - System.err.println(" resource = " + atts.getValue(SyntaxElement.RDF_RESOURCE.print())); + //logger.trace(" resource = {}", atts.getValue(SyntaxElement.RDF_RESOURCE.print())); try { cl1 = new URI( atts.getValue( SyntaxElement.RDF_RESOURCE.print() ) ); } catch (URISyntaxException e) { @@ -347,7 +344,7 @@ public class XMLParser extends DefaultHandler { alignment.setExtension( Namespace.ALIGNMENT.uri, Annotations.ID, about ); }; } else { - if ( debugMode > 0 ) System.err.println("[XMLParser] Unknown element name : "+pName); + logger.warn( "Unknown element name : {}", pName ); }; } else if ( namespaceURI.equals( Namespace.SOAP_ENV.prefix )) { //"http://schemas.xmlsoap.org/soap/envelope/")) { // Ignore SOAP namespace @@ -373,8 +370,7 @@ public class XMLParser extends DefaultHandler { * Put the content in a variable public void characters(char ch[], int start, int length) { content = new String( ch, start, length ); - if(debugMode > 2) - System.err.println("content XMLParser : " + content); + //logger.trace( "content XMLParser : {}", content ); } */ @@ -393,7 +389,7 @@ public class XMLParser extends DefaultHandler { } else { content = newContent; } - if ( debugMode > 2 ) System.err.println("content XMLParser : " + content); + logger.debug( "content XMLParser : {}", content ); } /** @@ -404,8 +400,7 @@ public class XMLParser extends DefaultHandler { * @param qName The name of the current element */ public void endElement(String namespaceURI, String pName, String qName ) throws SAXException { - if(debugMode > 2) - System.err.println("endElement XMLParser : " + pName); + logger.debug( "endElement XMLParser : {}", pName ); if( namespaceURI.equals( Namespace.ALIGNMENT.uri+"#" ) || namespaceURI.equals( Namespace.ALIGNMENT.uri ) ) { try { @@ -418,17 +413,15 @@ public class XMLParser extends DefaultHandler { } else if (pName.equals( SyntaxElement.ENTITY2.name )) { } else if (pName.equals( SyntaxElement.ENTITY1.name )) { } else if (pName.equals( SyntaxElement.CELL.name )) { - if(debugMode > 1) { - System.err.print(" " + cl1); - System.err.print(" " + cl2); - System.err.print(" " + relation); - System.err.println(" " + Double.parseDouble(measure)); - } + //logger.trace( " {}", cl1 ); + //logger.trace( " {}", cl2 ); + //logger.trace( " {}", relation); + //logger.trace( " {}", Double.parseDouble(measure)); if ( cl1 == null || cl2 == null ) { // Maybe we could just print this out and fail in the end. //throw new SAXException( "Missing entity "+cl1+" "+cl2 ); // The cell is void - System.err.println("Warning (cell voided), missing entity "+cl1+" "+cl2 ); + logger.warn( "(cell voided), missing entity {} {}", cl1, cl2 ); } else if ( measure == null || relation == null ){ cell = alignment.addAlignCell( cl1, cl2); } else { @@ -497,8 +490,8 @@ public class XMLParser extends DefaultHandler { alignment.setExtension( namespaceURI, pName, content ); } else if ( parseLevel == 5 ) { extensions.setExtension( namespaceURI, pName, content ); - } else //if ( debugMode > 0 ) - System.err.println("[XMLParser("+parseLevel+")] Unknown element name : "+pName); + } else + logger.warn( "("+parseLevel+") Unknown element name : {}", pName ); //throw new SAXException("[XMLParser] Unknown element name : "+pName); }; } catch ( AlignmentException e ) { throw new SAXException("[XMLParser] Exception raised", e); }; diff --git a/src/fr/inrialpes/exmo/align/service/AServProtocolManager.java b/src/fr/inrialpes/exmo/align/service/AServProtocolManager.java index ef6532ec..6bfa3735 100644 --- a/src/fr/inrialpes/exmo/align/service/AServProtocolManager.java +++ b/src/fr/inrialpes/exmo/align/service/AServProtocolManager.java @@ -248,7 +248,7 @@ public class AServProtocolManager implements Service { Alignment al = null; try { //logger.trace(" Parsing alignment"); - AlignmentParser aparser = new AlignmentParser(0); + AlignmentParser aparser = new AlignmentParser(); al = aparser.parse( name ); //logger.trace(" Alignment parsed"); } catch (Exception e) { diff --git a/src/fr/inrialpes/exmo/align/service/AlignmentService.java b/src/fr/inrialpes/exmo/align/service/AlignmentService.java index 1e74ae11..152b088e 100644 --- a/src/fr/inrialpes/exmo/align/service/AlignmentService.java +++ b/src/fr/inrialpes/exmo/align/service/AlignmentService.java @@ -1,7 +1,7 @@ /* * $Id$ * - * Copyright (C) INRIA, 2006-2009, 2010, 2013 + * Copyright (C) INRIA, 2006-2009, 2010, 2013-2014 * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License @@ -24,13 +24,15 @@ import fr.inrialpes.exmo.queryprocessor.QueryProcessor; import fr.inrialpes.exmo.queryprocessor.Result; import fr.inrialpes.exmo.queryprocessor.Type; -import fr.inrialpes.exmo.align.util.NullStream; +import fr.inrialpes.exmo.align.cli.CommonCLI; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import gnu.getopt.LongOpt; -import gnu.getopt.Getopt; +import org.apache.commons.cli.CommandLine; +import org.apache.commons.cli.Options; +import org.apache.commons.cli.OptionBuilder; +import org.apache.commons.cli.ParseException; import java.util.Hashtable; import java.util.Enumeration; @@ -62,12 +64,12 @@ $Id$ * @author J�r�me Euzenat */ -public class AlignmentService { +public class AlignmentService extends CommonCLI { final static Logger logger = LoggerFactory.getLogger( AlignmentService.class ); public String //DBMS Parameters DBHOST = "localhost", - DBPORT = "3306", + DBPORT = null, DBUSER = "adminAServ", DBPASS = "aaa345", DBBASE = "AServDB", @@ -91,22 +93,49 @@ public class AlignmentService { private AServProtocolManager manager; private DBService connection; + public AlignmentService() { + super(); + //options.addOption( OptionBuilder.withLongOpt( "load" ).hasArg().withDescription( "Load previous database image from FILE" ).withArgName("FILE").create( 'l' ) ); + options.addOption( OptionBuilder.withLongOpt( "impl" ).hasArg().withDescription( "Launch service corresponding to CLASS" ).withArgName("CLASS").create( 'i' ) ); + options.addOption( OptionBuilder.withLongOpt( "uriprefix" ).hasArg().withDescription( "Set alignment URIs with prefix URI" ).withArgName("URI").create( 'u' ) ); + options.addOption( OptionBuilder.withLongOpt( "host" ).hasArg().withDescription( "Set the HOSTNAME of the server" ).withArgName("HOSTNAME").create( 'S' ) ); + + options.addOption( OptionBuilder.withLongOpt( "http" ).hasOptionalArg().withDescription( "Launch HTTP service (with port PORT; default "+HTML+")" ).withArgName("PORT").create( 'H' ) ); + options.addOption( OptionBuilder.withLongOpt( "jade" ).hasOptionalArg().withDescription( "Launch JADE service (with port PORT; default "+JADE+")" ).withArgName("PORT").create( 'A' ) ); + options.addOption( OptionBuilder.withLongOpt( "wsdl" ).hasOptionalArg().withDescription( "Launch Web service (with port PORT; default "+WSDL+")" ).withArgName("PORT").create( 'W' ) ); + options.addOption( OptionBuilder.withLongOpt( "jxta" ).hasOptionalArg().withDescription( "Launch JXTA service (with port PORT; default "+JXTA+")" ).withArgName("PORT").create( 'X' ) ); + + options.addOption( "O", "oyster", false, "Register to Oyster directory" ); + //options.addOption( "U", "uddi", false, "Register to Oyster directory" ); + //options.addOption( OptionBuilder.withLongOpt( "params" ).hasArg().withDescription( "Read parameters from FILE" ).withArgName("FILE").create( 'p' ) ); + + options.addOption( OptionBuilder.withLongOpt( "dbms" ).hasArg().withDescription( "Use DBMS system (mysql,postgres; default: mysql)" ).withArgName("DBMS").create( 'B' ) ); + options.addOption( OptionBuilder.withLongOpt( "dbmshost" ).hasArg().withDescription( "Use DBMS HOST (default: "+DBHOST+")" ).withArgName("HOST").create( 'm' ) ); + options.addOption( OptionBuilder.withLongOpt( "dbmsport" ).hasArg().withDescription( "Use DBMS PORT (default: "+DBPORT+")" ).withArgName("PORT").create( 's' ) ); + options.addOption( OptionBuilder.withLongOpt( "dbmsuser" ).hasArg().withDescription( "Use DBMS USER (default: scott)" ).withArgName("USER").create( 'l' ) ); + options.addOption( OptionBuilder.withLongOpt( "dbmspass" ).hasArg().withDescription( "Use DBMS PASSword (default: tiger)" ).withArgName("PASS").create( 'p' ) ); + options.addOption( OptionBuilder.withLongOpt( "dbmsbase" ).hasArg().withDescription( "Use DBMS BASE (default: "+DBBASE+")" ).withArgName("BASE").create( 'b' ) ); + + } + public static void main(String[] args) { try { new AlignmentService().run( args ); } - catch ( Exception ex ) { - logger.error( "FATAL error", ex ); - }; + catch ( Exception ex ) { logger.error( "FATAL error", ex ); }; } public void run(String[] args) throws Exception { services = new Hashtable<String,AlignmentServiceProfile>(); directories = new Hashtable<String,Directory>(); + // Read parameters - Properties params = readParameters( args ); - if ( outfile != null ) { + readParameters( args ); + + // In principle, this is useless + if ( outputfilename != null ) { // This redirects error outout to log file given by -o - System.setErr( new PrintStream( outfile ) ); - } + System.setErr( new PrintStream( outputfilename ) ); + } + logger.debug("Parameter parsed"); // Shut down hook @@ -114,37 +143,49 @@ public class AlignmentService { public void run() { close(); } }); // Connect database - if( DBMS.equals("postgres") ) { + if ( DBMS.equals("postgres") ) { logger.debug("postgres driver"); - DBPORT = "5432"; - connection = new DBServiceImpl( "org.postgresql.Driver" , "jdbc:postgresql", DBPORT ); - } else { + if ( DBPORT == null ) DBPORT = "5432"; + connection = new DBServiceImpl( "org.postgresql.Driver", "jdbc:postgresql", DBPORT ); + } else if ( DBMS.equals("mysql") ) { logger.debug("mysql driver"); - DBPORT = "3306"; - connection = new DBServiceImpl( "com.mysql.jdbc.Driver" , "jdbc:mysql", DBPORT ); + if ( DBPORT == null ) DBPORT = "3306"; + connection = new DBServiceImpl( "com.mysql.jdbc.Driver", "jdbc:mysql", DBPORT ); + } else { + logger.error( "Unsupported JDBC driver: {}", DBMS ); + usage(); + System.exit(-1); } - - connection.init(); - connection.connect( DBHOST, DBPORT, DBUSER, DBPASS, DBBASE ); + try { + logger.debug("Connecting to database"); + connection.init(); + connection.connect( DBHOST, DBPORT, DBUSER, DBPASS, DBBASE ); + } catch ( Exception ex ) { + logger.error( ex.getMessage() ); + System.exit(-1); + } + logger.debug("Database connected"); // Create a AServProtocolManager manager = new AServProtocolManager( directories ); - manager.init( connection, params ); + manager.init( connection, parameters ); logger.debug("Manager created"); // Launch services for ( AlignmentServiceProfile serv : services.values() ) { try { - serv.init( params, manager ); + serv.init( parameters, manager ); } catch ( AServException ex ) { // This should rather be the job of the caller - logger.warn( "Cannot start {} server on {}:{}", serv, params.getProperty( "host" ), params.getProperty( "http" ) ); + logger.warn( "Cannot start {} server on {}:{}", serv, parameters.getProperty( "host" ), parameters.getProperty( "http" ) ); } } + logger.debug("Services launched"); + // Register to directories for ( Directory dir : directories.values() ) { try { - dir.open( params ); + dir.open( parameters ); logger.debug("{} connected.", dir); } catch ( AServException ex ) { logger.warn( "Cannot connect to {} directory", dir ); @@ -153,8 +194,10 @@ public class AlignmentService { //directories.remove( name, dir ); } } + logger.debug("Directories registered"); // Wait loop + logger.info("Alignment server running"); while ( true ) { // do not exhaust CPU Thread.sleep(1000); @@ -181,9 +224,11 @@ public class AlignmentService { } // Shut down database connection - manager.close(); + logger.debug("Stopping manager"); + if ( manager != null ) manager.close(); + logger.debug("Closing database connection"); connection.close(); - logger.debug("Database connection closed"); + logger.info("Alignment server stopped"); System.err.close(); } @@ -192,246 +237,95 @@ public class AlignmentService { finally { super.finalize(); } } - protected Object loadInstance( String className) throws ClassNotFoundException, NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException { + protected Object loadInstance( String className ) throws ClassNotFoundException, NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException { Class<?> cl = Class.forName(className); java.lang.reflect.Constructor constructor = cl.getConstructor( (Class[])null ); return constructor.newInstance( (Object[])null ); } + public void readParameters( String[] args ) { + try { + CommandLine line = parseCommandLine( args ); + if ( line == null ) System.exit(1); // -help - public Properties readParameters( String[] args ) { - Properties params = new Properties(); - // Default values - params.setProperty( "host", HOST ); - - // Read parameters + // Default values + parameters.setProperty( "host", HOST ); - LongOpt[] longopts = new LongOpt[20]; - // General parameters - longopts[0] = new LongOpt("help", LongOpt.NO_ARGUMENT, null, 'h'); - longopts[1] = new LongOpt("output", LongOpt.REQUIRED_ARGUMENT, null, 'o'); - longopts[2] = new LongOpt("debug", LongOpt.OPTIONAL_ARGUMENT, null, 'd'); - longopts[3] = new LongOpt("impl", LongOpt.REQUIRED_ARGUMENT, null, 'l'); - // Is there a way for that in LongOpt ??? - longopts[4] = new LongOpt("D", LongOpt.REQUIRED_ARGUMENT, null, 'D'); - // Service parameters - longopts[5] = new LongOpt("html", LongOpt.OPTIONAL_ARGUMENT, null, 'H'); - longopts[6] = new LongOpt("jade", LongOpt.OPTIONAL_ARGUMENT, null, 'A'); - longopts[7] = new LongOpt("wsdl", LongOpt.OPTIONAL_ARGUMENT, null, 'W'); - longopts[8] = new LongOpt("jxta", LongOpt.OPTIONAL_ARGUMENT, null, 'P'); - longopts[9] = new LongOpt("oyster", LongOpt.OPTIONAL_ARGUMENT, null, 'O'); - longopts[10] = new LongOpt("uddi", LongOpt.OPTIONAL_ARGUMENT, null, 'U'); - // DBMS Server parameters - longopts[11] = new LongOpt("dbmshost", LongOpt.REQUIRED_ARGUMENT, null, 'm'); - longopts[12] = new LongOpt("dbmsport", LongOpt.REQUIRED_ARGUMENT, null, 's'); - longopts[13] = new LongOpt("dbmsuser", LongOpt.REQUIRED_ARGUMENT, null, 'u'); - longopts[14] = new LongOpt("dbmspass", LongOpt.REQUIRED_ARGUMENT, null, 'p'); - longopts[15] = new LongOpt("dbmsbase", LongOpt.REQUIRED_ARGUMENT, null, 'b'); - longopts[16] = new LongOpt("dbms", LongOpt.REQUIRED_ARGUMENT, null, 'B'); - longopts[17] = new LongOpt("host", LongOpt.REQUIRED_ARGUMENT, null, 'S'); - longopts[18] = new LongOpt("serv", LongOpt.REQUIRED_ARGUMENT, null, 'i'); - longopts[19] = new LongOpt("uriprefix", LongOpt.REQUIRED_ARGUMENT, null, 'f'); - - Getopt g = new Getopt("", args, "ho:S:l:f:d::D:H::A::W::P::O::U::m:s:u:p:b:B:i:", longopts); - int c; - String arg; - - while ((c = g.getopt()) != -1) { - switch (c) { - case 'h' : - usage(); - System.exit(0); - break; - case 'o' : - /* Use filename instead of stdout */ - outfile = g.getOptarg(); - break; - case 'l' : - /* Use the given file as a database image to load */ - filename = g.getOptarg(); - break; - case 'd' : - /* DEPRECATED: Debug level */ - arg = g.getOptarg(); - System.err.println( "WARNING: debug argument is deprecated, use logging" ); - System.err.println( "See http://alignapi.gforge.inria.fr/logging.html" ); - break; - case 'i' : - /* external service */ - arg = g.getOptarg(); + // Here deal with command specific arguments + + /* Use the given file as a database image to load */ + //if ( line.hasOption( 'l' ) ) filename = line.getOptionValue( 'l' ); + if ( line.hasOption( 'i' ) ) { /* external service */ + String arg = line.getOptionValue( 'i' ); try { services.put( arg, (AlignmentServiceProfile)loadInstance( arg ) ); } catch (Exception ex) { logger.warn( "Cannot create service for {}", arg ); - logger.trace( "IGNORED Exception", ex ); - } - break; - case 'f' : - /* Parameter definition */ - params.setProperty( "prefix", g.getOptarg() ); - break; - case 'H' : - /* HTTP Server + port */ - arg = g.getOptarg(); - if ( arg != null ) { - params.setProperty( "http", arg ); - } else { - params.setProperty( "http", HTML ); + logger.debug( "IGNORED Exception", ex ); } + } + if ( line.hasOption( 'u' ) ) parameters.setProperty( "prefix", line.getOptionValue( 'u' ) ); + if ( line.hasOption( 'H' ) ) { + parameters.setProperty( "http", line.getOptionValue( 'H', HTML ) ); // This shows that it does not work try { services.put( "fr.inrialpes.exmo.align.service.HTMLAServProfile", (AlignmentServiceProfile)loadInstance( "fr.inrialpes.exmo.align.service.HTMLAServProfile" ) ); } catch (Exception ex) { logger.warn( "Cannot create service for HTMLAServProfile", ex ); } - break; - case 'A' : - /* JADE Server + port */ - arg = g.getOptarg(); - if ( arg != null ) { - params.setProperty( "jade", arg ); - } else { - params.setProperty( "jade", JADE ); - } + } + if ( line.hasOption( 'A' ) ) { + parameters.setProperty( "jade", line.getOptionValue( 'A', JADE ) ); try { services.put( "fr.inrialpes.exmo.align.service.jade.JadeFIPAAServProfile", (AlignmentServiceProfile)loadInstance( "fr.inrialpes.exmo.align.service.jade.JadeFIPAAServProfile" ) ); - } catch (Exception ex) { + } catch ( Exception ex ) { logger.warn("Cannot create service for JadeFIPAAServProfile", ex); } - break; - case 'W' : - /* Web service + port */ - arg = g.getOptarg(); - if ( arg != null ) { - params.setProperty( "wsdl", arg ); - } else { - params.setProperty( "wsdl", WSDL ); - }; + } + if ( line.hasOption( 'W' ) ) { + parameters.setProperty( "wsdl", line.getOptionValue( 'W', WSDL ) ); // The WSDL extension requires HTTP server (and the same one). // Put the default port, may be overriden - if ( params.getProperty( "http" ) == null ) - params.setProperty( "http", HTML ); + if ( parameters.getProperty( "http" ) == null ) + parameters.setProperty( "http", HTML ); try { services.put( "fr.inrialpes.exmo.align.service.HTMLAServProfile", (AlignmentServiceProfile)loadInstance( "fr.inrialpes.exmo.align.service.HTMLAServProfile" ) ); - } catch (Exception ex) { - logger.warn("Cannot create service for Web services", ex); - } - break; - case 'P' : - /* JXTA Server + port */ - arg = g.getOptarg(); - if ( arg != null ) { - params.setProperty( "jxta", arg ); - } else { - params.setProperty( "jxta", JXTA ); - } - break; - case 'S' : - /* Server */ - params.setProperty( "host", g.getOptarg() ); - break; - case 'O' : - /* [JE: Currently not working]: Oyster directory + port */ - arg = g.getOptarg(); - if ( arg != null ) { - params.setProperty( "oyster", arg ); - } else { - params.setProperty( "oyster", JADE ); + } catch ( Exception ex ) { + logger.warn( "Cannot create service for Web services", ex ); } + } + if ( line.hasOption( 'X' ) ) { parameters.setProperty( "jxta", line.getOptionValue( 'P', JXTA ) ); } + if ( line.hasOption( 'S' ) ) { parameters.setProperty( "host", line.getOptionValue( 'S' ) ); } + if ( line.hasOption( 'O' ) ) { try { directories.put( "fr.inrialpes.exmo.align.service.OysterDirectory", (Directory)loadInstance( "fr.inrialpes.exmo.align.service.OysterDirectory" ) ); } catch (Exception ex) { - logger.warn("Cannot create directory for Oyster", ex); + logger.warn( "Cannot create directory for Oyster", ex ); } - break; - case 'U' : - /* [JE: Currently not working]: UDDI directory + port */ - arg = g.getOptarg(); - if ( arg != null ) { - params.setProperty( "uddi", arg ); - } else { - params.setProperty( "uddi", JADE ); - } + } + /*if ( line.hasOption( 'U' ) ) { try { directories.put( "fr.inrialpes.exmo.align.service.UDDIDirectory", (Directory)loadInstance( "fr.inrialpes.exmo.align.service.UDDIDirectory" ) ); } catch (Exception ex) { logger.warn("Cannot create directory for UDDI", ex); } - break; - case 'm' : - DBHOST = g.getOptarg(); - break; - case 's' : - DBPORT = g.getOptarg(); - break; - case 'u' : - DBUSER = g.getOptarg(); - break; - case 'p' : - DBPASS = g.getOptarg(); - break; - case 'b' : - DBBASE = g.getOptarg(); - break; - case 'B' : - arg = g.getOptarg(); - if ( arg != null ) { - params.setProperty( "DBMS", arg ); - DBMS = arg; - } else { - params.setProperty( "DBMS", "mysql" ); - DBMS = "mysql"; - } - break; - case 'D' : - /* Parameter definition */ - arg = g.getOptarg(); - int index = arg.indexOf('='); - if ( index != -1 ) { - params.setProperty( arg.substring( 0, index), - arg.substring(index+1)); - } else { - logger.warn("Bad parameter syntax: "+g); - usage(); - System.exit(0); - - } - break; - } + }*/ + if ( line.hasOption( 'm' ) ) { DBHOST = line.getOptionValue( 'm' ); } + if ( line.hasOption( 's' ) ) { DBPORT = line.getOptionValue( 's' ); } + if ( line.hasOption( 'l' ) ) { DBUSER = line.getOptionValue( 'l' ); } + if ( line.hasOption( 'p' ) ) { DBPASS = line.getOptionValue( 'p' ); } + if ( line.hasOption( 'b' ) ) { DBBASE = line.getOptionValue( 'b' ); } + if ( line.hasOption( 'B' ) ) { DBMS = line.getOptionValue( 'B' ); } + parameters.setProperty( "DBMS", DBMS ); + } catch( ParseException exp ) { + logger.error( exp.getMessage() ); + usage(); + System.exit(-1); } - - return params; } - // Really missing: - // OUTPUT(o): what for, there is no output (maybe LOGS) - // LOAD(l): good idea, load from file, but what kind? sql? - // PARAMS(p is taken, P is taken): yes good as well to read parameters from file public void usage() { - System.err.println("usage: AlignmentService [options]"); - System.err.println("options are:"); - //System.err.println("\t--load=filename -l filename\t\tInitialize the Service with the content of this "); - System.err.println("\t--html[=port] -H[port]\t\t\tLaunch HTTP service"); - System.err.println("\t--jade[=port] -A[port]\t\t\tLaunch Agent service"); - System.err.println("\t--wsdl[=port] -W[port]\t\t\tLaunch Web service"); - System.err.println("\t--jxta[=port] -P[port]\t\t\tLaunch P2P service"); - System.err.println("\t--oyster -O\t\t\tRegister to Oyster directory"); - //System.err.println("\t--uddi -U\t\t\tRegister to Oyster directory"); - System.err.println("\t--serv=class -i class\t\t\tLaunch service corresponding to fully qualified classname"); - //System.err.println("\t--params=filename -p filename\tReads parameters from filename"); - System.err.println("\t--output=filename -o filename\tRedirect output to filename"); - System.err.println("\t--dbmshost=host -m host\t\t\tUse DBMS host"); - System.err.println("\t--dbmsport=port -s port\t\t\tUse DBMS port"); - System.err.println("\t--dbmsuser=name -u name\t\t\tUse DBMS user name"); - System.err.println("\t--dbmspass=pwd -p pwd\t\t\tUse DBMS password"); - System.err.println("\t--dbmsbase=name -b name\t\t\tUse Database name"); - System.err.println("\t--dbms=name -B name\t\t\tUse Database Management System"); - System.err.println("\t--uriprefix=uri -f uri\t\t\tSet alignment URIs with this prefix"); - System.err.println("\t-Dparam=value\t\t\tSet parameter"); - System.err.println("\t--help -h\t\t\tPrint this message"); - - System.err.print("\n"+AlignmentService.class.getPackage().getImplementationTitle()+" "+AlignmentService.class.getPackage().getImplementationVersion()); - System.err.println(" ($Id$)\n"); + usage( "java "+this.getClass().getName()+" [options]\nLaunch an Alignment server" ); } } diff --git a/src/fr/inrialpes/exmo/align/service/DBServiceImpl.java b/src/fr/inrialpes/exmo/align/service/DBServiceImpl.java index e411db08..08920dad 100644 --- a/src/fr/inrialpes/exmo/align/service/DBServiceImpl.java +++ b/src/fr/inrialpes/exmo/align/service/DBServiceImpl.java @@ -2,7 +2,7 @@ * $Id$ * * Copyright (C) Seungkeun Lee, 2006 - * Copyright (C) INRIA, 2007-2009, 2013 + * Copyright (C) INRIA, 2007-2009, 2013-2014 * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License @@ -81,7 +81,8 @@ public class DBServiceImpl implements DBService { public void connect(String IPAddress, String port, String user, String password, String database ) throws SQLException { dbpass = password; conn = DriverManager.getConnection(driverPrefix+"://"+IPAddress+":"+port+"/"+database, user, password); - } + } + //with "dbpass" given by "connect" public Connection reconnect() throws SQLException { conn = DriverManager.getConnection(driverPrefix+"://"+IPAddress+":"+port+"/"+database, user, dbpass); @@ -96,7 +97,7 @@ public class DBServiceImpl implements DBService { public void close() { try { - conn.close(); + if ( conn != null ) conn.close(); } catch (Exception ex) { logger.debug( "IGNORED Closing exception", ex ); } diff --git a/src/fr/inrialpes/exmo/align/service/QueryMediator.java b/src/fr/inrialpes/exmo/align/service/QueryMediator.java index c4fc23d7..8fedb1c8 100644 --- a/src/fr/inrialpes/exmo/align/service/QueryMediator.java +++ b/src/fr/inrialpes/exmo/align/service/QueryMediator.java @@ -1,7 +1,7 @@ /* * $Id$ * - * Copyright (C) INRIA, 2006-2009 + * Copyright (C) INRIA, 2006-2009, 2013 * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License @@ -76,7 +76,7 @@ public class QueryMediator implements QueryProcessor { public QueryMediator( QueryProcessor proc, String alignmentURI ) throws SAXException,ParserConfigurationException,IOException { processor = proc; - AlignmentParser aparser = new AlignmentParser(0); + AlignmentParser aparser = new AlignmentParser(); try { alignment = aparser.parse( alignmentURI ); } catch ( Exception ex ) { throw new ParserConfigurationException("Error on parsing"); diff --git a/src/fr/inrialpes/exmo/align/service/WSAlignment.java b/src/fr/inrialpes/exmo/align/service/WSAlignment.java index 7b891101..0d3c94ca 100644 --- a/src/fr/inrialpes/exmo/align/service/WSAlignment.java +++ b/src/fr/inrialpes/exmo/align/service/WSAlignment.java @@ -177,7 +177,7 @@ public class WSAlignment extends URIAlignment implements AlignmentProcess { //} - AlignmentParser parser = new AlignmentParser( 0 ); + AlignmentParser parser = new AlignmentParser(); parser.initAlignment( this ); parser.setEmbedded( true ); parser.parse( httpConn.getInputStream() ); diff --git a/src/fr/inrialpes/exmo/align/service/jade/JadeFIPAAServProfile.java b/src/fr/inrialpes/exmo/align/service/jade/JadeFIPAAServProfile.java index 9432c97a..ba25babf 100755 --- a/src/fr/inrialpes/exmo/align/service/jade/JadeFIPAAServProfile.java +++ b/src/fr/inrialpes/exmo/align/service/jade/JadeFIPAAServProfile.java @@ -2,7 +2,7 @@ * $Id$ * * Copyright (C) Orange R&D, 2006-2007 - * Copyright (C) INRIA, 2006-2007, 2009-2010 + * Copyright (C) INRIA, 2006-2007, 2009-2010, 2013 * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License @@ -24,7 +24,6 @@ package fr.inrialpes.exmo.align.service.jade; import jade.core.Profile; import jade.core.ProfileImpl; import jade.core.Runtime; -import jade.util.Logger; import jade.wrapper.AgentContainer; import jade.wrapper.AgentController; import jade.wrapper.ControllerException; @@ -36,16 +35,17 @@ import fr.inrialpes.exmo.align.service.AlignmentServiceProfile; import java.io.File; import java.util.Properties; -public class JadeFIPAAServProfile implements AlignmentServiceProfile { +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +public class JadeFIPAAServProfile implements AlignmentServiceProfile { + final static Logger logger = LoggerFactory.getLogger( JadeFIPAAServProfile.class ); private AgentContainer mc; private AgentController algagentcontroller; - private Logger myLogger = Logger.getMyLogger(getClass().getName()); public void init( Properties params, AServProtocolManager manager ) throws AServException { int port = 8888; - int debug = 0; Object args[] = new Object[2]; //set up the manager as an argument to pass to the JADEFIPAAServiceAgent @@ -56,8 +56,6 @@ public class JadeFIPAAServProfile implements AlignmentServiceProfile { if ( params.getProperty( "jade" ) != null ) port = Integer.parseInt( params.getProperty( "jade" ) ); - if ( params.getProperty( "debug" ) != null ) - debug = Integer.parseInt( params.getProperty( "debug" ) ) - 1; /** Properties props = new Properties(); @@ -76,8 +74,7 @@ public class JadeFIPAAServProfile implements AlignmentServiceProfile { // create a default Profile Profile pMain = new ProfileImpl(null, port, null); - if ( debug > 0 ) - System.out.println("Launching a whole in-process platform..."+pMain); + //logger.trace( "Launching a whole in-process platform... {}", pMain ); mc = rt.createMainContainer(pMain); algagentcontroller = mc.createNewAgent("JadeFIPAAServiceAgent", JadeFIPAAServiceAgent.class.getName(), args); algagentcontroller.start(); @@ -91,15 +88,15 @@ public class JadeFIPAAServProfile implements AlignmentServiceProfile { try{ algagentcontroller.kill(); mc.kill(); - myLogger.log(Logger.INFO, "Agent Alignement close"); + logger.info( "Agent Alignement closed" ); } catch (ControllerException e) { - myLogger.log(Logger.WARNING, "Error killing the alignment agent."); } + logger.warn( "Error killing the alignment agent." ); } try { // Destroy the files please (JE) new File("APDescription.txt").delete(); new File("MTPs-Main-Container.txt").delete(); } catch (Exception e) { - e.printStackTrace(); + logger.debug( "IGNORED Exception", e ); } } diff --git a/src/fr/inrialpes/exmo/align/service/jade/JadeFIPAAServiceAgent.java b/src/fr/inrialpes/exmo/align/service/jade/JadeFIPAAServiceAgent.java index 1fc9677c..3f67c5ae 100755 --- a/src/fr/inrialpes/exmo/align/service/jade/JadeFIPAAServiceAgent.java +++ b/src/fr/inrialpes/exmo/align/service/jade/JadeFIPAAServiceAgent.java @@ -2,7 +2,7 @@ * $Id$ * * Copyright (C) Orange R&D, 2006 - * Copyright (C) INRIA, 2006, 2008-2009, 2011-2012 + * Copyright (C) INRIA, 2006, 2008-2009, 2011-2013 * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License @@ -19,12 +19,14 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - package fr.inrialpes.exmo.align.service.jade; import java.util.Iterator; import java.util.Properties; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import jade.content.ContentElement; import jade.content.ContentManager; import jade.content.Predicate; @@ -40,7 +42,6 @@ import jade.domain.FIPAAgentManagement.DFAgentDescription; import jade.domain.FIPAAgentManagement.ServiceDescription; import jade.lang.acl.ACLMessage; import jade.lang.acl.MessageTemplate; -import jade.util.Logger; import fr.inrialpes.exmo.align.service.AServProtocolManager; import fr.inrialpes.exmo.align.service.msg.Message; @@ -58,12 +59,12 @@ import fr.inrialpes.exmo.align.service.jade.messageontology.STORE; import fr.inrialpes.exmo.align.service.jade.messageontology.TRANSLATE; public class JadeFIPAAServiceAgent extends Agent { + final static Logger logger = LoggerFactory.getLogger( JadeFIPAAServiceAgent.class ); private static final long serialVersionUID = 330; public static final String SERVICE_NAME = "Alignment"; public static final String SERVICE_TYPE = "Alignment-service"; - private Logger myLogger = Logger.getMyLogger(getClass().getName()); private String myId; private String serverId; private AServProtocolManager manager; @@ -78,24 +79,24 @@ public class JadeFIPAAServiceAgent extends Agent { protected void setup() { - //myLogger.log(Logger.INFO, getAID().getName()+" started"); - super.setup(); - codec = new SLCodec(); - - // ontology = ContextAgentManagerOntology.getInstance(); - CTmanager = this.getContentManager(); + logger.info( "{} started", getAID().getName() ); + super.setup(); + codec = new SLCodec(); - //System.out.println("agent" + getAID() + " "+ getLocalName()+" is created"); + // ontology = ContextAgentManagerOntology.getInstance(); + CTmanager = this.getContentManager(); + + // logger.trace("agent {} {} is created", getAID(), getLocalName() ); - CTmanager.registerOntology(ontology); - CTmanager.registerLanguage(codec); + CTmanager.registerOntology(ontology); + CTmanager.registerLanguage(codec); // Read arguments Object[] args = getArguments(); if (args != null) { /**for (int i = 0; i < args.length; ++i) { - myLogger.log(Logger.INFO, "Arg-"+i+" = "+args[i]); + logger.debug( "Arg-{} = {}", i, args[i] ); }**/ manager=(AServProtocolManager) args[0]; @@ -123,7 +124,7 @@ public class JadeFIPAAServiceAgent extends Agent { ACLMessage msg = myAgent.receive(tpl); if (msg != null) { // --------------------------------------------------------- - //myLogger.log(Logger.INFO, "Received message: "+msg.toString()); + //logger.debug( "Received message: {}", msg.toString() ); try{ ContentElement ce = null; @@ -141,7 +142,9 @@ public class JadeFIPAAServiceAgent extends Agent { ((Action)ce).setResult(answer.getContent()); CTmanager.fillContent(JADEanswer, ce); myAgent.send(JADEanswer); - }else{myLogger.log(Logger.WARNING, answer.getContent());} + }else{ + logger.warn( answer.getContent() ); + } }else if (ce instanceof LOAD){ Message answer = manager.load(new Message(newId(), (Message)null,myId,serverId,"",params)); if(!(answer instanceof ErrorMsg)){ @@ -153,7 +156,9 @@ public class JadeFIPAAServiceAgent extends Agent { CTmanager.fillContent(JADEanswer, ce); //JADEanswer.setContent(answer.getContent()); myAgent.send(JADEanswer); - }else{myLogger.log(Logger.WARNING, answer.getContent());} + }else{ + logger.warn( answer.getContent() ); + } }else if (ce instanceof RETRIEVE){ Message answer = manager.render(new Message(newId(), (Message)null,myId,serverId,"",params)); if(!(answer instanceof ErrorMsg)){ @@ -165,7 +170,9 @@ public class JadeFIPAAServiceAgent extends Agent { ((Action)ce).setResult(answer.getContent()); CTmanager.fillContent(JADEanswer, ce); myAgent.send(JADEanswer); - }else{myLogger.log(Logger.WARNING, answer.getContent());} + }else{ + logger.warn( answer.getContent() ); + } }else if (ce instanceof TRANSLATE){ //TODO }else if (ce instanceof METADATA){ @@ -181,7 +188,9 @@ public class JadeFIPAAServiceAgent extends Agent { ((Action)ce).setResult(answer.getContent()); CTmanager.fillContent(JADEanswer, ce); myAgent.send(JADEanswer); - }else{myLogger.log(Logger.WARNING, answer.getContent());} + }else{ + logger.warn( answer.getContent() ); + } }else if (ce instanceof FIND){ Message answer = manager.existingAlignments(new Message(newId(), (Message)null,myId,serverId,"",params)); if(!(answer instanceof ErrorMsg)){ @@ -193,7 +202,9 @@ public class JadeFIPAAServiceAgent extends Agent { ((Action)ce).setResult(answer.getContent()); CTmanager.fillContent(JADEanswer, ce); myAgent.send(JADEanswer); - }else{myLogger.log(Logger.WARNING, answer.getContent());} + }else{ + logger.warn( answer.getContent() ); + } }else if (ce instanceof CUT){ Message answer = manager.trim(new Message(newId(), (Message)null,myId,serverId,"",params)); if(!(answer instanceof ErrorMsg)){ @@ -205,7 +216,9 @@ public class JadeFIPAAServiceAgent extends Agent { ((Action)ce).setResult(answer.getContent()); CTmanager.fillContent(JADEanswer, ce); myAgent.send(JADEanswer); - }else{myLogger.log(Logger.WARNING, answer.getContent());} + }else{ + logger.warn( answer.getContent() ); + } }else { ACLMessage JADEanswer=msg.createReply(); JADEanswer.setLanguage(codec.getName()); @@ -213,10 +226,11 @@ public class JadeFIPAAServiceAgent extends Agent { JADEanswer.setPerformative(ACLMessage.NOT_UNDERSTOOD); myAgent.send(JADEanswer); } + } catch( CodecException ce ) { + logger.debug( "IGNORED Exception", ce ); + } catch( OntologyException oe ) { + logger.debug( "IGNORED Exception", oe ); } - - catch(CodecException ce){ce.printStackTrace();} - catch(OntologyException oe){oe.printStackTrace();} }else { block(); } @@ -231,9 +245,8 @@ public class JadeFIPAAServiceAgent extends Agent { }//end of Setup protected void takeDown() { - - myLogger.log(Logger.INFO, "Agent Alignement Service close"); - this.doDelete(); + logger.info( "Agent Alignement Service closed" ); + this.doDelete(); } private void registerWithDF() { @@ -244,12 +257,12 @@ public class JadeFIPAAServiceAgent extends Agent { sd.setType(SERVICE_TYPE); dfd.addServices(sd); try { - //myLogger.log(Logger.INFO, "Registering with DF..."); - DFService.register(this, dfd); - //myLogger.log(Logger.INFO, "Registration OK."); + logger.debug( "Registering with DF..." ); + DFService.register(this, dfd); + logger.debug( "Registration OK." ); } - catch (FIPAException fe) { - myLogger.log(Logger.WARNING, "Error registering with DF.", fe); + catch ( FIPAException fex ) { + logger.warn( "Error registering with DF", fex ); } } diff --git a/src/fr/inrialpes/exmo/align/service/jade/messageontology/JADEFIPAAlignmentServerOntology.java b/src/fr/inrialpes/exmo/align/service/jade/messageontology/JADEFIPAAlignmentServerOntology.java index fd307925..fcb4c905 100644 --- a/src/fr/inrialpes/exmo/align/service/jade/messageontology/JADEFIPAAlignmentServerOntology.java +++ b/src/fr/inrialpes/exmo/align/service/jade/messageontology/JADEFIPAAlignmentServerOntology.java @@ -1,5 +1,29 @@ -// file: JADEFIPAAlignmentServerOntologyOntology.java generated by ontology bean generator. DO NOT EDIT, UNLESS YOU ARE REALLY SURE WHAT YOU ARE DOING! +/* + * $Id$ + * + * Copyright (C) INRIA, 2007, 2013 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +// file: JADEFIPAAlignmentServerOntologyOntology.java generated by ontology bean generator. DO NOT EDIT, UNLESS YOU ARE REALLY SURE WHAT YOU ARE DOING! + package fr.inrialpes.exmo.align.service.jade.messageontology; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import jade.content.onto.*; import jade.content.schema.*; @@ -12,6 +36,7 @@ import jade.core.CaseInsensitiveString; * @version 2007/03/19, 17:12:29 */ public class JADEFIPAAlignmentServerOntology extends jade.content.onto.Ontology { + final static Logger logger = LoggerFactory.getLogger( JADEFIPAAlignmentServerOntology.class ); //NAME private static final long serialVersionUID = 330; public static final String ONTOLOGY_NAME = "JADEFIPAAlignmentServerOntology"; @@ -102,6 +127,7 @@ public class JADEFIPAAlignmentServerOntology extends jade.content.onto.Ontology - }catch (java.lang.Exception e) {e.printStackTrace();} + }catch (java.lang.Exception e) { + logger.debug( "IGNORED Exception", e );} } } diff --git a/src/fr/inrialpes/exmo/align/service/msg/AlignmentIds.java b/src/fr/inrialpes/exmo/align/service/msg/AlignmentIds.java index 147d0b77..cdde5684 100644 --- a/src/fr/inrialpes/exmo/align/service/msg/AlignmentIds.java +++ b/src/fr/inrialpes/exmo/align/service/msg/AlignmentIds.java @@ -22,11 +22,15 @@ package fr.inrialpes.exmo.align.service.msg; import java.util.Properties; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + /** * Contains the messages that should be sent according to the protocol */ public class AlignmentIds extends Success { + final static Logger logger = LoggerFactory.getLogger( AlignmentIds.class ); String pretty = null; @@ -45,8 +49,8 @@ public class AlignmentIds extends Success { if ( id.length >= 1 ) { result = "Alignment Ids: <ul>"; for ( int i = id.length-1; i >= 0; i-- ){ - //System.err.println("id["+i+"]"+id[i]); - //result += "<li><a href=\"../html/retrieve?method=fr.inrialpes.exmo.align.impl.renderer.HTMLRendererVisitor&id="+id[i]+"\">"; + // logger.trace("id[{}]{}", i, id[i] ); + // result += "<li><a href=\"../html/retrieve?method=fr.inrialpes.exmo.align.impl.renderer.HTMLRendererVisitor&id="+id[i]+"\">"; result += "<li><a href=\""+id[i]+"\">"; result += id[i]; String pp = null; @@ -56,7 +60,7 @@ public class AlignmentIds extends Success { if (pp != null && !pp.equals("") && !pp.equals("null")) { result += " ("+pp+")"; } - //System.err.println("pid["+i+"]="+pp); + // logger.trace( "pid[{}]={}", i, pp ); } catch(Exception ex) { } } diff --git a/src/fr/inrialpes/exmo/ontowrap/OntologyCache.java b/src/fr/inrialpes/exmo/ontowrap/OntologyCache.java index 0c4c9b4d..6770f214 100644 --- a/src/fr/inrialpes/exmo/ontowrap/OntologyCache.java +++ b/src/fr/inrialpes/exmo/ontowrap/OntologyCache.java @@ -1,7 +1,7 @@ /* * $Id$ * - * Copyright (C) INRIA, 2007-2008, 2010 + * Copyright (C) INRIA, 2007-2008, 2010, 2013 * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License @@ -21,11 +21,13 @@ package fr.inrialpes.exmo.ontowrap; -// import java classes import java.util.Hashtable; import java.util.Enumeration; import java.net.URI; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + /** * This caches the loaded ontologies so that it is possible * to share them between alignments @@ -38,7 +40,8 @@ import java.net.URI; */ public class OntologyCache <O extends LoadedOntology> { - + final static Logger logger = LoggerFactory.getLogger( OntologyCache.class ); + /** The list of currently loaded ontologies as a function: * URI --> Ontology * This is the ontology URI, NOT its filename @@ -73,15 +76,15 @@ public class OntologyCache <O extends LoadedOntology> { /* debugging utility */ public void displayCache(){ - System.err.println("CACHE: "+ontologies.size()+"/"+ontologyUris.size()+" elements cached"); + logger.trace( "CACHE: {}/{} elements cached", ontologies.size(), ontologyUris.size() ); // No way to make this iterable?? //for ( URI u : ontologies.keys() ){ for( Enumeration<URI> e = ontologies.keys(); e.hasMoreElements(); ){ - URI u = e.nextElement(); + URI u = e.nextElement(); LoadedOntology o = ontologies.get( u ); - System.err.println( " "+u ); - System.err.println( " "+o.getURI() ); - System.err.println( " --> "+o+" ("+o.getOntology()+")" ); + logger.trace( " {}", u ); + logger.trace( " {}", o.getURI() ); + logger.trace( " --> {} ({})", o, o.getOntology() ); } }; diff --git a/src/fr/inrialpes/exmo/ontowrap/OntologyFactory.java b/src/fr/inrialpes/exmo/ontowrap/OntologyFactory.java index 4c39e881..e7a60e78 100644 --- a/src/fr/inrialpes/exmo/ontowrap/OntologyFactory.java +++ b/src/fr/inrialpes/exmo/ontowrap/OntologyFactory.java @@ -168,11 +168,11 @@ public abstract class OntologyFactory { */ public LoadedOntology loadOntology( Ontology onto ) throws OntowrapException { // logger.trace( "loading Ontology: {}", onto ); - try { // Try with URI - return loadOntology( onto.getURI() ); + try { // Try with file + return loadOntology( onto.getFile() ); } catch ( Exception ex ) { - try { // Try with file - return loadOntology( onto.getFile() ); + try { // Try with URI + return loadOntology( onto.getURI() ); } catch ( Exception ex2 ) { throw new OntowrapException( "Cannot load ontology "+onto ); } diff --git a/src/fr/inrialpes/exmo/ontowrap/jena25/JENAOntology.java b/src/fr/inrialpes/exmo/ontowrap/jena25/JENAOntology.java index f7bec973..7595929c 100644 --- a/src/fr/inrialpes/exmo/ontowrap/jena25/JENAOntology.java +++ b/src/fr/inrialpes/exmo/ontowrap/jena25/JENAOntology.java @@ -55,11 +55,11 @@ import fr.inrialpes.exmo.ontowrap.util.EntityFilter; public class JENAOntology extends BasicOntology<OntModel> implements HeavyLoadedOntology<OntModel>{ - private boolean onlyLocalEntities=true; + private boolean onlyLocalEntities = true; // JE: this is not very Java 1.5... // This is because of the version of Jena we use apparently - + public JENAOntology() {} // default is true public JENAOntology(boolean onlyLocalEntities) { this.onlyLocalEntities=onlyLocalEntities; diff --git a/src/fr/inrialpes/exmo/ontowrap/jena25/JENAOntologyFactory.java b/src/fr/inrialpes/exmo/ontowrap/jena25/JENAOntologyFactory.java index 08e4286a..de57fd59 100644 --- a/src/fr/inrialpes/exmo/ontowrap/jena25/JENAOntologyFactory.java +++ b/src/fr/inrialpes/exmo/ontowrap/jena25/JENAOntologyFactory.java @@ -1,7 +1,7 @@ /* * $Id$ * - * Copyright (C) INRIA, 2003-2008, 2010 + * Copyright (C) INRIA, 2003-2008, 2010, 2013 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -24,6 +24,9 @@ import java.net.URI; import java.net.URISyntaxException; import java.util.NoSuchElementException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.hp.hpl.jena.ontology.OntModel; import com.hp.hpl.jena.ontology.OntModelSpec; import com.hp.hpl.jena.ontology.Ontology; @@ -35,6 +38,7 @@ import fr.inrialpes.exmo.ontowrap.OntologyCache; import fr.inrialpes.exmo.ontowrap.OntowrapException; public class JENAOntologyFactory extends OntologyFactory { + final static Logger logger = LoggerFactory.getLogger( JENAOntologyFactory.class ); private static URI formalismUri = null; private static String formalismId = "OWL1.0"; @@ -45,7 +49,9 @@ public class JENAOntologyFactory extends OntologyFactory { cache = new OntologyCache<JENAOntology>(); try { formalismUri = new URI("http://www.w3.org/2002/07/owl#"); - } catch (URISyntaxException ex) { ex.printStackTrace(); } // should not happen + } catch (URISyntaxException ex) { + logger.debug( "IGNORED (should never happen)", ex ); + } // should not happen } public JENAOntology newOntology( Object ontology , boolean onlyLocalEntities ) throws OntowrapException { diff --git a/src/fr/inrialpes/exmo/ontowrap/owlapi10/OWLAPIAnnotIt.java b/src/fr/inrialpes/exmo/ontowrap/owlapi10/OWLAPIAnnotIt.java index dcc760a4..177cfab7 100644 --- a/src/fr/inrialpes/exmo/ontowrap/owlapi10/OWLAPIAnnotIt.java +++ b/src/fr/inrialpes/exmo/ontowrap/owlapi10/OWLAPIAnnotIt.java @@ -1,7 +1,7 @@ /* * $Id: OWLAPIAnnotIt.java 896 2008-11-25 14:45:46Z jdavid $ * - * Copyright (C) INRIA, 2007-2008, 2010 + * Copyright (C) INRIA, 2007-2008, 2010, 2013 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -23,6 +23,9 @@ package fr.inrialpes.exmo.ontowrap.owlapi10; import java.util.Iterator; import java.util.NoSuchElementException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import org.semanticweb.owl.model.OWLAnnotationInstance; import org.semanticweb.owl.model.OWLDataValue; import org.semanticweb.owl.model.OWLEntity; @@ -36,6 +39,7 @@ import org.semanticweb.owl.model.OWLOntology; * */ public class OWLAPIAnnotIt implements Iterator<String> { + final static Logger logger = LoggerFactory.getLogger( OWLAPIAnnotIt.class ); /*private OWLOntology o; private OWLEntity e;*/ @@ -80,7 +84,7 @@ public class OWLAPIAnnotIt implements Iterator<String> { } } } catch (OWLException e) { - e.printStackTrace(); + logger.debug( "IGNORED Exception", e ); currentElem=null; } } diff --git a/src/fr/inrialpes/exmo/ontowrap/owlapi10/OWLAPIOntology.java b/src/fr/inrialpes/exmo/ontowrap/owlapi10/OWLAPIOntology.java index fb132c80..69bc1921 100644 --- a/src/fr/inrialpes/exmo/ontowrap/owlapi10/OWLAPIOntology.java +++ b/src/fr/inrialpes/exmo/ontowrap/owlapi10/OWLAPIOntology.java @@ -1,7 +1,7 @@ /* * $Id: OWLAPIOntology.java 896 2008-11-25 14:45:46Z jdavid $ * - * Copyright (C) INRIA, 2007-2008, 2010 + * Copyright (C) INRIA, 2007-2008, 2010, 2013 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -40,6 +40,9 @@ import java.util.Map; import java.util.Set; import java.util.HashSet; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import fr.inrialpes.exmo.ontowrap.Annotation; import fr.inrialpes.exmo.ontowrap.OntologyFactory; import fr.inrialpes.exmo.ontowrap.HeavyLoadedOntology; @@ -69,6 +72,7 @@ import org.semanticweb.owl.model.helper.OWLEntityCollector; */ public class OWLAPIOntology extends BasicOntology<OWLOntology> implements HeavyLoadedOntology<OWLOntology> { + final static Logger logger = LoggerFactory.getLogger( OWLAPIOntology.class ); /* For caching sizes */ private int nbentities = -1; @@ -82,7 +86,9 @@ public class OWLAPIOntology extends BasicOntology<OWLOntology> implements HeavyL setFormalism( "OWL1.0" ); try { setFormURI( new URI("http://www.w3.org/2002/07/owl#") ); - } catch (Exception e) {}; // does not happen + } catch (Exception e) { + logger.debug( "IGNORED (should never happen)", e ); + }; }; // ----------------------------------------------------------------- @@ -179,7 +185,7 @@ public class OWLAPIOntology extends BasicOntology<OWLOntology> implements HeavyL try { return new OWLAPIAnnotIt(o,e,lang,typeAnnot); } catch (OWLException e) { - e.printStackTrace(); + logger.debug( "IGNORED", e ); return null; } } @@ -357,7 +363,9 @@ public class OWLAPIOntology extends BasicOntology<OWLOntology> implements HeavyL public void unload() { try { onto.getOWLConnection().notifyOntologyDeleted( onto ); - } catch (OWLException ex) { System.err.println(ex); }; + } catch (OWLException ex) { + logger.debug( "IGNORED Exception", ex); + }; } // ----------------------------------------------------------------- @@ -412,7 +420,9 @@ public class OWLAPIOntology extends BasicOntology<OWLOntology> implements HeavyL if ( ent instanceof OWLRestriction ) prop.add( ((OWLRestriction)ent).getProperty() ); } - } catch (OWLException e) { e.printStackTrace(); } + } catch (OWLException e) { + logger.debug( "IGNORED", e ); + } } else { prop = getInheritedProperties( (OWLClass)cl ); } diff --git a/src/fr/inrialpes/exmo/ontowrap/owlapi10/OWLAPIOntologyFactory.java b/src/fr/inrialpes/exmo/ontowrap/owlapi10/OWLAPIOntologyFactory.java index 3039bd37..2bc3cb0d 100644 --- a/src/fr/inrialpes/exmo/ontowrap/owlapi10/OWLAPIOntologyFactory.java +++ b/src/fr/inrialpes/exmo/ontowrap/owlapi10/OWLAPIOntologyFactory.java @@ -28,6 +28,9 @@ import java.util.HashSet; import java.util.Map; import java.util.Set; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import org.semanticweb.owl.model.OWLException; import org.semanticweb.owl.model.OWLOntology; import org.semanticweb.owl.util.OWLConnection; @@ -40,6 +43,7 @@ import fr.inrialpes.exmo.ontowrap.LoadedOntology; import fr.inrialpes.exmo.ontowrap.OntowrapException; public class OWLAPIOntologyFactory extends OntologyFactory { + final static Logger logger = LoggerFactory.getLogger( OWLAPIOntologyFactory.class ); private static URI formalismUri = null; private static String formalismId = "OWL1.0"; @@ -49,7 +53,9 @@ public class OWLAPIOntologyFactory extends OntologyFactory { cache = new OntologyCache<OWLAPIOntology>(); try { formalismUri = new URI("http://www.w3.org/2002/07/owl#"); - } catch (URISyntaxException ex) { ex.printStackTrace(); } // should not happen + } catch (URISyntaxException ex) { + logger.debug( "IGNORED should never happen", ex ); + } }; public void clearCache() throws OntowrapException { @@ -67,7 +73,7 @@ public class OWLAPIOntologyFactory extends OntologyFactory { onto.setURI( ((OWLOntology)ontology).getLogicalURI() ); } catch (OWLException e) { // Better put in the OntowrapException of loaded - e.printStackTrace(); + logger.debug( "IGNORED (ontology without URI)", e ); } //cache.recordOntology( uri, onto ); return onto; @@ -99,7 +105,7 @@ public class OWLAPIOntologyFactory extends OntologyFactory { onto.setURI( ontology.getLogicalURI() ); } catch (OWLException e) { // Better put in the OntowrapException of loaded - e.printStackTrace(); + logger.debug( "IGNORED Exception", e ); } cache.recordOntology( uri, onto ); return onto; diff --git a/src/fr/inrialpes/exmo/ontowrap/owlapi30/OWLAPI3Ontology.java b/src/fr/inrialpes/exmo/ontowrap/owlapi30/OWLAPI3Ontology.java index 82e36865..3c3fea5d 100644 --- a/src/fr/inrialpes/exmo/ontowrap/owlapi30/OWLAPI3Ontology.java +++ b/src/fr/inrialpes/exmo/ontowrap/owlapi30/OWLAPI3Ontology.java @@ -93,9 +93,6 @@ public class OWLAPI3Ontology extends BasicOntology<OWLOntology> implements Heavy //return onto.getDataPropertiesInSignature(); } - - - public Set<? extends Object> getEntities() { //return onto.getSignature(); return new EntityFilter<OWLEntity>(onto.getSignature(),this) { diff --git a/src/fr/inrialpes/exmo/ontowrap/owlapi30/OWLAPI3OntologyFactory.java b/src/fr/inrialpes/exmo/ontowrap/owlapi30/OWLAPI3OntologyFactory.java index 788996dc..d08caf42 100644 --- a/src/fr/inrialpes/exmo/ontowrap/owlapi30/OWLAPI3OntologyFactory.java +++ b/src/fr/inrialpes/exmo/ontowrap/owlapi30/OWLAPI3OntologyFactory.java @@ -1,7 +1,7 @@ /* * $Id$ * - * Copyright (C) INRIA, 2008-2011 + * Copyright (C) INRIA, 2008-2011, 2013 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -23,6 +23,9 @@ package fr.inrialpes.exmo.ontowrap.owlapi30; import java.net.URI; import java.net.URISyntaxException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import org.semanticweb.owlapi.apibinding.OWLManager; import org.semanticweb.owlapi.model.OWLOntology; @@ -38,6 +41,7 @@ import fr.inrialpes.exmo.ontowrap.OntologyFactory; import fr.inrialpes.exmo.ontowrap.HeavyLoadedOntology; public class OWLAPI3OntologyFactory extends OntologyFactory { + final static Logger logger = LoggerFactory.getLogger( OWLAPI3OntologyFactory.class ); private URI formalismUri = null; @@ -52,13 +56,13 @@ public class OWLAPI3OntologyFactory extends OntologyFactory { try { formalismUri = new URI("http://www.w3.org/2002/07/owl#"); manager = OWLManager.createOWLOntologyManager(); - } catch (URISyntaxException ex) { // should not happen - ex.printStackTrace(); + } catch (URISyntaxException ex) { + logger.debug( "IGNORED should never happen", ex ); } } @Override - public OWLAPI3Ontology newOntology( Object ontology , boolean onlyLocalEntities) throws OntowrapException { + public OWLAPI3Ontology newOntology( Object ontology, boolean onlyLocalEntities) throws OntowrapException { if ( ontology instanceof OWLOntology ) { OWLAPI3Ontology onto = new OWLAPI3Ontology(onlyLocalEntities); onto.setFormalism( formalismId ); @@ -74,27 +78,26 @@ public class OWLAPI3OntologyFactory extends OntologyFactory { } @Override - public HeavyLoadedOntology loadOntology( URI uri , boolean onlyLocalEntities) throws OntowrapException { + public HeavyLoadedOntology loadOntology( URI uri, boolean onlyLocalEntities ) throws OntowrapException { OWLAPI3Ontology onto = null; - //System.err.println( " Loading ontology "+uri ); + // logger.trace( " Loading ontology {}", uri ); // Cache seems to be implemented in API 3.0 anyway // and it seems to not work well with this one onto = cache.getOntologyFromURI( uri ); - //System.err.println( " cache1: "+onto ); + // logger.trace( "cache1: {}", onto ); if ( onto != null ) return onto; onto = cache.getOntology( uri ); - //System.err.println( " cache2: "+onto ); + // logger.trace( "cache2: {}", onto ); if ( onto != null ) return onto; // OWLAPI's own cache IRI ontoIRI = IRI.create( uri ); OWLOntology ontology = manager.getOntology( ontoIRI ); - //System.err.println( " cache3: "+ontology ); - + // logger.trace( "cache3: {}", ontology ); try { // This below does not seem to work! //ontology = manager.loadOntologyFromOntologyDocument( IRI.create( uri ) ); if ( ontology == null ) ontology = manager.loadOntology( ontoIRI ); - //System.err.println( " loaded: "+ontology ); + // logger.trace( "loaded: {}", ontology ); // I must retrieve it from cache and return it! } catch ( OWLOntologyDocumentAlreadyExistsException oodaeex ) { // should never happen // This is a cache failure @@ -105,10 +108,9 @@ public class OWLAPI3OntologyFactory extends OntologyFactory { if ( ontology == null ) throw new OntowrapException("Already loaded [owl cache failure] " + uri, ooaeex ); } catch ( OWLOntologyCreationException oocex ) { - oocex.printStackTrace(); - throw new OntowrapException("Cannot load " + uri, oocex ); + throw new OntowrapException( "Cannot load " + uri, oocex ); } - onto = new OWLAPI3Ontology(onlyLocalEntities); + onto = new OWLAPI3Ontology( onlyLocalEntities ); onto.setFormalism( formalismId ); onto.setFormURI( formalismUri ); onto.setOntology( ontology ); @@ -119,10 +121,10 @@ public class OWLAPI3OntologyFactory extends OntologyFactory { // Better put in the OntowrapException of loaded // The ontology has no URI. In principle, it is not valid // It may be possible to put the uri instead (now it is void) - e.printStackTrace(); + logger.debug( "IGNORED Exception (ontology without URI)", e ); } cache.recordOntology( uri, onto ); - //System.err.println( " after-cache: "+cache.getOntology( uri ) ); + // logger.trace( "after-cache: {}", cache.getOntology( uri ) ); return onto; } diff --git a/src/fr/inrialpes/exmo/ontowrap/skosapi/SKOSOntologyFactory.java b/src/fr/inrialpes/exmo/ontowrap/skosapi/SKOSOntologyFactory.java index fa9fdf95..312c5d88 100644 --- a/src/fr/inrialpes/exmo/ontowrap/skosapi/SKOSOntologyFactory.java +++ b/src/fr/inrialpes/exmo/ontowrap/skosapi/SKOSOntologyFactory.java @@ -1,7 +1,7 @@ /* * $Id$ * - * Copyright (C) INRIA, 2009-2010 + * Copyright (C) INRIA, 2009-2010, 2013 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -24,6 +24,9 @@ import java.net.URI; import java.net.URISyntaxException; import java.util.NoSuchElementException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import org.semanticweb.skosapibinding.SKOSManager; import org.semanticweb.skos.SKOSCreationException; import org.semanticweb.skos.SKOSDataset; @@ -35,6 +38,7 @@ import fr.inrialpes.exmo.ontowrap.OntologyCache; import fr.inrialpes.exmo.ontowrap.OntowrapException; public class SKOSOntologyFactory extends OntologyFactory { + final static Logger logger = LoggerFactory.getLogger( SKOSOntologyFactory.class ); private static URI formalismUri = null; private static String formalismId = "SKOS1.0"; @@ -47,7 +51,7 @@ public class SKOSOntologyFactory extends OntologyFactory { cache = new OntologyCache<SKOSThesaurus>(); try { formalismUri = new URI("http://www.w3.org/2004/02/skos/core#"); - } catch (URISyntaxException ex) { ex.printStackTrace(); } // should not happen + } catch (URISyntaxException ex) { logger.debug( "IGNORED should not happen", ex ); } try { manager = new SKOSManager(); } catch (SKOSCreationException sce) { @@ -77,7 +81,7 @@ public class SKOSOntologyFactory extends OntologyFactory { @Override public SKOSThesaurus loadOntology( URI uri , boolean onlyLocalEntities) throws OntowrapException { - //System.err.println(" Loading "+uri ); + //logger.trace( "Loading {}", uri ); SKOSThesaurus onto = null; onto = cache.getOntologyFromURI( uri ); if ( onto != null ) return onto; diff --git a/src/fr/inrialpes/exmo/ontowrap/skosapi/SKOSThesaurus.java b/src/fr/inrialpes/exmo/ontowrap/skosapi/SKOSThesaurus.java index d0fbea57..8f8ab921 100644 --- a/src/fr/inrialpes/exmo/ontowrap/skosapi/SKOSThesaurus.java +++ b/src/fr/inrialpes/exmo/ontowrap/skosapi/SKOSThesaurus.java @@ -1,7 +1,7 @@ /* * $Id$ * - * Copyright (C) INRIA, 2009-2010, 2012 + * Copyright (C) INRIA, 2009-2010, 2012-2013 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -27,6 +27,9 @@ import java.util.Iterator; import java.util.Map; import java.util.Set; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import org.semanticweb.skos.SKOSDataFactory; import org.semanticweb.skos.SKOSDataset; import org.semanticweb.skos.SKOSAnnotation; @@ -45,6 +48,7 @@ import fr.inrialpes.exmo.ontowrap.HeavyLoadedOntology; import fr.inrialpes.exmo.ontowrap.OntowrapException; public class SKOSThesaurus extends BasicOntology<SKOSDataset> implements HeavyLoadedOntology<SKOSDataset>{ + final static Logger logger = LoggerFactory.getLogger( SKOSThesaurus.class ); SKOSDataFactory factory; @@ -88,7 +92,7 @@ onto.getSKOSDataRelationAssertions(concept) assertion.getSKOSObject(); if (literal.isTyped()) { SKOSTypedLiteral typedLiteral = literal.getAsSKOSTypedLiteral(); -System.out.println("\t\t" + assertion.getSKOSProperty().getURI().getFragment() + " " + literal.getLiteral() + " Type:" + typedLiteral.getDataType().getURI() ); +//logger.trace("\t\t {} {} Type: {}", assertion.getSKOSProperty().getURI().getFragment(), literal.getLiteral(), typedLiteral.getDataType().getURI() ); } else { SKOSUntypedLiteral untypedLiteral = literal.getAsSKOSUntypedLiteral(); if (untypedLiteral.hasLang()) { diff --git a/src/fr/inrialpes/exmo/ontowrap/skoslite/SKOSLiteOntologyFactory.java b/src/fr/inrialpes/exmo/ontowrap/skoslite/SKOSLiteOntologyFactory.java index aefc3594..8c412061 100644 --- a/src/fr/inrialpes/exmo/ontowrap/skoslite/SKOSLiteOntologyFactory.java +++ b/src/fr/inrialpes/exmo/ontowrap/skoslite/SKOSLiteOntologyFactory.java @@ -1,7 +1,7 @@ /* * $Id$ * - * Copyright (C) INRIA, 2008-2010 + * Copyright (C) INRIA, 2008-2010, 2013 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -23,6 +23,9 @@ package fr.inrialpes.exmo.ontowrap.skoslite; import java.net.URI; import java.net.URISyntaxException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.hp.hpl.jena.rdf.model.Model; import fr.inrialpes.exmo.ontowrap.OntologyCache; @@ -30,6 +33,7 @@ import fr.inrialpes.exmo.ontowrap.OntologyFactory; import fr.inrialpes.exmo.ontowrap.OntowrapException; public class SKOSLiteOntologyFactory extends OntologyFactory { + final static Logger logger = LoggerFactory.getLogger( SKOSLiteOntologyFactory.class ); private URI formalismUri; private final static String formalismId = "SKOS1.0"; @@ -39,8 +43,7 @@ public class SKOSLiteOntologyFactory extends OntologyFactory { try { formalismUri = new URI("http://www.w3.org/2004/02/skos/core#"); } catch (URISyntaxException e) { - - e.printStackTrace(); + logger.trace( "IGNORED: should never been raised", e ); } } diff --git a/src/fr/inrialpes/exmo/ontowrap/skoslite/SKOSLiteThesaurus.java b/src/fr/inrialpes/exmo/ontowrap/skoslite/SKOSLiteThesaurus.java index 51291e00..497726ac 100644 --- a/src/fr/inrialpes/exmo/ontowrap/skoslite/SKOSLiteThesaurus.java +++ b/src/fr/inrialpes/exmo/ontowrap/skoslite/SKOSLiteThesaurus.java @@ -1,7 +1,7 @@ /* * $Id$ * - * Copyright (C) INRIA, 2008-2010, 2012 + * Copyright (C) INRIA, 2008-2010, 2012-2013 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -27,6 +27,9 @@ import java.util.HashSet; import java.util.Map; import java.util.Set; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.hp.hpl.jena.graph.Node; import com.hp.hpl.jena.rdf.model.InfModel; import com.hp.hpl.jena.rdf.model.Model; @@ -45,6 +48,7 @@ import fr.inrialpes.exmo.ontowrap.HeavyLoadedOntology; import fr.inrialpes.exmo.ontowrap.OntowrapException; public class SKOSLiteThesaurus implements HeavyLoadedOntology<Model> { + final static Logger logger = LoggerFactory.getLogger( SKOSLiteThesaurus.class ); protected final static String SKOS_ONTO = SKOSLiteThesaurus.class.getClassLoader().getResource("fr/inrialpes/exmo/ontowrap/skoslite/skos.rdf").toString(); @@ -150,7 +154,7 @@ public class SKOSLiteThesaurus implements HeavyLoadedOntology<Model> { */ public Set<? extends Object> getSubClasses(Object c, int local, int asserted, int named) { HashSet<Object> sub = new HashSet<Object>(); - //System.out.println(c); + //logger.trace( "getSubClasses({})", c); StmtIterator it =ontoInf.listStatements(null,ontoInf.getProperty(SKOS_BROADERTRANSITIVE),(Resource) c); while ( it.hasNext() ) { Statement st = it.next(); @@ -203,7 +207,8 @@ public class SKOSLiteThesaurus implements HeavyLoadedOntology<Model> { try { Object o = ontoInf.getRawModel().getResource(u.toString()); if (! ontoInf.contains((Resource) o, RDF.type, ontoInf.getResource(SKOS_CONCEPT))) { - return null;//System.out.println(u+" : "+o); + //logger.trace( "getEntity({}) = {}", u, o); + return null; } return o; @@ -224,7 +229,7 @@ public class SKOSLiteThesaurus implements HeavyLoadedOntology<Model> { while (it.hasNext()) { Node n = it.next().asNode(); if (n.isLiteral() && (lang==null || lang.equals(n.getLiteralLanguage()))) { - //System.out.println(n.getLiteralLexicalForm()); + //logger.trace( "getEntityAnnotation = {}", n.getLiteralLexicalForm() ); annots.add(n.getLiteralLexicalForm()); } } @@ -243,7 +248,7 @@ public class SKOSLiteThesaurus implements HeavyLoadedOntology<Model> { while (it.hasNext()) { Node n = it.next().asNode(); if (n.isLiteral()) { - //System.out.println(n.getLiteralLexicalForm()); + //logger.trace( "getEntityAnnotationsL = {}", n.getLiteralLexicalForm() ); annots.add(new Annotation(n.getLiteralLexicalForm(),n.getLiteralLanguage())); } } diff --git a/src/fr/inrialpes/exmo/ontowrap/util/EntityFilter.java b/src/fr/inrialpes/exmo/ontowrap/util/EntityFilter.java index d99f8982..2504b503 100644 --- a/src/fr/inrialpes/exmo/ontowrap/util/EntityFilter.java +++ b/src/fr/inrialpes/exmo/ontowrap/util/EntityFilter.java @@ -1,7 +1,7 @@ /* * $Id$ * - * Copyright (C) INRIA, 2010 + * Copyright (C) INRIA, 2010, 2013 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -23,10 +23,14 @@ package fr.inrialpes.exmo.ontowrap.util; import java.net.URI; import java.util.Set; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import fr.inrialpes.exmo.ontowrap.LoadedOntology; import fr.inrialpes.exmo.ontowrap.OntowrapException; public class EntityFilter<T> extends FilteredSet<T> { + final static Logger logger = LoggerFactory.getLogger( EntityFilter.class ); private String ontoURI=null; private LoadedOntology<?> onto=null; @@ -43,11 +47,11 @@ public class EntityFilter<T> extends FilteredSet<T> { protected boolean isFiltered(T obj) { try { URI entURI=onto.getEntityURI(obj); - //System.out.println(entURI +" - "+ontoURI); + //logger.trace( "{}�- {}", entURI, ontoURI); return (entURI.getAuthority()!=null) && (entURI==null || ontoURI.equals(entURI.toString()) || !entURI.toString().startsWith(ontoURI)); } catch (OntowrapException e) { - // e.printStackTrace(); + logger.debug( "IGNORED: Entity is filtered", e ); } return true; } diff --git a/src/org/semanticweb/owl/align/AlignmentException.java b/src/org/semanticweb/owl/align/AlignmentException.java index a09da48c..f55cac7d 100644 --- a/src/org/semanticweb/owl/align/AlignmentException.java +++ b/src/org/semanticweb/owl/align/AlignmentException.java @@ -30,19 +30,16 @@ import java.lang.Exception; * @version $Id$ */ -public class AlignmentException extends Exception -{ +public class AlignmentException extends Exception { private static final long serialVersionUID = 330; - public AlignmentException( String message ) - { + public AlignmentException( String message ) { super( message ); } - public AlignmentException( String message, Exception e ) - { - super( message, e ); + public AlignmentException( String message, Exception ex ) { + super( message, ex ); } } diff --git a/test/clitest.sh b/test/clitest.sh new file mode 100644 index 00000000..00a4bd38 --- /dev/null +++ b/test/clitest.sh @@ -0,0 +1,1143 @@ +#!/bin/sh +# +# This long script runs commands from the +# +# It is highly dependent on logback and my own logback.xml +# + +CWD=`pwd` +CP=$CWD/lib/procalign.jar:$CWD/lib/slf4j/logback-core-1.0.9.jar:$CWD/lib/slf4j/logback-classic-1.0.9.jar:$CWD +RESDIR='/tmp/clitest' + +######################################################################## +# ProcAlign +######################################################################## + +/bin/rm -rf $RESDIR +mkdir -p $RESDIR + +# GOTO +if false; then +echo this is for avoiding some parts +#GOTO +fi + +echo "\t\tTHE -z OPTIONS RELY ON LOGBACK BEING PROPERLY DEFINED" +echo "\t\t *** Testing Procalign ***" + +#------------------- +echo "\t-z, -zzz" +java -Dlog.level=INFO -cp $CP fr.inrialpes.exmo.align.cli.Procalign -z &> $RESDIR/zerr.txt +grep "Unrecognized option: -z" $RESDIR/zerr.txt > $RESDIR/err.txt +if [ ! -s $RESDIR/err.txt ]; then echo error with PROC-ERR1; fi +java -Dlog.level=INFO -cp $CP fr.inrialpes.exmo.align.cli.Procalign --zzz &> $RESDIR/zzzerr.txt +grep "Unrecognized option: --zzz" $RESDIR/zzzerr.txt > $RESDIR/err.txt +if [ ! -s $RESDIR/err.txt ]; then echo error with PROC-ERR2; fi + +#------------------- +echo "\t-h,--help" +java -cp $CP fr.inrialpes.exmo.align.cli.Procalign -h &> $RESDIR/proc-h.txt +java -cp $CP fr.inrialpes.exmo.align.cli.Procalign --help &> $RESDIR/proc-help.txt +if [ -s $RESDIR/proc-h.txt ]; then diff $RESDIR/proc-h.txt $RESDIR/proc-help.txt > $RESDIR/proc-diff-h.txt; else echo error with PROC-HELP1; fi +if [ -s $RESDIR/proc-diff-h.txt ]; then echo error with PROC-HELP2; fi + +#------------------- +echo "\t-o,--output <FILE>" +java -cp $CP fr.inrialpes.exmo.align.cli.Procalign file://$CWD/examples/rdf/onto1.owl file://$CWD/examples/rdf/onto2.owl -o $RESDIR/proc-o1.rdf +java -cp $CP fr.inrialpes.exmo.align.cli.Procalign file://$CWD/examples/rdf/onto1.owl file://$CWD/examples/rdf/onto2.owl --output $RESDIR/proc-output1.rdf +sed "s:<time>[^<]*</time>::" $RESDIR/proc-o1.rdf > $RESDIR/proc-o.rdf +sed "s:<time>[^<]*</time>::" $RESDIR/proc-output1.rdf > $RESDIR/proc-output.rdf +if [ -s $RESDIR/proc-o.rdf ]; then diff $RESDIR/proc-o.rdf $RESDIR/proc-output.rdf; else echo error with PROC-OUTPUT1; fi + +#------------------- +echo "\t-a,--alignment <FILE>" +java -cp $CP fr.inrialpes.exmo.align.cli.Procalign file://$CWD/examples/rdf/onto1.owl file://$CWD/examples/rdf/onto2.owl -a examples/rdf/sample.rdf | sed "s:<time>[^<]*</time>::" > $RESDIR/proc-a.rdf +java -cp $CP fr.inrialpes.exmo.align.cli.Procalign file://$CWD/examples/rdf/onto1.owl file://$CWD/examples/rdf/onto2.owl --alignment examples/rdf/sample.rdf | sed "s:<time>[^<]*</time>::" > $RESDIR/proc-align.rdf +if [ -s $RESDIR/proc-a.rdf ]; then diff $RESDIR/proc-a.rdf $RESDIR/proc-align.rdf; else echo error with PROC-ALIGN1; fi + +#------------------- +echo "\t-i <C>, --impl <C>" +#JE: A random distance available (could try with others) +java -cp $CP fr.inrialpes.exmo.align.cli.Procalign file://$CWD/examples/rdf/onto1.owl file://$CWD/examples/rdf/onto2.owl -i fr.inrialpes.exmo.align.impl.method.StrucSubsDistAlignment | sed "s:<time>[^<]*</time>::" > $RESDIR/proc-i.rdf +java -cp $CP fr.inrialpes.exmo.align.cli.Procalign file://$CWD/examples/rdf/onto1.owl file://$CWD/examples/rdf/onto2.owl --impl fr.inrialpes.exmo.align.impl.method.StrucSubsDistAlignment | sed "s:<time>[^<]*</time>::" > $RESDIR/proc-impl.rdf +if [ -s $RESDIR/proc-i.rdf ]; then diff $RESDIR/proc-i.rdf $RESDIR/proc-impl.rdf; else echo error with PROC-IMPL1; fi + +#------------------- +echo "\t-Dn=v" +java -cp $CP fr.inrialpes.exmo.align.cli.Procalign file://$CWD/examples/rdf/onto1.owl file://$CWD/examples/rdf/onto2.owl -i fr.inrialpes.exmo.align.impl.method.StringDistAlignment -DstringFunction=levenshteinDistance | sed "s:<time>[^<]*</time>::" > $RESDIR/proc-id.rdf +if [ -s $RESDIR/proc-id.rdf ]; then diff $RESDIR/proc-i.rdf $RESDIR/proc-id.rdf | sed "s:<time>[^<]*</time>::" > $RESDIR/diff-proc.txt; else echo error with PROC-PARAM1; fi +if [ ! -s $RESDIR/diff-proc.txt ]; then echo error with PROC-PARAM2; fi + +#------------------- +echo "\t-t,--threshold <DOUBLE>" +java -cp $CP fr.inrialpes.exmo.align.cli.Procalign file://$CWD/examples/rdf/onto1.owl file://$CWD/examples/rdf/onto2.owl -i fr.inrialpes.exmo.align.impl.method.StringDistAlignment -DstringFunction=levenshteinDistance -t 0.4 | sed "s:<time>[^<]*</time>::" > $RESDIR/proc-t.rdf +java -cp $CP fr.inrialpes.exmo.align.cli.Procalign file://$CWD/examples/rdf/onto1.owl file://$CWD/examples/rdf/onto2.owl fr.inrialpes.exmo.align.impl.method.StringDistAlignment -DstringFunction=levenshteinDistance --threshold 0.4 | sed "s:<time>[^<]*</time>::" > $RESDIR/proc-threshold.rdf +if [ -s $RESDIR/proc-t.rdf ]; then diff $RESDIR/proc-t.rdf $RESDIR/proc-threshold.rdf; else echo error with PROC-THRES1; fi +# test diff from previous +diff $RESDIR/proc-t.rdf $RESDIR/proc-id.rdf > $RESDIR/diff-proc.txt +if [ ! -s $RESDIR/diff-proc.txt ]; then echo error with PROC-THRES2; fi + +#------------------- +echo "\t-T,--cutmethod <METHOD>" +java -cp $CP fr.inrialpes.exmo.align.cli.Procalign file://$CWD/examples/rdf/onto1.owl file://$CWD/examples/rdf/onto2.owl -i fr.inrialpes.exmo.align.impl.method.StringDistAlignment -DstringFunction=levenshteinDistance -t 0.4 -T perc | sed "s:<time>[^<]*</time>::" > $RESDIR/proc-C.rdf +java -cp $CP fr.inrialpes.exmo.align.cli.Procalign file://$CWD/examples/rdf/onto1.owl file://$CWD/examples/rdf/onto2.owl --impl fr.inrialpes.exmo.align.impl.method.StringDistAlignment -DstringFunction=levenshteinDistance -t 0.4 --cutmethod perc | sed "s:<time>[^<]*</time>::" > $RESDIR/proc-cutmethod.rdf +if [ -s $RESDIR/proc-C.rdf ]; then diff $RESDIR/proc-C.rdf $RESDIR/proc-cutmethod.rdf; else echo error with PROC-CUT1; fi +# test diff from previous +diff $RESDIR/proc-C.rdf $RESDIR/proc-t.rdf > $RESDIR/diff-proc.txt +if [ ! -s $RESDIR/diff-proc.txt ]; then echo error with PROC-CUT2; fi + +#------------------- +echo "\t-r,--renderer <CLASS>" +java -cp $CP fr.inrialpes.exmo.align.cli.Procalign file://$CWD/examples/rdf/onto1.owl file://$CWD/examples/rdf/onto2.owl -r fr.inrialpes.exmo.align.impl.renderer.OWLAxiomsRendererVisitor | sed "s/time: [0-9]*/time: 0/" > $RESDIR/proc-r.rdf +java -cp $CP fr.inrialpes.exmo.align.cli.Procalign file://$CWD/examples/rdf/onto1.owl file://$CWD/examples/rdf/onto2.owl --renderer fr.inrialpes.exmo.align.impl.renderer.OWLAxiomsRendererVisitor | sed "s/time: [0-9]*/time: 0/" > $RESDIR/proc-render.rdf +if [ -s $RESDIR/proc-r.rdf ]; then diff $RESDIR/proc-r.rdf $RESDIR/proc-render.rdf; else echo error with PROC-RENDER1; fi + +#------------------- +echo "\t-P,--params <FILE>" +echo "<?xml version='1.0' encoding='utf-8' standalone='no'?> +<\x21DOCTYPE properties SYSTEM \"http://java.sun.com/dtd/properties.dtd\"> +<properties> +<entry key=\"impl\">fr.inrialpes.exmo.align.impl.method.StringDistAlignment</entry> +<entry key=\"stringFunction\">levenshteinDistance</entry> +</properties>" > $RESDIR/params.xml +java -cp $CP fr.inrialpes.exmo.align.cli.Procalign file://$CWD/examples/rdf/onto1.owl file://$CWD/examples/rdf/onto2.owl -P $RESDIR/params.xml | sed "s:<time>[^<]*</time>::" > $RESDIR/proc-p.rdf +#Will not work because we use loadFromXML +#echo "impl=fr.inrialpes.exmo.align.impl.method.StringDistAlignment +#stringFunction=levenshteinDistance" > $RESDIR/params.prop +java -cp $CP fr.inrialpes.exmo.align.cli.Procalign file://$CWD/examples/rdf/onto1.owl file://$CWD/examples/rdf/onto2.owl --params $RESDIR/params.xml | sed "s:<time>[^<]*</time>::" > $RESDIR/proc-params.rdf +if [ -s $RESDIR/proc-p.rdf ]; then diff $RESDIR/proc-p.rdf $RESDIR/proc-params.rdf; else echo error with PROC-PARAMS1; fi +diff $RESDIR/proc-p.rdf $RESDIR/proc-id.rdf + +######################################################################## +# ParserPrinter +######################################################################## + +echo "\t\t *** Testing ParserPrinter ***" + +#------------------- +echo "\t-z, -zzz" + +java -Dlog.level=INFO -cp $CP fr.inrialpes.exmo.align.cli.ParserPrinter -z &> $RESDIR/zerr.txt +grep "Unrecognized option: -z" $RESDIR/zerr.txt > $RESDIR/err.txt +if [ ! -s $RESDIR/err.txt ]; then echo error with PARS-ERR1; fi +java -Dlog.level=INFO -cp $CP fr.inrialpes.exmo.align.cli.ParserPrinter --zzz &> $RESDIR/zzzerr.txt +grep "Unrecognized option: --zzz" $RESDIR/zzzerr.txt > $RESDIR/err.txt +if [ ! -s $RESDIR/err.txt ]; then echo error with PARS-ERR2; fi + +#------------------- +echo "\t-h, --help" +java -cp $CP fr.inrialpes.exmo.align.cli.ParserPrinter -h &> $RESDIR/pars-h.txt +java -cp $CP fr.inrialpes.exmo.align.cli.ParserPrinter --help &> $RESDIR/pars-help.txt +if [ -s $RESDIR/pars-h.txt ]; then diff $RESDIR/pars-h.txt $RESDIR/pars-help.txt; else echo error with $RESDIR/pars-h.txt; fi + +#------------------- +echo "\tno-op" +java -cp $CP fr.inrialpes.exmo.align.cli.ParserPrinter file://$CWD/examples/rdf/newsample.rdf &> $RESDIR/pars-noop.rdf + +#------------------- +echo "\t-e,--embedded" +java -cp $CP fr.inrialpes.exmo.align.cli.ParserPrinter file://$CWD/examples/rdf/newsample.rdf -e -o $RESDIR/pars-e.rdf +java -cp $CP fr.inrialpes.exmo.align.cli.ParserPrinter file://$CWD/examples/rdf/newsample.rdf --embedded -o $RESDIR/pars-emb.rdf +if [ -s $RESDIR/pars-e.rdf ]; then diff $RESDIR/pars-e.rdf $RESDIR/pars-emb.rdf; else echo error with PARS-EMB; fi +diff $RESDIR/pars-e.rdf $RESDIR/pars-noop.rdf + +#------------------- +# JE: there is no alternative parser (RDF/XML Parser are not AlignmentParsers) +echo "\t-p,--parser <CLASS>" +java -cp $CP fr.inrialpes.exmo.align.cli.ParserPrinter -p fr.inrialpes.exmo.align.parser.AlignmentParser file://$CWD/examples/rdf/newsample.rdf -o $RESDIR/pars-p1.rdf +java -cp $CP fr.inrialpes.exmo.align.cli.ParserPrinter --parser fr.inrialpes.exmo.align.parser.AlignmentParser file://$CWD/examples/rdf/newsample.rdf -o $RESDIR/pars-p2.rdf +if [ -s $RESDIR/pars-p1.rdf ]; then diff $RESDIR/pars-p1.rdf $RESDIR/pars-p2.rdf; else echo error with PARS-PARS1; fi + +#------------------- +echo "\t-o <F>, --output <F>" +java -cp $CP fr.inrialpes.exmo.align.cli.ParserPrinter file://$CWD/examples/rdf/newsample.rdf -o $RESDIR/pars-o1.rdf +if [ -s $RESDIR/pars-o1.rdf ]; then diff $RESDIR/pars-o1.rdf $RESDIR/pars-noop.rdf; else echo error with PARS-OUTPUT0; fi +java -cp $CP fr.inrialpes.exmo.align.cli.ParserPrinter file://$CWD/examples/rdf/newsample.rdf --output $RESDIR/pars-output1.rdf +diff $RESDIR/pars-o1.rdf $RESDIR/pars-output1.rdf + +#------------------- +# This is for SPARQL OUTPUT +echo "\t-c,--outputDir <DIR>" +#java -cp $CP fr.inrialpes.exmo.align.cli.ParserPrinter file://$CWD/examples/rdf/newsample.rdf -w $RESDIR -o pars-o2.rdf +#java -cp $CP fr.inrialpes.exmo.align.cli.ParserPrinter file://$CWD/examples/rdf/newsample.rdf --output pars-output2.rdf --outputDir $RESDIR +#if [ -s $RESDIR/pars-o2.rdf ]; then diff $RESDIR/pars-o2.rdf $RESDIR/pars-output2.rdf; else echo error with PARS-OUTPUT2; fi + +#------------------- +echo "\t-i,--inverse" +java -cp $CP fr.inrialpes.exmo.align.cli.ParserPrinter file://$CWD/examples/rdf/newsample.rdf -i -o $RESDIR/pars-i.rdf +if [ -s $RESDIR/pars-i.rdf ]; then diff $RESDIR/pars-i.rdf $RESDIR/pars-noop.rdf > $RESDIR/diff-pars.txt; else echo error with PARS-INV1; fi +if [ ! -s $RESDIR/diff-pars.txt ]; then echo error with PARS-INV2; fi +java -cp $CP fr.inrialpes.exmo.align.cli.ParserPrinter file://$CWD/examples/rdf/newsample.rdf --inverse --output $RESDIR/pars-inverse.rdf +diff $RESDIR/pars-i.rdf $RESDIR/pars-inverse.rdf + +#------------------- +echo "\t-t,--threshold <DOUBLE>" +java -cp $CP fr.inrialpes.exmo.align.cli.ParserPrinter file://$CWD/examples/rdf/newsample.rdf -t .6 -o $RESDIR/pars-t1.rdf +if [ -s $RESDIR/pars-t1.rdf ]; then diff $RESDIR/pars-t1.rdf $RESDIR/pars-noop.rdf > $RESDIR/diff-thres.txt; else echo error with PARS-THRES1; fi +if [ ! -s $RESDIR/diff-thres.txt ]; then echo error with PARS-THRES2; fi +java -cp $CP fr.inrialpes.exmo.align.cli.ParserPrinter file://$CWD/examples/rdf/newsample.rdf --threshold .6 --output $RESDIR/pars-thres1.rdf +diff $RESDIR/pars-t1.rdf $RESDIR/pars-thres1.rdf + +#------------------- +echo "\t-T,--cutmethod <METHOD>" +java -cp $CP fr.inrialpes.exmo.align.cli.ParserPrinter file://$CWD/examples/rdf/newsample.rdf -T best -t .6 -o $RESDIR/pars-g1.rdf +if [ -s $RESDIR/pars-g1.rdf ]; then diff $RESDIR/pars-g1.rdf $RESDIR/pars-t1.rdf > $RESDIR/diff-gap.txt; else echo error with PARS-GAP1; fi +if [ ! -s $RESDIR/diff-gap.txt ]; then echo error with PARS-GAP2; fi +java -cp $CP fr.inrialpes.exmo.align.cli.ParserPrinter file://$CWD/examples/rdf/newsample.rdf --cutmethod best --threshold .6 --output $RESDIR/pars-gap1.rdf +diff $RESDIR/pars-g1.rdf $RESDIR/pars-gap1.rdf + +#------------------- +echo "\t-r,--renderer <CLASS>" +java -cp $CP fr.inrialpes.exmo.align.cli.ParserPrinter file://$CWD/examples/rdf/newsample.rdf -r fr.inrialpes.exmo.align.impl.renderer.OWLAxiomsRendererVisitor -o $RESDIR/pars-r1.rdf +if [ -s $RESDIR/pars-r1.rdf ]; then diff $RESDIR/pars-r1.rdf $RESDIR/pars-o1.rdf > $RESDIR/diff-rend.txt; else echo error with PARS-RENDER1; fi +if [ ! -s $RESDIR/diff-rend.txt ]; then echo error with PARS-RENDER2; fi +java -cp $CP fr.inrialpes.exmo.align.cli.ParserPrinter file://$CWD/examples/rdf/newsample.rdf --renderer fr.inrialpes.exmo.align.impl.renderer.OWLAxiomsRendererVisitor -o $RESDIR/pars-render1.rdf +diff $RESDIR/pars-r1.rdf $RESDIR/pars-render1.rdf + +#------------------- +echo "\t-Dn=v" +echo "\t(same as Procalign)" + +#------------------- +echo "\t-P,--params <FILE>" +echo "\t(same as Procalign)" + +######################################################################## +# EvalAlign +######################################################################## + +echo "\t\t *** Testing EvalAlign ***" + +#------------------- +echo "\t-d(<L>), --debug (<L>) DEPRECATED" + +#------------------- +echo "\t-z, -zzz" + +java -Dlog.level=INFO -cp $CP fr.inrialpes.exmo.align.cli.EvalAlign -z &> $RESDIR/zerr.txt +grep "Unrecognized option: -z" $RESDIR/zerr.txt > $RESDIR/err.txt +if [ ! -s $RESDIR/err.txt ]; then echo error with EVAL-ERR1; fi +java -Dlog.level=INFO -cp $CP fr.inrialpes.exmo.align.cli.EvalAlign --zzz &> $RESDIR/zzzerr.txt +grep "Unrecognized option: --zzz" $RESDIR/zzzerr.txt > $RESDIR/err.txt +if [ ! -s $RESDIR/err.txt ]; then echo error with EVAL-ERR2; fi + +#------------------- +echo "\t-h, --help" +java -cp $CP fr.inrialpes.exmo.align.cli.EvalAlign -h &> $RESDIR/eval-h.txt +java -cp $CP fr.inrialpes.exmo.align.cli.EvalAlign --help &> $RESDIR/eval-help.txt +# This should be put everywhere! +if [ -s $RESDIR/eval-h.txt ]; then diff $RESDIR/eval-h.txt $RESDIR/eval-help.txt; else echo error with EVAL-HELP1; fi + +#java -cp $CP fr.inrialpes.exmo.align.cli.EvalAlign -i fr.inrialpes.exmo.align.impl.eval.PRecEvaluator html/tutorial/refalign.rdf html/tutorial/refalign.rdf -o $RESDIR/eval-i.txt +#java -cp $CP fr.inrialpes.exmo.align.cli.EvalAlign --impl fr.inrialpes.exmo.align.impl.eval.PRecEvaluator html/tutorial/refalign.rdf html/tutorial/refalign.rdf --output $RESDIR/eval-impl.txt +#if [ -s $RESDIR/eval-i.txt ]; then diff $RESDIR/eval-i.txt $RESDIR/eval-impl.txt; else echo error with EVAL_HELP2; fi + +#------------------- +echo "\tno-op" +java -cp $CP fr.inrialpes.exmo.align.cli.EvalAlign file://$CWD/examples/rdf/newsample.rdf file://$RESDIR/proc-o1.rdf &> $RESDIR/eval-noop.xml +if [ ! -s $RESDIR/eval-noop.xml ]; then echo error with EVAL-NOOP; fi + +#------------------- +echo "\t-o <F>, --output <F>" +java -cp $CP fr.inrialpes.exmo.align.cli.EvalAlign file://$CWD/examples/rdf/newsample.rdf file://$RESDIR/proc-o1.rdf -o $RESDIR/eval-o1.xml +if [ -s $RESDIR/eval-o1.xml ]; then diff $RESDIR/eval-o1.xml $RESDIR/eval-noop.xml; else echo error with EVAL-OUT1; fi +java -cp $CP fr.inrialpes.exmo.align.cli.EvalAlign file://$CWD/examples/rdf/newsample.rdf file://$RESDIR/proc-o1.rdf --output $RESDIR/eval-out1.xml +diff $RESDIR/eval-out1.xml $RESDIR/eval-o1.xml + +#------------------- +echo "\t-i <C>, --impl <C>" +java -cp $CP fr.inrialpes.exmo.align.cli.EvalAlign -i fr.inrialpes.exmo.align.impl.eval.WeightedPREvaluator file://$CWD/examples/rdf/newsample.rdf file://$RESDIR/proc-o1.rdf -o $RESDIR/eval-i1.xml +if [ -s $RESDIR/eval-i1.xml ]; then diff $RESDIR/eval-o1.xml $RESDIR/eval-noop.xml > $RESDIR/diff-evimpl.txt ; else echo error with EVAL-IMPL1; fi +if [ ! -s $RESDIR/diff-rend.txt ]; then echo error with EVAL-IMPL2; fi +java -cp $CP fr.inrialpes.exmo.align.cli.EvalAlign --impl fr.inrialpes.exmo.align.impl.eval.WeightedPREvaluator file://$CWD/examples/rdf/newsample.rdf file://$RESDIR/proc-o1.rdf -o $RESDIR/eval-impl1.xml +diff $RESDIR/eval-impl1.xml $RESDIR/eval-i1.xml + +#------------------- +echo "\t-Dn=v" +echo "\t(same as Procalign)" + +#------------------- +echo "\t-P,--params <FILE>" +echo "\t(same as Procalign)" + +######################################################################## +# TestGen +######################################################################## + +echo "\t\t *** Testing TestGen ***" + +#java -Xmx1200m -cp $CP fr.inrialpes.exmo.align.cli.TestGen -u http://www.example.org/mynewtest -w $RESDIR/outtestdir -DremoveClasses=.25 examples/rdf/edu.umbc.ebiquity.publication.owl +# --> This one +#java -Xmx1200m -cp $CP fr.inrialpes.exmo.align.cli.TestGen -t fr.inrialpes.exmo.align.gen.BenchmarkGenerator -u http://www.example.org/mynewtest -w $RESDIR/outtestdir examples/rdf/edu.umbc.ebiquity.publication.owl +#$JAVA -Xmx1200m -cp $CP fr.inrialpes.exmo.align.cli.TestGen -t fr.inrialpes.exmo.align.gen.BenchmarkGenerator -u $URI/$run/ -w $DIR/r$run $seedonto + +#------------------- +echo "\t-z, -zzz" + +java -Dlog.level=INFO -cp $CP fr.inrialpes.exmo.align.cli.TestGen -z &> $RESDIR/zerr.txt +grep "Unrecognized option: -z" $RESDIR/zerr.txt > $RESDIR/err.txt +if [ ! -s $RESDIR/err.txt ]; then echo error with GEN-ERR1; fi +java -Dlog.level=INFO -cp $CP fr.inrialpes.exmo.align.cli.TestGen --zzz &> $RESDIR/zzzerr.txt +grep "Unrecognized option: --zzz" $RESDIR/zzzerr.txt > $RESDIR/err.txt +if [ ! -s $RESDIR/err.txt ]; then echo error with GEN-ERR2; fi + +#------------------- +echo "\t-h, --help" +java -cp $CP fr.inrialpes.exmo.align.cli.TestGen -h &> $RESDIR/test-h.txt +java -cp $CP fr.inrialpes.exmo.align.cli.TestGen --help &> $RESDIR/test-help.txt +if [ -s $RESDIR/test-h.txt ]; then diff $RESDIR/test-h.txt $RESDIR/test-help.txt; else echo error with TEST-HELP; fi + +#------------------- +echo "\t-u,--urlprefix <URI> --uriprefix" +mkdir $RESDIR/smalltest +mkdir $RESDIR/smalltest/gentestempty1 +cd $RESDIR/smalltest/gentestempty1 +java -Xmx1200m -cp $CP fr.inrialpes.exmo.align.cli.TestGen -u http://www.example.org/mynewtest $CWD/examples/rdf/edu.umbc.ebiquity.publication.owl +if [ ! -s refalign.rdf ]; then echo error with GEN-EMP1; fi +if [ ! -s onto.rdf ]; then echo error with GEN-EMP2; fi +mkdir $RESDIR/smalltest/gentestempty2 +cd $RESDIR/smalltest/gentestempty2 +java -Xmx1200m -cp $CP fr.inrialpes.exmo.align.cli.TestGen --uriprefix http://www.example.org/mynewtest2 $CWD/examples/rdf/edu.umbc.ebiquity.publication.owl +if [ -s refalign.rdf ]; then diff refalign.rdf $RESDIR/smalltest/gentestempty1/refalign.rdf > gendiff.txt; else echo error with GEN-EMP3; fi +if [ ! -s gendiff.txt ]; then echo error with GEN-EMP4; fi +if [ -s onto.rdf ]; then diff onto.rdf $RESDIR/smalltest/gentestempty1/onto.rdf > gendiff.txt; else echo error with GEN-EMP5; fi +if [ ! -s gendiff.txt ]; then echo error with GEN-EMP6; fi +cd $CWD + +#------------------- +echo "\t-w,--outdir <DIR>" +java -Xmx1200m -cp $CP fr.inrialpes.exmo.align.cli.TestGen -u http://www.example.org/mynewtest -w $RESDIR/smalltest/outtestdir1 examples/rdf/edu.umbc.ebiquity.publication.owl +java -Xmx1200m -cp $CP fr.inrialpes.exmo.align.cli.TestGen -u http://www.example.org/mynewtest --outdir $RESDIR/smalltest/outtestdir2 examples/rdf/edu.umbc.ebiquity.publication.owl +#if [ -s $RESDIR/smalltest/outtestdir1/onto.rdf ]; then diff $RESDIR/smalltest/outtestdir1/onto.rdf $RESDIR/smalltest/outtestdir2/onto.rdf; else echo error with GEN-OUT1; fi +if [ -s $RESDIR/smalltest/outtestdir1/refalign.rdf ]; then diff $RESDIR/smalltest/outtestdir1/refalign.rdf $RESDIR/smalltest/outtestdir2/refalign.rdf; else echo error with GEN-OUT2; fi + +#------------------- +echo "\t-Dn=v" +java -Xmx1200m -cp $CP fr.inrialpes.exmo.align.cli.TestGen -u http://www.example.org/mynewtest -DremoveClasses=.25 -w $RESDIR/smalltest/outtestdir3 examples/rdf/edu.umbc.ebiquity.publication.owl +# Here we can do with many parameters +if [ -s $RESDIR/smalltest/outtestdir3/onto.rdf ]; then diff $RESDIR/smalltest/outtestdir1/refalign.rdf $RESDIR/smalltest/outtestdir3/refalign.rdf > $RESDIR/smalltest/outtestdir2/gendiff.txt ; else echo error with GEN-OUT3; fi +if [ ! -s $RESDIR/smalltest/outtestdir2/gendiff.txt ]; then echo error with GEN-VAR1; fi + +#------------------- +echo "\t-a,--alignname <FILE> " +echo "\t-o,--output <FILE>" +java -Xmx1200m -cp $CP fr.inrialpes.exmo.align.cli.TestGen -u http://www.example.org/mynewtest -a myalign.rdf -o biblio.owl -w $RESDIR/outtestdir4 examples/rdf/edu.umbc.ebiquity.publication.owl +java -Xmx1200m -cp $CP fr.inrialpes.exmo.align.cli.TestGen -u http://www.example.org/mynewtest --alignname myalign.rdf --output biblio.owl -w $RESDIR/outtestdir5 examples/rdf/edu.umbc.ebiquity.publication.owl +if [ -s $RESDIR/outtestdir4/biblio.owl ]; then diff $RESDIR/outtestdir5/biblio.owl $RESDIR/outtestdir4/biblio.owl; else echo error with GEN-OUT1; fi +if [ -s $RESDIR/outtestdir4/myalign.rdf ]; then diff $RESDIR/outtestdir5/myalign.rdf $RESDIR/outtestdir4/myalign.rdf; else echo error with GEN-AL1; fi +diff $RESDIR/outtestdir5/myalign.rdf $RESDIR/smalltest/outtestdir1/refalign.rdf > $RESDIR/outtestdir5/gendiff.txt +if [ ! -s $RESDIR/outtestdir5/gendiff.txt ]; then echo error with GEN-AL2; fi + +#------------------- +echo "\t-t,--testset <CLASS>" +mkdir $RESDIR/outtestdir +java -Xmx1200m -cp $CP fr.inrialpes.exmo.align.cli.TestGen -t fr.inrialpes.exmo.align.gen.BenchmarkGenerator -u http://www.example.org/mynewtest -w $RESDIR/outtestdir examples/rdf/edu.umbc.ebiquity.publication.owl +mkdir $RESDIR/outtestdir9 +java -Xmx1200m -cp $CP fr.inrialpes.exmo.align.cli.TestGen --testset fr.inrialpes.exmo.align.gen.BenchmarkGenerator --uriprefix http://www.example.org/mynewtest --outdir $RESDIR/outtestdir9 examples/rdf/edu.umbc.ebiquity.publication.owl +if [ -s $RESDIR/outtestdir9/266/onto.rdf ]; then diff $RESDIR/outtestdir/266/onto.rdf $RESDIR/outtestdir9/266/onto.rdf > $RESDIR/outtestdir9/gendiff.txt; else echo error with GEN-TSET1; fi +if [ ! -s $RESDIR/outtestdir9/gendiff.txt ]; then echo error with GEN-TSET2; fi + +#------------------- +echo "\t-P,--params <FILE>" +echo "\t(same as Procalign)" + +######################################################################## +# GroupAlign +######################################################################## + +# ADJUSTED Because otherwise --alignment below does not work + +for i in `cd $RESDIR/smalltest/; ls -d */` +do +sed -i '' "s;<location>http://ebiquity.umbc.edu/v2.1/ontology/publication.owl#</location>;<location>file://$RESDIR/smalltest/gentestempty1/onto1.rdf</location>;" $RESDIR/smalltest/${i}refalign.rdf +sed -i '' "s;<location>http://www.example.org/mynewtest/onto.rdf#</location>;<location>file://$RESDIR/smalltest/${i}onto.rdf</location>;" $RESDIR/smalltest/${i}refalign.rdf +sed -i '' "s;http://ebiquity.umbc.edu/v2.1/ontology/publication.owl#;http://www.example.org/mynewtest/101/onto.rdf#;" $RESDIR/smalltest/${i}refalign.rdf +done + +echo "\t\t *** Testing GroupAlign ***" + +cp $RESDIR/outtestdir/101/onto.rdf $RESDIR/smalltest/gentestempty1/onto1.rdf +cp $RESDIR/outtestdir/101/onto.rdf $RESDIR/smalltest/gentestempty2/onto1.rdf +cp $RESDIR/outtestdir/101/onto.rdf $RESDIR/smalltest/outtestdir1/onto1.rdf +cp $RESDIR/outtestdir/101/onto.rdf $RESDIR/smalltest/outtestdir2/onto1.rdf +cp $RESDIR/outtestdir/101/onto.rdf $RESDIR/smalltest/outtestdir3/onto1.rdf + +#------------------- +echo "\tEMPTY" +java -cp $CP fr.inrialpes.exmo.align.cli.GroupAlign + +#------------------- +echo "\t-z, -zzz" + +java -Dlog.level=INFO -cp $CP fr.inrialpes.exmo.align.cli.GroupAlign -z &> $RESDIR/zerr.txt +grep "Unrecognized option: -z" $RESDIR/zerr.txt > $RESDIR/err.txt +if [ ! -s $RESDIR/err.txt ]; then echo error with GRAL-ERR1; fi +java -Dlog.level=INFO -cp $CP fr.inrialpes.exmo.align.cli.GroupAlign --zzz &> $RESDIR/zzzerr.txt +grep "Unrecognized option: --zzz" $RESDIR/zzzerr.txt > $RESDIR/err.txt +if [ ! -s $RESDIR/err.txt ]; then echo error with GRAL-ERR2; fi + +#------------------- +echo "\t-h, --help" +java -cp $CP fr.inrialpes.exmo.align.cli.GroupAlign -h &> $RESDIR/gral-h.txt +java -cp $CP fr.inrialpes.exmo.align.cli.GroupAlign --help &> $RESDIR/gral-help.txt +if [ -s $RESDIR/gral-h.txt ]; then diff $RESDIR/gral-h.txt $RESDIR/gral-help.txt; else echo error with GRAL-HELP; fi + +#------------------- +echo "\t-w,--directory <DIR>" +echo "\t-o <F>, --output <F>" +java -cp $CP fr.inrialpes.exmo.align.cli.GroupAlign -w $RESDIR/smalltest -o streq1.rdf +java -cp $CP fr.inrialpes.exmo.align.cli.GroupAlign --directory $RESDIR/smalltest --output streq2.rdf +sed -i '' "s;<time>[^<]*</time>;;g" $RESDIR/smalltest/gentestempty1/streq1.rdf +sed -i '' "s;<time>[^<]*</time>;;g" $RESDIR/smalltest/gentestempty1/streq2.rdf +if [ -s $RESDIR/smalltest/gentestempty1/streq1.rdf ]; then diff $RESDIR/smalltest/gentestempty1/streq1.rdf $RESDIR/smalltest/gentestempty1/streq2.rdf > $RESDIR/smalltest/diffstreq.txt ; else echo error with GRAL-DIR1; fi +if [ -s $RESDIR/smalltest/diffstreq.txt ]; then echo error with GRAL-DIR2; fi + +#------------------- +echo "\t-i <C>, --impl <C>" +java -cp $CP fr.inrialpes.exmo.align.cli.GroupAlign -i fr.inrialpes.exmo.align.impl.method.EditDistNameAlignment -w $RESDIR/smalltest -o edna1.rdf +sed -i '' "s;<time>[^<]*</time>;;g" $RESDIR/smalltest/gentestempty1/edna1.rdf +if [ -s $RESDIR/smalltest/gentestempty1/edna1.rdf ]; then diff $RESDIR/smalltest/gentestempty1/edna1.rdf $RESDIR/smalltest/gentestempty1/streq2.rdf > $RESDIR/smalltest/diffstredna.txt ; else echo error with GRAL-IMPL1; fi +if [ ! -s $RESDIR/smalltest/diffstredna.txt ]; then echo error with GRAL-IMPL2; fi +java -cp $CP fr.inrialpes.exmo.align.cli.GroupAlign --impl fr.inrialpes.exmo.align.impl.method.EditDistNameAlignment -w $RESDIR/smalltest -o edna2.rdf +sed -i '' "s;<time>[^<]*</time>;;g" $RESDIR/smalltest/gentestempty1/edna2.rdf +if [ -s $RESDIR/smalltest/gentestempty1/edna2.rdf ]; then diff $RESDIR/smalltest/gentestempty1/edna1.rdf $RESDIR/smalltest/gentestempty1/edna2.rdf > $RESDIR/smalltest/diffedna.txt ; else echo error with GRAL-IMPL3; fi +if [ -s $RESDIR/smalltest/diffedna.txt ]; then echo error with GRAL-IMPL4; fi + +#------------------- +# This test in fact does not work because there are too many 1. values. +# I have checked that it works independently (add a bad distance name!) +echo "\t-Dn=v" + +java -cp $CP fr.inrialpes.exmo.align.cli.GroupAlign -i fr.inrialpes.exmo.align.impl.method.StringDistAlignment -DstringFunction=levenshteinDistance -w $RESDIR/smalltest -o lev1.rdf +sed -i '' "s;<time>[^<]*</time>;;g" $RESDIR/smalltest/gentestempty1/lev1.rdf +if [ -s $RESDIR/smalltest/gentestempty1/lev1.rdf ]; then diff $RESDIR/smalltest/gentestempty1/edna1.rdf $RESDIR/smalltest/gentestempty1/lev1.rdf > $RESDIR/smalltest/diffstredna.txt ; else echo error with GRAL-DV1; fi +if [ ! -s $RESDIR/smalltest/diffstredna.txt ]; then echo error with GRAL-DV2; fi + +#------------------- + +echo "\t-a,--alignment <FILE> " +java -cp $CP fr.inrialpes.exmo.align.cli.GroupAlign -a refalign.rdf -w $RESDIR/smalltest -o streq1a.rdf +java -cp $CP fr.inrialpes.exmo.align.cli.GroupAlign --alignment refalign.rdf --directory $RESDIR/smalltest --output streq2a.rdf +sed -i '' "s;<time>[^<]*</time>;;g" $RESDIR/smalltest/gentestempty1/streq1a.rdf +sed -i '' "s;<time>[^<]*</time>;;g" $RESDIR/smalltest/gentestempty1/streq2a.rdf +if [ -s $RESDIR/smalltest/gentestempty1/streq1a.rdf ]; then diff $RESDIR/smalltest/gentestempty1/streq1a.rdf $RESDIR/smalltest/gentestempty1/streq2a.rdf > $RESDIR/smalltest/diffstreqa.txt ; else echo error with GRAL-AL1; fi +if [ -s $RESDIR/smalltest/diffstreqa.txt ]; then echo error with GRAL-AL2; fi + +#------------------- +echo "\t-n,--name <URI>" +java -cp $CP fr.inrialpes.exmo.align.cli.GroupAlign -n file://$RESDIR/outtestdir/101/onto.rdf -w $RESDIR/smalltest -o streq1n.rdf +java -cp $CP fr.inrialpes.exmo.align.cli.GroupAlign --name file://$RESDIR/outtestdir/101/onto.rdf --directory $RESDIR/smalltest --output streq2n.rdf +sed -i '' "s;<time>[^<]*</time>;;g" $RESDIR/smalltest/gentestempty1/streq1n.rdf +sed -i '' "s;<time>[^<]*</time>;;g" $RESDIR/smalltest/gentestempty1/streq2n.rdf +if [ -s $RESDIR/smalltest/gentestempty1/streq1n.rdf ]; then diff $RESDIR/smalltest/gentestempty1/streq1n.rdf $RESDIR/smalltest/gentestempty1/streq2n.rdf > $RESDIR/smalltest/diffstreqn.txt ; else echo error with GRAL-NAME1; fi +if [ -s $RESDIR/smalltest/diffstreqn.txt ]; then echo error with GRAL-NAME2; fi + +#------------------- +echo "\t-r,--renderer <CLASS>" +java -cp $CP fr.inrialpes.exmo.align.cli.GroupAlign -r fr.inrialpes.exmo.align.impl.renderer.HTMLRendererVisitor -w $RESDIR/smalltest -o streq1.html +java -cp $CP fr.inrialpes.exmo.align.cli.GroupAlign --renderer fr.inrialpes.exmo.align.impl.renderer.HTMLRendererVisitor --directory $RESDIR/smalltest --output streq2.html +sed -i '' "s;time</td><td property=\"align:time\">[^<]*;;g" $RESDIR/smalltest/gentestempty1/streq1.html +sed -i '' "s;time</td><td property=\"align:time\">[^<]*;;g" $RESDIR/smalltest/gentestempty1/streq2.html +if [ -s $RESDIR/smalltest/gentestempty1/streq1.html ]; then diff $RESDIR/smalltest/gentestempty1/streq1.html $RESDIR/smalltest/gentestempty1/streq2.html ; else echo error with GRAL-RENDER1; fi + +#------------------- +echo "\t-s,--source <FILE>" +echo "\t-t,--target <FILE>" +java -cp $CP fr.inrialpes.exmo.align.cli.GroupAlign -s onto.rdf -t onto1.rdf -w $RESDIR/smalltest -o streq1x.rdf +sed -i '' "s;<time>[^<]*</time>;;g" $RESDIR/smalltest/gentestempty1/streq1x.rdf +if [ -s $RESDIR/smalltest/gentestempty1/streq1x.rdf ]; then diff $RESDIR/smalltest/gentestempty1/streq1x.rdf $RESDIR/smalltest/gentestempty1/streq2n.rdf > $RESDIR/smalltest/diffstreqxn.txt ; else echo error with GRAL-ST1; fi +if [ ! -s $RESDIR/smalltest/diffstreqxn.txt ]; then echo error with GRAL-ST2; fi +java -cp $CP fr.inrialpes.exmo.align.cli.GroupAlign --source onto.rdf --target onto1.rdf --directory $RESDIR/smalltest --output streq2x.rdf +sed -i '' "s;<time>[^<]*</time>;;g" $RESDIR/smalltest/gentestempty1/streq2x.rdf +if [ -s $RESDIR/smalltest/gentestempty1/streq1x.rdf ]; then diff $RESDIR/smalltest/gentestempty1/streq1x.rdf $RESDIR/smalltest/gentestempty1/streq2x.rdf ; else echo error with GRAL-ST3; fi + +#------------------- +echo "\t-u,--uriprefix <URI>" + +ln -s /tmp/clitest/smalltest /tmp/clitest/preftest + +java -cp $CP fr.inrialpes.exmo.align.cli.GroupAlign -w $RESDIR/smalltest -u file:///tmp/clitest/preftest -o strpr1.rdf +java -cp $CP fr.inrialpes.exmo.align.cli.GroupAlign --directory $RESDIR/smalltest --uriprefix file:///tmp/clitest/preftest --output strpr2.rdf +sed -i '' "s;<time>[^<]*</time>;;g" $RESDIR/smalltest/gentestempty1/strpr1.rdf +sed -i '' "s;<time>[^<]*</time>;;g" $RESDIR/smalltest/gentestempty1/strpr2.rdf +if [ -s $RESDIR/smalltest/gentestempty1/strpr1.rdf ]; then diff $RESDIR/smalltest/gentestempty1/strpr1.rdf $RESDIR/smalltest/gentestempty1/strpr2.rdf > $RESDIR/smalltest/diffpref.txt ; else echo error with GRAL-PR1; fi +if [ -s $RESDIR/smalltest/diffpref.txt ]; then echo error with GRAL-PR2; fi +java -cp $CP fr.inrialpes.exmo.align.cli.GroupAlign -w $RESDIR/smalltest -u file:///tmp/clitest/dummy -o strpr3.rdf +if [ -s $RESDIR/smalltest/gentestempty1/strpr3.rdf ]; then echo error with GRAL-PR3; fi + +#------------------- +echo "\t-P,--params <FILE>" +echo "\t(same as Procalign)" + +######################################################################## +# GroupEval +######################################################################## + +echo "\t\t *** Testing GroupEval ***" + +#------------------- +echo "\t-z, -zzz" + +java -Dlog.level=INFO -cp $CP fr.inrialpes.exmo.align.cli.GroupEval -z &> $RESDIR/zerr.txt +grep "Unrecognized option: -z" $RESDIR/zerr.txt > $RESDIR/err.txt +if [ ! -s $RESDIR/err.txt ]; then echo error with GREV-ERR1; fi +java -Dlog.level=INFO -cp $CP fr.inrialpes.exmo.align.cli.GroupEval --zzz &> $RESDIR/zzzerr.txt +grep "Unrecognized option: --zzz" $RESDIR/zzzerr.txt > $RESDIR/err.txt +if [ ! -s $RESDIR/err.txt ]; then echo error with GREV-ERR2; fi + +#------------------- +echo "\t-h, --help" + +java -cp $CP fr.inrialpes.exmo.align.cli.GroupEval -h &> $RESDIR/groupeval-h.txt +java -cp $CP fr.inrialpes.exmo.align.cli.GroupEval --help &> $RESDIR/groupeval-help.txt +if [ -s $RESDIR/groupeval-h.txt ]; then diff $RESDIR/groupeval-h.txt $RESDIR/groupeval-help.txt; else echo error with GREVAL-HELP; fi + +#------------------- +echo "\t-l,--list <FILE>" + +cd $RESDIR/smalltest +java -cp $CP fr.inrialpes.exmo.align.cli.GroupEval -l "refalign,lev1,streq1" > groupeval-l1.html +if [ ! -s groupeval-l1.html ]; then echo error with GREV-LIST1; fi +java -cp $CP fr.inrialpes.exmo.align.cli.GroupEval --list "refalign,lev1,streq1" > groupeval-l2.html +if [ -s groupeval-l2.html ]; then diff groupeval-l1.html groupeval-l2.html ; else echo error with GREV-LIST2; fi +cd $CWD + +#------------------- +echo "\t-w,--directory <DIR>" + +java -cp $CP fr.inrialpes.exmo.align.cli.GroupEval -l "refalign,edna1,streq1,streq1n,streq1x,streq2,streq2n,streq2x,lev1" -w $RESDIR/smalltest > $RESDIR/groupeval-w1.html +if [ -s $RESDIR/groupeval-w1.html ]; then diff $RESDIR/groupeval-w1.html $RESDIR/smalltest/groupeval-l1.html > $RESDIR/smalltest/diffgrev-w1.txt ; else echo error with GREV-DIR1; fi +if [ ! -s $RESDIR/smalltest/diffgrev-w1.txt ]; then echo error with GREV-DIR2; fi +java -cp $CP fr.inrialpes.exmo.align.cli.GroupEval -l "refalign,edna1,streq1,streq1n,streq1x,streq2,streq2n,streq2x,lev1" --directory $RESDIR/smalltest > $RESDIR/groupeval-w2.html +if [ -s $RESDIR/groupeval-w2.html ]; then diff $RESDIR/groupeval-w1.html $RESDIR/groupeval-w2.html ; else echo error with GREV-DIR3; fi + +#------------------- +echo "\t-o <F>, --output <F>" + +java -cp $CP fr.inrialpes.exmo.align.cli.GroupEval -l "refalign,edna1,streq1,streq1n,streq1x,streq2,streq2n,streq2x,lev1" -w $RESDIR/smalltest -o $RESDIR/groupeval-o1.html +if [ -s $RESDIR/groupeval-o1.html ]; then diff $RESDIR/groupeval-o1.html $RESDIR/groupeval-w1.html ; else echo error with GREV-OUT1; fi +java -cp $CP fr.inrialpes.exmo.align.cli.GroupEval -l "refalign,edna1,streq1,streq1n,streq1x,streq2,streq2n,streq2x,lev1" -w $RESDIR/smalltest --output $RESDIR/groupeval-o2.html +if [ -s $RESDIR/groupeval-o2.html ]; then diff $RESDIR/groupeval-o1.html $RESDIR/groupeval-o2.html ; else echo error with GREV-OUT3; fi + +#------------------- +echo "\t-f,--format <MEAS>" + +java -cp $CP fr.inrialpes.exmo.align.cli.GroupEval -f f -l "refalign,edna1,streq1,streq1n,streq1x,streq2,streq2n,streq2x,lev1" -w $RESDIR/smalltest > $RESDIR/groupeval-f1.html +if [ -s $RESDIR/groupeval-f1.html ]; then diff $RESDIR/groupeval-w1.html $RESDIR/groupeval-f1.html > $RESDIR/smalltest/diffgrev-f1.txt ; else echo error with GREV-FORM1; fi +if [ ! -s $RESDIR/smalltest/diffgrev-f1.txt ]; then echo error with GREV-FORM2; fi +java -cp $CP fr.inrialpes.exmo.align.cli.GroupEval --format f -l "refalign,edna1,streq1,streq1n,streq1x,streq2,streq2n,streq2x,lev1" -w $RESDIR/smalltest > $RESDIR/groupeval-f2.html +if [ -s $RESDIR/groupeval-f2.html ]; then diff $RESDIR/groupeval-f1.html $RESDIR/groupeval-f2.html ; else echo error with GREV-FORM3; fi + +#------------------- +echo "\t-c,--color (<COLOR>)" + +java -cp $CP fr.inrialpes.exmo.align.cli.GroupEval -c -l "refalign,edna1,streq1,streq1n,streq1x,streq2,streq2n,streq2x,lev1" -w $RESDIR/smalltest > $RESDIR/groupeval-c1.html +if [ -s $RESDIR/groupeval-c1.html ]; then diff $RESDIR/groupeval-w1.html $RESDIR/groupeval-c1.html > $RESDIR/smalltest/diffgrev-c1.txt ; else echo error with GREV-COL1; fi +if [ ! -s $RESDIR/smalltest/diffgrev-c1.txt ]; then echo error with GREV-COL2; fi +java -cp $CP fr.inrialpes.exmo.align.cli.GroupEval --color -l "refalign,edna1,streq1,streq1n,streq1x,streq2,streq2n,streq2x,lev1" -w $RESDIR/smalltest > $RESDIR/groupeval-c2.html +if [ -s $RESDIR/groupeval-c2.html ]; then diff $RESDIR/groupeval-c1.html $RESDIR/groupeval-c2.html ; else echo error with GREV-COL3; fi + +#------------------- +echo "\t-r,--reference <FILE>" +java -cp $CP fr.inrialpes.exmo.align.cli.GroupEval -r lev1.rdf -l "refalign,edna1,streq1,streq1n,streq1x,streq2,streq2n,streq2x,lev1" -w $RESDIR/smalltest -o $RESDIR/groupeval-r1.html +if [ -s $RESDIR/groupeval-r1.html ]; then diff $RESDIR/groupeval-w1.html $RESDIR/groupeval-r1.html > $RESDIR/smalltest/diffgrev-r1.txt ; else echo error with GREV-REF1; fi +if [ ! -s $RESDIR/smalltest/diffgrev-r1.txt ]; then echo error with GREV-REF2; fi +java -cp $CP fr.inrialpes.exmo.align.cli.GroupEval --reference lev1.rdf -l "refalign,edna1,streq1,streq1n,streq1x,streq2,streq2n,streq2x,lev1" -w $RESDIR/smalltest -o $RESDIR/groupeval-r2.html +if [ -s $RESDIR/groupeval-r2.html ]; then diff $RESDIR/groupeval-r1.html $RESDIR/groupeval-r2.html ; else echo error with GREV-REF3; fi + +#------------------- +echo "\t-t,--type <TYPE> Output TYPE (html|xml|tex|ascii|triangle" +java -cp $CP fr.inrialpes.exmo.align.cli.GroupEval -t triangle -l "refalign,edna1,streq1,streq1n,streq1x,streq2,streq2n,streq2x,lev1" -w $RESDIR/smalltest -o $RESDIR/groupeval-ttr1.tex +if [ -s $RESDIR/groupeval-ttr1.tex ]; then diff $RESDIR/groupeval-w1.html $RESDIR/groupeval-ttr1.tex > $RESDIR/smalltest/diffgrev-t1.txt ; else echo error with GREV-TYP1; fi +if [ ! -s $RESDIR/smalltest/diffgrev-t1.txt ]; then echo error with GREV-TYP2; fi +java -cp $CP fr.inrialpes.exmo.align.cli.GroupEval --type triangle -l "refalign,edna1,streq1,streq1n,streq1x,streq2,streq2n,streq2x,lev1" -w $RESDIR/smalltest -o $RESDIR/groupeval-ttr2.tex +if [ -s $RESDIR/groupeval-ttr2.tex ]; then diff $RESDIR/groupeval-ttr1.tex $RESDIR/groupeval-ttr2.tex ; else echo error with GREV-TYP3; fi + +#------------------- +echo "\t-Dn=v" +echo "\t(same as Procalign; useless: no parameters involved so far)" + +#------------------- +echo "\t-P,--params <FILE>" +echo "\t(same as Procalign; useless: no parameters involved so far)" + +######################################################################## +# WGroupEval +######################################################################## + +echo "\t\t *** Testing WGroupEval ***" + +#------------------- +echo "\t-z, -zzz" + +java -Dlog.level=INFO -cp $CP fr.inrialpes.exmo.align.cli.WGroupEval -z &> $RESDIR/zerr.txt +grep "Unrecognized option: -z" $RESDIR/zerr.txt > $RESDIR/err.txt +if [ ! -s $RESDIR/err.txt ]; then echo error with WGREV-ERR1; fi +java -Dlog.level=INFO -cp $CP fr.inrialpes.exmo.align.cli.WGroupEval --zzz &> $RESDIR/zzzerr.txt +grep "Unrecognized option: --zzz" $RESDIR/zzzerr.txt > $RESDIR/err.txt +if [ ! -s $RESDIR/err.txt ]; then echo error with WGREV-ERR2; fi + +#------------------- +echo "\t-h, --help" + +java -cp $CP fr.inrialpes.exmo.align.cli.WGroupEval -h &> $RESDIR/wgrev-h.txt +java -cp $CP fr.inrialpes.exmo.align.cli.WGroupEval --help &> $RESDIR/wgrev-help.txt +if [ -s $RESDIR/wgrev-h.txt ]; then diff $RESDIR/wgrev-h.txt $RESDIR/wgrev-help.txt; else echo error with WGREV-HELP; fi + +#------------------- +echo "\t-l,--list <FILE>" + +cd $RESDIR/smalltest +java -cp $CP fr.inrialpes.exmo.align.cli.WGroupEval -l "refalign,lev1,streq1" > wgrev-l1.html +if [ ! -s wgrev-l1.html ]; then echo error with WGREV-LIST1; fi +java -cp $CP fr.inrialpes.exmo.align.cli.WGroupEval --list "refalign,lev1,streq1" > wgrev-l2.html +if [ -s wgrev-l2.html ]; then diff wgrev-l1.html wgrev-l2.html ; else echo error with WGREV-LIST2; fi +cd $CWD + +#------------------- +echo "\t-w,--directory <DIR>" + +java -cp $CP fr.inrialpes.exmo.align.cli.WGroupEval -l "refalign,edna1,streq1,streq1n,streq1x,streq2,streq2n,streq2x,lev1" -w $RESDIR/smalltest > $RESDIR/wgrev-w1.html +if [ -s $RESDIR/wgrev-w1.html ]; then diff $RESDIR/wgrev-w1.html $RESDIR/smalltest/wgrev-l1.html > $RESDIR/smalltest/diffgrev-w1.txt ; else echo error with WGREV-DIR1; fi +if [ ! -s $RESDIR/smalltest/diffgrev-w1.txt ]; then echo error with WGREV-DIR2; fi +java -cp $CP fr.inrialpes.exmo.align.cli.WGroupEval -l "refalign,edna1,streq1,streq1n,streq1x,streq2,streq2n,streq2x,lev1" --directory $RESDIR/smalltest > $RESDIR/wgrev-w2.html +if [ -s $RESDIR/wgrev-w2.html ]; then diff $RESDIR/wgrev-w1.html $RESDIR/wgrev-w2.html ; else echo error with WGREV-DIR3; fi + +#------------------- +echo "\t-o <F>, --output <F>" + +java -cp $CP fr.inrialpes.exmo.align.cli.WGroupEval -l "refalign,edna1,streq1,streq1n,streq1x,streq2,streq2n,streq2x,lev1" -w $RESDIR/smalltest -o $RESDIR/wgrev-o1.html +if [ -s $RESDIR/wgrev-o1.html ]; then diff $RESDIR/wgrev-o1.html $RESDIR/wgrev-w1.html ; else echo error with WGREV-OUT1; fi +java -cp $CP fr.inrialpes.exmo.align.cli.WGroupEval -l "refalign,edna1,streq1,streq1n,streq1x,streq2,streq2n,streq2x,lev1" -w $RESDIR/smalltest --output $RESDIR/wgrev-o2.html +if [ -s $RESDIR/wgrev-o2.html ]; then diff $RESDIR/wgrev-o1.html $RESDIR/wgrev-o2.html ; else echo error with WGREV-OUT3; fi + +#------------------- +echo "\t-f,--format <MEAS>" + +java -cp $CP fr.inrialpes.exmo.align.cli.WGroupEval -f f -l "refalign,edna1,streq1,streq1n,streq1x,streq2,streq2n,streq2x,lev1" -w $RESDIR/smalltest > $RESDIR/wgrev-f1.html +if [ -s $RESDIR/wgrev-f1.html ]; then diff $RESDIR/wgrev-w1.html $RESDIR/wgrev-f1.html > $RESDIR/smalltest/diffgrev-f1.txt ; else echo error with WGREV-FORM1; fi +if [ ! -s $RESDIR/smalltest/diffgrev-f1.txt ]; then echo error with WGREV-FORM2; fi +java -cp $CP fr.inrialpes.exmo.align.cli.WGroupEval --format f -l "refalign,edna1,streq1,streq1n,streq1x,streq2,streq2n,streq2x,lev1" -w $RESDIR/smalltest > $RESDIR/wgrev-f2.html +if [ -s $RESDIR/wgrev-f2.html ]; then diff $RESDIR/wgrev-f1.html $RESDIR/wgrev-f2.html ; else echo error with WGREV-FORM3; fi + +#------------------- +echo "\t-c,--color (<COLOR>)" + +java -cp $CP fr.inrialpes.exmo.align.cli.WGroupEval -c -l "refalign,edna1,streq1,streq1n,streq1x,streq2,streq2n,streq2x,lev1" -w $RESDIR/smalltest > $RESDIR/wgrev-c1.html +if [ -s $RESDIR/wgrev-c1.html ]; then diff $RESDIR/wgrev-w1.html $RESDIR/wgrev-c1.html > $RESDIR/smalltest/diffgrev-c1.txt ; else echo error with WGREV-COL1; fi +if [ ! -s $RESDIR/smalltest/diffgrev-c1.txt ]; then echo error with WGREV-COL2; fi +java -cp $CP fr.inrialpes.exmo.align.cli.WGroupEval --color -l "refalign,edna1,streq1,streq1n,streq1x,streq2,streq2n,streq2x,lev1" -w $RESDIR/smalltest > $RESDIR/wgrev-c2.html +if [ -s $RESDIR/wgrev-c2.html ]; then diff $RESDIR/wgrev-c1.html $RESDIR/wgrev-c2.html ; else echo error with WGREV-COL3; fi + +#------------------- +echo "\t-r,--reference <FILE>" +java -cp $CP fr.inrialpes.exmo.align.cli.WGroupEval -r lev1.rdf -l "refalign,edna1,streq1,streq1n,streq1x,streq2,streq2n,streq2x,lev1" -w $RESDIR/smalltest -o $RESDIR/wgrev-r1.html +if [ -s $RESDIR/wgrev-r1.html ]; then diff $RESDIR/wgrev-w1.html $RESDIR/wgrev-r1.html > $RESDIR/smalltest/diffgrev-r1.txt ; else echo error with WGREV-REF1; fi +if [ ! -s $RESDIR/smalltest/diffgrev-r1.txt ]; then echo error with WGREV-REF2; fi +java -cp $CP fr.inrialpes.exmo.align.cli.WGroupEval --reference lev1.rdf -l "refalign,edna1,streq1,streq1n,streq1x,streq2,streq2n,streq2x,lev1" -w $RESDIR/smalltest -o $RESDIR/wgrev-r2.html +if [ -s $RESDIR/wgrev-r2.html ]; then diff $RESDIR/wgrev-r1.html $RESDIR/wgrev-r2.html ; else echo error with WGREV-REF3; fi + +#------------------- +echo "\t-t,--type <TYPE> Output TYPE (html|xml|tex|ascii|triangle)" +java -cp $CP fr.inrialpes.exmo.align.cli.WGroupEval -t triangle -l "refalign,edna1,streq1,streq1n,streq1x,streq2,streq2n,streq2x,lev1" -w $RESDIR/smalltest -o $RESDIR/wgrev-ttr1.tex +if [ -s $RESDIR/wgrev-ttr1.tex ]; then diff $RESDIR/wgrev-w1.html $RESDIR/wgrev-ttr1.tex > $RESDIR/smalltest/diffgrev-t1.txt ; else echo error with WGREV-TYP1; fi +if [ ! -s $RESDIR/smalltest/diffgrev-t1.txt ]; then echo error with WGREV-TYP2; fi +java -cp $CP fr.inrialpes.exmo.align.cli.WGroupEval --type triangle -l "refalign,edna1,streq1,streq1n,streq1x,streq2,streq2n,streq2x,lev1" -w $RESDIR/smalltest -o $RESDIR/wgrev-ttr2.tex +if [ -s $RESDIR/wgrev-ttr2.tex ]; then diff $RESDIR/wgrev-ttr1.tex $RESDIR/wgrev-ttr2.tex ; else echo error with WGREV-TYP3; fi + +#------------------- +echo "\t-Dn=v" +echo "\t(same as Procalign; useless: no parameters involved so far)" + +#------------------- +echo "\t-P,--params <FILE>" +echo "\t(same as Procalign; useless: no parameters involved so far)" + +######################################################################## +# ExtGroupEval +######################################################################## + +echo "\t\t *** Testing ExtGroupEval ***" + +#------------------- +echo "\t-z, -zzz" + +java -Dlog.level=INFO -cp $CP fr.inrialpes.exmo.align.cli.ExtGroupEval -z &> $RESDIR/zerr.txt +grep "Unrecognized option: -z" $RESDIR/zerr.txt > $RESDIR/err.txt +if [ ! -s $RESDIR/err.txt ]; then echo error with EXTGRPEV-ERR1; fi +java -Dlog.level=INFO -cp $CP fr.inrialpes.exmo.align.cli.ExtGroupEval --zzz &> $RESDIR/zzzerr.txt +grep "Unrecognized option: --zzz" $RESDIR/zzzerr.txt > $RESDIR/err.txt +if [ ! -s $RESDIR/err.txt ]; then echo error with EXTGRPEV-ERR2; fi + +#------------------- +echo "\t-h, --help" + +java -cp $CP fr.inrialpes.exmo.align.cli.ExtGroupEval -h &> $RESDIR/extgrpev-h.txt +java -cp $CP fr.inrialpes.exmo.align.cli.ExtGroupEval --help &> $RESDIR/extgrpev-help.txt +if [ -s $RESDIR/extgrpev-h.txt ]; then diff $RESDIR/extgrpev-h.txt $RESDIR/extgrpev-help.txt; else echo error with EXTGRPEV-HELP; fi + +#------------------- +echo "\t-l,--list <FILE>" + +cd $RESDIR/smalltest +java -cp $CP fr.inrialpes.exmo.align.cli.ExtGroupEval -l "refalign,lev1,streq1" > extgrpev-l1.html +if [ ! -s extgrpev-l1.html ]; then echo error with EXTGRPEV-LIST1; fi +java -cp $CP fr.inrialpes.exmo.align.cli.ExtGroupEval --list "refalign,lev1,streq1" > extgrpev-l2.html +if [ -s extgrpev-l2.html ]; then diff extgrpev-l1.html extgrpev-l2.html ; else echo error with EXTGRPEV-LIST2; fi +cd $CWD + +#------------------- +echo "\t-w,--directory <DIR>" + +java -cp $CP fr.inrialpes.exmo.align.cli.ExtGroupEval -l "refalign,edna1,streq1,streq1n,streq1x,streq2,streq2n,streq2x,lev1" -w $RESDIR/smalltest > $RESDIR/extgrpev-w1.html +if [ -s $RESDIR/extgrpev-w1.html ]; then diff $RESDIR/extgrpev-w1.html $RESDIR/smalltest/extgrpev-l1.html > $RESDIR/smalltest/diffgrev-w1.txt ; else echo error with EXTGRPEV-DIR1; fi +if [ ! -s $RESDIR/smalltest/diffgrev-w1.txt ]; then echo error with EXTGRPEV-DIR2; fi +java -cp $CP fr.inrialpes.exmo.align.cli.ExtGroupEval -l "refalign,edna1,streq1,streq1n,streq1x,streq2,streq2n,streq2x,lev1" --directory $RESDIR/smalltest > $RESDIR/extgrpev-w2.html +if [ -s $RESDIR/extgrpev-w2.html ]; then diff $RESDIR/extgrpev-w1.html $RESDIR/extgrpev-w2.html ; else echo error with EXTGRPEV-DIR3; fi + +#------------------- +echo "\t-o <F>, --output <F>" + +java -cp $CP fr.inrialpes.exmo.align.cli.ExtGroupEval -l "refalign,edna1,streq1,streq1n,streq1x,streq2,streq2n,streq2x,lev1" -w $RESDIR/smalltest -o $RESDIR/extgrpev-o1.html +if [ -s $RESDIR/extgrpev-o1.html ]; then diff $RESDIR/extgrpev-o1.html $RESDIR/extgrpev-w1.html ; else echo error with EXTGRPEV-OUT1; fi +java -cp $CP fr.inrialpes.exmo.align.cli.ExtGroupEval -l "refalign,edna1,streq1,streq1n,streq1x,streq2,streq2n,streq2x,lev1" -w $RESDIR/smalltest --output $RESDIR/extgrpev-o2.html +if [ -s $RESDIR/extgrpev-o2.html ]; then diff $RESDIR/extgrpev-o1.html $RESDIR/extgrpev-o2.html ; else echo error with EXTGRPEV-OUT3; fi + +#------------------- +echo "\t-f,--format <MEAS>" + +java -cp $CP fr.inrialpes.exmo.align.cli.ExtGroupEval -f f -l "refalign,edna1,streq1,streq1n,streq1x,streq2,streq2n,streq2x,lev1" -w $RESDIR/smalltest > $RESDIR/extgrpev-f1.html +if [ -s $RESDIR/extgrpev-f1.html ]; then diff $RESDIR/extgrpev-w1.html $RESDIR/extgrpev-f1.html > $RESDIR/smalltest/diffgrev-f1.txt ; else echo error with EXTGRPEV-FORM1; fi +if [ ! -s $RESDIR/smalltest/diffgrev-f1.txt ]; then echo error with EXTGRPEV-FORM2; fi +java -cp $CP fr.inrialpes.exmo.align.cli.ExtGroupEval --format f -l "refalign,edna1,streq1,streq1n,streq1x,streq2,streq2n,streq2x,lev1" -w $RESDIR/smalltest > $RESDIR/extgrpev-f2.html +if [ -s $RESDIR/extgrpev-f2.html ]; then diff $RESDIR/extgrpev-f1.html $RESDIR/extgrpev-f2.html ; else echo error with EXTGRPEV-FORM3; fi + +#------------------- +echo "\t-c,--color (<COLOR>)" + +java -cp $CP fr.inrialpes.exmo.align.cli.ExtGroupEval -c -l "refalign,edna1,streq1,streq1n,streq1x,streq2,streq2n,streq2x,lev1" -w $RESDIR/smalltest > $RESDIR/extgrpev-c1.html +if [ -s $RESDIR/extgrpev-c1.html ]; then diff $RESDIR/extgrpev-w1.html $RESDIR/extgrpev-c1.html > $RESDIR/smalltest/diffgrev-c1.txt ; else echo error with EXTGRPEV-COL1; fi +if [ ! -s $RESDIR/smalltest/diffgrev-c1.txt ]; then echo error with EXTGRPEV-COL2; fi +java -cp $CP fr.inrialpes.exmo.align.cli.ExtGroupEval --color -l "refalign,edna1,streq1,streq1n,streq1x,streq2,streq2n,streq2x,lev1" -w $RESDIR/smalltest > $RESDIR/extgrpev-c2.html +if [ -s $RESDIR/extgrpev-c2.html ]; then diff $RESDIR/extgrpev-c1.html $RESDIR/extgrpev-c2.html ; else echo error with EXTGRPEV-COL3; fi + +#------------------- +echo "\t-r,--reference <FILE>" +java -cp $CP fr.inrialpes.exmo.align.cli.ExtGroupEval -r lev1.rdf -l "refalign,edna1,streq1,streq1n,streq1x,streq2,streq2n,streq2x,lev1" -w $RESDIR/smalltest -o $RESDIR/extgrpev-r1.html +if [ -s $RESDIR/extgrpev-r1.html ]; then diff $RESDIR/extgrpev-o1.html $RESDIR/extgrpev-r1.html > $RESDIR/smalltest/diffgrev-r1.txt ; else echo error with EXTGRPEV-REF1; fi +if [ ! -s $RESDIR/smalltest/diffgrev-r1.txt ]; then echo error with EXTGRPEV-REF2; fi +java -cp $CP fr.inrialpes.exmo.align.cli.ExtGroupEval --reference lev1.rdf -l "refalign,edna1,streq1,streq1n,streq1x,streq2,streq2n,streq2x,lev1" -w $RESDIR/smalltest -o $RESDIR/extgrpev-r2.html +if [ -s $RESDIR/extgrpev-r2.html ]; then diff $RESDIR/extgrpev-r1.html $RESDIR/extgrpev-r2.html ; else echo error with EXTGRPEV-REF3; fi + +#------------------- +echo "\t-t,--type <TYPE> Output TYPE (html|xml|tex|ascii|triangle)" +java -cp $CP fr.inrialpes.exmo.align.cli.ExtGroupEval -t triangle -l "refalign,edna1,streq1,streq1n,streq1x,streq2,streq2n,streq2x,lev1" -w $RESDIR/smalltest -o $RESDIR/extgrpev-ttr1.tex +if [ -s $RESDIR/extgrpev-ttr1.tex ]; then diff $RESDIR/extgrpev-o1.html $RESDIR/extgrpev-ttr1.tex > $RESDIR/smalltest/diffgrev-t1.txt ; else echo error with EXTGRPEV-TYP1; fi +# Useless: only html is available at the moment, so the diff is empty +#if [ ! -s $RESDIR/smalltest/diffgrev-t1.txt ]; then echo error with EXTGRPEV-TYP2; fi +java -cp $CP fr.inrialpes.exmo.align.cli.ExtGroupEval --type triangle -l "refalign,edna1,streq1,streq1n,streq1x,streq2,streq2n,streq2x,lev1" -w $RESDIR/smalltest -o $RESDIR/extgrpev-ttr2.tex +if [ -s $RESDIR/extgrpev-ttr2.tex ]; then diff $RESDIR/extgrpev-ttr1.tex $RESDIR/extgrpev-ttr2.tex ; else echo error with EXTGRPEV-TYP3; fi + +#------------------- +echo "\t-Dn=v" +echo "\t(same as Procalign; useless: no parameters involved so far)" + +#------------------- +echo "\t-P,--params <FILE>" +echo "\t(same as Procalign; useless: no parameters involved so far)" + +######################################################################## +# GroupOutput +######################################################################## + +echo "\t\t *** Testing GroupOutput ***" + +#------------------- +echo "\t-z, -zzz" + +java -Dlog.level=INFO -cp $CP fr.inrialpes.exmo.align.cli.GroupOutput -z &> $RESDIR/zerr.txt +grep "Unrecognized option: -z" $RESDIR/zerr.txt > $RESDIR/err.txt +if [ ! -s $RESDIR/err.txt ]; then echo error with GROUT-ERR1; fi +java -Dlog.level=INFO -cp $CP fr.inrialpes.exmo.align.cli.GroupOutput --zzz &> $RESDIR/zzzerr.txt +grep "Unrecognized option: --zzz" $RESDIR/zzzerr.txt > $RESDIR/err.txt +if [ ! -s $RESDIR/err.txt ]; then echo error with GROUT-ERR2; fi + +#------------------- +echo "\t-h, --help" +java -cp $CP fr.inrialpes.exmo.align.cli.GroupOutput -h &> $RESDIR/grout-h.txt +java -cp $CP fr.inrialpes.exmo.align.cli.GroupOutput --help &> $RESDIR/grout-help.txt +if [ -s $RESDIR/grout-h.txt ]; then diff $RESDIR/grout-h.txt $RESDIR/grout-help.txt; else echo error with $RESDIR/grout-h.txt; fi +diff $RESDIR/grout-h.txt $RESDIR/grout-help.txt + +#------------------- +echo "\t-l,--list <FILE>" + +cd $RESDIR/smalltest +java -cp $CP fr.inrialpes.exmo.align.cli.GroupOutput -l "refalign,edna1,streq1,streq1n,streq1x,streq2,streq2n,streq2x,lev1" > grout-l1.tex +if [ ! -s grout-l1.tex ]; then echo error with GROUT-LIST1; fi +java -cp $CP fr.inrialpes.exmo.align.cli.GroupOutput --list "refalign,edna1,streq1,streq1n,streq1x,streq2,streq2n,streq2x,lev1" > grout-l2.tex +if [ -s grout-l2.tex ]; then diff grout-l1.tex grout-l2.tex ; else echo error with GROUT-LIST2; fi +cd $CWD + +#------------------- +echo "\t-o <F>, --output <F>" + +cd $RESDIR/smalltest +java -cp $CP fr.inrialpes.exmo.align.cli.GroupOutput -l "refalign,edna1,streq1,lev1" -o $RESDIR/grout-o1.tex +if [ ! -s $RESDIR/grout-o1.tex ]; then echo error with GROUT-OUT1; fi +java -cp $CP fr.inrialpes.exmo.align.cli.GroupOutput -l "refalign,edna1,streq1,lev1" --output $RESDIR/grout-o2.tex +if [ -s $RESDIR/grout-o2.tex ]; then diff $RESDIR/grout-o1.tex $RESDIR/grout-o2.tex ; else echo error with GROUT-OUT3; fi +cd $CWD + +#------------------- +echo "\t-w,--directory <DIR>" + +java -cp $CP fr.inrialpes.exmo.align.cli.GroupOutput -l "refalign,edna1,streq1,lev1" -w $RESDIR/smalltest -o $RESDIR/grout-w1.tex +if [ -s $RESDIR/grout-w1.tex ]; then diff $RESDIR/grout-o1.tex $RESDIR/grout-w1.tex ; else echo error with GROUT-DIR1; fi +java -cp $CP fr.inrialpes.exmo.align.cli.GroupOutput -l "refalign,edna1,streq1,lev1" --directory $RESDIR/smalltest --output $RESDIR/grout-w2.tex +if [ -s $RESDIR/grout-w2.tex ]; then diff $RESDIR/grout-o1.tex $RESDIR/grout-o2.tex ; else echo error with GROUT-DIR3; fi + +#------------------- +echo "\t-v,--value" + +java -cp $CP fr.inrialpes.exmo.align.cli.GroupOutput -l "refalign,edna1,streq1,lev1" -v -w $RESDIR/smalltest -o $RESDIR/grout-v1.tex +if [ -s $RESDIR/grout-v1.tex ]; then diff $RESDIR/grout-o1.tex $RESDIR/grout-v1.tex > $RESDIR/smalltest/diffgrout-v1.txt; else echo error with GROUT-VAL1; fi +if [ ! -s $RESDIR/smalltest/diffgrout-v1.txt ]; then echo error with GROUT-VAL2; fi +java -cp $CP fr.inrialpes.exmo.align.cli.GroupOutput -l "refalign,edna1,streq1,lev1" --values --directory $RESDIR/smalltest --output $RESDIR/grout-v2.tex +if [ -s $RESDIR/grout-v2.tex ]; then diff $RESDIR/grout-v1.tex $RESDIR/grout-v2.tex ; else echo error with GROUT-VAL3; fi + +#------------------- +echo "\t-e,--labels" + +java -cp $CP fr.inrialpes.exmo.align.cli.GroupOutput -l "refalign,edna1,streq1,lev1" -e -w $RESDIR/smalltest -o $RESDIR/grout-e1.tex +if [ -s $RESDIR/grout-e1.tex ]; then diff $RESDIR/grout-o1.tex $RESDIR/grout-e1.tex > $RESDIR/smalltest/diffgrout-e1.txt; else echo error with GROUT-LAB1; fi +if [ ! -s $RESDIR/smalltest/diffgrout-e1.txt ]; then echo error with GROUT-LAB2; fi +java -cp $CP fr.inrialpes.exmo.align.cli.GroupOutput -l "refalign,edna1,streq1,lev1" --labels --directory $RESDIR/smalltest --output $RESDIR/grout-e2.tex +if [ -s $RESDIR/grout-e2.tex ]; then diff $RESDIR/grout-e1.tex $RESDIR/grout-e2.tex ; else echo error with GROUT-LAB3; fi + +#------------------- +echo "\t-c,--color (<COLOR>)" + +java -cp $CP fr.inrialpes.exmo.align.cli.GroupOutput -c pink -l "refalign,edna1,streq1,lev1" -w $RESDIR/smalltest > $RESDIR/grout-c1.tex +if [ -s $RESDIR/grout-c1.tex ]; then diff $RESDIR/grout-o1.tex $RESDIR/grout-c1.tex > $RESDIR/smalltest/diffgrev-c1.txt ; else echo error with GROUT-COL1; fi +if [ ! -s $RESDIR/smalltest/diffgrev-c1.txt ]; then echo error with GROUT-COL2; fi +java -cp $CP fr.inrialpes.exmo.align.cli.GroupOutput --color pink -l "refalign,edna1,streq1,lev1" -w $RESDIR/smalltest > $RESDIR/grout-c2.tex +if [ -s $RESDIR/grout-c2.tex ]; then diff $RESDIR/grout-c1.tex $RESDIR/grout-c2.tex ; else echo error with GROUT-COL3; fi + +#------------------- +echo "\t-f,--format <MEAS>" + +java -cp $CP fr.inrialpes.exmo.align.cli.GroupOutput -f r -l "refalign,edna1,streq1,lev1" -w $RESDIR/smalltest > $RESDIR/grout-f1.tex +if [ -s $RESDIR/grout-f1.tex ]; then diff $RESDIR/grout-w1.tex $RESDIR/grout-f1.tex > $RESDIR/smalltest/diffgrev-f1.txt ; else echo error with GROUT-FORM1; fi +# These are always the same values, so no change with these parameters... +#if [ ! -s $RESDIR/smalltest/diffgrev-f1.txt ]; then echo error with GROUT-FORM2; fi +java -cp $CP fr.inrialpes.exmo.align.cli.GroupOutput --format r -l "refalign,edna1,streq1,lev1" -w $RESDIR/smalltest > $RESDIR/grout-f2.tex +if [ -s $RESDIR/grout-f2.tex ]; then diff $RESDIR/grout-f1.tex $RESDIR/grout-f2.tex ; else echo error with GROUT-FORM3; fi + +#------------------- +echo "\t-t,--type <TYPE> Output TYPE (tex|html) / only tex available in fact" + +java -cp $CP fr.inrialpes.exmo.align.cli.GroupOutput -t html -l "refalign,edna1,streq1,lev1" -w $RESDIR/smalltest -o $RESDIR/grout-t1.tex +# The results are necessary empty with html +#if [ -s $RESDIR/grout-t1.tex ]; then diff $RESDIR/grout-o1.tex $RESDIR/grout-t1.tex > $RESDIR/smalltest/diffgrev-t1.txt ; else echo error with GROUT-TYP1; fi +#if [ ! -s $RESDIR/smalltest/diffgrev-t1.txt ]; then echo error with GROUT-TYP2; fi +java -cp $CP fr.inrialpes.exmo.align.cli.GroupOutput --type html -l "refalign,edna1,streq1,lev1" -w $RESDIR/smalltest -o $RESDIR/grout-t2.tex +#if [ -s $RESDIR/grout-t2.tex ]; then diff $RESDIR/grout-t1.tex $RESDIR/grout-t2.tex ; else echo error with GROUT-TYP3; fi + +#------------------- +echo "\t-Dn=v" +echo "\t(same as Procalign; useless: no parameters involved so far)" + +#------------------- +echo "\t-P,--params <FILE>" +echo "\t(same as Procalign; useless: no parameters involved so far)" + +######################################################################## +# GenPlot +######################################################################## + +echo "\t\t *** Testing GenPlot ***" + +#------------------- +echo "\t-h, --help" +java -cp $CP fr.inrialpes.exmo.align.cli.GenPlot -h &> $RESDIR/genplot-h.txt +java -cp $CP fr.inrialpes.exmo.align.cli.GenPlot --help &> $RESDIR/genplot-help.txt +if [ -s $RESDIR/genplot-h.txt ]; then diff $RESDIR/genplot-h.txt $RESDIR/genplot-help.txt; else echo error with $RESDIR/genplot-h.txt; fi + +#------------------- +echo "\t-z,--zzz" + +java -Dlog.level=INFO -cp $CP fr.inrialpes.exmo.align.cli.GenPlot -z &> $RESDIR/zerr.txt +grep "Unrecognized option: -z" $RESDIR/zerr.txt > $RESDIR/err.txt +if [ ! -s $RESDIR/err.txt ]; then echo error with GENPLOT-ERR1; fi +java -Dlog.level=INFO -cp $CP fr.inrialpes.exmo.align.cli.GenPlot --zzz &> $RESDIR/zzzerr.txt +grep "Unrecognized option: --zzz" $RESDIR/zzzerr.txt > $RESDIR/err.txt +if [ ! -s $RESDIR/err.txt ]; then echo error with GENPLOT-ERR2; fi + +#------------------- +echo "\t-l,--list <FILE>" + +cd $RESDIR/smalltest +java -cp $CP fr.inrialpes.exmo.align.cli.GenPlot -l "refalign,edna1,streq1,streq1n,streq1x,streq2,streq2n,streq2x,lev1" > genplot-l1.tex +if [ ! -s genplot-l1.tex ]; then echo error with GENPLOT-LIST1; fi +java -cp $CP fr.inrialpes.exmo.align.cli.GenPlot --list "refalign,edna1,streq1,streq1n,streq1x,streq2,streq2n,streq2x,lev1" > genplot-l2.tex +if [ -s genplot-l2.tex ]; then diff genplot-l1.tex genplot-l2.tex ; else echo error with GENPLOT-LIST2; fi +cd $CWD + +#------------------- +echo "\t-o <F>, --output <F>" + +cd $RESDIR/smalltest +java -cp $CP fr.inrialpes.exmo.align.cli.GenPlot -l "refalign,edna1,streq1,lev1" -o $RESDIR/genplot-o1.tex +if [ ! -s $RESDIR/genplot-o1.tex ]; then echo error with GENPLOT-OUT1; fi +java -cp $CP fr.inrialpes.exmo.align.cli.GenPlot -l "refalign,edna1,streq1,lev1" --output $RESDIR/genplot-o2.tex +if [ -s $RESDIR/genplot-o2.tex ]; then diff $RESDIR/genplot-o1.tex $RESDIR/genplot-o2.tex ; else echo error with GENPLOT-OUT3; fi +cd $CWD + +#------------------- +echo "\t-w,--directory <DIR>" + +java -cp $CP fr.inrialpes.exmo.align.cli.GenPlot -l "refalign,edna1,streq1,lev1" -w $RESDIR/smalltest -o $RESDIR/genplot-w1.tex +if [ -s $RESDIR/genplot-w1.tex ]; then diff $RESDIR/genplot-o1.tex $RESDIR/genplot-w1.tex ; else echo error with GENPLOT-DIR1; fi +java -cp $CP fr.inrialpes.exmo.align.cli.GenPlot -l "refalign,edna1,streq1,lev1" --directory $RESDIR/smalltest --output $RESDIR/genplot-w2.tex +if [ -s $RESDIR/genplot-w2.tex ]; then diff $RESDIR/genplot-o1.tex $RESDIR/genplot-o2.tex ; else echo error with GENPLOT-DIR3; fi + +#------------------- +echo "\t-e,--evaluator <CLASS>" + +mv lev1.table $RESDIR/lev1-init.table +java -cp $CP fr.inrialpes.exmo.align.cli.GenPlot -e fr.inrialpes.exmo.align.impl.eval.WeightedPRecEvaluator -l "refalign,edna1,streq1,lev1" -w $RESDIR/smalltest -o $RESDIR/genplot-e1.tex +if [ -s lev1.table ]; then diff $RESDIR/lev1-init.table lev1.table > $RESDIR/smalltest/diffgrev-e1.txt; else echo error with GENPLOT-EVA1; fi +echo "--> These are the same values for both evaluators, so the error" +if [ ! -s $RESDIR/smalltest/diffgrev-e1.txt ]; then echo error with GENPLOT-EVA2; fi +java -cp $CP fr.inrialpes.exmo.align.cli.GenPlot --evaluator fr.inrialpes.exmo.align.impl.eval.WeightedPRecEvaluator -l "refalign,edna1,streq1,lev1" -w $RESDIR/smalltest -o $RESDIR/genplot-e2.tex +if [ -s $RESDIR/genplot-e2.tex ]; then diff $RESDIR/genplot-e1.tex $RESDIR/genplot-e2.tex ; else echo error with GENPLOT-EVA3; fi + +#------------------- +echo "\t-g,--grapher <CLASS> " + +java -cp $CP fr.inrialpes.exmo.align.cli.GenPlot -g fr.inrialpes.exmo.align.impl.eval.ROCCurveEvaluator -l "refalign,edna1,streq1,lev1" -w $RESDIR/smalltest -o $RESDIR/genplot-g1.tex +if [ -s $RESDIR/genplot-g1.tex ]; then diff $RESDIR/genplot-o1.tex $RESDIR/genplot-g1.tex > $RESDIR/smalltest/diffgrev-g1.txt ; else echo error with GENPLOT-GRA1; fi +if [ ! -s $RESDIR/smalltest/diffgrev-g1.txt ]; then echo error with GENPLOT-GRA2; fi +java -cp $CP fr.inrialpes.exmo.align.cli.GenPlot --grapher fr.inrialpes.exmo.align.impl.eval.ROCCurveEvaluator -l "refalign,edna1,streq1,lev1" -w $RESDIR/smalltest -o $RESDIR/genplot-g2.tex +if [ -s $RESDIR/genplot-g2.tex ]; then diff $RESDIR/genplot-g1.tex $RESDIR/genplot-g2.tex ; else echo error with GENPLOT-GRA3; fi + +#------------------- +echo "\t-t,--type <TYPE> Output TYPE (tsv|tex|html(|xml))" + +java -cp $CP fr.inrialpes.exmo.align.cli.GenPlot -t html -l "refalign,edna1,streq1,lev1" -w $RESDIR/smalltest -o $RESDIR/genplot-t1.html +if [ -s $RESDIR/genplot-t1.html ]; then diff $RESDIR/genplot-o1.tex $RESDIR/genplot-t1.html > $RESDIR/smalltest/diffgrev-t1.txt ; else echo error with GENPLOT-TYP1; fi +if [ ! -s $RESDIR/smalltest/diffgrev-t1.txt ]; then echo error with GENPLOT-TYP2; fi +java -cp $CP fr.inrialpes.exmo.align.cli.GenPlot --type html -l "refalign,edna1,streq1,lev1" -w $RESDIR/smalltest -o $RESDIR/genplot-t2.html +if [ -s $RESDIR/genplot-t2.html ]; then diff $RESDIR/genplot-t1.html $RESDIR/genplot-t2.html ; else echo error with GENPLOT-TYP3; fi + +#------------------- +echo "\t-Dn=v" +echo "\t(same as Procalign)" + +#------------------- +echo "\t-P,--params <FILE>" +echo "\t(same as Procalign)" + + +######################################################################## +# AlignmentService +######################################################################## + +echo "\t\t *** Testing AlignmentService ***" +echo "\tTHIS WILL ONLY WORK WITH A RUNNING MYSQL SET FOR THE SERVER" +echo "\tTHIS IS ALSO VERY SENSITIVE TO TIMEOUTS" + +#------------------- +echo "\t-z, -zzz" + +java -Dlog.level=INFO -cp $CP:lib/alignsvc.jar fr.inrialpes.exmo.align.service.AlignmentService -z &> $RESDIR/zerr.txt +grep "Unrecognized option: -z" $RESDIR/zerr.txt > $RESDIR/err.txt +if [ ! -s $RESDIR/err.txt ]; then echo error with ASERV-ERR1; fi +java -Dlog.level=INFO -cp $CP:lib/alignsvc.jar fr.inrialpes.exmo.align.service.AlignmentService --zzz &> $RESDIR/zzzerr.txt +grep "Unrecognized option: --zzz" $RESDIR/zzzerr.txt > $RESDIR/err.txt +if [ ! -s $RESDIR/err.txt ]; then echo error with ASERV-ERR2; fi + +#------------------- +echo "\t-h, --help" +java -cp $CP:lib/alignsvc.jar fr.inrialpes.exmo.align.service.AlignmentService -h &> $RESDIR/aser-h.txt +java -cp $CP:lib/alignsvc.jar fr.inrialpes.exmo.align.service.AlignmentService --help &> $RESDIR/aser-help.txt +if [ -s $RESDIR/aser-h.txt ]; then diff $RESDIR/aser-h.txt $RESDIR/aser-help.txt; else echo error with ASERV-HELP1; fi + +#------------------- +echo "\t-o <F>, --output <F>" +java -Dlog.level=DEBUG -cp $CP:lib/alignsvc.jar fr.inrialpes.exmo.align.service.AlignmentService -o $RESDIR/aserv.log & +sleep 15 +if [ -s $RESDIR/aserv.log ]; then grep "Alignment server running" $RESDIR/aserv.log > $RESDIR/oerr.txt; else echo error with ASERV-OUT1; fi +if [ ! -s $RESDIR/oerr.txt ]; then echo error with ASERV-OUT2; fi +kill -TERM $! +echo > $RESDIR/aserv.log +java -Dlog.level=DEBUG -cp $CP:lib/alignsvc.jar fr.inrialpes.exmo.align.service.AlignmentService --output $RESDIR/aserv2.log & +sleep 15 +if [ -s $RESDIR/aserv2.log ]; then grep "Alignment server running" $RESDIR/aserv2.log > $RESDIR/oerr.txt; else echo error with ASERV-OUT3; fi +if [ ! -s $RESDIR/oerr.txt ]; then echo error with ASERV-OUT4; fi +kill -TERM $! + +#------------------- +echo "\t-i,--impl <CLASS>" +java -Dlog.level=WARN -cp $CP:lib/alignsvc.jar fr.inrialpes.exmo.align.service.AlignmentService -i fr.inrialpes.exmo.align.cli.GenPlot &> $Resdir/err.txt & +sleep 5; +if [ ! -s $RESDIR/err.txt ]; then echo error with ASERV-IMPL1; else grep "Cannot create service for fr.inrialpes.exmo.align.cli.GenPlot" $RESDIR/err.txt > $RESDIR/ierr.txt; fi +if [ ! -s $RESDIR/err.txt ]; then echo error with ASERV-IMPL2; fi +kill -TERM $! +java -Dlog.level=WARN -cp $CP:lib/alignsvc.jar fr.inrialpes.exmo.align.service.AlignmentService --impl fr.inrialpes.exmo.align.cli.GenPlot2 &> $Resdir/err.txt & +sleep 5; +if [ ! -s $RESDIR/err.txt ]; then echo error with ASERV-IMPL3; else grep "Cannot create service for fr.inrialpes.exmo.align.cli.GenPlot2" $RESDIR/err.txt > $RESDIR/ierr.txt; fi +if [ ! -s $RESDIR/err.txt ]; then echo error with ASERV-IMPL4; fi +kill -TERM $! + +#------------------- +echo "\t-A,--jade <PORT>" +java -cp $CP:lib/alignsvc.jar fr.inrialpes.exmo.align.service.AlignmentService -A 5555 &> $RESDIR/err.txt & +sleep 20; +if [ -s $RESDIR/err.txt ]; then grep "is ready" $RESDIR/err.txt > $RESDIR/jerr.txt; else echo error with ASERV-JADE1; fi +if [ ! -s $RESDIR/jerr.txt ]; then echo error with ASERV-JADE2; fi +kill -TERM $! +java -cp $CP:lib/alignsvc.jar fr.inrialpes.exmo.align.service.AlignmentService --jade 5555 &> $RESDIR/err.txt & +sleep 20; +if [ -s $RESDIR/err.txt ]; then grep "is ready" $RESDIR/err.txt > $RESDIR/jerr.txt; else echo error with ASERV-JADE3; fi +if [ ! -s $RESDIR/jerr.txt ]; then echo error with ASERV-JADE4; fi +kill -TERM $! +/bin/rm -f $RESDIR/err.txt $RESDIR/jerr.txt + +#------------------- +echo "\t-W,--wsdl <PORT>" +java -cp $CP:lib/alignsvc.jar fr.inrialpes.exmo.align.service.AlignmentService -W 5555 &> $RESDIR/err.txt & +sleep 5; +kill -TERM $! +if [ -s $RESDIR/err.txt ]; then echo error with ASERV-WSDL1; fi +java -cp $CP:lib/alignsvc.jar fr.inrialpes.exmo.align.service.AlignmentService --wsdl 5555 &> $RESDIR/err.txt & +sleep 5; +kill -TERM $! +if [ -s $RESDIR/err.txt ]; then echo error with ASERV-WSDL2; fi + +#------------------- +echo "\t-H,--http <PORT>" +java -cp $CP:lib/alignsvc.jar fr.inrialpes.exmo.align.service.AlignmentService -H 5555 &> $RESDIR/err.txt & +sleep 5; +kill -TERM $! +if [ -s $RESDIR/err.txt ]; then echo error with ASERV-HTTP1; fi +java -cp $CP:lib/alignsvc.jar fr.inrialpes.exmo.align.service.AlignmentService --http 5555 &> $Resdir/err.txt & +sleep 5; +kill -TERM $! +if [ -s $RESDIR/err.txt ]; then echo error with ASERV-HTTP2; fi + +#------------------- +echo "\t-X,--jxta <PORT>" +java -cp $CP:lib/alignsvc.jar fr.inrialpes.exmo.align.service.AlignmentService -X 5555 &> $RESDIR/err.txt & +sleep 5; +kill -TERM $! +if [ -s $RESDIR/err.txt ]; then echo error with ASERV-JXTA1; fi +java -cp $CP:lib/alignsvc.jar fr.inrialpes.exmo.align.service.AlignmentService --jxta 5555 &> $RESDIR/err.txt & +sleep 5; +kill -TERM $! +if [ -s $RESDIR/err.txt ]; then echo error with ASERV-JXTA2; fi + +#------------------- +echo "\t-O,--oyster" +echo "\t\tTO BE DEPRECATED" +#java -cp $CP:lib/oyster/oyster.jar:lib/alignsvc.jar fr.inrialpes.exmo.align.service.AlignmentService -O &> $RESDIR/err.txt & +#sleep 5; +#if [ -s $RESDIR/err.txt ]; then echo error with ASERV-OYSTER1; fi +#kill -TERM $! +#java -cp $CP:lib/oyster/oyster.jar:lib/alignsvc.jar fr.inrialpes.exmo.align.service.AlignmentService --oyster &> $RESDIR/err.txt & +#sleep 5; +#if [ -s $RESDIR/err.txt ]; then echo error with ASERV-OYSTER2; fi +#kill -TERM $! + +#------------------- +echo "\t-S,--host <HOSTNAME>" +java -cp $CP:lib/alignsvc.jar fr.inrialpes.exmo.align.service.AlignmentService -S aserv.inria.fr &> $RESDIR/err.txt & +sleep 5; +kill -TERM $! +if [ -s $RESDIR/err.txt ]; then echo error with ASERV-HOST1; fi +java -cp $CP:lib/alignsvc.jar fr.inrialpes.exmo.align.service.AlignmentService --host aserv.inria.fr &> $RESDIR/err.txt & +sleep 5; +kill -TERM $! +if [ -s $RESDIR/err.txt ]; then echo error with ASERV-HOST2; fi + +#------------------- +echo "\t-u,--uriprefix <URI>" +java -cp $CP:lib/alignsvc.jar fr.inrialpes.exmo.align.service.AlignmentService -u http://www.example.org &> $RESDIR/err.txt & +sleep 5; +kill -TERM $! +if [ -s $RESDIR/err.txt ]; then echo error with ASERV-URIP1; fi +java -cp $CP:lib/alignsvc.jar fr.inrialpes.exmo.align.service.AlignmentService --uriprefix http://www.example.org &> $RESDIR/err.txt & +sleep 5; +kill -TERM $! +if [ -s $RESDIR/err.txt ]; then echo error with ASERV-URIP2; fi + +#------------------- +echo "\t-B,--dbms <DBMS>" +java -Dlog.level=ERROR -cp $CP:lib/alignsvc.jar fr.inrialpes.exmo.align.service.AlignmentService -B postgres &> $RESDIR/err.txt +if [ ! -s $RESDIR/err.txt ]; then echo error with ASERV-DBMS1; else grep "Connection refused." $RESDIR/err.txt > $RESDIR/dberr.txt; fi +if [ ! -s $RESDIR/dberr.txt ]; then echo error with ASERV-DBMS2; fi +java -Dlog.level=ERROR -cp $CP:lib/alignsvc.jar fr.inrialpes.exmo.align.service.AlignmentService --dbms postgres &> $RESDIR/err.txt +if [ ! -s $RESDIR/err.txt ]; then echo error with ASERV-DBMS3; else grep "Connection refused." $RESDIR/err.txt > $RESDIR/dberr.txt; fi +if [ ! -s $RESDIR/dberr.txt ]; then echo error with ASERV-DBMS4; fi + +#------------------- +echo "\t-m,--dbmshost <HOST>" +java -Dlog.level=ERROR -cp $CP:lib/alignsvc.jar fr.inrialpes.exmo.align.service.AlignmentService -m www.gloubi.boulga &> $RESDIR/err.txt +if [ ! -s $RESDIR/err.txt ]; then echo error with ASERV-DBHOST1; else grep "Communications link failure" $RESDIR/err.txt > $RESDIR/dberr.txt; fi +if [ ! -s $RESDIR/dberr.txt ]; then echo error with ASERV-DBHOST2; fi +java -Dlog.level=ERROR -cp $CP:lib/alignsvc.jar fr.inrialpes.exmo.align.service.AlignmentService --dbmshost www.gloubi.boulga &> $RESDIR/err.txt +if [ ! -s $RESDIR/err.txt ]; then echo error with ASERV-DBHOST3; else grep "Communications link failure" $RESDIR/err.txt > $RESDIR/dberr.txt; fi +if [ ! -s $RESDIR/dberr.txt ]; then echo error with ASERV-DBHOST4; fi + +#------------------- +echo "\t-s,--dbmsport <PORT>" +java -Dlog.level=ERROR -cp $CP:lib/alignsvc.jar fr.inrialpes.exmo.align.service.AlignmentService -s 5555 &> $RESDIR/err.txt +if [ ! -s $RESDIR/err.txt ]; then echo error with ASERV-DBPORT1; else grep "Communications link failure" $RESDIR/err.txt > $RESDIR/dberr.txt; fi +if [ ! -s $RESDIR/dberr.txt ]; then echo error with ASERV-DBPORT2; fi +java -Dlog.level=ERROR -cp $CP:lib/alignsvc.jar fr.inrialpes.exmo.align.service.AlignmentService --dbmsport 5555 &> $RESDIR/err.txt +if [ ! -s $RESDIR/err.txt ]; then echo error with ASERV-DBPORT3; else grep "Communications link failure" $RESDIR/err.txt > $RESDIR/dberr.txt; fi +if [ ! -s $RESDIR/dberr.txt ]; then echo error with ASERV-DBPORT4; fi + +#------------------- +echo "\t-b,--dbmsbase <BASE>" +java -Dlog.level=ERROR -cp $CP:lib/alignsvc.jar fr.inrialpes.exmo.align.service.AlignmentService -b myAlignDB &> $RESDIR/err.txt +if [ ! -s $RESDIR/err.txt ]; then echo error with ASERV-DBDB1; else grep "Access denied for user" $RESDIR/err.txt > $RESDIR/dberr.txt; fi +if [ ! -s $RESDIR/dberr.txt ]; then echo error with ASERV-DBDB2; fi +java -Dlog.level=ERROR -cp $CP:lib/alignsvc.jar fr.inrialpes.exmo.align.service.AlignmentService --dbmsbase myAlignDB &> $RESDIR/err.txt +if [ ! -s $RESDIR/err.txt ]; then echo error with ASERV-DBDB3; else grep "Access denied for user" $RESDIR/err.txt > $RESDIR/dberr.txt; fi +if [ ! -s $RESDIR/dberr.txt ]; then echo error with ASERV-DBDB4; fi + +#------------------- +echo "\t-l,--dbmsuser <USER>" +java -Dlog.level=ERROR -cp $CP:lib/alignsvc.jar fr.inrialpes.exmo.align.service.AlignmentService -l scott &> $RESDIR/err.txt +if [ ! -s $RESDIR/err.txt ]; then echo error with ASERV-DBUSR1; else grep "Access denied for user" $RESDIR/err.txt > $RESDIR/dberr.txt; fi +if [ ! -s $RESDIR/dberr.txt ]; then echo error with ASERV-DBUSR2; fi +java -Dlog.level=ERROR -cp $CP:lib/alignsvc.jar fr.inrialpes.exmo.align.service.AlignmentService --dbmsuser scott &> $RESDIR/err.txt +if [ ! -s $RESDIR/err.txt ]; then echo error with ASERV-DBUSR3; else grep "Access denied for user" $RESDIR/err.txt > $RESDIR/dberr.txt; fi +if [ ! -s $RESDIR/dberr.txt ]; then echo error with ASERV-DBUSR4; fi + +#------------------- +echo "\t-p,--dbmspass <PASS>" +java -Dlog.level=ERROR -cp $CP:lib/alignsvc.jar fr.inrialpes.exmo.align.service.AlignmentService -p tiger &> $RESDIR/err.txt +if [ ! -s $RESDIR/err.txt ]; then echo error with ASERV-DBPAS1; else grep "Access denied for user" $RESDIR/err.txt > $RESDIR/dberr.txt; fi +if [ ! -s $RESDIR/dberr.txt ]; then echo error with ASERV-DBPAS2; fi +java -Dlog.level=ERROR -cp $CP:lib/alignsvc.jar fr.inrialpes.exmo.align.service.AlignmentService --dbmspass tiger &> $RESDIR/err.txt +if [ ! -s $RESDIR/err.txt ]; then echo error with ASERV-DBPAS3; else grep "Access denied for user" $RESDIR/err.txt > $RESDIR/dberr.txt; fi +if [ ! -s $RESDIR/dberr.txt ]; then echo error with ASERV-DBPAS4; fi + +#------------------- +echo "\t-Dn=v" +echo "\t(same as Procalign)" + +#------------------- +echo "\t-P,--params <FILE>" +echo "\t(same as Procalign)" + +######################################################################## +echo Evrything is fine + + + + + diff --git a/test/src/EDOALTest.java b/test/src/EDOALTest.java index bf9e55b8..02a75c3c 100644 --- a/test/src/EDOALTest.java +++ b/test/src/EDOALTest.java @@ -1,7 +1,7 @@ /* * $Id$ * - * Copyright (C) INRIA, 2008-2011 + * Copyright (C) INRIA, 2008-2011, 2013 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -124,7 +124,8 @@ java -cp ../../lib/procalign.jar fr.inrialpes.exmo.align.cli.ParserPrinter wine2 //assertEquals( wine2, stream.toString() ); } - /* This is round triping wrt converting to URIALignment... */ + /* This is round triping wrt converting to URIALignment... + // Does not work anymore, because now it would try to parse an OMWG file... which goes to loop @Test(expectedExceptions = AlignmentException.class, groups = { "full", "omwg", "raw" }, dependsOnMethods = {"roundTripTest"}) public void anotherRoundTripTest() throws Exception { aparser1.initAlignment( null ); @@ -137,6 +138,6 @@ java -cp ../../lib/procalign.jar fr.inrialpes.exmo.align.cli.ParserPrinter wine2 eal = EDOALAlignment.toEDOALAlignment( al ); // does not work because the ontology cannot be loaded! assertNotNull( eal ); assertEquals( eal.nbCells(), 3 ); - } + } */ } diff --git a/test/src/RendererTest.java b/test/src/RendererTest.java index 80846e4c..512528b1 100644 --- a/test/src/RendererTest.java +++ b/test/src/RendererTest.java @@ -166,7 +166,7 @@ public class RendererTest { oalignment.render( renderer ); // test error with alignment writer.flush(); writer.close(); - assertTrue( valueSimilarTo( stream.toString().length(), 17293 ), "Rendered differently: expected "+17293+" but was "+stream.toString().length() ); + assertTrue( valueSimilarTo( stream.toString().length(), 33811 ), "Rendered differently: expected "+33811+" but was "+stream.toString().length() ); } @Test(groups = { "full", "impl", "raw" }) -- GitLab