env.java
来自「RESIN 3.2 最新源码」· Java 代码 · 共 759 行 · 第 1/2 页
JAVA
759 行
/* * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved * * This file is part of Resin(R) Open Source * * Each copy or derived work must preserve the copyright notice and this * notice unmodified. * * Resin Open Source is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Resin Open Source 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, or any warranty * of NON-INFRINGEMENT. See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License * along with Resin Open Source; if not, write to the * Free SoftwareFoundation, Inc. * 59 Temple Place, Suite 330 * Boston, MA 02111-1307 USA * * @author Scott Ferguson */package com.caucho.xpath;import com.caucho.util.FreeList;import com.caucho.xml.XmlUtil;import com.caucho.xpath.expr.ObjectVar;import com.caucho.xpath.expr.Var;import com.caucho.xpath.pattern.AbstractPattern;import com.caucho.xpath.pattern.NodeIterator;import org.w3c.dom.Document;import org.w3c.dom.Element;import org.w3c.dom.Node;import java.util.ArrayList;import java.util.HashMap;import java.util.Iterator;/** * Global and local variable environment. The April XSLT draft introduces * global and local variables. The Env class contains those bindings. * * <p>Because this class exists only to support XSL, it makes a number * of assumptions that would be invalid for a typical API. Specifically, * the variable names <font color='red'>must</font> be interned strings, i.e. * variable matching uses '==', not equals. * * <p>Local variables are handled like a stack. They are pushed and * popped as necessary. The top variables shadow bottom variables. * * <p>In other words, although the API somewhat resembles a HashMap, * it can't be used as a generic hash map. */public class Env implements ExprEnvironment { static FreeList<Env> _freeList = new FreeList<Env>(32); HashMap _ids; HashMap _idCache; Element _lastElement; HashMap<String,Var> _globals; // = new HashMap(); HashMap _functions; HashMap _cache; String []_varKeys; Var []_varValues; int _varSize; private Node _currentNode; private Node _contextNode; private int _positionIndex; private boolean _hasMorePositions; private int _useCount; private Env _parent; private Env _root; private ExprEnvironment _exprEnv; private AbstractPattern _select; private int _position; private int _size; private StylesheetEnv _stylesheetEnv; private VarEnv _varEnv; static Env create() { Env env = null; // (Env) freeList.allocate(); if (env == null) env = new Env(); env._root = env; return env; } public void setStylesheetEnv(StylesheetEnv stylesheetEnv) { _stylesheetEnv = stylesheetEnv; } public StylesheetEnv getStylesheetEnv() { for (Env env = this; env != null; env = env._parent) if (env._stylesheetEnv != null) return env._stylesheetEnv; return null; } /** * Sets the variable environment. */ public void setVarEnv(VarEnv varEnv) { _varEnv = varEnv; } /** * Returns the variable environment. */ public VarEnv getVarEnv() { return _varEnv; } /** * Initialize the XPath environment with values from the parent. */ void init(Env parent) { _parent = parent; _root = parent._root; } /** * Initialize the XPath environment with a context and a select node. */ void init(Env parent, AbstractPattern select, Node currentNode) { _parent = parent; _root = parent._root; _select = select; _currentNode = currentNode; } /** * Initialize the XPath environment with values from the parent. */ void initMacro(Env parent) { _parent = parent; _root = parent._root; _select = parent._select; _stylesheetEnv = parent._stylesheetEnv; _exprEnv = parent._exprEnv; _currentNode = parent._currentNode; _contextNode = parent._contextNode; _position = parent._position; _size = parent._size; _positionIndex = 0; _hasMorePositions = false; _useCount = 0; } /** * Clears all values in the local environment. */ public void clear() { if (true) return; _useCount++; if (_ids != null) { _ids.clear(); _idCache.clear(); } while (_varSize-- > 0) { _varKeys[_varSize] = null; _varValues[_varSize] = null; } _varSize = 0; _lastElement = null; _globals.clear(); _functions = null; _cache = null; _currentNode = null; _contextNode = null; _parent = null; _select = null; _size = 0; _position = 0; _positionIndex = 0; _hasMorePositions = false; } /** * Returns the parent envivonment. */ Env getParent() { return _parent; } /** * Returns the current number of local variables. */ public int getVarSize() { return _varSize; } /** * Sets the current number of local variables (popping, them). */ public void setVarSize(int size) { if (_varKeys == null) return; for (; _varSize > size; _varSize--) { _varSize--; _varKeys[_varSize] = null; _varValues[_varSize] = null; } } /** * Returns the value associated with name. * * <p><em>name must be interned</em> */ public Var getVar(String name) { for (int i = _varSize - 1; i >= 0; i--) { if (_varKeys[i] == name) return _varValues[i]; } if (_root._globals != null) { Var var = _root._globals.get(name); if (var != null) return var; } if (_root._varEnv != null) return _root._varEnv.getVar(name); else return null; } /** * Adds the value associated with name. * * <p><em>name must be interned</em> */ public int addVar(String name, Object value) { _useCount++; if (value instanceof Iterator) value = iteratorToList((Iterator) value); if (! (value instanceof Var)) value = new ObjectVar(value); return addVar(name, (Var) value); } /** * Sets the value associated with name. * * <p><em>name must be interned</em> */ public void setVar(String name, Object value) { _useCount++; if (value instanceof Iterator) value = iteratorToList((Iterator) value); if (! (value instanceof Var)) value = new ObjectVar(value); for (int i = _varSize - 1; i >= 0; i--) { if (_varKeys[i] == name) { _varValues[i] = (Var) value; return; } } addVar(name, (Var) value); } /** * Adds the value associated with name. * * <p><em>name must be interned</em> */ public int addVar(String name, Var value) { _useCount++; if (_varKeys == null) { _varKeys = new String[16]; _varValues = new Var[16]; } else if (_varSize == _varKeys.length) { String []newKeys = new String[2 * _varKeys.length]; Var []newValues = new Var[2 * _varKeys.length]; System.arraycopy(_varKeys, 0, newKeys, 0, _varSize); System.arraycopy(_varValues, 0, newValues, 0, _varSize); _varKeys = newKeys; _varValues = newValues; } _varKeys[_varSize] = name; _varValues[_varSize] = value; _varSize++; return _varSize - 1; } /** * Pops the last count vars from the local stack. */ public void popVars(int count) { _useCount++; if (_varKeys == null) return; for (; count > 0 && _varSize > 0; count--) { _varSize--; _varKeys[_varSize] = null; _varValues[_varSize].free(); _varValues[_varSize] = null; } } /** * Returns the top of the stack. */ public int getTop() { return _varSize; } /** * Pops the last count vars from the local stack. */ public void popToTop(int top) { _useCount++; if (_varKeys == null) return; while (top < _varSize) { _varSize--; _varKeys[_varSize] = null; _varValues[_varSize].free(); _varValues[_varSize] = null; } }
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?