typefactory.java

来自「RESIN 3.2 最新源码」· Java 代码 · 共 870 行 · 第 1/2 页

JAVA
870
字号
/* * 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.config.type;import com.caucho.config.*;import com.caucho.config.attribute.*;import com.caucho.config.program.*;import com.caucho.config.types.RawString;import com.caucho.loader.*;import com.caucho.util.*;import com.caucho.vfs.*;import com.caucho.xml.QName;import java.beans.*;import java.io.*;import java.net.URL;import java.lang.reflect.*;import java.util.*;import java.util.concurrent.atomic.*;import java.util.regex.Pattern;import java.util.logging.*;import javax.annotation.*;import javax.el.*;import javax.sql.*;import org.w3c.dom.Node;/** * Factory for returning type strategies. */public class TypeFactory implements AddLoaderListener{  private static final Logger log    = Logger.getLogger(TypeFactory.class.getName());  private static L10N L = new L10N(TypeFactory.class);  private static final HashMap<Class,ConfigType> _primitiveTypes    = new HashMap<Class,ConfigType>();    private static final EnvironmentLocal<TypeFactory> _localFactory    = new EnvironmentLocal<TypeFactory>();  private static final Object _introspectLock = new Object();  private final EnvironmentClassLoader _loader;  private final TypeFactory _parent;  private final HashSet<URL> _configSet    = new HashSet<URL>();    private final HashMap<String,ConfigType> _typeMap    = new HashMap<String,ConfigType>();  private final HashMap<QName,ConfigType> _attrMap    = new HashMap<QName,ConfigType>();  private final HashMap<QName,Attribute> _listAttrMap    = new HashMap<QName,Attribute>();  private final HashMap<QName,Attribute> _setAttrMap    = new HashMap<QName,Attribute>();  private final HashMap<QName,Attribute> _envAttrMap    = new HashMap<QName,Attribute>();  private final HashMap<String,NamespaceConfig> _nsMap    = new HashMap<String,NamespaceConfig>();  private final HashSet<URL> _driverTypeSet    = new HashSet<URL>();    private final HashMap<String,HashMap<String,String>> _driverTypeMap    = new HashMap<String,HashMap<String,String>>();  private final AtomicBoolean _isInInit = new AtomicBoolean();    private TypeFactory(ClassLoader loader)  {    _loader = Environment.getEnvironmentClassLoader(loader);    if (_loader != null) {      _parent = getFactory(_loader.getParent());      _loader.addLoaderListener(this);    }    else      _parent = null;    init(loader);  }  /**   * Returns the appropriate strategy.   */  public static ConfigType getType(Class type)  {    TypeFactory factory = getFactory(type.getClassLoader());    return factory.getConfigTypeImpl(type);  }  /**   * Returns the appropriate strategy.   */  public static ConfigType getType(Type type)  {    return getType((Class) type);  }  public static TypeFactory create()  {    return getFactory();  }  public static TypeFactory getFactory()  {    return getFactory(Thread.currentThread().getContextClassLoader());  }  public static TypeFactory getFactory(ClassLoader loader)  {    if (loader == null)      loader = ClassLoader.getSystemClassLoader();    TypeFactory factory = _localFactory.getLevel(loader);    if (factory == null) {      factory = new TypeFactory(loader);      _localFactory.set(factory, loader);      factory.init(loader);    }    return factory;  }  /**   * Returns an environment type.   */  public ConfigType getEnvironmentType(QName name)  {    synchronized (_attrMap) {      ConfigType type = _attrMap.get(name);      if (type != null)	return type;      type = getEnvironmentTypeRec(name);      if (type != null) {	_attrMap.put(name, type);		return type;      }      if (! "".equals(name.getNamespaceURI())) {	type = getEnvironmentType(new QName(name.getLocalName()));	if (type != null) {	  _attrMap.put(name, type);		  return type;	}      }      return null;    }  }  /**   * Returns an environment type.   */  public ConfigType getEnvironmentTypeRec(QName name)  {    synchronized (_attrMap) {      ConfigType type = _attrMap.get(name);      if (type != null)	return type;      if (_parent != null)	type = _parent.getEnvironmentTypeRec(name);      if (type != null) {	_attrMap.put(name, type);		return type;      }      NamespaceConfig ns = _nsMap.get(name.getNamespaceURI());      if (ns == null) {	// XXX: xbeans and spring would go here      }      if (ns != null) {	ns.loadBeans();	type = ns.getBean(name.getLocalName());		if (type != null) {	  _attrMap.put(name, type);		  return type;	}      }      return null;    }  }  /**   * Returns an environment type.   */  public Attribute getListAttribute(QName name)  {    synchronized (_listAttrMap) {      Attribute attr = _listAttrMap.get(name);      if (attr != null)	return attr;      ConfigType type = getEnvironmentType(name);      if (type == null)	return null;      attr = new ListValueAttribute(type);      _listAttrMap.put(name, attr);      return attr;    }  }  /**   * Returns an environment type.   */  public Attribute getSetAttribute(QName name)  {    synchronized (_setAttrMap) {      Attribute attr = _setAttrMap.get(name);      if (attr != null)	return attr;      ConfigType type = getEnvironmentType(name);      if (type == null)	return null;      attr = new SetValueAttribute(type);      _setAttrMap.put(name, attr);      return attr;    }  }  /**   * Returns an environment type.   */  public Attribute getEnvironmentAttribute(QName name)  {    synchronized (_envAttrMap) {      Attribute attr = _envAttrMap.get(name);      if (attr != null)	return attr;      ConfigType type = getEnvironmentType(name);      if (type == null)	return null;      if (type instanceof FlowBeanType)	attr = new FlowAttribute(type);      else	attr = new EnvironmentAttribute(type);      _envAttrMap.put(name, attr);      return attr;    }  }  private ConfigType getConfigTypeImpl(Class type)  {    synchronized (_introspectLock) {      ConfigType strategy = _typeMap.get(type.getName());      if (strategy == null) {	strategy = _primitiveTypes.get(type);	if (strategy == null)	  strategy = createType(type);	_typeMap.put(type.getName(), strategy);	strategy.introspect();      }      return strategy;    }  }  private ConfigType createType(Class type)  {    PropertyEditor editor = null;    if (ConfigType.class.isAssignableFrom(type)) {      try {	return (ConfigType) type.newInstance();      } catch (Exception e) {	throw ConfigException.create(e);      }    }    else if ((editor = PropertyEditorManager.findEditor(type)) != null)      return new PropertyEditorType(type, editor);    else if (type.getEnumConstants() != null)      return new EnumType(type);    else if (Set.class.isAssignableFrom(type))      return new SetType(type);    else if (Collection.class.isAssignableFrom(type)	     && ! Queue.class.isAssignableFrom(type)) {      // jms/2300      return new ListType(type);    }    else if (Map.class.isAssignableFrom(type))      return new MapType(type);    else if (EnvironmentBean.class.isAssignableFrom(type))      return new EnvironmentBeanType(type);    else if (FlowBean.class.isAssignableFrom(type))      return new FlowBeanType(type);    else if (type.isArray()) {      Class compType = type.getComponentType();            return new ArrayType(getType(compType), compType);    }    else if (type.isInterface()) {      return new InterfaceType(type);    }    else if (Modifier.isAbstract(type.getModifiers())) {      return new AbstractBeanType(type);    }    else      return new BeanType(type);  }  /**   * Initialize the type strategy factory with files in META-INF/caucho   *   * @param loader the owning class loader   * @throws Exception   */  private void init(ClassLoader loader)  {    if (! _isInInit.getAndSet(true))      return;    try {      _nsMap.clear();      _driverTypeSet.clear();      _driverTypeMap.clear();            Enumeration<URL> urls	= loader.getResources("META-INF/caucho/com.caucho.config.namespace.xml");      while (urls.hasMoreElements()) {	URL url = urls.nextElement();	if (hasConfig(url))	  continue;	_configSet.add(url);	InputStream is = url.openStream();	try {	  new Config(loader).configure(this, is);	} finally {	  is.close();	}      }    } catch (RuntimeException e) {      throw e;    } catch (Exception e) {      throw ConfigException.create(e);    } finally {      _isInInit.set(false);    }  }  protected boolean hasConfig(URL url)  {    if (_configSet.contains(url))      return true;    else if (_parent != null)      return _parent.hasConfig(url);    else      return false;  }  /**   * Returns a driver by the url   */  public Class getDriverClassByUrl(Class api, String url)  {

⌨️ 快捷键说明

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