001: // Copyright 2006, 2007 The Apache Software Foundation
002: //
003: // Licensed under the Apache License, Version 2.0 (the "License");
004: // you may not use this file except in compliance with the License.
005: // You may obtain a copy of the License at
006: //
007: // http://www.apache.org/licenses/LICENSE-2.0
008: //
009: // Unless required by applicable law or agreed to in writing, software
010: // distributed under the License is distributed on an "AS IS" BASIS,
011: // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012: // See the License for the specific language governing permissions and
013: // limitations under the License.
014:
015: package org.apache.tapestry;
016:
017: import java.io.PrintWriter;
018:
019: import org.apache.tapestry.dom.Document;
020: import org.apache.tapestry.dom.Element;
021: import org.apache.tapestry.dom.MarkupModel;
022: import org.apache.tapestry.dom.Raw;
023:
024: /**
025: * An interface used by objects, such as Tapestry components, that need to render themselves as some
026: * form of XML markup. A markup writer maintains the idea of a current element. Attributes are added
027: * to the current element, and new text and elements are placed inside the current element. In this
028: * way, the markup writer maintains a facade that XML markup is generated as a stream, even though
029: * the implementation builds a kind of DOM tree. The DOM tree can be also be manipulated. This
030: * solves a number of problems from Tapestry 4 (and earlier) where random access to the DOM was
031: * desired and had to be simulated through complex buffering.
032: */
033: public interface MarkupWriter {
034: /**
035: * Begins a new element as a child of the current element. The new element becomes the current
036: * element. The new Element is returned and can be directly manipulated (possibly at a later
037: * date). Optionally, attributes for the new element can be specified directly.
038: * <p>
039: * If the element is intended to be clickable or submittable in the
040: * {@link org.apache.tapestry.test.PageTester}, you should call
041: * {@link #linkElement(String, Link, Object[])} instead.
042: *
043: * @param name
044: * the name of the element to create
045: * @param attributes
046: * an even number of values, alternating names and values
047: * @return the new DOM Element node
048: * @see #attributes(Object[])
049: */
050: Element element(String name, Object... attributes);
051:
052: /**
053: * Ends the current element. The new current element will be the parent element. Returns the new
054: * current element (which may be null when ending the root element for the document).
055: */
056:
057: Element end();
058:
059: /**
060: * Writes the text as a child of the current element.
061: * <p>
062: * TODO: Filtering of XML entities.
063: */
064:
065: void write(String text);
066:
067: /** Writes a formatted string. */
068: void writef(String format, Object... args);
069:
070: /**
071: * Writes <em>raw</em> text, text with existing markup that should be passed through the
072: * client without change. This can be useful when the markup is read from an external source (a
073: * file or a database) and is simply to be included.
074: *
075: * @param text
076: * @see Raw
077: */
078: void writeRaw(String text);
079:
080: /**
081: * Adds an XML comment. The text should be just the comment content, the comment delimiters will
082: * be provided.
083: */
084: void comment(String text);
085:
086: /**
087: * Adds a series of attributes and values. Null values are quietly skipped. If a name already
088: * has a value, then the new value is <em>ignored</em>.
089: */
090: void attributes(Object... namesAndValues);
091:
092: /**
093: * Converts the collected markup into an markup stream (according to rules provided by the
094: * {@link Document}'s {@link MarkupModel}). The markup stream is sent to the writer.
095: */
096: void toMarkup(PrintWriter writer);
097:
098: /** Returns the Document into which this writer creates elements or other nodes. */
099: Document getDocument();
100:
101: /** Returns the currently active element. */
102: Element getElement();
103: }
|