Updated Branches: refs/heads/markup-driven-component-tree [created] 6ba324dba
Trivial POC of markup-driven component tree Project: http://git-wip-us.apache.org/repos/asf/wicket/repo Commit: http://git-wip-us.apache.org/repos/asf/wicket/commit/6ba324db Tree: http://git-wip-us.apache.org/repos/asf/wicket/tree/6ba324db Diff: http://git-wip-us.apache.org/repos/asf/wicket/diff/6ba324db Branch: refs/heads/markup-driven-component-tree Commit: 6ba324dba2eab841cedc5426f4560946f8688b10 Parents: 7a21d81 Author: Martin Tzvetanov Grigorov <[email protected]> Authored: Thu Jan 23 11:08:58 2014 +0200 Committer: Martin Tzvetanov Grigorov <[email protected]> Committed: Thu Jan 23 11:08:58 2014 +0200 ---------------------------------------------------------------------- .../src/main/java/org/apache/wicket/Auto.java | 13 ++ .../org/apache/wicket/ComponentTreeBuilder.java | 126 +++++++++++++++++++ .../src/main/java/org/apache/wicket/Page.java | 10 ++ .../org/apache/wicket/markup/ComponentTag.java | 4 +- .../wicket/markupdriventree/BasePage.java | 20 +++ .../markupdriventree/MarkupDrivenTreeTest.java | 41 ++++++ .../apache/wicket/markupdriventree/Page1.html | 24 ++++ .../apache/wicket/markupdriventree/Page1.java | 8 ++ .../apache/wicket/markupdriventree/Page2.html | 24 ++++ .../apache/wicket/markupdriventree/Page2.java | 8 ++ .../apache/wicket/markupdriventree/Page3.html | 26 ++++ .../apache/wicket/markupdriventree/Page3.java | 8 ++ 12 files changed, 310 insertions(+), 2 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/wicket/blob/6ba324db/wicket-core/src/main/java/org/apache/wicket/Auto.java ---------------------------------------------------------------------- diff --git a/wicket-core/src/main/java/org/apache/wicket/Auto.java b/wicket-core/src/main/java/org/apache/wicket/Auto.java new file mode 100644 index 0000000..3c3b6ab --- /dev/null +++ b/wicket-core/src/main/java/org/apache/wicket/Auto.java @@ -0,0 +1,13 @@ +package org.apache.wicket; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * + */ +@Retention(RetentionPolicy.RUNTIME) +public @interface Auto +{ + String id() default ""; +} http://git-wip-us.apache.org/repos/asf/wicket/blob/6ba324db/wicket-core/src/main/java/org/apache/wicket/ComponentTreeBuilder.java ---------------------------------------------------------------------- diff --git a/wicket-core/src/main/java/org/apache/wicket/ComponentTreeBuilder.java b/wicket-core/src/main/java/org/apache/wicket/ComponentTreeBuilder.java new file mode 100644 index 0000000..0b14ae7 --- /dev/null +++ b/wicket-core/src/main/java/org/apache/wicket/ComponentTreeBuilder.java @@ -0,0 +1,126 @@ +package org.apache.wicket; + +import java.lang.reflect.Field; +import java.util.Iterator; + +import org.apache.wicket.markup.ComponentTag; +import org.apache.wicket.markup.IMarkupFragment; +import org.apache.wicket.markup.MarkupElement; + +/** + * + */ +class ComponentTreeBuilder +{ + void rebuild(Page page) + { + MarkupContainer cursor = page; + + boolean entered = false; + + IMarkupFragment markup = page.getMarkup(); + Iterator<MarkupElement> markupElementIterator = markup.iterator(); + while (markupElementIterator.hasNext()) + { + MarkupElement element = markupElementIterator.next(); + + if (element instanceof ComponentTag) + { + ComponentTag tag = (ComponentTag) element; + + if (!tag.isAutoComponentTag() && (tag.isOpen() || tag.isOpenClose())) + { + + String componentId = tag.getId(); + Component component = cursor.get(componentId); + if (component == null) + { + try + { + component = findAutoAnnotatedComponent(cursor, componentId); + + if (component instanceof MarkupContainer) + { + cursor.add(component); + + entered = true; + cursor = (MarkupContainer) component; + } + + } catch (Exception e) + { + throw new WicketRuntimeException(e); + } + } + + print(tag); + } + else if (entered && tag.isClose()) + { + entered = false; + cursor = cursor.getParent(); + } + } + + } + } + + /** + * Searches for a member field that is a Component with the expected component id + * + * @param cursor + * @param componentId + * @return + * @throws IllegalAccessException + */ + private Component findAutoAnnotatedComponent(MarkupContainer cursor, String componentId) throws IllegalAccessException + { + if (cursor == null) + { + return null; + } + + Class<?> cursorClass = cursor.getClass(); + + while (cursorClass != null) + { + for (Field field : cursorClass.getDeclaredFields()) + { + Auto annotation = field.getAnnotation(Auto.class); + if (annotation != null) + { + String annId = annotation.id(); + if (componentId.equals(annId) || componentId.equals(field.getName())) + { + boolean accessible = field.isAccessible(); + try + { + field.setAccessible(true); + return (Component) field.get(cursor); + } + finally + { + field.setAccessible(accessible); + } + + } + } + } + + cursorClass = cursorClass.getSuperclass(); + } + + return findAutoAnnotatedComponent(cursor.getParent(), componentId); + } + + private void print(ComponentTag tag) + { + System.err.println("tag: id=" + tag.getId() + + "\n\t\topen=" + tag.isOpen() + + "\n\t\tclose=" + tag.isClose() + + "\n\t\topenclose=" + tag.isOpenClose() + + "\n\t\tautoLinkEnabled=" + tag.isAutolinkEnabled() + + "\n\t\tauto=" + tag.isAutoComponentTag()); + + } +} http://git-wip-us.apache.org/repos/asf/wicket/blob/6ba324db/wicket-core/src/main/java/org/apache/wicket/Page.java ---------------------------------------------------------------------- diff --git a/wicket-core/src/main/java/org/apache/wicket/Page.java b/wicket-core/src/main/java/org/apache/wicket/Page.java index 6d1dd44..bb9222a 100644 --- a/wicket-core/src/main/java/org/apache/wicket/Page.java +++ b/wicket-core/src/main/java/org/apache/wicket/Page.java @@ -24,6 +24,8 @@ import java.util.Set; import org.apache.wicket.authorization.UnauthorizedActionException; import org.apache.wicket.core.util.lang.WicketObjects; +import org.apache.wicket.markup.IMarkupFragment; +import org.apache.wicket.markup.MarkupElement; import org.apache.wicket.markup.MarkupException; import org.apache.wicket.markup.MarkupStream; import org.apache.wicket.markup.MarkupType; @@ -294,12 +296,20 @@ public abstract class Page extends MarkupContainer implements IRedirectListener, @Override protected void onInitialize() { + constructComponentTree(); + super.onInitialize(); final IPageManager pageManager = getSession().getPageManager(); pageManager.touchPage(this); } + private void constructComponentTree() + { + ComponentTreeBuilder builder = new ComponentTreeBuilder(); + builder.rebuild(this); + } + /** * THIS METHOD IS NOT PART OF THE WICKET PUBLIC API. DO NOT CALL. * http://git-wip-us.apache.org/repos/asf/wicket/blob/6ba324db/wicket-core/src/main/java/org/apache/wicket/markup/ComponentTag.java ---------------------------------------------------------------------- diff --git a/wicket-core/src/main/java/org/apache/wicket/markup/ComponentTag.java b/wicket-core/src/main/java/org/apache/wicket/markup/ComponentTag.java index d387368..f28e5f0 100644 --- a/wicket-core/src/main/java/org/apache/wicket/markup/ComponentTag.java +++ b/wicket-core/src/main/java/org/apache/wicket/markup/ComponentTag.java @@ -64,13 +64,13 @@ public class ComponentTag extends MarkupElement /** If true, then the tag contain an automatically created wicket id */ private final static int AUTO_COMPONENT = 0x0008; - /** Some HTML tags are allow to have no close tag, e.g. 'br' */ + /** Some HTML tags are allowed to have no close tag, e.g. 'br' */ private final static int NO_CLOSE_TAG = 0x0010; /** Render the tag as RawMarkup even if no Component can be found */ public final static int RENDER_RAW = 0x0020; - /** If close tag, than reference to the corresponding open tag */ + /** If close tag, then reference to the corresponding open tag */ private ComponentTag openTag; /** The underlying xml tag */ http://git-wip-us.apache.org/repos/asf/wicket/blob/6ba324db/wicket-core/src/test/java/org/apache/wicket/markupdriventree/BasePage.java ---------------------------------------------------------------------- diff --git a/wicket-core/src/test/java/org/apache/wicket/markupdriventree/BasePage.java b/wicket-core/src/test/java/org/apache/wicket/markupdriventree/BasePage.java new file mode 100644 index 0000000..1acd6d9 --- /dev/null +++ b/wicket-core/src/test/java/org/apache/wicket/markupdriventree/BasePage.java @@ -0,0 +1,20 @@ +package org.apache.wicket.markupdriventree; + +import org.apache.wicket.Auto; +import org.apache.wicket.markup.html.WebMarkupContainer; +import org.apache.wicket.markup.html.WebPage; + +public class BasePage extends WebPage { + + @Auto + WebMarkupContainer a, b, c; + + public BasePage() + { + super(); + + a = new WebMarkupContainer("a"); + b = new WebMarkupContainer("b"); + c = new WebMarkupContainer("c"); + } +} http://git-wip-us.apache.org/repos/asf/wicket/blob/6ba324db/wicket-core/src/test/java/org/apache/wicket/markupdriventree/MarkupDrivenTreeTest.java ---------------------------------------------------------------------- diff --git a/wicket-core/src/test/java/org/apache/wicket/markupdriventree/MarkupDrivenTreeTest.java b/wicket-core/src/test/java/org/apache/wicket/markupdriventree/MarkupDrivenTreeTest.java new file mode 100644 index 0000000..8e4fc9e --- /dev/null +++ b/wicket-core/src/test/java/org/apache/wicket/markupdriventree/MarkupDrivenTreeTest.java @@ -0,0 +1,41 @@ +package org.apache.wicket.markupdriventree; + +import org.apache.wicket.WicketTestCase; +import org.apache.wicket.markup.html.WebMarkupContainer; +import org.junit.Test; + +/** + * + */ +public class MarkupDrivenTreeTest extends WicketTestCase +{ + @Test + public void page1() + { + tester.startPage(Page1.class); + + tester.assertComponent("a", WebMarkupContainer.class); + tester.assertComponent("a:b", WebMarkupContainer.class); + tester.assertComponent("a:b:c", WebMarkupContainer.class); + } + + @Test + public void page2() + { + tester.startPage(Page2.class); + + tester.assertComponent("c", WebMarkupContainer.class); + tester.assertComponent("c:b", WebMarkupContainer.class); + tester.assertComponent("c:b:a", WebMarkupContainer.class); + } + + @Test + public void page3() + { + tester.startPage(Page3.class); + + tester.assertComponent("c", WebMarkupContainer.class); + tester.assertComponent("b", WebMarkupContainer.class); + tester.assertComponent("b:a", WebMarkupContainer.class); + } +} http://git-wip-us.apache.org/repos/asf/wicket/blob/6ba324db/wicket-core/src/test/java/org/apache/wicket/markupdriventree/Page1.html ---------------------------------------------------------------------- diff --git a/wicket-core/src/test/java/org/apache/wicket/markupdriventree/Page1.html b/wicket-core/src/test/java/org/apache/wicket/markupdriventree/Page1.html new file mode 100644 index 0000000..ead6c68 --- /dev/null +++ b/wicket-core/src/test/java/org/apache/wicket/markupdriventree/Page1.html @@ -0,0 +1,24 @@ +<!DOCTYPE html> +<html xmlns:wicket="http://wicket.apache.org"> + <head> + <meta charset="utf-8" /> + <title>Page1</title> + </head> + <body> + <div id="hd"> + <div id="logo"> + <img src="logo.png" width="50px" height="50px" alt="Wicket Logo" /> + <h1>Apache Wicket</h1> + </div> + </div> + <div id="bd"> + + <div wicket:id="a"> + <div wicket:id="b"> + <div wicket:id="c"></div> + </div> + </div> + </div> + + </body> +</html> http://git-wip-us.apache.org/repos/asf/wicket/blob/6ba324db/wicket-core/src/test/java/org/apache/wicket/markupdriventree/Page1.java ---------------------------------------------------------------------- diff --git a/wicket-core/src/test/java/org/apache/wicket/markupdriventree/Page1.java b/wicket-core/src/test/java/org/apache/wicket/markupdriventree/Page1.java new file mode 100644 index 0000000..52e0ef2 --- /dev/null +++ b/wicket-core/src/test/java/org/apache/wicket/markupdriventree/Page1.java @@ -0,0 +1,8 @@ +package org.apache.wicket.markupdriventree; + +/** + * + */ +public class Page1 extends BasePage +{ +} http://git-wip-us.apache.org/repos/asf/wicket/blob/6ba324db/wicket-core/src/test/java/org/apache/wicket/markupdriventree/Page2.html ---------------------------------------------------------------------- diff --git a/wicket-core/src/test/java/org/apache/wicket/markupdriventree/Page2.html b/wicket-core/src/test/java/org/apache/wicket/markupdriventree/Page2.html new file mode 100644 index 0000000..396255e --- /dev/null +++ b/wicket-core/src/test/java/org/apache/wicket/markupdriventree/Page2.html @@ -0,0 +1,24 @@ +<!DOCTYPE html> +<html xmlns:wicket="http://wicket.apache.org"> + <head> + <meta charset="utf-8" /> + <title>Page1</title> + </head> + <body> + <div id="hd"> + <div id="logo"> + <img src="logo.png" width="50px" height="50px" alt="Wicket Logo" /> + <h1>Apache Wicket</h1> + </div> + </div> + <div id="bd"> + + <div wicket:id="c"> + <div wicket:id="b"> + <div wicket:id="a"></div> + </div> + </div> + </div> + + </body> +</html> http://git-wip-us.apache.org/repos/asf/wicket/blob/6ba324db/wicket-core/src/test/java/org/apache/wicket/markupdriventree/Page2.java ---------------------------------------------------------------------- diff --git a/wicket-core/src/test/java/org/apache/wicket/markupdriventree/Page2.java b/wicket-core/src/test/java/org/apache/wicket/markupdriventree/Page2.java new file mode 100644 index 0000000..7ea019d --- /dev/null +++ b/wicket-core/src/test/java/org/apache/wicket/markupdriventree/Page2.java @@ -0,0 +1,8 @@ +package org.apache.wicket.markupdriventree; + +/** + * + */ +public class Page2 extends BasePage +{ +} http://git-wip-us.apache.org/repos/asf/wicket/blob/6ba324db/wicket-core/src/test/java/org/apache/wicket/markupdriventree/Page3.html ---------------------------------------------------------------------- diff --git a/wicket-core/src/test/java/org/apache/wicket/markupdriventree/Page3.html b/wicket-core/src/test/java/org/apache/wicket/markupdriventree/Page3.html new file mode 100644 index 0000000..f381c60 --- /dev/null +++ b/wicket-core/src/test/java/org/apache/wicket/markupdriventree/Page3.html @@ -0,0 +1,26 @@ +<!DOCTYPE html> +<html xmlns:wicket="http://wicket.apache.org"> + <head> + <meta charset="utf-8" /> + <title>Page1</title> + </head> + <body> + <div id="hd"> + <div id="logo"> + <img src="logo.png" width="50px" height="50px" alt="Wicket Logo" /> + <h1>Apache Wicket</h1> + </div> + </div> + <div id="bd"> + + <div wicket:id="c"> + </div> + + <div wicket:id="b"> + <div wicket:id="a"></div> + </div> + + </div> + + </body> +</html> http://git-wip-us.apache.org/repos/asf/wicket/blob/6ba324db/wicket-core/src/test/java/org/apache/wicket/markupdriventree/Page3.java ---------------------------------------------------------------------- diff --git a/wicket-core/src/test/java/org/apache/wicket/markupdriventree/Page3.java b/wicket-core/src/test/java/org/apache/wicket/markupdriventree/Page3.java new file mode 100644 index 0000000..3fcb006 --- /dev/null +++ b/wicket-core/src/test/java/org/apache/wicket/markupdriventree/Page3.java @@ -0,0 +1,8 @@ +package org.apache.wicket.markupdriventree; + +/** + * + */ +public class Page3 extends BasePage +{ +}
