KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > sapia > util > xml > confix > JDOMProcessor


1 package org.sapia.util.xml.confix;
2
3
4 // Import of jdom classes
5
// ----------------------
6
import org.jdom.Attribute;
7 import org.jdom.Document;
8 import org.jdom.Element;
9 import org.jdom.JDOMException;
10
11 import org.jdom.input.SAXBuilder;
12 import org.jdom.output.XMLOutputter;
13
14 // Import of Sapia's utility classes
15
// ---------------------------------
16
import org.sapia.util.xml.ProcessingException;
17 import org.xml.sax.InputSource JavaDoc;
18
19 // Import of Sun's JDK classes
20
// ---------------------------
21
import java.io.ByteArrayInputStream JavaDoc;
22 import java.io.ByteArrayOutputStream JavaDoc;
23 import java.io.IOException JavaDoc;
24 import java.io.InputStream JavaDoc;
25
26 import java.util.Iterator JavaDoc;
27
28
29 /**
30  * This class creates an object graph for a given XML input stream. It internally
31  * uses JDOM to transform the stream into a JDOM document, and then to create
32  * objects from the elements found in the document.
33  * <p>
34  * Usage:
35  * <p>
36  * <pre>
37  * ObjectFactoryIF fac = new ReflectionFactory("com.newtrade.company");
38  * JDOMProcessor proc = new JDOMProcessor(fac);
39  * Company comp = (Company)proc.process(new FileInputStream("d:/dev/company.xml"));
40  * </pre>
41  *
42  * @author Yanick Duchesne
43  *
44  * <dl>
45  * <dt><b>Copyright:</b><dd>Copyright &#169; 2002-2003 <a HREF="http://www.sapia-oss.org">Sapia Open Source Software</a>. All Rights Reserved.</dd></dt>
46  * <dt><b>License:</b><dd>Read the license.txt file of the jar or visit the
47  * <a HREF="http://www.sapia-oss.org/license.html">license page</a> at the Sapia OSS web site</dd></dt>
48  * </dl>
49  */

