Java tutorial
/******************************************************************************* * 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; } } }