javaclassdef.java
来自「RESIN 3.2 最新源码」· Java 代码 · 共 1,630 行 · 第 1/3 页
JAVA
1,630 行
/* * 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.program;import com.caucho.quercus.Quercus;import com.caucho.quercus.QuercusModuleException;import com.caucho.quercus.QuercusException;import com.caucho.quercus.QuercusRuntimeException;import com.caucho.quercus.annotation.*;import com.caucho.quercus.env.*;import com.caucho.quercus.expr.Expr;import com.caucho.quercus.expr.LiteralExpr;import com.caucho.quercus.function.JavaMarshal;import com.caucho.quercus.function.Marshal;import com.caucho.quercus.function.MarshalFactory;import com.caucho.quercus.module.ModuleContext;import com.caucho.util.L10N;import com.caucho.vfs.WriteStream;import java.io.IOException;import java.lang.annotation.Annotation;import java.lang.reflect.Constructor;import java.lang.reflect.Field;import java.lang.reflect.Method;import java.lang.reflect.Modifier;import java.math.BigDecimal;import java.math.BigInteger;import java.net.URL;import java.util.*;import java.util.logging.Level;import java.util.logging.Logger;/** * Represents an introspected Java class. */public class JavaClassDef extends ClassDef { private final static Logger log = Logger.getLogger(JavaClassDef.class.getName()); private final static L10N L = new L10N(JavaClassDef.class); private final ModuleContext _moduleContext; private final String _name; private final Class _type; private final HashSet<String> _instanceOfSet = new HashSet<String>(); private final boolean _isAbstract; private final boolean _isInterface; private final boolean _isDelegate; private String _resourceType; private JavaClassDef _componentDef; protected volatile boolean _isInit; private final HashMap<String, Value> _constMap = new HashMap<String, Value>(); private final MethodMap<AbstractJavaMethod> _functionMap = new MethodMap<AbstractJavaMethod>(); private final HashMap<StringValue, AbstractJavaMethod> _getMap = new HashMap<StringValue, AbstractJavaMethod>(); private final HashMap<StringValue, AbstractJavaMethod> _setMap = new HashMap<StringValue, AbstractJavaMethod>(); // _fieldMap stores all public non-static fields // used by getField and setField private final HashMap<StringValue, FieldMarshalPair> _fieldMap = new HashMap<StringValue, FieldMarshalPair> (); private AbstractJavaMethod _cons; private JavaMethod __fieldGet; private JavaMethod __fieldSet; private FunctionArrayDelegate _funArrayDelegate; private ArrayDelegate _arrayDelegate; private JavaMethod __call; private JavaMethod __toString; private Method _printRImpl; private Method _varDumpImpl; private Method _entrySet; private TraversableDelegate _traversableDelegate; private CountDelegate _countDelegate; private Method _iteratorMethod; private Marshal _marshal; private String _extension; public JavaClassDef(ModuleContext moduleContext, String name, Class type) { super(null, name, null, new String[] {}); _moduleContext = moduleContext; _name = name; _type = type; _isAbstract = Modifier.isAbstract(type.getModifiers()); _isInterface = type.isInterface(); _isDelegate = type.isAnnotationPresent(ClassImplementation.class); if (type.isArray() && ! isArray()) throw new IllegalStateException(L.l("'{0}' needs to be called with JavaArrayClassDef", type)); fillInstanceOfSet(_type); } public JavaClassDef(ModuleContext moduleContext, String name, Class type, String extension) { this(moduleContext, name, type); _extension = extension; moduleContext.addExtensionClass(extension, name); } private void fillInstanceOfSet(Class type) { if (type == null) return; _instanceOfSet.add(type.getSimpleName()); fillInstanceOfSet(type.getSuperclass()); Class []ifaceList = type.getInterfaces(); if (ifaceList != null) { for (Class iface : ifaceList) fillInstanceOfSet(iface); } } public static JavaClassDef create(ModuleContext moduleContext, String name, Class type) { if (Double.class.isAssignableFrom(type) || Float.class.isAssignableFrom(type)) return new DoubleClassDef(moduleContext); else if (Long.class.isAssignableFrom(type) || Integer.class.isAssignableFrom(type) || Short.class.isAssignableFrom(type) || Byte.class.isAssignableFrom(type)) return new LongClassDef(moduleContext); else if (BigDecimal.class.isAssignableFrom(type)) return new BigDecimalClassDef(moduleContext); else if (BigInteger.class.isAssignableFrom(type)) return new BigIntegerClassDef(moduleContext); else if (String.class.isAssignableFrom(type) || Character.class.isAssignableFrom(type)) return new StringClassDef(moduleContext); else if (Boolean.class.isAssignableFrom(type)) return new BooleanClassDef(moduleContext); else if (Calendar.class.isAssignableFrom(type)) return new CalendarClassDef(moduleContext); else if (Date.class.isAssignableFrom(type)) return new DateClassDef(moduleContext); else if (URL.class.isAssignableFrom(type)) return new URLClassDef(moduleContext); else if (Map.class.isAssignableFrom(type)) return new JavaMapClassDef(moduleContext, name, type); else if (List.class.isAssignableFrom(type)) return new JavaListClassDef(moduleContext, name, type); else if (Collection.class.isAssignableFrom(type) && ! Queue.class.isAssignableFrom(type)) return new JavaCollectionClassDef(moduleContext, name, type); else return null; } /** * Returns the class name. */ @Override public String getName() { return _name; } /** * Returns the class name. */ public String getSimpleName() { return _type.getSimpleName(); } public Class getType() { return _type; } /* * Returns the type of this resource. */ public String getResourceType() { return _resourceType; } protected ModuleContext getModuleContext() { return _moduleContext; } /* * Returns the name of the extension that this class is part of. */ @Override public String getExtension() { return _extension; } @Override public boolean isA(String name) { return _instanceOfSet.contains(name); } private boolean hasInterface(String name, Class type) { Class[] interfaces = type.getInterfaces(); if (interfaces != null) { for (Class intfc : interfaces) { if (intfc.getSimpleName().equalsIgnoreCase(name)) return true; if (hasInterface(name, intfc)) return true; } } return false; } @Override public boolean isAbstract() { return _isAbstract; } public boolean isArray() { return false; } @Override public boolean isInterface() { return _isInterface; } public boolean isDelegate() { return _isDelegate; } public JavaClassDef getComponentDef() { if (_componentDef == null) { Class compType = getType().getComponentType(); _componentDef = _moduleContext.getJavaClassDefinition(compType.getName()); } return _componentDef; } public Value wrap(Env env, Object obj) { if (! _isInit) init(); if (_resourceType != null) return new JavaResourceValue(env, obj, this); else return new JavaValue(env, obj, this); } private int cmpObject(Object lValue, Object rValue) { if (lValue == rValue) return 0; if (lValue == null) return -1; if (rValue == null) return 1; if (lValue instanceof Comparable) { if (!(rValue instanceof Comparable)) return -1; return ((Comparable) lValue).compareTo(rValue); } else if (rValue instanceof Comparable) { return 1; } if (lValue.equals(rValue)) return 0; String lName = lValue.getClass().getName(); String rName = rValue.getClass().getName(); return lName.compareTo(rName); } public int cmpObject(Object lValue, Object rValue, JavaClassDef rClassDef) { int cmp = cmpObject(lValue, rValue); if (cmp != 0) return cmp; // attributes // XX: not sure how to do this, to imitate PHP objects, // should getters be involved as well? for (Map.Entry<StringValue, FieldMarshalPair> lEntry : _fieldMap.entrySet()) { StringValue lFieldName = lEntry.getKey(); FieldMarshalPair rFieldPair = rClassDef._fieldMap.get(lFieldName); if (rFieldPair == null) return 1; FieldMarshalPair lFieldPair = lEntry.getValue(); try { Object lResult = lFieldPair._field.get(lValue); Object rResult = rFieldPair._field.get(lValue); int resultCmp = cmpObject(lResult, rResult); if (resultCmp != 0) return resultCmp; } catch (IllegalAccessException e) { log.log(Level.FINE, L.l(e.getMessage()), e); return 0; } } return 0; } /** * Returns the field getter. * * @param name * @return Value attained through invoking getter */ public Value getField(Env env, Value qThis, StringValue name) { AbstractJavaMethod get = _getMap.get(name); if (get != null) { try { return get.callMethod(env, qThis); } catch (Exception e) { log.log(Level.FINE, L.l(e.getMessage()), e); return null; } } FieldMarshalPair fieldPair = _fieldMap.get(name); if (fieldPair != null) { try { Object result = fieldPair._field.get(qThis.toJavaObject()); return fieldPair._marshal.unmarshal(env, result); } catch (Exception e) { log.log(Level.FINE, L.l(e.getMessage()), e); return null; } } if (__fieldGet != null) { try { return __fieldGet.callMethod(env, qThis, name); } catch (Exception e) { log.log(Level.FINE, L.l(e.getMessage()), e); return null; } } return null; } public Value putField(Env env, Value qThis, StringValue name, Value value) { AbstractJavaMethod setter = _setMap.get(name); if (setter != null) { try { return setter.callMethod(env, qThis, value); } catch (Exception e) { log.log(Level.FINE, L.l(e.getMessage()), e); return NullValue.NULL; } } FieldMarshalPair fieldPair = _fieldMap.get(name); if (fieldPair != null) { try { Class type = fieldPair._field.getType(); Object marshaledValue = fieldPair._marshal.marshal(env, value, type); fieldPair._field.set(qThis.toJavaObject(), marshaledValue); return value; } catch (Exception e) { log.log(Level.FINE, L.l(e.getMessage()), e); return NullValue.NULL; } } if (__fieldSet != null) { try { return __fieldSet.callMethod(env, qThis, name, value); } catch (Exception e) { log.log(Level.FINE, L.l(e.getMessage()), e); return NullValue.NULL; } } return null; } /** * Returns the marshal instance. */ public Marshal getMarshal() { return _marshal; } /** * Creates a new instance. */ @Override public ObjectValue newInstance(Env env, QuercusClass qClass) { // return newInstance(); return null; } public Value newInstance() { return null; /* try { //Object obj = _type.newInstance(); return new JavaValue(null, _type.newInstance(), this); } catch (Exception e) { throw new QuercusRuntimeException(e); } */ } /** * Eval new */ @Override public Value callNew(Env env, Value []args) { if (_cons != null) return _cons.callMethod(env, null, args); else return NullValue.NULL; } /** * Returns the matching method. */ public AbstractFunction findFunction(String name) { return _functionMap.get(name); } /** * Returns the __call. */ public AbstractFunction getCallMethod() { return __call; } /** * Eval a method */ public Value callMethod(Env env, Value qThis, int hash, char []name, int nameLen, Expr []args) {
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?