package org.neo4j.meta.model; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import java.util.Arrays; import java.util.List; import org.junit.Test; import org.neo4j.graphdb.Node; import org.neo4j.meta.MetaTestCase; import org.neo4j.meta.model.ClassRange; import org.neo4j.meta.model.DataRange; import org.neo4j.meta.model.DatatypeClassRange; import org.neo4j.meta.model.PropertyLookerUpper; import org.neo4j.meta.model.MetaModel; import org.neo4j.meta.model.MetaModelClass; import org.neo4j.meta.model.MetaModelImpl; import org.neo4j.meta.model.MetaModelNamespace; import org.neo4j.meta.model.MetaModelProperty; import org.neo4j.meta.model.MetaModelRestrictable; import org.neo4j.meta.model.MetaModelPropertyRestriction; import org.neo4j.meta.model.RdfUtil; public class TestOverall extends MetaTestCase { /** * Tests some basic stuff. */ @Test public void testSome() { MetaModel structure = new MetaModelImpl( graphDb(), indexService() ); assertEquals( 0, structure.getNamespaces().size() ); MetaModelNamespace namespace = structure.getGlobalNamespace(); assertNull( namespace.getName() ); assertEquals( 1, structure.getNamespaces().size() ); assertEquals( namespace, structure.getGlobalNamespace() ); assertNull( structure.getNamespace( "something", false ) ); MetaModelNamespace anotherNamespace = structure.getNamespace( "something", true ); assertNotNull( anotherNamespace ); assertEquals( 0, namespace.getMetaClasses().size() ); assertEquals( 0, namespace.getMetaProperties().size() ); assertNull( namespace.getMetaClass( "http://test#Thing", false ) ); MetaModelClass thingClass = namespace.getMetaClass( "http://test#Thing", true ); assertNotNull( thingClass ); assertNotNull( namespace.getMetaClass( "http://test#Thing", false ) ); assertEquals( 1, namespace.getMetaClasses().size() ); assertEquals( 0, namespace.getMetaProperties().size() ); MetaModelClass phoneClass = namespace.getMetaClass( "http://test#Phone", true ); assertEquals( 2, namespace.getMetaClasses().size() ); thingClass.getDirectSubs().add( phoneClass ); MetaModelProperty phoneTypeProperty = namespace.getMetaProperty( "http://test#phoneType", true ); phoneTypeProperty.setRange( new DataRange( RdfUtil.NS_XML_SCHEMA + "string", "home", "work", "cell" ) ); assertCollection( ( ( DataRange ) phoneTypeProperty.getRange() ). getValues(), "home", "work", "cell" ); assertEquals( 1, namespace.getMetaProperties().size() ); phoneClass.getDirectProperties().add( phoneTypeProperty ); assertCollection( phoneTypeProperty.associatedMetaPropertyContainers(), phoneClass ); MetaModelProperty phoneNumberProperty = namespace.getMetaProperty( "http://test#phoneNumber", true ); assertEquals( 2, namespace.getMetaProperties().size() ); phoneClass.getDirectProperties().add( phoneNumberProperty ); MetaModelClass personClass = namespace.getMetaClass( "http://test#Person", true ); personClass.getDirectSupers().add( thingClass ); MetaModelProperty nameProperty = namespace.getMetaProperty( "http://test#name", true ); nameProperty.setRange( new DatatypeClassRange( String.class ) ); assertEquals( DatatypeClassRange.class, nameProperty.getRange().getClass() ); assertEquals( String.class, ( ( DatatypeClassRange ) nameProperty.getRange() ).getRangeClass() ); MetaModelProperty givenNameProperty = namespace.getMetaProperty( "http://test#givenName", true ); nameProperty.getDirectSubs().add( givenNameProperty ); MetaModelRelationship phoneProperty = namespace.getMetaRelationship( "http://test#phone", true ); phoneProperty.setRange( new ClassRange( phoneClass ) ); assertEquals( phoneProperty.getName(), ( ( ClassRange ) phoneProperty.getRange() ).getRelationshipTypeToUse().name() ); doTestRelationshipTypeRestrictable( structure, phoneProperty ); personClass.getDirectProperties().add( givenNameProperty ); MetaModelClass userClass = namespace.getMetaClass( "http://test#User", true ); personClass.getDirectSubs().add( userClass ); assertCollection( userClass.getDirectProperties() ); assertCollection( userClass.getAllProperties(), givenNameProperty ); assertTrue( personClass.isSubOf( thingClass ) ); assertTrue( userClass.isSubOf( personClass ) ); assertTrue( userClass.isSubOf( thingClass ) ); assertFalse( userClass.isSubOf( phoneClass ) ); // Direct instances Node person1 = graphDb().createNode(); Node person2 = graphDb().createNode(); assertCollection( personClass.getDirectInstances() ); personClass.getDirectInstances().add( person1 ); assertCollection( personClass.getDirectInstances(), person1 ); personClass.getDirectInstances().add( person2 ); assertCollection( personClass.getDirectInstances(), person1, person2 ); personClass.getDirectInstances().remove( person2 ); assertCollection( personClass.getDirectInstances(), person1 ); graphDb().getNodeById( person2.getId() ); personClass.getDirectInstances().add( person2 ); // All instances (recursive) assertCollection( personClass.getAllInstances(), person1, person2 ); Node user1 = graphDb().createNode(); userClass.getDirectInstances().add( user1 ); assertCollection( personClass.getAllInstances(), person1, person2, user1 ); assertCollection( userClass.getDirectInstances(), user1 ); assertCollection( userClass.getAllInstances(), user1 ); //Instance range MetaModelClass adminClass = namespace.getMetaClass( "http://test#Admin", true ); userClass.getDirectSubs().add( adminClass ); Node admin1 = graphDb().createNode(); Node admin2 = graphDb().createNode(); InstanceRange iRange = new InstanceEnumerationRange(admin1, admin2); adminClass.setRange(iRange); assertCollection( adminClass.getAllInstances(), admin1, admin2); deleteMetaModel(); } /** * Tests extended functionality, like OWL constructs. */ @Test public void testExtended() { MetaModel structure = new MetaModelImpl( graphDb(), indexService() ); MetaModelNamespace namespace = structure.getGlobalNamespace(); MetaModelProperty maker = namespace.getMetaProperty( "http://test.org/test#maker", true ); MetaModelProperty madeBy = namespace.getMetaProperty( "http://test.org/test#madeBy", true ); assertNull( maker.getInverseOf() ); assertNull( madeBy.getInverseOf() ); maker.setInverseOf( madeBy ); assertEquals( maker, madeBy.getInverseOf() ); assertEquals( madeBy, maker.getInverseOf() ); madeBy.setInverseOf( maker ); assertEquals( maker, madeBy.getInverseOf() ); assertEquals( madeBy, maker.getInverseOf() ); maker.setInverseOf( null ); assertNull( maker.getInverseOf() ); assertNull( madeBy.getInverseOf() ); deleteMetaModel(); } /** * Tests restrictions. */ @Test public void testRestrictions() { MetaModel structure = new MetaModelImpl( graphDb(), indexService() ); MetaModelNamespace namespace = structure.getGlobalNamespace(); MetaModelClass thing = namespace.getMetaClass( "thing", true ); MetaModelClass person = namespace.getMetaClass( "person", true ); MetaModelClass user = namespace.getMetaClass( "user", true ); thing.getDirectSubs().add( person ); person.getDirectSubs().add( user ); MetaModelProperty name = namespace.getMetaProperty( "name", true ); MetaModelProperty nickName = namespace.getMetaProperty( "nickname", true ); nickName.getDirectSupers().add( name ); MetaModelPropertyRestriction personNickNameRestriction = person.getRestriction( nickName, true ); assertCollection( thing.getDirectPropertyRestrictions() ); assertCollection( thing.getAllPropertyRestrictions() ); assertCollection( person.getDirectPropertyRestrictions(), personNickNameRestriction ); assertCollection( person.getAllPropertyRestrictions(), personNickNameRestriction ); assertCollection( user.getDirectPropertyRestrictions() ); assertCollection( user.getAllPropertyRestrictions(), personNickNameRestriction ); person.getDirectProperties().add( name ); MetaModelPropertyRestriction personNameRestriction = person.getRestriction( name, true ); assertNotNull( personNameRestriction ); assertCollection( person.getDirectPropertyRestrictions(), personNameRestriction, personNickNameRestriction ); assertCollection( person.getAllPropertyRestrictions(), personNameRestriction, personNickNameRestriction ); assertCollection( user.getDirectPropertyRestrictions() ); assertCollection( user.getAllPropertyRestrictions(), personNameRestriction, personNickNameRestriction ); MetaModelPropertyRestriction userNameRestriction = user.getRestriction( name, true ); assertNotNull( userNameRestriction ); assertCollection( user.getDirectPropertyRestrictions(), userNameRestriction ); assertCollection( user.getAllPropertyRestrictions(), personNameRestriction, userNameRestriction, personNickNameRestriction ); MetaModelPropertyRestriction userNickNameRestriction = user.getRestriction( nickName, true ); assertNotNull( userNickNameRestriction ); assertCollection( user.getDirectPropertyRestrictions(), userNameRestriction, userNickNameRestriction ); assertCollection( user.getAllPropertyRestrictions(), personNameRestriction, userNameRestriction, userNickNameRestriction, personNickNameRestriction ); doTestPropertyTypeRestrictable( structure, userNameRestriction ); deleteMetaModel(); } private void doTestRelationshipTypeRestrictable( MetaModel structure, MetaModelRestrictable<RelationshipRange> restrictable ) { assertNull( restrictable.getMaxCardinality() ); assertNull( restrictable.getMinCardinality() ); restrictable.setMinCardinality( null ); restrictable.setMaxCardinality( 10 ); assertNull( restrictable.getMinCardinality() ); assertEquals( 10, ( int ) restrictable.getMaxCardinality() ); restrictable.setMinCardinality( 5 ); assertEquals( 5, ( int ) restrictable.getMinCardinality() ); assertNull( restrictable.getCollectionBehaviourClass() ); restrictable.setCollectionBehaviourClass( List.class ); assertEquals( List.class, restrictable.getCollectionBehaviourClass() ); restrictable.setCollectionBehaviourClass( null ); assertNull( restrictable.getCollectionBehaviourClass() ); restrictable.setMinCardinality( null ); restrictable.setMaxCardinality( null ); assertNull( restrictable.getMaxCardinality() ); assertNull( restrictable.getMinCardinality() ); MetaModelClass testClass = structure.getGlobalNamespace(). getMetaClass( "rangeTestClass", true ); restrictable.setRange( new ClassRange( testClass ) ); assertCollection( Arrays.asList( ( ( ClassRange ) restrictable.getRange() ).getRangeClasses() ), testClass ); } private void doTestPropertyTypeRestrictable( MetaModel structure, MetaModelRestrictable<PropertyRange> restrictable ) { assertNull( restrictable.getMaxCardinality() ); assertNull( restrictable.getMinCardinality() ); restrictable.setMinCardinality( null ); restrictable.setMaxCardinality( 10 ); assertNull( restrictable.getMinCardinality() ); assertEquals( 10, ( int ) restrictable.getMaxCardinality() ); restrictable.setMinCardinality( 5 ); assertEquals( 5, ( int ) restrictable.getMinCardinality() ); assertNull( restrictable.getCollectionBehaviourClass() ); restrictable.setCollectionBehaviourClass( List.class ); assertEquals( List.class, restrictable.getCollectionBehaviourClass() ); restrictable.setCollectionBehaviourClass( null ); assertNull( restrictable.getCollectionBehaviourClass() ); restrictable.setMinCardinality( null ); restrictable.setMaxCardinality( null ); assertNull( restrictable.getMaxCardinality() ); assertNull( restrictable.getMinCardinality() ); restrictable.setRange( new DatatypeClassRange( Float.class ) ); assertEquals( Float.class, ( ( DatatypeClassRange ) restrictable.getRange() ).getRangeClass() ); } /** * Tests the "lookup" functionality. */ @Test public void testLookup() { MetaModel meta = new MetaModelImpl( graphDb(), indexService() ); MetaModelNamespace namespace = meta.getGlobalNamespace(); // The classes MetaModelClass thing = namespace.getMetaClass( "thing", true ); MetaModelClass organism = namespace.getMetaClass( "organism", true ); MetaModelClass person = namespace.getMetaClass( "person", true ); MetaModelClass user = namespace.getMetaClass( "user", true ); MetaModelClass musicListener = namespace.getMetaClass( "musicListener", true ); MetaModelClass song = namespace.getMetaClass( "song", true ); // Class hierarchy organism.getDirectSupers().add( thing ); person.getDirectSupers().add( organism ); user.getDirectSupers().add( person ); musicListener.getDirectSupers().add( person ); // Properties MetaModelProperty size = namespace.getMetaProperty( "size", true ); size.setRange( new DatatypeClassRange( Integer.class ) ); MetaModelProperty age = namespace.getMetaProperty( "age", true ); age.setRange( new DatatypeClassRange( Integer.class ) ); MetaModelProperty name = namespace.getMetaProperty( "name", true ); name.setRange( new DatatypeClassRange( String.class ) ); MetaModelProperty nickName = namespace.getMetaProperty( "nickname", true ); MetaModelProperty login = namespace.getMetaProperty( "login", true ); MetaModelRelationship likes = namespace.getMetaRelationship( "likes", true ); likes.setRange( new ClassRange( thing ) ); // Property hierarchy login.getDirectSupers().add( name ); nickName.getDirectSupers().add( name ); // Domains and properties thing.getDirectProperties().add( size ); organism.getDirectProperties().add( age ); person.getDirectProperties().add( nickName ); person.getDirectRelationships().add( likes ); user.getDirectProperties().add( login ); age.setCardinality( 1 ); // Restrictions organism.getRestriction( size, true ).setCardinality( 1 ); person.getRestriction( nickName, true ).setMinCardinality( 0 ); person.getRestriction( nickName, false ).setMaxCardinality( 5 ); user.getRestriction( login, true ).setCardinality( 1 ); musicListener.getRestriction( likes, true ).setRange( new ClassRange( song ) ); // Verify assertLookup( meta, size, MetaModel.LOOKUP_PROPERTY_MIN_CARDINALITY, null, thing ); assertLookup( meta, size, MetaModel.LOOKUP_PROPERTY_MIN_CARDINALITY, 1, organism ); assertLookup( meta, age, MetaModel.LOOKUP_PROPERTY_MAX_CARDINALITY, 1, thing, organism, person, user, musicListener, song ); assertEquals( String.class, ( ( DatatypeClassRange ) meta.lookup( nickName, MetaModel.LOOKUP_PROPERTY_RANGE, user ) ).getRangeClass() ); assertCollection( Arrays.asList( ( ( ClassRange ) meta.lookup( likes, MetaModel.LOOKUP_RELATIONSHIPTYPE_RANGE, musicListener ) ).getRangeClasses() ), song ); assertCollection( Arrays.asList( ( ( ClassRange ) meta.lookup( likes, MetaModel.LOOKUP_RELATIONSHIPTYPE_RANGE, person ) ).getRangeClasses() ), thing ); deleteMetaModel(); } private <T> void assertLookup( MetaModel meta, MetaModelProperty property, PropertyLookerUpper<T> finder, T expectedValue, MetaModelClass... classes ) { T value = meta.lookup( property, finder, classes ); if ( expectedValue == null ) { assertNull( value ); } else { assertEquals( expectedValue, value ); } } private <T> void assertLookup( MetaModel meta, MetaModelRelationship relationshipType, RelationshipLookerUpper<T> finder, T expectedValue, MetaModelClass... classes ) { T value = meta.lookup( relationshipType, finder, classes ); if ( expectedValue == null ) { assertNull( value ); } else { assertEquals( expectedValue, value ); } } }