1 package org.sapia.util.xml.confix; 2 3 4 import org.dom4j.Attribute; 7 import org.dom4j.Document; 8 import org.dom4j.DocumentException; 9 import org.dom4j.DocumentHelper; 10 import org.dom4j.Element; 11 12 13 import org.dom4j.io.OutputFormat; 14 import org.dom4j.io.SAXReader; 15 import org.dom4j.io.XMLWriter; 16 17 import org.sapia.util.xml.ProcessingException; 20 import org.xml.sax.InputSource ; 21 22 import java.io.ByteArrayInputStream ; 25 import java.io.ByteArrayOutputStream ; 26 import java.io.IOException ; 27 import java.io.InputStream ; 28 import java.io.UnsupportedEncodingException ; 29 30 import java.util.Iterator ; 31 import java.util.List ; 32 33 54 public class Dom4jProcessor extends AbstractXMLProcessor { 55 59 64 public Dom4jProcessor(ObjectFactoryIF anObjectFactory) { 65 super(anObjectFactory); 66 } 67 68 72 80 public Object process(InputStream is) throws ProcessingException { 81 try { 82 SAXReader builder = new SAXReader(); 84 builder.setStripWhitespaceText(false); 85 builder.setMergeAdjacentText(false); 86 Document doc = builder.read(is); 87 88 Object aResult = process(null, doc.getRootElement()); 90 91 return aResult; 92 } catch (DocumentException de) { 93 String aMessage = "Error parsing the XML of the input stream."; 94 throw new ProcessingException(aMessage, de); 95 } finally { 96 try { 97 if (is != null) { 98 is.close(); 99 } 100 } catch (IOException ioe) { 101 String aMessage = "Error closing the input stream to process."; 102 103 throw new ProcessingException(aMessage, ioe); 104 } 105 } 106 } 107 108 117 public void process(Object root, InputStream is) throws ProcessingException { 118 try { 119 SAXReader reader = new SAXReader(); 121 Document doc = reader.read(is); 122 123 Object aResult = process(root, doc.getRootElement()); 125 } catch (DocumentException de) { 126 String aMessage = "Error parsing the XML of the input stream."; 127 throw new ProcessingException(aMessage, de); 128 } finally { 129 try { 130 if (is != null) { 131 is.close(); 132 } 133 } catch (IOException ioe) { 134 String aMessage = "Error closing the input stream to process."; 135 136 throw new ProcessingException(aMessage, ioe); 137 } 138 } 139 } 140 141 145 152 public Object process(Object aParent, Element anElement) 153 throws ProcessingException { 154 return process(aParent, anElement, null); 155 } 156 157 private Object process(Object aParent, Element anElement, String setterName) 158 throws ProcessingException { 159 String aName = anElement.getName(); 160 161 if (setterName == null) { 162 setterName = aName; 163 } 164 165 CreationStatus status = null; 166 167 try { 168 status = getObjectFactory().newObjectFor(anElement.getNamespace() 169 .getPrefix(), 170 anElement.getNamespace().getURI(), aName, aParent); 171 } catch (ObjectCreationException oce) { 172 if (aParent == null) { 173 String aMessage = "Unable to create an object for the element " + 174 anElement; 175 176 throw new ProcessingException(aMessage, oce); 177 } 178 List children; 179 if ((aParent != null) && 180 (containsMethod("set", aParent, aName) || 181 containsMethod("add", aParent, aName)) && 182 ((children = anElement.elements()).size() == 1)) { 183 Element child = (Element) children.get(0); 184 process(aParent, child, setterName); 185 186 return aParent; 187 } 188 189 try { 190 String aValue = anElement.getTextTrim(); 191 192 invokeSetter(aParent.getClass().getName(), aParent, aName, aValue); 193 194 return aParent; 195 } catch (ConfigurationException ce) { 196 String aMessage = 197 "Unable to create an object nor to call a setter for the element " + 198 anElement; 199 oce.printStackTrace(); 200 throw new ProcessingException(aMessage, ce); 201 } 202 } 203 204 String text = anElement.getTextTrim(); 205 206 if (text.length() > 0) { 207 try { 208 invokeSetter(aName, status.getCreated(), "Text", text); 209 } catch (ConfigurationException ce) { 210 String aMessage = "The object '" + aName + 211 "' does not accept free text"; 212 213 throw new ProcessingException(aMessage, ce); 214 } 215 } 216 217 try { 218 for (Iterator it = anElement.attributeIterator(); it.hasNext();) { 220 Attribute attr = (Attribute) it.next(); 221 222 invokeSetter(aName, status.getCreated(), attr.getName(), attr.getValue()); 223 } 224 225 for (Iterator it = anElement.elementIterator(); it.hasNext();) { 227 Element child = (Element) it.next(); 228 229 if (status.getCreated() instanceof Dom4jHandlerIF) { 230 ((Dom4jHandlerIF) status.getCreated()).handleElement(child); 231 } else if(status.getCreated() instanceof XMLConsumer) { 232 XMLConsumer cons = (XMLConsumer)status.getCreated(); 233 ByteArrayOutputStream bos = new ByteArrayOutputStream (); 234 XMLWriter writer; 235 try{ 236 writer = new XMLWriter(bos, OutputFormat.createPrettyPrint()); 237 }catch(UnsupportedEncodingException e){ 238 throw new ProcessingException("Could not instantiate XMLWriter", e); 239 } 240 241 try{ 242 Element copy = child.createCopy(); 243 copy.setDocument(null); 244 writer.write(DocumentHelper.createDocument(copy)); 245 ByteArrayInputStream in = new ByteArrayInputStream (bos.toByteArray()); 246 InputSource is = new InputSource (in); 247 cons.consume(is); 248 }catch(Exception e){ 249 throw new ProcessingException("Could not pipe content of element: " + child.getQualifiedName() + " to XMLConsumer", e); 250 } 251 } else { 252 process(status.getCreated(), child); 253 } 254 } 255 256 if (status.getCreated() instanceof ObjectCreationCallback) { 259 status._created = ((ObjectCreationCallback) status.getCreated()).onCreate(); 260 } 261 262 if ((aParent != null) && !status.wasAssigned() && 264 !(status.getCreated() instanceof NullObject)) { 265 assignToParent(aParent, status.getCreated(), setterName); 266 } 267 268 if (status.getCreated() instanceof NullObject) { 269 return null; 270 } 271 272 return status.getCreated(); 273 } catch (ConfigurationException ce) { 274 String aMessage = "Unable to process the content of the element " + 275 aName; 276 277 throw new ProcessingException(aMessage, ce); 278 } 279 } 280 } 281 | Popular Tags |