Как запарсить документ из кодека

196
23 февраля 2019, 01:00

Пишу систему прав.

Имею IPermissible, наследуемый классами пользователей и групп. Разница между этими сущностями в том, что группа содержит некоторую коллекцию прав (разрешений), применяемую пользователем при вступлении в эту группу.

  • пользователь: {"_id": "5bc667f58bb878c6a4e5a36b", "name": "ky ky", "permissions": ["add", "*"], "groups": ["admin"]}
  • группа: {"_id":"5bc66e758bb878c6a4e5a36c","name":"admin","permissions":["*"],"priority":1000}

Теперь, когда я создаю кодек пользователя, мне нужно получить группу admin, но мы имеешь лишь название, использовав которое, в принципе, мы могли бы получить группу, но не сейчас, т.к. на данном этапе у нас нет экземпляра MongoClient.

Один из костыльных вариантов — сохранять экземпляры кодеков в переменные, а после получение экземпляра клиента использовать какой-то сеттер коллекции групп (или уже распаршенных групп) в том самом кодеке пользователя, т.д. (думаю, понятно). В общем, бред.

Answer 1

Получилось добавиться нужного результата через подмену реестра кодеков рефлексией, но это не меньший костыль. В целом, никогда это боком не встанет. Прекрасное решение, если никто другого не предложит.

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;
        }
    }
}
READ ALSO
model.addAttribute (Spring MVC)

model.addAttribute (Spring MVC)

Объясните, пожалуйста, что значит modeladdAttribute("some text", someObject);

174
Взаимодействие с java приложением

Взаимодействие с java приложением

Есть приложение в котором можно выполнять скрипты на JSЗадача - из этого приложения отправлять e-mail

146
Вопрос по Java Web

Вопрос по Java Web

кто может подсказать, нашёл такой код(отрывок):

135
Kafka Consumer один поток - один топик

Kafka Consumer один поток - один топик

Есть много топиков сообщений из Kafka, например 20

160