001: /*
002: * Copyright 2000,2005 wingS development team.
003: *
004: * This file is part of wingS (http://wingsframework.org).
005: *
006: * wingS is free software; you can redistribute it and/or modify
007: * it under the terms of the GNU Lesser General Public License
008: * as published by the Free Software Foundation; either version 2.1
009: * of the License, or (at your option) any later version.
010: *
011: * Please see COPYING for the complete licence.
012: */
013: package org.wings.template;
014:
015: import org.wings.io.Device;
016: import org.wings.template.parser.ParseContext;
017: import org.wings.template.parser.PositionReader;
018: import org.wings.template.parser.SGMLTag;
019:
020: import java.io.IOException;
021: import java.io.InputStream;
022:
023: /**
024: * A TemplateTagHandler
025: *
026: * @author <A href="mailto:zeller@think.de">Henner Zeller</A>
027: */
028: public class RangeTagHandler extends TemplateTagHandler {
029: boolean close_is_missing = false;
030:
031: /**
032: * Parse special tag.
033: *
034: * @param context The ParseContext
035: * @param input The PositionReader, located after the Name token of the Tag
036: * @param startPosition The Position parsing of this token began
037: * @param startTag the SGMLTag found in the file.
038: */
039: public SGMLTag parseTag(ParseContext context, PositionReader input,
040: long startPosition, SGMLTag startTag) throws IOException {
041: final String startTagName = startTag.getName();
042: final String endTagName = "/" + startTagName;
043:
044: /*
045: * parse the full tag to get all parameters
046: * (i.e. an optional 'format'-parameter)
047: * and to place the Reader at the position
048: * after the closing '>'
049: */
050: startTag.parse(input);
051:
052: /*
053: * The Offset is the space the reader skipped
054: * before it reached the opening '<'
055: * <!-- a comment --> some garbage <DATE>
056: * ^----- offset --------------------^
057: */
058: startPos = startPosition + startTag.getOffset();
059:
060: /*
061: * get properties
062: */
063: properties = startTag.getAttributes();
064:
065: name = startTag.value("NAME", null);
066: if (name == null)
067: return null;
068:
069: endPos = input.getPosition(); // in case </component> is missing
070:
071: while (!startTag.finished()) {
072: startTag = new SGMLTag(input, true);
073: if (startTag.isNamed(endTagName)
074: || startTag.isNamed(startTagName))
075: break;
076: }
077:
078: // Either EOF or newly opened COMPONENT (unexpectedly)
079: if (startTag.finished() || startTag.isNamed(startTagName)) {
080: close_is_missing = true;
081: } else {
082: // The current Position is after the closing '>'
083: endPos = input.getPosition();
084: }
085:
086: // remove properties, which are not necessary for the PropertyManager
087: properties.remove("NAME");
088: properties.remove("TYPE");
089:
090: return startTag;
091: }
092:
093: /**
094: * actually perform the action associated with this tag.
095: *
096: * @throws Exception anything can happen .. and throw an Exception
097: * which is caught in PageParser
098: */
099: public void executeTag(ParseContext context, InputStream input)
100: throws Exception {
101: super .executeTag(context, input);
102:
103: // warn, if the closing tag was not found ..
104: if (close_is_missing) {
105: TemplateParseContext tcontext = (TemplateParseContext) context;
106: Device sink = tcontext.getDevice();
107: sink.print("<table bgcolor='#FFAA55'><tr><td>");
108: sink.print(" <blink><b>");
109: sink.print("closing tag missing");
110: sink.print(" for '<em>" + name + "</em>'");
111: sink.print("</b></blink> ");
112: sink.print("</td></tr></table>");
113: }
114: }
115: }
|