Serializing Benda

Perpustakaan Konfigurasi juga menyediakan sarana untuk men - tweak serialisasi dan deserialization objek secara otomatis. Secara default, satu set tipe data dapat (de) serial: antara lain String, ints, doubles, UUIDs, Lists (dari nilai serializable) dan Maps (di mana kedua kunci dan nilai serializable). Jika anda ingin menulis struktur data anda ke file konfigurasi, ini tidak akan cukup.

Bayangkan sebuah struktur data yang melacak berapa banyak berlian yang ditambang pemain. Mungkin terlihat sedikit seperti ini:

public class DiamondCounter {
    private UUID playerUUID;
    private int diamonds;

    ...
}

Juga asumsikan beberapa metode untuk mengakses bidang tersebut, pengaturan konstruktor yang bagus, baik dari keduanya, dll.

Membuat TypeSerializer kustom

Cara penulisan dan pemuatan struktur data yang sangat mudah adalah memberikan custom: javadoc: TypeSerializer. Antarmuka TypeSerializer` menyediakan dua metode, satu untuk menulis data dari sebuah objek ke node konfigurasi dan satu untuk membuat objek dari simpul konfigurasi yang diberikan.

import com.google.common.reflect.TypeToken;
import ninja.leaping.configurate.objectmapping.ObjectMappingException;
import ninja.leaping.configurate.objectmapping.serialize.TypeSerializer;

public class DiamondCounterSerializer implements TypeSerializer<DiamondCounter> {

    @Override
    public DiamondCounter deserialize(TypeToken<?> type, ConfigurationNode value)
      throws ObjectMappingException {
        UUID player = value.getNode("player").getValue(TypeToken.of(UUID.class));
        int diamonds = value.getNode("diamonds").getInt();
        return new DiamondCounter(player, diamonds);
    }

    @Override
    public void serialize(TypeToken<?> type, DiamondCounter obj, ConfigurationNode value)
      throws ObjectMappingException {
        value.getNode("player").setValue(obj.getPlayerUUID());
        value.getNode("diamonds").setValue(obj.getDiamonds());
    }
}

Ini '' TypeSerializer'' harus kemudian terdaftar dengan Configurate. Ini dapat dilakukan baik secara global, dengan mendaftar untuk :javadoc: default 'TypeSerializerCollection' atau secara lokal, dengan menetapkan itu di :javadoc: 'ConfigurationOptions' ketika loading konfigurasi Anda.

** Contoh Kode: Mendaftarkan TypeSerializer secara global **

import ninja.leaping.configurate.objectmapping.serialize.TypeSerializers;

TypeSerializers.getDefaultSerializers().registerType(TypeToken.of(DiamondCounter.class), new DiamondCounterSerializer());

** Contoh Kode: Mendaftarkan TypeSerializer secara lokal **

import ninja.leaping.configurate.ConfigurationNode;
import ninja.leaping.configurate.ConfigurationOptions;
import ninja.leaping.configurate.objectmapping.serialize.TypeSerializerCollection;
import ninja.leaping.configurate.objectmapping.serialize.TypeSerializers;

TypeSerializerCollection serializers = TypeSerializers.getDefaultSerializers().newChild();
serializers.registerType(TypeToken.of(DiamondCounter.class), new DiamondCounterSerializer());
ConfigurationOptions options = ConfigurationOptions.defaults().setSerializers(serializers);
ConfigurationNode rootNode = someConfigurationLoader.load(options);

Peringatan

Jika Anda memberikan tipe `` TypeSerializer 'khusus untuk jenis yang tidak diperkenalkan oleh plugin Anda sendiri, Anda seharusnya hanya mendaftarkannya secara lokal untuk menghindari konflik dengan plugin atau Sponge lainnya, yang disebabkan oleh `` TypeSerializer` yang akan ditimpa.

Menggunakan ObjectMappers

