Repository: wicket Updated Branches: refs/heads/master 5a3fd0d2a -> ccff0802a
WICKET-5577 Generation of wicket ids with prefix / suffix Project: http://git-wip-us.apache.org/repos/asf/wicket/repo Commit: http://git-wip-us.apache.org/repos/asf/wicket/commit/ccff0802 Tree: http://git-wip-us.apache.org/repos/asf/wicket/tree/ccff0802 Diff: http://git-wip-us.apache.org/repos/asf/wicket/diff/ccff0802 Branch: refs/heads/master Commit: ccff0802a729bc10d84ed876ec08d408efc377af Parents: 5a3fd0d Author: Martin Tzvetanov Grigorov <[email protected]> Authored: Mon May 19 18:38:01 2014 +0300 Committer: Martin Tzvetanov Grigorov <[email protected]> Committed: Mon May 19 18:38:37 2014 +0300 ---------------------------------------------------------------------- .../main/java/org/apache/wicket/Component.java | 53 +--------- .../java/org/apache/wicket/ComponentQueue2.java | 104 ------------------- .../apache/wicket/DefaultMarkupIdGenerator.java | 80 ++++++++++++++ .../org/apache/wicket/IMarkupIdGenerator.java | 32 ++++++ .../apache/wicket/settings/MarkupSettings.java | 29 ++++++ .../apache/wicket/MarkupIdGeneratorTest.java | 73 +++++++++++++ 6 files changed, 216 insertions(+), 155 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/wicket/blob/ccff0802/wicket-core/src/main/java/org/apache/wicket/Component.java ---------------------------------------------------------------------- diff --git a/wicket-core/src/main/java/org/apache/wicket/Component.java b/wicket-core/src/main/java/org/apache/wicket/Component.java index 0e91438..eed90a7 100644 --- a/wicket-core/src/main/java/org/apache/wicket/Component.java +++ b/wicket-core/src/main/java/org/apache/wicket/Component.java @@ -1498,57 +1498,8 @@ public abstract class Component */ public String getMarkupId(boolean createIfDoesNotExist) { - Object storedMarkupId = getMarkupIdImpl(); - if (storedMarkupId instanceof String) - { - return (String)storedMarkupId; - } - - if (storedMarkupId == null && createIfDoesNotExist == false) - { - return null; - } - - int generatedMarkupId = storedMarkupId instanceof Integer ? (Integer)storedMarkupId - : getSession().nextSequenceValue(); - - if (generatedMarkupId == 0xAD) - { - // WICKET-4559 skip suffix 'ad' because some ad-blocking solutions may hide the -// component - generatedMarkupId = getSession().nextSequenceValue(); - } - - if (storedMarkupId == null) - { - setMarkupIdImpl(generatedMarkupId); - } - - String markupIdPrefix = "id"; - if (getApplication().usesDevelopmentConfig()) - { - // in non-deployment mode we make the markup id include component id - // so it is easier to debug - markupIdPrefix = getId(); - } - - String markupIdPostfix = Integer.toHexString(generatedMarkupId).toLowerCase(); - - String markupId = markupIdPrefix + markupIdPostfix; - - // make sure id is compliant with w3c requirements (starts with a letter) - char c = markupId.charAt(0); - if (!Character.isLetter(c)) - { - markupId = "id" + markupId; - } - - // escape some noncompliant characters - markupId = Strings.replaceAll(markupId, "_", "__").toString(); - markupId = markupId.replace('.', '_'); - markupId = markupId.replace('-', '_'); - markupId = markupId.replace(' ', '_'); - + IMarkupIdGenerator markupIdGenerator = getApplication().getMarkupSettings().getMarkupIdGenerator(); + String markupId = markupIdGenerator.generateMarkupId(this); return markupId; } http://git-wip-us.apache.org/repos/asf/wicket/blob/ccff0802/wicket-core/src/main/java/org/apache/wicket/ComponentQueue2.java ---------------------------------------------------------------------- diff --git a/wicket-core/src/main/java/org/apache/wicket/ComponentQueue2.java b/wicket-core/src/main/java/org/apache/wicket/ComponentQueue2.java deleted file mode 100644 index 2ce3e8f..0000000 --- a/wicket-core/src/main/java/org/apache/wicket/ComponentQueue2.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * 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; - -import java.util.HashMap; -import java.util.Map; - -import org.apache.wicket.util.lang.Args; - -/** - * Manages the component queue. - * - * @author igor - * - * @deprecated uses too much memory compared to ComponentQueue - */ -class ComponentQueue2 -{ - private static final int INITIAL = 8; - - private Map<String, Component> queue; - private int queueSize = 0; - - void add(Component... components) - { - for (Component component : components) - { - add(component); - } - } - - void add(Component component) - { - Args.notNull(component, "component"); - - if (queue == null) - { - queue = new HashMap<>(INITIAL, 1); - } - - Component old = queue.put(component.getId(), component); - if (old != null) - { - throw new WicketRuntimeException("A component with id: " + component.getId() - + " has already been queued"); - } - queueSize++; - } - - Component remove(String id) - { - if (queue != null) - { - Component removed = queue.remove(id); - if (removed != null) - { - queueSize--; - if (isEmpty()) - { - queue = null; - } - return removed; - } - } - return null; - } - - public boolean isEmpty() - { - return queueSize == 0; - } - - public Component get(String id) - { - if (queue != null) - { - return queue.get(id); - } - return null; - } - - @Override - public String toString() - { - return "ComponentQueue{" + - "queueSize=" + queueSize + - ", queue=" + queue + - '}'; - } -} http://git-wip-us.apache.org/repos/asf/wicket/blob/ccff0802/wicket-core/src/main/java/org/apache/wicket/DefaultMarkupIdGenerator.java ---------------------------------------------------------------------- diff --git a/wicket-core/src/main/java/org/apache/wicket/DefaultMarkupIdGenerator.java b/wicket-core/src/main/java/org/apache/wicket/DefaultMarkupIdGenerator.java new file mode 100644 index 0000000..4f5d90f --- /dev/null +++ b/wicket-core/src/main/java/org/apache/wicket/DefaultMarkupIdGenerator.java @@ -0,0 +1,80 @@ +/* + * 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; + +import org.apache.wicket.util.string.Strings; + +/** + * An implementation of IMarkupIdGenerator that uses the Session to generate + * sequence numbers for the component markup ids. + * As a prefix for the generated markup id in development mode it uses the component id + * and in production mode the string <em>id</em>. + */ +public class DefaultMarkupIdGenerator implements IMarkupIdGenerator +{ + @Override + public String generateMarkupId(Component component) + { + Object storedMarkupId = component.getMarkupIdImpl(); + if (storedMarkupId instanceof String) + { + return (String)storedMarkupId; + } + + Session session = component.getSession(); + int generatedMarkupId = storedMarkupId instanceof Integer ? (Integer)storedMarkupId + : session.nextSequenceValue(); + + if (generatedMarkupId == 0xAD) + { + // WICKET-4559 skip suffix 'ad' because some ad-blocking solutions may hide the component + generatedMarkupId = session.nextSequenceValue(); + } + + if (storedMarkupId == null) + { + component.setMarkupIdImpl(generatedMarkupId); + } + + String markupIdPrefix = "id"; + if (component.getApplication().usesDevelopmentConfig()) + { + // in non-deployment mode we make the markup id include component id + // so it is easier to debug + markupIdPrefix = component.getId(); + } + + String markupIdPostfix = Integer.toHexString(generatedMarkupId).toLowerCase(); + + String markupId = markupIdPrefix + markupIdPostfix; + + // make sure id is compliant with w3c requirements (starts with a letter) + char c = markupId.charAt(0); + if (!Character.isLetter(c)) + { + markupId = "id" + markupId; + } + + // escape some noncompliant characters + markupId = Strings.replaceAll(markupId, "_", "__").toString(); + markupId = markupId.replace('.', '_'); + markupId = markupId.replace('-', '_'); + markupId = markupId.replace(' ', '_'); + + return markupId; + } +} http://git-wip-us.apache.org/repos/asf/wicket/blob/ccff0802/wicket-core/src/main/java/org/apache/wicket/IMarkupIdGenerator.java ---------------------------------------------------------------------- diff --git a/wicket-core/src/main/java/org/apache/wicket/IMarkupIdGenerator.java b/wicket-core/src/main/java/org/apache/wicket/IMarkupIdGenerator.java new file mode 100644 index 0000000..6bd2e30 --- /dev/null +++ b/wicket-core/src/main/java/org/apache/wicket/IMarkupIdGenerator.java @@ -0,0 +1,32 @@ +/* + * 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; + +/** + * Generates markup ids for components + */ +public interface IMarkupIdGenerator +{ + /** + * Generates markup id for the given component + * + * @param component + * The component for which to generate a markup id + * @return The generated markup id + */ + String generateMarkupId(Component component); +} http://git-wip-us.apache.org/repos/asf/wicket/blob/ccff0802/wicket-core/src/main/java/org/apache/wicket/settings/MarkupSettings.java ---------------------------------------------------------------------- diff --git a/wicket-core/src/main/java/org/apache/wicket/settings/MarkupSettings.java b/wicket-core/src/main/java/org/apache/wicket/settings/MarkupSettings.java index f615340..72869f0 100644 --- a/wicket-core/src/main/java/org/apache/wicket/settings/MarkupSettings.java +++ b/wicket-core/src/main/java/org/apache/wicket/settings/MarkupSettings.java @@ -16,6 +16,8 @@ */ package org.apache.wicket.settings; +import org.apache.wicket.DefaultMarkupIdGenerator; +import org.apache.wicket.IMarkupIdGenerator; import org.apache.wicket.markup.MarkupFactory; import org.apache.wicket.util.lang.Args; @@ -64,6 +66,12 @@ public class MarkupSettings private boolean stripWicketTags = false; /** + * Generates the markup ids for the components with + * {@link org.apache.wicket.Component#setOutputMarkupId(boolean) #setOutputMarkupId(true)} + */ + private IMarkupIdGenerator markupIdGenerator = new DefaultMarkupIdGenerator(); + + /** * Construct */ public MarkupSettings() @@ -244,4 +252,25 @@ public class MarkupSettings throwExceptionOnMissingXmlDeclaration = throwException; return this; } + + /** + * @return The configured generator for component markup ids + */ + public IMarkupIdGenerator getMarkupIdGenerator() + { + return markupIdGenerator; + } + + /** + * Sets a new IMarkupIdGenerator + * + * @param markupIdGenerator + * The generator of markup ids for the components + * @return {@code this} object for chaining + */ + public MarkupSettings setMarkupIdGenerator(IMarkupIdGenerator markupIdGenerator) + { + this.markupIdGenerator = Args.notNull(markupIdGenerator, "markupIdGenerator"); + return this; + } } http://git-wip-us.apache.org/repos/asf/wicket/blob/ccff0802/wicket-core/src/test/java/org/apache/wicket/MarkupIdGeneratorTest.java ---------------------------------------------------------------------- diff --git a/wicket-core/src/test/java/org/apache/wicket/MarkupIdGeneratorTest.java b/wicket-core/src/test/java/org/apache/wicket/MarkupIdGeneratorTest.java new file mode 100644 index 0000000..859f620 --- /dev/null +++ b/wicket-core/src/test/java/org/apache/wicket/MarkupIdGeneratorTest.java @@ -0,0 +1,73 @@ +/* + * 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; + +import org.apache.wicket.markup.html.link.Link; +import org.junit.Test; + +/** + * Tests for IMarkupIdGenerator + * + * @since 6.16.0 + * @see <a href="https://issues.apache.org/jira/browse/WICKET-5577">Generation of wicket ids with prefix / suffix</a> + */ +public class MarkupIdGeneratorTest extends WicketTestCase +{ + @Test + public void defaultMarkupIdGenerator() + { + MockPageWithLink page = new MockPageWithLink(); + Link link = new Link(MockPageWithLink.LINK_ID) + { + @Override + public void onClick() + { + } + }; + link.setOutputMarkupId(true); + page.add(link); + + assertEquals("link1", link.getMarkupId()); + } + + @Test + public void customMarkupIdGenerator() + { + final String customMarkupId = "custom"; + IMarkupIdGenerator generator = new IMarkupIdGenerator() + { + @Override + public String generateMarkupId(Component component) + { + return customMarkupId; + } + }; + tester.getApplication().getMarkupSettings().setMarkupIdGenerator(generator); + MockPageWithLink page = new MockPageWithLink(); + Link link = new Link(MockPageWithLink.LINK_ID) + { + @Override + public void onClick() + { + } + }; + link.setOutputMarkupId(true); + page.add(link); + + assertEquals(customMarkupId, link.getMarkupId()); + } +}
