001: package org.enhydra.util.ajaxforms;
002:
003: import java.io.IOException;
004: import java.nio.charset.Charset;
005: import java.nio.charset.IllegalCharsetNameException;
006: import java.nio.charset.UnsupportedCharsetException;
007:
008: import org.enhydra.util.DOMFormatter;
009: import org.w3c.dom.Element;
010: import org.w3c.dom.NamedNodeMap;
011: import org.w3c.dom.Node;
012: import org.w3c.dom.Text;
013:
014: public class AjaxFormsFormater implements DOMFormatter {
015:
016: private String encoding = null;
017:
018: public AjaxFormsFormater(String encoding) {
019: try {
020: if (null != Charset.forName(encoding))
021: this .encoding = encoding;
022: } catch (Exception ex) {
023: // keep default encoding
024: }
025:
026: }
027:
028: public void setEncoding(String encoding) {
029: try {
030: if (null != Charset.forName(encoding))
031: this .encoding = encoding;
032: } catch (IllegalCharsetNameException ex) {
033: // keep default encoding
034: } catch (UnsupportedCharsetException ex) {
035: // keep default encoding
036: }
037: }
038:
039: public String getEncoding() {
040: return this .encoding;
041: }
042:
043: public byte[] toBytes(Node document) {
044: removeEmpty(document);
045: StringBuffer sb = new StringBuffer();
046: try {
047: serialize(document, sb);
048: } catch (IOException e) {
049: e.printStackTrace();
050: }
051:
052: try {
053: return sb.toString().getBytes(encoding);
054: } catch (Exception e) {
055: return sb.toString().getBytes();
056: }
057:
058: }
059:
060: private void serialize(Node node, StringBuffer sb)
061: throws IOException {
062: short type = node.getNodeType();
063: String name = node.getNodeName();
064:
065: boolean jsp = false;
066:
067: switch (type) {
068: case Node.DOCUMENT_NODE:
069: sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
070: break;
071: case Node.ELEMENT_NODE:
072: if (!jsp || !name.equals("jsp:root")) {
073: sb.append("<").append(name);
074: NamedNodeMap atts = ((Element) node).getAttributes();
075:
076: for (int i = 0; i < atts.getLength(); i++) {
077: serialize(atts.item(i), sb);
078: }
079:
080: sb.append(">");
081:
082: if (jsp && name.indexOf(":") != -1) {
083: String pre = name.split(":")[0];
084: String uri = node.lookupNamespaceURI(pre);
085: boolean tagDir = uri.startsWith("urn:jsptagdir:");
086:
087: if (tagDir) {
088: uri = uri.substring(14);
089: }
090:
091: String dec = "<%@ taglib "
092: + (tagDir ? "tagdir" : "uri") + "=\"" + uri
093: + "\" prefix=\"" + pre + "\" %>\n";
094:
095: if (sb.indexOf(dec) == -1) {
096: sb.insert(0, dec);
097: }
098: }
099: }
100:
101: break;
102: case Node.ATTRIBUTE_NODE:
103: boolean process = name.indexOf("xmlns") == -1;
104:
105: if (process) {
106: sb.append(" ").append(name).append("=\"");
107: sb.append(encoding(node.getNodeValue())).append("\"");
108: }
109:
110: break;
111: case Node.TEXT_NODE:
112: sb.append(encoding(node.getNodeValue()));
113: break;
114: }
115:
116: if (type != Node.ATTRIBUTE_NODE) {
117: int length = node.getChildNodes().getLength();
118:
119: for (int i = 0; i < length; i++) {
120: serialize(node.getChildNodes().item(i), sb);
121: }
122: }
123:
124: if (type == Node.ELEMENT_NODE) {
125: if (jsp || !name.equals("jsp:root")) {
126: sb.append("</").append(name).append(">");
127: }
128: }
129: }
130:
131: private void removeEmpty(Node node) {
132: if (node instanceof Text) {
133: String nodeValue = node.getNodeValue().trim();
134:
135: if (nodeValue == null
136: || nodeValue.length() == 0
137: || (nodeValue.length() == 1 && nodeValue.charAt(0) == 160)) {
138: if (!node.getParentNode().getLocalName().equals("span")) {
139: node.getParentNode().removeChild(node);
140: }
141: }
142: } else {
143: Node child = node.getFirstChild();
144: Node old = child;
145:
146: while (child != null) {
147: removeEmpty(child);
148:
149: if (child.getParentNode() != null) {
150: old = child;
151: child = child.getNextSibling();
152: } else if (old.getParentNode() == null) {
153: child = node.getFirstChild();
154: old = child;
155: } else {
156: child = old.getNextSibling();
157: }
158: }
159: }
160: }
161:
162: private String encoding(String text) {
163: StringBuffer sb = new StringBuffer();
164: for (int i = 0; i < text.length(); i++) {
165: int c = text.charAt(i);
166:
167: switch (c) {
168: case '&':
169: sb.append("&");
170: break;
171: case '>':
172: sb.append(">");
173: break;
174: case '<':
175: sb.append("<");
176: break;
177: default:
178: sb.append((char) c);
179: }
180: }
181:
182: return sb.toString();
183: }
184: }
|