Package com.googlecode.objectify.impl.translate

Source Code of com.googlecode.objectify.impl.translate.MapifyTranslatorFactory

package com.googlecode.objectify.impl.translate;

import com.googlecode.objectify.ObjectifyFactory;
import com.googlecode.objectify.annotation.Mapify;
import com.googlecode.objectify.impl.Path;
import com.googlecode.objectify.mapper.Mapper;
import com.googlecode.objectify.util.GenericUtils;

import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Map;


/**
* <p>This takes a datastore collection and converts it to a POJO Map by letting you select out the key value
* using a class of your own devising. The values will be written to the collection, not the keys.</p>
*
* @author Jeff Schnitzer <jeff@infohazard.org>
*/
public class MapifyTranslatorFactory implements TranslatorFactory<Map<Object, Object>, Collection<Object>>
{
  @Override
  public Translator<Map<Object, Object>, Collection<Object>> create(TypeKey<Map<Object, Object>> tk, CreateContext ctx, Path path) {
    Mapify mapify = tk.getAnnotation(Mapify.class);
    if (mapify == null)
      return null;

    @SuppressWarnings("unchecked")
    final Class<? extends Map<?, ?>> mapType = tk.getTypeAsClass();

    if (!Map.class.isAssignableFrom(mapType))
      return null// We might be here processing the component type of the mapify map!

    final ObjectifyFactory fact = ctx.getFactory();

    Type componentType = GenericUtils.getMapValueType(tk.getType());
    final Translator<Object, Object> componentTranslator = fact.getTranslators().get(new TypeKey(componentType, tk), ctx, path);

    @SuppressWarnings("unchecked")
    final Mapper<Object, Object> mapper = (Mapper<Object, Object>)fact.construct(mapify.value());

    return new TranslatorRecycles<Map<Object, Object>, Collection<Object>>() {
      @Override
      public Map<Object, Object> loadInto(Collection<Object> node, LoadContext ctx, Path path, Map<Object, Object> map) throws SkipException {
        if (node == null)
          throw new SkipException();

        if (map == null)
          //noinspection unchecked
          map = (Map<Object, Object>)fact.constructMap(mapType);
        else
          map.clear();

        for (Object child: node) {
          try {
            Object translatedChild = componentTranslator.load(child, ctx, path);

            Object key = mapper.getKey(translatedChild);
            map.put(key, translatedChild);
          }
          catch (SkipException ex) {
            // No prob, just skip that one
          }
        }

        return map;
      }

      @Override
      public Collection<Object> save(Map<Object, Object> pojo, boolean index, SaveContext ctx, Path path) throws SkipException {

        // If it's empty, might as well skip it - the datastore doesn't store empty lists
        if (pojo == null || pojo.isEmpty())
          throw new SkipException();

        Collection<Object> list = new ArrayList<>(pojo.size());

        for (Object obj: pojo.values()) {
          try {
            Object child = componentTranslator.save(obj, index, ctx, path);
            list.add(child);
          }
          catch (SkipException ex) {
            // Just skip that node, no prob
          }
        }

        return list;
      }
    };
  }
}
TOP

Related Classes of com.googlecode.objectify.impl.translate.MapifyTranslatorFactory

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.