1 23 24 package org.enhydra.xml.xmlc.compiler; 25 26 import java.util.ArrayList ; 27 import java.util.HashMap ; 28 import java.util.Iterator ; 29 import java.util.List ; 30 import java.util.Map ; 31 import java.util.SortedMap ; 32 import java.util.TreeMap ; 33 34 import org.enhydra.xml.xmlc.XMLCError; 35 import org.enhydra.xml.xmlc.XMLCException; 36 import org.enhydra.xml.xmlc.dom.XMLCDocument; 37 import org.enhydra.xml.xmlc.metadata.MetaData; 38 import org.w3c.dom.Element ; 39 import org.w3c.dom.NamedNodeMap ; 40 import org.w3c.dom.Node ; 41 42 45 public class ElementTable { 46 49 private XMLCDocument fXmlcDoc; 50 51 54 private MetaData fMetaData; 55 56 59 private Map fElements = new HashMap (); 60 61 64 private SortedMap fXmlIds = new TreeMap (); 65 66 69 private SortedMap fJavaIds = new TreeMap (); 70 71 75 private SortedMap fInvalidElementIds; 76 77 80 private boolean fGlobalIdAttrMode; 81 82 86 private Map fTagName2IdAttrName; 87 88 92 private Map fTagName2ElementInfoList; 93 94 97 private int fDocumentNodeSize; 98 99 102 public ElementTable(MetaData metaData, 103 XMLCDocument xmlcDoc) throws XMLCException { 104 fMetaData = metaData; 105 fXmlcDoc = xmlcDoc; 106 107 fGlobalIdAttrMode = (fXmlcDoc.getGlobalIdAttribute() != null); 108 if (!fGlobalIdAttrMode) { 109 fTagName2IdAttrName = new HashMap (); 110 fTagName2ElementInfoList = new HashMap (); 111 } 112 fDocumentNodeSize = addElements(fXmlcDoc.getDocument()); 113 } 114 115 118 private int getRecursiveNodeCount(Node node) { 119 int count = getNodeCount(node); 120 121 for (Node child = node.getFirstChild(); child != null; 122 child = child.getNextSibling()) { 123 count += getRecursiveNodeCount(child); 124 } 125 return count; 126 } 127 128 132 private int getNodeCount(Node node) { 133 int count = 1; NamedNodeMap attrs = node.getAttributes(); 135 if (attrs != null) { 136 int len = attrs.getLength(); 137 for (int idx = 0; idx < len; idx++) { 138 count += getRecursiveNodeCount(attrs.item(idx)); 139 } 140 } 141 return count; 142 } 143 144 147 private void recordLocalIdAttributeInfo(ElementInfo elementInfo, 148 Element element) { 149 String tagName = element.getTagName(); 150 151 fTagName2IdAttrName.put(tagName, fXmlcDoc.getIdAttrName(element)); 152 153 List idElementList = (List )fTagName2ElementInfoList.get(tagName); 154 if (idElementList == null) { 155 idElementList = new ArrayList (); 156 fTagName2ElementInfoList.put(tagName, idElementList); 157 } 158 idElementList.add(elementInfo); 159 } 160 161 164 private void addElement(Element element, 165 int nodeSize, 166 int subTreeSize) throws XMLCException { 167 ElementInfo elementInfo 168 = new ElementInfo(element, nodeSize, subTreeSize, 169 fMetaData, fXmlcDoc); 170 171 String javaId = elementInfo.getJavaId(); 173 if (javaId != null) { 174 if (fJavaIds.containsKey(javaId)) { 176 throw new XMLCException("Duplicate element id \"" + elementInfo.getXmlId() 177 + "\", id must be unique after first character is capitalized"); 178 } 179 fJavaIds.put(javaId, elementInfo); 180 } 181 182 fElements.put(element, elementInfo); 184 185 if (elementInfo.hasInvalidJavaId()) { 187 if (fInvalidElementIds == null) { 189 fInvalidElementIds = new TreeMap (); 190 } 191 fInvalidElementIds.put(elementInfo.getXmlId(), 192 elementInfo); 193 } else { 194 String xmlId = elementInfo.getXmlId(); 196 if (xmlId != null) { 197 fXmlIds.put(xmlId, elementInfo); 198 } 199 } 200 201 if (!fGlobalIdAttrMode) { 202 recordLocalIdAttributeInfo(elementInfo, element); 203 } 204 } 205 206 211 private int addElements(Node node) throws XMLCException { 212 int nodeSize = getNodeCount(node); 213 int childSize = 0; 214 for (Node child = node.getFirstChild(); child != null; 215 child = child.getNextSibling()) { 216 childSize += addElements(child); 217 } 218 if (node instanceof Element ) { 219 addElement((Element )node, nodeSize, nodeSize+childSize); 220 } 221 return nodeSize+childSize; 222 } 223 224 227 public XMLCDocument getXMLCDocument() { 228 return fXmlcDoc; 229 } 230 231 234 public int getDocumentNodeSize() { 235 return fDocumentNodeSize; 236 } 237 238 241 public boolean isGlobalIdAttrMode() { 242 return fGlobalIdAttrMode; 243 } 244 245 246 249 public ElementInfo getElementInfo(Element element) { 250 ElementInfo info = (ElementInfo)fElements.get(element); 251 if (info == null) { 252 throw new XMLCError("element not found in element info table"); 253 } 254 return info; 255 } 256 257 260 public Iterator getElements() { 261 return fElements.values().iterator(); 262 } 263 264 267 public Iterator getJavaIdElements() { 268 return fJavaIds.values().iterator(); 269 } 270 271 275 public Iterator getElementsByTagName(String tagName) { 276 return ((List )fTagName2ElementInfoList.get(tagName)).iterator(); 277 } 278 279 283 public Iterator getTagNames() { 284 if (fGlobalIdAttrMode) { 285 return null; } else { 287 return fTagName2IdAttrName.keySet().iterator(); 288 } 289 } 290 291 294 public String getIdAttributeName(String tagName) { 295 return (String )fTagName2IdAttrName.get(tagName); 297 } 298 299 303 public Iterator getInvalidElementIds() { 304 if (fInvalidElementIds != null) { 305 return fInvalidElementIds.keySet().iterator(); 306 } else { 307 return null; 308 } 309 } 310 } 311 | Popular Tags |