📄 rdfschemamodel.java
字号:
Hashtable processedNodes = new Hashtable(); Hashtable stack = new Hashtable(); for(Enumeration en = all.elements(); en.hasMoreElements();) { Statement s = (Statement)en.nextElement(); if(!processedNodes.contains(s.object()) && s.object() instanceof Resource) { stack.clear(); if(traverseClosure(processedNodes, (Resource)s.object(), property, stack, closure, src, 0) && !allowLoops) throw new ModelException("[RDFSchemaModel] found invalid loop in transitive closure of " + property + ". Loop node: " + s.object()); } } return closure; } /** traverse down the tree, maintains stack and adds shortcuts to the model. * Returns true if loop is found. */ private static boolean traverseClosure(Hashtable processedNodes, Resource node, Resource property, Hashtable stack, Model closure, Model src, int depth) throws ModelException { processedNodes.put(node, node); boolean isOnStack = stack.contains(node); // System.err.println("Traversing node: " + node + ", on stack: " + isOnStack + ", depth: " + depth); boolean isLoop = isOnStack; if(!isOnStack) { stack.put(node, node); // get all children of this node Model children = src.find(null, property, node); for(Enumeration en = children.elements(); en.hasMoreElements();) { Statement s = (Statement)en.nextElement(); isLoop |= traverseClosure(processedNodes, s.subject(), property, stack, closure, src, depth+1); } if(!isLoop) stack.remove(node); } // add everything from stack if(!isOnStack) for(Enumeration en = stack.elements(); en.hasMoreElements();) { Resource parent = (Resource)en.nextElement(); closure.add(src.getNodeFactory().createStatement(node, property, parent)); // System.err.println("SUB: " + node + "-->" + parent); } return isLoop; } /** * Validates <tt>rawInstances</tt> model agains schema in <tt>rawSchema</tt> */ public static void validateRawSchema(Model rawInstances, Model rawSchema) throws ModelException { Model closure = RDFSchemaModel.computeRDFSClosure(rawSchema); RDFSchemaModel schema = new RDFSchemaModel(rawSchema, closure); RDFSchemaModel instances = new RDFSchemaModel(rawInstances, closure); validate(instances, schema); } /** * Validates the model. <tt>schema</tt> should be RDFSchemaModel */ public static void validate(Model instances, Model schema) throws ModelException { Hashtable containers = new Hashtable(); // triples containing collections and ordinals StringBuffer errors = new StringBuffer(); 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 rdf:Class if(t.object() instanceof Literal) invalid( errors, t, "Literals cannot be used for typing" ); Model res = schema.find( (Resource)t.object(), RDF.type, RDFS.Class ); if(res.isEmpty()) { // System.err.println("SUPERCLASSES(C)"); // RDFUtil.printStatements( schema.find( (Resource)t.object(), RDF.type, null ), System.err); if(noSchema(errors, t.object())) break; else invalid( errors, t, t.object().toString() + " must be an instance of " + RDFS.Class); } } else if(RDFUtil.getOrd(t.predicate()) > 0) { // save for later containers.put( t.subject(), t ); } else { // check domain and range Vector expected = new Vector(); // find all allowed domains of the Property Model domains = schema.find( t.predicate(), RDFS.domain, null ); if(!domains.isEmpty()) { boolean domainOK = false; // go through all valid domains and check whether // the subject() is an instance of a valid domain Class for(Enumeration en_d = domains.elements(); en_d.hasMoreElements();) { Resource domainClass = (Resource)((Statement)en_d.nextElement()).object(); // System.err.println("DOMAIN: checking " + t.subject() + " against " + domainClass); expected.addElement( domainClass ); if( !instances.find( t.subject(), RDF.type, domainClass ).isEmpty()) { // System.err.println("DOMAIN CHECKED: " + domainClass); domainOK = true; break; } } if(!domainOK) { // System.err.println("SUPERCLASSES"); // RDFUtil.printStatements( schema.find( t.subject(), RDF.type, null ), System.err); if(noSchema(errors, t.subject())) break; else invalid( errors, t, "Subject must be instance of " + expected ); } } expected.setSize(0); // find all allowed domains of the Property Model ranges = schema.find( t.predicate(), RDFS.range, null ); if(ranges.size() == 1) { // there can be only one range property!!! (See specs) boolean rangeOK = false; // go through all valid ranges and check whether // the object() is an instance of a valid range Class for(Enumeration en_r = ranges.elements(); en_r.hasMoreElements();) { Resource rangeClass = (Resource)((Statement)en_r.nextElement()).object(); // System.err.println("RANGE: checking " + t.object() + " against " + rangeClass); expected.addElement(rangeClass); // special treatment for Literals if(RDFS.Literal.equals(rangeClass)) { if( t.object() instanceof Literal ) { // System.err.println("RANGE CHECKED: Literal"); rangeOK = true; break; } else invalid( errors, t, t.object() + " must be a literal"); } else if ( t.object() instanceof Resource && !instances.find( (Resource)t.object(), RDF.type, rangeClass ).isEmpty() ) { // System.err.println("RANGE CHECKED: " + rangeClass); rangeOK = true; break; } } if(!rangeOK) if(noSchema(errors, t.object())) break; else invalid( errors, t, "Object must be instance of " + expected); } else if(ranges.size() > 1) invalid( errors, null, "Invalid schema. Multiple ranges for " + t.predicate() ); } } // Don't check containers. I'm not convinced about it. /* for(Enumeration en = containers.elements(); en.hasMoreElements();) { Statement t = (Statement)en.nextElement(); Resource c = t.subject(); // must be subclass of Container if( this.find( t.subject(), RDF.type, RDFS.Container ).size() == 0 ) invalid( errors, t, t.subject().toString() + " must be an instance of rdfs:Container" ); } */ if(errors.length() > 0) { // System.err.println("MODEL"); // RDFUtil.printStatements(instances, System.err); // System.err.println("SCHEMA"); // RDFUtil.printStatements(schema.get(), System.err); throw new InvalidModelException(errors.toString()); } } static boolean noSchema(StringBuffer b, RDFNode object) { return false; /* if(!(object instanceof Resource)) return false; if(!schema.contains(RDFUtil.getNS(object.toString()))) { invalid( b, null, "No schema available for " + object + ". Possible reason: API-constructed model, has to fetch schema explicitly"); return true; } return false; */ } 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 readModelsFromArgList(RDFFactory f, Model m, Model rawSchema, String[] args) throws Exception { String fileNameOrURL = args[0]; System.out.println("READING INSTANCE: " + fileNameOrURL); RDFUtil.parse(fileNameOrURL, f.createParser(), m); // in case there is schema info in the instance, append in to the schema // SetOperations.unite(rawSchema, m); for(int i = 1; i < args.length; i++) { String schemaURL = args[i]; Model partialSchema = f.createModel(); System.out.println("READING SCHEMA: " + schemaURL); RDFUtil.parse(schemaURL, f.createParser(), partialSchema); SetOperations.unite(rawSchema, partialSchema); } } public static void main(String[] args) throws Exception { // testing closure if(args.length == 0) { System.err.println("RDFSchemaModel <instance URL> {<schema URL>}+"); System.exit(1); } RDFFactory f = new RDFFactoryImpl(); Model m = f.createModel(); Model rawSchema = f.createModel(); readModelsFromArgList(f, m, rawSchema, args); // RDFUtil.printStatements(m, System.out); try { RDFSchemaModel.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 + -