Repository: wicket Updated Branches: refs/heads/wicket-6.x 7b6b88883 -> bc62f8cca
WICKET-5580 Allow markup to find child fragments when wicket:child is inside a component tag Project: http://git-wip-us.apache.org/repos/asf/wicket/repo Commit: http://git-wip-us.apache.org/repos/asf/wicket/commit/bc62f8cc Tree: http://git-wip-us.apache.org/repos/asf/wicket/tree/bc62f8cc Diff: http://git-wip-us.apache.org/repos/asf/wicket/diff/bc62f8cc Branch: refs/heads/wicket-6.x Commit: bc62f8cca03573160514444291513899211dae7e Parents: 7b6b888 Author: Martin Tzvetanov Grigorov <mgrigo...@apache.org> Authored: Mon May 26 20:45:58 2014 +0200 Committer: Martin Tzvetanov Grigorov <mgrigo...@apache.org> Committed: Mon May 26 20:45:58 2014 +0200 ---------------------------------------------------------------------- .../wicket/markup/AbstractMarkupFragment.java | 117 ++++++++++++++ .../java/org/apache/wicket/markup/Markup.java | 33 +--- .../apache/wicket/markup/MarkupFragment.java | 36 +---- .../org/apache/wicket/markup/MarkupTest.java | 161 +++++++++++++++++++ .../apache/wicket/markup/MarkupTest_Find_1.html | 68 ++++++++ .../apache/wicket/markup/MarkupTest_Find_1.java | 24 +++ .../apache/wicket/markup/MarkupTest_Find_2.html | 60 +++++++ .../apache/wicket/markup/MarkupTest_Find_2.java | 22 +++ .../apache/wicket/markup/MarkupTest_Find_3.html | 49 ++++++ .../apache/wicket/markup/MarkupTest_Find_3.java | 22 +++ 10 files changed, 527 insertions(+), 65 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/wicket/blob/bc62f8cc/wicket-core/src/main/java/org/apache/wicket/markup/AbstractMarkupFragment.java ---------------------------------------------------------------------- diff --git a/wicket-core/src/main/java/org/apache/wicket/markup/AbstractMarkupFragment.java b/wicket-core/src/main/java/org/apache/wicket/markup/AbstractMarkupFragment.java new file mode 100644 index 0000000..d990db2 --- /dev/null +++ b/wicket-core/src/main/java/org/apache/wicket/markup/AbstractMarkupFragment.java @@ -0,0 +1,117 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.wicket.markup; + +import java.util.Deque; +import java.util.LinkedList; +import org.apache.wicket.util.lang.Args; + +/** + * A base implementation of {@link IMarkupFragment}. + */ +public abstract class AbstractMarkupFragment implements IMarkupFragment +{ + /** + * Find the markup fragment of component with id equal to {@code id}, starting at offset {@code streamOffset}. + * + * @param id + * The id of the component tag being searched for. + * @param streamOffset + * The offset in the markup stream from which to start searching. + * @return the {@link IMarkupFragment} of the component tag if found, {@code null} is not found. + */ + protected final IMarkupFragment find(final String id, int streamOffset) + { + /* + * We need streamOffset because MarkupFragment starts searching from offset 1. + */ + Args.notEmpty(id, "id"); + Args.withinRange(0, size() - 1, streamOffset, "streamOffset"); + + Deque<Boolean> openTagUsability = new LinkedList<Boolean>(); + boolean canFind = true; + + MarkupStream stream = new MarkupStream(this); + stream.setCurrentIndex(streamOffset); + while (stream.hasMore()) + { + MarkupElement elem = stream.get(); + + if (elem instanceof ComponentTag) + { + ComponentTag tag = stream.getTag(); + + if (tag.isOpen() || tag.isOpenClose()) + { + if (canFind && tag.getId().equals(id)) + { + return stream.getMarkupFragment(); + } + else if (tag.isOpen() && !tag.hasNoCloseTag()) + { + openTagUsability.push(canFind); + + if (tag instanceof WicketTag) + { + WicketTag wtag = (WicketTag)tag; + + if (wtag.isExtendTag()) + { + canFind = true; + } + else if (wtag.isFragementTag()) + { + canFind = false; + } + /* + * We should potentially also not try find child markup inside some other + * Wicket tags. Other tags that we should think about refusing to look for + * child markup inside include: container, body, border, child (we already + * have special extend handling). + */ + } + else if (!"head".equals(tag.getName()) && !tag.isAutoComponentTag()) + { + canFind = false; + } + } + } + else if (tag.isClose()) + { + if (openTagUsability.isEmpty()) + { + canFind = false; + } + else + { + canFind = openTagUsability.pop(); + } + } + } + + stream.next(); + } + + return null; + } + + @Override + public String toString() + { + return toString(false); + } +} http://git-wip-us.apache.org/repos/asf/wicket/blob/bc62f8cc/wicket-core/src/main/java/org/apache/wicket/markup/Markup.java ---------------------------------------------------------------------- diff --git a/wicket-core/src/main/java/org/apache/wicket/markup/Markup.java b/wicket-core/src/main/java/org/apache/wicket/markup/Markup.java index 3bc2f39..2808e42 100644 --- a/wicket-core/src/main/java/org/apache/wicket/markup/Markup.java +++ b/wicket-core/src/main/java/org/apache/wicket/markup/Markup.java @@ -39,10 +39,8 @@ import org.slf4j.LoggerFactory; * * @author Juergen Donnerstag */ -public class Markup implements IMarkupFragment +public class Markup extends AbstractMarkupFragment { - private static final Logger log = LoggerFactory.getLogger(Markup.class); - /** Placeholder that indicates no markup */ public static final Markup NO_MARKUP = new Markup(); @@ -211,34 +209,7 @@ public class Markup implements IMarkupFragment @Override public final IMarkupFragment find(final String id) { - Args.notEmpty(id, "id"); - - MarkupStream stream = new MarkupStream(this); - stream.setCurrentIndex(0); - while (stream.hasMore()) - { - MarkupElement elem = stream.get(); - if (elem instanceof ComponentTag) - { - ComponentTag tag = stream.getTag(); - if (tag.isOpen() || tag.isOpenClose()) - { - if (tag.getId().equals(id)) - { - return stream.getMarkupFragment(); - } - if (tag.isOpen() && !tag.hasNoCloseTag() && !(tag instanceof WicketTag) && - !"head".equals(tag.getName()) && !tag.isAutoComponentTag()) - { - stream.skipToMatchingCloseTag(tag); - } - } - } - - stream.next(); - } - - return null; + return find(id, 0); } @Override http://git-wip-us.apache.org/repos/asf/wicket/blob/bc62f8cc/wicket-core/src/main/java/org/apache/wicket/markup/MarkupFragment.java ---------------------------------------------------------------------- diff --git a/wicket-core/src/main/java/org/apache/wicket/markup/MarkupFragment.java b/wicket-core/src/main/java/org/apache/wicket/markup/MarkupFragment.java index 35c434f..263adc6 100644 --- a/wicket-core/src/main/java/org/apache/wicket/markup/MarkupFragment.java +++ b/wicket-core/src/main/java/org/apache/wicket/markup/MarkupFragment.java @@ -36,7 +36,7 @@ import org.apache.wicket.util.string.AppendingStringBuffer; * * @author Juergen Donnerstag */ -public class MarkupFragment implements IMarkupFragment +public class MarkupFragment extends AbstractMarkupFragment { /** The parent markup. Must not be null. */ private final IMarkupFragment markup; @@ -147,33 +147,7 @@ public class MarkupFragment implements IMarkupFragment @Override public final IMarkupFragment find(final String id) { - Args.notEmpty(id, "id"); - - MarkupStream stream = new MarkupStream(this); - stream.setCurrentIndex(1); - while (stream.hasMore()) - { - MarkupElement elem = stream.get(); - if (elem instanceof ComponentTag) - { - ComponentTag tag = stream.getTag(); - if (tag.isOpen() || tag.isOpenClose()) - { - if (tag.getId().equals(id)) - { - return stream.getMarkupFragment(); - } - if (tag.isOpen() && !tag.hasNoCloseTag() && !tag.isAutoComponentTag()) - { - stream.skipToMatchingCloseTag(tag); - } - } - } - - stream.next(); - } - - return null; + return find(id, 1); } @Override @@ -210,12 +184,6 @@ public class MarkupFragment implements IMarkupFragment } @Override - public String toString() - { - return toString(false); - } - - @Override public String toString(boolean markupOnly) { final AppendingStringBuffer buf = new AppendingStringBuffer(400); http://git-wip-us.apache.org/repos/asf/wicket/blob/bc62f8cc/wicket-core/src/test/java/org/apache/wicket/markup/MarkupTest.java ---------------------------------------------------------------------- diff --git a/wicket-core/src/test/java/org/apache/wicket/markup/MarkupTest.java b/wicket-core/src/test/java/org/apache/wicket/markup/MarkupTest.java new file mode 100644 index 0000000..751be1a --- /dev/null +++ b/wicket-core/src/test/java/org/apache/wicket/markup/MarkupTest.java @@ -0,0 +1,161 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.wicket.markup; + +import org.apache.wicket.WicketTestCase; +import org.junit.Test; + +/** + * Tests {@link Markup} class. + */ +public class MarkupTest extends WicketTestCase +{ + @Test + public void testFind() + { + MarkupFactory markupFactory = tester.getApplication().getMarkupSettings().getMarkupFactory(); + Markup markup = markupFactory.getMarkup(new MarkupTest_Find_3(), false); + + IMarkupFragment childMarkup; + + /* + * Ensure we can find inside <head> + */ + childMarkup = markup.find("a1"); + assertNotNull(childMarkup); + assertTrue(childMarkup.get(0) instanceof ComponentTag); + assertEquals("a1", ((ComponentTag)childMarkup.get(0)).getId()); + + /* + * Ensure we can find in body + */ + childMarkup = markup.find("a2"); + assertNotNull(childMarkup); + assertTrue(childMarkup.get(0) instanceof ComponentTag); + assertEquals("a2", ((ComponentTag)childMarkup.get(0)).getId()); + + /* + * Ensure we cannot find inside component tag + */ + assertNull(markup.find("a3")); + + /* + * Ensure we can find after other component tag + */ + childMarkup = markup.find("a4"); + assertNotNull(childMarkup); + assertTrue(childMarkup.get(0) instanceof ComponentTag); + assertEquals("a4", ((ComponentTag)childMarkup.get(0)).getId()); + + /* + * Ensure we can find after wicket:child + */ + childMarkup = markup.find("a5"); + assertNotNull(childMarkup); + assertTrue(childMarkup.get(0) instanceof ComponentTag); + assertEquals("a5", ((ComponentTag)childMarkup.get(0)).getId()); + + /* + * Ensure we can find after fragment + */ + childMarkup = markup.find("a6"); + assertNotNull(childMarkup); + assertTrue(childMarkup.get(0) instanceof WicketTag); + assertEquals("a6", ((ComponentTag)childMarkup.get(0)).getId()); + assertTrue(((WicketTag)childMarkup.get(0)).isFragementTag()); + + /* + * Ensure we cannot find inside fragment + */ + assertNull(markup.find("a7")); + + /* + * Ensure we can find in subclass <wicket:head> section + */ + childMarkup = markup.find("b1"); + assertNotNull(childMarkup); + assertTrue(childMarkup.get(0) instanceof ComponentTag); + assertEquals("b1", ((ComponentTag)childMarkup.get(0)).getId()); + + /* + * Ensure we can find fragment in subclass + */ + childMarkup = markup.find("b2"); + assertNotNull(childMarkup); + assertTrue(childMarkup.get(0) instanceof WicketTag); + assertEquals("b2", ((ComponentTag)childMarkup.get(0)).getId()); + assertTrue(((WicketTag)childMarkup.get(0)).isFragementTag()); + + /* + * Ensure we cannot find inside fragment in subclass + */ + assertNull(markup.find("b3")); + + /* + * Ensure we can find in subclass <wicket:extend> section + */ + childMarkup = markup.find("b4"); + assertNotNull(childMarkup); + assertTrue(childMarkup.get(0) instanceof ComponentTag); + assertEquals("b4", ((ComponentTag)childMarkup.get(0)).getId()); + + /* + * Ensure we cannot find inside component tag in subclass + */ + assertNull(markup.find("b5")); + + /* + * Ensure we cannot find inside component tag in subclass after wicket:child + */ + assertNull(markup.find("b6")); + + /* + * Ensure we can find in subclass <wicket:head> section + */ + childMarkup = markup.find("c1"); + assertNotNull(childMarkup); + assertTrue(childMarkup.get(0) instanceof ComponentTag); + assertEquals("c1", ((ComponentTag)childMarkup.get(0)).getId()); + + /* + * Ensure we can find fragment in subclass + */ + childMarkup = markup.find("c2"); + assertNotNull(childMarkup); + assertTrue(childMarkup.get(0) instanceof WicketTag); + assertEquals("c2", ((ComponentTag)childMarkup.get(0)).getId()); + assertTrue(((WicketTag)childMarkup.get(0)).isFragementTag()); + + /* + * Ensure we cannot find inside fragment in subclass + */ + assertNull(markup.find("c3")); + + /* + * Ensure we can find in subclass <wicket:extend> section + */ + childMarkup = markup.find("c4"); + assertNotNull(childMarkup); + assertTrue(childMarkup.get(0) instanceof ComponentTag); + assertEquals("c4", ((ComponentTag)childMarkup.get(0)).getId()); + + /* + * Ensure we cannot find inside component tag in subclass + */ + assertNull(markup.find("c5")); + } +} http://git-wip-us.apache.org/repos/asf/wicket/blob/bc62f8cc/wicket-core/src/test/java/org/apache/wicket/markup/MarkupTest_Find_1.html ---------------------------------------------------------------------- diff --git a/wicket-core/src/test/java/org/apache/wicket/markup/MarkupTest_Find_1.html b/wicket-core/src/test/java/org/apache/wicket/markup/MarkupTest_Find_1.html new file mode 100644 index 0000000..6bcadc4 --- /dev/null +++ b/wicket-core/src/test/java/org/apache/wicket/markup/MarkupTest_Find_1.html @@ -0,0 +1,68 @@ +<!-- + 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. +--> +<html> + <head> + <meta wicket:id="a1"> + </head> + <body> + <!-- + Test that we correctly find after open-no-close + --> + <input type="text" wicket:id="textfield"> + + <!-- + Test that we correctly find after open-close + --> + <div wicket:id="openClose"/> + + <!-- + Test finding in body (normal) + --> + <div wicket:id="a2"> + <!-- + Test that we do not find d3 inside another component tag + --> + <div wicket:id="a3"> + </div> + </div> + + <!-- + Test after component + --> + <span wicket:id="a4"></span> + + <div> + <wicket:child/> + </div> + + <!-- + Test after wicket:child + --> + <span wicket:id="a5"></span> + + <!-- + Test find fragment + --> + <wicket:fragment wicket:id="a6"> + + <!-- + Test not find inside fragment + --> + <div wicket:id="a7"> + + </div> + + </wicket:fragment> +</body> +</html> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/wicket/blob/bc62f8cc/wicket-core/src/test/java/org/apache/wicket/markup/MarkupTest_Find_1.java ---------------------------------------------------------------------- diff --git a/wicket-core/src/test/java/org/apache/wicket/markup/MarkupTest_Find_1.java b/wicket-core/src/test/java/org/apache/wicket/markup/MarkupTest_Find_1.java new file mode 100644 index 0000000..f215512 --- /dev/null +++ b/wicket-core/src/test/java/org/apache/wicket/markup/MarkupTest_Find_1.java @@ -0,0 +1,24 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.wicket.markup; + +import org.apache.wicket.markup.html.WebPage; + +public class MarkupTest_Find_1 extends WebPage +{ + +} http://git-wip-us.apache.org/repos/asf/wicket/blob/bc62f8cc/wicket-core/src/test/java/org/apache/wicket/markup/MarkupTest_Find_2.html ---------------------------------------------------------------------- diff --git a/wicket-core/src/test/java/org/apache/wicket/markup/MarkupTest_Find_2.html b/wicket-core/src/test/java/org/apache/wicket/markup/MarkupTest_Find_2.html new file mode 100644 index 0000000..a0fa950 --- /dev/null +++ b/wicket-core/src/test/java/org/apache/wicket/markup/MarkupTest_Find_2.html @@ -0,0 +1,60 @@ +<!-- + 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. +--> +<html> + <wicket:head> + <!-- + Test find in wicket:head of subclass + --> + <link wicket:id="b1"> + </wicket:head> + + <wicket:extend> + + <!-- + test find fragment in subclass + --> + <wicket:fragment wicket:id="b2"> + + Something here + <!-- + Test not find in fragment in subclass + --> + <span wicket:id="b3">hhh</span> + + </wicket:fragment> + + <!-- + Test find in subclass + --> + <div wicket:id="b4"> + + <!-- + Test not find inside component tag in sub class + --> + <div wicket:id="b5"></div> + + <!-- + Notice that <wicket:child> is inside component tag. We must still be able to find + components inside <wicket:extend> of subclass. + --> + <wicket:child/> + + <!-- + Test not find inside component tag after wicket:child + --> + <div wicket:id="b6"></div> + </div> + + </wicket:extend> +</html> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/wicket/blob/bc62f8cc/wicket-core/src/test/java/org/apache/wicket/markup/MarkupTest_Find_2.java ---------------------------------------------------------------------- diff --git a/wicket-core/src/test/java/org/apache/wicket/markup/MarkupTest_Find_2.java b/wicket-core/src/test/java/org/apache/wicket/markup/MarkupTest_Find_2.java new file mode 100644 index 0000000..26d54bc --- /dev/null +++ b/wicket-core/src/test/java/org/apache/wicket/markup/MarkupTest_Find_2.java @@ -0,0 +1,22 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.wicket.markup; + +public class MarkupTest_Find_2 extends MarkupTest_Find_1 +{ + +} http://git-wip-us.apache.org/repos/asf/wicket/blob/bc62f8cc/wicket-core/src/test/java/org/apache/wicket/markup/MarkupTest_Find_3.html ---------------------------------------------------------------------- diff --git a/wicket-core/src/test/java/org/apache/wicket/markup/MarkupTest_Find_3.html b/wicket-core/src/test/java/org/apache/wicket/markup/MarkupTest_Find_3.html new file mode 100644 index 0000000..83f3e98 --- /dev/null +++ b/wicket-core/src/test/java/org/apache/wicket/markup/MarkupTest_Find_3.html @@ -0,0 +1,49 @@ +<!-- + 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. +--> +<html> + <wicket:head> + <!-- + Test find in wicket:head of subclass + --> + <link wicket:id="c1"> + </wicket:head> + + <wicket:extend> + + <!-- + test find fragment in subclass + --> + <wicket:fragment wicket:id="c2"> + + Something here + <!-- + Test not find in fragment in subclass + --> + <span wicket:id="c3">hhh</span> + + </wicket:fragment> + + <!-- + Test find in subclass + --> + <div wicket:id="c4"> + + <!-- + Test not find inside component tag in sub class + --> + <div wicket:id="b5"></div> + </div> + + </wicket:extend> +</html> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/wicket/blob/bc62f8cc/wicket-core/src/test/java/org/apache/wicket/markup/MarkupTest_Find_3.java ---------------------------------------------------------------------- diff --git a/wicket-core/src/test/java/org/apache/wicket/markup/MarkupTest_Find_3.java b/wicket-core/src/test/java/org/apache/wicket/markup/MarkupTest_Find_3.java new file mode 100644 index 0000000..9b71872 --- /dev/null +++ b/wicket-core/src/test/java/org/apache/wicket/markup/MarkupTest_Find_3.java @@ -0,0 +1,22 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.wicket.markup; + +public class MarkupTest_Find_3 extends MarkupTest_Find_2 +{ + +}