📄 umlmodel.java
字号:
* * @return a single triple if such was found;<br> * <code>null</code> if nothing was found;<br> * otherwise a RuntimeException is thrown. public Statement find1( Resource subject, Resource predicate, RDFnode object ); */ /** * Clone the model. */ public Model duplicate() throws ModelException { return new UMLModel(nodeFactory, instances.duplicate(), schema, inverse); } /** * Creates empty model of the same Class */ public Model create() throws ModelException { return new UMLModel(nodeFactory, instances.create(), schema, inverse); } /** * Returns the node factory for this model */ public NodeFactory getNodeFactory() throws ModelException { return nodeFactory; } public String toString() { try { return "[UMLModel " + getURI() + "]"; } catch (ModelException exc) { return "[UMLModel: " + exc + "]"; } } /** * Validates the model given instance and schema data */ public static void validateRawSchema(Model instances, Model schema) throws ModelException { // instances = new OrderedModel(instances); // schema = new OrderedModel(schema); StringBuffer errors = new StringBuffer(); // indicates that cardinality of property has beed verified Hashtable verifiedCardinality = new Hashtable(); UMLModel umlizedSchema = new UMLModel(schema, schema); Model umlizedInstance = new UMLModel(instances, schema); Model rdfsClosure = RDFSchemaModel.computeRDFSClosure(getRDFSClassHierarchy(umlizedSchema)); Model rdfSchema = new RDFSchemaModel(schema, rdfsClosure); Model rdfInstance = new RDFSchemaModel(instances, rdfsClosure); Hashtable inverse = umlizedSchema.getInverse(); // RDFUtil.printStatements(umlizedInstance.find(null, DataTypes.Multiplicity_range, null), System.out); for(Enumeration en = instances.elements(); en.hasMoreElements();) { Statement t = (Statement)en.nextElement(); // rdf:type if(RDF.type.equals(t.predicate())) { // ensure that the target is of type core:Classifier // ensure that the target is of type rdf:Class if(t.object() instanceof Literal) invalid( errors, t, "Literals cannot be used for typing" ); // if(DataTypes.PseudostateKind.getLabel().equals(t.object().getLabel())) { // System.err.println("TEST: "); // RDFUtil.printStatements(rdfSchema.find(DataTypes.PseudostateKind, RDF.type, UMLCore.Classifier), System.out); // RDFUtil.printStatements(rdfsClosure.find(UMLCore.DataType, null, null), System.out); // } Model res = rdfSchema.find( (Resource)t.object(), RDF.type, UMLCore.Classifier ); if(res.isEmpty()) { // System.err.println("SUPERCLASSES(C)"); // RDFUtil.printStatements( rdfSchema.find( (Resource)t.object(), RDF.type, null ), System.err); invalid( errors, t, t.object().toString() + " must be an instance of " + UMLCore.Classifier); } // t.subject() is typed. Check cardinality (multiplicity) of incoming and outgoing arcs Resource subject = t.subject(); Resource subjectType = (Resource)t.object(); if(!verifiedCardinality.contains(subject)) { verifiedCardinality.put(subject, subject); // get association ends that are typed with subjectType Model ends = umlizedSchema.find(null, UMLCore.AssociationEnd_type, subjectType); for(Enumeration endsEn = ends.elements(); endsEn.hasMoreElements();) { Resource end = ((Statement)endsEn.nextElement()).subject(); // multiplicity defined? Need to get multiplicity from the opposite AssociationEnd Resource otherEnd = (Resource)umlizedSchema.getInverse().get(end); if(otherEnd == null) // don't complain now, we'll check later for that continue; Resource multiplicity = RDFUtil.getObjectResource(umlizedSchema, otherEnd, UMLCore.AssociationEnd_multiplicity); if(multiplicity != null) { // determine multiplicity of this relation // System.out.println("CHECK: " + subject + " (of type " + subjectType + ") for outgoing link " + otherEnd + ": "); Model allEnds = umlizedInstance.find(subject, otherEnd, null); // verify declared multiplicity of this guy: find a range where the actual number of links fits Model ranges = umlizedSchema.find(multiplicity, DataTypes.Multiplicity_range, null); // System.out.println("Multiplicity: " + multiplicity + ", " + ranges.size()); boolean foundRange = false; String expectedRange = ""; for(Enumeration enRanges = ranges.elements(); enRanges.hasMoreElements();) { try { Resource range = (Resource)((Statement)enRanges.nextElement()).object(); // find lower and upper limit of this range String rangeLower = RDFUtil.getObjectLiteral(umlizedSchema, range, DataTypes.MultiplicityRange_lower); // System.out.println("Lower: " + rangeLower); RDFNode rangeUpper = RDFUtil.getObject(umlizedSchema, range, DataTypes.MultiplicityRange_upper); // System.out.println("Upper: " + rangeUpper); int lower = Integer.parseInt(rangeLower); int upper = rangeUpper instanceof Resource ? Integer.MAX_VALUE : Integer.parseInt(rangeUpper.getLabel()); if(!"".equals(expectedRange)) expectedRange += ","; if(lower == upper) expectedRange += rangeLower; else expectedRange += rangeLower + "-" + ((rangeUpper instanceof Resource) ? "*" : rangeUpper.getLabel()); if(lower <= allEnds.size() && allEnds.size() <= upper) { foundRange = true; break; } } catch (Exception any) { // System.err.println("EXC: " + any); } } if(!"".equals(expectedRange) && !foundRange) { // System.err.println("--------- ERROR: Resource " + subject + " (of type " + subjectType + ") is expected to have " + expectedRange + ", not " + allEnds.size() +", properties of type " + otherEnd + " (inverse of " + end + ")"); invalid( errors, null, "Resource " + subject + " (of type " + subjectType + ") is expected to have " + expectedRange + ", not " + allEnds.size() +", properties of type " + otherEnd + " (inverse of " + end + ")"); } } } } } else { // is t.predicate() an Association? Resource rangeType = RDFUtil.getObjectResource(rdfSchema, t.predicate(), UMLCore.AssociationEnd_type); if(rangeType != null) { // check domain and range if(!isInstanceOf(rdfInstance, rdfSchema, (Resource)t.object(), rangeType)) { invalid( errors, t, "Object must be instance of " + rangeType ); } // find all allowed domains of the Property Resource inverseEnd = (Resource)inverse.get(t.predicate()); if(inverseEnd == null) invalid( errors, null, "Bad schema definition of " + t.predicate() + ", no other AssociationEnd found"); else { Resource domainType = RDFUtil.getObjectResource(rdfSchema, inverseEnd, UMLCore.AssociationEnd_type); if(domainType == null) invalid( errors, null, "No association end type defined for " + inverseEnd); else if (!isInstanceOf(rdfInstance, rdfSchema, t.subject(), domainType)) { invalid( errors, t, "Subject must be instance of " + domainType ); } } } else { // is t.predicate() an Attribute? Resource attType = RDFUtil.getObjectResource(rdfSchema, t.predicate(), UMLCore.StructuralFeature_type); if(attType != null) { // try to check for various known Data Types if(!checkDataType(errors, t, attType)) { // check for non data-types if(!(t.object() instanceof Resource) || !isInstanceOf(rdfInstance, rdfSchema, (Resource)t.object(), attType)) invalid( errors, t, "Attribute value must be instance of " + attType ); } } } } } if(errors.length() > 0) { throw new InvalidModelException(errors.toString()); } } static boolean isInstanceOf(Model instance, Model schema, Resource r, Resource umlClass) throws ModelException { return RDFUtil.isInstanceOf(instance, r, umlClass) || RDFUtil.isInstanceOf(schema, r, umlClass); } static boolean isValidNumber(String str) { try { new java.math.BigInteger(str); return true; } catch (NumberFormatException nfe) { return false; } } static boolean checkDataType(StringBuffer errors, Statement t, Resource attType) throws ModelException { RDFNode value = t.object(); String strVal = value.getLabel(); if (DataTypes.Integer.equals(attType)) { if(!(value instanceof Literal) || !isValidNumber(strVal)) invalid( errors, t, "Attribute value must be an integer."); } else if (DataTypes.UnlimitedInteger.equals(attType)) { if(!DataTypes.UnlimitedInteger_c42.equals(value) && (!(value instanceof Literal) || !isValidNumber(strVal))) invalid( errors, t, "Attribute value must be an integer or " + DataTypes.UnlimitedInteger_c42); } else return false; return true; } /** * creates a fully enabled UML/RDFS model from a raw model */ public static Model create(Model raw) throws ModelException { Model schema = new UMLModel(raw, raw); SetOperations.unite(schema, UMLModel.getRDFSClassHierarchy(schema)); Model closure = RDFSchemaModel.computeRDFSClosure(schema); // make instances to be aware of inverse relationships return new UMLModel(new RDFSchemaModel(raw, closure), schema); } static void invalid(StringBuffer b, Statement t, String msg) { if(b.length() > 0) b.append('\n'); if(t != null) { // String objStr = (t.object() instanceof Literal) ? "\"" + t.object() + "\"" : t.object().toString(); // b.append("INVALID STATEMENT: (" + t.subject() + ", " + t.predicate() + ", " + objStr + "). "); b.append("Invalid statement:\n\t" + t + ".\n\t"); } b.append(msg); } public static void main(String[] args) throws Exception { // testing closure if(args.length == 0) { System.err.println("UMLModel <instance URL> {<schema URL>}+"); System.exit(1); } RDFFactory f = new RDFFactoryImpl(); Model m = f.createModel(); Model rawSchema = f.createModel(); RDFSchemaModel.readModelsFromArgList(f, m, rawSchema, args); // RDFUtil.printStatements(m, System.out); try { UMLModel.validateRawSchema(m, rawSchema); System.err.println("Model is valid."); } catch (InvalidModelException ime) { System.err.println(ime.getMessage()); } } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -