Browse Source

Delegate properties to Composite's root if possible

Fixes #9670
tags/8.1.0.rc2
Ilia Motornyi 6 years ago
parent
commit
c1aef3c50b

+ 50
- 31
server/src/main/java/com/vaadin/ui/Composite.java View File

import java.util.Collections; import java.util.Collections;
import java.util.Iterator; import java.util.Iterator;
import java.util.Objects; import java.util.Objects;
import java.util.Optional;


import com.vaadin.server.ErrorMessage; import com.vaadin.server.ErrorMessage;
import com.vaadin.server.Resource; import com.vaadin.server.Resource;
import com.vaadin.server.SerializableFunction;
import com.vaadin.shared.ui.ContentMode; import com.vaadin.shared.ui.ContentMode;
import com.vaadin.shared.ui.composite.CompositeState; import com.vaadin.shared.ui.composite.CompositeState;


*/ */
public class Composite extends AbstractComponent implements HasComponents { public class Composite extends AbstractComponent implements HasComponents {


private static final String COMPOSITE_HAS_NO_DOM_OR_WIDGET = "A composite has no DOM or widget";
/** /**
* The contained component. * The contained component.
*/ */
if (getCompositionRoot() != null) { if (getCompositionRoot() != null) {
return Collections.singletonList(getCompositionRoot()).iterator(); return Collections.singletonList(getCompositionRoot()).iterator();
} else { } else {
return Collections.<Component> emptyList().iterator();
return Collections.<Component>emptyList().iterator();
} }
} }




@Override @Override
public String getStyleName() { public String getStyleName() {
throw new UnsupportedOperationException(COMPOSITE_HAS_NO_DOM_OR_WIDGET);
Component root = getCompositionRoot();
return root == null ? "" : root.getStyleName();
} }


@Override @Override
public void setStyleName(String style) { public void setStyleName(String style) {
throw new UnsupportedOperationException(COMPOSITE_HAS_NO_DOM_OR_WIDGET);
getRootOrThrow().setStyleName(style);
} }


@Override @Override
public void setStyleName(String style, boolean add) { public void setStyleName(String style, boolean add) {
throw new UnsupportedOperationException(COMPOSITE_HAS_NO_DOM_OR_WIDGET);
getRootAbstractComponentOrThrow().setStyleName(style, add);
} }


@Override @Override
public void addStyleName(String style) { public void addStyleName(String style) {
throw new UnsupportedOperationException(COMPOSITE_HAS_NO_DOM_OR_WIDGET);
getRootOrThrow().addStyleName(style);
} }


@Override @Override
public void removeStyleName(String style) { public void removeStyleName(String style) {
throw new UnsupportedOperationException(COMPOSITE_HAS_NO_DOM_OR_WIDGET);
getRootOrThrow().removeStyleName(style);
} }


@Override @Override
public String getPrimaryStyleName() { public String getPrimaryStyleName() {
throw new UnsupportedOperationException(COMPOSITE_HAS_NO_DOM_OR_WIDGET);
return getRootAbstractComponentPropertyOrNull(AbstractComponent::getPrimaryStyleName);
} }


@Override @Override
public void setPrimaryStyleName(String style) { public void setPrimaryStyleName(String style) {
throw new UnsupportedOperationException(COMPOSITE_HAS_NO_DOM_OR_WIDGET);
getRootOrThrow().setPrimaryStyleName(style);
} }


private Component getRootOrThrow() { private Component getRootOrThrow() {
return Optional.ofNullable(getCompositionRoot())
.orElseThrow(() -> new IllegalStateException(
"Composition root has not been set"));
Component root = getCompositionRoot();
if(root == null) throw new IllegalStateException("Composition root has not been set");
return root;
}

private AbstractComponent getRootAbstractComponentOrThrow() {
Component root = getRootOrThrow();
if (!(root instanceof AbstractComponent)) {
throw new IllegalStateException("Composition root is not AbstractComponent");
}
return (AbstractComponent) root;
}

private <T> T getRootPropertyOrNull(SerializableFunction<Component, T> getter) {
Component root = getCompositionRoot();
return root == null ? null : getter.apply(root);
}

private <T> T getRootAbstractComponentPropertyOrNull(SerializableFunction<AbstractComponent, T> getter) {
Component root = getCompositionRoot();
if(root instanceof AbstractComponent) {
return getter.apply((AbstractComponent) root);
}
return null;
} }


@Override @Override


@Override @Override
public void setId(String id) { public void setId(String id) {
throw new UnsupportedOperationException(COMPOSITE_HAS_NO_DOM_OR_WIDGET);
getRootOrThrow().setId(id);
} }


@Override @Override
public String getId() { public String getId() {
// Design.read relies on being able to call this
return null;
return getRootPropertyOrNull(Component::getId);
} }


@Override @Override
public void setDebugId(String id) { public void setDebugId(String id) {
throw new UnsupportedOperationException(COMPOSITE_HAS_NO_DOM_OR_WIDGET);
getRootAbstractComponentOrThrow().setDebugId(id);
} }


@Override @Override
public String getDebugId() { public String getDebugId() {
throw new UnsupportedOperationException(COMPOSITE_HAS_NO_DOM_OR_WIDGET);
return getRootAbstractComponentPropertyOrNull(AbstractComponent::getDebugId);
} }


@Override @Override
public String getCaption() { public String getCaption() {
// Design.read relies on being able to call this
return null;
return getRootPropertyOrNull(Component::getCaption);
} }


@Override @Override
public void setCaption(String caption) { public void setCaption(String caption) {
throw new UnsupportedOperationException(COMPOSITE_HAS_NO_DOM_OR_WIDGET);
getRootOrThrow().setCaption(caption);
} }


@Override @Override
public void setCaptionAsHtml(boolean captionAsHtml) { public void setCaptionAsHtml(boolean captionAsHtml) {
throw new UnsupportedOperationException(COMPOSITE_HAS_NO_DOM_OR_WIDGET);
getRootAbstractComponentOrThrow().setCaptionAsHtml(captionAsHtml);
} }


@Override @Override
public boolean isCaptionAsHtml() { public boolean isCaptionAsHtml() {
throw new UnsupportedOperationException(COMPOSITE_HAS_NO_DOM_OR_WIDGET);
return getRootAbstractComponentPropertyOrNull(AbstractComponent::isCaptionAsHtml);
} }


@Override @Override
public Resource getIcon() { public Resource getIcon() {
throw new UnsupportedOperationException(COMPOSITE_HAS_NO_DOM_OR_WIDGET);
return getRootPropertyOrNull(Component::getIcon);
} }


@Override @Override
public void setIcon(Resource icon) { public void setIcon(Resource icon) {
throw new UnsupportedOperationException(COMPOSITE_HAS_NO_DOM_OR_WIDGET);
getRootOrThrow().setIcon(icon);
} }


@Override @Override
public String getDescription() { public String getDescription() {
throw new UnsupportedOperationException(COMPOSITE_HAS_NO_DOM_OR_WIDGET);
return getRootOrThrow().getDescription();
} }


@Override @Override
public void setDescription(String description) { public void setDescription(String description) {
throw new UnsupportedOperationException(COMPOSITE_HAS_NO_DOM_OR_WIDGET);
getRootAbstractComponentOrThrow().setDescription(description);
} }


@Override @Override
public void setDescription(String description, ContentMode mode) { public void setDescription(String description, ContentMode mode) {
throw new UnsupportedOperationException(COMPOSITE_HAS_NO_DOM_OR_WIDGET);
getRootAbstractComponentOrThrow().setDescription(description, mode);
} }


@Override @Override
public ErrorMessage getErrorMessage() { public ErrorMessage getErrorMessage() {
return null;
return getRootAbstractComponentPropertyOrNull(AbstractComponent::getErrorMessage);
} }


@Override @Override
public ErrorMessage getComponentError() { public ErrorMessage getComponentError() {
throw new UnsupportedOperationException(COMPOSITE_HAS_NO_DOM_OR_WIDGET);
return getRootAbstractComponentPropertyOrNull(AbstractComponent::getComponentError);
} }


@Override @Override
public void setComponentError(ErrorMessage componentError) { public void setComponentError(ErrorMessage componentError) {
throw new UnsupportedOperationException(COMPOSITE_HAS_NO_DOM_OR_WIDGET);
getRootAbstractComponentOrThrow().setComponentError(componentError);
} }


} }

+ 31
- 8
server/src/test/java/com/vaadin/tests/components/TreeTest.java View File

package com.vaadin.tests.components; package com.vaadin.tests.components;


import org.junit.Assert;
import org.junit.Test;

import com.vaadin.data.TreeData; import com.vaadin.data.TreeData;
import com.vaadin.data.provider.TreeDataProvider; import com.vaadin.data.provider.TreeDataProvider;
import com.vaadin.event.CollapseEvent; import com.vaadin.event.CollapseEvent;
import com.vaadin.event.CollapseEvent.CollapseListener; import com.vaadin.event.CollapseEvent.CollapseListener;
import com.vaadin.event.ExpandEvent; import com.vaadin.event.ExpandEvent;
import com.vaadin.event.ExpandEvent.ExpandListener; import com.vaadin.event.ExpandEvent.ExpandListener;
import com.vaadin.server.ThemeResource;
import com.vaadin.ui.Tree; import com.vaadin.ui.Tree;
import org.junit.Assert;
import org.junit.Test;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;


public class TreeTest { public class TreeTest {


public static final String TEST_CAPTION = "test caption";
public static final String TEST_DESCRIPTION = "test description";
public static final String TEST_RESOURCE_ID = "nothing.gif";

private static class TreeCollapseExpandListener private static class TreeCollapseExpandListener
implements ExpandListener<String>, CollapseListener<String> { implements ExpandListener<String>, CollapseListener<String> {




@Override @Override
public void itemCollapse(CollapseEvent<String> event) { public void itemCollapse(CollapseEvent<String> event) {
Assert.assertEquals("Source component was incorrect", tree,
assertEquals("Source component was incorrect", tree,
event.getComponent()); event.getComponent());
Assert.assertFalse("Multiple collapse events", collapsed); Assert.assertFalse("Multiple collapse events", collapsed);
collapsed = true; collapsed = true;


@Override @Override
public void itemExpand(ExpandEvent<String> event) { public void itemExpand(ExpandEvent<String> event) {
Assert.assertEquals("Source component was incorrect", tree,
assertEquals("Source component was incorrect", tree,
event.getComponent()); event.getComponent());
Assert.assertFalse("Multiple expand events", expanded); Assert.assertFalse("Multiple expand events", expanded);
expanded = true; expanded = true;


Assert.assertFalse(listener.isExpanded()); Assert.assertFalse(listener.isExpanded());
tree.expand("Foo"); tree.expand("Foo");
Assert.assertTrue("Item not expanded", tree.isExpanded("Foo"));
Assert.assertTrue("Expand event not fired", listener.isExpanded());
assertTrue("Item not expanded", tree.isExpanded("Foo"));
assertTrue("Expand event not fired", listener.isExpanded());
Assert.assertFalse(listener.isCollapsed()); Assert.assertFalse(listener.isCollapsed());
tree.collapse("Foo"); tree.collapse("Foo");
Assert.assertFalse("Item not collapsed", tree.isExpanded("Foo")); Assert.assertFalse("Item not collapsed", tree.isExpanded("Foo"));
Assert.assertTrue("Collapse event not fired", listener.isCollapsed());
assertTrue("Collapse event not fired", listener.isCollapsed());
} }


@Test
public void testComponentProperties() {
Tree<String> tree = new Tree<>();
tree.setCaption(TEST_CAPTION);
tree.setDescription(TEST_DESCRIPTION);
tree.setIcon(new ThemeResource(TEST_RESOURCE_ID));

assertEquals(TEST_CAPTION,tree.getCaption());
assertEquals(TEST_DESCRIPTION,tree.getDescription());
assertEquals(TEST_RESOURCE_ID,tree.getIcon().toString());

assertFalse(tree.isCaptionAsHtml());
tree.setCaptionAsHtml(true);
assertTrue(tree.isCaptionAsHtml());
}
} }

Loading…
Cancel
Save