Nesneleri Serileştirme

Yapılandırma kitaplığı ayrıca nesnelerin otomatik serileştirilmesi ve serileştirilmesi için gerekli araçları da sağlar. Varsayılan olarak, veri türleri kümesi (de)serialized: hale getirebilir: diğer dizeler arasında, ints, doubles, UUIDs, Lists (seri hale getirilebilir değerlerin) ve Maps (her iki anahtar ve değer de seri hale getirilebilir). Ancak, özel veri yapılarınızı bir yapılandırma dosyasına yazmak istiyorsanız, bu yeterli olmayacaktır.

Bir oyuncunun kaç elmas kazandığını izleyen bir veri yapısı düşünün. Biraz benzeyebilir:

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

    ...
}

Ayrıca bu alanlara erişmek için bazı yöntemler varsayalım, bu vb her ikisi de güzel bir yapıcı ayarı.

Özel bir TypeSerializer oluşturma

Bu tür bir veri yapısı yazma ve yükleme çok basit, özel bir :javadoc:`TypeSerializer`sağlar. ``TypeSerializer`` arabirimi, verileri bir nesneden bir yapılandırma düğümüne yazmak için iki yöntem ve belirli bir yapılandırma düğümünden bir nesne oluşturmak için arabirim sağlar.

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());
    }
}

Daha sonra bu``TypeSerializer`` yapılandırılarak kaydedilir. Bu genellikle, varsayılan TypeSerializerCollection veya yerel olarak, yapılandırmanızı yüklerken ConfigurationOptions içinde belirtilerek yapılabilir.

** Kod örneği: Bir TypeSerializer’ın genel olarak kaydedilmesi **

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

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

** Kod örneği: Bir TypeSerializer’ın yerel olarak kaydedilmesi **

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);

Uyarı

Eğer kendi eklentiniz tarafından kullanılmayan türler için özel bir TypeSerializer sağladıysanız, TypeSerializer’ın üzerine yazılmasından kaynaklanan diğer eklentiler veya Sponge ile uyumlu olmayanlar eklentiler için yerel olarak kaydetmelisiniz.

ObjectMappers kullanımı

Çoğu durumda serileştirme, harita alanlarını yapılandırma düğümlerine çevirir, böyle bir TypeSerializer yazmak oldukça sıkıcı bir durum ve yapılandırmada kendi başına yapılmasını istediğimiz bir durumdur. Bunu :javadoc: ConfigSerializable ve :javadoc:` Setting` bölümlerinde açıklayalım.

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;

    ...
}

Yukarıdaki örnek şimdi daha fazla kayıt olmadan yapılandırma düğümlerinden seri hale getirilebilir. @Setting açıklamaları, bir biçim düğümünü açıklama yapılan alanla eşleştirir. İki isteğe bağlı parametre, value ve comment kabul eder. Eğer value parametresi mevcutsa, alanın kaydedileceği düğümün adını tanımlar. Eğer mevcut değilse alanın adı kullanılır. Yukarıdaki örnekte, açıklama, playerUUID alanının içeriğinin “playerUUID” ile yorumlandığı ‘’player’’ düğümüne kaydedilmesini sağlar. Bununla birlikte, diamonds alanı, tam açıklamanın sadece bir yorum belirttiği için bu tam ad altında kaydedilecektir. Uygulama, yorumlanan yapılandırma düğümlerini destekliyorsa, bu yorum yapılandırmaya yazılır, yoksa atılır.

Tüyo

@Setting(value ="someNode") yerine @Setting("someNode") kısaltmasını da kullanabilirsiniz

@ConfigSerializable annotation’ı class için Configurate’in ObjectMapper oluşturmasına olanak sağladığından dolayı başka kayıtlara muhtaç kalınmasını engeller. Tek sınırlama Configurate’in belirlenmiş yerleri doldurabilmek için boş bir constructor’a ihtiyaç duymasıdır.

Özel bir ObjectMapperFactory sağlanıyor

Kısıtlama, farklı bir ObjectMapperFactory kullandığımızda, örneğin GuiceObjectMapperFactory, ortadan kaldırılabilir. Bu durumda boş bir constuctor’a ihtiyaç duyulması yerine guice’un dependency injenction ile oluşturabileceği tüm class’larda çalışır. Bu ayrıca @Inject ve @Setting gibi belirlenmiş yerlerin karışımına da olanak sağlar.

Eklentiniz, dependency injection (bkz Bağımlılık Enjeksiyonu) kullanıp bunu ConfigurationOptions``a okutarak``GuiceObjectMapperFactory kullanabilir.

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));
    }
}

Not

Yukarıda ki kod bir örnektir ve özlük için uygun bir istisna işlemesinden yoksundur.