diff options
author | Artur <artur@vaadin.com> | 2017-04-18 14:23:06 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-04-18 14:23:06 +0300 |
commit | a5b1741e47ab682963d8bd0c205c273a49dd2243 (patch) | |
tree | 8617519c2b3d74fbf85b952b04dcff787a4295b5 | |
parent | 20b49db2fc4b82d9a676925a78fd13be9ef81498 (diff) | |
download | vaadin-framework-a5b1741e47ab682963d8bd0c205c273a49dd2243.tar.gz vaadin-framework-a5b1741e47ab682963d8bd0c205c273a49dd2243.zip |
Support using Composite and CustomComponent as a Design root class (#9017)
Fixes #6043
12 files changed, 341 insertions, 10 deletions
diff --git a/server/src/main/java/com/vaadin/ui/Composite.java b/server/src/main/java/com/vaadin/ui/Composite.java index 10bcff0510..58efbaeb94 100644 --- a/server/src/main/java/com/vaadin/ui/Composite.java +++ b/server/src/main/java/com/vaadin/ui/Composite.java @@ -263,7 +263,8 @@ public class Composite extends AbstractComponent implements HasComponents { @Override public String getId() { - throw new UnsupportedOperationException(COMPOSITE_HAS_NO_DOM_OR_WIDGET); + // Design.read relies on being able to call this + return null; } @Override @@ -278,7 +279,8 @@ public class Composite extends AbstractComponent implements HasComponents { @Override public String getCaption() { - throw new UnsupportedOperationException(COMPOSITE_HAS_NO_DOM_OR_WIDGET); + // Design.read relies on being able to call this + return null; } @Override diff --git a/server/src/main/java/com/vaadin/ui/declarative/Design.java b/server/src/main/java/com/vaadin/ui/declarative/Design.java index e0c601efbc..b051c68a90 100644 --- a/server/src/main/java/com/vaadin/ui/declarative/Design.java +++ b/server/src/main/java/com/vaadin/ui/declarative/Design.java @@ -39,6 +39,9 @@ import com.vaadin.annotations.DesignRoot; import com.vaadin.server.VaadinServiceClassLoaderUtil; import com.vaadin.shared.util.SharedUtil; import com.vaadin.ui.Component; +import com.vaadin.ui.ComponentRootSetter; +import com.vaadin.ui.Composite; +import com.vaadin.ui.CustomComponent; import com.vaadin.ui.declarative.DesignContext.ComponentCreatedEvent; import com.vaadin.ui.declarative.DesignContext.ComponentCreationListener; @@ -409,9 +412,11 @@ public class Design implements Serializable { * the html tree * @param componentRoot * optional component root instance. The type must match the type - * of the root element in the design. Any member fields whose - * type is assignable from {@link Component} are bound to fields - * in the design based on id/local id/caption + * of the root element in the design or be a + * {@link CustomComponent} or {@link Composite}, in which case + * the root component will be set as the composition root. Any + * member fields whose type is assignable from {@link Component} + * are bound to fields in the design based on id/local id/caption */ private static DesignContext designToComponentTree(Document doc, Component componentRoot) { @@ -432,12 +437,19 @@ public class Design implements Serializable { * If a component root is given, the component instances created during * reading the design are assigned to its member fields based on their id, * local id, and caption + * <p> + * If the root is a custom component or composite, its composition root will + * be populated with the design contents. Note that even if the root + * component is a custom component/composite, the root element of the design + * should not be to avoid nesting a custom component in a custom component. * * @param doc * the html tree * @param componentRoot * optional component root instance. The type must match the type - * of the root element in the design. + * of the root element in the design or be a + * {@link CustomComponent} or {@link Composite}, in which case + * the root component will be set as the composition root. * @param classWithFields * a class (componentRoot class or a super class) with some * member fields. The member fields whose type is assignable from @@ -480,8 +492,15 @@ public class Design implements Serializable { binder.bindField(event.getComponent(), event.getLocalId()); }; designContext.addComponentCreationListener(creationListener); + // create subtree - designContext.readDesign(element, componentRoot); + if (componentRoot instanceof CustomComponent + || componentRoot instanceof Composite) { + Component rootComponent = designContext.readDesign(element); + ComponentRootSetter.setRoot(componentRoot, rootComponent); + } else { + designContext.readDesign(element, componentRoot); + } // make sure that all the member fields are bound Collection<String> unboundFields = binder.getUnboundFields(); if (!unboundFields.isEmpty()) { @@ -550,6 +569,12 @@ public class Design implements Serializable { * id/local id/caption in the design file. * <p> * The type of the root component must match the root element in the design + * or the root component must be a {@link CustomComponent} or + * {@link Composite}. If the root is a custom component or composite, its + * composition root will be populated with the design contents. Note that + * even if the root component is a custom component/composite, the root + * element of the design should not be to avoid nesting a custom component + * in a custom component. * * @param rootComponent * The root component of the layout @@ -640,7 +665,13 @@ public class Design implements Serializable { * design. Matching is done based on field name in the component class and * id/local id/caption in the design file. * <p> - * The type of the root component must match the root element in the design. + * The type of the root component must match the root element in the design + * or the root component must be a {@link CustomComponent} or + * {@link Composite}. If the root is a custom component or composite, its + * composition root will be populated with the design contents. Note that + * even if the root component is a custom component/composite, the root + * element of the design should not be to avoid nesting a custom component + * in a custom component. * * @param filename * The file name to load. Loaded from the same package as the @@ -680,8 +711,13 @@ public class Design implements Serializable { * design. Matching is done based on field name in the component class and * id/local id/caption in the design file. * <p> - * If rootComponent is not null, its type must match the type of the root - * element in the design + * The type of the root component must match the root element in the design + * or the root component must be a {@link CustomComponent} or + * {@link Composite}. If the root is a custom component or composite, its + * composition root will be populated with the design contents. Note that + * even if the root component is a custom component/composite, the root + * element of the design should not be to avoid nesting a custom component + * in a custom component. * * @param stream * The stream to read the design from diff --git a/server/src/test/java/com/vaadin/tests/design/designroot/CompositeDesignRootForMyComposite.java b/server/src/test/java/com/vaadin/tests/design/designroot/CompositeDesignRootForMyComposite.java new file mode 100644 index 0000000000..cc28875d5a --- /dev/null +++ b/server/src/test/java/com/vaadin/tests/design/designroot/CompositeDesignRootForMyComposite.java @@ -0,0 +1,28 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * 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. + */ +package com.vaadin.tests.design.designroot; + +import com.vaadin.annotations.DesignRoot; +import com.vaadin.ui.Composite; +import com.vaadin.ui.declarative.Design; + +@DesignRoot("MyComposite.html") +public class CompositeDesignRootForMyComposite extends Composite { + + public CompositeDesignRootForMyComposite() { + Design.read(this); + } +} diff --git a/server/src/test/java/com/vaadin/tests/design/designroot/CompositeDesignRootForVerticalLayout.java b/server/src/test/java/com/vaadin/tests/design/designroot/CompositeDesignRootForVerticalLayout.java new file mode 100644 index 0000000000..3b474de4a7 --- /dev/null +++ b/server/src/test/java/com/vaadin/tests/design/designroot/CompositeDesignRootForVerticalLayout.java @@ -0,0 +1,34 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * 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. + */ +package com.vaadin.tests.design.designroot; + +import com.vaadin.annotations.DesignRoot; +import com.vaadin.ui.Button; +import com.vaadin.ui.Composite; +import com.vaadin.ui.Label; +import com.vaadin.ui.declarative.Design; + +@DesignRoot("DesignWithEmptyAnnotation.html") +public class CompositeDesignRootForVerticalLayout extends Composite { + + public Button ok; + public Button cancel; + public Label preInitializedField = new Label("original"); + + public CompositeDesignRootForVerticalLayout() { + Design.read(this); + } +} diff --git a/server/src/test/java/com/vaadin/tests/design/designroot/CompositeDesignRootTest.java b/server/src/test/java/com/vaadin/tests/design/designroot/CompositeDesignRootTest.java new file mode 100644 index 0000000000..fbe0b029f2 --- /dev/null +++ b/server/src/test/java/com/vaadin/tests/design/designroot/CompositeDesignRootTest.java @@ -0,0 +1,50 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * 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. + */ +package com.vaadin.tests.design.designroot; + +import org.junit.Assert; +import org.junit.Test; + +import com.vaadin.tests.server.component.composite.MyPrefilledComposite; +import com.vaadin.ui.Component; +import com.vaadin.ui.VerticalLayout; + +public class CompositeDesignRootTest { + + @Test + public void compositeReadVerticalLayoutDesign() { + CompositeDesignRootForVerticalLayout r = new CompositeDesignRootForVerticalLayout(); + // Composition root, should be VerticalLayout + Component compositionRoot = r.iterator().next(); + Assert.assertNotNull(compositionRoot); + Assert.assertEquals(VerticalLayout.class, compositionRoot.getClass()); + Assert.assertNotNull(r.ok); + Assert.assertNotNull(r.cancel); + Assert.assertEquals("original", r.preInitializedField.getValue()); + } + + @Test + public void compositeReadCompositeDesign() { + CompositeDesignRootForMyComposite r = new CompositeDesignRootForMyComposite(); + // Composition root, should be MyPrefilledcomposite + Component compositionRoot = r.iterator().next(); + Assert.assertNotNull(compositionRoot); + Assert.assertEquals(MyPrefilledComposite.class, + compositionRoot.getClass()); + + } + +} diff --git a/server/src/test/java/com/vaadin/tests/design/designroot/CustomComponentDesignRootForMyCustomComponent.java b/server/src/test/java/com/vaadin/tests/design/designroot/CustomComponentDesignRootForMyCustomComponent.java new file mode 100644 index 0000000000..8fce20e29b --- /dev/null +++ b/server/src/test/java/com/vaadin/tests/design/designroot/CustomComponentDesignRootForMyCustomComponent.java @@ -0,0 +1,29 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * 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. + */ +package com.vaadin.tests.design.designroot; + +import com.vaadin.annotations.DesignRoot; +import com.vaadin.ui.CustomComponent; +import com.vaadin.ui.declarative.Design; + +@DesignRoot("MyCustomComponent.html") +public class CustomComponentDesignRootForMyCustomComponent + extends CustomComponent { + + public CustomComponentDesignRootForMyCustomComponent() { + Design.read(this); + } +} diff --git a/server/src/test/java/com/vaadin/tests/design/designroot/CustomComponentDesignRootForVerticalLayout.java b/server/src/test/java/com/vaadin/tests/design/designroot/CustomComponentDesignRootForVerticalLayout.java new file mode 100644 index 0000000000..e1d4561a25 --- /dev/null +++ b/server/src/test/java/com/vaadin/tests/design/designroot/CustomComponentDesignRootForVerticalLayout.java @@ -0,0 +1,34 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * 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. + */ +package com.vaadin.tests.design.designroot; + +import com.vaadin.annotations.DesignRoot; +import com.vaadin.ui.Button; +import com.vaadin.ui.CustomComponent; +import com.vaadin.ui.Label; +import com.vaadin.ui.declarative.Design; + +@DesignRoot("DesignWithEmptyAnnotation.html") +public class CustomComponentDesignRootForVerticalLayout extends CustomComponent { + + public Button ok; + public Button cancel; + public Label preInitializedField = new Label("original"); + + public CustomComponentDesignRootForVerticalLayout() { + Design.read(this); + } +} diff --git a/server/src/test/java/com/vaadin/tests/design/designroot/CustomComponentDesignRootTest.java b/server/src/test/java/com/vaadin/tests/design/designroot/CustomComponentDesignRootTest.java new file mode 100644 index 0000000000..5331fdba4b --- /dev/null +++ b/server/src/test/java/com/vaadin/tests/design/designroot/CustomComponentDesignRootTest.java @@ -0,0 +1,50 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * 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. + */ +package com.vaadin.tests.design.designroot; + +import org.junit.Assert; +import org.junit.Test; + +import com.vaadin.tests.server.component.customcomponent.MyPrefilledCustomComponent; +import com.vaadin.ui.Component; +import com.vaadin.ui.VerticalLayout; + +public class CustomComponentDesignRootTest { + + @Test + public void customComponentReadVerticalLayoutDesign() { + CustomComponentDesignRootForVerticalLayout r = new CustomComponentDesignRootForVerticalLayout(); + // Composition root, should be VerticalLayout + Component compositionRoot = r.iterator().next(); + Assert.assertNotNull(compositionRoot); + Assert.assertEquals(VerticalLayout.class, compositionRoot.getClass()); + Assert.assertNotNull(r.ok); + Assert.assertNotNull(r.cancel); + Assert.assertEquals("original", r.preInitializedField.getValue()); + } + + @Test + public void customComponentReadCustomComponentDesign() { + CustomComponentDesignRootForMyCustomComponent r = new CustomComponentDesignRootForMyCustomComponent(); + // Composition root, should be MyPrefilledCustomComponent + Component compositionRoot = r.iterator().next(); + Assert.assertNotNull(compositionRoot); + Assert.assertEquals(MyPrefilledCustomComponent.class, + compositionRoot.getClass()); + + } + +} diff --git a/server/src/test/java/com/vaadin/tests/server/component/composite/MyPrefilledComposite.java b/server/src/test/java/com/vaadin/tests/server/component/composite/MyPrefilledComposite.java new file mode 100644 index 0000000000..7e3a726fc6 --- /dev/null +++ b/server/src/test/java/com/vaadin/tests/server/component/composite/MyPrefilledComposite.java @@ -0,0 +1,25 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * 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. + */ +package com.vaadin.tests.server.component.composite; + +import com.vaadin.ui.Composite; +import com.vaadin.ui.NativeButton; + +public class MyPrefilledComposite extends Composite { + public MyPrefilledComposite() { + setCompositionRoot(new NativeButton()); + } +} diff --git a/server/src/test/java/com/vaadin/tests/server/component/customcomponent/MyPrefilledCustomComponent.java b/server/src/test/java/com/vaadin/tests/server/component/customcomponent/MyPrefilledCustomComponent.java new file mode 100644 index 0000000000..928e460255 --- /dev/null +++ b/server/src/test/java/com/vaadin/tests/server/component/customcomponent/MyPrefilledCustomComponent.java @@ -0,0 +1,25 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * 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. + */ +package com.vaadin.tests.server.component.customcomponent; + +import com.vaadin.ui.CustomComponent; +import com.vaadin.ui.NativeButton; + +public class MyPrefilledCustomComponent extends CustomComponent { + public MyPrefilledCustomComponent() { + setCompositionRoot(new NativeButton()); + } +} diff --git a/server/src/test/resources/com/vaadin/tests/design/designroot/MyComposite.html b/server/src/test/resources/com/vaadin/tests/design/designroot/MyComposite.html new file mode 100644 index 0000000000..8eee42d318 --- /dev/null +++ b/server/src/test/resources/com/vaadin/tests/design/designroot/MyComposite.html @@ -0,0 +1,9 @@ +<html> +<head> +<meta name='package-mapping' + content='x:com.vaadin.tests.server.component.composite' /> +</head> +<body> + <x-my-prefilled-composite /> +</body> +</html> diff --git a/server/src/test/resources/com/vaadin/tests/design/designroot/MyCustomComponent.html b/server/src/test/resources/com/vaadin/tests/design/designroot/MyCustomComponent.html new file mode 100644 index 0000000000..820169c87c --- /dev/null +++ b/server/src/test/resources/com/vaadin/tests/design/designroot/MyCustomComponent.html @@ -0,0 +1,9 @@ +<html> +<head> +<meta name='package-mapping' + content='x:com.vaadin.tests.server.component.customcomponent' /> +</head> +<body> + <x-my-prefilled-custom-component /> +</body> +</html> |