1 package net.sf.saxon.event; 2 import net.sf.saxon.om.NamePool; 3 import net.sf.saxon.om.NamespaceConstant; 4 import net.sf.saxon.om.NamespaceResolver; 5 import net.sf.saxon.trans.XPathException; 6 7 import java.util.ArrayList ; 8 import java.util.Iterator ; 9 import java.util.List ; 10 11 20 21 public class NamespaceReducer extends ProxyReceiver implements NamespaceResolver 22 { 23 25 28 34 private int[] namespaces = new int[50]; private int namespacesSize = 0; private int[] countStack = new int[50]; 37 private int depth = 0; 38 39 44 private boolean[] disinheritStack = new boolean[50]; 45 46 private int[] pendingUndeclarations = null; 47 48 52 53 public void startElement(int nameCode, int typeCode, int locationId, int properties) throws XPathException { 54 55 super.startElement(nameCode, typeCode, locationId, properties); 56 57 60 if (depth>0 && disinheritStack[depth-1]) { 61 pendingUndeclarations = new int[namespacesSize]; 62 System.arraycopy(namespaces, 0, pendingUndeclarations, 0, namespacesSize); 63 } else { 64 pendingUndeclarations = null; 65 } 66 67 69 countStack[depth] = 0; 70 disinheritStack[depth] = (properties & ReceiverOptions.DISINHERIT_NAMESPACES) != 0; 71 if (++depth >= countStack.length) { 72 int[] newstack = new int[depth*2]; 73 System.arraycopy(countStack, 0, newstack, 0, depth); 74 boolean[] disStack2 = new boolean[depth*2]; 75 System.arraycopy(disinheritStack, 0, disStack2, 0, depth); 76 countStack = newstack; 77 disinheritStack = disStack2; 78 } 79 80 81 85 if ((properties & ReceiverOptions.NAMESPACE_OK) == 0) { 86 namespace(getNamePool().allocateNamespaceCode(nameCode), 0); 87 } 88 89 } 90 91 public void namespace(int namespaceCode, int properties) throws XPathException { 92 93 95 if (isNeeded(namespaceCode)) { 96 addToStack(namespaceCode); 97 countStack[depth - 1]++; 98 super.namespace(namespaceCode, properties); 99 } 100 } 101 102 105 106 120 123 124 private boolean isNeeded(int nscode) { 125 if (nscode==NamespaceConstant.XML_NAMESPACE_CODE) { 126 return false; 128 } 129 130 132 if (pendingUndeclarations != null) { 133 for (int p=0; p<pendingUndeclarations.length; p++) { 134 if ((nscode>>16) == (pendingUndeclarations[p]>>16)) { 135 pendingUndeclarations[p] = -1; 136 } 138 } 139 } 140 141 for (int i=namespacesSize-1; i>=0; i--) { 142 if (namespaces[i]==nscode) { 143 return false; 145 } 146 if ((namespaces[i]>>16) == (nscode>>16)) { 147 return true; 149 } 150 } 151 152 return (nscode != NamespaceConstant.NULL_NAMESPACE_CODE); 154 } 155 156 159 160 private void addToStack(int nscode) { 161 if (namespacesSize+1 >= namespaces.length) { 163 int[] newlist = new int[namespacesSize*2]; 164 System.arraycopy(namespaces, 0, newlist, 0, namespacesSize); 165 namespaces = newlist; 166 } 167 namespaces[namespacesSize++] = nscode; 168 } 169 170 174 175 public void startContent() throws XPathException { 176 177 if (pendingUndeclarations != null) { 178 for (int i=0; i<pendingUndeclarations.length; i++) { 179 int nscode = pendingUndeclarations[i]; 180 if (nscode != -1) { 181 namespace(nscode & 0xffff0000, 0); 182 } 184 } 185 } 186 pendingUndeclarations = null; 187 super.startContent(); 188 } 189 190 193 194 195 public void endElement () throws XPathException 196 { 197 if (depth-- == 0) { 198 throw new IllegalStateException ("Attempt to output end tag with no matching start tag"); 199 } 200 201 int nscount = countStack[depth]; 202 namespacesSize -= nscount; 203 204 super.endElement(); 205 206 } 207 208 214 215 protected short getURICode(short prefixCode) { 216 for (int i=namespacesSize-1; i>=0; i--) { 217 if ((namespaces[i]>>16) == (prefixCode)) { 218 return (short)(namespaces[i]&0xffff); 219 } 220 } 221 if (prefixCode == 0) { 222 return 0; } else { 224 return -1; 225 } 226 } 227 228 237 238 public String getURIForPrefix(String prefix, boolean useDefault) { 239 NamePool pool = getNamePool(); 240 if ("".equals(prefix) && !useDefault) { 241 return ""; 242 } else if ("xml".equals(prefix)) { 243 return NamespaceConstant.XML; 244 } else { 245 short prefixCode = pool.getCodeForPrefix(prefix); 246 short uriCode = getURICode(prefixCode); 247 if (uriCode == -1) { 248 return null; 249 } 250 return pool.getURIFromURICode(uriCode); 251 } 252 } 253 254 258 259 public Iterator iteratePrefixes() { 260 NamePool pool = getNamePool(); 261 List prefixes = new ArrayList (namespacesSize); 262 for (int i=namespacesSize-1; i>=0; i--) { 263 String prefix = pool.getPrefixFromNamespaceCode(namespaces[i]); 264 if (!prefixes.contains(prefix)) { 265 prefixes.add(prefix); 266 } 267 } 268 prefixes.add("xml"); 269 return prefixes.iterator(); 270 } 271 } 272 273 | Popular Tags |