1 package net.sf.saxon.style; 2 import net.sf.saxon.expr.*; 3 import net.sf.saxon.instruct.Executable; 4 import net.sf.saxon.om.AttributeCollection; 5 import net.sf.saxon.om.Axis; 6 import net.sf.saxon.sort.SortKeyDefinition; 7 import net.sf.saxon.trans.XPathException; 8 import net.sf.saxon.type.ItemType; 9 import net.sf.saxon.value.EmptySequence; 10 import net.sf.saxon.value.SequenceType; 11 import net.sf.saxon.value.StringValue; 12 13 import java.text.Collator ; 14 import java.util.Comparator ; 15 import java.util.Locale ; 16 17 20 21 public class XSLSort extends StyleElement { 22 23 private SortKeyDefinition sortKeyDefinition; 24 private Expression select; 25 private Expression order; 26 private Expression dataType = null; 27 private Expression caseOrder; 28 private Expression lang; 29 private Expression collationName; 30 31 35 36 public boolean mayContainSequenceConstructor() { 37 return true; 38 } 39 40 public void prepareAttributes() throws XPathException { 41 42 AttributeCollection atts = getAttributeList(); 43 44 String selectAtt = null; 45 String orderAtt = null; 46 String dataTypeAtt = null; 47 String caseOrderAtt = null; 48 String langAtt = null; 49 String collationAtt = null; 50 51 for (int a=0; a<atts.getLength(); a++) { 52 int nc = atts.getNameCode(a); 53 String f = getNamePool().getClarkName(nc); 54 if (f==StandardNames.SELECT) { 55 selectAtt = atts.getValue(a); 56 } else if (f==StandardNames.ORDER) { 57 orderAtt = atts.getValue(a).trim(); 58 } else if (f==StandardNames.DATA_TYPE) { 59 dataTypeAtt = atts.getValue(a).trim(); 60 } else if (f==StandardNames.CASE_ORDER) { 61 caseOrderAtt = atts.getValue(a).trim(); 62 } else if (f==StandardNames.LANG) { 63 langAtt = atts.getValue(a).trim(); 64 } else if (f==StandardNames.COLLATION) { 65 collationAtt = atts.getValue(a).trim(); 66 } else { 67 checkUnknownAttribute(nc); 68 } 69 } 70 71 if (selectAtt==null) { 72 } else { 74 select = makeExpression(selectAtt); 75 } 76 77 if (orderAtt == null) { 78 order = new StringValue("ascending"); 79 } else { 80 order = makeAttributeValueTemplate(orderAtt); 81 } 82 83 if (dataTypeAtt == null) { 84 dataType = EmptySequence.getInstance(); 85 } else { 86 dataType = makeAttributeValueTemplate(dataTypeAtt); 87 } 88 89 if (caseOrderAtt == null) { 90 caseOrder = new StringValue("#default"); 91 } else { 92 caseOrder = makeAttributeValueTemplate(caseOrderAtt); 93 } 94 95 if (langAtt == null) { 96 lang = new StringValue(Locale.getDefault().getLanguage()); 97 } else { 98 lang = makeAttributeValueTemplate(langAtt); 99 } 100 101 if (collationAtt != null) { 102 collationName = makeAttributeValueTemplate(collationAtt); 103 } 104 105 } 106 107 public void validate() throws XPathException { 108 if (select != null && hasChildNodes()) { 109 compileError("An xsl:sort element with a select attribute must be empty"); 110 } 111 if (select == null && !hasChildNodes()) { 112 select = new ContextItemExpression(); 113 } 114 115 117 Comparator collator = null; 118 if (collationName instanceof StringValue) { 119 String uri = ((StringValue)collationName).getStringValue(); 120 collator = getPrincipalStylesheet().findCollation(uri); 121 if (collator==null) { 122 compileError("Collation " + uri + " has not been defined"); 123 collator = Collator.getInstance(); } 125 } 126 127 select = typeCheck("select", select); 128 order = typeCheck("order", order); 129 caseOrder = typeCheck("case-order", caseOrder); 130 lang = typeCheck("lang", lang); 131 dataType = typeCheck("data-type", dataType); 132 collationName = typeCheck("collation", collationName); 133 134 if (select != null) { 135 try { 136 RoleLocator role = 137 new RoleLocator(RoleLocator.INSTRUCTION, "xsl:sort/select", 0, null); 138 role.setSourceLocator(new ExpressionLocation(this)); 139 select = TypeChecker.staticTypeCheck(select, 140 SequenceType.ATOMIC_SEQUENCE, 141 false, role, getStaticContext()); 142 } catch (XPathException err) { 143 compileError(err); 144 } 145 } 146 147 sortKeyDefinition = new SortKeyDefinition(); 148 sortKeyDefinition.setOrder(order); 149 sortKeyDefinition.setCaseOrder(caseOrder); 150 sortKeyDefinition.setLanguage(lang); 151 sortKeyDefinition.setSortKey(select); 152 sortKeyDefinition.setDataTypeExpression(dataType); 153 sortKeyDefinition.setCollationName(collationName); 154 sortKeyDefinition.setCollation(collator); 155 } 156 157 165 166 protected ItemType getReturnedItemType() { 167 return null; 168 } 169 170 public Expression compile(Executable exec) throws XPathException { 171 if (select == null) { 172 Expression b = compileSequenceConstructor(exec, iterateAxis(Axis.CHILD), true); 173 if (b instanceof ComputedExpression) { 174 ((ComputedExpression)b).setParentExpression(this); 175 } 176 if (b == null) { 177 b = EmptySequence.getInstance(); 178 } 179 try { 180 StaticContext env = getStaticContext(); 181 Atomizer atomizedSortKey = new Atomizer(b.simplify(env), env.getConfiguration()); 182 atomizedSortKey.setParentExpression(sortKeyDefinition.getParentExpression()); 183 sortKeyDefinition.setSortKey(atomizedSortKey); 184 } catch (XPathException e) { 185 compileError(e); 186 } 187 } 188 sortKeyDefinition = sortKeyDefinition.simplify(exec); 191 return null; 193 } 194 195 public SortKeyDefinition getSortKeyDefinition() { 196 return sortKeyDefinition; 197 } 198 199 200 } 201 202 | Popular Tags |