50 public class JDOMProcessor extends AbstractXMLProcessor {
51   /////////////////////////////////////////////////////////////////////////////////////////
52
//////////////////////////////////// CONSTRUCTORS /////////////////////////////////////
53
/////////////////////////////////////////////////////////////////////////////////////////
54

55   /**
56    * Creates a new JDOMProcessor instance with the argument passed in.
57    *
58    * @param anObjectFactory The object factory of this processor.
59    */

60   public JDOMProcessor(ObjectFactoryIF anObjectFactory) {
61     super(anObjectFactory);
62   }
63
64   /////////////////////////////////////////////////////////////////////////////////////////
65
////////////////////////////////// OVERRIDEN METHODS //////////////////////////////////
66
/////////////////////////////////////////////////////////////////////////////////////////
67

68   /**
69    * This method takes an XML stream as input and returns an object
70    * representation of the passed-in XML.
71    *
72    * @param is an XML stream
73    * @return an object representation of the XML stream.
74    * @exception ProcessingException
75    */

76   public Object JavaDoc process(InputStream JavaDoc is) throws ProcessingException {
77     try {
78       // Build the document from the input stream
79
SAXBuilder builder = new SAXBuilder();
80       Document doc = builder.build(is);
81
82       // Process the document
83
Object JavaDoc aResult = process(null, doc.getRootElement());
84
85       return aResult;
86     } catch (IOException JavaDoc ioe) {
87       String JavaDoc aMessage = "Error parsing the XML of the input stream.";
88       throw new ProcessingException(aMessage, ioe);
89     } catch (JDOMException je) {
90       String JavaDoc aMessage = "Error parsing the XML of the input stream.";
91       throw new ProcessingException(aMessage, je);
92     } finally {
93       try {
94         if (is != null) {
95           is.close();
96         }
97       } catch (IOException JavaDoc ioe) {
98         String JavaDoc aMessage = "Error closing the input stream to process.";
99
100         throw new ProcessingException(aMessage, ioe);
101       }
102     }
103   }
104
105   /**
106    * This method takes an object and assigns to it the object representation
107    * of the passed XML stream.
108    *
109    * @param root an <code>Object</code> that is the root of the object graph to create
110    * from the given XML.
111    * @param is an XML <code>InputStream</code>.
112    * @throws ProcessingException if an error occurs while processing the given XML stream.
113    */

114   public void process(Object JavaDoc root, InputStream JavaDoc is) throws ProcessingException {
115     try {
116       // Build the document from the input stream
117
SAXBuilder builder = new SAXBuilder();
118       Document doc = builder.build(is);
119
120       // Process the document
121
Object JavaDoc aResult = process(root, doc.getRootElement());
122     } catch (IOException JavaDoc ioe) {
123       String JavaDoc aMessage = "Error parsing the XML of the input stream.";
124       throw new ProcessingException(aMessage, ioe);
125     } catch (JDOMException je) {
126       String JavaDoc aMessage = "Error parsing the XML of the input stream.";
127       throw new ProcessingException(aMessage, je);
128     } finally {
129       try {
130         if (is != null) {
131           is.close();
132         }
133       } catch (IOException JavaDoc ioe) {
134         String JavaDoc aMessage = "Error closing the input stream to process.";
135
136         throw new ProcessingException(aMessage, ioe);
137       }
138     }
139   }
140
141   /////////////////////////////////////////////////////////////////////////////////////////
142
/////////////////////////////////// HELPER METHODS ////////////////////////////////////
143
/////////////////////////////////////////////////////////////////////////////////////////
144

145   /**
146    * This method will process the dom element passed in to create an object.
147    *
148    * @param aParent The parent object of the one to create.
149    * @param anElement The dom element to process.
150    * @exception ProcessingException If an error occurs while processing the dom tree.
151    */

152   public Object JavaDoc process(Object JavaDoc aParent, Element anElement)
153     throws ProcessingException {
154     return process(aParent, anElement, null);
155   }
156
157   private Object JavaDoc process(Object JavaDoc aParent, Element anElement, String JavaDoc setterName)
158     throws ProcessingException {
159     String JavaDoc 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 JavaDoc aMessage = "Unable to create an object for the element " +
174           anElement;
175
176         throw new ProcessingException(aMessage, oce);
177       }
178
179       if ((aParent != null) &&
180             (containsMethod("set", aParent, aName) ||
181             containsMethod("add", aParent, aName)) &&
182             (anElement.getChildren().size() == 1)) {
183         Element child = (Element) anElement.getChildren().get(0);
184         process(aParent, child, setterName);
185
186         return aParent;
187       }
188
189       try {
190         String JavaDoc aValue = anElement.getTextTrim();
191
192         invokeSetter(aParent.getClass().getName(), aParent, aName, aValue);
193
194         return aParent;
195       } catch (ConfigurationException ce) {
196         String JavaDoc 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 JavaDoc text = anElement.getTextTrim();
205
206     if (text.length() > 0) {
207       try {
208         invokeSetter(aName, status.getCreated(), "Text", text);
209       } catch (ConfigurationException ce) {
210         String JavaDoc aMessage = "The object '" + aName +
211           "' does not accept free text";
212
213         throw new ProcessingException(aMessage, ce);
214       }
215     }
216
217     try {
218       // Process the attributes of the DOM element
219
for (Iterator JavaDoc it = anElement.getAttributes().iterator(); it.hasNext();) {
220         Attribute attr = (Attribute) it.next();
221
222         invokeSetter(aName, status.getCreated(), attr.getName(), attr.getValue());
223       }
224
225       // Process the child elements
226
for (Iterator JavaDoc it = anElement.getChildren().iterator(); it.hasNext();) {
227         Element child = (Element) it.next();
228
229         if (status.getCreated() instanceof JDOMHandlerIF) {
230           ((JDOMHandlerIF) status.getCreated()).handleElement(child);
231         } else if(status.getCreated() instanceof XMLConsumer) {
232                     XMLConsumer cons = (XMLConsumer)status.getCreated();
233                     XMLOutputter outputter = new XMLOutputter();
234                     ByteArrayOutputStream JavaDoc bos = new ByteArrayOutputStream JavaDoc();
235                     try{
236                         Element clone = (Element)child.clone();
237                         outputter.output(new Document(clone.detach()), bos);
238                         ByteArrayInputStream JavaDoc in = new ByteArrayInputStream JavaDoc(bos.toByteArray());
239                         InputSource JavaDoc is = new InputSource JavaDoc(in);
240                         cons.consume(is);
241                     }catch(Exception JavaDoc e){
242                         e.printStackTrace();
243                         throw new ProcessingException("Could not pipe content of element: " + child.getQualifiedName() + " to XMLConsumer", e);
244                     }
245         } else {
246           process(status.getCreated(), child);
247         }
248       }
249
250       // before assigning to parent, check if object
251
// implements ObjectCreationCallback.
252
if (status.getCreated() instanceof ObjectCreationCallback) {
253         status._created = ((ObjectCreationCallback) status.getCreated()).onCreate();
254       }
255
256       // assign obj to parent through setXXX or addXXX
257
if ((aParent != null) && !status.wasAssigned() &&
258             !(status.getCreated() instanceof NullObject)) {
259         assignToParent(aParent, status.getCreated(), setterName);
260       }
261
262       if (status.getCreated() instanceof NullObject) {
263         return null;
264       }
265
266       return status.getCreated();
267     } catch (ConfigurationException ce) {
268       String JavaDoc aMessage = "Unable to process the content of the element " +
269         aName;
270
271       throw new ProcessingException(aMessage, ce);
272     }
273   }
274 }
275
Popular Tags