कई दिनों के शोध के बाद, मैंने एक समाधान निकाला है।
DutyBlockCodec
LocalDateCodec
. पर निर्भर करता है (जो मैंने बनाया) एन्कोड/डीकोड करने के लिए। यह निर्भरता केवल दो कोडेक को एक ही कोडेक रजिस्ट्री में जोड़ने से संतुष्ट नहीं होती है। समाधान एक CodecRegistry
. पास करना है कोडेक्स युक्त ऑब्जेक्ट जो DutyBlockCodec
निर्भर करता है (उदाहरण के लिए एक CodecRegistry
इसके भीतर LocalDateCodec
. है ) से DutyBlockCodec
का कंस्ट्रक्टर, जिसे एक सदस्य चर के रूप में संग्रहीत किया जाता है। LocalDateCodec
. का उपयोग करने के लिए एन्कोड करने के लिए, मैं EncoderContext.encodeWithChildContext()
. का उपयोग करता हूं विधि, कोडेक, लेखक, और एनकोड करने के लिए तत्व में गुजर रहा है। इसके अतिरिक्त, मैं Document
लिखने के बजाय अलग-अलग फ़ील्ड लिखता हूं String
के रूप में (जैसा कि मेरे मूल कोड में है)। इस प्रकार DutyBlock
कोडेक इस तरह दिखता है:
public class DutyBlockCodec implements Codec<DutyBlock> {
private final CodecRegistry codecRegistry;
public DutyBlockCodec(final CodecRegistry codecRegistry) {
this.codecRegistry = codecRegistry;
}
@Override
public void encode(BsonWriter writer, DutyBlock t, EncoderContext ec) {
writer.writeStartDocument();
Codec dateCodec = codecRegistry.get(LocalDate.class);
writer.writeName("startDate");
ec.encodeWithChildContext(dateCodec, writer, t.getStartDate());
writer.writeName("endDate");
ec.encodeWithChildContext(dateCodec, writer, t.getEndDate());
writer.writeName("blockLength");
writer.writeInt32(t.getBlockLength());
writer.writeName("pointValue");
writer.writeDouble(t.getPointValue());
//Writing ArrayList of RAs
writer.writeName("assigned");
writer.writeStartArray();
for (Ra ra : t.getRasOnDuty()) {
Codec raCodec = codecRegistry.get(Ra.class);
ec.encodeWithChildContext(raCodec, writer, ra);
}
writer.writeEndArray();
writer.writeEndDocument();
}
@Override
public Class<DutyBlock> getEncoderClass() {
return DutyBlock.class;
}
@Override
public DutyBlock decode(BsonReader reader, DecoderContext dc) {
reader.readStartDocument();
Codec<LocalDate> dateCodec = codecRegistry.get(LocalDate.class);
reader.readName();
LocalDate startDate = dateCodec.decode(reader, dc);
reader.readName();
LocalDate endDate = dateCodec.decode(reader, dc);
reader.readName();
int blockLength = reader.readInt32();
reader.readName();
double pointValue = reader.readDouble();
//Reading ArrayList of RAs
reader.readName();
Codec<Ra> raCodec = codecRegistry.get(Ra.class);
ArrayList<Ra> rasOnDuty = new ArrayList<>();
reader.readStartArray();
while (reader.readBsonType() != BsonType.END_OF_DOCUMENT) {
rasOnDuty.add(raCodec.decode(reader, dc));
}
reader.readEndArray();
reader.readEndDocument();
return new DutyBlock(startDate, endDate, blockLength, pointValue, rasOnDuty);
}
}
DutyBlockCodec
दूसरे कोडेक पर निर्भर करता है, और इसलिए एक CodecRegistry
. की आवश्यकता होती है इसके निर्माता पर पारित किया जाना है। जबकि मेरा मानना है कि CodecRegistry
. बनाना संभव है LocalDateCodec
. के साथ , फिर इसे DutyBlockCodec
. के तर्क के रूप में पास करें कंस्ट्रक्टर, फिर एक और CodecRegistry
create बनाएं दोनों LocalDateCodec
. युक्त और DutyBlockCodec
, यह बल्कि भ्रमित करने वाला है, और MongoDB एक कार्यक्षमता प्रदान करता है, CodecProvider
इस प्रक्रिया को सुविधाजनक बनाने के लिए।
CodecProvider
का उपयोग करना इंटरफ़ेस, मैंने एक DutyBlockCodecProvider
लिखा था
public class DutyBlockCodecProvider implements CodecProvider {
@Override
public <T> Codec<T> get(Class<T> type, CodecRegistry cr) {
if (type == DutyBlock.class) {
return (Codec<T>) new DutyBlockCodec(cr);
}
return null;
}
}
मैंने ये CodecProviders
जोड़े हैं MongoDB क्लाइंट के लिए CodecRegistries.fromProviders()
. का उपयोग कर विधि।
CodecRegistry codecRegistry = CodecRegistries.fromRegistries(
CodecRegistries.fromCodecs(new LocalDateCodec()),
CodecRegistries.fromProviders(
new RaCodecProvider(),
new DutyBlockCodecProvider(),
new ScheduledDutyCodecProvider()),
MongoClient.getDefaultCodecRegistry());
MongoClientOptions options = MongoClientOptions.builder()
.codecRegistry(codecRegistry).build();
mongoClient = new MongoClient(new ServerAddress(), options);
db = mongoClient.getDatabase("DutySchedulerDB");
इस परियोजना के लिए मेरा स्रोत कोड https://github.com/desrepair/DutyScheduler पर पाया जा सकता है, मैं लोगों के किसी भी प्रश्न का उत्तर देने के लिए तैयार हूं।