/*
* #!
* Ontopia Engine
* #-
* Copyright (C) 2001 - 2013 The Ontopia Project
* #-
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* !#
*/
package net.ontopia.topicmaps.cmdlineutils;
import java.io.IOException;
import net.ontopia.topicmaps.core.TopicMapIF;
import net.ontopia.topicmaps.query.core.InvalidQueryException;
import net.ontopia.topicmaps.query.core.ParsedQueryIF;
import net.ontopia.topicmaps.query.core.QueryProcessorIF;
import net.ontopia.topicmaps.query.core.QueryResultIF;
import net.ontopia.topicmaps.query.impl.basic.QueryTracer;
import net.ontopia.topicmaps.query.utils.QueryUtils;
import net.ontopia.topicmaps.utils.ImportExportUtils;
import net.ontopia.topicmaps.utils.DuplicateSuppressionUtils;
import net.ontopia.utils.CmdlineOptions;
import net.ontopia.utils.CmdlineUtils;
import net.ontopia.utils.StreamUtils;
/**
* PUBLIC: Runs tolog queries against a given topic map.
*/
public class TologQuery {
public static void main(String [] argv) {
// Initialize logging
CmdlineUtils.initializeLogging();
// Initialize command line option parser and listeners
CmdlineOptions options = new CmdlineOptions("TologQuery", argv);
OptionsListener ohandler = new OptionsListener();
// Register local options
options.addLong(ohandler, "trace", 't');
options.addLong(ohandler, "debug", 'd');
options.addLong(ohandler, "timeit", 'i');
// Register logging options
CmdlineUtils.registerLoggingOptions(options);
// Parse command line options
try {
options.parse();
} catch (CmdlineOptions.OptionsException e) {
System.err.println("Error: " + e.getMessage());
usage();
System.exit(1);
}
// Get command line arguments
String[] args = options.getArguments();
if (args.length != 2) {
System.err.println("Error: Must have exactly two arguments!");
usage();
System.exit(1);
}
// Set up tracing
if (ohandler.trace)
QueryTracer.addListener(new OutQueryTracer());
try {
// Run the query
runquery(args[0], args[1], ohandler);
}
catch (java.net.MalformedURLException e) {
System.err.println(e);
System.exit(2);
}
catch (java.io.IOException e) {
System.err.println(e);
System.exit(2);
}
catch (InvalidQueryException e) {
System.err.println(e);
//throw new net.ontopia.utils.OntopiaRuntimeException(e);
System.exit(2);
}
}
private static void usage() {
System.out.println("TologQuery [options] <tm> <query>");
System.out.println("");
System.out.println(" Runs a tolog query against a topic map.");
System.out.println(" Options:");
CmdlineUtils.printLoggingOptionsUsage(System.out);
System.out.println(" --trace: turn on query tracing");
System.out.println(" --timeit: run query 10 times to check performance");
System.out.println("");
System.out.println(" <tm>: url or file name of topic map to be queried");
System.out.println(" <query>: query string or file containing query");
System.out.println("");
}
private static void runquery(String tmfile, String qryfile,
OptionsListener ohandler)
throws IOException, java.net.MalformedURLException, InvalidQueryException {
TopicMapIF tm = ImportExportUtils.getReader(tmfile).read();
// run duplicate suppression only on in-memory topic maps. too expensive on
// rdbms topic maps.
if (tm instanceof net.ontopia.topicmaps.impl.basic.TopicMap)
DuplicateSuppressionUtils.removeDuplicates(tm);
String query;
if (qryfile.trim().endsWith("?"))
query = qryfile;
else
query = StreamUtils.read(new java.io.FileReader(qryfile));
QueryProcessorIF processor = QueryUtils.getQueryProcessor(tm);
ParsedQueryIF pquery = processor.parse(query);
if (ohandler.debug) {
System.out.println("Parsed query: " + pquery + "\n\n");
net.ontopia.topicmaps.query.impl.basic.ParsedQuery pq =
(net.ontopia.topicmaps.query.impl.basic.ParsedQuery) pquery;
java.util.Iterator it = pq.getAllVariables().iterator();
while (it.hasNext()) {
String var = (String) it.next();
System.out.println(var + ": " +
net.ontopia.utils.DebugUtils.toString(pq.getVariableTypes(var)));
}
}
long time = System.currentTimeMillis();
QueryResultIF result = pquery.execute();
System.out.println("Query time: " + (System.currentTimeMillis() - time));
int rows = 0;
while (result.next()) {
for (int ix = 0; ix < result.getWidth(); ix++)
System.out.print(result.getValue(ix) + "\t");
System.out.println("");
rows++;
}
System.out.println("Rows: " + rows);
if (ohandler.timeit) {
// runs the query 10 more times, to produce an average time
System.out.println("\nDoing timing...");
int times = 10;
long total = 0;
for (int ix = 0; ix < times; ix++) {
time = System.currentTimeMillis();
pquery.execute();
total += (System.currentTimeMillis() - time);
}
System.out.println("Average: " + (total / times));
}
}
private static class OptionsListener implements CmdlineOptions.ListenerIF {
boolean trace;
boolean debug;
boolean timeit;
public void processOption(char option, String value)
throws CmdlineOptions.OptionsException {
if (option == 't') trace = true;
if (option == 'd') debug = true;
if (option == 'i') timeit = true;
}
}
private static class OutQueryTracer extends QueryTracer.TracePrinter {
public boolean isEnabled() {
return true;
}
public void output(String message) {
System.out.println(message);
System.out.flush();
}
}
}