/* * 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.xmi; import org.xml.sax.Attributes; import au.com.langdale.sax.XMLElement; import com.hp.hpl.jena.graph.FrontsNode; import au.com.langdale.kena.OntModel; import au.com.langdale.kena.ModelFactory; import au.com.langdale.kena.OntResource; /** * A base for the XMI2OWL interpretor that wraps a Jena OWL model * and provides the low level operations for interpreting XMI elements * as resource in that model. */ public class XMIModel { public static final String LANG = null; // if changed, review the SearchWizard code /** the ontology under construction */ protected OntModel model = ModelFactory.createMem(); /** a debug flag that causes xmi:id's to be preserved as annotations */ public boolean keepID = true; /** * Return the underlying Jena OWL model. */ public OntModel getModel() { return model; } /** * Utility to find OWL class for XMI reference. * * @param element in XMI referring to a class. * @return resource representing the class or null. */ protected OntResource findClass(XMLElement element) { return findClass(element, "xmi.idref"); } /** * Utility to find OWL class for XMI reference by attribute. * * @param element in XMI referring to a class. * @return resource representing the class or null. */ protected OntResource findClass(XMLElement element, String refattr) { String xuid = element.getAttributes().getValue(refattr); if( xuid != null && xuid.length() != 0) { OntResource subject = model.createClass(XMI.NS + xuid); if(keepID) subject.addProperty(UML.id, xuid); return subject; } else return null; } /** * Utility to find OWL resource for XMI reference. * * @param element the element containing the reference * @param name the name of attribute containing the reference * @return resource in the model or null. */ protected OntResource findResource(XMLElement element, String name) { return createUnknown(element.getAttributes().getValue(name)); } /** * Utility to find OWL resource for XMI reference. * @param element the element containing the reference * @return resource in the model or null. */ protected OntResource findResource(XMLElement element) { return findResource(element, "xmi.idref"); } /** * Utility to create and label an OWL class for an XMI declaration. * @param element in XMI declaring a class. * @return resource representing the class or null. */ protected OntResource createClass(XMLElement element) { Attributes atts = element.getAttributes(); String xuid = atts.getValue("xmi.id"); String name = atts.getValue("name"); return createClass(xuid, name); } protected OntResource createClass(String xuid, String name) { if( xuid != null && name != null ) { OntResource subject = model.createClass(XMI.NS + xuid); subject.addLabel(name, LANG); if(keepID) subject.addProperty(UML.id, xuid); return subject; } return null; } // /** // * Utility to create and label an OWL datatype for an XMI declaration. // * @param element in XMI declaring a datatype. // * @return resource representing the datatype or null. // */ // protected OntResource createDatatype(XMLElement element) { // Attributes atts = element.getAttributes(); // String xuid = atts.getValue("xmi.id"); // String name = atts.getValue("name"); // if( xuid != null && name != null ) { // OntResource subject = model.createIndividual(XMI.NS + xuid, RDFS.Datatype); // subject.addLabel(name, LANG); // if(keepID) // subject.addProperty(UML.id, xuid); // return subject; // } // return null; // } /** * Utility to create and label an OWL object property for an XMI * association end declaration. * * @param element in XMI declaring a class. * @return resource representing the property or null. */ protected OntResource createObjectProperty(XMLElement element) { Attributes atts = element.getAttributes(); String xuid = atts.getValue("xmi.id"); String name = atts.getValue("name"); return createObjectProperty(xuid, name); } protected OntResource createObjectProperty(String xuid, String name) { if( xuid != null ) { OntResource subject = model.createObjectProperty(XMI.NS + xuid); if(name != null) subject.addLabel(name, LANG); if(keepID) subject.addProperty(UML.id, xuid); return subject; } return null; } /** * Utility to create and label an OWL object property for an XMI * association end declaration, where the latter has no id. An * id is synthesised from the parent element's id and the role name. * * @param element in XMI declaring a class. * @return resource representing the property or null. */ protected OntResource createObjectProperty(XMLElement element, String xuid, boolean sideA) { Attributes atts = element.getAttributes(); String name = atts.getValue("name"); return createObjectProperty(xuid, sideA, name); } protected OntResource createObjectProperty(String xuid, boolean sideA, String name) { if( xuid != null ) { String synth = xuid + "-" + (sideA? "A": "B"); OntResource subject = model.createObjectProperty(XMI.NS + synth); if( name != null) subject.addLabel(name, LANG); if(keepID) subject.addProperty(UML.id, synth); return subject; } return null; } /** *Create and label an OWL annotation property * for an XMI tag declaration. * * @param element in XMI declaring the property. * @return resource representing the property or null. */ protected OntResource createAnnotationProperty(XMLElement element) { Attributes atts = element.getAttributes(); // handle a reference String tagXuid = atts.getValue("xmi.idref"); if( tagXuid != null ) return model.createAnnotationProperty(XMI.NS + tagXuid); // create a new annotation property String xuid = atts.getValue("xmi.id"); String name = atts.getValue("name"); if( xuid != null && name != null ) { OntResource subject = model.createAnnotationProperty(XMI.NS + xuid); subject.addLabel(name, LANG); if(keepID) subject.addProperty(UML.id, xuid); return subject; } return null; } /** * Create or reference a stereotype */ protected OntResource createStereotype(XMLElement element) { String xuid = element.getAttributes().getValue("xmi.idref"); if( xuid != null ) { return createStereotype(xuid); } else return createIndividual(element, UML.Stereotype); } /** * Reference a stereotype by id string. */ protected OntResource createStereotype(String xuid) { OntResource subject = model.createIndividual(XMI.NS + xuid, UML.Stereotype); if(keepID) subject.addProperty(UML.id, xuid); return subject; } /** * Create or reference a stereotype by name. */ protected OntResource createStereotypeByName(String name) { return model.createIndividual(UML.NS + name.toLowerCase(), UML.Stereotype); } /** * Utility to create and label a generic OWL property * for an XMI tag declaration. * * @param element in XMI declaring property. * @return resource representing the property or null. */ protected OntResource createAttributeProperty(XMLElement element) { Attributes atts = element.getAttributes(); String xuid = atts.getValue("xmi.id"); String name = atts.getValue("name"); return createAttributeProperty(xuid, name); } protected OntResource createAttributeProperty(String xuid, String name) { if( xuid != null && name != null ) { OntResource subject = model.createOntProperty(XMI.NS + xuid); subject.addProperty(UML.hasStereotype, UML.attribute); subject.addLabel(name, LANG); if(keepID) subject.addProperty(UML.id, xuid); return subject; } return null; } /** * Utility to create an OWL resource of given typefor XMI element. * @param element the element containing the reference * @param type the class of the resource * @return resource in the model or null. */ protected OntResource createIndividual(XMLElement element, FrontsNode type) { Attributes atts = element.getAttributes(); String xuid = atts.getValue("xmi.id"); String name = atts.getValue("name"); return createIndividual(xuid, name, type); } protected OntResource createIndividual(String xuid, String name, FrontsNode type) { if( xuid != null && name != null ) { OntResource subject = model.createIndividual(XMI.NS + xuid, type); subject.addLabel(name, LANG); if(keepID) subject.addProperty(UML.id, xuid); return subject; } return null; } /** * Utility to create a labeled resource of (as yet) unknown species. */ protected OntResource createUnknown(XMLElement element) { Attributes atts = element.getAttributes(); String xuid = atts.getValue("xmi.id"); String name = atts.getValue("name"); if( xuid != null && name != null ) { OntResource subject = model.createResource(XMI.NS + xuid); subject.addLabel(name, null); if(keepID) subject.addProperty(UML.id, xuid); return subject; } return null; } /** * Utility to create a resource of (as yet) unknown species. */ protected OntResource createUnknown(String xuid) { if( xuid != null && xuid.length() > 0) { OntResource subject = model.createResource(XMI.NS + xuid); if(keepID) subject.addProperty(UML.id, xuid); return subject; } else return null; } /** * Utility to create a resource representing a UML association. * The association links two Object Properties (the roles) during * model interpretation but is not required in the final model. */ protected OntResource createAssocation(String xuid) { if( xuid != null && xuid.length() > 0) { OntResource subject = model.createResource(XMI.NS + xuid); if(keepID) subject.addProperty(UML.id, xuid); return subject; } else return null; } /** * Utility to create and label an resource for an XMI * package declaration. * * @param element in XMI declaring a class. * @return resource representing the package or null. */ protected OntResource createPackage(XMLElement element) { return createIndividual(element, UML.Package); } /** * Recognise an model declaration. * * @param element candidate element * @param type the element type name * @return true if the element is the correct type * and has the required attributes. */ protected boolean matchDef(XMLElement element, String type) { Attributes atts = element.getAttributes(); return element.matches(type) && atts.getValue("xmi.id") != null && atts.getValue("name") != null; } protected OntResource createGlobalPackage() { OntResource packResource = model.createIndividual(UML.global_package.getURI(), UML.Package); packResource.addLabel("Global", null); return packResource; } /** * Description of an association role. * */ public class Role { public OntResource range; public OntResource property; public int lower =-1, upper=-1; public boolean composite; public boolean aggregate; /** * Interpret this association role in the context of its mate. * Establish the OWL domain and rage. Interpret the UML * multiplicity as OWL functional and inverse functional * property types. */ public void mate(Role other) { if( property == null) return; if( composite ) property.addProperty(UML.hasStereotype, UML.ofComposite); if( aggregate ) property.addProperty(UML.hasStereotype, UML.ofAggregate); if( other.range != null) property.addDomain(other.range); if( range != null ) property.addRange(range); if( other.property != null ) property.addInverseOf(other.property); if( upper == 1 ) property.convertToFunctionalProperty(); if( other.upper == 1) property.convertToInverseFunctionalProperty(); if( other.composite ) property.addProperty(UML.hasStereotype, UML.compositeOf); if( other.aggregate ) property.addProperty(UML.hasStereotype, UML.aggregateOf); } } }