summaryrefslogtreecommitdiff
path: root/src/traffic-incidents-service/org.genivi.trafficinfo.dbus-java/src/main/java/org/freedesktop/dbus/Marshalling.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/traffic-incidents-service/org.genivi.trafficinfo.dbus-java/src/main/java/org/freedesktop/dbus/Marshalling.java')
-rwxr-xr-xsrc/traffic-incidents-service/org.genivi.trafficinfo.dbus-java/src/main/java/org/freedesktop/dbus/Marshalling.java629
1 files changed, 629 insertions, 0 deletions
diff --git a/src/traffic-incidents-service/org.genivi.trafficinfo.dbus-java/src/main/java/org/freedesktop/dbus/Marshalling.java b/src/traffic-incidents-service/org.genivi.trafficinfo.dbus-java/src/main/java/org/freedesktop/dbus/Marshalling.java
new file mode 100755
index 0000000..b561f19
--- /dev/null
+++ b/src/traffic-incidents-service/org.genivi.trafficinfo.dbus-java/src/main/java/org/freedesktop/dbus/Marshalling.java
@@ -0,0 +1,629 @@
+/*
+ D-Bus Java Implementation
+ Copyright (c) 2005-2006 Matthew Johnson
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of either the GNU Lesser General Public License Version 2 or the
+ Academic Free Licence Version 2.1.
+
+ Full licence texts are included in the COPYING file with this program.
+*/
+package org.freedesktop.dbus;
+
+import static org.freedesktop.dbus.Gettext._;
+
+import java.lang.reflect.Array;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.GenericArrayType;
+import java.lang.reflect.Method;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.lang.reflect.TypeVariable;
+import java.text.MessageFormat;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Vector;
+
+import org.freedesktop.dbus.exceptions.DBusException;
+import org.freedesktop.dbus.types.DBusListType;
+import org.freedesktop.dbus.types.DBusMapType;
+import org.freedesktop.dbus.types.DBusStructType;
+
+import cx.ath.matthew.debug.Debug;
+
+/**
+ * Contains static methods for marshalling values.
+ */
+public class Marshalling
+{
+ private static Map<Type, String[]> typeCache = new HashMap<Type, String[]>();
+ /**
+ * Will return the DBus type corresponding to the given Java type.
+ * Note, container type should have their ParameterizedType not their
+ * Class passed in here.
+ * @param c The Java types.
+ * @return The DBus types.
+ * @throws DBusException If the given type cannot be converted to a DBus type.
+ */
+ public static String getDBusType(Type[] c) throws DBusException
+ {
+ StringBuffer sb = new StringBuffer();
+ for (Type t: c)
+ for (String s: getDBusType(t))
+ sb.append(s);
+ return sb.toString();
+ }
+ /**
+ * Will return the DBus type corresponding to the given Java type.
+ * Note, container type should have their ParameterizedType not their
+ * Class passed in here.
+ * @param c The Java type.
+ * @return The DBus type.
+ * @throws DBusException If the given type cannot be converted to a DBus type.
+ */
+ public static String[] getDBusType(Type c) throws DBusException
+ {
+ String[] cached = typeCache.get(c);
+ if (null != cached) return cached;
+ cached = getDBusType(c, false);
+ typeCache.put(c, cached);
+ return cached;
+ }
+ /**
+ * Will return the DBus type corresponding to the given Java type.
+ * Note, container type should have their ParameterizedType not their
+ * Class passed in here.
+ * @param c The Java type.
+ * @param basic If true enforces this to be a non-compound type. (compound types are Maps, Structs and Lists/arrays).
+ * @return The DBus type.
+ * @throws DBusException If the given type cannot be converted to a DBus type.
+ */
+ public static String[] getDBusType(Type c, boolean basic) throws DBusException
+ {
+ return recursiveGetDBusType(c, basic, 0);
+ }
+ private static StringBuffer[] out = new StringBuffer[20]; // pego
+ @SuppressWarnings("unchecked")
+ public static String[] recursiveGetDBusType(Type c, boolean basic, int level) throws DBusException
+ {
+ if (out.length <= level) {
+ StringBuffer[] newout = new StringBuffer[out.length];
+ System.arraycopy(out, 0, newout, 0, out.length);
+ out = newout;
+ }
+ if (null == out[level]) out[level] = new StringBuffer();
+ else out[level].delete(0, out[level].length());
+
+ if (basic && !(c instanceof Class))
+ throw new DBusException(c+_(" is not a basic type"));
+
+ if (c instanceof TypeVariable) out[level].append((char) Message.ArgumentType.VARIANT);
+ else if (c instanceof GenericArrayType) {
+ out[level].append((char) Message.ArgumentType.ARRAY);
+ String[] s = recursiveGetDBusType(((GenericArrayType) c).getGenericComponentType(), false, level+1);
+ if (s.length != 1) throw new DBusException(_("Multi-valued array types not permitted"));
+ out[level].append(s[0]);
+ } else if ((c instanceof Class &&
+ DBusSerializable.class.isAssignableFrom((Class<? extends Object>) c)) ||
+ (c instanceof ParameterizedType &&
+ DBusSerializable.class.isAssignableFrom((Class<? extends Object>) ((ParameterizedType) c).getRawType()))) {
+ // it's a custom serializable type
+ Type[] newtypes = null;
+ if (c instanceof Class) {
+ for (Method m: ((Class<? extends Object>) c).getDeclaredMethods())
+ if (m.getName().equals("deserialize"))
+ newtypes = m.getGenericParameterTypes();
+ }
+ else
+ for (Method m: ((Class<? extends Object>) ((ParameterizedType) c).getRawType()).getDeclaredMethods())
+ if (m.getName().equals("deserialize"))
+ newtypes = m.getGenericParameterTypes();
+
+ if (null == newtypes) throw new DBusException(_("Serializable classes must implement a deserialize method"));
+
+ String[] sigs = new String[newtypes.length];
+ for (int j = 0; j < sigs.length; j++) {
+ String[] ss = recursiveGetDBusType(newtypes[j], false, level+1);
+ if (1 != ss.length) throw new DBusException(_("Serializable classes must serialize to native DBus types"));
+ sigs[j] = ss[0];
+ }
+ return sigs;
+ }
+ else if (c instanceof ParameterizedType) {
+ ParameterizedType p = (ParameterizedType) c;
+ if (p.getRawType().equals(Map.class)) {
+ out[level].append("a{");
+ Type[] t = p.getActualTypeArguments();
+ try {
+ String[] s = recursiveGetDBusType(t[0], true, level+1);
+ if (s.length != 1) throw new DBusException(_("Multi-valued array types not permitted"));
+ out[level].append(s[0]);
+ s = recursiveGetDBusType(t[1], false, level+1);
+ if (s.length != 1) throw new DBusException(_("Multi-valued array types not permitted"));
+ out[level].append(s[0]);
+ } catch (ArrayIndexOutOfBoundsException AIOOBe) {
+ AIOOBe.printStackTrace(); // pego
+ if (AbstractConnection.EXCEPTION_DEBUG && Debug.debug) Debug.print(Debug.ERR, AIOOBe);
+ throw new DBusException(_("Map must have 2 parameters"));
+ }
+ out[level].append('}');
+ }
+ else if (List.class.isAssignableFrom((Class<? extends Object>) p.getRawType())) {
+ for (Type t: p.getActualTypeArguments()) {
+ if (Type.class.equals(t))
+ out[level].append((char) Message.ArgumentType.SIGNATURE);
+ else {
+ String[] s = recursiveGetDBusType(t, false, level+1);
+ if (s.length != 1) throw new DBusException(_("Multi-valued array types not permitted"));
+ out[level].append((char) Message.ArgumentType.ARRAY);
+ out[level].append(s[0]);
+ }
+ }
+ }
+ else if (p.getRawType().equals(Variant.class)) {
+ out[level].append((char) Message.ArgumentType.VARIANT);
+ }
+ else if (DBusInterface.class.isAssignableFrom((Class<? extends Object>) p.getRawType())) {
+ out[level].append((char) Message.ArgumentType.OBJECT_PATH);
+ }
+ else if (Tuple.class.isAssignableFrom((Class<? extends Object>) p.getRawType())) {
+ Type[] ts = p.getActualTypeArguments();
+ Vector<String> vs = new Vector<String>();
+ for (Type t: ts)
+ for (String s: recursiveGetDBusType(t, false, level+1))
+ vs.add(s);
+ return vs.toArray(new String[0]);
+ }
+ else
+ throw new DBusException(_("Exporting non-exportable parameterized type ")+c);
+ }
+
+ else if (c.equals(Byte.class)) out[level].append((char) Message.ArgumentType.BYTE);
+ else if (c.equals(Byte.TYPE)) out[level].append((char) Message.ArgumentType.BYTE);
+ else if (c.equals(Boolean.class)) out[level].append((char) Message.ArgumentType.BOOLEAN);
+ else if (c.equals(Boolean.TYPE)) out[level].append((char) Message.ArgumentType.BOOLEAN);
+ else if (c.equals(Short.class)) out[level].append((char) Message.ArgumentType.INT16);
+ else if (c.equals(Short.TYPE)) out[level].append((char) Message.ArgumentType.INT16);
+ else if (c.equals(UInt16.class)) out[level].append((char) Message.ArgumentType.UINT16);
+ else if (c.equals(Integer.class)) out[level].append((char) Message.ArgumentType.INT32);
+ else if (c.equals(Integer.TYPE)) out[level].append((char) Message.ArgumentType.INT32);
+ else if (c.equals(UInt32.class)) out[level].append((char) Message.ArgumentType.UINT32);
+ else if (c.equals(Long.class)) out[level].append((char) Message.ArgumentType.INT64);
+ else if (c.equals(Long.TYPE)) out[level].append((char) Message.ArgumentType.INT64);
+ else if (c.equals(UInt64.class)) out[level].append((char) Message.ArgumentType.UINT64);
+ else if (c.equals(Double.class)) out[level].append((char) Message.ArgumentType.DOUBLE);
+ else if (c.equals(Double.TYPE)) out[level].append((char) Message.ArgumentType.DOUBLE);
+ else if (c.equals(Float.class) && AbstractConnection.FLOAT_SUPPORT) out[level].append((char) Message.ArgumentType.FLOAT);
+ else if (c.equals(Float.class)) out[level].append((char) Message.ArgumentType.DOUBLE);
+ else if (c.equals(Float.TYPE) && AbstractConnection.FLOAT_SUPPORT) out[level].append((char) Message.ArgumentType.FLOAT);
+ else if (c.equals(Float.TYPE)) out[level].append((char) Message.ArgumentType.DOUBLE);
+ else if (c.equals(String.class)) out[level].append((char) Message.ArgumentType.STRING);
+ else if (c.equals(Variant.class)) out[level].append((char) Message.ArgumentType.VARIANT);
+ else if (c instanceof Class &&
+ DBusInterface.class.isAssignableFrom((Class<? extends Object>) c)) out[level].append((char) Message.ArgumentType.OBJECT_PATH);
+ else if (c instanceof Class &&
+ Path.class.equals((Class<? extends Object>) c)) out[level].append((char) Message.ArgumentType.OBJECT_PATH);
+ else if (c instanceof Class &&
+ ObjectPath.class.equals((Class<? extends Object>) c)) out[level].append((char) Message.ArgumentType.OBJECT_PATH);
+ else if (c instanceof Class &&
+ ((Class<? extends Object>) c).isArray()) {
+ if (Type.class.equals(((Class<? extends Object>) c).getComponentType()))
+ out[level].append((char) Message.ArgumentType.SIGNATURE);
+ else {
+ out[level].append((char) Message.ArgumentType.ARRAY);
+ String[] s = recursiveGetDBusType(((Class<? extends Object>) c).getComponentType(), false, level+1);
+ if (s.length != 1) throw new DBusException(_("Multi-valued array types not permitted"));
+ out[level].append(s[0]);
+ }
+ } else if (c instanceof Class &&
+ Struct.class.isAssignableFrom((Class<? extends Object>) c)) {
+ out[level].append((char) Message.ArgumentType.STRUCT1);
+ Type[] ts = Container.getTypeCache(c);
+ if (null == ts) {
+ Field[] fs = ((Class<? extends Object>) c).getDeclaredFields();
+ ts = new Type[fs.length];
+ for (Field f : fs) {
+ Position p = f.getAnnotation(Position.class);
+ if (null == p) continue;
+ ts[p.value()] = f.getGenericType();
+ }
+ Container.putTypeCache(c, ts);
+ }
+
+ for (Type t: ts)
+ if (t != null)
+ for (String s: recursiveGetDBusType(t, false, level+1))
+ out[level].append(s);
+ out[level].append(')');
+ } else {
+ throw new DBusException(_("Exporting non-exportable type ")+c);
+ }
+
+ if (Debug.debug) Debug.print(Debug.VERBOSE, "Converted Java type: "+c+" to D-Bus Type: "+out[level]);
+
+ return new String[] { out[level].toString() };
+ }
+
+ /**
+ * Converts a dbus type string into Java Type objects,
+ * @param dbus The DBus type or types.
+ * @param rv Vector to return the types in.
+ * @param limit Maximum number of types to parse (-1 == nolimit).
+ * @return number of characters parsed from the type string.
+ */
+ public static int getJavaType(String dbus, List<Type> rv, int limit) throws DBusException
+ {
+ if (null == dbus || "".equals(dbus) || 0 == limit) return 0;
+
+ try {
+ int i = 0;
+ for (; i < dbus.length() && (-1 == limit || limit > rv.size()); i++)
+ switch(dbus.charAt(i)) {
+ case Message.ArgumentType.STRUCT1:
+ int j = i+1;
+ for (int c = 1; c > 0; j++) {
+ if (')' == dbus.charAt(j)) c--;
+ else if (Message.ArgumentType.STRUCT1 == dbus.charAt(j)) c++;
+ }
+
+ Vector<Type> contained = new Vector<Type>();
+ int c = getJavaType(dbus.substring(i+1, j-1), contained, -1);
+ rv.add(new DBusStructType(contained.toArray(new Type[0])));
+ i = j;
+ break;
+ case Message.ArgumentType.ARRAY:
+ if (Message.ArgumentType.DICT_ENTRY1 == dbus.charAt(i+1)) {
+ contained = new Vector<Type>();
+ c = getJavaType(dbus.substring(i+2), contained, 2);
+ rv.add(new DBusMapType(contained.get(0), contained.get(1)));
+ i += (c+2);
+ } else {
+ contained = new Vector<Type>();
+ c = getJavaType(dbus.substring(i+1), contained, 1);
+ rv.add(new DBusListType(contained.get(0)));
+ i += c;
+ }
+ break;
+ case Message.ArgumentType.VARIANT:
+ rv.add(Variant.class);
+ break;
+ case Message.ArgumentType.BOOLEAN:
+ rv.add(Boolean.class);
+ break;
+ case Message.ArgumentType.INT16:
+ rv.add(Short.class);
+ break;
+ case Message.ArgumentType.BYTE:
+ rv.add(Byte.class);
+ break;
+ case Message.ArgumentType.OBJECT_PATH:
+ rv.add(DBusInterface.class);
+ break;
+ case Message.ArgumentType.UINT16:
+ rv.add(UInt16.class);
+ break;
+ case Message.ArgumentType.INT32:
+ rv.add(Integer.class);
+ break;
+ case Message.ArgumentType.UINT32:
+ rv.add(UInt32.class);
+ break;
+ case Message.ArgumentType.INT64:
+ rv.add(Long.class);
+ break;
+ case Message.ArgumentType.UINT64:
+ rv.add(UInt64.class);
+ break;
+ case Message.ArgumentType.DOUBLE:
+ rv.add(Double.class);
+ break;
+ case Message.ArgumentType.FLOAT:
+ rv.add(Float.class);
+ break;
+ case Message.ArgumentType.STRING:
+ rv.add(String.class);
+ break;
+ case Message.ArgumentType.SIGNATURE:
+ rv.add(Type[].class);
+ break;
+ case Message.ArgumentType.DICT_ENTRY1:
+ rv.add(Map.Entry.class);
+ contained = new Vector<Type>();
+ c = getJavaType(dbus.substring(i+1), contained, 2);
+ i+=c+1;
+ break;
+ default:
+ throw new DBusException(MessageFormat.format(_("Failed to parse DBus type signature: {0} ({1})."), new Object[] { dbus, dbus.charAt(i) }));
+ }
+ return i;
+ } catch (IndexOutOfBoundsException IOOBe) {
+ IOOBe.printStackTrace(); // pego
+ if (AbstractConnection.EXCEPTION_DEBUG && Debug.debug) Debug.print(Debug.ERR, IOOBe);
+ throw new DBusException(_("Failed to parse DBus type signature: ")+dbus);
+ }
+ }
+ /**
+ * Recursively converts types for serialization onto DBus.
+ * @param parameters The parameters to convert.
+ * @param types The (possibly generic) types of the parameters.
+ * @return The converted parameters.
+ * @throws DBusException Thrown if there is an error in converting the objects.
+ */
+ @SuppressWarnings("unchecked")
+ public static Object[] convertParameters(Object[] parameters, Type[] types, AbstractConnection conn) throws DBusException
+ {
+ if (null == parameters) return null;
+ for (int i = 0; i < parameters.length; i++) {
+ if (Debug.debug) Debug.print(Debug.VERBOSE,"Converting "+i+" from "+parameters[i]+" to "+types[i]);
+ if (null == parameters[i]) continue;
+
+ if (parameters[i] instanceof DBusSerializable) {
+ for (Method m: parameters[i].getClass().getDeclaredMethods())
+ if (m.getName().equals("deserialize")) {
+ Type[] newtypes = m.getParameterTypes();
+ Type[] expand = new Type[types.length + newtypes.length - 1];
+ System.arraycopy(types, 0, expand, 0, i);
+ System.arraycopy(newtypes, 0, expand, i, newtypes.length);
+ System.arraycopy(types, i+1, expand, i+newtypes.length, types.length-i-1);
+ types = expand;
+ Object[] newparams = ((DBusSerializable) parameters[i]).serialize();
+ Object[] exparams = new Object[parameters.length + newparams.length - 1];
+ System.arraycopy(parameters, 0, exparams, 0, i);
+ System.arraycopy(newparams, 0, exparams, i, newparams.length);
+ System.arraycopy(parameters, i+1, exparams, i+newparams.length, parameters.length-i-1);
+ parameters = exparams;
+ }
+ i--;
+ } else if (parameters[i] instanceof Tuple) {
+ Type[] newtypes = ((ParameterizedType) types[i]).getActualTypeArguments();
+ Type[] expand = new Type[types.length + newtypes.length - 1];
+ System.arraycopy(types, 0, expand, 0, i);
+ System.arraycopy(newtypes, 0, expand, i, newtypes.length);
+ System.arraycopy(types, i+1, expand, i+newtypes.length, types. length-i-1);
+ types = expand;
+ Object[] newparams = ((Tuple) parameters[i]).getParameters();
+ Object[] exparams = new Object[parameters.length + newparams.length - 1];
+ System.arraycopy(parameters, 0, exparams, 0, i);
+ System.arraycopy(newparams, 0, exparams, i, newparams.length);
+ System.arraycopy(parameters, i+1, exparams, i+newparams.length, parameters.length-i-1);
+ parameters = exparams;
+ if (Debug.debug) Debug.print(Debug.VERBOSE, "New params: "+Arrays.deepToString(parameters)+" new types: "+Arrays.deepToString(types));
+ i--;
+ } else if (types[i] instanceof TypeVariable &&
+ !(parameters[i] instanceof Variant))
+ // its an unwrapped variant, wrap it
+ parameters[i] = new Variant<Object>(parameters[i]);
+ else if (parameters[i] instanceof DBusInterface)
+ parameters[i] = conn.getExportedObject((DBusInterface) parameters[i]);
+ }
+ return parameters;
+ }
+ @SuppressWarnings("unchecked")
+ static Object deSerializeParameter(Object parameter, Type type, AbstractConnection conn) throws Exception
+ {
+ if (Debug.debug) Debug.print(Debug.VERBOSE, "Deserializing from "+parameter.getClass()+" to "+type.getClass());
+ if (null == parameter)
+ return null;
+
+ // its a wrapped variant, unwrap it
+ if (type instanceof TypeVariable
+ && parameter instanceof Variant) {
+ parameter = ((Variant)parameter).getValue();
+ }
+
+ // Turn a signature into a Type[]
+ if (type instanceof Class
+ && ((Class) type).isArray()
+ && ((Class) type).getComponentType().equals(Type.class)
+ && parameter instanceof String) {
+ Vector<Type> rv = new Vector<Type>();
+ getJavaType((String) parameter, rv, -1);
+ parameter = rv.toArray(new Type[0]);
+ }
+
+ // its an object path, get/create the proxy
+ if (parameter instanceof ObjectPath) {
+ if (type instanceof Class && DBusInterface.class.isAssignableFrom((Class) type))
+ parameter = conn.getExportedObject(
+ ((ObjectPath) parameter).source,
+ ((ObjectPath) parameter).path);
+ else
+ parameter = new Path(((ObjectPath) parameter).path);
+ }
+
+ // it should be a struct. create it
+ if (parameter instanceof Object[] &&
+ type instanceof Class &&
+ Struct.class.isAssignableFrom((Class) type)) {
+ if (Debug.debug) Debug.print(Debug.VERBOSE, "Creating Struct "+type+" from "+parameter);
+ Type[] ts = Container.getTypeCache(type);
+ if (null == ts) {
+ Field[] fs = ((Class) type).getDeclaredFields();
+ ts = new Type[fs.length];
+ for (Field f : fs) {
+ Position p = f.getAnnotation(Position.class);
+ if (null == p) continue;
+ ts[p.value()] = f.getGenericType();
+ }
+ Container.putTypeCache(type, ts);
+ }
+
+ // recurse over struct contents
+ parameter = deSerializeParameters((Object[]) parameter, ts, conn);
+ for (Constructor con: ((Class) type).getDeclaredConstructors()) {
+ try {
+ parameter = con.newInstance((Object[]) parameter);
+ break;
+ } catch (IllegalArgumentException IAe) {}
+ }
+ }
+
+ // recurse over arrays
+ if (parameter instanceof Object[]) {
+ Type[] ts = new Type[((Object[]) parameter).length];
+ Arrays.fill(ts, parameter.getClass().getComponentType());
+ parameter = deSerializeParameters((Object[]) parameter,
+ ts, conn);
+ }
+ if (parameter instanceof List) {
+ Type type2;
+ if (type instanceof ParameterizedType)
+ type2 = ((ParameterizedType) type).getActualTypeArguments()[0];
+ else if (type instanceof GenericArrayType)
+ type2 = ((GenericArrayType) type).getGenericComponentType();
+ else if (type instanceof Class && ((Class) type).isArray())
+ type2 = ((Class) type).getComponentType();
+ else
+ type2 = null;
+ if (null != type2)
+ parameter = deSerializeParameters((List) parameter, type2, conn);
+ }
+
+ // correct floats if appropriate
+ if (type.equals(Float.class) || type.equals(Float.TYPE))
+ if (!(parameter instanceof Float))
+ parameter = ((Number) parameter).floatValue();
+
+ // make sure arrays are in the correct format
+ if (parameter instanceof Object[] ||
+ parameter instanceof List ||
+ parameter.getClass().isArray()) {
+ if (type instanceof ParameterizedType)
+ parameter = ArrayFrob.convert(parameter,
+ (Class<? extends Object>) ((ParameterizedType) type).getRawType());
+ else if (type instanceof GenericArrayType) {
+ Type ct = ((GenericArrayType) type).getGenericComponentType();
+ Class cc = null;
+ if (ct instanceof Class)
+ cc = (Class) ct;
+ if (ct instanceof ParameterizedType)
+ cc = (Class) ((ParameterizedType) ct).getRawType();
+ Object o = Array.newInstance(cc, 0);
+ parameter = ArrayFrob.convert(parameter,
+ o.getClass());
+ } else if (type instanceof Class &&
+ ((Class) type).isArray()) {
+ Class cc = ((Class) type).getComponentType();
+ if ((cc.equals(Float.class) || cc.equals(Float.TYPE))
+ && (parameter instanceof double[])) {
+ double[] tmp1 = (double[]) parameter;
+ float[] tmp2 = new float[tmp1.length];
+ for (int i = 0; i < tmp1.length; i++)
+ tmp2[i] = (float) tmp1[i];
+ parameter = tmp2;
+ }
+ Object o = Array.newInstance(cc, 0);
+ parameter = ArrayFrob.convert(parameter,
+ o.getClass());
+ }
+ }
+ if (parameter instanceof DBusMap) {
+ if (Debug.debug) Debug.print(Debug.VERBOSE, "Deserializing a Map");
+ DBusMap dmap = (DBusMap) parameter;
+ Type[] maptypes = ((ParameterizedType) type).getActualTypeArguments();
+ for (int i = 0; i < dmap.entries.length; i++) {
+ dmap.entries[i][0] = deSerializeParameter(dmap.entries[i][0], maptypes[0], conn);
+ dmap.entries[i][1] = deSerializeParameter(dmap.entries[i][1], maptypes[1], conn);
+ }
+ }
+ return parameter;
+ }
+ static List<Object> deSerializeParameters(List<Object> parameters, Type type, AbstractConnection conn) throws Exception
+ {
+ if (Debug.debug) Debug.print(Debug.VERBOSE, "Deserializing from "+parameters+" to "+type);
+ if (null == parameters) return null;
+ for (int i = 0; i < parameters.size(); i++) {
+ if (null == parameters.get(i)) continue;
+
+ /* DO NOT DO THIS! IT'S REALLY NOT SUPPORTED!
+ * if (type instanceof Class &&
+ DBusSerializable.class.isAssignableFrom((Class) types[i])) {
+ for (Method m: ((Class) types[i]).getDeclaredMethods())
+ if (m.getName().equals("deserialize")) {
+ Type[] newtypes = m.getGenericParameterTypes();
+ try {
+ Object[] sub = new Object[newtypes.length];
+ System.arraycopy(parameters, i, sub, 0, newtypes.length);
+ sub = deSerializeParameters(sub, newtypes, conn);
+ DBusSerializable sz = (DBusSerializable) ((Class) types[i]).newInstance();
+ m.invoke(sz, sub);
+ Object[] compress = new Object[parameters.length - newtypes.length + 1];
+ System.arraycopy(parameters, 0, compress, 0, i);
+ compress[i] = sz;
+ System.arraycopy(parameters, i + newtypes.length, compress, i+1, parameters.length - i - newtypes.length);
+ parameters = compress;
+ } catch (ArrayIndexOutOfBoundsException AIOOBe) {
+ if (AbstractConnection.EXCEPTION_DEBUG && Debug.debug) Debug.print(Debug.ERR, AIOOBe);
+ throw new DBusException("Not enough elements to create custom object from serialized data ("+(parameters.size()-i)+" < "+(newtypes.length)+")");
+ }
+ }
+ } else*/
+ parameters.set(i, deSerializeParameter(parameters.get(i), type, conn));
+ }
+ return parameters;
+ }
+
+ @SuppressWarnings("unchecked")
+ static Object[] deSerializeParameters(Object[] parameters, Type[] types, AbstractConnection conn) throws Exception
+ {
+ if (Debug.debug) Debug.print(Debug.VERBOSE, "Deserializing from "+Arrays.deepToString(parameters)+" to "+Arrays.deepToString(types));
+ if (null == parameters) return null;
+
+ if (types.length == 1 && types[0] instanceof ParameterizedType
+ && Tuple.class.isAssignableFrom((Class) ((ParameterizedType) types[0]).getRawType())) {
+ types = ((ParameterizedType) types[0]).getActualTypeArguments();
+ }
+
+ for (int i = 0; i < parameters.length; i++) {
+ // CHECK IF ARRAYS HAVE THE SAME LENGTH <-- has to happen after expanding parameters
+ if (i >= types.length) {
+ if (Debug.debug) {
+ for (int j = 0; j < parameters.length; j++) {
+ Debug.print(Debug.ERR, String.format("Error, Parameters difference (%1d, '%2s')", j, parameters[j].toString()));
+ }
+ }
+ throw new DBusException(_("Error deserializing message: number of parameters didn't match receiving signature"));
+ }
+ if (null == parameters[i]) continue;
+
+ if ((types[i] instanceof Class &&
+ DBusSerializable.class.isAssignableFrom((Class<? extends Object>) types[i])) ||
+ (types[i] instanceof ParameterizedType &&
+ DBusSerializable.class.isAssignableFrom((Class<? extends Object>) ((ParameterizedType) types[i]).getRawType()))) {
+ Class<? extends DBusSerializable> dsc;
+ if (types[i] instanceof Class)
+ dsc = (Class<? extends DBusSerializable>) types[i];
+ else
+ dsc = (Class<? extends DBusSerializable>) ((ParameterizedType) types[i]).getRawType();
+ for (Method m: dsc.getDeclaredMethods())
+ if (m.getName().equals("deserialize")) {
+ Type[] newtypes = m.getGenericParameterTypes();
+ try {
+ Object[] sub = new Object[newtypes.length];
+ System.arraycopy(parameters, i, sub, 0, newtypes.length);
+ sub = deSerializeParameters(sub, newtypes, conn);
+ DBusSerializable sz = dsc.newInstance();
+ m.invoke(sz, sub);
+ Object[] compress = new Object[parameters.length - newtypes.length + 1];
+ System.arraycopy(parameters, 0, compress, 0, i);
+ compress[i] = sz;
+ System.arraycopy(parameters, i + newtypes.length, compress, i+1, parameters.length - i - newtypes.length);
+ parameters = compress;
+ } catch (ArrayIndexOutOfBoundsException AIOOBe) {
+ AIOOBe.printStackTrace(); // pego
+ if (AbstractConnection.EXCEPTION_DEBUG && Debug.debug) Debug.print(Debug.ERR, AIOOBe);
+ throw new DBusException(MessageFormat.format(_("Not enough elements to create custom object from serialized data ({0} < {1})."),
+ new Object[] { parameters.length-i, newtypes.length }));
+ }
+ }
+ } else
+ parameters[i] = deSerializeParameter(parameters[i], types[i], conn);
+ }
+ return parameters;
+ }
+}
+
+