Fixes #6043tags/8.1.0.alpha6
@@ -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 |
@@ -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 |
@@ -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); | |||
} | |||
} |
@@ -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); | |||
} | |||
} |
@@ -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()); | |||
} | |||
} |
@@ -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); | |||
} | |||
} |
@@ -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); | |||
} | |||
} |
@@ -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()); | |||
} | |||
} |
@@ -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()); | |||
} | |||
} |
@@ -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()); | |||
} | |||
} |
@@ -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> |
@@ -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> |