/*
* Copyright 2014 Nicolas Morel
*
* 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 com.github.nmorel.gwtjackson.shared.mixins;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
import com.github.nmorel.gwtjackson.shared.AbstractTester;
import com.github.nmorel.gwtjackson.shared.ObjectWriterTester;
public final class MixinSerForMethodsTester extends AbstractTester {
/*
/**********************************************************
/* Helper bean classes
/**********************************************************
*/
// base class: just one visible property ('b')
public static class BaseClass {
@SuppressWarnings("unused")
private String a;
private String b;
protected BaseClass() { }
public BaseClass( String a, String b ) {
this.a = a;
this.b = b;
}
@JsonProperty("b")
public String takeB() { return b; }
}
/* extends, just for fun; and to show possible benefit of being
* able to declare that a method is overridden (compile-time check
* that our intended mix-in override will match a method)
*/
public abstract static class MixIn extends BaseClass {
// let's make 'a' visible
@JsonProperty
String a;
@Override
@JsonProperty("b2")
public abstract String takeB();
// also: just for fun; add a "red herring"... unmatched method
@JsonProperty
abstract String getFoobar();
}
public static class LeafClass extends BaseClass {
public LeafClass( String a, String b ) { super( a, b ); }
@Override
@JsonIgnore
public String takeB() { return null; }
}
@JsonPropertyOrder( alphabetic = true )
public interface ObjectMixIn {
// and then ditto for hashCode..
@Override
@JsonProperty
public int hashCode();
}
public static class EmptyBean {}
public static class SimpleBean extends EmptyBean {
int x() { return 42; }
}
/**
* This mix-in is to be attached to EmptyBean, but really modify
* methods that its subclass, SimpleBean, has.
*/
public abstract class MixInForSimple {
// This should apply to sub-class
@JsonProperty("x")
abstract int x();
// and this matches nothing, should be ignored
@JsonProperty("notreally")
public int xxx() { return 3; }
// nor this
public abstract int getIt();
}
public static final MixinSerForMethodsTester INSTANCE = new MixinSerForMethodsTester();
private MixinSerForMethodsTester() {
}
/*
/**********************************************************
/* Unit tests
/**********************************************************
*/
/**
* Unit test for verifying that leaf-level mix-ins work ok;
* that is, any annotations added properly override all annotations
* that masked methods (fields etc) have.
*/
public void testLeafMixin( ObjectWriterTester<BaseClass> writer ) {
// with leaf-level mix-in
String json = writer.write( new BaseClass( "a1", "b2" ) );
assertEquals( "{\"a\":\"a1\",\"b2\":\"b2\"}", json );
}
/**
* Unit test for verifying that having a mix-in "between" classes
* (overriding annotations of a base class, but being overridden
* further by a sub-class) works as expected
*/
public void testIntermediateMixin( ObjectWriterTester<LeafClass> writer ) {
String json = writer.write( new LeafClass( "XXX", "b2" ) );
assertEquals( "{\"a\":\"XXX\"}", json );
}
/**
* Another intermediate mix-in, to verify that annotations
* properly "trickle up"
*/
public void testIntermediateMixin2( ObjectWriterTester<SimpleBean> writer ) {
String json = writer.write( new SimpleBean() );
assertEquals( "{\"x\":42}", json );
}
/**
* Unit test for verifying that it is actually possible to attach
* mix-in annotations to basic <code>Object.class</code>. This
* will essentially apply to any and all Objects.
*/
public void testObjectMixin( ObjectWriterTester<BaseClass> writer ) {
BaseClass bean = new BaseClass( "a", "b" );
String json = writer.write( bean );
assertEquals( "{\"b\":\"b\",\"hashCode\":" + bean.hashCode() + "}", json );
/* 15-Oct-2010, tatu: Actually, we now block serialization (attemps) of plain Objects, by default
* (since generally that makes no sense -- may need to revisit). As such, need to comment out
* this part of test
*/
/* Hmmh. For plain Object.class... I suppose getClass() does
* get serialized (and can't really be blocked either).
* Fine.
*/
/*
result = writeAndMap(mapper, new Object());
assertEquals(2, result.size());
ob = result.get("hashCode");
assertNotNull(ob);
assertEquals(Integer.class, ob.getClass());
assertEquals("java.lang.Object", result.get("class"));
*/
}
}