definitionstate.java

来自「RESIN 3.2 最新源码」· Java 代码 · 共 444 行

JAVA
444
字号
/* * 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 Software Foundation, Inc. *   59 Temple Place, Suite 330 *   Boston, MA 02111-1307  USA * * @author Scott Ferguson */package com.caucho.quercus.env;import com.caucho.quercus.Quercus;import com.caucho.quercus.QuercusException;import com.caucho.quercus.program.AbstractFunction;import com.caucho.quercus.program.ClassDef;import com.caucho.quercus.program.UnsetFunction;import com.caucho.util.Crc64;import com.caucho.util.L10N;import com.caucho.util.LruCache;import java.lang.ref.SoftReference;import java.lang.ref.WeakReference;import java.util.ArrayList;import java.util.Collections;import java.util.HashMap;import java.util.logging.Logger;/** * Represents the state of the definitions: functions, classes and * constants. */public final class DefinitionState {  private static final L10N L = new L10N(DefinitionState.class);  private static final Logger log    = Logger.getLogger(DefinitionState.class.getName());    private static final    LruCache<ClassKey,SoftReference<QuercusClass>> _classCache    = new LruCache<ClassKey,SoftReference<QuercusClass>>(4096);  private final Quercus _quercus;  private boolean _isStrict;  private HashMap<String, AbstractFunction> _funMap;  private HashMap<String, AbstractFunction> _lowerFunMap;  private HashMap<String, ClassDef> _classDefMap;  private HashMap<String, ClassDef> _lowerClassDefMap;  private boolean _isLazy;  // crc of the entries  private long _crc;  public DefinitionState(Quercus quercus)  {    _quercus = quercus;    _isStrict = quercus.isStrict();    _funMap = new HashMap<String, AbstractFunction>(256, 0.25F);    _classDefMap = new HashMap<String, ClassDef>(256, 0.25F);    if (! _isStrict) {      _lowerFunMap = new HashMap<String, AbstractFunction>(256, 0.25F);      _lowerClassDefMap = new HashMap<String, ClassDef>(256, 0.25F);    }  }  private DefinitionState(DefinitionState oldState)  {    this(oldState._quercus);    _funMap.putAll(oldState._funMap);    if (_lowerFunMap != null)      _lowerFunMap.putAll(oldState._lowerFunMap);    _classDefMap.putAll(oldState._classDefMap);    if (_lowerClassDefMap != null)      _lowerClassDefMap.putAll(oldState._lowerClassDefMap);    _crc = oldState._crc;  }  private DefinitionState(DefinitionState oldState, boolean isLazy)  {    _isLazy = true;        _quercus = oldState._quercus;    _isStrict = oldState._isStrict;    _funMap = oldState._funMap;    _lowerFunMap = oldState._lowerFunMap;    _classDefMap = oldState._classDefMap;    _lowerClassDefMap = oldState._lowerClassDefMap;        _crc = oldState._crc;  }  /**   * Returns true for strict mode.   */  public final boolean isStrict()  {    return _isStrict;  }  /**   * Returns the owning PHP engine.   */  public Quercus getQuercus()  {    return _quercus;  }  /**   * returns the crc.   */  public long getCrc()  {    return _crc;  }  /**   * Returns an array of the defined functions.   */  public ArrayValue getDefinedFunctions()  {    ArrayValue result = new ArrayValueImpl();    ArrayValue internal = _quercus.getDefinedFunctions();    ArrayValue user = new ArrayValueImpl();    // XXX: i18n    result.put(new StringBuilderValue("internal"), internal);    result.put(new StringBuilderValue("user"), user);    for (String name : _funMap.keySet()) {      StringValue key = new StringBuilderValue(name);      if (! internal.contains(key).isset())        user.put(name);    }    return result;  }  /**   * Finds the java reflection method for the function with the given name.   *   * @param name the method name   * @return the found method or null if no method found.   */  public AbstractFunction findFunction(String name)  {    AbstractFunction fun = _funMap.get(name);    if (fun == null) {    }    else if (fun instanceof UnsetFunction) {      UnsetFunction unsetFun = (UnsetFunction) fun;      if (_crc == unsetFun.getCrc())	return null;    }    else {      return fun;    }        if (_lowerFunMap != null) {      fun = _lowerFunMap.get(name.toLowerCase());      if (fun != null) {        // copyOnWrite();        _funMap.put(name, fun);        return fun;      }    }    fun = findModuleFunction(name);    if (fun != null) {      // copyOnWrite();      _funMap.put(name, fun);      return fun;    }    else {      // copyOnWrite();      _funMap.put(name, new UnsetFunction(_crc));            return null;    }  }  /**   * Finds the java reflection method for the function with the given name.   *   * @param name the method name   * @return the found method or null if no method found.   */  private AbstractFunction findModuleFunction(String name)  {    AbstractFunction fun = null;    fun = _quercus.findFunction(name);    if (fun != null)      return fun;    return fun;  }  /**   * Adds a function, e.g. from an include.   */  public Value addFunction(String name, AbstractFunction fun)  {    AbstractFunction oldFun = findFunction(name);    if (oldFun != null) {      throw new QuercusException(L.l("can't redefine function {0}", name));    }    copyOnWrite();    _funMap.put(name, fun);    _crc = Crc64.generate(_crc, name);    if (_lowerFunMap != null)      _lowerFunMap.put(name.toLowerCase(), fun);    return BooleanValue.TRUE;  }  /**   * Adds a function from a compiled include   *   * @param name the function name, must be an intern() string   * @param lowerName the function name, must be an intern() string   */  public Value addFunction(String name, String lowerName, AbstractFunction fun)  {    // XXX: skip the old function check since the include for compiled    // pages is already verified.  Might have a switch here?    /*    AbstractFunction oldFun = _lowerFunMap.get(lowerName);    if (oldFun == null)      oldFun = _quercus.findLowerFunctionImpl(lowerName);    if (oldFun != null) {      throw new QuercusException(L.l("can't redefine function {0}", name));    }    */    copyOnWrite();    _funMap.put(name, fun);    _crc = Crc64.generate(_crc, name);    if (_lowerFunMap != null)      _lowerFunMap.put(lowerName, fun);    return BooleanValue.TRUE;  }  /**   * Adds a class, e.g. from an include.   */  public void addClassDef(String name, ClassDef cl)  {    copyOnWrite();    _classDefMap.put(name, cl);    _crc = Crc64.generate(_crc, name);    if (_lowerClassDefMap != null)      _lowerClassDefMap.put(name.toLowerCase(), cl);  }  /**   * Adds a class, e.g. from an include.   */  public ClassDef findClassDef(String name)  {    ClassDef def = _classDefMap.get(name);    if (def != null)      return def;    if (_lowerClassDefMap != null)      def = _lowerClassDefMap.get(name.toLowerCase());    return def;  }  /**   * Returns the declared classes.   *   * @return an array of the declared classes()   */  public Value getDeclaredClasses(Env env)  {    ArrayList<String> names = new ArrayList<String>();    /*    for (String name : _classMap.keySet()) {      if (! names.contains(name))        names.add(name);    }    */    for (String name : _classDefMap.keySet()) {      if (! names.contains(name))        names.add(name);    }    for (String name : _quercus.getClassMap().keySet()) {      if (! names.contains(name))        names.add(name);    }    Collections.sort(names);    ArrayValue array = new ArrayValueImpl();    for (String name : names) {      array.put(env.createString(name));    }    return array;  }  public DefinitionState copy()  {    return new DefinitionState(this);  }  public DefinitionState copyLazy()  {    return new DefinitionState(this, true);  }  private void copyOnWrite()  {    if (! _isLazy)      return;        _isLazy = false;    _funMap = new HashMap<String, AbstractFunction>(_funMap);    if (_lowerFunMap != null) {      _lowerFunMap = new HashMap<String, AbstractFunction>(_lowerFunMap);    }    _classDefMap = new HashMap<String, ClassDef>(_classDefMap);    if (_lowerClassDefMap != null) {      _lowerClassDefMap = new HashMap<String, ClassDef>(_lowerClassDefMap);    }  }  static class ClassKey {    private final WeakReference<ClassDef> _defRef;    private final WeakReference<QuercusClass> _parentRef;    ClassKey(ClassDef def, QuercusClass parent)    {      _defRef = new WeakReference<ClassDef>(def);      if (parent != null)	_parentRef = new WeakReference<QuercusClass>(parent);      else	_parentRef = null;    }    public int hashCode()    {      int hash = 37;      ClassDef def = _defRef.get();            QuercusClass parent = null;      if (_parentRef != null)	parent = _parentRef.get();      if (def != null)	hash = 65521 * hash + def.hashCode();      if (parent != null)	hash = 65521 * hash + parent.hashCode();      return hash;    }    public boolean equals(Object o)    {      ClassKey key = (ClassKey) o;      ClassDef aDef = _defRef.get();      ClassDef bDef = key._defRef.get();      if (aDef != bDef)	return false;      if (_parentRef == key._parentRef)	return true;            else if (_parentRef != null && key._parentRef != null)	return _parentRef.get() == key._parentRef.get();      else	return false;    }  }}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?