package org.neo4j.rdf.store;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Random;
import javax.transaction.SystemException;
import org.neo4j.index.IndexService;
import org.neo4j.index.lucene.LuceneIndexService;
import org.neo4j.rdf.fulltext.FulltextIndex;
import org.neo4j.rdf.fulltext.SimpleFulltextIndex;
import org.neo4j.rdf.model.CompleteStatement;
import org.neo4j.rdf.model.Context;
import org.neo4j.rdf.model.Literal;
import org.neo4j.rdf.model.Resource;
import org.neo4j.rdf.model.Statement;
import org.neo4j.rdf.model.Uri;
import org.neo4j.rdf.model.Value;
import org.neo4j.rdf.model.Wildcard;
import org.neo4j.rdf.model.WildcardStatement;
import org.neo4j.rdf.store.representation.standard.AbstractUriBasedExecutor;
public abstract class StoreTestCase extends Neo4jWithIndexTestCase
{
public static final String BASE_URI = "http://uri.neo4j.org/";
public static final Wildcard WILDCARD_SUBJECT = new Wildcard( "subject" );
public static final Wildcard WILDCARD_PREDICATE= new Wildcard(
"predicate" );
public static final Wildcard WILDCARD_OBJECT = new Wildcard( "object" );
public static final Uri PERSON = new Uri( "http://person" );
public static final Uri NAME = new Uri( "http://name" );
public static final Uri NICKNAME = new Uri( "http://nickname" );
public static final Uri KNOWS = new Uri( "http://knows" );
public static final Context TEST_CONTEXT = new Context( "aTest" );
private RdfStore store = null;
private FulltextIndex fulltextIndex;
@Override
protected void setUp() throws Exception
{
super.setUp();
createStoreIfNeeded();
}
@Override
protected void tearDown() throws Exception
{
tearDownStoreIfNeeded();
super.tearDown();
}
private void createStoreIfNeeded()
{
if ( store() == null )
{
this.fulltextIndex = instantiateFulltextIndex();
this.store = instantiateStore();
}
}
private void tearDownStoreIfNeeded()
{
if ( store() != null )
{
// TODO, not really nice
FulltextIndex fulltextIndex =
( ( RdfStoreImpl ) this.store ).getFulltextIndex();
if ( fulltextIndex != null )
{
fulltextIndex.clear();
}
this.store.shutDown();
this.store = null;
}
}
@Override
protected void restartTx()
{
try
{
// Temporary solution
int txId =
graphDbUtil().getTransactionManager().getTransaction().hashCode();
super.restartTx();
FulltextIndex fulltextIndex =
( ( RdfStoreImpl ) store ).getFulltextIndex();
if ( fulltextIndex != null )
{
fulltextIndex.end( txId, true );
}
}
catch ( SystemException e )
{
throw new RuntimeException( e );
}
}
protected RdfStore store()
{
return this.store;
}
protected FulltextIndex fulltextIndex()
{
return this.fulltextIndex;
}
@Override
protected IndexService instantiateIndexService()
{
return new LuceneIndexService( graphDb() );
}
protected FulltextIndex instantiateFulltextIndex()
{
return new SimpleFulltextIndex( graphDb(), new File( getBasePath(),
"fulltext" ) );
}
protected abstract RdfStore instantiateStore();
protected void waitForFulltextIndex()
{
try
{
while ( !fulltextIndex().queueIsEmpty() )
{
Thread.sleep( 50 );
}
}
catch ( InterruptedException e )
{
}
}
protected void debug( String text )
{
System.out.println( text );
}
protected void add( RdfStore store, Statement statement, int numberOfTimes )
{
if ( !(statement instanceof CompleteStatement ) )
{
throw new IllegalArgumentException(
"Can only add complete statements " );
}
while ( numberOfTimes-- > 0 )
{
debug( "addStatement " + statement );
store.addStatements( ( CompleteStatement ) statement );
}
}
protected void remove( RdfStore store, WildcardStatement statement,
int numberOfTimes )
{
while ( numberOfTimes-- > 0 )
{
debug( "removeStatement " + statement );
store.removeStatements( statement );
}
}
protected Statement statement( String subject, String predicate,
Resource object, Context context )
{
return new CompleteStatement( new Uri( subject ), new Uri( predicate ),
object, context, null );
}
protected Statement statement( String subject, String predicate,
Object object, Context context )
{
return new CompleteStatement( new Uri( subject ), new Uri( predicate ),
new Literal( object ), context, null );
}
protected void removeStatements( RdfStore store,
List<CompleteStatement> statements )
{
removeStatements( store, statements, 1 );
}
protected void removeStatements( RdfStore store,
List<CompleteStatement> statements, int numberOfTimesForEach )
{
while ( !statements.isEmpty() )
{
CompleteStatement statement = statements.remove(
new Random().nextInt( statements.size() ) );
WildcardStatement wildcardStatement =
statement.asWildcardStatement();
remove( store, wildcardStatement, numberOfTimesForEach );
}
}
protected void assertResultCount( WildcardStatement wildcard,
int expectedCount )
{
Iterator<CompleteStatement> result =
store().getStatements( wildcard, false ).iterator();
int resultCount = 0;
while ( result.hasNext() )
{
result.next();
resultCount++;
}
assertEquals( expectedCount, resultCount );
}
protected void assertResult( WildcardStatement wildcard,
CompleteStatement... expectedResult )
{
Collection<CompleteStatement> expectedResultCollection =
new ArrayList<CompleteStatement>( Arrays.asList( expectedResult ) );
Iterable<CompleteStatement> result =
store().getStatements( wildcard, false );
for ( CompleteStatement resultStatement : result )
{
CompleteStatement foundEquivalentStatement = null;
for ( CompleteStatement expectedResultStatement :
expectedResultCollection )
{
if ( statementsAreEquivalent( resultStatement,
expectedResultStatement ) )
{
foundEquivalentStatement = expectedResultStatement;
break;
}
}
assertTrue( "Result found in store, but not in expected list: " +
resultStatement, foundEquivalentStatement != null );
expectedResultCollection.remove( foundEquivalentStatement );
}
assertTrue( "Statements which should've been found " +
expectedResultCollection, expectedResultCollection.isEmpty() );
}
protected void assertEquivalentStatement( Statement first,
Statement second )
{
assertTrue( statementsAreEquivalent( first, second ) );
}
protected boolean statementsAreEquivalent( Statement first,
Statement second )
{
return first.getSubject().equals( second.getSubject() ) &&
first.getPredicate().equals( second.getPredicate() ) &&
first.getObject().equals( second.getObject() ) &&
first.getContext().equals( second.getContext() );
}
protected void addStatements( CompleteStatement... statements )
{
store().addStatements( statements );
}
protected void removeStatements( WildcardStatement statement )
{
store.removeStatements( statement );
}
static CompleteStatement completeStatement( TestUri subject,
TestUri predicate, TestUri object, TestUri context )
{
return completeStatement( subject.uriAsString(),
predicate.uriAsString(), object.uriAsString(),
context.uriAsString() );
}
static CompleteStatement completeStatement( TestUri subject,
TestUri predicate, TestUri object, Context context )
{
return completeStatement( subject.uriAsString(),
predicate.uriAsString(), object.uriAsString(),
context.getUriAsString() );
}
static CompleteStatement completeStatement( TestUri subject,
TestUri predicate, Literal objectLiteral, Context context )
{
return new CompleteStatement(
new Uri( subject.uriAsString() ),
new Uri( predicate.uriAsString() ),
objectLiteral,
context );
}
static CompleteStatement completeStatement( String subjectUri,
String predicateUri, String objectUri, String contextUri )
{
return new CompleteStatement(
new Uri( subjectUri ),
new Uri( predicateUri ),
new Uri( objectUri ),
new Context( contextUri ) );
}
static CompleteStatement completeStatement( TestUri subject,
TestUri predicate, Literal objectLiteral, TestUri context )
{
return new CompleteStatement(
new Uri( subject.uriAsString() ),
new Uri( predicate.uriAsString() ),
objectLiteral,
new Context( context.uriAsString() ), null );
}
static WildcardStatement wildcardStatement( TestUri subject, TestUri
predicate, TestUri object, TestUri context )
{
return wildcardStatement( subject.toUri(), predicate.toUri(),
object.toUri(), new Context( context.uriAsString() ) );
}
static WildcardStatement wildcardStatement( TestUri subject, TestUri
predicate, TestUri object, Value context )
{
return wildcardStatement( subject.toUri(), predicate.toUri(),
object.toUri(), context );
}
static WildcardStatement wildcardStatement( Value subject, Value predicate,
Value object, Value context )
{
return new WildcardStatement( subject, predicate, object, context );
}
public enum TestUri
{
EMIL( "person/emil" ),
MATTIAS( "person/mattias" ),
JOHAN( "person/johan" ),
FOAF_KNOWS( "foaf_knows" ),
FOAF_NICK( "foaf_nick" ),
FOAF_NAME( "foaf_name" ),
EMIL_PUBLIC_GRAPH( "context/emil-public" ),
EMIL_PRIVATE_GRAPH( "context/emil-private" ),
MATTIAS_PUBLIC_GRAPH( "context/mattias-public" ),
MATTIAS_PRIVATE_GRAPH( "context/mattias-private" ),
PERSON( "person" ),
RDF_TYPE( AbstractUriBasedExecutor.RDF_TYPE_URI ),
;
private final String uri;
TestUri( String uri )
{
if ( uri.startsWith( "http://" ) || uri.contains( ":" ) )
{
this.uri = uri;
}
else
{
this.uri = BASE_URI + uri;
}
}
public String uriAsString()
{
return this.uri;
}
public Uri toUri()
{
return new Uri( uriAsString() );
}
@Override
public String toString()
{
return uriAsString();
}
}
}