I just realized I could have attached the file, I have attached the file to 
this message that way you don't need to go to pastbin.

-- 
You received this message because you are subscribed to the Google Groups 
"Google Web Toolkit" group.
To view this discussion on the web visit 
https://groups.google.com/d/msg/google-web-toolkit/-/gc_wH8407NYJ.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/google-web-toolkit?hl=en.

package gwtbugtest;

import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.notNullValue;
import static org.junit.Assert.assertThat;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.junit.Before;
import org.junit.Test;

import com.google.web.bindery.event.shared.SimpleEventBus;
import com.google.web.bindery.requestfactory.server.ExceptionHandler;
import com.google.web.bindery.requestfactory.server.ServiceLayer;
import com.google.web.bindery.requestfactory.server.SimpleRequestProcessor;
import com.google.web.bindery.requestfactory.server.testing.InProcessRequestTransport;
import com.google.web.bindery.requestfactory.shared.DefaultProxyStore;
import com.google.web.bindery.requestfactory.shared.EntityProxy;
import com.google.web.bindery.requestfactory.shared.Locator;
import com.google.web.bindery.requestfactory.shared.ProxyFor;
import com.google.web.bindery.requestfactory.shared.ProxySerializer;
import com.google.web.bindery.requestfactory.shared.Receiver;
import com.google.web.bindery.requestfactory.shared.Request;
import com.google.web.bindery.requestfactory.shared.RequestContext;
import com.google.web.bindery.requestfactory.shared.RequestFactory;
import com.google.web.bindery.requestfactory.shared.ServerFailure;
import com.google.web.bindery.requestfactory.shared.Service;
import com.google.web.bindery.requestfactory.vm.RequestFactorySource;

/***
 * I'm using this to set up a POC for a bug which I believe exists in GWT related
 * to their ProxySerializer.
 * 
 * Basically when trying to deserialize an proxy object from a ProxyStore twice will cause an 
 * exception, but it also causes an issue when deserializing an object with a reference to another
 * object that was already deserialized.
 * 
 * @author jmartinez
 *
 */

public class ProxySerializerBugTest {

	public static class MyEntity {
		private Integer id;
		private Integer version;
		private String name;
		private MyEntity parent;
		
		public MyEntity() {	}
		
		public MyEntity(Integer id, Integer version, String name, MyEntity parent) {
			this.id = id;
			this.version = version;
			this.name = name;
			this.parent = parent;
		}

		public Integer getId() {
			return id;
		}
		public void setId(Integer id) {
			this.id = id;
		}
		public Integer getVersion() {
			return version;
		}
		public void setVersion(Integer version) {
			this.version = version;
		}
		public String getName() {
			return name;
		}
		public void setName(String name) {
			this.name = name;
		}
		public MyEntity getParent() {
			return parent;
		}
		public void setParent(MyEntity parent) {
			this.parent = parent;
		}	
	}
	
	@ProxyFor(value=MyEntity.class, locator=MyEntityLocator.class)
	public static interface MyEntityProxy extends EntityProxy {
		Integer getId();
		Integer getVersion();
		String getName();
		MyEntityProxy getParent();
	}
	
	public static class MyEntityLocator extends Locator<MyEntity, Integer> {
		
		private static final Map<Integer, MyEntity> myDb;
		
		static {
			myDb = new HashMap<Integer, ProxySerializerBugTest.MyEntity>();
			myDb.put(1, new MyEntity(1,1,"The parent",null));
			myDb.put(2, new MyEntity(2,1,"Child with id 2",myDb.get(1)));
			myDb.put(3, new MyEntity(3,1,"Child with id 3",myDb.get(1)));
			myDb.put(4, new MyEntity(4,1,"Child with id 4",myDb.get(1)));
			myDb.put(5, new MyEntity(5,1,"Parent with id 5",null));
			myDb.put(6, new MyEntity(6,1,"Parent with id 6",null));
		}
		
		public MyEntityLocator() {	}

		@Override
		public MyEntity create(Class<? extends MyEntity> clazz) {
			return new MyEntity();
		}

		@Override
		public MyEntity find(Class<? extends MyEntity> clazz, Integer id) {
			return myDb.get(id);
		}

		@Override
		public Class<MyEntity> getDomainType() {
			return MyEntity.class;
		}

		@Override
		public Integer getId(MyEntity domainObject) {
			return domainObject.getId();
		}

		@Override
		public Class<Integer> getIdType() {
			return Integer.class;
		}

		@Override
		public Object getVersion(MyEntity domainObject) {
			return domainObject.getVersion();
		}
		
		public static List<MyEntity> getAll() {
			return new ArrayList<ProxySerializerBugTest.MyEntity>(myDb.values());
		}
		
		public static List<MyEntity> getAllParents() {
			List<MyEntity> results = new ArrayList<ProxySerializerBugTest.MyEntity>();
			results.add(myDb.get(1));
			results.add(myDb.get(5));
			results.add(myDb.get(6));
			return results;
		}
	}
	
