/** * This file Copyright (c) 2012 Magnolia International * Ltd. (http://www.magnolia-cms.com). All rights reserved. * * * This file is dual-licensed under both the Magnolia * Network Agreement and the GNU General Public License. * You may elect to use one or the other of these licenses. * * This file is distributed in the hope that it will be * useful, but AS-IS and WITHOUT ANY WARRANTY; without even the * implied warranty of MERCHANTABILITY or FITNESS FOR A * PARTICULAR PURPOSE, TITLE, or NONINFRINGEMENT. * Redistribution, except as permitted by whichever of the GPL * or MNA you select, is prohibited. * * 1. For the GPL license (GPL), you can redistribute and/or * modify this file under the terms of the GNU General * Public License, Version 3, as published by the Free Software * Foundation. You should have received a copy of the GNU * General Public License, Version 3 along with this program; * if not, write to the Free Software Foundation, Inc., 51 * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * 2. For the Magnolia Network Agreement (MNA), this file * and the accompanying materials are made available under the * terms of the MNA which accompanies this distribution, and * is available at http://www.magnolia-cms.com/mna.html * * Any modifications to this file must keep this entire header * intact. * */ package info.magnolia.jcr.node2bean; import static org.junit.Assert.*; import info.magnolia.commands.chain.ChainBase; import info.magnolia.commands.chain.Command; import info.magnolia.context.MgnlContext; import info.magnolia.jcr.node2bean.impl.CollectionPropertyHidingTransformer; import info.magnolia.jcr.node2bean.impl.Node2BeanProcessorImpl; import info.magnolia.jcr.node2bean.impl.Node2BeanTransformerImpl; import info.magnolia.jcr.node2bean.impl.TypeMappingImpl; import info.magnolia.objectfactory.Components; import info.magnolia.test.ComponentsTestUtil; import info.magnolia.test.mock.jcr.SessionTestUtil; import java.io.IOException; import java.text.MessageFormat; import java.util.AbstractMap; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.TreeSet; import java.util.Vector; import java.util.regex.Pattern; import javax.jcr.PathNotFoundException; import javax.jcr.RepositoryException; import javax.jcr.Session; import org.junit.After; import org.junit.Before; import org.junit.Ignore; import org.junit.Test; import com.google.common.collect.Iterables; /** * Node2Bean tests. */ public class Node2BeanTest { private final TypeMapping typeMapping = new TypeMappingImpl(); private final Node2BeanTransformer transformer = new Node2BeanTransformerImpl(); @Before public void setUp() { ComponentsTestUtil.setInstance(TypeMapping.class, typeMapping); } @After public void tearDown() { ComponentsTestUtil.clear(); MgnlContext.setInstance(null); } @Test public void testNodeToBeanWithClassDefined() throws Node2BeanException, PathNotFoundException, RepositoryException, IOException { // GIVEN Session session = SessionTestUtil.createSession("test", "/test/node.class=info.magnolia.jcr.node2bean.SimpleBean\n" + "/test/node.integer=999\n" + "/test/node.string=Hello\n" ); Node2BeanProcessorImpl node2bean = new Node2BeanProcessorImpl(typeMapping, transformer); // WHEN Object bean = node2bean.toBean(session.getNode("/test/node")); // THEN assertTrue(bean instanceof SimpleBean); assertEquals(999, ((SimpleBean) bean).getInteger()); assertEquals("Hello", ((SimpleBean) bean).getString()); } @Test public void testNodeToBeanWithSubBean() throws IOException, RepositoryException, Node2BeanException { // GIVEN Session session = SessionTestUtil.createSession("test", "/test/node.class=info.magnolia.jcr.node2bean.BeanWithSubBean\n" + "/test/node.integer=999\n" + "/test/node.string=Hello\n" + "/test/node/sub.class=info.magnolia.jcr.node2bean.OtherSimpleBean\n" + "/test/node/sub.integer=111\n" + "/test/node/sub.string=World\n" ); Node2BeanProcessorImpl node2bean = new Node2BeanProcessorImpl(typeMapping, transformer); // WHEN BeanWithSubBean bean = (BeanWithSubBean) node2bean.toBean(session.getNode("/test/node")); OtherSimpleBean sub = (OtherSimpleBean) bean.getSub(); // THEN assertNotNull(sub); assertEquals(999, bean.getInteger()); assertEquals("Hello", bean.getString()); assertEquals(111, sub.getInteger()); assertEquals("World", sub.getString()); } @Test public void testNodeToBeanWithSubMap() throws IOException, RepositoryException, Node2BeanException { // GIVEN Session session = SessionTestUtil.createSession("test", "/parent.class=info.magnolia.jcr.node2bean.BeanWithMapWithGenerics\n" + "/parent.integer=1\n" + "/parent.string=Hello\n" + "/parent/beans/sub1.integer=2\n" + "/parent/beans/sub1.string=World\n" + "/parent/beans/sub2.integer=3\n" + "/parent/beans/sub2.string=:)\n" ); Node2BeanProcessorImpl n2b = new Node2BeanProcessorImpl(typeMapping, transformer); BeanWithMapWithGenerics bean = (BeanWithMapWithGenerics) n2b.toBean(session.getNode("/parent")); // WHEN Map<String, SimpleBean> beans = bean.getBeans(); // THEN assertNotNull(beans); assertNotNull(beans.get("sub1")); assertNotNull(beans.get("sub2")); assertEquals(2, beans.get("sub1").getInteger()); assertEquals("World", beans.get("sub1").getString()); assertEquals(3, beans.get("sub2").getInteger()); assertEquals(":)", beans.get("sub2").getString()); } @Test public void testNode2BeanWithCollection() throws IOException, RepositoryException, Node2BeanException { // GIVEN Session session = SessionTestUtil.createSession("test", "/parent.class=info.magnolia.jcr.node2bean.BeanWithCollectionOfString\n" + "/parent/values.val1=test\n" + "/parent/values.val2=str\n" ); Node2BeanProcessorImpl n2b = new Node2BeanProcessorImpl(typeMapping, transformer); // WHEN BeanWithCollectionOfString bean = (BeanWithCollectionOfString) n2b.toBean(session.getNode("/parent")); // THEN assertNotNull(bean); assertEquals(2, bean.getValues().size()); assertTrue(bean.getValues().contains("test")); assertTrue(bean.getValues().contains("str")); } @Test public void testNodeToBeanWithList() throws IOException, RepositoryException, Node2BeanException { // GIVEN Session session = SessionTestUtil.createSession("test", "/parent.class=info.magnolia.jcr.node2bean.BeanWithListOfString\n" + "/parent/values.val1=test\n" + "/parent/values.val2=str\n" ); Node2BeanProcessorImpl n2b = new Node2BeanProcessorImpl(typeMapping, transformer); // WHEN BeanWithListOfString bean = (BeanWithListOfString) n2b.toBean(session.getNode("/parent")); // THEN assertNotNull(bean); assertTrue(bean.getValues() instanceof LinkedList); assertEquals(2, bean.getValues().size()); assertEquals("test", bean.getValues().get(0)); assertEquals("str", bean.getValues().get(1)); } @Test public void testNode2BeanWithSet() throws IOException, RepositoryException, Node2BeanException { // GIVEN Session session = SessionTestUtil.createSession("test", "/parent.class=info.magnolia.jcr.node2bean.BeanWithSetOfString\n" + "/parent/values.val1=test\n" + "/parent/values.val2=str\n" ); Node2BeanProcessorImpl n2b = new Node2BeanProcessorImpl(typeMapping, transformer); // WHEN BeanWithSetOfString bean = (BeanWithSetOfString) n2b.toBean(session.getNode("/parent")); // THEN assertNotNull(bean); assertTrue(bean.getValues() instanceof HashSet); assertEquals(2, bean.getValues().size()); assertTrue(bean.getValues().contains("test")); assertTrue(bean.getValues().contains("str")); } @Test public void testNode2BeanWithAraryList() throws IOException, RepositoryException, Node2BeanException { // GIVEN Session session = SessionTestUtil.createSession("test", "/parent.class=info.magnolia.jcr.node2bean.BeanWithArrayListOfString\n" + "/parent/values.val1=test\n" + "/parent/values.val2=str\n" ); Node2BeanProcessorImpl n2b = new Node2BeanProcessorImpl(typeMapping, transformer); // WHEN BeanWithArrayListOfString bean = (BeanWithArrayListOfString) n2b.toBean(session.getNode("/parent")); // THEN assertNotNull(bean); assertTrue(bean.getValues() instanceof ArrayList); assertEquals(2, bean.getValues().size()); assertEquals("test", bean.getValues().get(0)); assertEquals("str", bean.getValues().get(1)); } @Test public void testNode2BeanWithTreeSet() throws IOException, RepositoryException, Node2BeanException { // GIVEN Session session = SessionTestUtil.createSession("test", "/parent.class=info.magnolia.jcr.node2bean.BeanWithTreeSetOfString\n" + "/parent/values.val1=test\n" + "/parent/values.val2=str\n" ); Node2BeanProcessorImpl n2b = new Node2BeanProcessorImpl(typeMapping, transformer); // WHEN BeanWithTreeSetOfString bean = (BeanWithTreeSetOfString) n2b.toBean(session.getNode("/parent")); // THEN assertNotNull(bean); assertTrue(bean.getValues() instanceof TreeSet); assertEquals(2, bean.getValues().size()); assertTrue(bean.getValues().contains("test")); assertTrue(bean.getValues().contains("str")); } @Test public void testNodeToBeanWithArray() throws IOException, RepositoryException, Node2BeanException { // GIVEN Session session = SessionTestUtil.createSession("test", "/parent.class=info.magnolia.jcr.node2bean.BeanWithArrayOfSimpleBean\n" + "/parent.integer=1\n" + "/parent.string=Hello\n" + "/parent/beans/sub1.integer=2\n" + "/parent/beans/sub1.string=World\n" + "/parent/beans/sub2.integer=3\n" + "/parent/beans/sub2.string=:)\n" ); Node2BeanProcessorImpl n2b = new Node2BeanProcessorImpl(typeMapping, transformer); BeanWithArrayOfSimpleBean bean = (BeanWithArrayOfSimpleBean) n2b.toBean(session.getNode("/parent")); // WHEN SimpleBean[] beans = bean.getBeans(); // THEN assertNotNull(beans); assertEquals(2, beans.length); assertNotNull(bean.getBeans()[0]); assertNotNull(bean.getBeans()[1]); assertEquals(2, beans[0].getInteger()); assertEquals("World", beans[0].getString()); assertEquals(3, beans[1].getInteger()); assertEquals(":)", beans[1].getString()); } @Test public void testNodeToBeanWithHashMap() throws IOException, RepositoryException, Node2BeanException { // GIVEN Session session = SessionTestUtil.createSession("test", "/parent.class=info.magnolia.jcr.node2bean.BeanWithHashMap\n" + "/parent.integer=1\n" + "/parent.string=Hello\n" + "/parent/beans/sub1.integer=2\n" + "/parent/beans/sub1.string=World\n" + "/parent/beans/sub2.integer=3\n" + "/parent/beans/sub2.string=:)\n" ); Node2BeanProcessorImpl n2b = new Node2BeanProcessorImpl(typeMapping, transformer); // WHEN BeanWithHashMap bean = (BeanWithHashMap) n2b.toBean(session.getNode("/parent")); // THEN assertNotNull(bean.getBeans()); assertEquals(2, bean.getBeans().size()); } @Test public void testNodeToBeanWithCollectionWithAdder() throws IOException, RepositoryException, Node2BeanException { // GIVEN Session session = SessionTestUtil.createSession("test", "/parent.class=info.magnolia.jcr.node2bean.BeanWithCollectionAndAdder\n" + "/parent/messages.val1=Hello\n" + "/parent/messages.val2=World\n" ); Node2BeanProcessorImpl n2b = new Node2BeanProcessorImpl(typeMapping, transformer); // WHEN BeanWithCollectionAndAdder bean = (BeanWithCollectionAndAdder) n2b.toBean(session.getNode("/parent")); // THEN assertNotNull(bean.getMessages()); assertEquals(2, bean.getMessages().size()); Iterator<String> it = bean.getMessages().iterator(); assertEquals("Hello", it.next()); assertEquals("World", it.next()); } @Test public void testNodeToBeanWithMapWithAdder() throws IOException, RepositoryException, Node2BeanException { // GIVEN Session session = SessionTestUtil.createSession("test", "/parent.class=info.magnolia.jcr.node2bean.BeanWithMapAndAdder\n" + "/parent/beans/val1.string=Hello\n" + "/parent/beans/val2.string=World\n" ); Node2BeanProcessorImpl n2b = new Node2BeanProcessorImpl(typeMapping, transformer); // WHEN BeanWithMapAndAdder bean = (BeanWithMapAndAdder) n2b.toBean(session.getNode("/parent")); // THEN assertNotNull(bean.getBeans()); assertEquals(2, bean.getBeans().size()); assertEquals("Hello", bean.getBeans().get("val1").getString()); assertEquals("World", bean.getBeans().get("val2").getString()); } @Test public void testNodeToBeanWithArrayWithAdder() throws IOException, RepositoryException, Node2BeanException { // GIVEN Session session = SessionTestUtil.createSession("test", "/parent.class=info.magnolia.jcr.node2bean.BeanWithArrayAndAdder\n" + "/parent/messages.val1=Hello\n" + "/parent/messages.val2=World\n" ); Node2BeanProcessorImpl n2b = new Node2BeanProcessorImpl(typeMapping, transformer); // WHEN BeanWithArrayAndAdder bean = (BeanWithArrayAndAdder) n2b.toBean(session.getNode("/parent")); // THEN assertNotNull(bean.getMessages()); assertEquals(2, bean.getMessages().length); assertEquals("Hello", bean.getMessages()[0]); assertEquals("World", bean.getMessages()[1]); } @Test public void testClassPropertiesAreConvertedProperly() throws IOException, RepositoryException, Node2BeanException { // GIVEN Session session = SessionTestUtil.createSession("test", "/parent.class=info.magnolia.jcr.node2bean.BeanWithClass\n" + "/parent.foo=blah\n" + "/parent.clazz=java.lang.String\n" ); Node2BeanProcessorImpl n2b = new Node2BeanProcessorImpl(typeMapping, transformer); // WHEN BeanWithClass o = (BeanWithClass) n2b.toBean(session.getNode("/parent")); // THEN assertEquals("blah", o.getFoo()); assertEquals(String.class, o.getClazz()); } @Test public void testJCRPropertiesTypes() throws IOException, RepositoryException, Node2BeanException { // GIVEN Session session = SessionTestUtil.createSession("test", "/parent.class=info.magnolia.jcr.node2bean.BeanWithPrimitiveProperties\n" + "/parent.integer=5\n" + "/parent.bool=true\n" ); Node2BeanProcessorImpl n2b = new Node2BeanProcessorImpl(typeMapping, transformer); // WHEN BeanWithPrimitiveProperties bean = (BeanWithPrimitiveProperties) n2b.toBean(session.getNode("/parent")); // THEN assertEquals(5, bean.getInteger()); assertEquals(true, bean.isBool()); } @Test public void testFlatteningSubNodesToSimpleList() throws RepositoryException, IOException, Node2BeanException { // GIVEN Session session = SessionTestUtil.createSession("test", "/parent.class=info.magnolia.jcr.node2bean.BeanWithListOfString\n" + "/parent/values/sub1.value=one\n" + "/parent/values/sub2.value=two" ); Node2BeanProcessorImpl n2b = new Node2BeanProcessorImpl(typeMapping, transformer); // WHEN BeanWithListOfString bean = (BeanWithListOfString) n2b.toBean(session.getNode("/parent")); // THEN assertEquals("one", bean.getValues().get(0)); assertEquals("two", bean.getValues().get(1)); } @Test public void testCanConvertStringsToTheAppropriateEnumEquivalent() throws IOException, RepositoryException, Node2BeanException { // GIVEN Session session = SessionTestUtil.createSession("test", "/parent.class=info.magnolia.jcr.node2bean.BeanWithEnum\n" + "/parent.value=Hello\n" + "/parent.sample=two\n" ); Node2BeanProcessorImpl n2b = new Node2BeanProcessorImpl(typeMapping, transformer); // WHEN BeanWithEnum bean = (BeanWithEnum) n2b.toBean(session.getNode("/parent")); // THEN assertNotNull(bean); assertTrue(bean.getSample().getClass().isEnum()); assertEquals("Hello", bean.getValue()); assertEquals(SampleEnum.two, bean.getSample()); } @Test public void testCanSpecifySpecificMapImplementation() throws Exception { // GIVEN Session session = SessionTestUtil.createSession("test", "/foo/bar.class=" + BeanWithMapWithGenerics.class.getName(), "/foo/bar/beans.class=" + MyMap.class.getName(), "/foo/bar/beans/a.class=" + SimpleBean.class.getName(), "/foo/bar/beans/a.string=Hello", "/foo/bar/beans/b.class=" + SimpleBean.class.getName(), "/foo/bar/beans/b.string=World"); final Node2BeanProcessorImpl n2b = new Node2BeanProcessorImpl(typeMapping, transformer); final BeanWithMapWithGenerics bean = (BeanWithMapWithGenerics) n2b.toBean(session.getNode("/foo/bar")); // WHEN final Map<String, SimpleBean> map = bean.getBeans(); // THEN assertNotNull(map); assertEquals(2, map.size()); assertEquals("Hello", map.get("a").getString()); assertEquals("World", map.get("b").getString()); assertTrue("we wanted a custom map impl!", map instanceof MyMap); } @Test public void testPopulateBeanPropertyIfNoGenericsUsedInSetter() throws IOException, RepositoryException, Node2BeanException { // GIVEN Session session = SessionTestUtil.createSession("test", "/foo/bar.class=info.magnolia.jcr.node2bean.Node2BeanTest$StupidBean\n" + "/foo/bar/messages/1.string=Hello\n" + "/foo/bar/messages/2.string=World\n" ); final Node2BeanProcessorImpl n2b = new Node2BeanProcessorImpl(typeMapping, transformer); // WHEN StupidBean bean = (StupidBean) n2b.toBean(session.getNode("/foo/bar")); assertNotNull(bean.getMessages()); assertEquals(2, bean.getMessages().size()); assertEquals("Hello", ((SimpleBean) bean.getMessages().get(0)).getString()); assertEquals("World", ((SimpleBean) bean.getMessages().get(1)).getString()); } @Test public void testWillFailToUseACustomMapWhichIsNotConcrete() throws Exception { // DUH ! // GIVEN Session session = SessionTestUtil.createSession("/test", "/bar.class=" + BeanWithMapWithGenerics.class.getName(), "/bar/beans.class=" + StupidMap.class.getName(), "/bar/beans/a.class=" + SimpleBean.class.getName(), "/bar/beans/a.string=hello", "/bar/beans/b.class=" + SimpleBean.class.getName(), "/bar/beans/b.string=world" ); final Node2BeanProcessorImpl n2b = new Node2BeanProcessorImpl(typeMapping, transformer); n2b.setForceCreation(false); try { // WHEN n2b.toBean(session.getNode("/bar")); fail("should have failed"); } catch (Node2BeanException t) { // THEN assertEquals("Can't instantiate bean for /bar/beans", t.getMessage()); final String causeMsg = t.getCause().getMessage(); assertTrue(causeMsg.contains("StupidMap")); assertTrue(causeMsg.contains("No concrete implementation defined")); } } @Test public void testBeanExtendsAnotherBean() throws IOException, RepositoryException, Node2BeanException { // GIVEN Session session = SessionTestUtil.createSession("test", "/parent.class=info.magnolia.jcr.node2bean.SimpleBean\n" + "/parent.string=Hello\n" + "/parent.integer=10\n" + "/sub/bean.class=info.magnolia.jcr.node2bean.OtherSimpleBean\n" + "/sub/bean.string=World\n" + "/sub/bean.value=foo\n" + "/sub/bean.extends=../../parent\n" ); final Node2BeanProcessorImpl n2b = new Node2BeanProcessorImpl(typeMapping, transformer); // WHEN OtherSimpleBean bean = (OtherSimpleBean) n2b.toBean(session.getNode("/sub/bean")); // THEN assertNotNull(bean); assertEquals("World", bean.getString()); // overwritten assertEquals(10, bean.getInteger()); // inherited assertEquals("foo", bean.getValue()); // new } @Test public void testBeanExtendsAnotherBean2() throws IOException, RepositoryException, Node2BeanException { // GIVEN Session session = SessionTestUtil.createSession("test", "/parent.class=info.magnolia.jcr.node2bean.BeanWithMapWithGenerics\n" + "/parent.string=Hello\n" + "/parent.integer=10\n" + "/parent/beans/sub1.string=foo\n" + "/parent/beans/sub2.string=bar\n" + "/parent/beans/sub3.string=baz\n" + "/sub/bean.class=info.magnolia.jcr.node2bean.BeanWithMapWithGenerics\n" + "/sub/bean.string=World\n" + "/sub/bean.integer=999\n" + "/sub/bean.extends=/parent\n" + "/another/sub/bean.class=info.magnolia.jcr.node2bean.BeanWithMapWithGenerics\n" + "/another/sub/bean.extends=../../../sub/bean\n" + "/another/sub/bean/beans/sub3.string=bla\n" + "/another/sub/bean/beans/sub4.string=blah\n" ); final Node2BeanProcessorImpl n2b = new Node2BeanProcessorImpl(typeMapping, transformer); // WHEN BeanWithMapWithGenerics bean = (BeanWithMapWithGenerics) n2b.toBean(session.getNode("/another/sub/bean")); // THEN assertNotNull(bean); assertEquals(999, bean.getInteger()); assertEquals("World", bean.getString()); assertEquals(4, bean.getBeans().size()); assertEquals("foo", bean.getBeans().get("sub1").getString()); assertEquals("bar", bean.getBeans().get("sub2").getString()); assertEquals("bla", bean.getBeans().get("sub3").getString()); assertEquals("blah", bean.getBeans().get("sub4").getString()); } @Test @Ignore("jsimak: MAGNOLIA-4685") public void testBeansWithEnabledPropertySetToFalseAreExcludedFromCollection() throws IOException, RepositoryException, Node2BeanException { // GIVEN Session session = SessionTestUtil.createSession("test", "/parent.class=info.magnolia.jcr.node2bean.BeanWithCollectionOfSimpleBean\n" + "/parent/beans/sub1.string=Hello\n" + "/parent/beans/sub2.string=World\n" + "/parent/beans/sub2.enabled=false\n" ); final Node2BeanProcessorImpl n2b = new Node2BeanProcessorImpl(typeMapping, transformer); // WHEN BeanWithCollectionOfSimpleBean bean = (BeanWithCollectionOfSimpleBean) n2b.toBean(session.getNode("/parent")); // THEN assertNotNull(bean); assertEquals(1, bean.getBeans().size()); // WHEN SimpleBean simple = Iterables.get(bean.getBeans(), 0); // THEN assertEquals(true, simple.isEnabled()); assertEquals("Hello", simple.getString()); } @Test @Ignore("jsimak: MAGNOLIA-4685") public void testBeansWithEnabledPropertySetToFalseAreExcludedFromMap() throws IOException, RepositoryException, Node2BeanException { // GIVEN Session session = SessionTestUtil.createSession("test", "/parent.class=info.magnolia.jcr.node2bean.BeanWithMapWithGenerics\n" + "/parent.string=Hello\n" + "/parent.integer=10\n" + "/parent/beans/sub1.string=foo\n" + "/parent/beans/sub1.enabled=false\n" + "/parent/beans/sub2.string=bar\n" + "/parent/beans/sub3.string=baz\n" + "/sub/bean.class=info.magnolia.jcr.node2bean.BeanWithMapWithGenerics\n" + "/sub/bean.string=World\n" + "/sub/bean.integer=999\n" + "/sub/bean.extends=/parent\n" + "/sub/bean.enabled=false\n" + "/another/sub/bean.class=info.magnolia.jcr.node2bean.BeanWithMapWithGenerics\n" + "/another/sub/bean.extends=../../../sub/bean\n" + "/another/sub/bean/beans/sub3.string=bla\n" + "/another/sub/bean/beans/sub4.string=blah\n" + "/another/sub/bean/beans/sub4.enabled=false\n" ); final Node2BeanProcessorImpl n2b = new Node2BeanProcessorImpl(typeMapping, transformer); // WHEN BeanWithMapWithGenerics bean = (BeanWithMapWithGenerics) n2b.toBean(session.getNode("/another/sub/bean")); // THEN assertNotNull(bean); assertEquals(999, bean.getInteger()); assertEquals("World", bean.getString()); assertEquals(2, bean.getBeans().size()); assertEquals("bar", bean.getBeans().get("sub2").getString()); assertEquals("bla", bean.getBeans().get("sub3").getString()); } @Test public void testCollectionPropertyIsHidden() throws IOException, RepositoryException, Node2BeanException { // GIVEN Session session = SessionTestUtil.createSession("test", "/parent.class=info.magnolia.jcr.node2bean.BeanWithCollectionOfSimpleBean\n" + "/parent/beans/sub1.string=ahoj\n" + "/parent/beans/sub2.string=hello\n" ); final Node2BeanProcessorImpl n2b = new Node2BeanProcessorImpl(typeMapping, transformer); // WHEN final BeanWithCollectionOfSimpleBean bean = (BeanWithCollectionOfSimpleBean) n2b.toBean( session.getNode("/parent"), true, new CollectionPropertyHidingTransformer(BeanWithCollectionOfSimpleBean.class, "beans"), Components.getComponentProvider() ); // THEN assertEquals(0, bean.getBeans().size()); } @Test public void testNodeToBeanWithClassDefined2() throws RepositoryException, Node2BeanException, IOException { // GIVEN Session session = SessionTestUtil.createSession("test", "/parent.class=info.magnolia.jcr.node2bean.OtherSimpleBean\n" + "/parent.string=hello\n" ); Node2BeanProcessorImpl n2b = new Node2BeanProcessorImpl(typeMapping, transformer); // WHEN OtherSimpleBean bean = (OtherSimpleBean) n2b.toBean(session.getNode("/parent"), false, new ProxyingNode2BeanTransformer(), Components.getComponentProvider()); // THEN assertTrue(bean instanceof SimpleBean); assertEquals("proxied: hello", bean.getString()); } @Test public void testCanSpecifySpecificCollectionImplementation() throws Exception { // GIVEN Session session = SessionTestUtil.createSession("test", "/parent.class=info.magnolia.jcr.node2bean.BeanWithCollectionOfSimpleBean\n" + "/parent/beans.class=java.util.Vector\n" + "/parent/beans/a.class=info.magnolia.jcr.node2bean.SimpleBean\n" + "/parent/beans/a.string=hello\n" + "/parent/beans/b.class=info.magnolia.jcr.node2bean.SimpleBean\n" + "/parent/beans/b.string=world\n" ); Node2BeanProcessorImpl n2b = new Node2BeanProcessorImpl(typeMapping, transformer); final BeanWithCollectionOfSimpleBean bean = (BeanWithCollectionOfSimpleBean) n2b.toBean(session.getNode("/parent")); // WHEN final Collection<SimpleBean> coll = bean.getBeans(); // THEN assertNotNull(coll); assertEquals(2, coll.size()); final Iterator it = coll.iterator(); final SimpleBean a = (SimpleBean) it.next(); final SimpleBean b = (SimpleBean) it.next(); assertNotSame(a, b); assertFalse(a.getString().equals(b.getString())); assertTrue("hello".equals(a.getString()) || "hello".equals(b.getString())); assertTrue("world".equals(a.getString()) || "world".equals(b.getString())); assertTrue("we wanted a custom collection impl!", coll instanceof Vector); } @Test public void testMessageFormatIsConvertedAutomagically() throws Exception { // GIVEN Session session = SessionTestUtil.createSession("test", "/parent.class=info.magnolia.jcr.node2bean.BeanWithMessageFormat\n" + "/parent.myFormat=plop {0} plop {1} plop\n" ); Node2BeanProcessorImpl n2b = new Node2BeanProcessorImpl(typeMapping, transformer); // WHEN final BeanWithMessageFormat res = (BeanWithMessageFormat) n2b.toBean(session.getNode("parent")); // THEN assertNotNull(res); assertNotNull(res.getMyFormat()); assertTrue(res.getMyFormat() instanceof MessageFormat); assertEquals("plop hey plop ho plop", res.formatIt("hey", "ho")); } @Test public void testRegexPatternIsConvertedAutomagically() throws Exception { // GIVEN Session session = SessionTestUtil.createSession("test", "/parent.class=info.magnolia.jcr.node2bean.BeanWithRegexPattern\n" + "/parent.myPattern=a*b\n" ); Node2BeanProcessorImpl n2b = new Node2BeanProcessorImpl(typeMapping, transformer); // WHEN final BeanWithRegexPattern res = (BeanWithRegexPattern) n2b.toBean(session.getNode("parent")); // THEN assertNotNull(res); assertNotNull(res.getMyPattern()); assertTrue(res.getMyPattern() instanceof Pattern); assertTrue(res.matches("aaaaab")); assertFalse(res.matches("baaaaa")); } @Test public void testBeanWillUseTransformerFromAnnotatedSetter() throws Exception { // GIVEN Session session = SessionTestUtil.createSession("test", "/listener.class=info.magnolia.jcr.node2bean.Node2BeanTest$BeanWithAnnotation\n" + "/listener/command/version.class=info.magnolia.test.TestCommand\n" + "/listener/command/alert.class=info.magnolia.test.TestCommand\n" ); Node2BeanProcessorImpl n2b = new Node2BeanProcessorImpl(typeMapping, transformer); // WHEN BeanWithAnnotation bean = (BeanWithAnnotation) n2b.toBean(session.getNode("/listener")); // THEN assertTrue(bean.getCommand() instanceof MyChain); assertEquals(2, ((MyChain) bean.getCommand()).getCommands().length); } @Test public void testWillNotAddIncorrectTypesToMap() throws RepositoryException, IOException, Node2BeanException { // GIVEN final Session session = SessionTestUtil.createSession("/foo", "/foo.class=" + BeanWithMapWithGenerics.class.getName(), "/foo/beans.untitled=", "/foo/beans/a.prop1=test" ); Node2BeanProcessorImpl n2b = new Node2BeanProcessorImpl(typeMapping, transformer); // WHEN final BeanWithMapWithGenerics bean = (BeanWithMapWithGenerics) n2b.toBean(session.getNode("/foo")); // THEN assertEquals(1, bean.getBeans().size()); assertTrue(bean.getBeans().get("a") instanceof SimpleBean); } @Test public void testWillNodAddIncorrectTypesToCollection() throws RepositoryException, IOException, Node2BeanException { // GIVEN final Session session = SessionTestUtil.createSession("/foo", "/foo.class=" + BeanWithCollectionOfSimpleBean.class.getName(), "/foo/beans.untitled=", "/foo/beans/a.message=test" ); Node2BeanProcessorImpl n2b = new Node2BeanProcessorImpl(typeMapping, transformer); // WHEN final BeanWithCollectionOfSimpleBean bean = (BeanWithCollectionOfSimpleBean) n2b.toBean(session.getNode("/foo")); // THEN assertEquals(1, bean.getBeans().size()); assertTrue(bean.getBeans().iterator().next() instanceof SimpleBean); } private class ProxyingNode2BeanTransformer extends Node2BeanTransformerImpl { @Override public void initBean(TransformationState state, Map properties) throws Node2BeanException { super.initBean(state, properties); Object bean = state.getCurrentBean(); if (bean instanceof SimpleBean) { state.setCurrentBean(new ProxyingSimpleBean((SimpleBean) bean)); } } } private class ProxyingSimpleBean extends OtherSimpleBean { private final SimpleBean target; public ProxyingSimpleBean(SimpleBean target) { this.target = target; } @Override public String getString() { return "proxied: " + target.getString(); } } public static class MyMap extends HashMap { } public abstract static class StupidMap extends AbstractMap { } public final class StupidBean { private List messages = new ArrayList(); public void addMessage(SimpleBean str) { this.messages.add(str); } public void setMessages(List messages) { this.messages = messages; } public List getMessages() { return this.messages; } } public class BeanWithAnnotation { private Command command; @TransformedBy(SomeCommandTransformer.class) public void setCommand(Command command) { this.command = command; } public Command getCommand() { return command; } } public static class MyChain extends ChainBase { public Command[] getCommands() { return commands; } } }