KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > openharmonise > rm > resources > xml > XMLResource


1 /*
2  * The contents of this file are subject to the
3  * Mozilla Public License Version 1.1 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at http://www.mozilla.org/MPL/
6  *
7  * Software distributed under the License is distributed on an "AS IS"
8  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
9  * See the License for the specific language governing rights and
10  * limitations under the License.
11  *
12  * The Initial Developer of the Original Code is Simulacra Media Ltd.
13  * Portions created by Simulacra Media Ltd are Copyright (C) Simulacra Media Ltd, 2004.
14  *
15  * All Rights Reserved.
16  *
17  * Contributor(s):
18  */

19 package org.openharmonise.rm.resources.xml;
20
21 import java.io.*;
22 import java.util.Vector JavaDoc;
23
24 import javax.xml.parsers.*;
25
26 import org.openharmonise.commons.dsi.*;
27 import org.openharmonise.commons.dsi.dml.JoinConditions;
28 import org.openharmonise.commons.xml.XMLDocument;
29 import org.openharmonise.commons.xml.namespace.NamespaceType;
30 import org.openharmonise.rm.*;
31 import org.openharmonise.rm.factory.*;
32 import org.openharmonise.rm.publishing.Publishable;
33 import org.openharmonise.rm.resources.content.TextResource;
34 import org.openharmonise.rm.resources.lifecycle.*;
35 import org.w3c.dom.*;
36 import org.xml.sax.*;
37
38
39 /**
40  * This class represnts a generic XML resource within Harmonise.
41  *
42  * @author Michael Bell
43  * @version $Revision: 1.2 $
44  *
45  */

