001: package net.sf.saxon.functions;
002:
003: import net.sf.saxon.expr.Expression;
004: import net.sf.saxon.expr.StaticContext;
005: import net.sf.saxon.expr.StaticProperty;
006: import net.sf.saxon.expr.XPathContext;
007: import net.sf.saxon.om.Item;
008: import net.sf.saxon.om.NodeInfo;
009: import net.sf.saxon.style.StandardNames;
010: import net.sf.saxon.trans.DynamicError;
011: import net.sf.saxon.trans.XPathException;
012: import net.sf.saxon.value.BooleanValue;
013:
014: public class Lang extends SystemFunction {
015:
016: /**
017: * preEvaluate: this method suppresses compile-time evaluation by doing nothing
018: */
019:
020: public Expression preEvaluate(StaticContext env) {
021: return this ;
022: }
023:
024: /**
025: * Evaluate in a general context
026: */
027:
028: public Item evaluateItem(XPathContext c) throws XPathException {
029: NodeInfo target;
030: if (argument.length > 1) {
031: target = (NodeInfo) argument[1].evaluateItem(c);
032: } else {
033: Item current = c.getContextItem();
034: if (current == null) {
035: DynamicError err = new DynamicError(
036: "The context item is undefined");
037: err.setErrorCode("FONC0001");
038: err.setXPathContext(c);
039: throw err;
040: }
041: if (!(current instanceof NodeInfo)) {
042: DynamicError err = new DynamicError(
043: "The context item is not a node");
044: err.setErrorCode("FOTY0011");
045: err.setXPathContext(c);
046: throw err;
047: }
048: target = (NodeInfo) current;
049: }
050: final Item arg0Val = argument[0].evaluateItem(c);
051: final String testLang = (arg0Val == null ? "" : arg0Val
052: .getStringValue());
053: boolean b = isLang(testLang, target);
054: return BooleanValue.get(b);
055: }
056:
057: /**
058: * Determine the dependencies
059: */
060:
061: public int getIntrinsicDependencies() {
062: return StaticProperty.DEPENDS_ON_CONTEXT_ITEM;
063: }
064:
065: /**
066: * Test whether the context node has the given language attribute
067: * @param arglang the language being tested
068: * @param target the target node
069: */
070:
071: private boolean isLang(String arglang, NodeInfo target) {
072:
073: String doclang = null;
074: NodeInfo node = target;
075:
076: while (node != null) {
077: doclang = node.getAttributeValue(StandardNames.XML_LANG);
078: if (doclang != null)
079: break;
080: node = node.getParent();
081: if (node == null)
082: return false;
083: }
084:
085: if (doclang == null)
086: return false;
087:
088: if (arglang.equalsIgnoreCase(doclang))
089: return true;
090: int hyphen = doclang.indexOf("-");
091: if (hyphen < 0)
092: return false;
093: doclang = doclang.substring(0, hyphen);
094: if (arglang.equalsIgnoreCase(doclang))
095: return true;
096: return false;
097: }
098:
099: }
100:
101: //
102: // The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
103: // you may not use this file except in compliance with the License. You may obtain a copy of the
104: // License at http://www.mozilla.org/MPL/
105: //
106: // Software distributed under the License is distributed on an "AS IS" basis,
107: // WITHOUT WARRANTY OF ANY KIND, either express or implied.
108: // See the License for the specific language governing rights and limitations under the License.
109: //
110: // The Original Code is: all this file.
111: //
112: // The Initial Developer of the Original Code is Michael H. Kay.
113: //
114: // Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
115: //
116: // Contributor(s): none.
117: //
|