// taken care of by jsoup.
Element root = doc.body();
Elements children = root.children();
- if (children.size() != 1) {
+ if (children.size() > 1) {
throw new DesignException(
- "The first level of a component hierarchy should contain exactly one root component, but found "
- + children.size());
+ "The first level of a component hierarchy should contain at most one root component, but found "
+ + children.size() + ".");
}
- Element element = children.first();
+ Element element = children.size() == 0 ? null : children.first();
if (componentRoot != null) {
+ if (element == null) {
+ throw new DesignException(
+ "The root element cannot be null when the specified root Component is"
+ + " not null.");
+ }
// user has specified root instance that may have member fields that
// should be bound
final FieldBinder binder;
designContext.removeComponentCreationListener(creationListener);
} else {
// createChild creates the entire component hierarchy
- componentRoot = designContext.readDesign(element);
+ componentRoot = element == null ? null : designContext
+ .readDesign(element);
}
designContext.setRootComponent(componentRoot);
return designContext;
// creates the entire component hierarchy rooted at the
// given root node.
Component root = designContext.getRootComponent();
- Node rootNode = designContext.createElement(root);
- body.appendChild(rootNode);
+ if (root != null) {
+ Node rootNode = designContext.createElement(root);
+ body.appendChild(rootNode);
+ }
designContext.writePackageMappings(doc);
return doc;
}
/**
* Writes the given component tree in design format to the given output
- * stream
+ * stream.
*
* @param component
- * the root component of the component tree
+ * the root component of the component tree, null can be used for
+ * generating an empty design
* @param outputStream
* the output stream to write the design to. The design is always
* written as UTF-8
* and other information not available in the component tree.
*
* @param designContext
- * the DesignContext object specifying the component hierarchy
- * and the local id values of the objects
+ * The DesignContext object specifying the component hierarchy
+ * and the local id values of the objects. If
+ * designContext.getRootComponent() is null, an empty design will
+ * be generated.
* @param outputStream
* the output stream to write the design to. The design is always
* written as UTF-8
*
* @param componentDesign
* The design element containing the description of the component
- * to be created
+ * to be created.
* @return the root component of component tree
*/
public Component readDesign(Element componentDesign) {
--- /dev/null
+/*
+ * 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;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+
+import junit.framework.TestCase;
+
+import org.jsoup.nodes.Document;
+import org.jsoup.nodes.DocumentType;
+import org.jsoup.nodes.Element;
+
+import com.vaadin.ui.Component;
+import com.vaadin.ui.VerticalLayout;
+import com.vaadin.ui.declarative.Design;
+import com.vaadin.ui.declarative.DesignContext;
+import com.vaadin.ui.declarative.DesignException;
+
+/**
+ * Test cases for checking that reading a design with no elements in the html
+ * body produces null as the root component.
+ */
+public class TestReadEmptyDesign extends TestCase {
+ InputStream is;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ String html = createDesign().toString();
+ is = new ByteArrayInputStream(html.getBytes());
+ }
+
+ public void testReadComponent() {
+ Component root = Design.read(is);
+ assertNull("The root component should be null.", root);
+ }
+
+ public void testReadContext() {
+ DesignContext ctx = Design.read(is, null);
+ assertNotNull("The design context should not be null.", ctx);
+ assertNull("The root component should be null.", ctx.getRootComponent());
+ }
+
+ public void testReadContextWithRootParameter() {
+ try {
+ Component rootComponent = new VerticalLayout();
+ DesignContext ctx = Design.read(is, rootComponent);
+ fail("Reading a design with no elements should fail when a non-null root Component is specified.");
+ } catch (DesignException e) {
+ // This is the expected outcome, nothing to do.
+ }
+ }
+
+ private Document createDesign() {
+ Document doc = new Document("");
+ DocumentType docType = new DocumentType("html", "", "", "");
+ doc.appendChild(docType);
+ Element html = doc.createElement("html");
+ doc.appendChild(html);
+ html.appendChild(doc.createElement("head"));
+ html.appendChild(doc.createElement("body"));
+ return doc;
+ }
+}
\ No newline at end of file
--- /dev/null
+/*
+ * 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;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+import junit.framework.TestCase;
+
+import org.jsoup.Jsoup;
+import org.jsoup.nodes.Document;
+import org.jsoup.nodes.Element;
+
+import com.vaadin.ui.Component;
+import com.vaadin.ui.declarative.Design;
+import com.vaadin.ui.declarative.DesignContext;
+
+/**
+ * Test cases for checking that writing a component hierarchy with null root
+ * produces an html document that has no elements in the html body.
+ */
+public class TestWriteEmptyDesign extends TestCase {
+
+ public void testWriteComponent() throws IOException {
+ OutputStream os = new ByteArrayOutputStream();
+ Design.write((Component) null, os);
+ checkHtml(os.toString());
+ }
+
+ public void testWriteContext() throws IOException {
+ OutputStream os = new ByteArrayOutputStream();
+ DesignContext ctx = new DesignContext();
+ ctx.setRootComponent(null);
+ Design.write(ctx, os);
+ checkHtml(os.toString());
+ }
+
+ private void checkHtml(String html) {
+ Document doc = Jsoup.parse(html);
+ Element body = doc.body();
+ assertEquals("There should be no elements in the html body.", "",
+ body.html());
+ }
+}
\ No newline at end of file