001 // Copyright 2006, 2007, 2008 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.tapestry5; 016 017 import org.apache.tapestry5.dom.Document; 018 import org.apache.tapestry5.dom.Element; 019 import org.apache.tapestry5.dom.MarkupModel; 020 import org.apache.tapestry5.dom.Raw; 021 022 import java.io.PrintWriter; 023 024 /** 025 * An interface used by objects, such as Tapestry components, that need to render themselves as some form of XML markup. 026 * A markup writer maintains the idea of a current element. Attributes are added to the current element, and new text 027 * and elements are placed inside the current element. In this way, the markup writer maintains a facade that XML markup 028 * is generated as a stream, even though the implementation builds a kind of DOM tree. The DOM tree can be also be 029 * manipulated. This solves a number of problems from Tapestry 4 (and earlier) where random access to the DOM was 030 * desired and had to be simulated through complex buffering. 031 */ 032 public interface MarkupWriter 033 { 034 /** 035 * Begins a new element as a child of the current element. The new element becomes the current element. The new 036 * Element is returned and can be directly manipulated (possibly at a later date). Optionally, attributes for the 037 * new element can be specified directly. 038 * <p/> 039 * 040 * @param name the name of the element to create 041 * @param attributes an even number of values, alternating names and values 042 * @return the new DOM Element node 043 * @see #attributes(Object[]) 044 */ 045 Element element(String name, Object... attributes); 046 047 /** 048 * Ends the current element. The new current element will be the parent element. Returns the new current element 049 * (which may be null when ending the root element for the document). 050 */ 051 052 Element end(); 053 054 /** 055 * Writes the text as a child of the current element. 056 */ 057 058 void write(String text); 059 060 /** 061 * Writes a formatted string. 062 */ 063 void writef(String format, Object... args); 064 065 /** 066 * Writes <em>raw</em> text, text with existing markup that should be passed through the client without change. This 067 * can be useful when the markup is read from an external source (a file or a database) and is simply to be 068 * included. 069 * 070 * @param text 071 * @see Raw 072 */ 073 void writeRaw(String text); 074 075 /** 076 * Adds an XML comment. The text should be just the comment content, the comment delimiters will be provided. 077 * Note that, as of Tapestry 5.2., no extra whitespace is added (previous releases added a space around the text). 078 */ 079 void comment(String text); 080 081 082 /** 083 * Adds parsed character content. This will be enclosed in a CDATA block if supported. When not supported, this is 084 * the same as {@link #write(String)}. 085 * 086 * @param content pre-parsed content 087 */ 088 void cdata(String content); 089 090 /** 091 * Adds a series of attributes and values. Null values are quietly skipped. If a name already has a value, then the 092 * new value is <em>ignored</em>. 093 */ 094 void attributes(Object... namesAndValues); 095 096 /** 097 * Converts the collected markup into an markup stream (according to rules provided by the {@link Document}'s {@link 098 * MarkupModel}). The markup stream is sent to the writer. 099 */ 100 void toMarkup(PrintWriter writer); 101 102 /** 103 * Returns the Document into which this writer creates elements or other nodes. 104 */ 105 Document getDocument(); 106 107 /** 108 * Returns the currently active element. 109 */ 110 Element getElement(); 111 112 /** 113 * Defines a namespace for the currently active element. The namespace URI will be mapped to the provided namespace 114 * prefix within the Element. 115 * 116 * @param namespace the namespace URI 117 * @param namespacePrefix the prefix for elements and attributes associated with the namespace (may be the empty 118 * string for the default namespace) 119 * @return the currently active element 120 */ 121 Element defineNamespace(String namespace, String namespacePrefix); 122 123 /** 124 * Starts an element within the given namespace. The correct namespace prefix will be identified and used. Must be 125 * balanced by a call to {@link #end()}. 126 * 127 * @param namespace URI containing the element 128 * @param elementName name of the element within the namespace 129 * @return the new Element 130 */ 131 Element elementNS(String namespace, String elementName); 132 133 /** 134 * Creates an attribute within the namespace for the current element. 135 * 136 * @param namespace URI containing the element 137 * @param attributeName name of the attribute within the namespace 138 * @param attributeValue the value for the attribute 139 * @return the currently active element 140 */ 141 Element attributeNS(String namespace, String attributeName, String attributeValue); 142 143 /** 144 * Adds a markup writer listener that will be notified as elements are started and ended. 145 */ 146 void addListener(MarkupWriterListener listener); 147 148 /** 149 * Removes a previously added listener. 150 */ 151 void removeListener(MarkupWriterListener listener); 152 }