001/** 002 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 003 * 004 * Copyright (c) 2006 Sun Microsystems Inc. All Rights Reserved 005 * 006 * The contents of this file are subject to the terms 007 * of the Common Development and Distribution License 008 * (the License). You may not use this file except in 009 * compliance with the License. 010 * 011 * You can obtain a copy of the License at 012 * https://opensso.dev.java.net/public/CDDLv1.0.html or 013 * opensso/legal/CDDLv1.0.txt 014 * See the License for the specific language governing 015 * permission and limitations under the License. 016 * 017 * When distributing Covered Code, include this CDDL 018 * Header Notice in each file and include the License file 019 * at opensso/legal/CDDLv1.0.txt. 020 * If applicable, add the following below the CDDL Header, 021 * with the fields enclosed by brackets [] replaced by 022 * your own identifying information: 023 * "Portions Copyrighted [year] [name of copyright owner]" 024 * 025 * $Id: WebtopParser.java,v 1.3 2008/06/25 05:41:29 qcheng Exp $ 026 * 027 */ 028/** 029 * Portions Copyrighted 2012 ForgeRock Inc 030 */ 031package com.iplanet.dpro.parser; 032 033 034import com.sun.identity.shared.xml.XMLUtils; 035import java.io.ByteArrayInputStream; 036import java.io.FileInputStream; 037import java.io.IOException; 038import java.io.InputStream; 039import java.io.UnsupportedEncodingException; 040import java.util.Hashtable; 041import java.util.Vector; 042import javax.xml.parsers.DocumentBuilder; 043import javax.xml.parsers.ParserConfigurationException; 044import org.w3c.dom.Document; 045import org.w3c.dom.Element; 046import org.w3c.dom.NamedNodeMap; 047import org.w3c.dom.Node; 048import org.xml.sax.SAXException; 049import org.xml.sax.SAXParseException; 050 051/** 052 * XMLParser provides a way for applications to handle a hook into 053 * applications and applications and its server. 054 * 055 * @supported.all.api 056 */ 057public class WebtopParser { 058 private Hashtable elemmap = new Hashtable(); 059 private boolean useGenericClass = false; 060 061 static public void main(String argv[]) throws Exception { 062 WebtopParser wp = new WebtopParser(true); 063 GenericNode n = (GenericNode) wp.parse(new FileInputStream(argv[0])); 064 System.out.println("FINAL:"+n.toString()); 065 } 066 067 /** 068 * Parses and processes a Node. 069 * 070 * @param nd The Node to parse. 071 * @return the parsed object for the node. 072 * @throws Exception if node cannot be parsed or <code>ParseOutput</code> 073 * object cannot be instantiated. 074 */ 075 ParseOutput walkTree(Node nd) 076 throws Exception 077 { 078 Vector elements = new Vector(); 079 Vector retelements; 080 String pcdata = null; 081 Hashtable atts = new Hashtable(); 082 NamedNodeMap nd_map = nd.getAttributes(); 083 if (nd_map != null) { 084 for (int i=0; i < nd_map.getLength(); i++) { 085 Node att = nd_map.item(i); 086 atts.put(att.getNodeName(), att.getNodeValue()); 087 } 088 } 089 for (Node ch = nd.getFirstChild(); 090 ch != null; ch = ch.getNextSibling()) { 091 switch (ch.getNodeType()) { 092 case Node.ELEMENT_NODE : 093 elements.addElement(walkTree(ch)); 094 break; 095 case Node.TEXT_NODE : 096 String tmp = stripWhitespaces(ch.getNodeValue()); 097 if (tmp != null && tmp.length() !=0) { 098 pcdata = tmp; 099 } 100 break; 101 default : 102 } 103 } 104 // lookup hash 105 String po_name = (String) elemmap.get(nd.getNodeName()); 106 ParseOutput po; 107 if (po_name == null) { 108 if (useGenericClass) { 109 po = (ParseOutput) new GenericNode(); 110 } else { 111 throw new Exception("No class registered for"+nd.getNodeName()); 112 } 113 } else { 114 try { 115 po = (ParseOutput) Class.forName(po_name).newInstance(); 116 } catch(Exception ex) { 117 StringBuilder buf = new StringBuilder(); 118 buf.append("Got Exception while creating class instance of "); 119 buf.append(nd.getNodeName()); 120 buf.append(" :"); 121 buf.append(ex.toString()); 122 throw new Exception(buf.toString()); 123 } 124 } 125 po.process(nd.getNodeName(), elements, atts, pcdata); 126 return po; 127 } 128 129 /** 130 * Removes leading and trailing whitespace. 131 * 132 * @param s String from which to remove whitespace. 133 * @return String with leading and trailing whitespace removed. 134 */ 135 String stripWhitespaces(String s) { 136 return s.trim(); 137 } 138 139 /** 140 * Constructs a <code>WebtopParser</code> instance. 141 */ 142 public WebtopParser() { 143 } 144 145 /** 146 * Sets whether to use the default <code>GenericNode</code> as the node 147 * type. 148 * 149 * @param usegeneric <code>true</code> if <code>GenericNode</code> type is 150 * to be used. 151 */ 152 public WebtopParser(boolean usegeneric) { 153 useGenericClass = usegeneric; 154 } 155 156 /** 157 * Parses an XML document from a String variable. 158 * 159 * @param s The XML document. 160 * @throws Exception if there are unsupported encoding issues. 161 */ 162 public Object parse(String s) throws Exception { 163 ByteArrayInputStream bin = null; 164 String st = stripWhitespaces(s); 165 try { 166 bin = new ByteArrayInputStream(st.getBytes("UTF-8")); 167 } catch(UnsupportedEncodingException ex) { 168 throw new Exception("Encoding not supported:" + ex.toString()); 169 } 170 return parse(bin); 171 } 172 173 /** 174 * Parses an XML document. 175 * 176 * @param xmlin the XML document. 177 * @return the ParseOutput object from walking and processing the node. 178 * @throws Exception if there are IO or XML parsing exceptions. 179 */ 180 public Object parse(InputStream xmlin) 181 throws Exception 182 { 183 DocumentBuilder db = null; 184 try { 185 db = XMLUtils.getSafeDocumentBuilder(false); 186 } catch (ParserConfigurationException e) { 187 throw new Exception("DBG:Got ParserConfigurationException:" + 188 e.toString()); 189 } 190 191 Document doc = null; 192 try { 193 doc = db.parse(xmlin); 194 } catch(SAXParseException e) { 195 throw new Exception("DBG:Got SAXParseException:" + 196 e.toString() + "line:" +e.getLineNumber() + 197 " col :" + e.getColumnNumber()); 198 } catch (SAXException e) { 199 throw new Exception("DBG:Got SAXException:" +e.toString()); 200 } catch (IOException ex) { 201 throw new Exception("DBG: Got IOException:" + ex.toString()); 202 } 203 204 Element elem = doc.getDocumentElement(); 205 return(walkTree(elem)); 206 } 207 208 /** 209 * Registers a call back function. 210 * 211 * @param elemname The tag name of this node. 212 * @param classname The call back function. 213 */ 214 public void register(String elemname, String classname) { 215 if (elemmap == null) { 216 elemmap = new Hashtable(); 217 } 218 elemmap.put(elemname, classname); 219 } 220} 221