/*
 * Copyright (c) 2008, Rickard Öberg. All Rights Reserved.
 *
 * Licensed 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.qi4j.library.rdf.entity;

import java.util.Collections;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.junit.Assert.assertThat;
import org.junit.Before;
import org.junit.Test;
import org.openrdf.model.Statement;
import org.openrdf.rio.RDFHandlerException;
import org.qi4j.bootstrap.AssemblyException;
import org.qi4j.bootstrap.ModuleAssembly;
import org.qi4j.api.entity.EntityBuilder;
import org.qi4j.api.unitofwork.UnitOfWork;
import org.qi4j.api.unitofwork.UnitOfWorkCompletionException;
import org.qi4j.entitystore.memory.MemoryEntityStoreService;
import org.qi4j.api.injection.scope.Service;
import org.qi4j.api.injection.scope.Uses;
import org.qi4j.spi.entity.EntityState;
import org.qi4j.spi.entity.EntityStore;
import org.qi4j.spi.entity.QualifiedIdentity;
import org.qi4j.test.AbstractQi4jTest;

/**
 * TODO
 */
public class EntityParserTest
    extends AbstractQi4jTest
{
    @Service private EntityStore entityStore;
    @Uses private EntityStateSerializer serializer;
    @Uses private EntityStateParser parser;

    public void assemble( ModuleAssembly module ) throws AssemblyException
    {
        module.addServices( MemoryEntityStoreService.class );
        module.addEntities( TestEntity.class );
        module.addObjects( EntityStateSerializer.class, EntityStateParser.class, EntityParserTest.class );
    }

    @Override @Before public void setUp() throws Exception
    {
        super.setUp();

        createDummyData();
    }

    @Test
    public void testEntityParser() throws RDFHandlerException
    {
        objectBuilderFactory.newObjectBuilder( EntityParserTest.class ).injectTo( this );

        QualifiedIdentity qualifiedIdentity = new QualifiedIdentity( "test2", TestEntity.class );
        EntityState entityState = entityStore.getEntityState( qualifiedIdentity );

        Iterable<Statement> graph = serializer.serialize( entityState );

        parser.parse( graph, entityState );

        entityStore.prepare( Collections.EMPTY_LIST, Collections.singleton( entityState ), Collections.EMPTY_LIST ).commit();

        UnitOfWork unitOfWork = unitOfWorkFactory.newUnitOfWork();
        try
        {
            TestEntity entity = unitOfWork.find( "test1", TestEntity.class );
            TestEntity entity2 = unitOfWork.find( "test2", TestEntity.class );
            assertThat( "values are ok", entity2.name().get(), equalTo( "Niclas" ) );
            assertThat( "values are ok", entity2.association().get(), equalTo( entity ) );

            unitOfWork.complete();
        }
        catch( Exception e )
        {
            unitOfWork.discard();
        }
    }

    void createDummyData()
        throws UnitOfWorkCompletionException
    {
        UnitOfWork unitOfWork = unitOfWorkFactory.newUnitOfWork();
        EntityBuilder<TestEntity> builder = unitOfWork.newEntityBuilder( "test1", TestEntity.class );
        builder.stateOfComposite().name().set( "Rickard" );
        builder.stateOfComposite().title().set( "Developer" );
        TestEntity testEntity = builder.newInstance();

        EntityBuilder<TestEntity> builder2 = unitOfWork.newEntityBuilder( "test2", TestEntity.class );
        builder2.stateOfComposite().name().set( "Niclas" );
        builder2.stateOfComposite().title().set( "Developer" );
        builder2.stateOfComposite().association().set( testEntity );
        builder2.stateOfComposite().manyAssoc().add( testEntity );
        builder2.stateOfComposite().group().add( testEntity );
        builder2.stateOfComposite().group().add( testEntity );
        builder2.stateOfComposite().group().add( testEntity );
        builder2.newInstance();
        unitOfWork.complete();
    }
}
@@ -916,77 +916,77 @@
 i4j.
-bootstrap.AssemblyException;%0Aimport org.qi4j.bootstrap.ModuleAssembly
+api.entity.EntityBuilder;%0Aimport org.qi4j.api.injection.scope.Service
 ;%0Aim
@@ -1003,36 +1003,36 @@
 i4j.api.
-entity.EntityBuilder
+injection.scope.Uses
 ;%0Aimport
@@ -1150,138 +1150,178 @@
 i4j.
-entitystore.memory.MemoryEntityStoreService;%0Aimport org.qi4j.api.injection.scope.Service;%0Aimport org.qi4j.api.injection.scope.Uses
+api.value.ValueBuilder;%0Aimport org.qi4j.bootstrap.AssemblyException;%0Aimport org.qi4j.bootstrap.ModuleAssembly;%0Aimport org.qi4j.entitystore.memory.MemoryEntityStoreService
 ;%0Aim
@@ -1887,32 +1887,77 @@
 Entity.class );%0A
+        module.addValues( TestValue.class );%0A
         module.a
@@ -3403,32 +3403,246 @@
 Exception%0A    %7B%0A
+        ValueBuilder%3CTestValue%3E valueBuilder = valueBuilderFactory.newValueBuilder( TestValue.class );%0A        valueBuilder.prototype().test1().set( 4L );%0A        TestValue testValue = valueBuilder.newInstance();%0A%0A
         UnitOfWo
@@ -3909,32 +3909,93 @@
  %22Developer%22 );%0A
+        builder.stateOfComposite().value().set( testValue );%0A
         TestEnti
@@ -4578,32 +4578,94 @@
 ( testEntity );%0A
+        builder2.stateOfComposite().value().set( testValue );%0A
         builder2

Initialize TestValue as it is mandatory.