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.util.SStringBuilder;
017: import org.wings.template.parser.ParseContext;
018: import org.wings.template.parser.PositionReader;
019: import org.wings.template.parser.SGMLTag;
020:
021: import java.io.IOException;
022: import java.io.InputStream;
023: import java.io.Reader;
024:
025: /**
026: * A TemplateTagHandler
027: *
028: * @author Holger Engels
029: */
030: public class LabelTagHandler extends TemplateTagHandler {
031: boolean close_is_missing = false;
032: SStringBuilder content = new SStringBuilder();
033:
034: /**
035: * @param context the parsing context
036: * @param input the PositionReader, located after the name token of the tag
037: * @param startPosition the position where parsing of this token began
038: * @param startTag the SGMLTag found in the file.
039: */
040: public SGMLTag parseTag(ParseContext context, PositionReader input,
041: long startPosition, SGMLTag startTag) throws IOException {
042: final String startTagName = startTag.getName();
043: final String endTagName = "/" + startTagName;
044:
045: /*
046: * parse the full tag to get all parameters
047: * and to place the Reader to 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: */
056: startPos = startPosition + startTag.getOffset();
057:
058: /*
059: * get properties
060: */
061: properties = startTag.getAttributes();
062:
063: if (startTag.value("FOR", null) == null)
064: return null;
065:
066: endPos = input.getPosition(); // in case </label> is missing
067:
068: SGMLTag endTag;
069: int len;
070: do {
071: len = readContent(input, content);
072: endTag = new SGMLTag(input, false);
073: } while (!endTag.finished() && !endTag.isNamed(endTagName));
074:
075: if (startTag.finished())
076: close_is_missing = true;
077: else
078: endPos = input.getPosition();
079:
080: return endTag;
081: }
082:
083: public int readContent(Reader r, SStringBuilder content)
084: throws IOException {
085: int c, len = 0;
086: do {
087: r.mark(1);
088: c = r.read();
089: len++;
090: content.append((char) c);
091: } while (c >= 0 && c != '<');
092: r.reset();
093: content.setLength(content.length() - 1);
094: return len - 1;
095: }
096:
097: public String getContent() {
098: return content.toString();
099: }
100:
101: public String getFor() {
102: return (String) properties.get("FOR");
103: }
104:
105: /**
106: * actually perform the action associated with this tag.
107: *
108: * @throws Exception anything can happen .. and throw an Exception
109: * which is caught in PageParser
110: */
111: public void executeTag(ParseContext context, InputStream input)
112: throws Exception {
113: TemplateParseContext tcontext = (TemplateParseContext) context;
114: copy(input, tcontext.getDevice(), getTagLength(), new byte[512]);
115:
116: // warn, if the closing tag was not found ..
117: if (close_is_missing) {
118: Device sink = tcontext.getDevice();
119: sink.print("<table bgcolor='#FFAA55'><tr><td>");
120: sink.print(" <blink><b>");
121: sink.print("closing tag missing");
122: sink.print(" for '<em>" + name + "</em>'");
123: sink.print("</b></blink> ");
124: sink.print("</td></tr></table>");
125: }
126: }
127:
128: private static void copy(InputStream in, Device device,
129: long length, byte buf[]) throws IOException {
130: int len;
131: boolean limited = (length >= 0);
132: int rest = limited ? (int) length : buf.length;
133: while (rest > 0
134: && (len = in.read(buf, 0,
135: (rest > buf.length) ? buf.length : rest)) > 0) {
136: device.write(buf, 0, len);
137: if (limited)
138: rest -= len;
139: }
140: }
141: }
|