ru.ksu.niimm.cll.mocassin.rdf.ontology.util.OntologyReportGenerator.java Source code

Java tutorial

Introduction

Here is the source code for ru.ksu.niimm.cll.mocassin.rdf.ontology.util.OntologyReportGenerator.java

Source

/*******************************************************************************
 * Copyright (c) 2010-2012 Nikita Zhiltsov.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the GNU Public License v3.0
 * which accompanies this distribution, and is available at
 * http://www.gnu.org/licenses/gpl.html
 * 
 * Contributors:
 *     Nikita Zhiltsov - initial API and implementation
 *     Azat Khasanshin - implementation
 ******************************************************************************/
package ru.ksu.niimm.cll.mocassin.rdf.ontology.util;

import static java.lang.String.format;

import java.io.IOException;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import java.util.regex.Pattern;

import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;

import com.google.common.collect.Sets;
import com.hp.hpl.jena.ontology.AllValuesFromRestriction;
import com.hp.hpl.jena.ontology.OntClass;
import com.hp.hpl.jena.ontology.OntModel;
import com.hp.hpl.jena.ontology.OntProperty;

public final class OntologyReportGenerator {
    private static final String OWL_THING_URI = "http://www.w3.org/2002/07/owl#Thing";
    private static final Pattern SMALL_RUSSIAN_START_LETTER_PATTERN = Pattern.compile("^[-?].*");
    private static final Pattern SMALL_LATIN_START_LETTER_PATTERN = Pattern.compile("^[a-z].*");

    private static final String ONTO_MATH_PRO_PREFIX = "http://cll.niimm.ksu.ru/ontologies/mathematics#E";
    private static final String RU_LOCALE = "ru";
    private static final String EN_LOCALE = "en";

    private static final Set<String> classesWithEmptyComments = Sets.newHashSet();

    private OntologyReportGenerator() {
    }

    public static String refactor(OntModel model) throws IOException {
        List<OntClass> classes = new ArrayList<OntClass>(model.listNamedClasses().toList());
        Collections.sort(classes, new OntClassByCodeComparator());
        StringWriter sw = new StringWriter();
        model.write(sw, null, "RDF/XML");
        model.close();
        String modelSource = new String(sw.toString());
        sw.close();
        Iterator<OntClass> it = classes.iterator();
        int i = 1;
        while (it.hasNext()) {
            OntClass ontClass = it.next();

            String code = ontClass.getLocalName();
            int codeInt = Integer.parseInt(code.substring(1));

            if (codeInt != i) {
                modelSource = modelSource.replaceAll(
                        format("\"http://cll.niimm.ksu.ru/ontologies/mathematics#%s\"", code),
                        format("\"http://cll.niimm.ksu.ru/ontologies/mathematics#E%d\"", i));
            }
            i++;
        }
        return modelSource;
    }

    public static OntologyReport generate(OntModel model) {
        XWPFDocument wordDocument = new XWPFDocument();
        List<OntClass> classes = new ArrayList<OntClass>(model.listNamedClasses().toList());
        Collections.sort(classes, new OntClassByCodeComparator());
        Set<String> allClassesIds = new LinkedHashSet<String>();
        for (OntClass ontClass : classes) {
            allClassesIds.add(ontClass.getLocalName());
            addURI(wordDocument, ontClass);
            addSuperclasses(wordDocument, ontClass);
            addSubclasses(wordDocument, ontClass);
            addComment(wordDocument, ontClass);
            wordDocument.createParagraph().setSpacingAfter(10);
            addProperties(wordDocument, ontClass);
        }
        return new OntologyReport(wordDocument, classesWithEmptyComments, allClassesIds);
    }

    private static void addProperties(XWPFDocument wordDocument, OntClass ontClass) {
        Set<OntClass> equivalentClasses = ontClass.listEquivalentClasses().toSet();
        if (equivalentClasses.isEmpty())
            return;
        XWPFParagraph paragraph = wordDocument.createParagraph();
        paragraph.setStyle("style0");
        XWPFRun run = paragraph.createRun();
        run.setText("?: ");

        for (OntClass equivalentClass : equivalentClasses) {
            if (!equivalentClass.isRestriction())
                continue;
            AllValuesFromRestriction restriction = equivalentClass.asRestriction().asAllValuesFromRestriction();
            XWPFParagraph p = wordDocument.createParagraph();
            p.setIndentationLeft(1440);
            XWPFRun r = p.createRun();
            OntProperty onProperty = restriction.getOnProperty();
            OntClass toClass = restriction.getAllValuesFrom().as(OntClass.class);

            r.setText(format("%s: %s", formatPropertyURI(onProperty), formatURI(toClass)));
            r.setItalic(true);
        }
        wordDocument.createParagraph().setIndentationLeft(1440);
    }

    private static String formatPropertyURI(OntProperty onProperty) {
        return format("%s %s", onProperty.getLocalName(), onProperty.getLabel(RU_LOCALE).replace("_", " "));
    }

