/* * JBoss, Home of Professional Open Source. * Copyright 2011, Red Hat, Inc., and individual contributors * as indicated by the @author tags. See the copyright.txt file in the * distribution for a full listing of individual contributors. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package org.exoplatform.portal.mop.management.binding.xml; import static org.junit.Assert.assertArrayEquals; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import org.exoplatform.portal.config.model.Application; import org.exoplatform.portal.config.model.ApplicationState; import org.exoplatform.portal.config.model.ApplicationType; import org.exoplatform.portal.config.model.Container; import org.exoplatform.portal.config.model.DevicePropertyCondition; import org.exoplatform.portal.config.model.ModelObject; import org.exoplatform.portal.config.model.NodeMap; import org.exoplatform.portal.config.model.PageBody; import org.exoplatform.portal.config.model.PortalConfig; import org.exoplatform.portal.config.model.PortalRedirect; import org.exoplatform.portal.config.model.RedirectCondition; import org.exoplatform.portal.config.model.RedirectMappings; import org.exoplatform.portal.config.model.TransientApplicationState; import org.exoplatform.portal.config.model.UserAgentConditions; import org.exoplatform.portal.pom.config.Utils; import org.exoplatform.portal.pom.data.ApplicationData; import org.exoplatform.portal.pom.data.BodyData; import org.exoplatform.portal.pom.data.BodyType; import org.exoplatform.portal.pom.data.ComponentData; import org.exoplatform.portal.pom.data.ContainerData; import org.exoplatform.portal.pom.data.PortalData; import org.exoplatform.portal.pom.spi.portlet.Portlet; import org.exoplatform.portal.pom.spi.portlet.Preference; /** * @author <a href="mailto:nscavell@redhat.com">Nick Scavelli</a> * @version $Revision$ */ public class SiteLayoutMarshallerTest extends AbstractMarshallerTest { public void testPortalDataUnmarshalling() { SiteLayoutMarshaller marshaller = new SiteLayoutMarshaller(); PortalConfig data = marshaller.unmarshal(getClass().getResourceAsStream( "/org/exoplatform/portal/mop/management/portal.xml")); assertNotNull(data); assertEquals("classic", data.getName()); assertEquals("site-label", data.getLabel()); assertEquals("site-description", data.getDescription()); assertEquals("en", data.getLocale()); assertEquals("Everyone", Utils.join(";", data.getAccessPermissions())); assertEquals("*:/platform/administrators", data.getEditPermission()); assertNotNull(data.getProperties()); assertEquals(1, data.getProperties().size()); assertTrue(data.getProperties().containsKey("sessionAlive")); assertEquals("onDemand", data.getProperties().get("sessionAlive")); // Verify portal layout container only has children assertNotNull(data.getPortalLayout()); Container layout = data.getPortalLayout(); assertNull(layout.getStorageId()); assertNull(layout.getId()); assertNull(layout.getName()); assertNull(layout.getIcon()); assertNull(layout.getTemplate()); assertNull(layout.getFactoryId()); assertNull(layout.getTitle()); assertNull(layout.getDescription()); assertNull(layout.getWidth()); assertNull(layout.getHeight()); assertNull(layout.getAccessPermissions()); assertArrayEquals(new String[] {"*:/platform/app-movers"}, layout.getMoveAppsPermissions()); assertArrayEquals(new String[] {"*:/platform/container-movers"}, layout.getMoveContainersPermissions()); List<ModelObject> children = data.getPortalLayout().getChildren(); assertEquals(5, children.size()); // Verify banner portlet app { @SuppressWarnings("unchecked") Application<Portlet> application = (Application<Portlet>) children.get(0); assertTrue(application.getType() == ApplicationType.PORTLET); ApplicationState<Portlet> state = application.getState(); assertNotNull(state); assertTrue(state instanceof TransientApplicationState); TransientApplicationState<Portlet> tas = (TransientApplicationState<Portlet>) state; assertEquals("web/BannerPortlet", tas.getContentId()); Portlet portlet = tas.getContentState(); int count = 0; for (Iterator<Preference> it = portlet.iterator(); it.hasNext(); it.next()) { count++; } assertEquals(1, count); Preference pref = portlet.getPreference("template"); assertNotNull(pref); assertEquals("template", pref.getName()); assertEquals("par:/groovy/groovy/webui/component/UIBannerPortlet.gtmpl", pref.getValue()); assertFalse(pref.isReadOnly()); assertEquals("Default:DefaultTheme::Mac:MacTheme::Vista:VistaTheme", application.getTheme()); assertEquals("Banner", application.getTitle()); assertEquals("*:/platform/administrators;*:/organization/management/executive-board", Utils.join(";", application.getAccessPermissions())); assertFalse(application.getShowInfoBar()); assertTrue(application.getShowApplicationState()); assertFalse(application.getShowApplicationMode()); assertEquals("Banner Portlet", application.getDescription()); assertEquals("PortletIcon", application.getIcon()); assertEquals("250px", application.getWidth()); assertEquals("350px", application.getHeight()); } // Verify navigation portlet app { @SuppressWarnings("unchecked") Application<Portlet> application = (Application<Portlet>) children.get(1); assertTrue(application.getType() == ApplicationType.PORTLET); ApplicationState<Portlet> state = application.getState(); assertNotNull(state); assertTrue(state instanceof TransientApplicationState); TransientApplicationState<Portlet> tas = (TransientApplicationState<Portlet>) state; assertEquals("web/NavigationPortlet", tas.getContentId()); assertNull(tas.getContentState()); assertNull(application.getTheme()); assertNull(application.getTitle()); assertEquals("Everyone", Utils.join(";", application.getAccessPermissions())); assertFalse(application.getShowInfoBar()); assertTrue(application.getShowApplicationState()); assertTrue(application.getShowApplicationMode()); assertNull(application.getDescription()); assertNull(application.getIcon()); assertNull(application.getWidth()); assertNull(application.getHeight()); } } public void testPortalDataMarshalling() { ByteArrayOutputStream baos = new ByteArrayOutputStream(); Portlet portlet = new Portlet(); portlet.putPreference(new Preference("pref-1", "value-1", true)); portlet.putPreference(new Preference("pref-2", "value-2", false)); portlet.putPreference(new Preference("multi-value-pref", Arrays.asList("one", "two", "three"), false)); portlet.putPreference(new Preference("no-value-pref", (String) null, true)); ApplicationState<Portlet> state = new TransientApplicationState<Portlet>("app-ref/portlet-ref", portlet); ApplicationData<Portlet> application = new ApplicationData<Portlet>(null, null, ApplicationType.PORTLET, state, null, "app-title", "app-icon", "app-description", false, true, false, "app-theme", "app-wdith", "app-height", new HashMap<String, String>(), Collections.singletonList("app-edit-permissions")); List<ComponentData> children = new ArrayList<ComponentData>(); children.add(application); children.add(new BodyData(null, BodyType.PAGE)); ContainerData layout = new ContainerData(null, null, "container-name", "container-icon", "container-template", "factoryId", "title", "description", "width", "height", Collections.singletonList("accessPermissions"), Collections.singletonList("moveAppsPermissions"), Collections.singletonList("moveContainersPermissions"), children); Map<String, String> properties = new HashMap<String, String>(); properties.put("key1", "value1"); properties.put("key2", "value2"); PortalData expectedData = new PortalData(null, "name", "type", "locale", "label", "description", Collections.singletonList("access-permissions"), "edit-permissions", properties, "skin", layout, null); PortalConfig expected = new PortalConfig(expectedData); Container expectedLayout = expected.getPortalLayout(); SiteLayoutMarshaller marshaller = new SiteLayoutMarshaller(); marshaller.marshal(expected, baos, false); // System.out.println(baos.toString()); PortalConfig actual = marshaller.unmarshal(new ByteArrayInputStream(baos.toByteArray())); assertNotNull(actual); assertNull(actual.getStorageId()); assertNull(actual.getStorageName()); assertEquals("name", actual.getName()); assertEquals("label", actual.getLabel()); assertEquals("description", actual.getDescription()); assertEquals("portal", actual.getType()); assertEquals("locale", actual.getLocale()); assertEquals("access-permissions", Utils.join(";", actual.getAccessPermissions())); assertEquals("edit-permissions", actual.getEditPermission()); assertEquals(properties, actual.getProperties()); assertEquals("skin", actual.getSkin()); Container actualLayout = actual.getPortalLayout(); assertNotNull(actualLayout); assertArrayEquals(expectedLayout.getMoveAppsPermissions(), actualLayout.getMoveAppsPermissions()); assertArrayEquals(expectedLayout.getMoveContainersPermissions(), actualLayout.getMoveContainersPermissions()); assertNotNull(actual.getPortalLayout().getChildren()); assertEquals(2, actual.getPortalLayout().getChildren().size()); compareComponents(expected.getPortalLayout().getChildren(), actual.getPortalLayout().getChildren()); } public void testPortalWithPageBodyInContainer() { SiteLayoutMarshaller marshaller = new SiteLayoutMarshaller(); PortalConfig data = marshaller.unmarshal(getClass().getResourceAsStream( "/org/exoplatform/portal/mop/management/portal-pagebody.xml")); assertNotNull(data); assertEquals("classic", data.getName()); assertEquals("site-label", data.getLabel()); assertEquals("site-description", data.getDescription()); assertEquals("en", data.getLocale()); assertEquals("Everyone", Utils.join(";", data.getAccessPermissions())); assertEquals("*:/platform/administrators", data.getEditPermission()); assertNotNull(data.getProperties()); assertEquals(1, data.getProperties().size()); assertTrue(data.getProperties().containsKey("sessionAlive")); assertEquals("onDemand", data.getProperties().get("sessionAlive")); // Verify portal layout container only has children assertNotNull(data.getPortalLayout()); Container layout = data.getPortalLayout(); assertNull(layout.getStorageId()); assertNull(layout.getId()); assertNull(layout.getName()); assertNull(layout.getIcon()); assertNull(layout.getTemplate()); assertNull(layout.getFactoryId()); assertNull(layout.getTitle()); assertNull(layout.getDescription()); assertNull(layout.getWidth()); assertNull(layout.getHeight()); assertNull(layout.getAccessPermissions()); List<ModelObject> children = data.getPortalLayout().getChildren(); assertEquals(5, children.size()); // Verify container w/ page-body Container container = (Container) layout.getChildren().get(3); assertArrayEquals(new String[] {"*:/platform/app-movers"}, container.getMoveAppsPermissions()); assertArrayEquals(new String[] {"*:/platform/container-movers"}, container.getMoveContainersPermissions()); assertNotNull(container.getChildren()); assertEquals(2, container.getChildren().size()); Container container0 = (Container) container.getChildren().get(0); PageBody body = (PageBody) container0 .getChildren().get(0); assertNotNull(body); } public void testPortalWithRedirect() { SiteLayoutMarshaller marshaller = new SiteLayoutMarshaller(); PortalConfig data = marshaller.unmarshal(getClass().getResourceAsStream( "/org/exoplatform/portal/mop/management/portal-redirects.xml")); // Create the objects that match what should be parsed from xml List<PortalRedirect> redirects = new ArrayList<PortalRedirect>(2); PortalRedirect redirect = new PortalRedirect(); redirect.setRedirectSite("redirectA"); redirect.setName("Redirect Site A"); redirect.setEnabled(true); // condition 0 redirect.getConditions().add(new ConditionBuilder("condition 0") .userAgent().contains(".*").build() .deviceProperty("foo").equals("bar").build() .deviceProperty("hello").matches("(?i)world").build() .deviceProperty("number").greaterThan(10.0f).lessThan(25.0f).build() .build()); // condition 1 redirect.getConditions().add(new ConditionBuilder("condition 1") .userAgent().contains("(?i)foo").doesNotContain("bar").build() .build()); // condition 2 redirect.getConditions().add(new ConditionBuilder("condition 2") .userAgent().contains("(?i)abc", "(?i)def").doesNotContain("world").build() .build()); // condition 3 redirect.getConditions().add(new ConditionBuilder("condition 3") .userAgent().contains("(?i)abc").doesNotContain("hello", "world").build() .build()); // condition 4 redirect.getConditions().add(new ConditionBuilder("condition 4") .userAgent().contains("(?i)abc", "(?i)def").doesNotContain("hello", "world").build() .build()); // condition 5 redirect.getConditions().add(new ConditionBuilder("condition 5") .userAgent().contains("(?i)abc", "(?i)def").build() .build()); // condition 6 redirect.getConditions().add(new ConditionBuilder("condition 6") .userAgent().doesNotContain("hello", "world").build() .build()); // node mappings redirect.setMappings(new RedirectMappingsBuilder().nameMatching(false).unresolved(RedirectMappings.UnknownNodeMapping.COMMON_ANCESTOR_NAME_MATCH) .map("foo", "bar") .map("hello/world", "redirect/hello/world") .map("/", "redirect_root") .map("root", "/") .map("ABC/123/XYZ", "123") .map("/with_slash", "/with_slash") .map("/with_slash_two", "without_slash") .map("without_slash", "/with_slash_two") .build()); // add redirects.add(redirect); // redirect 2 redirect = new PortalRedirect(); redirect.setRedirectSite("redirectB"); redirect.setName("Redirect Site B"); redirect.setEnabled(false); // add redirects.add(redirect); assertEquals(redirects, data.getPortalRedirects(), "redirects", PortalRedirect.class); } public void testPortalRedirectMarshalling() { SiteLayoutMarshaller marshaller = new SiteLayoutMarshaller(); PortalConfig expected = marshaller.unmarshal(getClass().getResourceAsStream( "/org/exoplatform/portal/mop/management/portal-redirects.xml")); ByteArrayOutputStream baos = new ByteArrayOutputStream(); marshaller.marshal(expected, baos, false); PortalConfig actual = marshaller.unmarshal(new ByteArrayInputStream(baos.toByteArray())); assertEquals(expected.getPortalRedirects(), actual.getPortalRedirects(), "redirects", PortalRedirect.class); } private static void assertEquals(PortalRedirect expected, PortalRedirect actual) { if (expected == null) { assertNull("Actual redirect was NOT null.", actual); return; } else { assertNotNull("Actual redirect was null.", actual); } assertEquals(expected.getRedirectSite(), actual.getRedirectSite()); assertEquals(expected.getName(), actual.getName()); assertEquals(expected.isEnabled(), actual.isEnabled()); assertEquals(expected.getConditions(), actual.getConditions(), "conditions", RedirectCondition.class); assertEquals(expected.getMappings(), actual.getMappings()); } private static void assertEquals(RedirectCondition expected, RedirectCondition actual) { if (expected == null) { assertNull("Actual condition was NOT null.", actual); return; } else { assertNotNull("Actual condition was null.", actual); } assertEquals(expected.getName(), actual.getName()); assertEquals(expected.getUserAgentConditions(), actual.getUserAgentConditions()); assertEquals(expected.getDeviceProperties(), actual.getDeviceProperties(), "device properties", DevicePropertyCondition.class); } private static void assertEquals(UserAgentConditions expected, UserAgentConditions actual) { if (expected == null) { assertNull("Actual user agent conditions was NOT null.", actual); return; } else { assertNotNull("Actual user agent conditions was null.", actual); } assertEquals(expected.getContains(), actual.getContains()); assertEquals(expected.getDoesNotContain(), actual.getDoesNotContain()); } private static void assertEquals(DevicePropertyCondition expected, DevicePropertyCondition actual) { if (expected == null) { assertNull("Actual device property condition was NOT null.", actual); return; } else { assertNotNull("Actual device property condition was null.", actual); } assertEquals(expected.getPropertyName(), actual.getPropertyName()); assertEquals(expected.getGreaterThan(), actual.getGreaterThan()); assertEquals(expected.getLessThan(), actual.getLessThan()); assertEquals(expected.getEquals(), actual.getEquals()); assertEquals(expected.getMatches(), actual.getMatches()); } private static void assertEquals(RedirectMappings expected, RedirectMappings actual) { if (expected == null) { assertNull("Actual mappings was NOT null.", actual); return; } else { assertNotNull("Actual mappings was null.", actual); } assertEquals(expected.isUseNodeNameMatching(), actual.isUseNodeNameMatching()); assertEquals(expected.getUnresolvedNode(), actual.getUnresolvedNode()); assertEquals(expected.getMappings(), actual.getMappings(), "mappings", NodeMap.class); } private static void assertEquals(NodeMap expected, NodeMap actual) { if (expected == null) { assertNull("Actual node map was NOT null.", actual); return; } else { assertNotNull("Actual node map was null.", actual); } assertEquals(expected.getOriginNode(), actual.getOriginNode()); assertEquals(expected.getRedirectNode(), actual.getRedirectNode()); } // Would be nice if the actual objects properly supported equals... private static <T> void assertEquals(List<T> expected, List<T> actual, String elements, Class<T> clazz) { if (expected == null) { assertNull("Actual " + elements + " was NOT null.", actual); return; } else { assertNotNull("Actual " + elements + " was null.", actual); assertEquals("Number of " + elements + ".", expected.size(), actual.size()); } for (int i=0; i<expected.size(); i++) { if (clazz == PortalRedirect.class) { assertEquals((PortalRedirect) expected.get(i), (PortalRedirect) actual.get(i)); } else if (clazz == RedirectCondition.class) { assertEquals((RedirectCondition) expected.get(i), (RedirectCondition) actual.get(i)); } else if (clazz == DevicePropertyCondition.class) { assertEquals((DevicePropertyCondition) expected.get(i), (DevicePropertyCondition) actual.get(i)); } else if (clazz == NodeMap.class) { assertEquals((NodeMap) expected.get(i), (NodeMap) actual.get(i)); } } } private static class ConditionBuilder { private String name; private UserAgentConditions userAgentConditions; private ArrayList<DevicePropertyCondition> devicePropertyConditions; public ConditionBuilder(String name) { this.name = name; } public UserAgentConditionsBuilder userAgent() { return new UserAgentConditionsBuilder(this); } public DevicePropertyConditionBuilder deviceProperty(String propertyName) { if (devicePropertyConditions == null) { devicePropertyConditions = new ArrayList<DevicePropertyCondition>(); } return new DevicePropertyConditionBuilder(propertyName, this); } public RedirectCondition build() { RedirectCondition condition = new RedirectCondition(); condition.setName(name); condition.setUserAgentConditions(userAgentConditions); condition.setDeviceProperties(devicePropertyConditions); return condition; } } private static class UserAgentConditionsBuilder { private final ConditionBuilder conditionBuilder; private String[] contains; private String[] doesNotContain; private UserAgentConditionsBuilder(ConditionBuilder conditionBuilder) { this.conditionBuilder = conditionBuilder; } public UserAgentConditionsBuilder contains(String...contains) { this.contains = contains; return this; } public UserAgentConditionsBuilder doesNotContain(String...doesNotContain) { this.doesNotContain = doesNotContain; return this; } public ConditionBuilder build() { UserAgentConditions uac = new UserAgentConditions(); if (contains != null) { uac.setContains(new ArrayList<String>(Arrays.asList(contains))); } if (doesNotContain != null) { uac.setDoesNotContain(new ArrayList<String>(Arrays.asList(doesNotContain))); } conditionBuilder.userAgentConditions = uac; return conditionBuilder; } } private static class DevicePropertyConditionBuilder { private final ConditionBuilder conditionBuilder; private final String propertyName; private Float greaterThan; private Float lessThan; private String equals; private String matches; private DevicePropertyConditionBuilder(String propertyName, ConditionBuilder conditionBuilder) { this.conditionBuilder = conditionBuilder; this.propertyName = propertyName; } public DevicePropertyConditionBuilder greaterThan(Float greaterThan) { this.greaterThan = greaterThan; return this; } public DevicePropertyConditionBuilder lessThan(Float lessThan) { this.lessThan = lessThan; return this; } public DevicePropertyConditionBuilder equals(String equals) { this.equals = equals; return this; } public DevicePropertyConditionBuilder matches(String matches) { this.matches = matches; return this; } public ConditionBuilder build() { DevicePropertyCondition condition = new DevicePropertyCondition(); condition.setPropertyName(propertyName); condition.setGreaterThan(greaterThan); condition.setLessThan(lessThan); condition.setEquals(equals); condition.setMatches(matches); conditionBuilder.devicePropertyConditions.add(condition); return conditionBuilder; } } private static class RedirectMappingsBuilder { private Boolean useNodeNameMatching; private RedirectMappings.UnknownNodeMapping unresolvedNode; private ArrayList<NodeMap> mappings; public RedirectMappingsBuilder nameMatching(boolean matching) { useNodeNameMatching = matching; return this; } public RedirectMappingsBuilder unresolved(RedirectMappings.UnknownNodeMapping unresolvedNode) { this.unresolvedNode = unresolvedNode; return this; } public RedirectMappingsBuilder map(String origin, String redirect) { if (mappings == null) { mappings = new ArrayList<NodeMap>(); } mappings.add(new NodeMap(origin, redirect)); return this; } public RedirectMappings build() { RedirectMappings mapping = new RedirectMappings(); if (useNodeNameMatching != null) { mapping.setUseNodeNameMatching(useNodeNameMatching); } if (unresolvedNode != null) { mapping.setUnresolvedNode(unresolvedNode); } if (mappings != null) { mapping.setMappings(mappings); } return mapping; } } }