Package org.springframework.data.gemfire.mapping

Source Code of org.springframework.data.gemfire.mapping.MappingPdxSerializer

/*
* Copyright 2012 the original author or authors.
*
* 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.springframework.data.gemfire.mapping;

import java.util.Map;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.core.convert.ConversionService;
import org.springframework.core.convert.support.DefaultConversionService;
import org.springframework.data.convert.EntityInstantiator;
import org.springframework.data.convert.EntityInstantiators;
import org.springframework.data.mapping.PersistentEntity;
import org.springframework.data.mapping.PropertyHandler;
import org.springframework.data.mapping.model.BeanWrapper;
import org.springframework.data.mapping.model.MappingException;
import org.springframework.data.mapping.model.PersistentEntityParameterValueProvider;
import org.springframework.data.mapping.model.SpELContext;
import org.springframework.util.Assert;

import com.gemstone.gemfire.pdx.PdxReader;
import com.gemstone.gemfire.pdx.PdxSerializer;
import com.gemstone.gemfire.pdx.PdxWriter;

/**
* {@link PdxSerializer} implementation that uses a
* {@link GemfireMappingContext} to read and write entities.
*
* @author Oliver Gierke
* @author David Turanski
*/
public class MappingPdxSerializer implements PdxSerializer, ApplicationContextAware {

  private final GemfireMappingContext mappingContext;

  private final ConversionService conversionService;

  private EntityInstantiators instantiators;
 
  private Map<Class<?>,PdxSerializer> customSerializers;

  private SpELContext context;

  /**
   * Creates a new {@link MappingPdxSerializer} using the given
   * {@link GemfireMappingContext} and {@link ConversionService}.
   *
   * @param mappingContext must not be {@literal null}.
   * @param conversionService must not be {@literal null}.
   */
  public MappingPdxSerializer(GemfireMappingContext mappingContext, ConversionService conversionService) {

    Assert.notNull(mappingContext);
    Assert.notNull(conversionService);

    this.mappingContext = mappingContext;
    this.conversionService = conversionService;
    this.instantiators = new EntityInstantiators();
    this.context = new SpELContext(PdxReaderPropertyAccessor.INSTANCE);
  }

  /**
   * Creates a new {@link MappingPdxSerializer} using the default
   * {@link GemfireMappingContext} and {@link DefaultConversionService}.
   */
  public MappingPdxSerializer() {
    this(new GemfireMappingContext(), new DefaultConversionService());
  }

  /**
   * Configures the {@link EntityInstantiator}s to be used to create the
   * instances to be read.
   *
   * @param gemfireInstantiators must not be {@literal null}.
   */
  public void setGemfireInstantiators(Map<Class<?>, EntityInstantiator> gemfireInstantiators) {
    Assert.notNull(gemfireInstantiators);
    this.instantiators = new EntityInstantiators(gemfireInstantiators);
  }

  /**
   * Configures custom PDX serializers to use for specific class types.
   *
   * @param customSerializers a mapping of domain object class types and their corresponding PDX serializer.
   */
  public void setCustomSerializers(Map<Class<?>, PdxSerializer> customSerializers) {
    this.customSerializers = customSerializers;
  }

  /*
   * (non-Javadoc)
   *
   * @see
   * org.springframework.context.ApplicationContextAware#setApplicationContext
   * (org.springframework.context.ApplicationContext)
   */
  @Override
  public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
    this.context = new SpELContext(context, applicationContext);
  }

  /*
   * (non-Javadoc)
   *
   * @see com.gemstone.gemfire.pdx.PdxSerializer#fromData(java.lang.Class,
   * com.gemstone.gemfire.pdx.PdxReader)
   */
  @Override
  public Object fromData(Class<?> type, final PdxReader reader) {
    final GemfirePersistentEntity<?> entity = mappingContext.getPersistentEntity(type);
    EntityInstantiator instantiator = instantiators.getInstantiatorFor(entity);
    GemfirePropertyValueProvider propertyValueProvider = new GemfirePropertyValueProvider(reader);

    PersistentEntityParameterValueProvider<GemfirePersistentProperty> provider = new PersistentEntityParameterValueProvider<GemfirePersistentProperty>(
        entity, propertyValueProvider, null);
    Object instance = instantiator.createInstance(entity, provider);

    final BeanWrapper<Object> wrapper = BeanWrapper.create(instance, conversionService);

    entity.doWithProperties(new PropertyHandler<GemfirePersistentProperty>() {
      @Override
      public void doWithPersistentProperty(GemfirePersistentProperty persistentProperty) {

        if (entity.isConstructorArgument(persistentProperty)) {
          return;
        }
       
        PdxSerializer customSerializer = getCustomSerializer(persistentProperty.getType());
        Object value = null;
        if (customSerializer != null) {
          value = customSerializer.fromData(persistentProperty.getType(), reader);
        } else {
          value = reader.readField(persistentProperty.getName());
        }
        try {
          wrapper.setProperty(persistentProperty, value);
        }
        catch (Exception e) {
          throw new MappingException("Could not read value " + value.toString(), e);
        }
      }
    });

    return wrapper.getBean();
  }

  /*
   * (non-Javadoc)
   *
   * @see com.gemstone.gemfire.pdx.PdxSerializer#toData(java.lang.Object,
   * com.gemstone.gemfire.pdx.PdxWriter)
   */
  @Override
  public boolean toData(Object value, final PdxWriter writer) {
    GemfirePersistentEntity<?> entity = mappingContext.getPersistentEntity(value.getClass());
    final BeanWrapper<Object> wrapper = BeanWrapper.create(value, conversionService);

    entity.doWithProperties(new PropertyHandler<GemfirePersistentProperty>() {
      @SuppressWarnings({ "unchecked", "rawtypes" })
      @Override
      public void doWithPersistentProperty(GemfirePersistentProperty persistentProperty) {
       
        try {
          Object propertyValue = wrapper.getProperty(persistentProperty);
          PdxSerializer customSerializer = getCustomSerializer(persistentProperty.getType());
          if (customSerializer != null) {
            customSerializer.toData(propertyValue, writer);
          } else {
            writer.writeField(persistentProperty.getName(), propertyValue, (Class) persistentProperty.getType());
          }
        }
        catch (Exception e) {
          throw new MappingException("Could not write value for property " + persistentProperty.toString(), e);
        }
      }
    });

    GemfirePersistentProperty idProperty = entity.getIdProperty();

    if (idProperty != null) {
      writer.markIdentityField(idProperty.getName());
    }

    return true;
  }
 
  private PdxSerializer getCustomSerializer(Class<?> clazz) {
    return customSerializers == null ? null : customSerializers.get(clazz);
  }
}
TOP

Related Classes of org.springframework.data.gemfire.mapping.MappingPdxSerializer

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.