/** * Creates an EntityManager that knows about all the same managed types and * named queries as the given entity manager, but works from a different * storage backend. When combined with the namespacing support of a storage * backend, this allows you to work with several independent entity managers * at the same time. * * @param delegateEntityManager * @param namespacedStorageBackend */ public ErraiEntityManager(final ErraiEntityManager delegateEntityManager, final StorageBackendFactory namespacedStorageBackend) { this(delegateEntityManager.getMetamodel(), delegateEntityManager.namedQueries, namespacedStorageBackend); }
@PostConstruct private void setup() { expectedStateEm = new ErraiEntityManager(desiredStateEm, new StorageBackendFactory() { @Override public StorageBackend createInstanceFor(ErraiEntityManager em) { return new WebStorageBackend(em, "expected-state:"); } }); entityComparator = new EntityComparator(desiredStateEm.getMetamodel(), attributeAccessor); }
@Override public List<X> getResultList() { List<X> results = em.findAll(em.getMetamodel().entity(resultType), this); Comparator<X> cmp = getComparator(); if (cmp != null) { Collections.sort(results, cmp); } return results; }
protected <Y> void parseInlineJson(X targetEntity, ErraiAttribute<? super X, Y> attr, JSONValue attrJsonValue, ErraiEntityManager eem) { Class<Y> attributeType = attr.getJavaType(); Y value; // FIXME this should search all managed types, or maybe all embeddables. not just entities. if (eem.getMetamodel().getEntities().contains(attributeType)) { ErraiIdentifiableType<Y> attrEntityType = eem.getMetamodel().entity(attributeType); value = attrEntityType.fromJson(eem, attrJsonValue); } else { value = JsonUtil.basicValueFromJson(attrJsonValue, attributeType); } attr.set(targetEntity, value); }
/** * Returns a Key instance for the entity type of the given class. * * @param em * The entity manager (required for looking up the EntityType for the * given class). Must not be null. * @param entityClass * The class of the entity for the key. Must not be null. * @param id * The ID value for the entity. Must not be null. * @return A Key instance for the given entity type and ID value. * @throws NullPointerException * if any argument is null. * @throws IllegalArgumentException * if {@code entityClass} is not a known JPA entity type. */ public static <X, T> Key<X, T> get(ErraiEntityManager em, Class<X> entityClass, T id) { ErraiIdentifiableType<X> entityType = em.getMetamodel().entity(entityClass); return new Key<X, T>(entityType, id); }
/** * Creates the key that describes the given entity, <b>generating and setting * it if it is presently unset and the given entity type's ID is configured to * be generated on demand</b>. This version of the {@code keyFor()} method * assumes the given object's entity type can be obtained by calling {@code * entity.getClass()}. If you already have a specific entity type in mind, use * the {@link #keyFor(ErraiIdentifiableType, Object)} version of the method. * * @param entityType * The entity type of the entity * @param entity * The entity instance. <b>Side effect: this instance may have its ID * value initialized as a result of this call</b>. * @return The key for the given entity, which--for generated values--may have * just been set on the entity. */ public <X> Key<X, ?> keyFor(final X entity) { final ErraiIdentifiableType<X> entityType = getMetamodel().entity(getNarrowedClass(entity)); return keyFor(entityType, entity); }
/** * Returns an inline JSON representation of the value of the given attribute * of the given entity instance. * * @param targetEntity * The instance of the entity to retrieve the attribute value from. * Not null. * @param attr * The attribute to read from {@code targetEntity}. Not null. * @param eem * The ErraiEntityManager that owns the entity. Not null. * @return a JSONValue that represents the requested attribute value of the * given entity. Never null, although it could be JSONNull. */ private <Y> JSONValue makeInlineJson(X targetEntity, ErraiAttribute<? super X, Y> attr, ErraiEntityManager eem) { Class<Y> attributeType = attr.getJavaType(); Y attrValue = attr.get(Assert.notNull(targetEntity)); // FIXME this should search all managed types, or maybe all embeddables. not just entities. // TODO it would be better to code-generate an Attribute.asJson() method than to do this at runtime if (eem.getMetamodel().getEntities().contains(attributeType)) { ErraiIdentifiableType<Y> attrEntityType = eem.getMetamodel().entity(attributeType); return attrEntityType.toJson(eem, attrValue); } return JsonUtil.basicValueToJson(attrValue); }
private static <X, Y> void copySingularAssociation( ErraiEntityManager em, ErraiAttribute<X, Y> attr, X targetEntity, X sourceEntity) { ErraiIdentifiableType<Y> relatedEntityType = em.getMetamodel().entity(attr.getJavaType()); Y oldRelatedEntity = attr.get(sourceEntity); Y resolvedEntity; if (oldRelatedEntity == null) { resolvedEntity = null; } else { Key<Y, ?> key = em.keyFor(oldRelatedEntity); resolvedEntity = em.find(key, Collections.<String,Object>emptyMap()); if (resolvedEntity == null) { resolvedEntity = relatedEntityType.newInstance(); } } attr.set(targetEntity, resolvedEntity); }
protected <C, E> void parsePluralJsonReference( X targetEntity, ErraiPluralAttribute<? super X, C, E> attr, JSONArray attrJsonValues, ErraiEntityManager eem) { if (attrJsonValues == null || attrJsonValues.isNull() != null) return; Class<E> attributeElementType = attr.getElementType().getJavaType(); ErraiIdentifiableType<E> attrEntityType = eem.getMetamodel().entity(attributeElementType); // FIXME this is broken for Map attributes // TODO when we support Map attributes, we should get the attribute with getCollection()/getMap() to fix this warning Collection<E> collection = (Collection<E>) attr.createEmptyCollection(); for (int i = 0; i < attrJsonValues.size(); i++) { Key<E, ?> key = (Key<E, ?>) Key.fromJsonObject(eem, attrJsonValues.get(i).isObject(), true); logger.trace(" looking for " + key); E value = eem.getPartiallyConstructedEntity(key); if (value == null) { value = eem.find(key, Collections.<String,Object>emptyMap()); } collection.add(value); } attr.set(targetEntity, (C) collection); }
private static <X, C, E> void copyPluralAssociation( ErraiEntityManager em, ErraiPluralAttribute<X, C, E> attr, X targetEntity, X sourceEntity) { C oldCollection = attr.get(sourceEntity); C newCollection; if (oldCollection == null) { newCollection = null; } else { newCollection = attr.createEmptyCollection(); ErraiIdentifiableType<E> elemType = em.getMetamodel().entity(attr.getElementType().getJavaType()); // TODO support map-valued plural attributes for (Object oldEntry : (Collection<?>) oldCollection) { Key<Object, ?> key = em.keyFor(oldEntry); Object resolvedEntry = em.find(key, Collections.<String,Object>emptyMap()); if (resolvedEntry == null) { resolvedEntry = elemType.newInstance(); } ((Collection) newCollection).add(resolvedEntry); } } attr.set(targetEntity, newCollection); }
return JSONNull.getInstance(); ErraiIdentifiableType<Y> attrEntityType = eem.getMetamodel().entity(attributeType); if (attrEntityType == null) { throw new IllegalArgumentException("Can't make a reference to non-entity-typed attribute " + attr);
ErraiIdentifiableType<E> entityType = desiredStateEm.getMetamodel().entity((Class<E>) newEntity.getClass()); ErraiSingularAttribute<? super E, Object> idAttr = entityType.getId(Object.class); changeId(entityType, icr.getOldId(), idAttr.get(newEntity)); E inTheWay = desiredStateEm.find(conflictingKey, Collections.<String,Object>emptyMap()); if (inTheWay != null) { ErraiIdentifiableType<E> entityType = desiredStateEm.getMetamodel().entity(entityClass); ErraiSingularAttribute<? super E, Object> idAttr = entityType.getId(Object.class); ErraiIdGenerator<Object> idGenerator = idAttr.getValueGenerator();
final ErraiIdentifiableType<X> entityType = getMetamodel().entity(getNarrowedClass(entity)); if (backend.isModified(key, entity)) { final Object currentId = entityType.getId(Object.class).get(entity);
/** * Returns a Key instance based on the given JSON object. * * @param em * The entity manager that can be used to look up the entity type * corresponding with the key. * @param key * The properties of the key to create. * @param failIfNotFound * If true, and the entity type given in {@code key} is not known to * {@code em}, an IllegalArgumentException will be thrown. * @return An instance of Key that corresponds with the entity type and ID of * the given JSON object. */ public static Key<?, ?> fromJsonObject(ErraiEntityManager em, JSONObject key, boolean failIfNotFound) { String entityClassName = key.get("entityType").isString().stringValue(); ErraiIdentifiableType<Object> et = em.getMetamodel().entity(entityClassName, failIfNotFound); if (et == null) { return null; } ErraiSingularAttribute<?, Object> idAttr = et.getId(Object.class); Object id = JsonUtil.basicValueFromJson(key.get("id"), idAttr.getJavaType()); return new Key<Object, Object>(et, id); } }
ErraiIdentifiableType<E> attrEntityType = eem.getMetamodel().entity(attributeType); if (attrEntityType == null) { throw new IllegalArgumentException("Can't make a reference to collection of non-entity-typed attributes " + attr);
final ErraiIdentifiableType<X> entityType = getMetamodel().entity(getNarrowedClass(entity));