001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements. See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership. The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the "License");
007 * you may not use this file except in compliance with the License.
008 * You may obtain a copy of the License at
009 *
010 * http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018 /*
019 * $Id: Hashtree2Node.java 475902 2006-11-16 20:03:16Z minchau $
020 */
021
022 package org.apache.xml.utils;
023
024 import java.util.ArrayList;
025 import java.util.Enumeration;
026 import java.util.Hashtable;
027 import java.util.Iterator;
028 import java.util.List;
029
030 import org.w3c.dom.Document;
031 import org.w3c.dom.Element;
032 import org.w3c.dom.Node;
033
034 /**
035 * Simple static utility to convert Hashtable to a Node.
036 *
037 * @see org.apache.xalan.xslt.EnvironmentCheck
038 * @see org.apache.xalan.lib.Extensions
039 * @author shane_curcuru@us.ibm.com
040 * @version $Id: Hashtree2Node.java 475902 2006-11-16 20:03:16Z minchau $
041 * @xsl.usage general
042 */
043 public abstract class Hashtree2Node
044 {
045
046 /**
047 * Convert a Hashtable into a Node tree.
048 *
049 * <p>The hash may have either Hashtables as values (in which
050 * case we recurse) or other values, in which case we print them
051 * as <item> elements, with a 'key' attribute with the value
052 * of the key, and the element contents as the value.</p>
053 *
054 * <p>If args are null we simply return without doing anything.
055 * If we encounter an error, we will attempt to add an 'ERROR'
056 * Element with exception info; if that doesn't work we simply
057 * return without doing anything else byt printStackTrace().</p>
058 *
059 * @param hash to get info from (may have sub-hashtables)
060 * @param name to use as parent element for appended node
061 * futurework could have namespace and prefix as well
062 * @param container Node to append our report to
063 * @param factory Document providing createElement, etc. services
064 */
065 public static void appendHashToNode(Hashtable hash, String name,
066 Node container, Document factory)
067 {
068 // Required arguments must not be null
069 if ((null == container) || (null == factory) || (null == hash))
070 {
071 return;
072 }
073
074 // name we will provide a default value for
075 String elemName = null;
076 if ((null == name) || ("".equals(name)))
077 elemName = "appendHashToNode";
078 else
079 elemName = name;
080
081 try
082 {
083 Element hashNode = factory.createElement(elemName);
084 container.appendChild(hashNode);
085
086 Enumeration keys = hash.keys();
087 List v = new ArrayList();
088
089 while (keys.hasMoreElements())
090 {
091 Object key = keys.nextElement();
092 String keyStr = key.toString();
093 Object item = hash.get(key);
094
095 if (item instanceof Hashtable)
096 {
097 // Ensure a pre-order traversal; add this hashes
098 // items before recursing to child hashes
099 // Save name and hash in two steps
100 v.add(keyStr);
101 v.add((Hashtable) item);
102 }
103 else
104 {
105 try
106 {
107 // Add item to node
108 Element node = factory.createElement("item");
109 node.setAttribute("key", keyStr);
110 node.appendChild(factory.createTextNode((String)item));
111 hashNode.appendChild(node);
112 }
113 catch (Exception e)
114 {
115 Element node = factory.createElement("item");
116 node.setAttribute("key", keyStr);
117 node.appendChild(factory.createTextNode("ERROR: Reading " + key + " threw: " + e.toString()));
118 hashNode.appendChild(node);
119 }
120 }
121 }
122
123 // Now go back and do the saved hashes
124 Iterator it = v.iterator();
125 while (it.hasNext())
126 {
127 // Retrieve name and hash in two steps
128 String n = (String) it.next();
129 Hashtable h = (Hashtable) it.next();
130
131 appendHashToNode(h, n, hashNode, factory);
132 }
133 }
134 catch (Exception e2)
135 {
136 // Ooops, just bail (suggestions for a safe thing
137 // to do in this case appreciated)
138 e2.printStackTrace();
139 }
140 }
141 }