46 public class XMLResource extends TextResource implements Editable, Publishable,
47         Cloneable JavaDoc, Comparable JavaDoc, EditEventListener {
48
49     //DB constants
50
private static final String JavaDoc ATTRIB_HREF = "href";
51
52     private static final String JavaDoc TBL_XML = "xml";
53
54     //XML constants
55
public static final String JavaDoc TAG_XML = "XML";
56
57     public static final String JavaDoc PROTOCOL_OH = "ohrm";
58
59     private XMLDocument m_cached_xincludedDoc = null;
60
61     private XMLDocument m_cached_doc = null;
62
63     // initialise content type
64
{
65         m_sContentType = "text/xml";
66     }
67
68     /**
69      * Basic constructor.
70      */

71     public XMLResource() {
72         super();
73
74     }
75
76     /**
77      * Basic constructor which sets up an interface to the DB.
78      *
79      * @param dbintrf
80      */

81     public XMLResource(AbstractDataStoreInterface dbintrf) {
82         super(dbintrf);
83
84     }
85
86     /**
87      * Standard constructor for a known XML resource which may be a historical
88      * version.
89      *
90      * @param dbintrf
91      * @param nId
92      * @param bIsHist
93      */

94     public XMLResource(AbstractDataStoreInterface dbintrf, int nId, int nKey,
95             boolean bIsHist) {
96         super(dbintrf, nId, nKey, bIsHist);
97     }
98
99     /**
100      * Standard constructor for a known XML resource.
101      *
102      * @param dbintrf
103      * @param nId
104      */

105     public XMLResource(AbstractDataStoreInterface dbintrf, int nId) {
106         super(dbintrf, nId);
107
108     }
109
110     /* (non-Javadoc)
111      * @see org.openharmonise.rm.resources.AbstractChildObject#getParentObjectClassName()
112      */

113     public String JavaDoc getParentObjectClassName() {
114
115         return XMLResourceGroup.class.getName();
116     }
117
118     /* (non-Javadoc)
119      * @see org.openharmonise.rm.dsi.DataStoreObject#getDBTableName()
120      */

121     public String JavaDoc getDBTableName() {
122         return TBL_XML;
123     }
124
125     /* (non-Javadoc)
126      * @see org.openharmonise.rm.publishing.Publishable#getTagName()
127      */

128     public String JavaDoc getTagName() {
129         return TAG_XML;
130     }
131
132     /* (non-Javadoc)
133      * @see org.openharmonise.rm.dsi.DataStoreObject#getInstanceJoinConditions(java.lang.String, boolean)
134      */

135     public JoinConditions getInstanceJoinConditions(String JavaDoc sObjectTag,
136             boolean bIsOuter) throws DataStoreException {
137         return null;
138     }
139
140     /**
141      * Returns a <code>XMLDocument</code> for this resource.
142      *
143      * @return @throws
144      * DataAccessException
145      */

146     public XMLDocument getDocument() throws DataAccessException {
147
148         if (m_cached_doc == null) {
149
150             String JavaDoc sContent = getContent();
151             if (sContent != null) {
152                 try {
153                     StringReader sreader = new StringReader(sContent);
154
155                     InputSource insource = new InputSource(sreader);
156
157                     DocumentBuilderFactory factory = DocumentBuilderFactory
158                             .newInstance();
159
160                     factory.setNamespaceAware(true);
161
162                     DocumentBuilder builder = factory.newDocumentBuilder();
163
164                     m_cached_doc = new XMLDocument(builder.parse(insource));
165                 } catch (ParserConfigurationException e) {
166                     throw new DataAccessException("Parser config error", e);
167                 } catch (FactoryConfigurationError e) {
168                     throw new DataAccessException("Factory config error", e);
169                 } catch (SAXException e) {
170                     throw new DataAccessException("SAX error", e);
171                 } catch (IOException e) {
172                     throw new DataAccessException(
173                             "Error occured reading string", e);
174                 }
175             } else {
176                 m_cached_doc = new XMLDocument();
177             }
178         }
179
180         //clone Document to avoid problems with tampered docs
181
XMLDocument rDoc = new XMLDocument((Document) m_cached_doc
182                 .cloneNode(true));
183
184         return rDoc;
185     }
186
187     /**
188      * Returns a <code>XMLDocument</code> with any XInclude tags replaced with
189      * the relevant data.
190      *
191      * @return @throws
192      * DataAccessException
193      */

194     synchronized public XMLDocument getXIncludeResolvedDocument()
195             throws DataAccessException {
196
197         if (m_cached_xincludedDoc == null) {
198             m_cached_xincludedDoc = new XMLDocument(
199                     (org.w3c.dom.Document JavaDoc) getDocument().cloneNode(true));
200             NodeList nodes = m_cached_xincludedDoc.getDocumentElement()
201                     .getElementsByTagNameNS(NamespaceType.XINCLUDE.getURI(),
202                             "include");
203             Vector JavaDoc replaceList = new Vector JavaDoc();
204             for (int i = 0; i < nodes.getLength(); i++) {
205                 replaceList.add((Element) nodes.item(i));
206             }
207             for (int i = 0; i < replaceList.size(); i++) {
208                 Element includeEl = (Element) replaceList.get(i);
209                 Element replaceEl = getIncludeReplacement(
210                         m_cached_xincludedDoc, includeEl);
211                 m_cached_xincludedDoc.getDocumentElement().replaceChild(
212                         replaceEl, includeEl);
213             }
214
215         }
216
217         //clone Document to avoid problems with tampered docs
218
XMLDocument rDoc = new XMLDocument((Document) m_cached_xincludedDoc
219                 .cloneNode(true));
220
221         return rDoc;
222     }
223
224     /*----------------------------------------------------------------------------
225      Protected methods
226      -----------------------------------------------------------------------------*/

227
228     /**
229      * Returns the Element which the given include Element represents.
230      *
231      * @param includeEl
232      * @return
233      */

234     protected Element getIncludeReplacement(org.w3c.dom.Document JavaDoc xdoc,
235             Element includeEl) throws DataAccessException {
236
237         String JavaDoc href = includeEl.getAttribute(ATTRIB_HREF);
238         String JavaDoc sProtocol = PROTOCOL_OH;
239
240         Element resultEl = null;
241
242         int nColon = href.indexOf(":");
243
244         if (nColon >= 0) {
245             sProtocol = href.substring(0, nColon);
246             href = href.substring(nColon);
247         }
248
249         if (sProtocol.equalsIgnoreCase(PROTOCOL_OH) == true) {
250             try {
251                 if (href.startsWith("/") == false) {
252                     href = getPath() + href;
253                 }
254                 String JavaDoc sClassName = this.getClass().getName();
255
256                 XMLResource xmlRes = (XMLResource) HarmoniseObjectFactory
257                         .instantiateHarmoniseObject(this.m_dsi, sClassName, href);
258
259                 if (xmlRes == null
260                         && sClassName.equals(XMLResource.class.getName()) == false) {
261                     xmlRes = (XMLResource) HarmoniseObjectFactory
262                             .instantiateHarmoniseObject(this.m_dsi, XMLResource.class
263                                     .getName(), href);
264                 }
265
266                 //add this as a listener so we can clear cached doc if
267
//necessary
268
xmlRes.addEditEventListener(this);
269
270                 resultEl = (Element) xdoc.importNode(xmlRes.getDocument()
271                         .getDocumentElement(), true);
272
273             } catch (HarmoniseFactoryException e) {
274                 throw new DataAccessException(
275                         "Error occured getting xml resource from factory",e);
276             } catch (NullPointerException JavaDoc npe) {
277                 throw new DataAccessException(
278                         "Error occured getting xml resource from factory",npe);
279             }
280
281         } else {
282             // TODO support other protocols
283
resultEl = xdoc.createElement("UnsupportedProtocol");
284         }
285
286         return resultEl;
287     }
288
289     /* (non-Javadoc)
290      * @see org.openharmonise.rm.resources.AbstractEditableObject#saveNonCoreData()
291      */

292     protected void saveNonCoreData() throws EditException {
293         // nothing to do
294

295     }
296
297     /* (non-Javadoc)
298      * @see org.openharmonise.rm.resources.AbstractObject#setIsChanged(boolean)
299      */

300     public void setIsChanged(boolean bIsChanged) {
301         //if something has changed then clear the cached docs
302
if (bIsChanged == true) {
303             m_cached_doc = null;
304             m_cached_xincludedDoc = null;
305         }
306
307         super.setIsChanged(bIsChanged);
308     }
309
310     /* (non-Javadoc)
311      * @see org.openharmonise.rm.resources.lifecycle.EditEventListener#workflowObjectSaved(org.openharmonise.rm.resources.lifecycle.EditEvent)
312      */

313     public void workflowObjectSaved(EditEvent event) {
314         super.workflowObjectSaved(event);
315
316     }
317
318     /* (non-Javadoc)
319      * @see org.openharmonise.rm.resources.lifecycle.EditEventListener#workflowObjectStatusChanged(org.openharmonise.rm.resources.lifecycle.EditEvent)
320      */

321     public void workflowObjectStatusChanged(EditEvent event) {
322         super.workflowObjectStatusChanged(event);
323
324     }
325
326     /* (non-Javadoc)
327      * @see org.openharmonise.rm.resources.lifecycle.EditEventListener#workflowObjectArchived(org.openharmonise.rm.resources.lifecycle.EditEvent)
328      */

329     public void workflowObjectArchived(EditEvent event) {
330         if (event.getSource() instanceof XMLResource) {
331             //if source was a XMLResource it was probably an include
332
//so we need to clear the cached xincluded doc
333
m_cached_xincludedDoc = null;
334         }
335         super.workflowObjectArchived(event);
336     }
337
338     /* (non-Javadoc)
339      * @see org.openharmonise.rm.resources.lifecycle.EditEventListener#workflowObjectReactivated(org.openharmonise.rm.resources.lifecycle.EditEvent)
340      */

341     public void workflowObjectReactivated(EditEvent event) {
342         super.workflowObjectReactivated(event);
343
344     }
345
346     /* (non-Javadoc)
347      * @see org.openharmonise.rm.resources.lifecycle.EditEventListener#workflowObjectLocked(org.openharmonise.rm.resources.lifecycle.EditEvent)
348      */

349     public void workflowObjectLocked(EditEvent event) {
350         super.workflowObjectLocked(event);
351
352     }
353
354     /* (non-Javadoc)
355      * @see org.openharmonise.rm.resources.lifecycle.EditEventListener#workflowObjectUnlocked(org.openharmonise.rm.resources.lifecycle.EditEvent)
356      */

357     public void workflowObjectUnlocked(EditEvent event) {
358         super.workflowObjectUnlocked(event);
359
360     }
361
362     /* (non-Javadoc)
363      * @see org.openharmonise.rm.resources.content.TextResource#setContent(java.lang.String)
364      */

365     public void setContent(String JavaDoc sContent) throws PopulateException {
366
367         // ensure that sContent is parseable XML
368
try {
369             StringReader sreader = new StringReader(sContent);
370
371             InputSource insource = new InputSource(sreader);
372
373             DocumentBuilderFactory factory = DocumentBuilderFactory
374                     .newInstance();
375
376             factory.setNamespaceAware(true);
377
378             DocumentBuilder builder = factory.newDocumentBuilder();
379             m_cached_doc = new XMLDocument(builder.parse(insource));
380             m_cached_xincludedDoc = null;
381         } catch (ParserConfigurationException e) {
382             throw new InvalidXMLContentException(e);
383         } catch (SAXException e) {
384             throw new InvalidXMLContentException(e);
385         } catch (IOException e) {
386             throw new InvalidXMLContentException(e);
387         }
388
389         super.setContent(sContent);
390     }
391
392 }
Popular Tags