Package org.qi4j.spi.entitystore.helpers

Source Code of org.qi4j.spi.entitystore.helpers.JSONEntityState

/*  Copyright 2007 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.spi.entitystore.helpers;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.qi4j.api.common.QualifiedName;
import org.qi4j.api.entity.EntityDescriptor;
import org.qi4j.api.entity.EntityReference;
import org.qi4j.api.json.JSONDeserializer;
import org.qi4j.api.json.JSONObjectSerializer;
import org.qi4j.api.property.PropertyDescriptor;
import org.qi4j.api.structure.Module;
import org.qi4j.spi.entity.EntityState;
import org.qi4j.spi.entity.EntityStatus;
import org.qi4j.spi.entity.ManyAssociationState;
import org.qi4j.spi.entitystore.DefaultEntityStoreUnitOfWork;
import org.qi4j.spi.entitystore.EntityStoreException;

/**
* Standard implementation of EntityState.
*/
public final class JSONEntityState
    implements EntityState
{
    public static final String JSON_KEY_PROPERTIES = "properties";
    public static final String JSON_KEY_ASSOCIATIONS = "associations";
    public static final String JSON_KEY_MANYASSOCIATIONS = "manyassociations";
    public static final String JSON_KEY_IDENTITY = "identity";
    public static final String JSON_KEY_APPLICATION_VERSION = "application_version";
    public static final String JSON_KEY_TYPE = "type";
    public static final String JSON_KEY_VERSION = "version";
    public static final String JSON_KEY_MODIFIED = "modified";
    private static final String[] EMPTY_NAMES = new String[ 0 ];
    private static final String[] CLONE_NAMES = {
        JSON_KEY_IDENTITY,
        JSON_KEY_APPLICATION_VERSION,
        JSON_KEY_TYPE,
        JSON_KEY_VERSION,
        JSON_KEY_MODIFIED
    };

    protected DefaultEntityStoreUnitOfWork unitOfWork;
    protected EntityStatus status;
    protected String version;

    protected long lastModified;
    private final EntityReference identity;
    private final EntityDescriptor entityDescriptor;
    protected JSONObject state;

    public JSONEntityState( DefaultEntityStoreUnitOfWork unitOfWork,
                            EntityReference identity,
                            EntityDescriptor entityDescriptor,
                            JSONObject initialState
    )
    {
        this( unitOfWork, "",
              unitOfWork.currentTime(),
              identity,
              EntityStatus.NEW,
              entityDescriptor,
              initialState );
    }

    public JSONEntityState( DefaultEntityStoreUnitOfWork unitOfWork,
                            String version,
                            long lastModified,
                            EntityReference identity,
                            EntityStatus status,
                            EntityDescriptor entityDescriptor,
                            JSONObject state
    )
    {
        this.unitOfWork = unitOfWork;
        this.version = version;
        this.lastModified = lastModified;
        this.identity = identity;
        this.status = status;
        this.entityDescriptor = entityDescriptor;
        this.state = state;
    }

    // EntityState implementation

    public final String version()
    {
        return version;
    }

    public long lastModified()
    {
        return lastModified;
    }

    public EntityReference identity()
    {
        return identity;
    }

    public Object getProperty( QualifiedName stateName )
    {
        try
        {
            Object json = state.getJSONObject( JSON_KEY_PROPERTIES ).opt( stateName.name() );
            if( json == null || json == JSONObject.NULL )
            {
                return null;
            }
            else
            {
                Module module = unitOfWork.module();
                PropertyDescriptor descriptor = entityDescriptor.state().getPropertyByQualifiedName( stateName );

                if (descriptor == null)
                    return null;

                JSONDeserializer deserializer = new JSONDeserializer( module );

                return deserializer.deserialize( json, descriptor.valueType() );
            }
        }
        catch( JSONException e )
        {
            throw new EntityStoreException( e );
        }
    }

    public void setProperty( QualifiedName stateName, Object newValue )
    {
        try
        {
            Object jsonValue;
            if( newValue == null )
            {
                jsonValue = JSONObject.NULL;
            }
            else
            {
                PropertyDescriptor persistentPropertyDescriptor = entityDescriptor.state()
                    .getPropertyByQualifiedName( stateName );

                JSONObjectSerializer serializer = new JSONObjectSerializer();
                serializer.serialize( newValue, persistentPropertyDescriptor.valueType() );
                jsonValue = serializer.getRoot();
            }
            cloneStateIfGlobalStateLoaded();
            state.getJSONObject( JSON_KEY_PROPERTIES ).put( stateName.name(), jsonValue );
            markUpdated();
        }
        catch( JSONException e )
        {
            throw new EntityStoreException( e );
        }
    }

    private JSONObject cloneJSON( JSONObject jsonObject )
        throws JSONException
    {
        String[] names = JSONObject.getNames( jsonObject );
        if( names == null )
        {
            names = EMPTY_NAMES;
        }
        return new JSONObject( jsonObject, names );
    }

    public EntityReference getAssociation( QualifiedName stateName )
    {
        try
        {
            Object jsonValue = state.getJSONObject( JSON_KEY_ASSOCIATIONS ).opt( stateName.name() );
            if( jsonValue == null )
            {
                return null;
            }

            EntityReference value = jsonValue == JSONObject.NULL ? null : EntityReference.parseEntityReference(
                (String) jsonValue );
            return value;
        }
        catch( JSONException e )
        {
            throw new EntityStoreException( e );
        }
    }

    public void setAssociation( QualifiedName stateName, EntityReference newEntity )
    {
        try
        {
            cloneStateIfGlobalStateLoaded();
            state.getJSONObject( JSON_KEY_ASSOCIATIONS )
                .put( stateName.name(), newEntity == null ? null : newEntity.identity() );
            markUpdated();
        }
        catch( JSONException e )
        {
            throw new EntityStoreException( e );
        }
    }

    public ManyAssociationState getManyAssociation( QualifiedName stateName )
    {
        try
        {
            JSONObject manyAssociations = state.getJSONObject( JSON_KEY_MANYASSOCIATIONS );
            JSONArray jsonValues = manyAssociations.optJSONArray( stateName.name() );
            if( jsonValues == null )
            {
                jsonValues = new JSONArray();
                manyAssociations.put( stateName.name(), jsonValues );
            }
            return new JSONManyAssociationState( this, jsonValues );
        }
        catch( JSONException e )
        {
            throw new EntityStoreException( e );
        }
    }

    public void remove()
    {
        status = EntityStatus.REMOVED;
    }

    public EntityStatus status()
    {
        return status;
    }

    @Override
    public boolean isAssignableTo( Class<?> type )
    {
        return entityDescriptor.isAssignableTo( type );
    }

    public EntityDescriptor entityDescriptor()
    {
        return entityDescriptor;
    }

    public JSONObject state()
    {
        return state;
    }

    @Override
    public String toString()
    {
        return identity + "(" + state + ")";
    }

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

    boolean isStateNotCloned()
    {
        return status == EntityStatus.LOADED;
    }

    void cloneStateIfGlobalStateLoaded()
    {
        if( isStateNotCloned() )
        {
            return;
        }

        try
        {
            JSONObject newProperties = cloneJSON( state.getJSONObject( JSON_KEY_PROPERTIES ) );
            JSONObject newAssoc = cloneJSON( state.getJSONObject( JSON_KEY_ASSOCIATIONS ) );
            JSONObject newManyAssoc = cloneJSON( state.getJSONObject( JSON_KEY_MANYASSOCIATIONS ) );
            JSONObject stateClone = new JSONObject( state, CLONE_NAMES );
            stateClone.put( JSON_KEY_PROPERTIES, newProperties );
            stateClone.put( JSON_KEY_ASSOCIATIONS, newAssoc );
            stateClone.put( JSON_KEY_MANYASSOCIATIONS, newManyAssoc );
            state = stateClone;
        }
        catch( JSONException e )
        {
            throw new EntityStoreException( e );
        }
    }
}
TOP

Related Classes of org.qi4j.spi.entitystore.helpers.JSONEntityState

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.