001: /*
002: * Copyright 1999-2004 The Apache Software Foundation.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016: /*
017: * $Id: ElemSort.java,v 1.12 2004/08/17 18:35:33 jycli Exp $
018: */
019: package org.apache.xalan.templates;
020:
021: import org.apache.xalan.res.XSLTErrorResources;
022: import org.apache.xpath.XPath;
023:
024: import org.w3c.dom.DOMException;
025: import org.w3c.dom.Node;
026:
027: /**
028: * Implement xsl:sort.
029: * <pre>
030: * <!ELEMENT xsl:sort EMPTY>
031: * <!ATTLIST xsl:sort
032: * select %expr; "."
033: * lang %avt; #IMPLIED
034: * data-type %avt; "text"
035: * order %avt; "ascending"
036: * case-order %avt; #IMPLIED
037: * >
038: * <!-- xsl:sort cannot occur after any other elements or
039: * any non-whitespace character -->
040: * </pre>
041: * @see <a href="http://www.w3.org/TR/xslt#sorting">sorting in XSLT Specification</a>
042: * @xsl.usage advanced
043: */
044: public class ElemSort extends ElemTemplateElement {
045: static final long serialVersionUID = -4991510257335851938L;
046:
047: /**
048: * xsl:sort has a select attribute whose value is an expression.
049: * @serial
050: */
051: private XPath m_selectExpression = null;
052:
053: /**
054: * Set the "select" attribute.
055: * xsl:sort has a select attribute whose value is an expression.
056: * For each node to be processed, the expression is evaluated
057: * with that node as the current node and with the complete
058: * list of nodes being processed in unsorted order as the current
059: * node list. The resulting object is converted to a string as if
060: * by a call to the string function; this string is used as the
061: * sort key for that node. The default value of the select attribute
062: * is ., which will cause the string-value of the current node to
063: * be used as the sort key.
064: *
065: * @param v Value to set for the "select" attribute
066: */
067: public void setSelect(XPath v) {
068:
069: if (v.getPatternString().indexOf("{") < 0)
070: m_selectExpression = v;
071: else
072: error(XSLTErrorResources.ER_NO_CURLYBRACE, null);
073: }
074:
075: /**
076: * Get the "select" attribute.
077: * xsl:sort has a select attribute whose value is an expression.
078: * For each node to be processed, the expression is evaluated
079: * with that node as the current node and with the complete
080: * list of nodes being processed in unsorted order as the current
081: * node list. The resulting object is converted to a string as if
082: * by a call to the string function; this string is used as the
083: * sort key for that node. The default value of the select attribute
084: * is ., which will cause the string-value of the current node to
085: * be used as the sort key.
086: *
087: * @return The value of the "select" attribute
088: */
089: public XPath getSelect() {
090: return m_selectExpression;
091: }
092:
093: /**
094: * lang specifies the language of the sort keys.
095: * @serial
096: */
097: private AVT m_lang_avt = null;
098:
099: /**
100: * Set the "lang" attribute.
101: * lang specifies the language of the sort keys; it has the same
102: * range of values as xml:lang [XML]; if no lang value is
103: * specified, the language should be determined from the system environment.
104: *
105: * @param v The value to set for the "lang" attribute
106: */
107: public void setLang(AVT v) {
108: m_lang_avt = v;
109: }
110:
111: /**
112: * Get the "lang" attribute.
113: * lang specifies the language of the sort keys; it has the same
114: * range of values as xml:lang [XML]; if no lang value is
115: * specified, the language should be determined from the system environment.
116: *
117: * @return The value of the "lang" attribute
118: */
119: public AVT getLang() {
120: return m_lang_avt;
121: }
122:
123: /**
124: * data-type specifies the data type of the
125: * strings to be sorted.
126: * @serial
127: */
128: private AVT m_dataType_avt = null;
129:
130: /**
131: * Set the "data-type" attribute.
132: * <code>data-type</code> specifies the data type of the
133: * strings; the following values are allowed:
134: * <ul>
135: * <li>
136: * <code>text</code> specifies that the sort keys should be
137: * sorted lexicographically in the culturally correct manner for the
138: * language specified by <code>lang</code>.
139: * </li>
140: * <li>
141: * <code>number</code> specifies that the sort keys should be
142: * converted to numbers and then sorted according to the numeric value;
143: * the sort key is converted to a number as if by a call to the
144: * <b><a href="http://www.w3.org/TR/xpath#function-number">number</a></b> function; the <code>lang</code>
145: * attribute is ignored.
146: * </li>
147: * <li>
148: * A <a href="http://www.w3.org/TR/REC-xml-names#NT-QName">QName</a> with a prefix
149: * is expanded into an <a href="http://www.w3.org/TR/xpath#dt-expanded-name">expanded-name</a> as described
150: * in <a href="#qname">[<b>2.4 Qualified Names</b>]</a>; the expanded-name identifies the data-type;
151: * the behavior in this case is not specified by this document.
152: * </li>
153: * </ul>
154: * <p>The default value is <code>text</code>.</p>
155: * <blockquote>
156: * <b>NOTE: </b>The XSL Working Group plans that future versions of XSLT will
157: * leverage XML Schemas to define further values for this
158: * attribute.</blockquote>
159: *
160: * @param v Value to set for the "data-type" attribute
161: */
162: public void setDataType(AVT v) {
163: m_dataType_avt = v;
164: }
165:
166: /**
167: * Get the "data-type" attribute.
168: * <code>data-type</code> specifies the data type of the
169: * strings; the following values are allowed:
170: * <ul>
171: * <li>
172: * <code>text</code> specifies that the sort keys should be
173: * sorted lexicographically in the culturally correct manner for the
174: * language specified by <code>lang</code>.
175: * </li>
176: * <li>
177: * <code>number</code> specifies that the sort keys should be
178: * converted to numbers and then sorted according to the numeric value;
179: * the sort key is converted to a number as if by a call to the
180: * <b><a href="http://www.w3.org/TR/xpath#function-number">number</a></b> function; the <code>lang</code>
181: * attribute is ignored.
182: * </li>
183: * <li>
184: * A <a href="http://www.w3.org/TR/REC-xml-names#NT-QName">QName</a> with a prefix
185: * is expanded into an <a href="http://www.w3.org/TR/xpath#dt-expanded-name">expanded-name</a> as described
186: * in <a href="#qname">[<b>2.4 Qualified Names</b>]</a>; the expanded-name identifies the data-type;
187: * the behavior in this case is not specified by this document.
188: * </li>
189: * </ul>
190: * <p>The default value is <code>text</code>.</p>
191: * <blockquote>
192: * <b>NOTE: </b>The XSL Working Group plans that future versions of XSLT will
193: * leverage XML Schemas to define further values for this
194: * attribute.</blockquote>
195: *
196: * @return The value of the "data-type" attribute
197: */
198: public AVT getDataType() {
199: return m_dataType_avt;
200: }
201:
202: /**
203: * order specifies whether the strings should be sorted in ascending
204: * or descending order.
205: * @serial
206: */
207: private AVT m_order_avt = null;
208:
209: /**
210: * Set the "order" attribute.
211: * order specifies whether the strings should be sorted in ascending
212: * or descending order; ascending specifies ascending order; descending
213: * specifies descending order; the default is ascending.
214: *
215: * @param v The value to set for the "order" attribute
216: */
217: public void setOrder(AVT v) {
218: m_order_avt = v;
219: }
220:
221: /**
222: * Get the "order" attribute.
223: * order specifies whether the strings should be sorted in ascending
224: * or descending order; ascending specifies ascending order; descending
225: * specifies descending order; the default is ascending.
226: *
227: * @return The value of the "order" attribute
228: */
229: public AVT getOrder() {
230: return m_order_avt;
231: }
232:
233: /**
234: * case-order has the value upper-first or lower-first.
235: * The default value is language dependent.
236: * @serial
237: */
238: private AVT m_caseorder_avt = null;
239:
240: /**
241: * Set the "case-order" attribute.
242: * case-order has the value upper-first or lower-first; this applies
243: * when data-type="text", and specifies that upper-case letters should
244: * sort before lower-case letters or vice-versa respectively.
245: * For example, if lang="en", then A a B b are sorted with
246: * case-order="upper-first" and a A b B are sorted with case-order="lower-first".
247: * The default value is language dependent.
248: *
249: * @param v The value to set for the "case-order" attribute
250: *
251: * @serial
252: */
253: public void setCaseOrder(AVT v) {
254: m_caseorder_avt = v;
255: }
256:
257: /**
258: * Get the "case-order" attribute.
259: * case-order has the value upper-first or lower-first; this applies
260: * when data-type="text", and specifies that upper-case letters should
261: * sort before lower-case letters or vice-versa respectively.
262: * For example, if lang="en", then A a B b are sorted with
263: * case-order="upper-first" and a A b B are sorted with case-order="lower-first".
264: * The default value is language dependent.
265: *
266: * @return The value of the "case-order" attribute
267: */
268: public AVT getCaseOrder() {
269: return m_caseorder_avt;
270: }
271:
272: /**
273: * Get an int constant identifying the type of element.
274: * @see org.apache.xalan.templates.Constants
275: *
276: * @return The token ID of the element
277: */
278: public int getXSLToken() {
279: return Constants.ELEMNAME_SORT;
280: }
281:
282: /**
283: * Return the node name.
284: *
285: * @return The element's name
286: */
287: public String getNodeName() {
288: return Constants.ELEMNAME_SORT_STRING;
289: }
290:
291: /**
292: * Add a child to the child list.
293: *
294: * @param newChild Child to add to the child list
295: *
296: * @return Child just added to the child list
297: *
298: * @throws DOMException
299: */
300: public Node appendChild(Node newChild) throws DOMException {
301:
302: error(XSLTErrorResources.ER_CANNOT_ADD, new Object[] {
303: newChild.getNodeName(), this .getNodeName() }); //"Can not add " +((ElemTemplateElement)newChild).m_elemName +
304:
305: //" to " + this.m_elemName);
306: return null;
307: }
308:
309: /**
310: * This function is called after everything else has been
311: * recomposed, and allows the template to set remaining
312: * values that may be based on some other property that
313: * depends on recomposition.
314: */
315: public void compose(StylesheetRoot sroot)
316: throws javax.xml.transform.TransformerException {
317: super .compose(sroot);
318: StylesheetRoot.ComposeState cstate = sroot.getComposeState();
319: java.util.Vector vnames = cstate.getVariableNames();
320: if (null != m_caseorder_avt)
321: m_caseorder_avt.fixupVariables(vnames, cstate
322: .getGlobalsSize());
323: if (null != m_dataType_avt)
324: m_dataType_avt.fixupVariables(vnames, cstate
325: .getGlobalsSize());
326: if (null != m_lang_avt)
327: m_lang_avt.fixupVariables(vnames, cstate.getGlobalsSize());
328: if (null != m_order_avt)
329: m_order_avt.fixupVariables(vnames, cstate.getGlobalsSize());
330: if (null != m_selectExpression)
331: m_selectExpression.fixupVariables(vnames, cstate
332: .getGlobalsSize());
333: }
334: }
|