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 + -
显示快捷键?