public GuiceObjectFactory(final Registry injector, final Morphia morphia) { this.injector = requireNonNull(injector, "Injector is required."); MapperOptions options = morphia.getMapper().getOptions(); this.delegate = options.getObjectFactory(); options.setObjectFactory(this); }
@Override protected DBRef asReference(Object constant) { Key<?> key = morphia.getMapper().getKey(constant); return morphia.getMapper().keyToDBRef(key); }
@Override protected DBRef asReferenceKey(Class<?> entity, Object id) { String collection = morphia.getMapper().getCollectionName(entity); Key<?> key = new Key<Object>(entity, collection, id); return morphia.getMapper().keyToDBRef(key); } }
private void readMappedField(final Datastore datastore, final MappedField mf, final Object entity, final EntityCache cache, final DBObject dbObject) { if (mf.hasAnnotation(Property.class) || mf.hasAnnotation(Serialized.class) || mf.isTypeMongoCompatible() || getConverters().hasSimpleValueConverter(mf)) { opts.getValueMapper().fromDBObject(datastore, dbObject, mf, entity, cache, this); } else if (mf.hasAnnotation(Embedded.class)) { opts.getEmbeddedMapper().fromDBObject(datastore, dbObject, mf, entity, cache, this); } else if (mf.hasAnnotation(Reference.class)) { opts.getReferenceMapper().fromDBObject(datastore, dbObject, mf, entity, cache, this); } else { opts.getDefaultMapper().fromDBObject(datastore, dbObject, mf, entity, cache, this); } }
private void addValue(final List values, final Object o, final Mapper mapper, final boolean idOnly) { if (o == null && mapper.getOptions().isStoreNulls()) { values.add(null); return; } final Key key = o instanceof Key ? (Key) o : getKey(o, mapper); values.add(idOnly ? mapper.keyToId(key) : mapper.keyToDBRef(key)); }
private Object readMapOrCollectionOrEntity(final Datastore datastore, final Mapper mapper, final EntityCache cache, final MappedField mf, final EphemeralMappedField ephemeralMappedField, final DBObject dbObj) { if (ephemeralMappedField != null) { mapper.fromDb(datastore, dbObj, ephemeralMappedField, cache); return ephemeralMappedField.getValue(); } else { final Object newEntity = mapper.getOptions().getObjectFactory().createInstance(mapper, mf, dbObj); return mapper.fromDb(datastore, dbObj, newEntity, cache); } }
@Override public void fromDBObject(final Datastore datastore, final DBObject dbObject, final MappedField mf, final Object entity, final EntityCache cache, final Mapper mapper) { final Class fieldType = mf.getType(); final Reference refAnn = mf.getAnnotation(Reference.class); if (mf.isMap()) { readMap(datastore, mapper, entity, refAnn, cache, mf, dbObject); } else if (mf.isMultipleValues()) { readCollection(datastore, mapper, dbObject, mf, entity, refAnn, cache); } else { readSingle(datastore, mapper, entity, fieldType, refAnn, cache, mf, dbObject); } }
@Override public void prePersist(final Object entity, final DBObject dbObj, final Mapper mapper) { MappedClass mclass = mapper.getMappedClass(entity); Field id = mclass.getIdField(); if (id != null && id.getAnnotation(GeneratedValue.class) != null) { try { id.setAccessible(true); final String collName = gen.value(mclass.getClazz()); final Query<StoredId> q = db.find(StoredId.class, "_id", collName); final UpdateOperations<StoredId> uOps = db.createUpdateOperations(StoredId.class) .inc("value"); StoredId newId = db.findAndModify(q, uOps); if (newId == null) { newId = new StoredId(collName); db.save(newId); } id.set(entity, newId.value); } catch (Exception ex) { throw new IllegalStateException("Can't generate ID on " + mclass, ex); } } }
@Override public void configure(final Env env, final Config conf, final Binder binder) { configure(env, conf, binder, (uri, client) -> { String db = uri.getDatabase(); Mapper mapper = new Mapper(); Morphia morphia = new Morphia(mapper); if (this.morphiaCbck != null) { this.morphiaCbck.accept(morphia, conf); } Datastore datastore = morphia.createDatastore(client, mapper, db); if (gen != null) { mapper.addInterceptor(new AutoIncID(datastore, gen)); } if (callback != null) { callback.accept(datastore); } ServiceKey serviceKey = env.serviceKey(); serviceKey.generate(Morphia.class, db, k -> binder.bind(k).toInstance(morphia)); serviceKey.generate(Datastore.class, db, k -> binder.bind(k).toInstance(datastore)); env.onStart(registry -> new GuiceObjectFactory(registry, morphia)); }); }
@Override @SuppressWarnings("unchecked") public Set createSet(final MappedField mf) { return newInstance(mf != null ? mf.getCTor() : null, HashSet.class); }
@Override public Object createInstance(final Mapper mapper, final MappedField mf, final DBObject dbObj) { Class<?> clazz = mf.getType(); if (shouldInject(clazz)) { return injector.require(clazz); } return delegate.createInstance(mapper, mf, dbObj); }
/** * Creates a Morphia instance with the given classes * * @param classesToMap the classes to map */ public Morphia(final Set<Class> classesToMap) { this(new Mapper(), classesToMap); }
@Override public Object visit(Constant<?> expr, Void context) { Object value = super.visit(expr, context); return morphia.getMapper().toMongoObject(null, null, value); }
/** * If the underlying java type is a map then it returns T from Map<T,V> * * @return the type of the map key */ public Class getMapKeyClass() { return toClass(mapKeyType); }
/** * @return true if this field is a container type such as a List, Map, Set, or array */ public boolean isMultipleValues() { return !isSingleValue(); }
/** * Creates a MappedField * * @param field the Type for the field * @param type the Type for the field * @param mapper the Mapper to use */ MappedField(final Field field, final Type type, final Mapper mapper) { this.field = field; genericType = type; discoverType(mapper); }
@Override @SuppressWarnings("unchecked") public List createList(final MappedField mf) { return newInstance(mf != null ? mf.getCTor() : null, ArrayList.class); }
/** * If the java field is a list/array/map then the sub-type T is returned (ex. List<T>, T[], Map<?,T> * * @return the parameterized type of the field */ public Class getSubClass() { return toClass(subType); }
@Override @SuppressWarnings("unchecked") public Map createMap(final MappedField mf) { return newInstance(mf != null ? mf.getCTor() : null, HashMap.class); }