/* * eXist Open Source Native XML Database * Copyright (C) 2001-06 Wolfgang M. Meier * wolfgang@exist-db.org * http://exist.sourceforge.net * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * $Id$ */ package org.exist.xquery; import org.exist.dom.DocumentSet; import org.exist.xquery.util.ExpressionDumper; import org.exist.xquery.value.Item; import org.exist.xquery.value.Sequence; import org.exist.xquery.value.Type; /** * Represents a reference to an in-scope variable. * * @author wolf */ public class VariableReference extends AbstractExpression { private final String qname; public VariableReference(XQueryContext context, String qname) { super(context); this.qname = qname; } /* (non-Javadoc) * @see org.exist.xquery.Expression#analyze(org.exist.xquery.AnalyzeContextInfo) */ public void analyze(AnalyzeContextInfo contextInfo) throws XPathException { Variable var = null; try { var = getVariable(); } catch (XPathException e) { // ignore: variable might not be known yet return; } if (var == null) throw new XPathException(this, "XPDY0002 : variable '$" + qname + "' is not set."); if (!var.isInitialized()) throw new XPathException(this, "XQST0054: variable declaration of '$" + qname + "' cannot " + "be executed because of a circularity."); contextInfo.setStaticReturnType(var.getStaticType()); } /* (non-Javadoc) * @see org.exist.xquery.Expression#eval(org.exist.xquery.StaticContext, org.exist.dom.DocumentSet, org.exist.xquery.value.Sequence, org.exist.xquery.value.Item) */ public Sequence eval(Sequence contextSequence, Item contextItem) throws XPathException { if (context.getProfiler().isEnabled()) { context.getProfiler().start(this); context.getProfiler().message(this, Profiler.DEPENDENCIES, "DEPENDENCIES", Dependency.getDependenciesName(this.getDependencies())); if (contextSequence != null) context.getProfiler().message(this, Profiler.START_SEQUENCES, "CONTEXT SEQUENCE", contextSequence); if (contextItem != null) context.getProfiler().message(this, Profiler.START_SEQUENCES, "CONTEXT ITEM", contextItem.toSequence()); } Variable var = getVariable(); if (var == null) throw new XPathException(this, "XPDY0002 : variable '$" + qname + "' is not set."); Sequence seq = var.getValue(); if (seq == null) throw new XPathException(this, "XPDY0002 : undefined value for variable '$" + qname + "'"); Sequence result = seq; if (context.getProfiler().isEnabled()) context.getProfiler().end(this, "", result); return result; } protected Variable getVariable() throws XPathException { try { return context.resolveVariable(qname); } catch (XPathException e) { e.setLocation(line, column); throw e; } } /* (non-Javadoc) * @see org.exist.xquery.Expression#preselect(org.exist.dom.DocumentSet, org.exist.xquery.StaticContext) */ public DocumentSet preselect(DocumentSet in_docs) throws XPathException { return in_docs; } /* (non-Javadoc) * @see org.exist.xquery.Expression#dump(org.exist.xquery.util.ExpressionDumper) */ public void dump(ExpressionDumper dumper) { dumper.display('$').display(qname); } public String toString() { return "$" + qname; } /* (non-Javadoc) * @see org.exist.xquery.Expression#returnsType() */ public int returnsType() { try { Variable var = context.resolveVariable(qname); if(var != null) { if (var.getValue() != null) { int type = var.getValue().getItemType(); return type; } else { return var.getType(); } } } catch (XPathException e) { } return Type.ITEM; } /* (non-Javadoc) * @see org.exist.xquery.AbstractExpression#getDependencies() */ public int getDependencies() { try { Variable var = context.resolveVariable(qname); if (var != null) { int deps = var.getDependencies(context); return deps; } } catch (XPathException e) { } return Dependency.CONTEXT_SET + Dependency.CONTEXT_ITEM; } /* (non-Javadoc) * @see org.exist.xquery.AbstractExpression#getCardinality() */ public int getCardinality() { try { Variable var = context.resolveVariable(qname); if (var != null && var.getValue() != null) { int card = var.getValue().getCardinality(); return card; } } catch (XPathException e) { } return Cardinality.ZERO_OR_MORE; // unknown cardinality } /* (non-Javadoc) * @see org.exist.xquery.AbstractExpression#resetState() */ public void resetState(boolean postOptimization) { super.resetState(postOptimization); } public void accept(ExpressionVisitor visitor) { visitor.visitVariableReference(this); } }