Пишу систему прав.
Имею IPermissible
, наследуемый классами пользователей
и групп
. Разница между этими сущностями в том, что группа
содержит некоторую коллекцию прав (разрешений), применяемую пользователем
при вступлении в эту группу.
{"_id": "5bc667f58bb878c6a4e5a36b", "name": "ky ky", "permissions": ["add", "*"], "groups": ["admin"]}
{"_id":"5bc66e758bb878c6a4e5a36c","name":"admin","permissions":["*"],"priority":1000}
Теперь, когда я создаю кодек пользователя, мне нужно получить группу admin
, но мы имеешь лишь название, использовав которое, в принципе, мы могли бы получить группу, но не сейчас, т.к. на данном этапе у нас нет экземпляра MongoClient
.
Один из костыльных вариантов — сохранять экземпляры кодеков в переменные, а после получение экземпляра клиента использовать какой-то сеттер коллекции групп (или уже распаршенных групп) в том самом кодеке пользователя, т.д. (думаю, понятно). В общем, бред.
Получилось добавиться нужного результата через подмену реестра кодеков рефлексией, но это не меньший костыль. В целом, никогда это боком не встанет. Прекрасное решение, если никто другого не предложит.
package me.delsy.libraries.mongodb.bootstrap;
import com.mongodb.MongoClient;
import com.mongodb.MongoClientOptions;
import com.mongodb.MongoCredential;
import com.mongodb.ServerAddress;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;
import com.mongodb.client.model.Filters;
import java.lang.reflect.Field;
import org.bson.BsonReader;
import org.bson.BsonWriter;
import org.bson.codecs.Codec;
import org.bson.codecs.DecoderContext;
import org.bson.codecs.EncoderContext;
import org.bson.codecs.configuration.CodecRegistries;
import org.bson.codecs.configuration.CodecRegistry;
/**
* @author xDelsy
*/
public class Bootstrap {
public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
MongoCredential credentials = MongoCredential.createCredential("admin", "admin", "admin".toCharArray());
MongoClientOptions options = MongoClientOptions.builder().codecRegistry(CodecRegistries.fromRegistries(MongoClient.getDefaultCodecRegistry(), CodecRegistries.fromCodecs(new Test1Codec()))).build();
MongoClient client = new MongoClient(new ServerAddress(), credentials, options);
MongoDatabase database = client.getDatabase("vkontakte-school-bot");
MongoCollection<Test1> test1Collection = database.getCollection("test1", Test1.class);
{ // подмена реестра рефлексией
MongoClientOptions clientOptions = client.getMongoClientOptions();
Field field = client.getMongoClientOptions().getClass().getDeclaredField("codecRegistry");
{
field.setAccessible(true);
}
field.set(clientOptions, CodecRegistries.fromRegistries(client.getMongoClientOptions().getCodecRegistry(), CodecRegistries.fromCodecs(new Test2Codec(test1Collection))));
}
// без обновления database не работает
MongoCollection<Test2> test2Collection = (database = client.getDatabase("vkontakte-school-bot")).getCollection("test2", Test2.class);
for(Test2 test2 : test2Collection.find()) {
System.out.println(test2);
}
}
public static class Test1 {
private String s;
private String permission;
//
Test1(String s, String permission) {
this.s = s;
this.permission = permission;
}
//
@Override
public String toString() {
return "Test1{" + "s='" + s + '\'' + ", permission='" + permission + '\'' + '}';
}
}
public static class Test2 {
private int i;
private Test1 test1;
//
Test2(int i, Test1 test1) {
this.i = i;
this.test1 = test1;
}
//
@Override
public String toString() {
return "Test2{" + "i=" + i + ", test1=" + test1 + '}';
}
}
static class Test1Codec implements Codec<Test1> {
@Override
public Test1 decode(BsonReader bsonReader, DecoderContext decoderContext) {
{
bsonReader.readStartDocument();
bsonReader.readObjectId();
}
Test1 a = new Test1(bsonReader.readString("s"), bsonReader.readString("permission"));
bsonReader.readEndDocument();
return a;
}
@Override
public void encode(BsonWriter bsonWriter, Test1 test1, EncoderContext encoderContext) {
bsonWriter.writeStartDocument();
{
bsonWriter.writeString("s", test1.s);
bsonWriter.writeString("permission", test1.permission);
}
bsonWriter.writeEndDocument();
}
@Override
public Class<Test1> getEncoderClass() {
return Test1.class;
}
}
static class Test2Codec implements Codec<Test2> {
private final MongoCollection<Test1> collection;
//
public Test2Codec(MongoCollection<Test1> collection) {
this.collection = collection;
}
//
@Override
public Test2 decode(BsonReader bsonReader, DecoderContext decoderContext) {
{
bsonReader.readStartDocument();
bsonReader.readObjectId();
}
Test2 a = new Test2(bsonReader.readInt32("i"), this.collection.find(Filters.eq("s", bsonReader.readString("test1S"))).first());
bsonReader.readEndDocument();
return a;
}
@Override
public void encode(BsonWriter bsonWriter, Test2 test2, EncoderContext encoderContext) {
bsonWriter.writeStartDocument();
{
bsonWriter.writeInt32("i", test2.i);
bsonWriter.writeString("test1S", test2.test1.s);
}
bsonWriter.writeEndDocument();
}
@Override
public Class<Test2> getEncoderClass() {
return Test2.class;
}
}
}
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Объясните, пожалуйста, что значит modeladdAttribute("some text", someObject);
Есть приложение в котором можно выполнять скрипты на JSЗадача - из этого приложения отправлять e-mail