All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.googlecode.objectify.impl.translate.Translators Maven / Gradle / Ivy

There is a newer version: 6.1.2
Show newest version
package com.googlecode.objectify.impl.translate;

import com.google.appengine.api.datastore.PropertyContainer;
import com.googlecode.objectify.ObjectifyFactory;
import com.googlecode.objectify.impl.Path;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;


/**
 * 

Manages all the translators used to map between POJO fields and the * types that the Datastore can actually persist. Essentially acts as an * aggregator for all the TranslatorFactory objects.

* *

When Objectify arranges a translator for a type at registration time, it runs * through the available TranslatorFactory instances one at time looking for one that * will provide a Translator. The first one found is kept and used during runtime * assembly and disassembly of entities.

* * @author Jeff Schnitzer */ public class Translators { /** */ ObjectifyFactory fact; /** */ List> translatorFactories = new ArrayList<>(); /** Where we should insert new translators */ int insertPoint; /** Where we should insert new early translators */ int earlyInsertPoint; /** */ Map> translators = new ConcurrentHashMap<>(); /** * Initialize the default set of converters in the proper order. */ public Translators(ObjectifyFactory fact) { this.fact = fact; // The order is CRITICAL! this.translatorFactories.add(new TranslateTranslatorFactory(true)); // Early translators get first shot at everything // Magic inflection point at which we want to prioritize added EARLY translators this.earlyInsertPoint = this.translatorFactories.size(); // Annotation based translators go first this.translatorFactories.add(new ContainerTranslatorFactory()); this.translatorFactories.add(new SerializeTranslatorFactory()); // Serialize has priority over everything this.translatorFactories.add(new MapifyTranslatorFactory()); // Magic inflection point at which we want to prioritize added normal translators this.insertPoint = this.translatorFactories.size(); this.translatorFactories.add(new ByteArrayTranslatorFactory()); this.translatorFactories.add(new ArrayTranslatorFactory()); // AFTER byte array otherwise we will occlude it this.translatorFactories.add(new CollectionTranslatorFactory()); this.translatorFactories.add(new EmbeddedMapTranslatorFactory()); this.translatorFactories.add(new TranslateTranslatorFactory(false)); // Late translators get a shot after collections this.translatorFactories.add(new StringTranslatorFactory()); this.translatorFactories.add(new TextTranslatorFactory()); this.translatorFactories.add(new NumberTranslatorFactory()); this.translatorFactories.add(new KeyTranslatorFactory()); this.translatorFactories.add(new RefTranslatorFactory()); this.translatorFactories.add(new EnumTranslatorFactory()); this.translatorFactories.add(new SqlDateTranslatorFactory()); this.translatorFactories.add(new TimeZoneTranslatorFactory()); this.translatorFactories.add(new URLTranslatorFactory()); // Things that just work as they are (fundamental datastore classes) this.translatorFactories.add(new AsIsTranslatorFactory()); // LAST! It catches everything. this.translatorFactories.add(new ClassTranslatorFactory<>()); } /** *

Add a new translator to the list. Translators are added in order after most of the "plumbing" translators * (collections, arrays, maps, serialize, embeds, references) but before any of the standard value conversions * like String, Number, Key, Enum, SqlDate, TimeZone, etc.

* *

Translators are added in-order so earlier translaters pre-empt later translators.

*/ public void add(TranslatorFactory trans) { this.translatorFactories.add(insertPoint, trans); insertPoint++; } /** *

Add a new translator to the beginning of the list, before all other translators * except other translators that have been added early.

*/ public void addEarly(TranslatorFactory trans) { this.translatorFactories.add(earlyInsertPoint, trans); earlyInsertPoint++; insertPoint++; } /** * Obtains the Translator appropriate for this type and annotations. May be a cached * translator; if not, one will be discovered and cached. */ public Translator get(TypeKey tk, CreateContext ctx, Path path) { Translator translator = translators.get(tk); if (translator == null) { translator = create(tk, ctx, path); translators.put(tk, translator); } //noinspection unchecked return (Translator)translator; } /** * Get the translator for a root entity class */ public

Translator getRoot(Class

clazz) { return get(new TypeKey(clazz), new CreateContext(fact), Path.root()); } /** * Create a translator from scratch by going through the discovery process. */ private Translator create(TypeKey tk, CreateContext ctx, Path path) { for (TranslatorFactory trans: this.translatorFactories) { @SuppressWarnings("unchecked") Translator soFar = trans.create(tk, ctx, path); if (soFar != null) return soFar; } throw new IllegalArgumentException("Don't know how to translate " + tk.getType() + " with annotations " + Arrays.toString(tk.getAnnotations())); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy