Source code

This is really "alpha" code, it will be published in a better way in future releases.
/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (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.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is Protégé-OWL SPARQL Query Launcher.
 *
 * The Initial Developer of the Original Code is
 * Banca Finnat Euramerica S.p.A.
 * Portions created by the Initial Developer are Copyright (C) 2006
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *         Massimo Coletti <mc@mcoletti.net>
 *
 * ***** END LICENSE BLOCK ***** */

package net.mcoletti.protegex.owl.sparql;

import java.io.FileWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.Map;

import edu.stanford.smi.protege.model.Project;
import edu.stanford.smi.protegex.owl.model.OWLIndividual;
import edu.stanford.smi.protegex.owl.model.OWLModel;
import edu.stanford.smi.protegex.owl.model.OWLNamedClass;
import edu.stanford.smi.protegex.owl.model.RDFProperty;
import edu.stanford.smi.protegex.owl.model.RDFSLiteral;
import edu.stanford.smi.protegex.owl.model.impl.DefaultOWLIndividual;
import edu.stanford.smi.protegex.owl.model.query.QueryResults;
import edu.stanford.smi.protegex.owl.writer.rdfxml.util.Util;
import edu.stanford.smi.protegex.owl.writer.xml.DefaultXMLWriter;

/**
 * Excutes a query expressed in SPARQL language against a Knowledgebase, and
 * formats the results in XML format.
 * 
 * The resulting XML document is not defined by a schema (now), but have a very
 * simple structure: <resultset> -- the root element <query> -- the query text
 *         <result> -- each resulting row
 *             <variable> -- each result variable in the SELECT statement
 *                 <individual> -- only if the variable is not a literal
 *                     <label> -- for each label of the individual
 *                     <propertyValue> -- for the literal properties of the individual
 * 
 * I believe that this simple format is well-suited to simple transformations
 * in order to obtain HTML or PDF presentations.
 * 
 * VERSION: alpha code A.1 - march 13, 2006
 *  
 * @author Massimo Coletti
 *
 */

public class QueryResultsWriter {

    /** the model on which the query runs * */
    private OWLModel kb;

    /** the writer object used to output the result document * */
    private Writer outw;

    /** the query text * */
    private String queryText;

    {
        // the default output is System.out
        outw = new StringWriter();
    }

    /**
     * Executes the query and creates the XML documents.
     * 
     * This version can be executed only if the Writer object, the query text,
     * and the OWL model, are properly initialized.
     * 
     */
    public void processQuery() {

        String dftns = kb.getNamespaceManager().getDefaultNamespace();
        try {
            QueryResults qr = kb.executeSPARQLQuery(queryText);

            // creazione di un XML writer
            DefaultXMLWriter xmlw = new DefaultXMLWriter(outw, Util
                    .getNamespacePrefixes(kb.getNamespaceManager(), dftns));
            xmlw.startDocument("resultset");

            xmlw.writeStartElement("query-text");
            xmlw.writeTextContent(queryText);
            xmlw.writeEndElement();

            while (qr.hasNext()) {
                Map riga = qr.next();

                xmlw.writeStartElement("result");

                Collection resc = riga.keySet();
                for (Object it : resc) {
                    xmlw.writeStartElement("variable");
                    xmlw.writeAttribute("variable-name", (String) it);
                    String className = riga.get((String) it).getClass()
                            .getName();
                    xmlw.writeAttribute("className", className);
                    if (className.contains("RDFSLiteral"))
                        xmlw.writeAttribute("value", riga.get((String) it)
                                .toString());
                    if (className.contains("OWLIndividual")) {
                        OWLIndividual owli = (OWLIndividual) riga
                                .get((String) it);
                        xmlw.writeStartElement("individual");
                        xmlw.writeAttribute("individualName", owli.getName());

                        Iterator rdft = owli.listRDFTypes();
                        while (rdft.hasNext()) {
                            OWLNamedClass onetype = (OWLNamedClass) rdft.next();
                            xmlw.writeAttribute("rdfType", onetype.getName());
                        }

                        DefaultOWLIndividual indi = (DefaultOWLIndividual) riga
                                .get((String) it);
                        // elaborazione labels
                        Collection labels = indi.getLabels();
                        for (Object lab : labels) {
//                            String labtext = lab.getString();
//                            String lang = lab.getLanguage();
                            xmlw.writeStartElement("label");
//                            if (lang != null)
//                                xmlw.writeAttribute("lang",lang);
                            xmlw.writeTextContent(lab.toString());
                            xmlw.writeEndElement();
                        }
                        
                        // elaborazione proprietà
                        Collection<RDFProperty> propert = indi
                                .getRDFProperties();
                        for (RDFProperty p : propert) {
                            xmlw.writeStartElement("propertyValue");
                            xmlw.writeAttribute("name", p.getName());
                            try {
                                for (Object lit : indi
                                        .getPropertyValueLiterals(p)) {
                                    xmlw.writeTextContent(lit.toString());
                                }
                            } catch (Exception e) { // void

                            }
                            xmlw.writeEndElement();
                        }
                        xmlw.writeEndElement();

                    }
                    xmlw.writeEndElement();
                }
                xmlw.writeEndElement();
            }

            xmlw.endDocument();
            outw.close();

        } catch (Exception e) {
            e.printStackTrace(System.err);
        }
        // System.out.println(errors.size());

    }

    /**
     * This is the method used to execute the query from the command line. The
     * command synopsis is:
     * 
     * QueryResultWriter <query text> -p <protégé project file name> -o <output
     * file name>
     * 
     * @param args
     */
    public static void main(String[] args) {

        // TODO refine parameter parsing!
        
        if (args.length<3) {
            System.err.println("Usage:");
            System.err.println("\tQueryResultWriter <query text> -p <protégé project file name> -o <output file>");
            System.exit(2);
        }
        QueryResultsWriter qrw = new QueryResultsWriter();
        qrw.setQueryText(args[0]);
        boolean dftOutput = true;
        Collection errors = new ArrayList();

        if (args[1].startsWith("-p")) {
            errors = qrw.setKnowledgeBaseFromFile(args[2]);
        }

        if (args.length>3 && args[3].startsWith("-o")) {
            dftOutput = false;
            try {
                qrw.setOutw(new FileWriter(args[4]));
            } catch (Exception e) {
                Exception newe = new Exception("Invalid output file", e);
                newe.printStackTrace(System.err);
                System.exit(1);
            }
        }
        qrw.processQuery();
        
        // if the output is the default, I have to emit the result
        if (dftOutput) {
            System.out.println(qrw.getOutw().toString());
        }
        
        // load errors
        if (errors.size()>0) {
            System.err.println("Found errors loading knowledge base:");
            for (Object er:errors) {
                System.err.println(er.toString());
            }
            System.exit(3);
        }
        System.exit(0);
    }

    public OWLModel getKb() {
        return kb;
    }

    public void setKb(OWLModel kb) {
        this.kb = kb;
    }

    public Writer getOutw() {
        return outw;
    }

    public void setOutw(Writer outw) {
        this.outw = outw;
    }

    public String getQueryText() {
        return queryText;
    }

    public void setQueryText(String queryText) {
        this.queryText = queryText;
    }

    /**
     *  Sets the model from a Protégé project object.
     *  
     * @param ppj a Project
     */
    public void setKnowledgeBaseFromProject(Project ppj) {
        setKb((OWLModel) ppj.getKnowledgeBase());
    }
    
    /**
     *  Sets the model from the name of a Protégé project file
     *  
     *  @param filename a String with the name of the local file
     *  
     * @return a Collection with the errors found loading the kb
     */
    public Collection setKnowledgeBaseFromFile(String filename) {
        Collection errors = new ArrayList();

        Project project = new Project(filename, errors);
        setKnowledgeBaseFromProject(project);
        return errors;
    }
}