package org.jolokia.converter.json; import java.beans.Transient; import java.io.File; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.util.*; import javax.management.*; import org.jolokia.converter.object.StringToObjectConverter; import org.testng.annotations.*; import static org.testng.AssertJUnit.*; /* * Copyright 2009-2013 Roland Huss * * 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. */ /** * Testing the converter * * @author roland * @since Jul 24, 2009 */ public class ObjectToJsonConverterTest { private ObjectToJsonConverter converter; @BeforeMethod public void setup() { converter = new ObjectToJsonConverter(new StringToObjectConverter(),null); converter.setupContext(); } @AfterMethod public void tearDown() { converter.clearContext(); } @Test public void basics() throws AttributeNotFoundException { Map result = (Map) converter.extractObject(new SelfRefBean1(), new Stack<String>(), true); assertNotNull("Bean2 is set",result.get("bean2")); assertNotNull("Binary attribute is set",result.get("strong")); } @Test public void checkDeadLockDetection() throws AttributeNotFoundException { Map result = (Map) converter.extractObject(new SelfRefBean1(), new Stack<String>(), true); assertNotNull("Bean 2 is set",result.get("bean2")); assertNotNull("Bean2:Bean1 is set",((Map)result.get("bean2")).get("bean1")); assertEquals("Reference breackage",((Map)result.get("bean2")).get("bean1").getClass(),String.class); assertTrue("Bean 3 should be resolved",result.get("bean3") instanceof Map); } @Test public void maxDepth() throws AttributeNotFoundException, NoSuchFieldException, IllegalAccessException { setOptionsViaReflection("maxDepth",2); Map result = (Map) converter.extractObject(new SelfRefBean1(), new Stack<String>(), true); String c = (String) ((Map) result.get("bean2")).get("bean1"); assertTrue("Recurence detected",c.contains("bean1: toString")); } @Test public void maxObjects() throws NoSuchFieldException, IllegalAccessException, AttributeNotFoundException { setOptionsViaReflection("maxObjects",1); Map<String,Object> result = (Map) converter.extractObject(new InnerValueTestBean("foo", "bar", "baz"), new Stack<String>(), true); boolean found = false; for (Object val : result.values()) { if (val instanceof String) { found = ((String) val).matches("^\\[.*(limit).*\\]$"); } } assertTrue(found); } private void setOptionsViaReflection(String pLimit, int pVal) throws NoSuchFieldException, IllegalAccessException { ObjectSerializationContext ctx = converter.getStackContextLocal().get(); Field field = ObjectSerializationContext.class.getDeclaredField("options"); field.setAccessible(true); JsonConvertOptions opts = (JsonConvertOptions) field.get(ctx); field = JsonConvertOptions.class.getDeclaredField(pLimit); field.setAccessible(true); field.set(opts,pVal); } @Test public void customSimplifier() throws AttributeNotFoundException { Date date = new Date(); Map result = (Map) converter.extractObject(date, new Stack<String>(), true); assertEquals(date.getTime(),result.get("millis")); } @Test public void fileSimplifier() throws AttributeNotFoundException { Map result = (Map) converter.extractObject(new File("/tmp"), new Stack<String>(), true); assertNull(result.get("parent")); } @Test public void customNegativeSimpifier() throws MalformedObjectNameException, AttributeNotFoundException { ObjectName name = new ObjectName("java.lang:type=Memory"); Map result = (Map) converter.extractObject(name, new Stack<String>(), true); // Since we removed the objectname simplifier from the list of simplifiers // explicitely, the converter should return the full blown object; assertEquals("type=Memory",result.get("canonicalKeyPropertyListString")); } @Test public void convertToJsonTest() throws MalformedObjectNameException, AttributeNotFoundException { File file = new File("myFile"); Map ret = (Map) converter.convertToJson(file, null, JsonConvertOptions.DEFAULT); assertEquals(ret.get("name"),"myFile"); String name = (String) converter.convertToJson(file, Arrays.asList("name"), JsonConvertOptions.DEFAULT); assertEquals(name,"myFile"); } @Test public void setInnerValueTest() throws IllegalAccessException, AttributeNotFoundException, InvocationTargetException { InnerValueTestBean bean = new InnerValueTestBean("foo","bar","baz"); Object oldValue = converter.setInnerValue(bean,"blub",new ArrayList<String>(Arrays.asList("map","foo","1"))); assertEquals(oldValue,"baz"); assertEquals(bean.getMap().get("foo").get(0),"bar"); assertEquals(bean.getMap().get("foo").get(1),"blub"); oldValue = converter.setInnerValue(bean,"fcn",new ArrayList<String>(Arrays.asList("array","0"))); assertEquals(oldValue,"bar"); assertEquals(bean.getArray()[0],"fcn"); } @Test public void convertTransientValue() throws AttributeNotFoundException { TransientValueBean bean = new TransientValueBean(); bean.value = "value"; bean.transientValue = "transient"; Map ret = (Map)converter.convertToJson(bean, null, JsonConvertOptions.DEFAULT); assertNull(ret.get("transientValue")); assertEquals(ret.get("value"),"value"); } // ============================================================================ // TestBeans: class SelfRefBean1 { SelfRefBean2 bean2; SelfRefBean3 bean3; boolean strong; SelfRefBean1() { bean3 = new SelfRefBean3(this); bean2 = new SelfRefBean2(this,bean3); } public SelfRefBean2 getBean2() { return bean2; } public SelfRefBean3 getBean3() { return bean3; } public boolean isStrong() { return strong; } public String toString() { return "bean1: toString"; } } class SelfRefBean2 { SelfRefBean1 bean1; SelfRefBean3 bean3; SelfRefBean2(SelfRefBean1 pBean1,SelfRefBean3 pBean3) { bean1 = pBean1; bean3 = pBean3; } public SelfRefBean1 getBean1() { return bean1; } public SelfRefBean3 getBean3() { return bean3; } } class SelfRefBean3 { SelfRefBean1 bean1; SelfRefBean3(SelfRefBean1 pBean1) { bean1 = pBean1; } public SelfRefBean1 getBean1() { return bean1; } } class InnerValueTestBean { private Map<String, List<String>> map; private String[] array; InnerValueTestBean(String key, String value1, String value2) { map = new HashMap<String, List<String>>(); map.put(key,Arrays.asList(value1, value2)); array = new String[] { value1, value2 }; } public Map<String, List<String>> getMap() { return map; } public String[] getArray() { return array; } } class TransientValueBean { String value; transient String transientValue; public String getValue() { return value; } public void setValue(String value) { this.value = value; } @Transient public String getTransientValue() { return transientValue; } @Transient public void setTransientValue(String transientValue) { this.transientValue = transientValue; } } }