2016-06-13 68 views
1

我一直在使用SnakeYAML進行某些序列化/反序列化。我的應用程序結合了Python和Java,所以我需要對標籤和類型進行一些「合理的行爲」。在JavaBean屬性上強制使用YAML標記

我的問題/實際的YAML文檔狀態:

!!mypackage.MyClassA 
someFirstField: normal string 
someSecondField: 
    a: !!mypackage.ThisIsIt 
    subField: 1 
    subOtherField: 2 
    b: !!mypackage.ThisIsIt 
    subField: 3 
    subOtherField: 4 
someThirdField: 
    subField: 5 
    subOtherField: 6 

我重新實現checkGlobalTag,簡單地進行return實現集合內(見例如someSecondField)使用的標籤。這一點,如果我理解正確的話,確保沒有snakeyaml的智能清潔和維護標籤。到目前爲止這麼好:我需要這個類型。

但是,這還不夠,因爲someThirdField也是!!mypackage.ThisIsIt,但它有隱含標記,這是一個問題(Python不理解它)。還有一些其他的角落案例並不重要(試圖在Python方面採取一些捷徑,並且他們成了一個糟糕的想法)。

哪種方法可以確保標籤對所有用戶定義的類都顯示?我認爲我應該重寫Representer上的一些方法,但我一直無法找到哪一個。

回答

1

負責人認爲「智能標記自動清潔」是以下行:

if (property.getType() == propertyValue.getClass()) 

可以在representJavaBeanProperty發現,該類Representer

的(醜陋的)解決方案,我發現是延長Representer@OverriderepresentJavaBeanProperty有以下幾點:

protected NodeTuple representJavaBeanProperty(Object javaBean, 
     Property property, 
     Object propertyValue, 
     Tag customTag) { 
    // Copy paste starts here... 

    ScalarNode nodeKey = (ScalarNode) representData(property.getName()); 
    // the first occurrence of the node must keep the tag 
    boolean hasAlias = this.representedObjects.containsKey(propertyValue); 

    Node nodeValue = representData(propertyValue); 

    if (propertyValue != null && !hasAlias) { 
     NodeId nodeId = nodeValue.getNodeId(); 
     if (customTag == null) { 
      if (nodeId == NodeId.scalar) { 
       if (propertyValue instanceof Enum<?>) { 
        nodeValue.setTag(Tag.STR); 
       } 
      } 
      // Copy-paste ends here !!! 
      // Ignore the else block --always maintain the tag. 
     } 
    } 

    return new NodeTuple(nodeKey, nodeValue); 

這也迫使顯式標籤上列出的行爲(先前通過的覆蓋強制執行現在已經在representJavaBeanProperty代碼中實現了checkGlobalTag方法)。