    private static void addComment(XWPFDocument wordDocument, OntClass ontClass) {
        String comment = null;
        if (ontClass.getComment(RU_LOCALE) != null) {
            comment = ontClass.getComment(RU_LOCALE);
        } else if (ontClass.getComment(EN_LOCALE) != null) {
            comment = ontClass.getComment(EN_LOCALE);
        } else {
            comment = ontClass.getComment(null);
        }
        if (comment == null || comment.isEmpty()) {
            classesWithEmptyComments.add(formatURI(ontClass));
            return;
        }
        XWPFParagraph paragraph = wordDocument.createParagraph();
        paragraph.setStyle("style0");
        XWPFRun run = paragraph.createRun();
        run.setText(format("?: \n%s",
                comment != null ? comment.replace("http://", ". http://").replace("www.", ". www.") : ""));
    }

    private static void addNeighbourClasses(XWPFDocument wordDocument, Set<OntClass> classes, String header) {
        if (classes.isEmpty())
            return;
        XWPFParagraph paragraph = wordDocument.createParagraph();
        paragraph.setStyle("style0");
        XWPFRun run = paragraph.createRun();
        run.setText(header);
        StringBuilder sb = new StringBuilder();
        List<OntClass> classList = new ArrayList<OntClass>(classes);
        Collections.sort(classList, new OntClassByLabelComparatorAsc());
        Iterator<OntClass> it = classList.iterator();
        while (it.hasNext()) {
            OntClass clazz = it.next();
            sb.append(formatURI(clazz));
            if (it.hasNext()) {
                sb.append("; ");
            }
        }
        XWPFParagraph p = wordDocument.createParagraph();
        p.setIndentationLeft(1440);
        XWPFRun r = p.createRun();
        r.setText(sb.toString());
        r.setItalic(true);
        wordDocument.createParagraph().setIndentationLeft(1440);
    }

    private static void addSubclasses(XWPFDocument wordDocument, OntClass ontClass) {
        Set<OntClass> subclasses = ontClass.listSubClasses(true).toSet();
        if (!subclasses.isEmpty()) {
            addNeighbourClasses(wordDocument, subclasses, "??: ");
        }
    }

    private static void addSuperclasses(XWPFDocument wordDocument, OntClass ontClass) {
        addNeighbourClasses(wordDocument, ontClass.listSuperClasses(true).toSet(), "??: ");
    }

    private static void addURI(XWPFDocument wordDocument, OntClass ontClass) {
        XWPFParagraph paragraph = wordDocument.createParagraph();
        paragraph.setSpacingBefore(10);
        paragraph.setStyle("Heading 5");
        XWPFRun run = paragraph.createRun();
        run.setText(formatURI(ontClass));
    }

    private static String formatURI(OntClass ontClass) {

        if (ontClass.getURI().equals(OWL_THING_URI))
            return "owl:Thing";

        if (!ontClass.getURI().startsWith(ONTO_MATH_PRO_PREFIX))
            throw new RuntimeException(
                    format("OntClass='%s' does not have the appropriate URI", ontClass.getURI()));
        String preparedLabel = prepareLabel(ontClass);
        return format("%s %s", ontClass.getLocalName(), preparedLabel);

    }

    private static String prepareLabel(OntClass ontClass) {

        String rdfsLabel = null;
        if (ontClass.getLabel(RU_LOCALE) != null) {
            rdfsLabel = ontClass.getLabel(RU_LOCALE);
        } else if (ontClass.getLabel(EN_LOCALE) != null) {
            rdfsLabel = ontClass.getLabel(EN_LOCALE);
        } else {
            rdfsLabel = ontClass.getLabel(null);
        }
        if (rdfsLabel == null)
            throw new RuntimeException("Cannot handle classes with empty labels: " + ontClass.getURI());
        if (SMALL_RUSSIAN_START_LETTER_PATTERN.matcher(rdfsLabel).matches()
                || SMALL_LATIN_START_LETTER_PATTERN.matcher(rdfsLabel).matches()) {
            StringBuilder sb = new StringBuilder();
            sb.append(Character.toUpperCase(rdfsLabel.charAt(0)));
            sb.append(rdfsLabel.substring(1));
            rdfsLabel = sb.toString();
        }

        String preparedLabel = rdfsLabel.replace("_", " ");
        return preparedLabel;
    }

    private static class OntClassByLabelComparatorDesc implements Comparator<OntClass> {

        @Override
        public int compare(OntClass first, OntClass second) {
            return prepareLabel(second).compareTo(prepareLabel(first));
        }

    }

    private static class OntClassByLabelComparatorAsc implements Comparator<OntClass> {

        @Override
        public int compare(OntClass first, OntClass second) {
            return prepareLabel(first).compareTo(prepareLabel(second));
        }

    }

    private static class OntClassByCodeComparator implements Comparator<OntClass> {

        @Override
        public int compare(OntClass first, OntClass second) {
            int firstCode = Integer.parseInt(first.getLocalName().substring(1));
            int secondCode = Integer.parseInt(second.getLocalName().substring(1));
            if (firstCode < secondCode)
                return -1;
            if (firstCode > secondCode)
                return 1;
            return 0;
        }

    }
}