*** empty log message ***
This commit is contained in:
@@ -0,0 +1,739 @@
|
||||
/*
|
||||
* The contents of this file are subject to the Mozilla Public License Version 1.1
|
||||
* (the "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at <http://www.mozilla.org/MPL/>.
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
|
||||
* WARRANTY OF ANY KIND, either express or implied. See the License for the specific
|
||||
* language governing rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Venice Web Communities System.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>,
|
||||
* for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
|
||||
* Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
package com.silverwrist.dynamo.obj;
|
||||
|
||||
import java.lang.reflect.*;
|
||||
import java.util.*;
|
||||
import com.silverwrist.util.*;
|
||||
import com.silverwrist.dynamo.except.*;
|
||||
import com.silverwrist.dynamo.iface.*;
|
||||
|
||||
class JavaDynamicClass implements DynamicClass, DynamicWrapper
|
||||
{
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Internal class implementing properties
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
private class Property
|
||||
{
|
||||
/*====================================================================
|
||||
* Attributes
|
||||
*====================================================================
|
||||
*/
|
||||
|
||||
private String m_name;
|
||||
private Field m_field = null;
|
||||
private Method m_get_method = null;
|
||||
private Method[] m_set_methods = null;
|
||||
|
||||
/*====================================================================
|
||||
* Constructor
|
||||
*====================================================================
|
||||
*/
|
||||
|
||||
Property(String name)
|
||||
{
|
||||
m_name = name;
|
||||
|
||||
} // end constructor
|
||||
|
||||
/*====================================================================
|
||||
* External operations
|
||||
*====================================================================
|
||||
*/
|
||||
|
||||
String getName()
|
||||
{
|
||||
return m_name;
|
||||
|
||||
} // end getName
|
||||
|
||||
void setField(Field field)
|
||||
{
|
||||
if (m_field==null)
|
||||
m_field = field;
|
||||
else
|
||||
throw new IllegalStateException("multiple field defs not permitted");
|
||||
|
||||
} // end setField
|
||||
|
||||
void setGetMethod(Method method)
|
||||
{
|
||||
if (m_get_method==null)
|
||||
m_get_method = method;
|
||||
else
|
||||
throw new IllegalStateException("multiple getters not permitted");
|
||||
|
||||
} // end setGetMethod
|
||||
|
||||
void setSetMethods(Method[] methods)
|
||||
{
|
||||
if (m_set_methods==null)
|
||||
m_set_methods = methods;
|
||||
// else this is a no-op
|
||||
|
||||
} // end setSetMethod
|
||||
|
||||
Object doGet(Object on_obj) throws DynamicObjectException
|
||||
{
|
||||
try
|
||||
{ // try calling the various possible methods
|
||||
if (m_get_method!=null)
|
||||
return m_get_method.invoke(on_obj,NULL_ARG_LIST);
|
||||
else if (m_field!=null)
|
||||
return m_field.get(on_obj);
|
||||
else
|
||||
throw new CodeNotFoundException(JavaDynamicClass.this,CodeNotFoundException.GET,m_name);
|
||||
|
||||
} // end try
|
||||
catch (IllegalAccessException e)
|
||||
{ // translate to CallFailureException
|
||||
throw new CallFailureException(JavaDynamicClass.this,e);
|
||||
|
||||
} // end catch
|
||||
catch (InvocationTargetException e)
|
||||
{ // translate to CallFailureException
|
||||
throw new CallFailureException(JavaDynamicClass.this,e.getCause());
|
||||
|
||||
} // end catch
|
||||
catch (UndeclaredThrowableException e)
|
||||
{ // translate to CallFailureException
|
||||
throw new CallFailureException(JavaDynamicClass.this,e.getCause());
|
||||
|
||||
} // end catch
|
||||
|
||||
} // end doGet
|
||||
|
||||
void doSet(Object on_obj, Object value) throws DynamicObjectException
|
||||
{
|
||||
try
|
||||
{ // try calling the various possible methods
|
||||
if (m_set_methods!=null)
|
||||
{ // pick a method and invoke it
|
||||
Object[] args = new Object[] { value };
|
||||
Method m = selectMethod(m_set_methods,args);
|
||||
if (m==null)
|
||||
throw new CodeNotFoundException(JavaDynamicClass.this,CodeNotFoundException.SET,m_name);
|
||||
else
|
||||
m.invoke(on_obj,args);
|
||||
|
||||
} // end if
|
||||
else if (m_field!=null)
|
||||
m_field.set(on_obj,value);
|
||||
else
|
||||
throw new CodeNotFoundException(JavaDynamicClass.this,CodeNotFoundException.SET,m_name);
|
||||
|
||||
} // end try
|
||||
catch (IllegalAccessException e)
|
||||
{ // translate to CallFailureException
|
||||
throw new CallFailureException(JavaDynamicClass.this,e);
|
||||
|
||||
} // end catch
|
||||
catch (InvocationTargetException e)
|
||||
{ // translate to CallFailureException
|
||||
throw new CallFailureException(JavaDynamicClass.this,e.getCause());
|
||||
|
||||
} // end catch
|
||||
catch (UndeclaredThrowableException e)
|
||||
{ // translate to CallFailureException
|
||||
throw new CallFailureException(JavaDynamicClass.this,e.getCause());
|
||||
|
||||
} // end catch
|
||||
|
||||
} // end doSet
|
||||
|
||||
} // end class Property
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Static data members
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
private static final Object[] NULL_ARG_LIST = new Object[0];
|
||||
private static final Method[] METHOD_TEMPLATE = new Method[0];
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Attributes
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
private Class m_klass;
|
||||
private Map m_static_methods;
|
||||
private Map m_object_methods;
|
||||
private Map m_static_properties;
|
||||
private Map m_object_properties;
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Constructor
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
JavaDynamicClass(Class klass)
|
||||
{
|
||||
m_klass = klass; // save Java class
|
||||
|
||||
// Allocate various HashMaps required to properly introspect the class's methods
|
||||
// and properties.
|
||||
HashMap ometh_map = new HashMap();
|
||||
HashMap smeth_map = new HashMap();
|
||||
HashMap oprop_map = new HashMap();
|
||||
HashMap oprop_set_map = new HashMap();
|
||||
HashMap sprop_map = new HashMap();
|
||||
HashMap sprop_set_map = new HashMap();
|
||||
|
||||
// Get the methods for the object and fill them in as object methods, and as
|
||||
// property getters and setters.
|
||||
Method[] meths = klass.getMethods();
|
||||
int i;
|
||||
for (i=0; i<meths.length; i++)
|
||||
{ // look at all methods and create appropriate entries
|
||||
Map meth_map, prop_map, prop_set_map;
|
||||
if (Modifier.isStatic(meths[i].getModifiers()))
|
||||
{ // add to "static" maps
|
||||
meth_map = smeth_map;
|
||||
prop_map = sprop_map;
|
||||
prop_set_map = sprop_set_map;
|
||||
|
||||
} // end if
|
||||
else
|
||||
{ // add to "object" maps
|
||||
meth_map = ometh_map;
|
||||
prop_map = oprop_map;
|
||||
prop_set_map = oprop_set_map;
|
||||
|
||||
} // end else
|
||||
|
||||
// Add method to list of methods with this name.
|
||||
String name = meths[i].getName();
|
||||
ArrayList al = (ArrayList)(meth_map.get(name));
|
||||
if (al==null)
|
||||
{ // create method list
|
||||
al = new ArrayList();
|
||||
meth_map.put(name,al);
|
||||
|
||||
} // end if
|
||||
|
||||
al.add(meths[i]);
|
||||
|
||||
Property p = null;
|
||||
if (isGetterMethod(meths[i]))
|
||||
{ // create property name and Property entry
|
||||
name = makePropertyName(name);
|
||||
p = (Property)(prop_map.get(name));
|
||||
if (p==null)
|
||||
{ // create new Property entry
|
||||
p = new Property(name);
|
||||
prop_map.put(name,p);
|
||||
|
||||
} // end if
|
||||
|
||||
p.setGetMethod(meths[i]);
|
||||
|
||||
} // end if (found getter)
|
||||
else if (isSetterMethod(meths[i]))
|
||||
{ // create property name and ArrayList for setter
|
||||
name = makePropertyName(name);
|
||||
al = (ArrayList)(prop_set_map.get(name));
|
||||
if (al==null)
|
||||
{ // create new ArrayList
|
||||
al = new ArrayList();
|
||||
prop_set_map.put(name,al);
|
||||
|
||||
} // end if
|
||||
|
||||
al.add(meths[i]);
|
||||
|
||||
} // end else if (found setter)
|
||||
|
||||
} // end for
|
||||
|
||||
// Freeze the static method map.
|
||||
HashMap tmp = null;
|
||||
Iterator it;
|
||||
if (smeth_map.isEmpty())
|
||||
m_static_methods = Collections.EMPTY_MAP;
|
||||
else
|
||||
{ // copy entries to fresh HashMap, converting to Method arrays
|
||||
tmp = new HashMap();
|
||||
it = smeth_map.keySet().iterator();
|
||||
while (it.hasNext())
|
||||
{ // get name, then ArrayList, then make array
|
||||
String name = (String)(it.next());
|
||||
ArrayList al = (ArrayList)(smeth_map.get(name));
|
||||
tmp.put(name,al.toArray(METHOD_TEMPLATE));
|
||||
al.clear();
|
||||
|
||||
} // end while
|
||||
|
||||
// freeze static methods
|
||||
m_static_methods = Collections.unmodifiableMap(tmp);
|
||||
smeth_map.clear();
|
||||
|
||||
} // end else
|
||||
|
||||
smeth_map = null;
|
||||
|
||||
// Freeze the object method map.
|
||||
if (ometh_map.isEmpty())
|
||||
m_object_methods = Collections.EMPTY_MAP;
|
||||
else
|
||||
{ // copy entries to fresh HashMap, converting to Method arrays
|
||||
tmp = new HashMap();
|
||||
it = ometh_map.keySet().iterator();
|
||||
while (it.hasNext())
|
||||
{ // get name, then ArrayList, then make array
|
||||
String name = (String)(it.next());
|
||||
ArrayList al = (ArrayList)(ometh_map.get(name));
|
||||
tmp.put(name,al.toArray(METHOD_TEMPLATE));
|
||||
al.clear();
|
||||
|
||||
} // end while
|
||||
|
||||
// freeze object methods
|
||||
m_object_methods = Collections.unmodifiableMap(tmp);
|
||||
ometh_map.clear();
|
||||
|
||||
} // end else
|
||||
|
||||
ometh_map = null;
|
||||
|
||||
// Load the setter arrays for static properties.
|
||||
it = sprop_set_map.keySet().iterator();
|
||||
while (it.hasNext())
|
||||
{ // get name, then ArrayList, then Property, then save off array
|
||||
String name = (String)(it.next());
|
||||
ArrayList al = (ArrayList)(sprop_set_map.get(name));
|
||||
Property p = (Property)(sprop_map.get(name));
|
||||
if (p==null)
|
||||
{ // create new Property entry
|
||||
p = new Property(name);
|
||||
sprop_map.put(name,p);
|
||||
|
||||
} // end if
|
||||
|
||||
p.setSetMethods((Method[])(al.toArray(METHOD_TEMPLATE)));
|
||||
al.clear();
|
||||
|
||||
} // end while
|
||||
|
||||
sprop_set_map.clear(); // zap the setter maps
|
||||
sprop_set_map = null;
|
||||
|
||||
// Load the setter arrays for object properties.
|
||||
it = oprop_set_map.keySet().iterator();
|
||||
while (it.hasNext())
|
||||
{ // get name, then ArrayList, then Property, then save off array
|
||||
String name = (String)(it.next());
|
||||
ArrayList al = (ArrayList)(oprop_set_map.get(name));
|
||||
Property p = (Property)(oprop_map.get(name));
|
||||
if (p==null)
|
||||
{ // create new Property entry
|
||||
p = new Property(name);
|
||||
oprop_map.put(name,p);
|
||||
|
||||
} // end if
|
||||
|
||||
p.setSetMethods((Method[])(al.toArray(METHOD_TEMPLATE)));
|
||||
al.clear();
|
||||
|
||||
} // end while
|
||||
|
||||
oprop_set_map.clear(); // zap the setter maps
|
||||
oprop_set_map = null;
|
||||
|
||||
Field[] fields = klass.getFields();
|
||||
for (i=0; i<fields.length; i++)
|
||||
{ // look up property entry for each field
|
||||
Map prop_map;
|
||||
if (Modifier.isStatic(fields[i].getModifiers()))
|
||||
prop_map = sprop_map; // add to "static" maps
|
||||
else // add to "object" maps
|
||||
prop_map = oprop_map;
|
||||
|
||||
String name = fields[i].getName();
|
||||
Property p = (Property)(prop_map.get(name));
|
||||
if (p==null)
|
||||
{ // create new Property entry
|
||||
p = new Property(name);
|
||||
prop_map.put(name,p);
|
||||
|
||||
} // end if
|
||||
|
||||
p.setField(fields[i]); // save off field pointer
|
||||
|
||||
} // end for
|
||||
|
||||
// Freeze the two property maps.
|
||||
if (sprop_map.isEmpty())
|
||||
m_static_properties = Collections.EMPTY_MAP;
|
||||
else
|
||||
m_static_properties = Collections.unmodifiableMap(sprop_map);
|
||||
if (oprop_map.isEmpty())
|
||||
m_object_properties = Collections.EMPTY_MAP;
|
||||
else
|
||||
m_object_properties = Collections.unmodifiableMap(oprop_map);
|
||||
|
||||
} // end constructor
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Internal operations
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
private static final boolean isGetterMethod(Method m)
|
||||
{
|
||||
Class[] parms = m.getParameterTypes();
|
||||
if (parms.length!=0)
|
||||
return false;
|
||||
String name = m.getName();
|
||||
if (name.startsWith("get") && (name.length()>3))
|
||||
return true;
|
||||
if (name.startsWith("is") && (name.length()>2))
|
||||
{ // "is" is a valid getter, but only for Booleans
|
||||
Class rtype = m.getReturnType();
|
||||
if ((rtype==Boolean.class) || (rtype==Boolean.TYPE))
|
||||
return true;
|
||||
|
||||
} // end if
|
||||
|
||||
return false;
|
||||
|
||||
} // end isGetterMethod
|
||||
|
||||
private static final boolean isSetterMethod(Method m)
|
||||
{
|
||||
Class[] parms = m.getParameterTypes();
|
||||
if (parms.length!=1)
|
||||
return false;
|
||||
Class rtype = m.getReturnType();
|
||||
if (rtype!=Void.TYPE)
|
||||
return false;
|
||||
String name = m.getName();
|
||||
return (name.startsWith("set") && (name.length()>3));
|
||||
|
||||
} // end isSetterMethod
|
||||
|
||||
private static final String makePropertyName(String name)
|
||||
{
|
||||
String rc = null;
|
||||
if (name.startsWith("get") || name.startsWith("set"))
|
||||
rc = name.substring(3);
|
||||
else if (name.startsWith("is"))
|
||||
rc = name.substring(2);
|
||||
if (Character.isUpperCase(rc.charAt(0)) && !(Character.isUpperCase(rc.charAt(1))))
|
||||
return StringUtils.uncapitalise(rc);
|
||||
else
|
||||
return rc;
|
||||
|
||||
} // end makePropertyName
|
||||
|
||||
private static final int getFigureOfMerit(Class param_class, Class actual_class)
|
||||
{
|
||||
if (param_class==actual_class)
|
||||
return 0;
|
||||
if (param_class.isPrimitive())
|
||||
return 0;
|
||||
if (param_class.isInterface())
|
||||
return 1;
|
||||
|
||||
int figm = 0;
|
||||
while ((actual_class!=Object.class) && (actual_class!=param_class))
|
||||
{ // go up the class hierarchy until we get a match
|
||||
actual_class = actual_class.getSuperclass();
|
||||
figm += 2;
|
||||
|
||||
} // end while
|
||||
|
||||
return figm;
|
||||
|
||||
} // end getFigureOfMerit
|
||||
|
||||
private static final int getFigureOfMerit(Method method, Class[] arg_classes)
|
||||
{
|
||||
Class[] param_classes = method.getParameterTypes();
|
||||
if (param_classes.length!=arg_classes.length)
|
||||
return -1; // parameter count mismatch
|
||||
|
||||
int figm = 0;
|
||||
for (int i=0; i<param_classes.length; i++)
|
||||
{ // check each parameter type to see which is right
|
||||
if (!(param_classes[i].isAssignableFrom(arg_classes[i])))
|
||||
return -1; // parameter type mismatch
|
||||
figm += getFigureOfMerit(param_classes[i],arg_classes[i]);
|
||||
|
||||
} // end for
|
||||
|
||||
return figm;
|
||||
|
||||
} // end getFigureOfMerit
|
||||
|
||||
private static final Method selectMethod(Method[] methods, Object[] args)
|
||||
{
|
||||
if (methods.length==1)
|
||||
return methods[0]; // trivial
|
||||
|
||||
Class[] arg_classes = new Class[args.length];
|
||||
int i;
|
||||
for (i=0; i<args.length; i++)
|
||||
arg_classes[i] = args[i].getClass();
|
||||
|
||||
Method rc = null;
|
||||
int current_figm = Integer.MAX_VALUE;
|
||||
for (i=0; i<methods.length; i++)
|
||||
{ // get the figure of merit for this method
|
||||
int figm = getFigureOfMerit(methods[i],arg_classes);
|
||||
if (figm<0)
|
||||
continue;
|
||||
if (figm<current_figm)
|
||||
{ // this is the new "best" method
|
||||
rc = methods[i];
|
||||
current_figm = figm;
|
||||
|
||||
} // end if
|
||||
|
||||
if (current_figm==0)
|
||||
break; // can't get any better than this
|
||||
|
||||
} // end for
|
||||
|
||||
return rc;
|
||||
|
||||
} // end selectMethod
|
||||
|
||||
private static final Object unwrapObject(Object obj)
|
||||
{
|
||||
while (obj instanceof DynamicWrapper)
|
||||
obj = ((DynamicWrapper)obj).unwrap();
|
||||
return obj;
|
||||
|
||||
} // end unwrapObject
|
||||
|
||||
private static final Object[] unwrapArray(Object[] arr)
|
||||
{
|
||||
for (int i=0; i<arr.length; i++)
|
||||
{ // look for a dynamically wrapped object
|
||||
if (arr[i] instanceof DynamicWrapper)
|
||||
{ // we need to unwrap at least part of this array - do it
|
||||
Object[] rc = new Object[arr.length];
|
||||
if (i>0)
|
||||
System.arraycopy(arr,0,rc,0,i);
|
||||
for (int j=i; j<arr.length; j++)
|
||||
rc[j] = unwrapObject(arr[j]);
|
||||
return rc;
|
||||
|
||||
} // end if
|
||||
|
||||
} // end for
|
||||
|
||||
return arr; // no need to unwrap anything
|
||||
|
||||
} // end unwrapArray
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Overrides from class Object
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
public boolean equals(Object obj)
|
||||
{
|
||||
if (obj==null)
|
||||
return false;
|
||||
if (!(obj instanceof JavaDynamicClass))
|
||||
return false;
|
||||
JavaDynamicClass other = (JavaDynamicClass)obj;
|
||||
return m_klass.equals(other.m_klass);
|
||||
|
||||
} // end equals
|
||||
|
||||
public int hashCode()
|
||||
{
|
||||
return m_klass.hashCode();
|
||||
|
||||
} // end hashCode
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return "dynamic " + m_klass.toString();
|
||||
|
||||
} // end toString
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Implementations from interface NamedObject
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
public String getName()
|
||||
{
|
||||
return m_klass.getName();
|
||||
|
||||
} // end getName
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Implementations from interface DynamicClass
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
public Object get(String property_name) throws DynamicObjectException
|
||||
{
|
||||
Property p = (Property)(m_static_properties.get(property_name));
|
||||
if (p==null)
|
||||
throw new CodeNotFoundException(JavaDynamicClass.this,CodeNotFoundException.PROPERTY,property_name);
|
||||
return p.doGet(null);
|
||||
|
||||
} // end get
|
||||
|
||||
public void set(String property_name, Object value) throws DynamicObjectException
|
||||
{
|
||||
Property p = (Property)(m_static_properties.get(property_name));
|
||||
if (p==null)
|
||||
throw new CodeNotFoundException(JavaDynamicClass.this,CodeNotFoundException.PROPERTY,property_name);
|
||||
p.doSet(null,unwrapObject(value));
|
||||
|
||||
} // end set
|
||||
|
||||
public Object call(String method_name, Object[] parameters) throws DynamicObjectException
|
||||
{
|
||||
Method m = null;
|
||||
Method[] arr = (Method[])(m_static_methods.get(method_name));
|
||||
Object[] real_parameters = null;
|
||||
if (arr!=null)
|
||||
{ // convert parameters and select
|
||||
real_parameters = unwrapArray(parameters);
|
||||
m = selectMethod(arr,real_parameters);
|
||||
|
||||
} // end if
|
||||
|
||||
if (m==null)
|
||||
throw new CodeNotFoundException(JavaDynamicClass.this,CodeNotFoundException.CALL,method_name);
|
||||
try
|
||||
{ // call the static method
|
||||
return m.invoke(null,real_parameters);
|
||||
|
||||
} // end try
|
||||
catch (IllegalAccessException e)
|
||||
{ // translate to CallFailureException
|
||||
throw new CallFailureException(JavaDynamicClass.this,e);
|
||||
|
||||
} // end catch
|
||||
catch (InvocationTargetException e)
|
||||
{ // translate to CallFailureException
|
||||
throw new CallFailureException(JavaDynamicClass.this,e.getCause());
|
||||
|
||||
} // end catch
|
||||
catch (UndeclaredThrowableException e)
|
||||
{ // translate to CallFailureException
|
||||
throw new CallFailureException(JavaDynamicClass.this,e.getCause());
|
||||
|
||||
} // end catch
|
||||
|
||||
} // end call
|
||||
|
||||
public Object call(String method_name, List parameters) throws DynamicObjectException
|
||||
{
|
||||
return call(method_name,parameters.toArray());
|
||||
|
||||
} // end call
|
||||
|
||||
public DynamicObject cast(Object source) throws ClassCastException
|
||||
{
|
||||
Object obj = unwrapObject(source);
|
||||
if (m_klass.isInstance(obj))
|
||||
return new JavaDynamicObject(this,obj);
|
||||
throw new ClassCastException("not instance of class " + m_klass.getName());
|
||||
|
||||
} // end cast
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Implementations from interface DynamicWrapper
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
public Object unwrap()
|
||||
{
|
||||
return m_klass;
|
||||
|
||||
} // end unwrap
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* External operations
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
Object getForObject(Object target, String property_name) throws DynamicObjectException
|
||||
{
|
||||
Property p = (Property)(m_object_properties.get(property_name));
|
||||
if (p==null)
|
||||
p = (Property)(m_static_properties.get(property_name));
|
||||
if (p==null)
|
||||
throw new CodeNotFoundException(JavaDynamicClass.this,CodeNotFoundException.PROPERTY,property_name);
|
||||
return p.doGet(target);
|
||||
|
||||
} // end getForObject
|
||||
|
||||
void setForObject(Object target, String property_name, Object value) throws DynamicObjectException
|
||||
{
|
||||
Property p = (Property)(m_object_properties.get(property_name));
|
||||
if (p==null)
|
||||
p = (Property)(m_static_properties.get(property_name));
|
||||
if (p==null)
|
||||
throw new CodeNotFoundException(JavaDynamicClass.this,CodeNotFoundException.PROPERTY,property_name);
|
||||
p.doSet(target,unwrapObject(value));
|
||||
|
||||
} // end setForObject
|
||||
|
||||
Object callForObject(Object target, String method_name, Object[] parameters) throws DynamicObjectException
|
||||
{
|
||||
Method m = null;
|
||||
Method[] arr = (Method[])(m_object_methods.get(method_name));
|
||||
if (arr==null)
|
||||
arr = (Method[])(m_static_methods.get(method_name));
|
||||
Object[] real_parameters = null;
|
||||
if (arr!=null)
|
||||
{ // convert parameters and select
|
||||
real_parameters = unwrapArray(parameters);
|
||||
m = selectMethod(arr,real_parameters);
|
||||
|
||||
} // end if
|
||||
|
||||
if (m==null)
|
||||
throw new CodeNotFoundException(JavaDynamicClass.this,CodeNotFoundException.CALL,method_name);
|
||||
try
|
||||
{ // call the static method
|
||||
return m.invoke(target,real_parameters);
|
||||
|
||||
} // end try
|
||||
catch (IllegalAccessException e)
|
||||
{ // translate to CallFailureException
|
||||
throw new CallFailureException(JavaDynamicClass.this,e);
|
||||
|
||||
} // end catch
|
||||
catch (InvocationTargetException e)
|
||||
{ // translate to CallFailureException
|
||||
throw new CallFailureException(JavaDynamicClass.this,e.getCause());
|
||||
|
||||
} // end catch
|
||||
catch (UndeclaredThrowableException e)
|
||||
{ // translate to CallFailureException
|
||||
throw new CallFailureException(JavaDynamicClass.this,e.getCause());
|
||||
|
||||
} // end catch
|
||||
|
||||
} // end callForObject
|
||||
|
||||
} // end class JavaDynamicClass
|
||||
@@ -0,0 +1,121 @@
|
||||
/*
|
||||
* The contents of this file are subject to the Mozilla Public License Version 1.1
|
||||
* (the "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at <http://www.mozilla.org/MPL/>.
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
|
||||
* WARRANTY OF ANY KIND, either express or implied. See the License for the specific
|
||||
* language governing rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Venice Web Communities System.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>,
|
||||
* for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
|
||||
* Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
package com.silverwrist.dynamo.obj;
|
||||
|
||||
import java.util.*;
|
||||
import java.lang.reflect.*;
|
||||
import com.silverwrist.dynamo.except.*;
|
||||
import com.silverwrist.dynamo.iface.*;
|
||||
|
||||
class JavaDynamicObject implements DynamicObject, DynamicWrapper
|
||||
{
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Attributes
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
private JavaDynamicClass m_dclass;
|
||||
private Object m_object;
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Constructor
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
JavaDynamicObject(JavaDynamicClass dclass, Object obj)
|
||||
{
|
||||
m_dclass = dclass;
|
||||
m_object = obj;
|
||||
|
||||
} // end constructor
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Overrides from class Object
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
public boolean equals(Object obj)
|
||||
{
|
||||
if (obj==null)
|
||||
return false;
|
||||
if (obj instanceof DynamicObject)
|
||||
return obj.equals(m_object);
|
||||
else
|
||||
return m_object.equals(obj);
|
||||
|
||||
} // end equals
|
||||
|
||||
public int hashCode()
|
||||
{
|
||||
return m_object.hashCode();
|
||||
|
||||
} // end hashCode
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return m_object.toString();
|
||||
|
||||
} // end toString
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Implementations from interface DynamicObject
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
public Object get(String property_name) throws DynamicObjectException
|
||||
{
|
||||
return m_dclass.getForObject(m_object,property_name);
|
||||
|
||||
} // end get
|
||||
|
||||
public void set(String property_name, Object value) throws DynamicObjectException
|
||||
{
|
||||
m_dclass.setForObject(m_object,property_name,value);
|
||||
|
||||
} // end set
|
||||
|
||||
public Object call(String method_name, Object[] parameters) throws DynamicObjectException
|
||||
{
|
||||
return m_dclass.callForObject(m_object,method_name,parameters);
|
||||
|
||||
} // end call
|
||||
|
||||
public Object call(String method_name, List parameters) throws DynamicObjectException
|
||||
{
|
||||
return m_dclass.callForObject(m_object,method_name,parameters.toArray());
|
||||
|
||||
} // end call
|
||||
|
||||
public DynamicClass getDClass()
|
||||
{
|
||||
return m_dclass;
|
||||
|
||||
} // end getDClass
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Implementations from interface DynamicWrapper
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
public Object unwrap()
|
||||
{
|
||||
return m_object;
|
||||
|
||||
} // end unwrap
|
||||
|
||||
} // end class JavaDynamicObject
|
||||
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
* The contents of this file are subject to the Mozilla Public License Version 1.1
|
||||
* (the "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at <http://www.mozilla.org/MPL/>.
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
|
||||
* WARRANTY OF ANY KIND, either express or implied. See the License for the specific
|
||||
* language governing rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Venice Web Communities System.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>,
|
||||
* for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
|
||||
* Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
package com.silverwrist.dynamo.obj;
|
||||
|
||||
import java.util.*;
|
||||
import com.silverwrist.dynamo.iface.*;
|
||||
|
||||
public class JavaObjectBindery
|
||||
{
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Static data members
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
private static JavaObjectBindery _self = null;
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Attributes
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
private HashMap m_class_to_dc; // Class object to DynamicClass
|
||||
private HashMap m_name_to_dc; // classname to DynamicClass
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Constructor
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
private JavaObjectBindery()
|
||||
{
|
||||
m_class_to_dc = new HashMap();
|
||||
m_name_to_dc = new HashMap();
|
||||
|
||||
} // end constructor
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* External operations
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
public synchronized DynamicClass lookupClass(Class klass)
|
||||
{
|
||||
DynamicClass rc = (DynamicClass)(m_class_to_dc.get(klass));
|
||||
if (rc==null)
|
||||
{ // create new class object and register it
|
||||
rc = new JavaDynamicClass(klass);
|
||||
m_class_to_dc.put(klass,rc);
|
||||
m_name_to_dc.put(klass.getName(),rc);
|
||||
|
||||
} // end if
|
||||
|
||||
return rc;
|
||||
|
||||
} // end lookupClass
|
||||
|
||||
public synchronized DynamicClass lookupClass(String name)
|
||||
{
|
||||
DynamicClass rc = (DynamicClass)(m_name_to_dc.get(name));
|
||||
if (rc==null)
|
||||
{ // class not present, try loading it
|
||||
try
|
||||
{ // but we have to load the regular class first
|
||||
Class klass = Class.forName(name);
|
||||
rc = new JavaDynamicClass(klass);
|
||||
m_class_to_dc.put(klass,rc);
|
||||
m_name_to_dc.put(name,rc);
|
||||
|
||||
} // end try
|
||||
catch (ClassNotFoundException e)
|
||||
{ // no class found...
|
||||
return null; // TODO: exception?
|
||||
|
||||
} // end catch
|
||||
|
||||
} // end if
|
||||
|
||||
return rc;
|
||||
|
||||
} // end lookupClass
|
||||
|
||||
public synchronized void bind(String name, Class klass)
|
||||
{
|
||||
DynamicClass dc = new JavaDynamicClass(klass);
|
||||
m_class_to_dc.put(klass,dc);
|
||||
m_name_to_dc.put(name,dc);
|
||||
|
||||
} // end bind
|
||||
|
||||
public synchronized void bind(Class klass)
|
||||
{
|
||||
bind(klass.getName(),klass);
|
||||
|
||||
} // end bind
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* External static operations
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
public static synchronized JavaObjectBindery get()
|
||||
{
|
||||
if (_self==null)
|
||||
_self = new JavaObjectBindery();
|
||||
return _self;
|
||||
|
||||
} // end get
|
||||
|
||||
} // end class JavaObjectBindery
|
||||
|
||||
|
||||
Reference in New Issue
Block a user