/*
 * Copyright (C) 2008 XStream Committers.
 * All rights reserved.
 *
 * The software in this package is published under the terms of the BSD
 * style license a copy of which has been included with this distribution in
 * the LICENSE.txt file.
 * 
 * Created on 12. November 2008 by Joerg Schaible
 */
package com.thoughtworks.acceptance;

import com.thoughtworks.xstream.converters.ConverterLookup;
import com.thoughtworks.xstream.core.ReferenceByIdMarshaller;
import com.thoughtworks.xstream.core.ReferenceByIdMarshallingStrategy;
import com.thoughtworks.xstream.core.TreeMarshaller;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
import com.thoughtworks.xstream.mapper.Mapper;

public class BeanIDCircularReferenceTest extends AbstractCircularReferenceTest {

    // inherits test from superclass
    protected void setUp() throws Exception {
        super.setUp();
        xstream.setMarshallingStrategy(new ReferenceByIdMarshallingStrategy(){

            protected TreeMarshaller createMarshallingContext(HierarchicalStreamWriter writer,
                ConverterLookup converterLookup, Mapper mapper) {
                return new ReferenceByIdMarshaller(writer, converterLookup, mapper, new ReferenceByIdMarshaller.IDGenerator(){

                    public String next(Object item) {
                        // we have only persons here
                        return ((Person)item).firstname;
                    }});
            }
            
        });
    }

    public void testCircularReferenceXml() {
        Person bob = new Person("bob");
        Person jane = new Person("jane");
        bob.likes = jane;
        jane.likes = bob;

        String expected = "" +
                "<person id=\"bob\">\n" +
                "  <firstname>bob</firstname>\n" +
                "  <likes id=\"jane\">\n" +
                "    <firstname>jane</firstname>\n" +
                "    <likes reference=\"bob\"/>\n" +
                "  </likes>\n" +
                "</person>";

        assertEquals(expected, xstream.toXML(bob));
    }

    public void testCircularReferenceToSelfXml() {
        Person bob = new Person("bob");
        bob.likes = bob;

        String expected = "" +
                "<person id=\"bob\">\n" +
                "  <firstname>bob</firstname>\n" +
                "  <likes reference=\"bob\"/>\n" +
                "</person>";

        assertEquals(expected, xstream.toXML(bob));
    }

}

@@ -17,16 +17,22 @@
 (C) 2008
+, 2010
  XStream
@@ -786,129 +786,126 @@
     
-// inherits test from superclass%0A    protected void setUp() throws Exception %7B%0A        super.setUp();%0A        xstream.set
+private ReferenceByFirstnameMarshallingStrategy marshallingStrategy;%0A%0A%09private static final class ReferenceByFirstname
 Mars
@@ -923,12 +923,16 @@
 tegy
-(new
+ extends
  Ref
@@ -960,33 +960,22 @@
 Strategy
-()%7B%0A%0A            
+%0A%09%7B%0A%09%09
 protecte
@@ -1049,28 +1049,18 @@
 writer,%0A
-            
+%09%09
     Conv
@@ -1101,36 +1101,26 @@
 r mapper) %7B%0A
-            
+%09%09
     return n
@@ -1223,28 +1223,18 @@
 tor()%7B%0A%0A
-            
+%09%09
         
@@ -1267,28 +1267,18 @@
 item) %7B%0A
-            
+%09%09
         
@@ -1310,24 +1310,18 @@
 ns here%0A
-        
+%09%09
         
@@ -1324,20 +1324,16 @@
         
-    
 return (
@@ -1357,28 +1357,18 @@
 stname;%0A
-            
+%09%09
         
@@ -1376,44 +1376,248 @@
 %7D);%0A
-            %7D%0A         
+%09%09%7D%0A%09%7D%0A%0A%09// inherits test from superclass%0A    protected void setUp() throws Exception %7B%0A        super.setUp();%0A
    
-%0A
      
-   %7D
+marshallingStrategy = new ReferenceByFirstnameMarshallingStrategy();%0A%09%09xstream.setMarshallingStrategy(marshallingStrategy
 );%0A 
@@ -2580,10 +2580,938 @@
 %0A    %7D%0A%0A
+    public void testCanAvoidMemberIfUsedAsId() throws Exception%0A%09%7B%0A%09%09xstream.omitField(Person.class, %22firstname%22);%0A%0A        Person bob = new Person(%22bob%22);%0A        Person jane = new Person(%22jane%22);%0A        bob.likes = jane;%0A        jane.likes = bob;%0A%0A        String expected = %22%22 +%0A                %22%3Cperson id=%5C%22bob%5C%22%3E%5Cn%22 +%0A                %22  %3Clikes id=%5C%22jane%5C%22%3E%5Cn%22 +%0A                %22    %3Clikes reference=%5C%22bob%5C%22/%3E%5Cn%22 +%0A                %22  %3C/likes%3E%5Cn%22 +%0A                %22%3C/person%3E%22;%0A%0A        assertEquals(expected, xstream.toXML(bob));%0A        %0A        setUp(); // new XStream instance, since marshal and unmarshal is asymmetric%0A        xstream.useAttributeFor(%22firstname%22, String.class);%0A        xstream.aliasField(%22id%22, Person.class, %22firstname%22);%0A        %0A        Person bobAgain = (Person)xstream.fromXML(expected);%0A        assertEquals(%22bob%22, bobAgain.firstname);%0A        assertEquals(%22jane%22, bobAgain.likes.firstname);%0A%09%7D%0A
 %7D%0A

Test independent XStream instances for asymmetric marshal/unmarshal operation if member is used as ID that should not be repeated as member.