Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* Copyright (c) 2007 through 2024 David Berkman
*
* This file is part of the SmallMind Code Project.
*
* The SmallMind Code Project is free software, you can redistribute
* it and/or modify it under either, at your discretion...
*
* 1) The terms of GNU Affero General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* ...or...
*
* 2) The terms of the Apache License, Version 2.0.
*
* The SmallMind Code Project is distributed in the hope that it will
* be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License or Apache License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* and the Apache License along with the SmallMind Code Project. If not, see
* or .
*
* Additional permission under the GNU Affero GPL version 3 section 7
* ------------------------------------------------------------------
* If you modify this Program, or any covered work, by linking or
* combining it with other code, such other code is not for that reason
* alone subject to any of the requirements of the GNU Affero GPL
* version 3.
*/
package org.smallmind.mongodb.throng;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.LinkedList;
import com.mongodb.client.FindIterable;
import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoDatabase;
import com.mongodb.client.model.DeleteOptions;
import com.mongodb.client.model.InsertOneOptions;
import com.mongodb.client.model.UpdateOptions;
import com.mongodb.client.result.DeleteResult;
import com.mongodb.client.result.InsertOneResult;
import org.bson.BsonDocument;
import org.bson.codecs.configuration.CodecRegistries;
import org.bson.codecs.configuration.CodecRegistry;
import org.smallmind.mongodb.throng.codec.ArrayCodecProvider;
import org.smallmind.mongodb.throng.index.IndexUtility;
import org.smallmind.mongodb.throng.mapping.EmbeddedReferences;
import org.smallmind.mongodb.throng.mapping.ThrongEmbeddedUtility;
import org.smallmind.mongodb.throng.mapping.ThrongEntity;
import org.smallmind.mongodb.throng.mapping.ThrongEntityCodec;
import org.smallmind.mongodb.throng.mapping.annotation.Embedded;
import org.smallmind.mongodb.throng.mapping.annotation.Entity;
import org.smallmind.mongodb.throng.query.Filter;
import org.smallmind.mongodb.throng.query.Query;
import org.smallmind.mongodb.throng.query.Updates;
/*
Weaknesses...
1) Entity classes can not be marked as polymorphic.
2) Embedded classes can not have lifecycle methods.
3) There's no fully correct automated handling for containers with generics of either @Embedded or @Codec types, i.e. List, Map, Bag, etc.
Containers of @Embedded types will miss automated index processing, and containers of @Codec types will throw an exception due to mismatch
of the field and codec. Creating container subclasses, with codecs parameterized for those subclasses, and, in the case of @Embedded types,
adding the appropriate indexes to the parent class, is the correct route.
*/
public class ThrongClient {
private final MongoDatabase mongoDatabase;
private final CodecRegistry codecRegistry;
private final HashMap, ThrongEntityCodec>> entityCodecMap = new HashMap<>();
public ThrongClient (MongoClient mongoClient, String database, ThrongOptions options, Class>... entityClasses)
throws ThrongMappingException, NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException {
CodecRegistry driverCodecRegistry;
EmbeddedReferences embeddedReferences = new EmbeddedReferences();
mongoDatabase = mongoClient.getDatabase(database);
driverCodecRegistry = CodecRegistries.fromRegistries(mongoDatabase.getCodecRegistry(), CodecRegistries.fromProviders(new ArrayCodecProvider(options.isStoreNulls())));
if (entityClasses != null) {
for (Class> entityClass : entityClasses) {
Embedded embedded;
if ((embedded = entityClass.getAnnotation(Embedded.class)) != null) {
ThrongEmbeddedUtility.generateEmbeddedCodec(entityClass, embedded, driverCodecRegistry, embeddedReferences, options.isStoreNulls());
}
}
for (Class> entityClass : entityClasses) {
Entity entity;
if ((entity = entityClass.getAnnotation(Entity.class)) != null) {
ThrongEntityCodec> entityCodec;
entityCodecMap.put(entityClass, entityCodec = new ThrongEntityCodec<>(new ThrongEntity<>(entityClass, entity, CodecRegistries.fromRegistries(CodecRegistries.fromRegistries(CodecRegistries.fromCodecs(new LinkedList<>(embeddedReferences.values()))), driverCodecRegistry), embeddedReferences, options.isStoreNulls())));
if (options.isCreateIndexes()) {
IndexUtility.createIndex(mongoDatabase.getCollection(entityCodec.getCollection()), entityCodec.provideIndexes(), options.isIncludeCollation());
}
}
}
}
codecRegistry = CodecRegistries.fromRegistries(CodecRegistries.fromCodecs(new ThrongDocumentCodec()), CodecRegistries.fromRegistries(CodecRegistries.fromCodecs(new LinkedList<>(embeddedReferences.values()))), driverCodecRegistry);
}
private ThrongEntityCodec getCodec (Class entityClass) {
ThrongEntityCodec entityCodec;
if ((entityCodec = (ThrongEntityCodec)entityCodecMap.get(entityClass)) == null) {
throw new ThrongRuntimeException("Unmapped entity type(%s)", entityClass);
} else {
return entityCodec;
}
}
public long count (Class entityClass, Filter filter) {
ThrongEntityCodec entityCodec = getCodec(entityClass);
return mongoDatabase.getCollection(entityCodec.getCollection()).withCodecRegistry(codecRegistry).withDocumentClass(ThrongDocument.class).countDocuments(filter.toBsonDocument(BsonDocument.class, codecRegistry));
}
public ThrongIterable find (Class entityClass, Query query) {
ThrongEntityCodec entityCodec = getCodec(entityClass);
return new ThrongIterable<>(query.apply(mongoDatabase.getCollection(entityCodec.getCollection()).withCodecRegistry(codecRegistry).withDocumentClass(ThrongDocument.class).find(), BsonDocument.class, codecRegistry), entityCodec);
}
public T findOne (Class entityClass, Query query) {
ThrongEntityCodec entityCodec = getCodec(entityClass);
FindIterable findIterable = query.apply(mongoDatabase.getCollection(entityCodec.getCollection()).withCodecRegistry(codecRegistry).withDocumentClass(ThrongDocument.class).find(), BsonDocument.class, codecRegistry).limit(1);
ThrongDocument throngDocument;
if ((throngDocument = findIterable.first()) == null) {
return null;
} else {
return TranslationUtility.fromBson(entityCodec, throngDocument.getBsonDocument());
}
}
public InsertOneResult insert (T value, InsertOneOptions options) {
ThrongEntityCodec entityCodec = getCodec((Class)value.getClass());
return mongoDatabase.getCollection(entityCodec.getCollection()).withCodecRegistry(codecRegistry).withDocumentClass(ThrongDocument.class).insertOne(new ThrongDocument(TranslationUtility.toBson(value, entityCodec)));
}
public UpdateResult update (Class entityClass, Filter filter, Updates updates, UpdateOptions updateOptions) {
ThrongEntityCodec entityCodec = getCodec(entityClass);
return new UpdateResult(mongoDatabase.getCollection(entityCodec.getCollection()).withCodecRegistry(codecRegistry).withDocumentClass(ThrongDocument.class).updateMany(filter.toBsonDocument(BsonDocument.class, codecRegistry), updates.toBsonDocument(BsonDocument.class, codecRegistry), updateOptions));
}
public DeleteResult delete (Class entityClass, Filter filter, DeleteOptions deleteOptions) {
ThrongEntityCodec entityCodec = getCodec(entityClass);
return mongoDatabase.getCollection(entityCodec.getCollection()).withCodecRegistry(codecRegistry).withDocumentClass(ThrongDocument.class).deleteMany(filter.toBsonDocument(BsonDocument.class, codecRegistry), deleteOptions);
}
}