Package org.qi4j.entitystore.gae

Source Code of org.qi4j.entitystore.gae.GaeEntityState$GaeManyAssociationState

/*
* Copyright 2010 Niclas Hedhman.
*
* 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.entitystore.gae;

import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.Text;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.qi4j.api.common.QualifiedName;
import org.qi4j.api.entity.EntityDescriptor;
import org.qi4j.api.entity.EntityReference;
import org.qi4j.api.property.PropertyDescriptor;
import org.qi4j.api.structure.Module;
import org.qi4j.api.type.ValueCompositeType;
import org.qi4j.api.type.ValueType;
import org.qi4j.api.value.ValueSerialization;
import org.qi4j.api.value.ValueSerializationException;
import org.qi4j.spi.entity.EntityState;
import org.qi4j.spi.entity.EntityStatus;
import org.qi4j.spi.entity.ManyAssociationState;
import org.qi4j.spi.entity.NamedAssociationState;

import static org.qi4j.functional.Iterables.first;
import static org.qi4j.functional.Iterables.toList;

public class GaeEntityState
    implements EntityState
{
    static final String PROPERTY_TYPE = "$type";

    private final Entity entity;
    private EntityStatus status;
    private final GaeEntityStoreUnitOfWork unitOfWork;
    private final ValueSerialization valueSerialization;
    private final EntityDescriptor descriptor;
    private final HashMap<QualifiedName, ValueType> valueTypes;
    private final Module module;

    public GaeEntityState( GaeEntityStoreUnitOfWork unitOfWork,
                           ValueSerialization valueSerialization,
                           Key key,
                           EntityDescriptor descriptor,
                           Module module )
    {
        System.out.println( "GaeEntityState( " + unitOfWork + ", " + key + ", " + descriptor + " )" );
        this.module = module;
        this.unitOfWork = unitOfWork;
        this.valueSerialization = valueSerialization;
        this.descriptor = descriptor;
        entity = new Entity( key );
        entity.setProperty( "$version", unitOfWork.identity() );
        Class type = first( descriptor.types() );
        String name = type.getName();
        System.out.println( "New Entity\n" +
                            "    descriptor:" + descriptor + "\n  " +
                            "    entityType:" + name + "\n  " +
                            "    name:" + name + "\n  "
        );
        entity.setUnindexedProperty( PROPERTY_TYPE, name );
        status = EntityStatus.NEW;
        valueTypes = initializeValueTypes( descriptor );
    }

    public GaeEntityState( GaeEntityStoreUnitOfWork unitOfWork,
                           ValueSerialization valueSerialization,
                           Entity entity,
                           Module module )
    {
        System.out.println( "GaeEntityState( " + unitOfWork + ", " + entity + " )" );
        if( entity == null )
        {
            throw new NullPointerException();
        }
        if( unitOfWork == null )
        {
            throw new NullPointerException();
        }
        this.module = module;
        this.unitOfWork = unitOfWork;
        this.valueSerialization = valueSerialization;
        this.entity = entity;
        String typeName = (String) entity.getProperty( GaeEntityState.PROPERTY_TYPE );
        System.out.println( "LOADING [" + typeName + "]" );
        descriptor = module.entityDescriptor( typeName );
        status = EntityStatus.LOADED;
        valueTypes = initializeValueTypes( descriptor );
    }

    private HashMap<QualifiedName, ValueType> initializeValueTypes( EntityDescriptor descriptor )
    {
        HashMap<QualifiedName, ValueType> result = new HashMap<QualifiedName, ValueType>();
        for( PropertyDescriptor persistent : descriptor.state().properties() )
        {
            if( persistent.valueType() instanceof ValueCompositeType )
            {
                QualifiedName name = persistent.qualifiedName();
                result.put( name, persistent.valueType() );
            }
        }
        return result;
    }

    Entity entity()
    {
        System.out.println( "entity()  -->  " + entity );
        return entity;
    }

    @Override
    public EntityReference identity()
    {
        EntityReference ref = new EntityReference( entity.getKey().getName() );
        System.out.println( "identity()  -->  " + ref );
        return ref;
    }

    @Override
    public String version()
    {
        String version = (String) entity.getProperty( "$version" );
        System.out.println( "version()  -->  " + version );
        return version;
    }

    @Override
    public long lastModified()
    {
        Long lastModified = (Long) entity.getProperty( "$lastModified" );
        System.out.println( "lastModified()  -->  " + lastModified );
        return lastModified;
    }

    @Override
    public void remove()
    {
        System.out.println( "remove()" );
        status = EntityStatus.REMOVED;
    }

    @Override
    public EntityStatus status()
    {
        System.out.println( "status()  -->  " + status );
        return status;
    }

    @Override
    public boolean isAssignableTo( Class<?> type )
    {
        System.out.println( "isAssignableTo( " + type + " )  -->  false" );
        return false;
    }

    @Override
    public EntityDescriptor entityDescriptor()
    {
        System.out.println( "entityDescriptor()  -->  " + descriptor );
        return descriptor;
    }

    @Override
    public Object propertyValueOf( QualifiedName stateName )
    {
        String uri = stateName.toURI();
        Object value = entity.getProperty( uri );
        if( value instanceof Text )
        {
            value = ( (Text) value ).getValue();
        }
        ValueType type = valueTypes.get( stateName );
        if( value != null && type != null )
        {
            try
            {
                value = valueSerialization.deserialize( type, value.toString() );
            }
            catch( ValueSerializationException e )
            {
                String message = "\nqualifiedName: " + stateName +
                                 "\n    stateName: " + stateName.name() +
                                 "\n          uri: " + uri +
                                 "\n         type: " + type +
                                 "\n        value: " + value +
                                 "\n";
                InternalError error = new InternalError( message );
                error.initCause( e );
                throw error;
            }
        }
        System.out.println( "getProperty( " + stateName + " )  -->  " + uri + "=" + value );
        return value;
    }

    @Override
    public void setPropertyValue( QualifiedName stateName, Object newValue )
    {
        System.out.println( "setProperty( " + stateName + ", " + newValue + " )" );
        Object value = null;
        if( newValue == null || ValueType.isPrimitiveValue( newValue ) )
        {
            value = newValue;
        }
        else
        {
            try
            {
                value = valueSerialization.serialize( newValue );
            }
            catch( ValueSerializationException e )
            {
                String message = "\nqualifiedName: " + stateName +
                                 "\n    stateName: " + stateName.name() +
                                 "\n        class: " + newValue.getClass() +
                                 "\n        value: " + value +
                                 "\n";
                InternalError error = new InternalError( message );
                error.initCause( e );
                throw error;
            }
        }
        if( value instanceof String )
        {
            value = new Text( (String) value );
        }
        entity.setUnindexedProperty( stateName.toURI(), value );
    }

    @Override
    public EntityReference associationValueOf( QualifiedName stateName )
    {
        String uri = stateName.toURI();
        String identity = (String) entity.getProperty( uri );
        System.out.println( "association( " + stateName + " )  -->  " + uri + " = " + identity );
        EntityReference ref = new EntityReference( identity );
        return ref;
    }

    @Override
    public void setAssociationValue( QualifiedName stateName, EntityReference newEntity )
    {
        System.out.println( "setAssociation( " + stateName + ", " + newEntity + " )" );
        String uri = stateName.toURI();
        String id = null;
        if( newEntity != null )
        {
            id = newEntity.identity();
        }
        entity.setUnindexedProperty( uri, id );
    }

    @Override
    public ManyAssociationState manyAssociationValueOf( QualifiedName stateName )
    {
        List<String> assocs = (List<String>) entity.getProperty( stateName.toURI() );
        ManyAssociationState state = new GaeManyAssociationState( this, assocs );
        return state;
    }

    @Override
    public NamedAssociationState namedAssociationValueOf( QualifiedName stateName )
    {
        Map<String, String> assocs = (Map<String, String>) entity.getProperty( stateName.toURI() );
        NamedAssociationState state = new GaeNamedAssociationState( this, assocs );
        return state;
    }

    public void hasBeenApplied()
    {
        System.out.println( "hasBeenApplied()" );
        status = EntityStatus.LOADED;
    }

    private static class GaeManyAssociationState
        implements ManyAssociationState
    {
        private List<String> assocs;
        private final GaeEntityState entityState;

        public GaeManyAssociationState( GaeEntityState entityState, List<String> listOfAssociations )
        {
            this.entityState = entityState;
            if( listOfAssociations == null )
            {
                this.assocs = new ArrayList<String>();
            }
            else
            {
                this.assocs = listOfAssociations;
            }
        }

        @Override
        public int count()
        {
            return assocs.size();
        }

        @Override
        public boolean contains( EntityReference entityReference )
        {
            return assocs.contains( entityReference.identity() );
        }

        @Override
        public boolean add( int index, EntityReference entityReference )
        {
            System.out.println( "NICLAS::" + entityReference );
            String identity = entityReference.identity();
            System.out.println( "NICLAS::" + identity );
            System.out.println( "NICLAS::" + assocs );
            if( assocs.contains( identity ) )
            {
                return false;
            }
            assocs.add( index, entityReference.identity() );
            entityState.markUpdated();
            return true;
        }

        @Override
        public boolean remove( EntityReference entityReference )
        {
            return assocs.remove( entityReference.identity() );
        }

        @Override
        public EntityReference get( int index )
        {
            String id = assocs.get( index );
            return new EntityReference( id );
        }

        @Override
        public Iterator<EntityReference> iterator()
        {
            ArrayList<EntityReference> result = new ArrayList<EntityReference>();
            for( String id : assocs )
            {
                result.add( new EntityReference( id ) );
            }
            return result.iterator();
        }
    }

    private static class GaeNamedAssociationState
        implements NamedAssociationState
    {
        private final Map<String, String> assocs;
        private final GaeEntityState entityState;

        private GaeNamedAssociationState( GaeEntityState entityState, Map<String, String> associations )
        {
            this.entityState = entityState;
            if( associations == null )
            {
                this.assocs = new HashMap<>();
            }
            else
            {
                this.assocs = associations;
            }
        }

        @Override
        public int count()
        {
            return assocs.size();
        }

        @Override
        public boolean containsName( String name )
        {
            return assocs.containsKey( name );
        }

        @Override
        public boolean put( String name, EntityReference entityReference )
        {
            if( assocs.containsKey( name ) && entityReference.identity().equals( assocs.get( name ) ) )
            {
                return false;
            }
            assocs.put( name, entityReference.identity() );
            entityState.markUpdated();
            return true;
        }

        @Override
        public boolean remove( String name )
        {
            boolean removed = assocs.remove( name ) != null;
            entityState.markUpdated();
            return removed;
        }

        @Override
        public EntityReference get( String name )
        {
            return new EntityReference( assocs.get( name ) );
        }

        @Override
        public String nameOf( EntityReference entityReference )
        {
            String identity = entityReference.identity();
            for( Map.Entry<String, String> entry : assocs.entrySet() )
            {
                if( identity.equals( entry.getValue() ) )
                {
                    return entry.getKey();
                }
            }
            return null;
        }

        @Override
        public Iterator<String> iterator()
        {
            return toList( assocs.keySet() ).iterator();
        }

    }

    private void markUpdated()
    {
        if( status == EntityStatus.LOADED )
        {
            status = EntityStatus.UPDATED;
        }
    }
}
TOP

Related Classes of org.qi4j.entitystore.gae.GaeEntityState$GaeManyAssociationState

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.