/** * Retrieves an ErraiEntityType by name rather than class reference. * * @param className * The fully-qualified class name of the entity type to retrieve (as * returned by {@code Class.getName()}). Null not permitted. * @return the ErraiEntityType associated with the named class. * @throws IllegalArgumentException * if the given class name is not an known entity type. */ public <X> ErraiEntityType<X> entity(String className) { return entity(className, true); }
@Override public <X> ErraiEntityType<X> entity(Class<X> cls) { return entity(cls.getName()); }
@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; }
/** * Returns a Key instance corresponding to the runtime type of the given * object, and the given ID value. * * @param object * The object to get the type information from. If it is a proxy * (WrappedPortable) it will be unwrapped. Must not be null. * @param id * The ID value for the key. Must not be null. * @return A key for the given ID and the exact type of the given object. */ @SuppressWarnings("unchecked") private <X, Y> Key<X, Y> normalizedKey(X object, Y id) { X unwrapped = object; if (object instanceof WrappedPortable) { unwrapped = (X) ((WrappedPortable) object).unwrap(); } ErraiManagedType<X> actualEntityType = (ErraiManagedType<X>) mm.entity(unwrapped.getClass()); Key<X, Y> normalizedKey = new Key<X, Y>(actualEntityType, id); return normalizedKey; }
/** * 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); }
/** * Tests if this entity manager's storage backend contains an entity that * could conflict with the given key. This method is free of side effects: it * will not affect the contents of the persistence context, and it will not * affect the persistence state of any entity (hence it will not deliver any * events to JPA lifecycle listeners). * * @param key * The key to test for in backend storage. Not null. * @return true if and only if this entity manager's storage backend contains * an entity with the given key. */ public boolean isKeyInUse(final Key<?, ?> key) { // search up the supertype chain for the most generic entity type reachable from the type given in the key ErraiManagedType<?> superManagedType = key.getEntityType(); Class<?> javaType = key.getEntityType().getJavaType().getSuperclass(); while (javaType != null) { final ErraiManagedType<?> mt = metamodel.entity(javaType.getName(), false); if (mt != null) { superManagedType = mt; } javaType = javaType.getSuperclass(); } final Key<?, ?> mostGenericKey = new Key<Object, Object>((ErraiManagedType<Object>) superManagedType, key.getId()); return backend.contains(mostGenericKey); }
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); }
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); }
/** * 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); }
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));