1 package com.icl.saxon.sort; 2 import com.icl.saxon.*; 3 import com.icl.saxon.om.Name; 4 5 import com.icl.saxon.expr.*; 6 import javax.xml.transform.TransformerException ; 7 8 17 18 19 public class SortKeyDefinition { 20 21 private Expression sortKey; 22 private Expression order; 23 private Expression dataType; 24 private Expression caseOrder; 25 private Expression language; 26 private StaticContext staticContext; 27 28 private Comparer comparer = null; 29 30 33 34 public void setSortKey(Expression exp) { 35 sortKey = exp; 36 } 37 38 43 44 public void setOrder(Expression exp) { 45 order = exp; 46 } 47 48 53 54 public void setDataType(Expression exp) { 55 dataType = exp; 56 } 57 58 63 64 public void setCaseOrder(Expression exp) { 65 caseOrder = exp; 66 } 67 68 73 74 public void setLanguage(Expression exp) { 75 language = exp; 76 } 77 78 82 83 public void setStaticContext(StaticContext sc) { 84 staticContext = sc; 85 } 86 87 88 public Expression getSortKey() { 89 return sortKey; 90 } 91 92 public Expression getOrder() { 93 return (order==null ? new StringValue("ascending") : order); 94 } 95 96 public Expression getDataType() { 97 return (dataType==null ? new StringValue("text") : dataType); 98 } 99 100 public Expression getCaseOrder() { 101 return (caseOrder==null ? new StringValue("#default") : caseOrder); 102 } 103 104 public Expression getLanguage() { 105 return (language==null ? new StringValue("en") : language); 106 } 107 108 111 112 public void bindComparer() throws XPathException { 113 if ((dataType instanceof StringValue) && 114 (order instanceof StringValue) && 115 (caseOrder instanceof StringValue) && 116 (language instanceof StringValue)) { 117 comparer = makeComparer(null); 118 } 119 } 120 121 124 125 public Comparer getComparer(Context context) throws XPathException { 126 if (comparer==null) { 127 return makeComparer(context); 128 } else { 129 return comparer; 130 } 132 } 133 134 137 138 private Comparer makeComparer(Context context) throws XPathException { 139 140 Comparer comp; 141 boolean isAscending; 142 143 String orderAtt; 144 if (order==null) { 145 orderAtt="ascending"; 146 } else { 147 orderAtt = order.evaluateAsString(context); 148 } 149 150 if (orderAtt.equals("ascending")) { 151 isAscending = true; 152 } else if (orderAtt.equals("descending")) { 153 isAscending = false; 154 } else { 155 throw new XPathException("order must be ascending or descending"); 156 } 157 158 String dataTypeURI; 159 String dataTypeLocalName; 160 161 String dataTypeAtt; 162 if (dataType==null) { 163 dataTypeAtt = "text"; 164 } else { 165 dataTypeAtt = dataType.evaluateAsString(context); 166 } 167 168 if (dataTypeAtt.equals("text")) { 169 dataTypeURI = null; 170 dataTypeLocalName = null; 171 } else if (dataTypeAtt.equals("number")) { 172 dataTypeURI = null; 173 dataTypeLocalName = null; 174 } else { 175 String prefix = Name.getPrefix(dataTypeAtt); 176 if (prefix.equals("")) { 177 throw new XPathException("data-type must be text, number, or a prefixed name"); 178 } 179 180 dataTypeURI = staticContext.getURIForPrefix(prefix); 181 dataTypeLocalName = Name.getLocalName(dataTypeAtt); 182 } 183 184 int caseOrderValue; 185 String caseOrderAtt; 186 if (caseOrder==null) { 187 caseOrderAtt = "#default"; 188 } else { 189 caseOrderAtt = caseOrder.evaluateAsString(context); 190 } 191 192 if (caseOrderAtt.equals("#default")) { 193 caseOrderValue = TextComparer.DEFAULT_CASE_ORDER; 194 } else if (caseOrderAtt.equals("lower-first")) { 195 caseOrderValue = TextComparer.LOWERCASE_FIRST; 196 } else if (caseOrderAtt.equals("upper-first")) { 197 caseOrderValue = TextComparer.UPPERCASE_FIRST; 198 } else { 199 throw new XPathException("case-order must be lower-first or upper-first"); 200 } 201 202 203 204 if (dataTypeAtt.equals("text")) { 205 if (language==null) { 206 comp = new StringComparer(); 207 } else { 208 String langValue = language.evaluateAsString(context); 209 String userClassName = "com.icl.saxon.sort.Compare_"; 210 for (int i=0; i<langValue.length(); i++) { 211 if (Character.isLetter(langValue.charAt(i))) { 212 userClassName += langValue.charAt(i); 213 } 214 } 215 try { 216 comp = loadComparer(userClassName); 217 } catch (Exception err) { 218 comp = new Compare_en(); 220 } 221 } 222 223 } else if (dataTypeAtt.equals("number")) { 224 comp = new DoubleComparer(); 225 } else { 226 try { 227 comp = loadComparer(dataTypeLocalName); 228 } catch (Exception err) { 229 System.err.println("Warning: no comparer " + dataTypeLocalName + " found; using default"); 230 comp = new StringComparer(); 231 } 232 } 233 234 comp = comp.setDataType(dataTypeURI, dataTypeLocalName); 235 comp = comp.setOrder(isAscending); 236 if (comp instanceof TextComparer) { 237 comp = ((TextComparer)comp).setCaseOrder(caseOrderValue); 238 } 239 240 241 return comp; 242 } 243 244 247 248 private static TextComparer loadComparer (String className) throws XPathException 249 { 250 try { 251 return (TextComparer)Loader.getInstance(className); 252 } catch (ClassCastException e) { 253 throw new XPathException("Failed to load TextComparer " + className + 254 ": it does not implement the TextComparer interface"); 255 } catch (TransformerException err) { 256 if (err instanceof XPathException) { 257 throw (XPathException)err; 258 } else { 259 throw new XPathException(err); 260 } 261 } 262 } 263 264 } 265 266 267 | Popular Tags |