/* * This software is Copyright 2005,2006,2007,2008 Langdale Consultants. * Langdale Consultants can be contacted at: http://www.langdale.com.au */ package au.com.langdale.kena; import java.util.Iterator; import com.hp.hpl.jena.graph.Graph; import com.hp.hpl.jena.graph.compose.MultiUnion; import com.hp.hpl.jena.reasoner.InfGraph; /** * A collection of utilities for composing and decomposing models. * */ public class Composition { /** * Create the union of two models and wrap a transitive inferencer around it. * * Updates will be directed to the first model. * * Any existing inferences or inferencer will be excluded from the result. * * This differs from the Jena methods in that the graph hierarchy of the new * model will not grow in depth on repeated application. The underlying graphs * of the arguments are extracted and inferences are dropped. * */ public static OntModel merge(OntModel updatableModel, OntModel backgroundModel) { MultiUnion union = new MultiUnion(); add(union, updatableModel.getGraph()); add(union, backgroundModel.getGraph()); return ModelFactory.createTransInf(union); } /** * Create the union of two models with no inferencer. * * Updates will be directed to the first model. * * Any existing inferences or inferencer will be excluded from the result. * * This differs from the Jena methods in that the graph hierarchy of the new * model will not grow in depth on repeated application. The underlying graphs * of the arguments are extracted and inferences are dropped. * */ public static OntModel simpleMerge(OntModel updatableModel, OntModel backgroundModel) { MultiUnion union = new MultiUnion(); add(union, updatableModel.getGraph()); add(union, backgroundModel.getGraph()); return ModelFactory.createMem(union); } /** * Merge an empty updatable model with a background model and add an inferencer. */ public static OntModel overlay(OntModel backgroundModel) { return merge(ModelFactory.createMem(), backgroundModel); } /** * Copy a model's content as a new model. * * The new model will contain forward inferences from the given model * but will not have an inferencer of its own. */ public static OntModel copy(OntModel model) { OntModel clone = ModelFactory.createMem(); clone.add(model); return clone; } /** * Decompose the rhs graph and add its parts to the lhs union. * Discard inferences. * */ private static void add( MultiUnion union, Graph graph) { if( graph instanceof MultiUnion) { MultiUnion parts = (MultiUnion)graph; add(union, parts.getBaseGraph()); Iterator it = parts.getSubGraphs().iterator(); while( it.hasNext()) add(union, (Graph)it.next()); } else if( graph instanceof InfGraph) add(union, ((InfGraph)graph).getRawGraph()); else if( graph != null) { Graph base = union.getBaseGraph(); union.addGraph(graph); if( base == null) union.setBaseGraph(graph); } } /** * Get the updateable sub-model of a composite model. * * Something of a hack to deal with problems in the Jena API * OntModel.getBaseModel() does not return an OntModel, OK, * but it does not even return the model that would be hit * by a mutating operation such as createClass(), * contrary to documentation. */ public static OntModel getUpdatableModel(OntModel model) { Graph graph = model.getGraph(); while( true ) { if( graph instanceof MultiUnion) graph = ((MultiUnion)graph).getBaseGraph(); else if( graph instanceof InfGraph) graph = ((InfGraph)graph).getRawGraph(); else break; } return ModelFactory.createMem(graph); } }