1 package org.objectweb.jonas.tools.migration.jboss; 2 3 import java.util.*; 4 import javax.xml.parsers.*; 5 import org.w3c.dom.*; 6 7 12 13 public class Transformer { 14 15 protected interface NodeFilter { 16 boolean accept(Node node); 17 } 18 19 protected static final NodeFilter ALL = new NodeFilter() { 20 public boolean accept(Node node) { return true; } 21 }; 22 23 protected static final String LINE = 24 System.getProperty("line.separator", "\n\r"); 25 26 private Stack m_stack = new Stack(); 27 private Document m_doc; 28 private Node m_node; 29 30 protected Transformer() { 31 try { 32 DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder(); 33 m_doc = db.newDocument(); 34 } catch (ParserConfigurationException e) { 35 throw new RuntimeException (e); 36 } 37 m_node = m_doc; 38 } 39 40 protected Document getDocument() { 41 return m_doc; 42 } 43 44 private String indent(int level) { 45 StringBuffer buf = new StringBuffer (); 46 for (int i = 0; i < level; i++) { 47 buf.append(" "); 48 } 49 return buf.toString(); 50 } 51 52 private void indent(boolean indent, int offset) { 53 int level = m_stack.size() + offset; 54 if (indent && level > 0) { 55 text(LINE + indent(level)); 56 } 57 } 58 59 protected void open(String name) { 60 open(name, true); 61 } 62 63 protected void open(String name, boolean indent) { 64 indent(indent, 0); 65 Element el = m_doc.createElement(name); 66 m_node.appendChild(el); 67 m_stack.push(m_node); 68 m_node = el; 69 } 70 71 protected void close() { 72 close(true); 73 } 74 75 protected void close(boolean indent) { 76 indent(indent, -1); 77 m_node = (Node) m_stack.pop(); 78 } 79 80 protected void set(String name, String value) { 81 if (m_node.getNodeType() != Node.ELEMENT_NODE) { 82 throw new IllegalStateException 83 ("not currently in an element"); 84 } 85 Element el = (Element) m_node; 86 el.setAttribute(name, value); 87 } 88 89 protected void text(String text) { 90 m_node.appendChild(m_doc.createTextNode(text)); 91 } 92 93 protected void comment(String comment) { 94 m_node.appendChild(m_doc.createComment(comment)); 95 } 96 97 protected void tag(String name, String value) { 98 if (value == null) { return; } 99 open(name); 100 text(value); 101 close(false); 102 } 103 104 protected void get(Node node, String name, Collection result, 105 NodeFilter filter) { 106 NodeList nodes = node.getChildNodes(); 107 for (int i = 0; i < nodes.getLength(); i++) { 108 Node child = nodes.item(i); 109 if (child.getNodeName().equals(name) && filter.accept(child)) { 110 result.add(child); 111 } 112 } 113 } 114 115 protected void query(Node node, String path, Collection result) { 116 query(node, path, result, ALL); 117 } 118 119 protected void query(Node node, String path, Collection result, 120 NodeFilter filter) { 121 int idx = path.indexOf('/'); 122 if (idx < 0) { 123 get(node, path, result, filter); 124 return; 125 } 126 127 String first = path.substring(0, idx); 128 String rest = path.substring(idx+1); 129 ArrayList l = new ArrayList(); 130 get(node, first, l, ALL); 131 for (int i = 0; i < l.size(); i++) { 132 Node n = (Node) l.get(i); 133 query(n, rest, result, filter); 134 } 135 } 136 137 protected List nodes(Node node, String path) { 138 List result = new ArrayList(); 139 query(node, path, result); 140 return result; 141 } 142 143 protected Node node(Node node, String path) { 144 ArrayList result = new ArrayList(); 145 query(node, path, result); 146 return singleton(result); 147 } 148 149 protected String value(Node node, String path) { 150 if (node == null) { return null; } 151 Node val = node(node, path + "/#text"); 152 if (val == null) { 153 return null; 154 } else { 155 String result = val.getNodeValue(); 156 if (result == null) { 157 throw new IllegalStateException 158 ("node has no value: " + val); 159 } else { 160 return result.trim(); 161 } 162 } 163 } 164 165 protected List values(Node node, String path) { 166 List result = new ArrayList(); 167 List nodes = nodes(node, path + "/#text"); 168 for (int i = 0; i < nodes.size(); i++) { 169 Node nd = (Node) nodes.get(i); 170 result.add(nd.getNodeValue()); 171 } 172 return result; 173 } 174 175 protected Node singleton(Collection c) { 176 if (c.isEmpty()) { 177 return null; 178 } else if (c.size() > 1) { 179 throw new IllegalStateException 180 ("too many results: " + c); 181 } else { 182 return (Node) c.iterator().next(); 183 } 184 } 185 186 private boolean isInlinable(NodeList nodes) { 187 for (int i = 0; i < nodes.getLength(); i++) { 188 Node node = nodes.item(i); 189 switch (node.getNodeType()) { 190 case Node.TEXT_NODE: 191 case Node.ENTITY_REFERENCE_NODE: 192 continue; 193 default: 194 return false; 195 } 196 } 197 return true; 198 } 199 200 protected boolean isEmpty(String str) { 201 return str == null || str.equals(""); 202 } 203 204 protected void rename(Collection nodes, Map substitutions) { 205 for (Iterator it = nodes.iterator(); it.hasNext(); ) { 206 Node node = (Node) it.next(); 207 rename(node, substitutions); 208 } 209 } 210 211 protected void rename(Node node, Map substitutions) { 212 if (node == null) { return; } 213 if (node.getNodeType() == Node.TEXT_NODE) { 214 String value = node.getNodeValue().trim(); 215 if (!value.equals("")) { 216 text(node.getNodeValue()); 217 } 218 return; 219 } 220 String name = node.getNodeName(); 221 if (!substitutions.containsKey(name)) { 222 return; 223 } 224 name = (String ) substitutions.get(name); 225 NodeList nodes = node.getChildNodes(); 226 boolean opened = false; 227 if (!isEmpty(name)) { 228 open(name); 229 opened = true; 230 } 231 for (int i = 0; i < nodes.getLength(); i++) { 232 rename(nodes.item(i), substitutions); 233 } 234 if (opened) { 235 close(!isInlinable(nodes)); 236 } 237 } 238 239 protected static class Mapper extends LinkedHashMap { 240 Mapper copy(String element) { 241 return rename(element, element); 242 } 243 Mapper rename(String from, String to) { 244 put(from, to); 245 return this; 246 } 247 Mapper remove(String element) { 248 return rename(element, ""); 249 } 250 } 251 252 } 253 | Popular Tags |