/* * Copyright 2009 Martin Grotzke * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package de.javakaffee.web.msm.serializer.xstream; import java.io.Serializable; import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.util.HashMap; import java.util.Map; import org.apache.catalina.core.StandardContext; import org.apache.catalina.session.StandardSession; import org.testng.Assert; import org.testng.annotations.Test; import de.javakaffee.web.msm.MemcachedBackupSession; import de.javakaffee.web.msm.MemcachedBackupSessionManager; import de.javakaffee.web.msm.serializer.xstream.XStreamTranscoderTest.Person.Gender; /** * Test for {@link XStreamTranscoder}. * * @author Martin Grotzke (martin.grotzke@freiheit.com) (initial creation) */ public class XStreamTranscoderTest { @Test public void testReadValueIntoObject() throws Exception { final MemcachedBackupSessionManager manager = new MemcachedBackupSessionManager(); manager.setContainer( new StandardContext() ); final XStreamTranscoder transcoder = new XStreamTranscoder( manager ); final MemcachedBackupSession session = manager.createEmptySession(); session.setValid( true ); session.setCreationTime( System.currentTimeMillis() ); getField( StandardSession.class, "lastAccessedTime" ).set( session, System.currentTimeMillis() + 100 ); session.setMaxInactiveInterval( 600 ); session.setId( "foo" ); session.setAttribute( "person1", createPerson( "foo bar", Gender.MALE, "foo.bar@example.org", "foo.bar@example.com" ) ); session.setAttribute( "person2", createPerson( "bar baz", Gender.FEMALE, "bar.baz@example.org", "bar.baz@example.com" ) ); final long start1 = System.nanoTime(); transcoder.serializeAttributes( session, session.getAttributesInternal() ); System.out.println("xstream-ser took " + (System.nanoTime() - start1)/1000); final long start2 = System.nanoTime(); transcoder.serializeAttributes( session, session.getAttributesInternal() ); System.out.println("xstream-ser took " + (System.nanoTime() - start2)/1000); final long start3 = System.nanoTime(); final byte[] json = transcoder.serializeAttributes( session, session.getAttributesInternal() ); final Map<String, Object> readValue = (Map<String, Object>) transcoder.deserializeAttributes( json ); System.out.println("xstream-round took " + (System.nanoTime() - start3)/1000); //System.out.println( "Have json: " + new String(json) ); assertEquals( readValue, session.getAttributesInternal() ); } private Person createPerson( final String name, final Gender gender, final String... emailAddresses ) { final Person person = new Person(); person.setName( name ); person.setGender( gender ); final HashMap<String, Object> props = new HashMap<String, Object>(); for ( int i = 0; i < emailAddresses.length; i++ ) { final String emailAddress = emailAddresses[i]; props.put( "email" + i, new Email( name, emailAddress ) ); } person.setProps( props ); return person; } private Field getField( final Class<?> clazz, final String name ) throws NoSuchFieldException { final Field field = clazz.getDeclaredField( name ); field.setAccessible( true ); return field; } /* * person2=Person * [_gender=FEMALE, _name=bar baz, * _props={email0=Email [_email=bar.baz@example.org, _name=bar baz], * email1=Email [_email=bar.baz@example.com, _name=bar baz]}], * person1=Person [_gender=MALE, _name=foo bar, * _props={email0=Email [_email=foo.bar@example.org, _name=foo bar], * email1=Email [_email=foo.bar@example.com, _name=foo bar]}]} * * but was: * person2={name=bar baz, * props={email0={name=bar baz, email=bar.baz@example.org}, * email1={name=bar baz, email=bar.baz@example.com}}, gender=FEMALE} * person1={name=foo bar, * props={email0={name=foo bar, email=foo.bar@example.org}, * email1={name=foo bar, email=foo.bar@example.com}}, gender=MALE}} */ private void assertEquals( final Object one, final Object another ) throws Exception { if ( one == another ) { return; } if ( one == null && another != null || one != null && another == null ) { Assert.fail( "One of both is null: " + one + ", " + another ); } Assert.assertEquals( one.getClass(), another.getClass() ); if ( one.getClass().isPrimitive() || one instanceof String || Number.class.isAssignableFrom( one.getClass() ) || one instanceof Boolean || one instanceof Map<?,?> ) { Assert.assertEquals( one, another ); return; } Class<? extends Object> clazz = one.getClass(); while ( clazz != null ) { assertEqualDeclaredFields( clazz, one, another ); clazz = clazz.getSuperclass(); } } private void assertEqualDeclaredFields( final Class<? extends Object> clazz, final Object one, final Object another ) throws Exception, IllegalAccessException { for ( final Field field : clazz.getDeclaredFields() ) { field.setAccessible( true ); if ( !Modifier.isTransient( field.getModifiers() ) ) { assertEquals( field.get( one ), field.get( another ) ); } } } static class Person implements Serializable { private static final long serialVersionUID = 1L; static enum Gender { MALE, FEMALE } private String _name; private Gender _gender; private Map<String, Object> _props; public String getName() { return _name; } public void setName( final String name ) { _name = name; } public Map<String, Object> getProps() { return _props; } public void setProps( final Map<String, Object> props ) { _props = props; } public Gender getGender() { return _gender; } public void setGender( final Gender gender ) { _gender = gender; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ( ( _gender == null ) ? 0 : _gender.hashCode() ); result = prime * result + ( ( _name == null ) ? 0 : _name.hashCode() ); result = prime * result + ( ( _props == null ) ? 0 : _props.hashCode() ); return result; } @Override public boolean equals( final Object obj ) { if ( this == obj ) return true; if ( obj == null ) return false; if ( getClass() != obj.getClass() ) return false; final Person other = (Person) obj; if ( _gender == null ) { if ( other._gender != null ) return false; } else if ( !_gender.equals( other._gender ) ) return false; if ( _name == null ) { if ( other._name != null ) return false; } else if ( !_name.equals( other._name ) ) return false; if ( _props == null ) { if ( other._props != null ) return false; } else if ( !_props.equals( other._props ) ) return false; return true; } @Override public String toString() { return "Person [_gender=" + _gender + ", _name=" + _name + ", _props=" + _props + "]"; } } static class Email implements Serializable { private static final long serialVersionUID = 1L; private String _name; private String _email; public Email( final String name, final String email ) { super(); _name = name; _email = email; } public String getName() { return _name; } public void setName( final String name ) { _name = name; } public String getEmail() { return _email; } public void setEmail( final String email ) { _email = email; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ( ( _email == null ) ? 0 : _email.hashCode() ); result = prime * result + ( ( _name == null ) ? 0 : _name.hashCode() ); return result; } @Override public boolean equals( final Object obj ) { if ( this == obj ) return true; if ( obj == null ) return false; if ( getClass() != obj.getClass() ) return false; final Email other = (Email) obj; if ( _email == null ) { if ( other._email != null ) return false; } else if ( !_email.equals( other._email ) ) return false; if ( _name == null ) { if ( other._name != null ) return false; } else if ( !_name.equals( other._name ) ) return false; return true; } @Override public String toString() { return "Email [_email=" + _email + ", _name=" + _name + "]"; } } }