diff options
author | Artur Signell <artur@vaadin.com> | 2016-07-11 16:05:30 +0300 |
---|---|---|
committer | Vaadin Code Review <review@vaadin.com> | 2016-07-13 07:29:11 +0000 |
commit | 94ae194409ea2be4afa2b571338e4e9c7b5a3732 (patch) | |
tree | 280071f636e24c1ade5299e81252bd88a5d886c9 | |
parent | 3b30b65e9401a7aee6604c0d0dd5eebe62ba508b (diff) | |
download | vaadin-framework-94ae194409ea2be4afa2b571338e4e9c7b5a3732.tar.gz vaadin-framework-94ae194409ea2be4afa2b571338e4e9c7b5a3732.zip |
Support static inner classes when reading/writing declarative files (#20038)
Uses outer class name as package name for static inner classes. When reading,
there is no way to know that the class is an inner class so only when creating
a class fails, an inner class is tried as a backup.
Change-Id: I3ebf5b2da11384f9dc64072a3dc8ee132607237c
3 files changed, 76 insertions, 4 deletions
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 5ce1f5dc60..a12cd65557 100644 --- a/server/src/main/java/com/vaadin/ui/declarative/Design.java +++ b/server/src/main/java/com/vaadin/ui/declarative/Design.java @@ -22,6 +22,7 @@ import java.io.OutputStream; import java.io.Serializable; import java.lang.annotation.Annotation; import java.util.Collection; +import java.util.Locale; import java.util.logging.Level; import java.util.logging.Logger; @@ -146,9 +147,24 @@ public class Design implements Serializable { @Override public Component createComponent(String fullyQualifiedClassName, DesignContext context) { - Class<? extends Component> componentClass = resolveComponentClass( - fullyQualifiedClassName, context); + Class<? extends Component> componentClass; + try { + componentClass = resolveComponentClass(fullyQualifiedClassName, + context); + } catch (DesignException e) { + // Try with an inner class. + int lastDot = fullyQualifiedClassName.lastIndexOf('.'); + if (lastDot != -1) { + String qualifiedInnerClassName = fullyQualifiedClassName + .substring(0, lastDot) + + "$" + + fullyQualifiedClassName.substring(lastDot + 1); + return createComponent(qualifiedInnerClassName, context); + } else { + throw e; + } + } assert Component.class.isAssignableFrom(componentClass) : "resolveComponentClass returned " + componentClass + " which is not a Vaadin Component class"; @@ -234,10 +250,11 @@ public class Design implements Serializable { @Override public String componentToTag(Component component, DesignContext context) { Class<?> componentClass = component.getClass(); - String packageName = componentClass.getPackage().getName(); + String packageName = getPackageName(componentClass); String prefix = context.getPackagePrefix(packageName); if (prefix == null) { - prefix = packageName.replace('.', '_'); + prefix = packageName.replace('.', '_').toLowerCase( + Locale.ENGLISH); context.addPackagePrefix(prefix, packageName); } prefix = prefix + "-"; @@ -248,6 +265,16 @@ public class Design implements Serializable { return tagName; } + private String getPackageName(Class<?> componentClass) { + if (componentClass.isMemberClass()) { + Class<?> enclosingClass = componentClass.getEnclosingClass(); + return getPackageName(enclosingClass) + "." + + enclosingClass.getSimpleName(); + } else { + return componentClass.getPackage().getName(); + } + } + /** * Creates the name of the html tag corresponding to the given class * name. The name is derived by converting each uppercase letter to diff --git a/server/src/test/java/com/vaadin/tests/design/InnerClassDesignReadWriteTest.java b/server/src/test/java/com/vaadin/tests/design/InnerClassDesignReadWriteTest.java new file mode 100644 index 0000000000..e42a89e98d --- /dev/null +++ b/server/src/test/java/com/vaadin/tests/design/InnerClassDesignReadWriteTest.java @@ -0,0 +1,38 @@ +package com.vaadin.tests.design; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; + +import org.junit.Test; + +import com.vaadin.tests.design.InnerClassDesignReadWriteTest.Foo.StaticInnerInner; +import com.vaadin.tests.design.UPPERCASE.InUpperCasePackage; +import com.vaadin.ui.GridLayout; +import com.vaadin.ui.HorizontalLayout; +import com.vaadin.ui.VerticalLayout; +import com.vaadin.ui.declarative.Design; + +public class InnerClassDesignReadWriteTest { + @Test + public void testWritingAndReadingBackInnerClass() throws IOException { + VerticalLayout vl = new VerticalLayout(); + vl.addComponent(new StaticInner()); + vl.addComponent(new StaticInnerInner()); + vl.addComponent(new InUpperCasePackage()); + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + Design.write(vl, baos); + Design.read(new ByteArrayInputStream(baos.toByteArray())); + } + + public static class StaticInner extends GridLayout { + } + + public static class Foo { + public static class StaticInnerInner extends HorizontalLayout { + + } + } + +} diff --git a/server/src/test/java/com/vaadin/tests/design/UPPERCASE/InUpperCasePackage.java b/server/src/test/java/com/vaadin/tests/design/UPPERCASE/InUpperCasePackage.java new file mode 100644 index 0000000000..255581d9f3 --- /dev/null +++ b/server/src/test/java/com/vaadin/tests/design/UPPERCASE/InUpperCasePackage.java @@ -0,0 +1,7 @@ +package com.vaadin.tests.design.UPPERCASE; + +import com.vaadin.ui.VerticalLayout; + +public class InUpperCasePackage extends VerticalLayout { + +}
\ No newline at end of file |