/**
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.brixcms.markup;
import org.brixcms.markup.tag.Comment;
import org.brixcms.markup.tag.Item;
import org.brixcms.markup.tag.Tag;
import org.brixcms.markup.tag.Text;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
/**
* Renders the given list of items into an XHTML markup.
*
* @author Matej Knopp
*/
public abstract class MarkupRenderer {
private final String doctype;
private final List<Item> items;
MarkupRenderer(List<Item> items, String doctype) {
this.items = items;
this.doctype = doctype;
}
/**
* Renders the items.
*
* @return XHTML string
*/
public String render() {
StringBuilder builder = new StringBuilder();
if (doctype != null) {
builder.append(doctype);
}
for (Item item : items) {
render(item, builder);
}
return builder.toString();
}
private void render(Item item, StringBuilder builder) {
if (item instanceof Tag) {
render((Tag) item, builder);
} else if (item instanceof Text) {
render((Text) item, builder);
} else if (item instanceof Comment) {
render((Comment) item, builder);
} else {
throw new IllegalStateException("Unknown item type '" + item.getClass().getName() + "'");
}
}
private void render(Tag tag, StringBuilder builder) {
if (tag.getType() == Tag.Type.CLOSE) {
builder.append("</");
} else {
builder.append("<");
}
builder.append(tag.getName());
if (tag.getType() == Tag.Type.OPEN || tag.getType() == Tag.Type.OPEN_CLOSE) {
Map<String, String> attributeMap = new HashMap<String, String>(tag.getAttributeMap());
postprocessTagAttributes(tag, attributeMap);
for (Entry<String, String> e : attributeMap.entrySet()) {
builder.append(" ");
builder.append(e.getKey());
builder.append("=\"");
builder.append(e.getValue());
builder.append("\"");
}
}
if (tag.getType() == Tag.Type.OPEN_CLOSE) {
builder.append(" /");
}
builder.append(">");
}
abstract void postprocessTagAttributes(Tag tag, Map<String, String> attributes);
private void render(Text text, StringBuilder builder) {
builder.append(text.getText());
}
private void render(Comment comment, StringBuilder builder) {
builder.append("<!-- ");
builder.append(comment.getText());
builder.append(" -->");
}
}