001: /*
002: * Created on Sep 23, 2005
003: */
004: package uk.org.ponder.rsf.renderer.scr;
005:
006: import java.util.ArrayList;
007: import java.util.HashMap;
008: import java.util.Iterator;
009:
010: import uk.org.ponder.rsf.renderer.ComponentRenderer;
011: import uk.org.ponder.rsf.renderer.RenderUtil;
012: import uk.org.ponder.rsf.template.XMLLump;
013: import uk.org.ponder.streamutil.write.PrintOutputStream;
014: import uk.org.ponder.xml.NameValue;
015: import uk.org.ponder.xml.XMLUtil;
016: import uk.org.ponder.xml.XMLWriter;
017:
018: /** Class encapsulating a "static" (i.e. independent of any producer
019: * components) rewriting operation on a tag, which is "flat" - that is,
020: * operates on a predetermined attribute based on static data.
021: * @author Antranig Basman (antranig@caret.cam.ac.uk)
022: *
023: */
024: public class FlatSCR implements BasicSCR {
025: /** A value for the <code>body_strategy</code> field, indicating that this
026: * renderer will append to any existing tag body that it discovers.
027: */
028: public static final String APPEND_BODY = "append body";
029: /** A value for the <code>body_strategy</code> field, indicating that this
030: * renderer will replace any existing tag body that it discovers.
031: */
032: public static final String REPLACE_BODY = "replace body";
033: /** A replacement tag, if tag is to be rewritten - this is currently only
034: * supported for empty tags. May be null for no action.
035: */
036: public String tag;
037: /** An attribute map to be applied on top of any existing attributes */
038: private HashMap attributemap = new HashMap();
039: /** The name of this renderer, to form as index - it will be invoked by the
040: * renderer on seeing an attribute rsf-id="scr:[name]";
041: */
042: private String name;
043: /** Takes on one of the two static values above, indicating strategy to be
044: * used with the supplied body text.
045: */
046: public String body_strategy = null;
047: /** Any text to form as the body of the tag, null if no replacement required.
048: * May only be set if the renderer type is LEAF_TAG. */
049: public String body;
050: /** One of the values from ComponentRenderer, indicating whether this
051: * renderer is intended to act on complete tags, consuming the close tag from
052: * the template stream.
053: */
054: public int tag_type = ComponentRenderer.LEAF_TAG;
055:
056: public void addNameValue(NameValue toadd) {
057: attributemap.put(toadd.name, toadd.value);
058: }
059:
060: public String getName() {
061: return name;
062: }
063:
064: public void setName(String name) {
065: this .name = name;
066: }
067:
068: // deserialisation method - fix this system at some point. Cannot understand
069: // any more how maps are supported by the SAXalizer.
070: /** A method for deserialisation */
071: public Iterator getNameValue() {
072: ArrayList values = new ArrayList();
073: for (Iterator vit = attributemap.keySet().iterator(); vit
074: .hasNext();) {
075: String key = (String) vit.next();
076: values.add(new NameValue(key, (String) attributemap
077: .get(key)));
078: }
079: return values.iterator();
080: }
081:
082: public int render(XMLLump lump, XMLWriter xmlw) {
083: PrintOutputStream pos = xmlw.getInternalWriter();
084:
085: //XMLLump lump = lumps[lumpindex];
086: XMLLump close = lump.close_tag;
087: XMLLump endopen = lump.open_end;
088: if (tag != null) {
089: pos.print("<").print(tag).print(" ");
090: } else {
091: pos.write(lump.parent.buffer, lump.start, lump.length);
092: }
093: HashMap newattrs = new HashMap();
094: newattrs.putAll(lump.attributemap);
095: newattrs.putAll(attributemap);
096: newattrs.remove(XMLLump.ID_ATTRIBUTE);
097: XMLUtil.dumpAttributes(newattrs, xmlw);
098: if (endopen == close && body == null) {
099: pos.print("/>");
100: } else {
101: pos.print(">");
102: if (tag_type == ComponentRenderer.LEAF_TAG) {
103: if (body != null && body_strategy.equals(REPLACE_BODY)) {
104: pos.print(body);
105: pos.write(close.parent.buffer, close.start,
106: close.length);
107: } else {
108: if (body != null) {
109: pos.print(body);
110: RenderUtil.dumpTillLump(lump.parent.lumps,
111: endopen.lumpindex + 1,
112: close.lumpindex + 1, pos);
113: }
114: } // end if complete body replacement
115: } // end if leaf tag
116: }
117: return tag_type;
118: }
119: }
|