	@Service(value = MyEntityLocator.class)
	public static interface MyEntityRequest extends RequestContext {
		Request<List<MyEntityProxy>> getAll();
		Request<List<MyEntityProxy>> getAllParents();
	}
	
	public static interface MyAppRequestFactory extends RequestFactory {
		MyEntityRequest myEntityRequest();
	}
	
	MyAppRequestFactory factory = null;
	
	@Before
	public void setupAppRequestFactory() {
		ServiceLayer serviceLayer = ServiceLayer.create();
		SimpleRequestProcessor processor = new SimpleRequestProcessor(serviceLayer);
		processor.setExceptionHandler(new ExceptionHandler() {		
			@Override
			public ServerFailure createServerFailure(Throwable throwable) {
				if (throwable!=null) {
					throwable.printStackTrace();
				}
			    return new ServerFailure(
			            "Server Error: " + (throwable == null ? null : throwable.getMessage()), null, null, true);
			}
		});
		this.factory = RequestFactorySource.create(MyAppRequestFactory.class);
		this.factory.initialize(new SimpleEventBus(), new InProcessRequestTransport(processor));
	}
	
	@Test
	public void testGetAll() {
		this.factory.myEntityRequest().getAll().with("parent").fire(new Receiver<List<MyEntityProxy>>() {
			@Override
			public void onSuccess(List<MyEntityProxy> response) {
				assertThat(response, is(notNullValue()));
				assertThat(response.size(), is(equalTo(6)));
			}
		});
	}
	
	@Test
	public void testGetAllParents() {
		this.factory.myEntityRequest().getAllParents().with("parent").fire(new Receiver<List<MyEntityProxy>>() {
			@Override
			public void onSuccess(List<MyEntityProxy> response) {
				assertThat(response, is(notNullValue()));
				assertThat(response.size(), is(equalTo(3)));
			}
		});
	}
	
	@Test
	public void testGetAllParentsProxySerializeDeserialize() {
		final List<List<MyEntityProxy>> rfResult = new ArrayList<List<MyEntityProxy>>(1);
		this.factory.myEntityRequest().getAllParents().with("parent").fire(new Receiver<List<MyEntityProxy>>() {
			@Override
			public void onSuccess(List<MyEntityProxy> response) {
				assertThat(response, is(notNullValue()));
				assertThat(response.size(), is(equalTo(3)));
				rfResult.add(response);
			}
		});
		assertThat(rfResult.size(), is(equalTo(1)));
		
		List<MyEntityProxy> response = rfResult.get(0);
		
		doProxySerializerTest(response);
	}
	
	@Test
	public void testGetAllProxySerializeDeserialize() {
		final List<List<MyEntityProxy>> rfResult = new ArrayList<List<MyEntityProxy>>(1);
		this.factory.myEntityRequest().getAll().fire(new Receiver<List<MyEntityProxy>>() {
			@Override
			public void onSuccess(List<MyEntityProxy> response) {
				assertThat(response, is(notNullValue()));
				assertThat(response.size(), is(equalTo(6)));
				rfResult.add(response);
			}
		});
		assertThat(rfResult.size(), is(equalTo(1)));
		
		List<MyEntityProxy> response = rfResult.get(0);
		
		doProxySerializerTest(response);
	}
	
	@Test
	public void testGetAllProxySerializeDeserializeWithParentProxyObjectsSet() {
		final List<List<MyEntityProxy>> rfResult = new ArrayList<List<MyEntityProxy>>(1);
		this.factory.myEntityRequest().getAll().with("parent").fire(new Receiver<List<MyEntityProxy>>() {
			@Override
			public void onSuccess(List<MyEntityProxy> response) {
				assertThat(response, is(notNullValue()));
				assertThat(response.size(), is(equalTo(6)));
				rfResult.add(response);
			}
		});
		assertThat(rfResult.size(), is(equalTo(1)));
		
		List<MyEntityProxy> response = rfResult.get(0);
		
		doProxySerializerTest(response);
	}

	private void doProxySerializerTest(List<MyEntityProxy> response) {
		// serialize the response
		DefaultProxyStore store = new DefaultProxyStore();
		ProxySerializer ser = factory.getSerializer(store);
		List<String> keys = new ArrayList<String>();
		
		for (MyEntityProxy ep:response) {
			keys.add(ser.serialize(ep));
		}
		
		assertThat(keys.size(), is(equalTo(response.size())));
		
		String payload = store.encode();
		assertThat(payload, is(notNullValue()));
		
		// assume the list of keys and payload is available to the client via Dictionary values
		
		// now make sure we can deserialize it
		List<MyEntityProxy> deserialized = new ArrayList<MyEntityProxy>();
		DefaultProxyStore clientstore = new DefaultProxyStore(payload);
		ProxySerializer clientser = factory.getSerializer(clientstore);
		
		for (String key:keys) {
			deserialized.add(clientser.deserialize(MyEntityProxy.class, key));
		}
		
		assertThat(deserialized.size(), is(equalTo(response.size())));
	}
}

Reply via email to