Skip to content

Instantly share code, notes, and snippets.

@oanhthai
Last active March 11, 2016 07:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save oanhthai/a649094b62556a436b1c to your computer and use it in GitHub Desktop.
Save oanhthai/a649094b62556a436b1c to your computer and use it in GitHub Desktop.
/**
* This file Copyright (c) 2016 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.ui.form.field.transformer.composite;
import info.magnolia.ui.api.i18n.I18NAuthoringSupport;
import info.magnolia.ui.form.field.definition.CompositeFieldDefinition;
import info.magnolia.ui.form.field.definition.ConfiguredFieldDefinition;
import info.magnolia.ui.form.field.definition.MultiValueFieldDefinition;
import info.magnolia.ui.form.field.definition.SwitchableFieldDefinition;
import info.magnolia.ui.vaadin.integration.jcr.AbstractJcrNodeAdapter;
import info.magnolia.ui.vaadin.integration.jcr.JcrNodeAdapter;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.google.common.collect.Lists;
import com.vaadin.data.Item;
import com.vaadin.data.util.PropertysetItem;
/**
* This delegating {@link info.magnolia.ui.form.field.transformer.Transformer Transformer} is dedicated to the {@link info.magnolia.ui.form.field.SwitchableField SwitchableField};
* it simply delegates property handling to the configured sub-fields.
* <p>
* Therefore, sub-fields use their own transformers to store the field value; e.g. with {@link info.magnolia.ui.form.field.transformer.basic.BasicTransformer} properties are named after their respective {@link info.magnolia.ui.form.field.definition.FieldDefinition#getName()}.
*/
public class ComplexFieldFriendlySwitchableTransformer extends DelegatingCompositeFieldTransformer {
private Map<String, List<AbstractJcrNodeAdapter>> removedChild = new HashMap<>();
private JcrNodeAdapter relatedJcrNodeAdapter = null;
public ComplexFieldFriendlySwitchableTransformer(Item relatedFormItem, ConfiguredFieldDefinition definition, Class<PropertysetItem> type, List<String> fieldsName, I18NAuthoringSupport i18NAuthoringSupport) {
super(relatedFormItem, definition, type, fieldsName, i18NAuthoringSupport);
if (relatedFormItem instanceof JcrNodeAdapter) {
relatedJcrNodeAdapter = (JcrNodeAdapter) relatedFormItem;
}
}
@Override
public void writeToItem(PropertysetItem newValue) {
// If switchable
if (definition instanceof SwitchableFieldDefinition) {
SwitchableFieldDefinition switchDefinition = (SwitchableFieldDefinition) definition;
// Get the selected option value
String currentSelection = String.valueOf(relatedFormItem.getItemProperty(switchDefinition.getName()).getValue());
Collection<String> propertyNames = (Collection<String>) newValue.getItemPropertyIds();
for (String propertyName : propertyNames) {
if (!(propertyName.equals(currentSelection) || propertyName.equals(switchDefinition.getName()))) {
removeAllProperties(propertyName, switchDefinition);
removeAllChild(propertyName, switchDefinition);
} else {
if (newValue.getItemProperty(propertyName) != null) {
unRemoveAllProperties(propertyName, switchDefinition);
unRemoveAllChild(propertyName, switchDefinition);
}
}
}
}
}
private List<String> findAllPropertiesOfSubField(String propertyName, SwitchableFieldDefinition definition) {
List<String> propertyNames = new ArrayList<>();
for (ConfiguredFieldDefinition fieldDefinition : definition.getFields()) {
if (fieldDefinition.getName().equals(propertyName)) {
// Find all properties
propertyNames = getNamesOfSubField(fieldDefinition);
break;
}
}
return propertyNames;
}
private List<String> getNamesOfSubField(ConfiguredFieldDefinition fieldDefinition) {
List<String> namesOfSubField = new ArrayList<>();
if (fieldDefinition instanceof CompositeFieldDefinition) {
List<ConfiguredFieldDefinition> fields = ((CompositeFieldDefinition) fieldDefinition).getFields();
for (ConfiguredFieldDefinition field : fields) {
namesOfSubField.addAll(getNamesOfSubField(field));
}
} else {
namesOfSubField.add(fieldDefinition.getName());
}
return namesOfSubField;
}
private List<AbstractJcrNodeAdapter> getChildOfSubField(ConfiguredFieldDefinition fieldDefinition) {
List<AbstractJcrNodeAdapter> items = new ArrayList<>();
if (fieldDefinition instanceof MultiValueFieldDefinition) {
for (Map.Entry<String, AbstractJcrNodeAdapter> entry : relatedJcrNodeAdapter.getChildren().entrySet()) {
if (entry.getKey().contains(fieldDefinition.getName())) {
items.add(entry.getValue());
}
}
}
return items;
}
private void removeAllProperties(String propertyName, SwitchableFieldDefinition definition) {
List<String> propertyNames = findAllPropertiesOfSubField(propertyName, definition);
for (String proName : propertyNames) {
relatedJcrNodeAdapter.removeItemProperty(proName);
}
}
private void removeAllChild(String propertyName, SwitchableFieldDefinition definition) {
for (ConfiguredFieldDefinition fieldDefinition : definition.getFields()) {
String name = fieldDefinition.getName();
if (name.equals(propertyName)) {
// Find all child
List<AbstractJcrNodeAdapter> getChildOfSubField = getChildOfSubField(fieldDefinition);
for (AbstractJcrNodeAdapter child : getChildOfSubField) {
relatedJcrNodeAdapter.removeChild(child);
// Keep track removed child to map
if (removedChild.containsKey(name)) {
removedChild.get(name).add(child);
} else {
removedChild.put(name, Lists.newArrayList(child));
}
}
}
}
}
private void unRemoveAllProperties(String propertyName, SwitchableFieldDefinition definition) {
List<String> propertyNames = findAllPropertiesOfSubField(propertyName, definition);
for (String proName : propertyNames) {
if (relatedJcrNodeAdapter.getItemProperty(proName) != null) {
relatedJcrNodeAdapter.addItemProperty(proName, relatedJcrNodeAdapter.getItemProperty(proName));
}
}
}
private void unRemoveAllChild(String propertyName, SwitchableFieldDefinition definition) {
for (ConfiguredFieldDefinition fieldDefinition : definition.getFields()) {
String name = fieldDefinition.getName();
if (name.equals(propertyName)) {
// Find all removed child
List<AbstractJcrNodeAdapter> getChildOfSubField = removedChild.containsKey(name) ? removedChild.get(name) : new ArrayList<AbstractJcrNodeAdapter>();
for (AbstractJcrNodeAdapter child : getChildOfSubField) {
relatedJcrNodeAdapter.addChild(child);
}
}
}
}
}
/**
* This file Copyright (c) 2016 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.ui.form.field.transformer.composite;
import static com.google.common.collect.Lists.newArrayList;
import static info.magnolia.test.hamcrest.NodeMatchers.*;
import static org.hamcrest.CoreMatchers.not;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.*;
import info.magnolia.cms.i18n.Messages;
import info.magnolia.cms.i18n.MessagesManager;
import info.magnolia.context.MgnlContext;
import info.magnolia.context.SystemContext;
import info.magnolia.objectfactory.ComponentProvider;
import info.magnolia.objectfactory.Components;
import info.magnolia.test.ComponentsTestUtil;
import info.magnolia.test.mock.MockContext;
import info.magnolia.test.mock.jcr.MockSession;
import info.magnolia.ui.api.context.UiContext;
import info.magnolia.ui.api.i18n.I18NAuthoringSupport;
import info.magnolia.ui.form.field.CompositeField;
import info.magnolia.ui.form.field.MultiField;
import info.magnolia.ui.form.field.SwitchableField;
import info.magnolia.ui.form.field.definition.CompositeFieldDefinition;
import info.magnolia.ui.form.field.definition.ConfiguredFieldDefinition;
import info.magnolia.ui.form.field.definition.FieldDefinition;
import info.magnolia.ui.form.field.definition.MultiValueFieldDefinition;
import info.magnolia.ui.form.field.definition.OptionGroupFieldDefinition;
import info.magnolia.ui.form.field.definition.SelectFieldDefinition;
import info.magnolia.ui.form.field.definition.SelectFieldOptionDefinition;
import info.magnolia.ui.form.field.definition.SwitchableFieldDefinition;
import info.magnolia.ui.form.field.definition.TextFieldDefinition;
import info.magnolia.ui.form.field.definition.TwinColSelectFieldDefinition;
import info.magnolia.ui.form.field.factory.CompositeFieldFactory;
import info.magnolia.ui.form.field.factory.FieldFactory;
import info.magnolia.ui.form.field.factory.FieldFactoryFactory;
import info.magnolia.ui.form.field.factory.MultiValueFieldFactory;
import info.magnolia.ui.form.field.factory.OptionGroupFieldFactory;
import info.magnolia.ui.form.field.factory.SelectFieldFactory;
import info.magnolia.ui.form.field.factory.SwitchableFieldFactory;
import info.magnolia.ui.form.field.factory.TextFieldFactory;
import info.magnolia.ui.form.field.factory.TwinColSelectFieldFactory;
import info.magnolia.ui.form.field.transformer.multi.DelegatingMultiValueFieldTransformer;
import info.magnolia.ui.vaadin.integration.jcr.JcrNodeAdapter;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import javax.jcr.Node;
import javax.jcr.Session;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.mockito.internal.stubbing.answers.ReturnsArgumentAt;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.vaadin.ui.AbstractOrderedLayout;
import com.vaadin.ui.Button;
import com.vaadin.ui.Component;
import com.vaadin.ui.NativeButton;
import com.vaadin.ui.OptionGroup;
import com.vaadin.ui.TextField;
import com.vaadin.ui.TwinColSelect;
import com.vaadin.ui.VerticalLayout;
public class SwitchableFieldTransformerTest {
private Session session;
private ComponentProvider componentProvider;
private I18NAuthoringSupport i18nAuthoringSupport;
private UiContext uiContext;
private FieldFactoryFactory fieldFactoryFactory;
@Before
public void setUp() throws Exception {
session = new MockSession("website");
MockContext ctx = new MockContext();
ctx.addSession("website", session);
MgnlContext.setInstance(ctx);
componentProvider = Components.getComponentProvider();
i18nAuthoringSupport = mock(I18NAuthoringSupport.class);
ComponentsTestUtil.setInstance(I18NAuthoringSupport.class, i18nAuthoringSupport);
uiContext = mock(UiContext.class);
ComponentsTestUtil.setInstance(UiContext.class, uiContext);
ComponentsTestUtil.setInstance(SystemContext.class, ctx);
mockMessagesManager();
fieldFactoryFactory = new MockFieldFactoryFactory(componentProvider);
ComponentsTestUtil.setInstance(FieldFactoryFactory.class, fieldFactoryFactory);
}
@After
public void tearDown() {
ComponentsTestUtil.clear();
MgnlContext.setInstance(null);
}
@Test
public void cleansUpUnselectedOptionsSwitchableFieldUsingSwitchableTransformer() throws Exception {
// GIVEN
SwitchableFieldDefinition definition = createSwitchableFieldDefinitionUsingSwitchableTransformer("switchable");
Node node = session.getRootNode().addNode("node");
JcrNodeAdapter nodeAdapter = new JcrNodeAdapter(node);
SwitchableFieldFactory<SwitchableFieldDefinition> factory = new SwitchableFieldFactory<>(definition, nodeAdapter, fieldFactoryFactory, componentProvider, i18nAuthoringSupport);
SwitchableField field = (SwitchableField) factory.createField();
Iterator<Component> componentIterator = field.iterator();
// CustomField#getContent is lazy, we trigger it via ComponentIterator#next()
VerticalLayout layout = (VerticalLayout) componentIterator.next();
OptionGroup options = (OptionGroup) layout.getComponent(0);
TextField t1 = (TextField) layout.getComponent(1);
TextField t2 = (TextField) layout.getComponent(2);
// WHEN
options.setValue("t1");
t1.setValue("v1");
options.setValue("t2");
t2.setValue("v2");
nodeAdapter.applyChanges();
// THEN
assertThat(node, hasProperty("switchable", "t2"));
assertThat(node, hasProperty("switchablet2", "v2"));
assertThat(node, not(hasProperty("switchablet1")));
}
@Test
public void cleansUpUnselectedOptionsSwitchableFieldUsingDelegatingSwitchableFieldTransformer() throws Exception {
// GIVEN
SwitchableFieldDefinition definition = createSwitchableFieldDefinitionUsingDelegatingSwitchableFieldTransformer("switchable2");
Node node = session.getRootNode().addNode("node");
JcrNodeAdapter nodeAdapter = new JcrNodeAdapter(node);
SwitchableFieldFactory<SwitchableFieldDefinition> factory = new SwitchableFieldFactory<>(definition, nodeAdapter, fieldFactoryFactory, componentProvider, i18nAuthoringSupport);
SwitchableField field = (SwitchableField) factory.createField();
Iterator<Component> componentIterator = field.iterator();
// CustomField#getContent is lazy, we trigger it via ComponentIterator#next()
VerticalLayout layout = (VerticalLayout) componentIterator.next();
OptionGroup options = (OptionGroup) layout.getComponent(0);
CompositeField switchInnerComposite1 = (CompositeField) layout.getComponent(1);
AbstractOrderedLayout switchInnerCompositeLayout = (AbstractOrderedLayout) switchInnerComposite1.iterator().next();
TextField t1 = (TextField) switchInnerCompositeLayout.getComponent(0);
TextField t2 = (TextField) switchInnerCompositeLayout.getComponent(1);
CompositeField switchInnerComposite2 = (CompositeField) layout.getComponent(2);
TextField t3 = (TextField) ((AbstractOrderedLayout) switchInnerComposite2.iterator().next()).getComponent(0);
// WHEN
options.setValue("switchInnerComposite1");
t1.setValue("v1");
t2.setValue("v2");
options.setValue("switchInnerComposite2");
t3.setValue("v3");
nodeAdapter.applyChanges();
// THEN
assertThat(node, hasProperty("switchable2", "switchInnerComposite2"));
assertThat(node, not(hasProperty("t1", "v1")));
assertThat(node, not(hasProperty("t2", "v2")));
assertThat(node, hasProperty("t3", "v3"));
}
@Test
public void cleansUpUnselectedOptionsSwitchableFieldWithCompositeAndMultiValueField() throws Exception {
// GIVEN
SwitchableFieldDefinition definition = createSwitchableFieldDefinitionWithCompositeAndMultiValueField("switchable3");
Node node = session.getRootNode().addNode("node");
JcrNodeAdapter nodeAdapter = new JcrNodeAdapter(node);
SwitchableFieldFactory<SwitchableFieldDefinition> factory = new SwitchableFieldFactory<>(definition, nodeAdapter, fieldFactoryFactory, componentProvider, i18nAuthoringSupport);
SwitchableField field = (SwitchableField) factory.createField();
Iterator<Component> componentIterator = field.iterator();
// CustomField#getContent is lazy, we trigger it via ComponentIterator#next()
VerticalLayout layout = (VerticalLayout) componentIterator.next();
OptionGroup options = (OptionGroup) layout.getComponent(0);
CompositeField switchInnerComposite = (CompositeField) layout.getComponent(1);
AbstractOrderedLayout switchInnerCompositeLayout = (AbstractOrderedLayout) switchInnerComposite.iterator().next();
TextField t1 = (TextField) switchInnerCompositeLayout.getComponent(0);
TextField t2 = (TextField) switchInnerCompositeLayout.getComponent(1);
MultiField switchInnerMulti = (MultiField) layout.getComponent(2);
AbstractOrderedLayout switchInnerMultiLayout = (AbstractOrderedLayout) switchInnerMulti.iterator().next();
Button addButton = (NativeButton) switchInnerMultiLayout.iterator().next();
addButton.click();
TextField textField = (TextField)((AbstractOrderedLayout) switchInnerMultiLayout.iterator().next()).getComponent(0) ;
textField.setValue("textField");
// WHEN
options.setValue("switchInnerComposite");
t1.setValue("v1");
t2.setValue("v2");
options.setValue("switchInnerMulti");
node = nodeAdapter.applyChanges();
// THEN
assertThat(node, hasProperty("switchable3", "switchInnerMulti"));
assertThat(node, not(hasProperty("t1", "v1")));
assertThat(node, not(hasProperty("t2", "v2")));
assertThat(node, hasNode("switchInnerMulti0"));
assertThat(node.getNode("switchInnerMulti0"), hasProperty("t3", "textField"));
}
@Test
public void cleansUpUnselectedOptionsSwitchableFieldWithCompositeAndTwinColField() throws Exception {
// GIVEN
SwitchableFieldDefinition definition = createSwitchableFieldDefinitionWithCompositeAndTwinColumnField("switchable4");
Node node = session.getRootNode().addNode("node");
JcrNodeAdapter nodeAdapter = new JcrNodeAdapter(node);
SwitchableFieldFactory<SwitchableFieldDefinition> factory = new SwitchableFieldFactory<>(definition, nodeAdapter, fieldFactoryFactory, componentProvider, i18nAuthoringSupport);
SwitchableField field = (SwitchableField) factory.createField();
Iterator<Component> componentIterator = field.iterator();
// CustomField#getContent is lazy, we trigger it via ComponentIterator#next()
VerticalLayout layout = (VerticalLayout) componentIterator.next();
OptionGroup options = (OptionGroup) layout.getComponent(0);
CompositeField switchInnerComposite = (CompositeField) layout.getComponent(1);
AbstractOrderedLayout switchInnerCompositeLayout = (AbstractOrderedLayout) switchInnerComposite.iterator().next();
TextField t1 = (TextField) switchInnerCompositeLayout.getComponent(0);
TextField t2 = (TextField) switchInnerCompositeLayout.getComponent(1);
TwinColSelect switchTwinColSelect = (TwinColSelect) layout.getComponent(2);
// WHEN
options.setValue("switchInnerComposite");
t1.setValue("v1");
t2.setValue("v2");
options.setValue("switchTwinColSelect");
switchTwinColSelect.select("option2");
node = nodeAdapter.applyChanges();
// THEN
assertThat(node, hasProperty("switchable4", "switchTwinColSelect"));
assertThat(node, not(hasProperty("t1", "v1")));
assertThat(node, not(hasProperty("t2", "v2")));
assertThat(node, hasProperty("switchTwinColSelect"));
assertEquals("option2", node.getProperty("switchTwinColSelect").getValues()[0].getString());
}
private SwitchableFieldDefinition createSwitchableFieldDefinitionUsingSwitchableTransformer(String name) {
SwitchableFieldDefinition switchable = new SwitchableFieldDefinition();
switchable.setName(name);
switchable.setTransformerClass(SwitchableTransformer.class);
TextFieldDefinition t1 = new TextFieldDefinition();
t1.setName("t1");
TextFieldDefinition t2 = new TextFieldDefinition();
t2.setName("t2");
switchable.setFields(Lists.<ConfiguredFieldDefinition>newArrayList(t1, t2));
switchable.setOptions(createOptions(newArrayList("t1", "t2")));
return switchable;
}
private SwitchableFieldDefinition createSwitchableFieldDefinitionUsingDelegatingSwitchableFieldTransformer(String name) {
SwitchableFieldDefinition switchable = new SwitchableFieldDefinition();
switchable.setName(name);
switchable.setTransformerClass(ComplexFieldFriendlySwitchableTransformer.class);
TextFieldDefinition t1 = new TextFieldDefinition();
t1.setName("t1");
TextFieldDefinition t2 = new TextFieldDefinition();
t2.setName("t2");
CompositeFieldDefinition switchInnerComposite1 = createCompositeDefinition("switchInnerComposite1", Lists.<ConfiguredFieldDefinition>newArrayList(t1, t2));
TextFieldDefinition t3 = new TextFieldDefinition();
t3.setName("t3");
CompositeFieldDefinition switchInnerComposite2 = createCompositeDefinition("switchInnerComposite2", Lists.<ConfiguredFieldDefinition>newArrayList(t3));
switchable.setFields(Lists.<ConfiguredFieldDefinition>newArrayList(switchInnerComposite1, switchInnerComposite2));
switchable.setOptions(createOptions(newArrayList("switchInnerComposite1", "switchInnerComposite2")));
return switchable;
}
private SwitchableFieldDefinition createSwitchableFieldDefinitionWithCompositeAndMultiValueField(String name) {
SwitchableFieldDefinition switchable = new SwitchableFieldDefinition();
switchable.setName(name);
switchable.setTransformerClass(ComplexFieldFriendlySwitchableTransformer.class);
TextFieldDefinition t1 = new TextFieldDefinition();
t1.setName("t1");
TextFieldDefinition t2 = new TextFieldDefinition();
t2.setName("t2");
CompositeFieldDefinition switchInnerComposite = createCompositeDefinition("switchInnerComposite", Lists.<ConfiguredFieldDefinition>newArrayList(t1, t2));
MultiValueFieldDefinition switchInnerMulti = new MultiValueFieldDefinition();
switchInnerMulti.setName("switchInnerMulti");
switchInnerMulti.setTransformerClass(DelegatingMultiValueFieldTransformer.class);
TextFieldDefinition t3 = new TextFieldDefinition();
t3.setName("t3");
switchInnerMulti.setField(t3);
switchable.setFields(Lists.newArrayList(switchInnerComposite, switchInnerMulti));
switchable.setOptions(createOptions(newArrayList("switchInnerComposite", "switchInnerMulti")));
return switchable;
}
private SwitchableFieldDefinition createSwitchableFieldDefinitionWithCompositeAndTwinColumnField(String name) {
SwitchableFieldDefinition switchable = new SwitchableFieldDefinition();
switchable.setName(name);
switchable.setTransformerClass(ComplexFieldFriendlySwitchableTransformer.class);
TextFieldDefinition t1 = new TextFieldDefinition();
t1.setName("t1");
TextFieldDefinition t2 = new TextFieldDefinition();
t2.setName("t2");
CompositeFieldDefinition switchInnerComposite = createCompositeDefinition("switchInnerComposite", Lists.<ConfiguredFieldDefinition>newArrayList(t1, t2));
TwinColSelectFieldDefinition switchTwinColSelect = new TwinColSelectFieldDefinition();
switchTwinColSelect.setName("switchTwinColSelect");
switchTwinColSelect.setOptions(createOptions(newArrayList("option1", "option2", "option3")));
switchable.setFields(Lists.newArrayList(switchInnerComposite, switchTwinColSelect));
switchable.setOptions(createOptions(newArrayList("switchInnerComposite", "switchTwinColSelect")));
return switchable;
}
private static class MockFieldFactoryFactory extends FieldFactoryFactory {
private final Map<Class<? extends FieldDefinition>, Class<? extends FieldFactory>> fieldTypes = Maps.newHashMap();
private final ComponentProvider componentProvider;
public MockFieldFactoryFactory(ComponentProvider componentProvider) {
super(null, null, null);
this.componentProvider = componentProvider;
registerFieldType(TextFieldDefinition.class, TextFieldFactory.class);
registerFieldType(OptionGroupFieldDefinition.class, OptionGroupFieldFactory.class);
registerFieldType(SelectFieldDefinition.class, SelectFieldFactory.class);
registerFieldType(CompositeFieldDefinition.class, CompositeFieldFactory.class);
registerFieldType(MultiValueFieldDefinition.class, MultiValueFieldFactory.class);
registerFieldType(TwinColSelectFieldDefinition.class, TwinColSelectFieldFactory.class);
}
public void registerFieldType(Class<? extends FieldDefinition> definitionClass, Class<? extends FieldFactory> factoryClass) {
fieldTypes.put(definitionClass, factoryClass);
}
@Override
public FieldFactory createFieldFactory(FieldDefinition definition, Object... parameters) {
if (fieldTypes.containsKey(definition.getClass())) {
Class<? extends FieldFactory> factoryClass = fieldTypes.get(definition.getClass());
ArrayList<Object> combinedParameters = Lists.newArrayList(parameters);
combinedParameters.add(definition);
combinedParameters.add(componentProvider);
return componentProvider.newInstance(factoryClass, combinedParameters.toArray());
}
return null;
}
}
private static void mockMessagesManager() {
MockMessagesManager messagesManager = mock(MockMessagesManager.class);
Messages messages = mock(Messages.class);
doAnswer(new ReturnsArgumentAt(0)).when(messages).get(anyString());
doReturn(messages).when(messagesManager).getMessagesInternal(anyString(), any(Locale.class));
ComponentsTestUtil.setInstance(MessagesManager.class, messagesManager);
}
/**
* Just exposing #getMessagesInternal() for mocking.
*/
private abstract static class MockMessagesManager extends MessagesManager {
@Override
public abstract Messages getMessagesInternal(String basename, Locale locale);
}
private List<SelectFieldOptionDefinition> createOptions(List<String> optionNames) {
List<SelectFieldOptionDefinition> options = new ArrayList<>();
for (String optionName : optionNames) {
SelectFieldOptionDefinition option = new SelectFieldOptionDefinition();
option.setName(optionName);
options.add(option);
}
return options;
}
private CompositeFieldDefinition createCompositeDefinition(String name, List<ConfiguredFieldDefinition> fieldDefinitions) {
CompositeFieldDefinition switchInnerComposite = new CompositeFieldDefinition();
switchInnerComposite.setName(name);
switchInnerComposite.setTransformerClass(DelegatingCompositeFieldTransformer.class);
switchInnerComposite.setFields(fieldDefinitions);
return switchInnerComposite;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment