/*
* $Id: ObjectPool.java,v 1.33 2002/09/16 08:05:02 jkl Exp $
*
* Copyright (c) 2002 Njet Communications Ltd. All Rights Reserved.
*
* Use is subject to license terms, as defined in
* Anvil Sofware License, Version 1.1. See LICENSE
* file, or http://njet.org/license-1.1.txt
*/
package anvil.core;
import anvil.script.Context;
import anvil.core.reflect.Reflection;
import anvil.core.reflect.PackageReflection;
import anvil.core.reflect.MethodTree;
import anvil.core.reflect.ConstructorTree;
import anvil.core.reflect.AdaptiveMemberVariable;
import anvil.core.reflect.AdaptiveClassVariable;
import anvil.core.arrays.AnyBooleanArrayConstructor;
import anvil.core.arrays.AnyCharArrayConstructor;
import anvil.core.arrays.AnyDoubleArrayConstructor;
import anvil.core.arrays.AnyFloatArrayConstructor;
import anvil.core.arrays.AnyIntArrayConstructor;
import anvil.core.arrays.AnyLongArrayConstructor;
import anvil.core.arrays.AnyShortArrayConstructor;
import anvil.core.arrays.AnyStringArrayConstructor;
import anvil.core.arrays.AnyObjectArrayConstructor;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.Hashtable;
import org.apache.oro.text.regex.MalformedPatternException;
import org.apache.oro.text.regex.Pattern;
import org.apache.oro.text.regex.Perl5Compiler;
public final class ObjectPool
{
private static AnyConstructor OBJECT_CONSTRUCTOR = new AnyObjectConstructor();
private static AnyConstructor BOOLEAN_ARRAY_CONSTRUCTOR = new AnyBooleanArrayConstructor();
private static AnyConstructor BINARY_CONSTRUCTOR = new AnyBinaryConstructor();
private static AnyConstructor CHAR_ARRAY_CONSTRUCTOR = new AnyCharArrayConstructor();
private static AnyConstructor INT_ARRAY_CONSTRUCTOR = new AnyIntArrayConstructor();
private static AnyConstructor SHORT_ARRAY_CONSTRUCTOR = new AnyShortArrayConstructor();
private static AnyConstructor LONG_ARRAY_CONSTRUCTOR = new AnyLongArrayConstructor();
private static AnyConstructor FLOAT_ARRAY_CONSTRUCTOR = new AnyFloatArrayConstructor();
private static AnyConstructor DOUBLE_ARRAY_CONSTRUCTOR = new AnyDoubleArrayConstructor();
private static AnyConstructor STRING_ARRAY_CONSTRUCTOR = new AnyStringArrayConstructor();
private static AnyConstructor OBJECT_ARRAY_CONSTRUCTOR = new AnyObjectArrayConstructor();
private static AnyConstructor LIST_CONSTRUCTOR = new AnyListConstructor();
private static Class STRING_CLASS = String.class;
private static Class BOOLEAN_CLASS = Boolean.class;
private static Class BYTE_CLASS = Byte.class;
private static Class SHORT_CLASS = Short.class;
private static Class INTEGER_CLASS = Integer.class;
private static Class LONG_CLASS = Long.class;
private static Class FLOAT_CLASS = Float.class;
private static Class DOUBLE_CLASS = Double.class;
private static Hashtable _registered = new Hashtable();
private static Hashtable _resolved = new Hashtable();
private static Hashtable _reflections = new Hashtable();
private static Hashtable _patterns = new Hashtable();
private static AnyInt[] _intArray = new AnyInt[1024+256];
private static Integer[] _integerArray = new Integer[1024+256];
private static AnyString[] _charArray = new AnyString[256];
static {
int n = _intArray.length;
for(int i=0; i<n; i++) {
_intArray[i] = new AnyInt(i-256);
}
n = _integerArray.length;
for(int i=0; i<n; i++) {
_integerArray[i] = new Integer(i-256);
}
char[] string = new char[1];
for(int i=0; i<256; i++) {
string[0] = (char)i;
_charArray[i] = new AnyString(new String(string));
}
}
private ObjectPool()
{
}
public static final void register(Class anyclass)
{
if (Any.class.isAssignableFrom(anyclass)) {
try {
Constructor ctors[] = anyclass.getConstructors();
int n = ctors.length;
for(int i=0; i<n; i++) {
Constructor ctor = ctors[i];
Class params[] = ctor.getParameterTypes();
if ((params.length == 1) && (!params[0].isPrimitive())) {
_registered.put(params[0].getName(), new AnyConstructor(ctor));
}
}
} catch (ClassCastException e) {
anvil.Log.log().error(e);
} catch (IllegalArgumentException e) {
anvil.Log.log().error(e);
} catch (SecurityException e) {
anvil.Log.log().error(e);
} catch (RuntimeException e) {
anvil.Log.log().error(e);
}
}
}
public static final AnyConstructor resolve(Class c)
{
AnyConstructor ctor = null;
if (c.isArray()) {
Class elemcls = c.getComponentType();
if (elemcls.isPrimitive()) {
if (elemcls.equals(Byte.TYPE)) {
return BINARY_CONSTRUCTOR;
} else if (elemcls.equals(Character.TYPE)) {
return CHAR_ARRAY_CONSTRUCTOR;
} else if (elemcls.equals(Integer.TYPE)) {
return INT_ARRAY_CONSTRUCTOR;
} else if (elemcls.equals(Long.TYPE)) {
return LONG_ARRAY_CONSTRUCTOR;
} if (elemcls.equals(Double.TYPE)) {
return DOUBLE_ARRAY_CONSTRUCTOR;
} else if (elemcls.equals(Short.TYPE)) {
return SHORT_ARRAY_CONSTRUCTOR;
} if (elemcls.equals(Float.TYPE)) {
return FLOAT_ARRAY_CONSTRUCTOR;
} if (elemcls.equals(Boolean.TYPE)) {
return BOOLEAN_ARRAY_CONSTRUCTOR;
}
} else {
if (elemcls.equals(Any.class)) {
return LIST_CONSTRUCTOR;
} else if (elemcls.equals(String.class)) {
return STRING_ARRAY_CONSTRUCTOR;
} else if (elemcls.equals(Object.class)) {
return OBJECT_ARRAY_CONSTRUCTOR;
} else {
return OBJECT_ARRAY_CONSTRUCTOR;
}
}
}
while(c != null) {
Class superc = c.getSuperclass();
if (!c.equals(Object.class)) {
String name = c.getName();
ctor = (AnyConstructor)_registered.get(name);
if (ctor != null) {
return ctor;
}
}
Class[] impls = c.getInterfaces();
int n = impls.length;
for(int i=0; i<n; i++) {
Class impl = impls[i];
ctor = (AnyConstructor)_registered.get(impl.getName());
if (ctor != null) {
return ctor;
}
Class implimpls[] = impl.getInterfaces();
int m = implimpls.length;
for(int j=0; j<m; j++) {
impl = implimpls[j];
ctor = (AnyConstructor)_registered.get(impl.getName());
if (ctor != null) {
return ctor;
}
}
}
c = superc;
}
return OBJECT_CONSTRUCTOR;
}
public static final Reflection getReflection(String classname)
{
return (Reflection)_reflections.get(classname);
}
public static synchronized final Reflection createReflection(Class cls)
{
Reflection reflection = (Reflection)_reflections.get(cls);
if (reflection == null) {
reflection = new Reflection();
_reflections.put(cls, reflection);
_reflections.put(cls.getName(), reflection);
reflection.initialize(cls);
}
return reflection;
}
public static synchronized final PackageReflection createReflection(Package pack)
{
if (pack == null) {
pack = Object.class.getPackage();
}
PackageReflection reflection = (PackageReflection)_reflections.get(pack);
if (reflection == null) {
reflection = new PackageReflection(pack);
_reflections.put(pack, reflection);
}
return reflection;
}
public static final Any create(Object object)
{
if (object == null) {
return Any.NULL;
}
if (object instanceof Any) {
return (Any)object;
}
Class cls = object.getClass();
if ((cls.getModifiers() & Modifier.FINAL) != 0) {
if (cls == STRING_CLASS) {
return new AnyString((String) object);
}
if (cls == INTEGER_CLASS) {
return createInt(((Integer) object).intValue());
}
if (cls == BOOLEAN_CLASS) {
return ((Boolean)object).booleanValue() ? Any.TRUE : Any.FALSE;
}
if (cls == BYTE_CLASS) {
return createInt(((Byte) object).intValue());
}
if (cls == LONG_CLASS) {
return createLong(((Long) object).longValue());
}
if (cls == DOUBLE_CLASS) {
return new AnyDouble((Double) object);
}
if (cls == FLOAT_CLASS) {
return new AnyDouble(((Float) object).doubleValue());
}
if (cls == SHORT_CLASS) {
return createInt(((Short) object).intValue());
}
}
AnyConstructor ctor = (AnyConstructor)_resolved.get(cls);
if (ctor == null) {
ctor = resolve(cls);
_resolved.put(cls, ctor);
}
return ctor.construct(object);
}
public static Any createBoolean(boolean bool)
{
return bool ? Any.TRUE : Any.FALSE;
}
public static final AnyInt createInt(int integer)
{
if (integer>=-256 && integer<1024) {
return _intArray[integer + 256];
} else {
return new AnyInt(integer);
}
}
public static final Integer createInteger(int integer)
{
if (integer>=-256 && integer<1024) {
return _integerArray[integer + 256];
} else {
return new Integer(integer);
}
}
public static final AnyInt createLong(long lng)
{
if (lng>=-256 && lng<1024) {
return _intArray[(int)lng + 256];
} else {
return new AnyInt(lng);
}
}
public static final AnyString createChar(char ch)
{
if (ch <= 255) {
return _charArray[ch];
} else {
char[] string = new char[1];
string[0] = ch;
return new AnyString(new String(string));
}
}
public static Any createString(String string)
{
if (string == null) {
return Any.NULL;
}
int n = string.length();
if (n == 0) {
return Any.EMPTY_STRING;
} else if (n == 1) {
char ch = string.charAt(0);
if (ch <= 255) {
return _charArray[ch];
}
}
return new AnyString(string);
}
public static final Pattern createPattern(Context context, Any from)
{
if (from == null) {
return null;
}
try {
if (from.isPattern()) {
return from.toPattern();
} else {
return createPattern(from.toString(), null);
}
} catch (MalformedPatternException e) {
throw context.MalformedPattern(e.getMessage());
}
}
public static final Pattern createPattern(String pattern, String flagPattern) throws MalformedPatternException
{
boolean ignoreCase = false;
boolean multiLine = false;
boolean extended = false;
if (flagPattern != null) {
int n = flagPattern.length();
for(int i=0; i<n; i++) {
switch(flagPattern.charAt(i)) {
case 'i':
ignoreCase = true;
break;
case 'm':
multiLine = true;
break;
case 'x':
extended = true;
break;
}
}
}
StringBuffer buffer = new StringBuffer(pattern.length()+4);
buffer.append(pattern);
buffer.append('/');
if (ignoreCase) {
buffer.append('i');
}
if (multiLine) {
buffer.append('m');
}
if (extended) {
buffer.append('x');
}
String key = buffer.toString();
Pattern pat = (Pattern)_patterns.get(key);
if (pat == null) {
int flags =
Perl5Compiler.READ_ONLY_MASK |
(ignoreCase ? Perl5Compiler.CASE_INSENSITIVE_MASK : 0) |
(multiLine ? Perl5Compiler.MULTILINE_MASK : Perl5Compiler.SINGLELINE_MASK) |
(extended ? Perl5Compiler.EXTENDED_MASK : 0);
pat = new Perl5Compiler().compile(pattern, flags);
_patterns.put(key, pat);
}
return pat;
}
}