diff options
author | Hans-Christoph Steiner <eighthave@users.sourceforge.net> | 2008-03-22 02:15:12 +0000 |
---|---|---|
committer | Hans-Christoph Steiner <eighthave@users.sourceforge.net> | 2008-03-22 02:15:12 +0000 |
commit | a764e59e1d3a8e330f0d484fdb26b35ca3f0b2e4 (patch) | |
tree | c4ecadccdecf2809b99c0da0545f255a6ad25bb5 /src/java/com/cycling74/max/Attribute.java |
bringing pdj-0.8.3 into the main branchsvn2git-root
svn path=/trunk/externals/loaders/pdj/; revision=9621
Diffstat (limited to 'src/java/com/cycling74/max/Attribute.java')
-rw-r--r-- | src/java/com/cycling74/max/Attribute.java | 463 |
1 files changed, 463 insertions, 0 deletions
diff --git a/src/java/com/cycling74/max/Attribute.java b/src/java/com/cycling74/max/Attribute.java new file mode 100644 index 0000000..2e5cccf --- /dev/null +++ b/src/java/com/cycling74/max/Attribute.java @@ -0,0 +1,463 @@ +package com.cycling74.max; + +import java.lang.reflect.*; +import com.e1.pdj.PDJError; + +class Attribute { + boolean readOnly = false; + + // the method setter and getter if specified + Method setter; + Method getter; + + // the field to update if no setter or getter is specified + Field field; + + // attribute type + char type; + + // the owner of the field or method + Object obj; + + // tells if the arguments are a array + boolean isArray; + + Attribute(Object obj, String name, String setter_name, String getter_name) { + char typeCheck = 0; + + try { + this.obj = obj; + if ( getter == null ) { + field = obj.getClass().getDeclaredField(name); + field.setAccessible(true); + type = mapType(field.getType()); + if ( type == '-' ) { + throw new PDJError("Field: " + name + " is a unsupported type"); + } + isArray = Character.isLowerCase(type); + } else { + getter = obj.getClass().getDeclaredMethod(getter_name, null); + type = mapType(getter.getReturnType()); + if ( type == '-' ) { + throw new PDJError("Method: " + getter_name + " returns a unsupported type"); + } + isArray = Character.isLowerCase(type); + } + + if ( setter == null ) { + field = obj.getClass().getDeclaredField(name); + field.setAccessible(true); + typeCheck = mapType(field.getType()); + } else { + Method methods[] = obj.getClass().getMethods(); + + for(int i=0;i<methods.length;i++) { + if ( methods[i].getName().equals(setter_name) ) { + Class c[] = methods[i].getParameterTypes(); + if ( c.length > 1 ) + throw new PDJError("Method: " + setter_name + " has too much parameters to be a setter"); + typeCheck = mapType(c[0]); + setter = methods[i]; + break; + } + } + if ( typeCheck == 0 ) { + throw new NoSuchMethodException(setter_name); + } + } + } catch ( Exception e ) { + throw new PDJError(e); + } + + if ( typeCheck != type ) { + throw new PDJError("Object type for setter and getter is not the same"); + } + + } + + private char mapType(Class clz) { + if ( clz == Integer.TYPE ) + return 'i'; + if ( clz == int[].class ) + return 'I'; + if ( clz == Float.TYPE ) + return 'f'; + if ( clz == float[].class ) + return 'F'; + if ( clz == Double.TYPE ) + return 'd'; + if ( clz == double[].class ) + return 'D'; + if ( clz == Boolean.TYPE ) + return 'z'; + if ( clz == Boolean[].class ) + return 'Z'; + if ( clz == Byte.TYPE ) + return 'b'; + if ( clz == byte[].class ) + return 'B'; + if ( clz == Character.TYPE ) + return 'c'; + if ( clz == char[].class ) + return 'C'; + if ( clz == Short.TYPE ) + return 's'; + if ( clz == short[].class ) + return 'S'; + if ( clz == String.class ) + return 'g'; + if ( clz == String[].class ) + return 'G'; + if ( clz == Atom.class ) + return 'a'; + if ( clz == Atom[].class ) + return 'A'; + return '-'; + } + + private void fieldSetter(Atom[] value) throws Exception { + Object work; + int i; + + switch ( type ) { + case 'z' : + field.setBoolean(obj, value[0].toBoolean()); + break; + case 'Z' : + work = field.get(obj); + for (i=0;i<value.length;i++) + Array.setBoolean(work, i, value[i].toBoolean()); + break; + case 'f' : + field.setFloat(obj, value[0].toFloat()); + break; + case 'F' : + work = field.get(obj); + for (i=0;i<value.length;i++) + Array.setFloat(work, i, value[i].toFloat()); + break; + case 'i' : + field.setInt(obj, value[0].toInt()); + break; + case 'I' : + work = field.get(obj); + for (i=0;i<value.length;i++) + Array.setInt(work, i, value[i].toInt()); + break; + case 'd' : + field.setDouble(obj, value[0].toDouble()); + break; + case 'D' : + work = field.get(obj); + for (i=0;i<value.length;i++) + Array.setDouble(work, i, value[i].toDouble()); + break; + case 'b' : + field.setByte(obj, value[0].toByte()); + break; + case 'B' : + work = field.get(obj); + for (i=0;i<value.length;i++) + Array.setByte(work, i, value[i].toByte()); + break; + case 'c' : + field.setChar(obj, value[0].toChar()); + break; + case 'C' : + work = field.get(obj); + for (i=0;i<value.length;i++) + Array.setChar(work, i, value[i].toChar()); + break; + case 's' : + field.setShort(obj, value[0].toShort()); + break; + case 'S' : + work = field.get(obj); + for (i=0;i<value.length;i++) + Array.setShort(work, i, value[i].toShort()); + break; + case 'g' : + field.set(obj, value.toString()); + break; + case 'G' : + work = field.get(obj); + for (i=0;i<value.length;i++) + Array.set(work, i, value[i].toString()); + break; + case 'a' : + field.set(obj, value[0]); + break; + case 'A' : + field.set(obj, value); + break; + default: + throw new PDJError("Unable to pass attribute value"); + } + } + + private Atom[] fieldGetter() throws Exception { + Object array = null; + Atom[] ret; + int i; + + if ( isArray ) { + ret = new Atom[1]; + } else { + array = field.get(obj); + ret = new Atom[Array.getLength(array)]; + } + + switch ( type ) { + case 'z' : + ret[0] = Atom.newAtom(field.getBoolean(obj)); + break; + case 'Z' : + for (i=0;i<ret.length;i++) + ret[i] = Atom.newAtom(Array.getBoolean(array, i)); + break; + case 'f' : + ret[0] = Atom.newAtom(field.getFloat(obj)); + break; + case 'F' : + for (i=0;i<ret.length;i++) + ret[i] = Atom.newAtom(Array.getFloat(array, i)); + break; + case 'i' : + ret[0] = Atom.newAtom(field.getInt(obj)); + break; + case 'I' : + for (i=0;i<ret.length;i++) + ret[i] = Atom.newAtom(Array.getInt(array, i)); + break; + case 'd' : + ret[0] = Atom.newAtom(field.getDouble(obj)); + break; + case 'D' : + for (i=0;i<ret.length;i++) + ret[i] = Atom.newAtom(Array.getDouble(array, i)); + break; + case 'b' : + ret[0] = Atom.newAtom(field.getByte(obj)); + break; + case 'B' : + for (i=0;i<ret.length;i++) + ret[i] = Atom.newAtom(Array.getByte(array, i)); + break; + case 'c' : + ret[0] = Atom.newAtom(field.getChar(obj)); + break; + case 'C' : + for (i=0;i<ret.length;i++) + ret[i] = Atom.newAtom(Array.getChar(array, i)); + break; + case 's' : + ret[0] = Atom.newAtom(field.getShort(obj)); + break; + case 'S' : + for (i=0;i<ret.length;i++) + ret[i] = Atom.newAtom(Array.getShort(array, i)); + break; + case 'g' : + ret[0] = Atom.newAtom((String) field.get(obj)); + break; + case 'G' : + for (i=0;i<ret.length;i++) + ret[i] = Atom.newAtom((String) Array.get(array, i)); + break; + case 'a' : + ret[0] = (Atom) field.get(obj); + break; + case 'A' : + for (i=0;i<ret.length;i++) + ret[i] = (Atom) Array.get(array, i); + break; + default: + throw new PDJError("Unable to pass attribute value"); + } + + return ret; + } + + private Atom[] methodGetter() throws Exception { + Object array = null; + Atom[] ret; + int i; + + if ( isArray ) { + ret = new Atom[1]; + } else { + array = field.get(obj); + ret = new Atom[Array.getLength(array)]; + } + + switch ( type ) { + case 'z' : + ret[0] = Atom.newAtom(((Boolean)getter.invoke(obj, null)).booleanValue()); + break; + case 'Z' : + boolean tmpz[] = (boolean[]) getter.invoke(obj, null); + for (i=0;i<ret.length;i++) + ret[i] = Atom.newAtom(tmpz[i]); + break; + case 'f' : + ret[0] = Atom.newAtom(((Float)getter.invoke(obj, null)).floatValue()); + break; + case 'F' : + float tmpf[] = (float[]) getter.invoke(obj, null); + for (i=0;i<ret.length;i++) + ret[i] = Atom.newAtom(tmpf[i]); + break; + case 'i' : + ret[0] = Atom.newAtom(((Integer)getter.invoke(obj, null)).intValue()); + break; + case 'I' : + int tmpi[] = (int[]) getter.invoke(obj, null); + for (i=0;i<ret.length;i++) + ret[i] = Atom.newAtom(tmpi[i]); + break; + case 'd' : + ret[0] = Atom.newAtom(((Double)getter.invoke(obj, null)).doubleValue()); + break; + case 'D' : + double tmpd[] = (double[]) getter.invoke(obj, null); + for (i=0;i<ret.length;i++) + ret[i] = Atom.newAtom(tmpd[i]); + break; + case 'b' : + ret[0] = Atom.newAtom(((Byte)getter.invoke(obj, null)).byteValue()); + break; + case 'B' : + byte tmpb[] = (byte[]) getter.invoke(obj, null); + for (i=0;i<ret.length;i++) + ret[i] = Atom.newAtom(tmpb[i]); + break; + case 'c' : + ret[0] = Atom.newAtom(((Character)getter.invoke(obj, null)).charValue()); + break; + case 'C' : + char tmpc[] = (char[]) getter.invoke(obj, null); + for (i=0;i<ret.length;i++) + ret[i] = Atom.newAtom(tmpc[i]); + break; + case 's' : + ret[0] = Atom.newAtom(((Short)getter.invoke(obj, null)).shortValue()); + break; + case 'S' : + short tmps[] = (short[]) getter.invoke(obj, null); + for (i=0;i<ret.length;i++) + ret[i] = Atom.newAtom(tmps[i]); + break; + case 'g' : + ret[0] = Atom.newAtom((String) getter.invoke(obj, null)); + break; + case 'G' : + for (i=0;i<ret.length;i++) + ret[i] = Atom.newAtom((String) Array.get(array, i)); + break; + case 'a' : + ret[0] = (Atom) getter.invoke(obj, null); + break; + case 'A' : + ret = (Atom []) getter.invoke(obj, null); + break; + default: + throw new PDJError("Unable to pass attribute value"); + } + + return ret; + } + + private Object setterCast(Atom values[]) throws Exception { + int i; + + switch ( type ) { + case 'z' : + return new Boolean(values[0].toBoolean()); + case 'Z' : + boolean tmpz[] = new boolean[values.length]; + for (i=0;i<values.length; i++) + tmpz[i] = values[i].toBoolean(); + return tmpz; + case 'f' : + return new Float(values[0].toFloat()); + case 'F' : + float tmpf[] = new float[values.length]; + for (i=0;i<values.length; i++) + tmpf[i] = values[i].toFloat(); + return tmpf; + case 'i' : + return new Integer(values[0].toInt()); + case 'I' : + int tmpi[] = new int[values.length]; + for (i=0;i<values.length; i++) + tmpi[i] = values[i].toInt(); + return tmpi; + case 'd' : + return new Double(values[0].toDouble()); + case 'D' : + double tmpd[] = new double[values.length]; + for (i=0;i<values.length; i++) + tmpd[i] = values[i].toDouble(); + return tmpd; + case 'b' : + return new Byte(values[0].toByte()); + case 'B' : + byte tmpb[] = new byte[values.length]; + for (i=0;i<values.length; i++) + tmpb[i] = values[i].toByte(); + return tmpb; + case 'c' : + return new Character(values[0].toChar()); + case 'C' : + char tmpc[] = new char[values.length]; + for (i=0;i<values.length; i++) + tmpc[i] = values[i].toChar(); + return tmpc; + case 's' : + return new Short(values[0].toShort()); + case 'S' : + short tmps[] = new short[values.length]; + for (i=0;i<values.length; i++) + tmps[i] = values[i].toShort(); + return tmps; + case 'g' : + return values[0].toString(); + case 'G' : + String tmpg[] = new String[values.length]; + for (i=0;i<values.length;i++) + tmpg[i] = values[0].toString(); + return tmpg; + case 'a' : + return values[0]; + case 'A' : + return values; + default: + throw new PDJError("Unable to pass attribute value"); + } + } + + Atom[] get() { + try { + if ( getter == null ) + return fieldGetter(); + return methodGetter(); + } catch ( Exception e ){ + throw new PDJError(e); + } + } + + void set(Atom values[]) { + if ( readOnly ) + throw new PDJError("Field is readonly"); + + try { + if ( setter == null ) + fieldSetter(values); + else + setter.invoke(obj, new Object[] { setterCast(values) }); + } catch (Exception e) { + throw new PDJError(e); + } + } + +} |