2013-08-13 4 views
6

Ich habe die folgende Methode, die ich verwenden, das Objekt zu yaml Darstellung umgewandelt zu bekommen (was ich kann zum Beispiel Druck auf die Konsole.)Java SnakeYAML - verhindern Dumping Referenznamen

@Nonnull 
private String outputObject(@Nonnull final ObjectToPrint packageSchedule) { 
    DumperOptions options = new DumperOptions(); 
    options.setAllowReadOnlyProperties(true); 
    options.setPrettyFlow(true); 
    return new Yaml(new Constructor(), new JodaTimeRepresenter(), options).dump(ObjectToPrint); 
} 

Alles ist gut, aber für einige Objekt enthalten innerhalb ObjectToPrint Struktur Ich bekomme so etwas wie Referenznamen und nicht den eigentlichen Objektinhalt, z.

!!com.blah.blah.ObjectToPrint 
businessYears: 
- businessYearMonths: 12 
    ppiYear: &id001 { 
    endDate: 30-06-2013, 
    endYear: 2013, 
    startDate: 01-07-2012, 
    startYear: 2012 
    } 
    ppiPeriod: 
    ppiYear: *id001 
    endDate: 27-03-2014 
    startDate: 21-06-2013 
    units: 24.000 
    number: 1 

Wie Sie das Beispiel sehen können oben I ppiYear Objekt gedruckt (markiert als $id001) haben und das gleiche Objekt in ppiPeriod verwendet, sondern nur der Referenzname wird gedruckt, das Objekt nicht Inhalt. Wie drucke ich den Objektinhalt jedes Mal, wenn ich dieses Objekt in meiner Struktur verwende, die ich in yaml konvertieren möchte(). PS. Es wäre schön, den Referenznamen überhaupt nicht zu drucken (&id001), aber das ist nicht entscheidend

Antwort

4

Dies liegt daran, dass Sie das gleiche Objekt an verschiedenen Stellen referenzieren. Um dies zu vermeiden, müssen Sie Kopien dieser Objekte erstellen. Yaml hat kein Flag, um dies auszuschalten, da Sie bei zyklischen Referenzen in Endlosschleifen geraten könnten. immer Sie könnten Yaml Quellcode zwicken doppelte Verweise zu ignorieren:

Blick auf Serializer line ~ 170 Methode serializeNode:

... 
if (this.serializedNodes.contains(node)) { 
    this.emmitter.emit(new AliasEvent(...)); 
} else { 
    serializedNodes.add(node); // <== Replace with myHook(serializedNodes,node); 
... 

void myHook(serializedNodes,node) { 
    if (node's class != myClass(es) to avoid) { 
     serializedNodes.add(node); 
    } 

, wenn Sie einen Weg finden, Yaml zu vermeiden Knoten in die serializedNodes Sammlung zu setzen, Ihre Das Problem wird gelöst, jedoch wird Ihr Programm bei zyklischen Referenzen endlos durchlaufen.

Die beste Lösung besteht darin, einen Hook hinzuzufügen, der verhindert, dass nur die Klasse registriert wird, die Sie einfach schreiben möchten.

+0

Ich habe gerade kommentiert ** if (this.serializedNodes.contains (node)) { this.emitter.emit (new AliasEvent (tAlias, null, null)); } sonst {** von serializeNode-Methode und ** anchorNode (Knoten); ** von serialize-Methode. Dies verhindert das Erstellen von Ankern und Aliasen. – Ajeesh

+0

Das hat der OP verlangt :-). Sie müssen myHook korrekt implementieren, um die ref-Erkennung nur für einige Klassen zu deaktivieren. –