Karena dalam banyak kasus serialisasi (de) bermuara pada bidang pemetaan ke nodus konfigurasi, menulis semacam `` TypeSerializer`` adalah urusan yang agak membosankan dan sesuatu yang kami ingin Konfigurasi melakukannya sendiri. Jadi, mari anotasikan kelas kami dengan: javadoc: ConfigSerializable dan: javadoc:` Setting` anotasi.

import ninja.leaping.configurate.objectmapping.Setting;
import ninja.leaping.configurate.objectmapping.serialize.ConfigSerializable;

@ConfigSerializable
public class DiamondCounter {

    @Setting(value="player", comment="Player UUID")
    private UUID playerUUID;
    @Setting(comment="Number of diamonds mined")
    private int diamonds;

    ...
}

Contoh di atas sekarang bisa diserialisasikan dan di deserialized dari node konfigurasi tanpa registrasi lebih lanjut. Anotasi `` @ Setting`` memetakan simpul konfigurasi ke bidang yang diberi catatan. Ini menerima dua parameter opsional, `` value`` dan `` comment``. Jika parameter `` value`` ada, maka nama node akan ditentukan dalam field yang akan disimpan. Jika tidak ada, nama field akan digunakan sebagai gantinya. Jadi dalam contoh di atas, anotasi memastikan bahwa isi field `` playerUUID`` disimpan ke node "player", dikomentari dengan "Pemain UUID". Field `` intan` akan disimpan dengan nama persisnya karena anotasinya hanya menentukan komentar. Komentar itu akan ditulis ke konfigurasi jika implementasinya mendukung simpul konfigurasi yang berkomentar, jika tidak maka akan dibuang.

Tip

Anda boleh juga menggunakan singkatan @Setting("someNode") daripada @Setting(value="someNode")

Anotasi `` @ ConfigSerializable`` menghilangkan kebutuhan akan registrasi apapun karena memungkinkan Configurate hanya menghasilkan sebuah: javadoc: ObjectMapper untuk kelas. Satu-satunya batasan adalah Configurate membutuhkan konstruktor kosong untuk memberi instantiate objek baru sebelum mengisi bidang beranotasi.

Menyediakan ObjectMapperFactory kustom

Pembatasan itu, bagaimanapun, dapat dicabut jika kita menggunakan yang berbeda: javadoc: ObjectMapperFactory, misalnya a: javadoc:` GuiceObjectMapperFactory`. Alih-alih membutuhkan konstruktor kosong, ini akan bekerja pada kelas mana pun yang bisa dibuat melalui injeksi ketergantungan. Ini juga memungkinkan untuk campuran bidang `` @ Inject`` dan `` @ Setting`` beranotasi.

Plugin Anda hanya bisa mendapatkan `` GuiceObjectMapperFactory`` hanya dengan suntikan ketergantungan (lihat: doc: ../ injection) dan kemudian menyebarkannya ke` ConfigurationOptions`.

import org.spongepowered.api.event.Listener;
import org.spongepowered.api.event.game.state.GamePreInitializationEvent;
import org.spongepowered.api.plugin.Plugin;
import com.google.inject.Inject;
import ninja.leaping.configurate.commented.CommentedConfigurationNode;
import ninja.leaping.configurate.loader.ConfigurationLoader;
import ninja.leaping.configurate.objectmapping.GuiceObjectMapperFactory;

@Plugin(name="IStoleThisFromZml", id="shamelesslystolen", version="0.8.15")
public class StolenCodeExample {

    @Inject private GuiceObjectMapperFactory factory;
    @Inject private ConfigurationLoader<CommentedConfigurationNode> loader;

    @Listener
    public void enable(GamePreInitializationEvent event) {
        CommentedConfigurationNode node =
          loader.load(ConfigurationOptions.defaults().setObjectMapperFactory(factory));
        DiamondCounter myDiamonds = node.getValue(TypeToken.of(DiamondCounter.class));
    }
}

Catatan

Kode di atas adalah sebuah contoh dan, untuk singkatnya, tidak memiliki penanganan eksepsi yang tepat.