001: /*
002: * $Id: WicketRemoveTagHandler.java,v 1.4 2005/01/23 17:45:03 jdonnerstag
003: * Exp $ $Revision: 461655 $ $Date: 2006-07-30 14:37:49 +0200 (Sun, 30 Jul 2006) $
004: *
005: * ==============================================================================
006: * Licensed under the Apache License, Version 2.0 (the "License"); you may not
007: * use this file except in compliance with the License. You may obtain a copy of
008: * the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing, software
013: * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
014: * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
015: * License for the specific language governing permissions and limitations under
016: * the License.
017: */
018: package wicket.markup.parser.filter;
019:
020: import java.text.ParseException;
021:
022: import wicket.markup.ComponentTag;
023: import wicket.markup.MarkupElement;
024: import wicket.markup.WicketTag;
025: import wicket.markup.parser.AbstractMarkupFilter;
026:
027: /**
028: * This is a markup inline filter. It identifies preview regions useful for HTML
029: * designers to design the page. But they must be removed prior to sending the
030: * markup to the client. Preview regions are enclosed by <wicket:remove>
031: * tags.
032: *
033: * @author Juergen Donnerstag
034: */
035: public final class WicketRemoveTagHandler extends AbstractMarkupFilter {
036: /** Flag value to use as component name for ignored components */
037: public static final String IGNORE = "<<Removed by WicketRemoveTagHandler>>";
038:
039: static {
040: // register "wicket:fragement"
041: WicketTagIdentifier.registerWellKnownTagName("remove");
042: }
043:
044: /**
045: * Construct.
046: */
047: public WicketRemoveTagHandler() {
048: }
049:
050: /**
051: * Removes preview regions enclosed by <wicket:remove> tags. Note that
052: * for obvious reasons, nested components are not allowed.
053: *
054: * @see wicket.markup.parser.IMarkupFilter#nextTag()
055: * @return The next tag to be processed. Null, if not more tags are
056: * available
057: */
058: public final MarkupElement nextTag() throws ParseException {
059: // Get the next tag from the next MarkupFilter in the chain
060: // If null, no more tags are available
061: final ComponentTag openTag = (ComponentTag) getParent()
062: .nextTag();
063: if (openTag == null) {
064: return openTag;
065: }
066:
067: // If it is not a remove tag, than we are finished
068: if (!(openTag instanceof WicketTag)
069: || !((WicketTag) openTag).isRemoveTag()) {
070: return openTag;
071: }
072:
073: // remove tag must not be open-close tags
074: if (openTag.isOpenClose()) {
075: throw new ParseException(
076: "Wicket remove tag must not be an open-close tag: "
077: + openTag.toUserDebugString(), openTag
078: .getPos());
079: }
080:
081: // Find the corresponding close tag and remove all tags in between
082: ComponentTag closeTag;
083: while (null != (closeTag = (ComponentTag) getParent().nextTag())) {
084: // No Wicket component tags are allowed within the preview region.
085: // Wicket components will a component name assigned.
086: if (closeTag.getId() == null) {
087: continue;
088: }
089:
090: // The first Wicket component following the preview region open
091: // tag, must be it's corresponding close tag.
092: if (closeTag.closes(openTag)) {
093: // Component's named with the IGNORE component name will be ignored
094: // by MarkupParser and not added to the Markup.
095: openTag.setId(IGNORE);
096: return openTag;
097: }
098:
099: throw new ParseException(
100: "Markup remove regions must not contain Wicket component tags. "
101: + "tag: " + closeTag.toUserDebugString(),
102: closeTag.getPos());
103: }
104:
105: throw new ParseException(
106: "Did not find close tag for markup remove region. "
107: + "Open tag: " + openTag.toUserDebugString(),
108: openTag.getPos());
109: }
110: }
|