blob: c1458b451141ca5989bf051db06403d02a049621 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.jena.arq.junit.manifest;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.function.Consumer;
import org.apache.jena.atlas.lib.IRILib;
import org.apache.jena.rdf.model.* ;
import org.apache.jena.riot.RDFDataMgr;
import org.apache.jena.vocabulary.RDF ;
import org.apache.jena.vocabulary.RDFS ;
import org.apache.jena.vocabulary.TestManifest ;
import org.apache.jena.vocabulary.TestManifestX ;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* A "Manifest" is the includes and entries for a single file.
*/
public class Manifest
{
private static Logger log = LoggerFactory.getLogger(Manifest.class) ;
private Model manifest ;
private String manifestName ;
private String filename ;
private List<String> includedFiles = new ArrayList<>() ;
private List<ManifestEntry> entries = new ArrayList<>() ;
private Resource manifestRes = null ;
public static Manifest parse(String manifestFile) {
Manifest manifest = new Manifest(manifestFile);
return manifest;
}
public static void walk(Manifest manifest, Consumer<Manifest> actionManifest, Consumer<ManifestEntry> actionEntry) {
actionManifest.accept(manifest);
Iterator<String> sub = manifest.includedManifests();
while(sub.hasNext() ) {
String mf = sub.next();
Manifest manifestSub = Manifest.parse(mf);
walk(manifestSub, actionManifest, actionEntry);
}
for ( ManifestEntry entry : manifest.entries() ) {
actionEntry.accept(entry);
}
}
private Manifest(String fn) {
filename = IRILib.filenameToIRI(fn) ;
manifest = RDFDataMgr.loadModel(filename) ;
parseManifest() ;
parseIncludes() ;
parseEntries() ;
}
public String getName() { return manifestName ; }
public String getFileName() { return filename ; }
public Iterator<String> includedManifests() { return includedFiles.iterator() ; }
public List<ManifestEntry> entries() { return entries ; }
private void parseManifest()
{
StmtIterator manifestStmts = manifest.listStatements(null, RDF.type, TestManifest.Manifest);
if ( !manifestStmts.hasNext() ) {
log.warn("No manifest in manifest file: "+filename) ;
return ;
}
Statement manifestItemStmt = manifestStmts.nextStatement();
if ( manifestStmts.hasNext() ) {
log.warn("Multiple manifests in manifest file: "+filename) ;
return ;
}
manifestRes = manifestItemStmt.getSubject();
manifestName = getLiteral(manifestRes, RDFS.label) ;
if ( manifestName == null )
manifestName = getLiteral(manifestRes, RDFS.comment) ;
if ( manifestName == null )
manifestName = getLiteral(manifestRes, TestManifest.name) ;
manifestStmts.close();
}
private void parseEntries() {
StmtIterator manifestStmts = manifest.listStatements(null, RDF.type, TestManifest.Manifest);
for (; manifestStmts.hasNext();)
{
Statement manifestItemStmt = manifestStmts.nextStatement();
Resource manifestRes = manifestItemStmt.getSubject();
// For each item in this manifest
StmtIterator listIter = manifestRes.listProperties(TestManifest.entries);
for (; listIter.hasNext();)
{
//List head
Resource listItem = listIter.nextStatement().getResource();
for (; !listItem.equals(RDF.nil);)
{
Resource entry = listItem.getRequiredProperty(RDF.first).getResource();
String testName = getLiteral(entry, TestManifest.name) ;
Resource action = getResource(entry, TestManifest.action) ;
Resource result = getResource(entry, TestManifest.result) ;
Resource testType = getResource(entry, RDF.type);
ManifestEntry manifestEntry = new ManifestEntry(this, entry, testName, testType, action, result);
entries.add(manifestEntry);
// Move to next list item
listItem = listItem.getRequiredProperty(RDF.rest).getResource();
}
}
listIter.close();
}
manifestStmts.close();
}
// -------- included manifests
private void parseIncludes()
{
parseIncludes(TestManifest.include) ;
parseIncludes(TestManifestX.include) ;
}
private void parseIncludes(Property property)
{
StmtIterator includeStmts = manifest.listStatements(null, property, (RDFNode)null) ;
for (; includeStmts.hasNext(); )
{
Statement s = includeStmts.nextStatement() ;
if ( ! ( s.getObject() instanceof Resource ) )
{
log.warn("Include: not a Resource"+s) ;
continue ;
}
Resource r = s.getResource() ;
parseOneIncludesList(r) ;
}
includeStmts.close() ;
}
private void parseOneIncludesList(Resource r)
{
if ( r == null )
return ;
if ( r.equals(RDF.nil) )
return ;
if ( ! r.isAnon() )
{
String uri = r.getURI() ;
if ( includedFiles.contains(uri) )
return ;
includedFiles.add(r.getURI()) ;
return ;
}
// BNnode => list
Resource listItem = r ;
while(!listItem.equals(RDF.nil))
{
r = listItem.getRequiredProperty(RDF.first).getResource();
parseOneIncludesList(r) ;
// Move on
listItem = listItem.getRequiredProperty(RDF.rest).getResource();
}
}
private static Resource getResource(Resource r, Property p)
{
if ( r == null )
return null ;
if ( ! r.hasProperty(p) )
return null ;
RDFNode n = r.getProperty(p).getObject() ;
if ( n instanceof Resource )
return (Resource)n ;
throw new ExTestSetup("Manifest problem (not a Resource): "+n+" => "+p) ;
}
private static Collection<Resource> listResources(Resource r, Property p)
{
if ( r == null )
return null ;
List<Resource> x = new ArrayList<>() ;
StmtIterator sIter = r.listProperties(p) ;
for ( ; sIter.hasNext() ; ) {
RDFNode n = sIter.next().getObject() ;
if ( ! ( n instanceof Resource ) )
throw new ExTestSetup("Manifest problem (not a Resource): "+n+" => "+p) ;
x.add((Resource)n) ;
}
return x ;
}
private static String getLiteral(Resource r, Property p)
{
if ( r == null )
return null ;
if ( ! r.hasProperty(p) )
return null ;
RDFNode n = r.getProperty(p).getObject() ;
if ( n instanceof Literal )
return ((Literal)n).getLexicalForm() ;
throw new ExTestSetup("Manifest problem (not a Literal): "+n+" => "+p) ;
}
private static String getLiteralOrURI(Resource r, Property p)
{
if ( r == null )
return null ;
if ( ! r.hasProperty(p) )
return null ;
RDFNode n = r.getProperty(p).getObject() ;
if ( n instanceof Literal )
return ((Literal)n).getLexicalForm() ;
if ( n instanceof Resource )
{
Resource r2 = (Resource)n ;
if ( ! r2.isAnon() )
return r2.getURI() ;
}
throw new ExTestSetup("Manifest problem: "+n+" => "+p) ;
}
private static String safeName(String s)
{
// Safe from Eclipse
s = s.replace('(','[') ;
s = s.replace(')',']') ;
return s ;
}
@Override
public String toString() {
return "manifest["+filename+"]";
}
}