/** * Copyright 2005 Open Cloud Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.mobicents.eclipslee.util.slee.xml; import java.io.IOException; import java.io.InputStream; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import org.apache.xerces.parsers.SAXParser; import org.w3c.dom.DOMImplementation; import org.w3c.dom.Document; import org.w3c.dom.DocumentType; import org.w3c.dom.Element; import org.w3c.dom.NodeList; import org.xml.sax.EntityResolver; import org.xml.sax.InputSource; import org.xml.sax.SAXException; /** * @author cath * * Basic XML file reading class. It's likely that you'll want to use * the component-specific version of this class. */ public class DTDXML extends XML { /** * Creates an empty XML file. * */ public DTDXML(String qualifiedName, String publicID, String systemID, EntityResolver resolver) throws ParserConfigurationException { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); factory.setValidating(true); DocumentBuilder builder = factory.newDocumentBuilder(); builder.setEntityResolver(resolver); builder.setErrorHandler(new XMLErrorHandler()); DOMImplementation impl = builder.getDOMImplementation(); DocumentType docType = impl.createDocumentType(qualifiedName, publicID, systemID); document = impl.createDocument(systemID, qualifiedName, docType); root = document.getDocumentElement(); } /** * Parse the provided InputStream as though it contains JAIN SLEE Event XML Data. * @param stream */ public DTDXML(InputStream stream, EntityResolver resolver) throws ParserConfigurationException, IOException, SAXException { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); factory.setValidating(true); DocumentBuilder builder = factory.newDocumentBuilder(); builder.setEntityResolver(resolver); builder.setErrorHandler(new XMLErrorHandler()); document = builder.parse(stream); root = document.getDocumentElement(); } protected void readDTDVia(EntityResolver resolver, InputSource dummyXML) { try { SAXParser parser = new SAXParser(); dtd = new DTDHandler(); parser.setEntityResolver(resolver); parser.setProperty("http://xml.org/sax/properties/declaration-handler", dtd); parser.parse(dummyXML); } catch (Exception e) { System.err.println("Exception thrown trying to read DTD."); e.printStackTrace(); } } /** * Creates a new XML object rooted at the specified element. * * @param document * @param root */ protected DTDXML(Document document, Element root, DTDHandler dtd) { super(document, root); this.dtd = dtd; } /** * Creates a new child element with the specified name and adds it to the parent * element at the location specified in the document's DTD. * @param parent * @param childName * @return */ protected Element addElement(Element parent, String childName) { Element child = document.createElement(childName); // Should be able to use the DTD to determine which elements to insert this before/after // Returns children in order. DTDHandler.Element ele = dtd.getElementDecl(parent.getNodeName()); String validChildren[] = ele.getChildren(); int childIndex = -1; for (int i = 0; i < validChildren.length; i++) { if (validChildren[i].equals(childName)) { childIndex = i; break; } } if (childIndex == -1) { System.err.println("Element " + childName + " is not a valid child of " + parent.getNodeName()); return null; // throw new Exception("Not a valid child of this node."); } NodeList children = parent.getChildNodes(); for (int i = childIndex + 1; i < validChildren.length; i++) { // Look for a current child with the specified index. // If found insert the new node before it. // If not found continue for (int j = 0; j < children.getLength(); j++) { if (children.item(j).getNodeName().equals(validChildren[i])) { parent.insertBefore(child, children.item(j)); return child; } } } // If still not found append to the parent element. parent.appendChild(child); return child; } protected DTDHandler dtd; }