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

com.googlecode.objectify.impl.Registrar Maven / Gradle / Ivy

Go to download

*** THIS VERSION UPLOADED FOR USE WITH CEDAR-COMMON, TO AVOID DEPENDENCIES ON GOOGLE CODE-BASED MAVEN REPOSITORIES. *** The simplest convenient interface to the Google App Engine datastore

The newest version!
package com.googlecode.objectify.impl;

import java.util.HashMap;
import java.util.Map;

import com.googlecode.objectify.Key;
import com.googlecode.objectify.ObjectifyFactory;
import com.googlecode.objectify.annotation.Entity;
import com.googlecode.objectify.annotation.Subclass;

/**
 * 

Maintains information about registered entity classes

* *

There logic here is convoluted by polymorphic hierarchies. Entity classes can * be registered in any particular order, requiring some considerable care.

* * @author Jeff Schnitzer */ public class Registrar { /** Needed to obtain the converters */ protected ObjectifyFactory fact; /** This maps kind to EntityMetadata */ protected Map> byKind = new HashMap>(); /** This maps class to EntityMetadata for all registered classes */ protected Map, EntityMetadata> byClass = new HashMap, EntityMetadata>(); /** True if any @Cached entities have been registered */ protected boolean cacheEnabled; /** @return true if any entities are cacheable */ public boolean isCacheEnabled() { return this.cacheEnabled; } /** * @param fact is so that the conversions can be obtained */ public Registrar(ObjectifyFactory fact) { this.fact = fact; } /** *

All POJO entity classes which are to be managed by Objectify * must be registered first. This method must be called in a single-threaded * mode sometime around application initialization.

*/ public void register(Class clazz) { // There are two possible cases // 1) This might be a simple class with @Entity or unannotated // 2) This might be a class annotated with @Subclass String kind = Key.getKind(clazz); if (clazz.isAnnotationPresent(Subclass.class)) { this.registerPolymorphicHierarchy(kind, clazz); } else { EntityMetadata meta = this.byKind.get(kind); if (meta == null) { ConcreteEntityMetadata cmeta = new ConcreteEntityMetadata(this.fact.getConversions(), clazz); this.byKind.put(kind, cmeta); this.byClass.put(clazz, cmeta); if (cmeta.getCacheExpirySeconds() != null) this.cacheEnabled = true; } else if (meta instanceof PolymorphicEntityMetadata) { // nothing special - the base class must already have been registered } else { throw new IllegalArgumentException("Attempted to register kind '" + kind + "' twice"); } } } /** * Recursively register classes in the hierarchy which have @Subclass * or @Entity. Stops when arriving at the first @Entity. Safely handles * classes that have already been registered, including @Entity classes * that were registered as non-polymorphic. * * @return the PolymorphicEntityMetadata associated with the kind. */ @SuppressWarnings("unchecked") protected PolymorphicEntityMetadata registerPolymorphicHierarchy(String kind, Class clazz) { if (clazz == Object.class) throw new IllegalArgumentException("A @Subclass hierarchy must have an @Entity superclass (direct or indirect)"); // First thing we do is climb and take care of the actual root @Entity if (clazz.isAnnotationPresent(Entity.class) || clazz.isAnnotationPresent(javax.persistence.Entity.class)) { // We're at the end of the recursion, deal with the base EntityMetadata meta = this.byKind.get(kind); if (meta == null) meta = new ConcreteEntityMetadata(this.fact.getConversions(), clazz); if (meta instanceof ConcreteEntityMetadata) { PolymorphicEntityMetadata polymeta = new PolymorphicEntityMetadata(clazz, (ConcreteEntityMetadata)meta); this.byKind.put(kind, polymeta); this.byClass.put(clazz, polymeta); return polymeta; } else return (PolymorphicEntityMetadata)meta; } else { // Climb the superclass tree, then check for subclass registration PolymorphicEntityMetadata polymeta = this.registerPolymorphicHierarchy(kind, clazz.getSuperclass()); // We only register @Subclass entities; other intermediate classes are not registered if (clazz.isAnnotationPresent(Subclass.class) && !this.byClass.containsKey(clazz)) { ConcreteEntityMetadata cmeta = new ConcreteEntityMetadata(this.fact.getConversions(), clazz); polymeta.addSubclass(clazz, cmeta); this.byClass.put(clazz, polymeta); // always the poly version when available } return polymeta; } } /** * @return the metadata for the specified kind, or null if there was nothing appropriate registered */ @SuppressWarnings("unchecked") public EntityMetadata getMetadata(String kind) { return (EntityMetadata)this.byKind.get(kind); } /** * @return the metadata for the specified class, or null if there was nothing appropriate registered */ @SuppressWarnings("unchecked") public EntityMetadata getMetadata(Class clazz) { return (EntityMetadata)this.byClass.get(clazz); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy