1 package com.icl.saxon; 2 3 import com.icl.saxon.om.*; 4 import com.icl.saxon.pattern.Pattern; 5 import com.icl.saxon.expr.Expression; 6 import com.icl.saxon.pattern.AnyNodeTest; 7 import com.icl.saxon.expr.Value; 8 import com.icl.saxon.expr.NodeSetValue; 9 import com.icl.saxon.om.NodeEnumeration; 10 import com.icl.saxon.expr.NodeSetExtent; 11 import com.icl.saxon.om.Axis; 12 import com.icl.saxon.om.SingletonEnumeration; 13 import com.icl.saxon.om.EmptyEnumeration; 14 import com.icl.saxon.expr.XPathException; 15 import com.icl.saxon.sort.LocalOrderComparer; 16 17 import java.util.*; 18 19 24 25 public class KeyManager { 26 27 private Hashtable keyList; 30 33 34 public KeyManager() { 35 keyList = new Hashtable(); 36 } 37 38 43 44 public void setKeyDefinition(KeyDefinition keydef) { 45 Integer keykey = new Integer(keydef.getFingerprint()); 46 Vector v = (Vector)keyList.get(keykey); 47 if (v==null) { 48 v = new Vector(); 49 keyList.put(keykey, v); 50 } 51 v.addElement(keydef); 52 } 53 54 59 60 public Vector getKeyDefinitions(int fingerprint) { 61 return (Vector)keyList.get(new Integer(fingerprint)); 62 } 63 64 71 72 private synchronized Hashtable buildIndex(int fingerprint, 73 DocumentInfo doc, 74 Controller controller) throws XPathException { 75 76 Vector definitions = getKeyDefinitions(fingerprint); 77 if (definitions==null) { 78 throw new XPathException("Key " + 79 controller.getNamePool().getDisplayName(fingerprint) + 80 " has not been defined"); 81 } 82 83 Hashtable index = new Hashtable(); 84 85 for (int k=0; k<definitions.size(); k++) { 86 constructIndex(doc, index, (KeyDefinition)definitions.elementAt(k), 87 controller, k==0); 88 } 89 90 return index; 91 92 } 93 94 97 98 private void constructIndex( DocumentInfo doc, 99 Hashtable index, 100 KeyDefinition keydef, 101 Controller controller, 102 boolean isFirst) throws XPathException { 103 104 Pattern match = keydef.getMatch(); 105 Expression use = keydef.getUse(); 106 NodeInfo sourceRoot = doc; 107 NodeInfo curr = sourceRoot; 108 Context c = controller.makeContext(doc); 109 110 short type = match.getNodeType(); 111 112 NodeEnumeration all = 113 doc.getEnumeration( Axis.DESCENDANT, 114 AnyNodeTest.getInstance()); 115 116 117 if (type==NodeInfo.ATTRIBUTE || type==NodeInfo.NODE) { 118 while(all.hasMoreElements()) { 119 curr = all.nextElement(); 120 if (curr.getNodeType()==NodeInfo.ELEMENT) { 121 NodeEnumeration atts = 122 curr.getEnumeration(Axis.ATTRIBUTE, AnyNodeTest.getInstance()); 123 while (atts.hasMoreElements()) { 124 processKeyNode(atts.nextElement(), match, use, index, c, isFirst); 125 } 126 if (type==NodeInfo.NODE) { 127 processKeyNode(curr, match, use, index, c, isFirst); 129 } 130 } else { 131 processKeyNode(curr, match, use, index, c, isFirst); 132 } 133 } 134 135 } else { 136 while(all.hasMoreElements()) { 137 curr = all.nextElement(); 138 processKeyNode(curr, match, use, index, c, isFirst); 139 } 140 } 141 } 142 143 146 147 private void processKeyNode(NodeInfo curr, Pattern match, Expression use, 148 Hashtable index, Context c, boolean isFirst) throws XPathException { 149 if (match.matches(curr, c)) { 150 c.setContextNode(curr); 151 c.setCurrentNode(curr); 152 c.setPosition(1); 153 c.setLast(1); 154 Value useval = use.evaluate(c); 155 if (useval instanceof NodeSetValue) { 156 NodeEnumeration enum = ((NodeSetValue)useval).enumerate(); 158 while (enum.hasMoreElements()) { 159 NodeInfo node = (NodeInfo)enum.nextElement(); 160 String val = node.getStringValue(); 161 NodeSetExtent nodes = (NodeSetExtent)index.get(val); 162 if (nodes==null) { 163 nodes = new NodeSetExtent(LocalOrderComparer.getInstance()); 164 nodes.setSorted(true); 165 index.put(val, nodes); 166 } 167 nodes.append(curr); 168 if (!isFirst) { 169 nodes.setSorted(false); 173 nodes.sort(); 174 } 175 } 176 } else { 177 String val = useval.asString(); 178 c.setContextNode(curr); 179 NodeSetExtent nodes = (NodeSetExtent)index.get(val); 180 if (nodes==null) { 181 nodes = new NodeSetExtent(LocalOrderComparer.getInstance()); 182 nodes.setSorted(true); 183 index.put(val, nodes); 184 } 185 nodes.append(curr); 186 if (!isFirst) { 187 nodes.setSorted(false); 191 nodes.sort(); 192 } 193 } 194 } 195 } 196 197 205 206 public NodeEnumeration selectByKey( int fingerprint, 207 DocumentInfo doc, 208 String value, 209 Controller controller) throws XPathException { 210 211 Hashtable index = doc.getKeyIndex(this, fingerprint); 212 if (index==null) { 213 index = buildIndex(fingerprint, doc, controller); 214 doc.setKeyIndex(this, fingerprint, index); 215 } 216 NodeSetExtent nodes = (NodeSetExtent)index.get(value); 217 return (nodes==null ? EmptyEnumeration.getInstance() : nodes.enumerate()); 218 } 219 220 } 221 222 | Popular Tags |