/*
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.text.MessageFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Hashtable;
import java.util.List;
import cx.ath.matthew.debug.Debug;
class ArrayFrob
{
static Hashtable<Class<? extends Object>, Class<? extends Object>> primitiveToWrapper = new Hashtable<Class<? extends Object>, Class<? extends Object>>();
static Hashtable<Class<? extends Object>, Class<? extends Object>> wrapperToPrimitive = new Hashtable<Class<? extends Object>, Class<? extends Object>>();
static {
primitiveToWrapper.put( Boolean.TYPE, Boolean.class );
primitiveToWrapper.put( Byte.TYPE, Byte.class );
primitiveToWrapper.put( Short.TYPE, Short.class );
primitiveToWrapper.put( Character.TYPE, Character.class );
primitiveToWrapper.put( Integer.TYPE, Integer.class );
primitiveToWrapper.put( Long.TYPE, Long.class );
primitiveToWrapper.put( Float.TYPE, Float.class );
primitiveToWrapper.put( Double.TYPE, Double.class );
wrapperToPrimitive.put( Boolean.class, Boolean.TYPE );
wrapperToPrimitive.put( Byte.class, Byte.TYPE );
wrapperToPrimitive.put( Short.class, Short.TYPE );
wrapperToPrimitive.put( Character.class, Character.TYPE );
wrapperToPrimitive.put( Integer.class, Integer.TYPE );
wrapperToPrimitive.put( Long.class, Long.TYPE );
wrapperToPrimitive.put( Float.class, Float.TYPE );
wrapperToPrimitive.put( Double.class, Double.TYPE );
}
@SuppressWarnings("unchecked")
public static <T> T[] wrap(Object o) throws IllegalArgumentException
{
Class<? extends Object> ac = o.getClass();
if (!ac.isArray()) throw new IllegalArgumentException(_("Not an array"));
Class<? extends Object> cc = ac.getComponentType();
Class<? extends Object> ncc = primitiveToWrapper.get(cc);
if (null == ncc) throw new IllegalArgumentException(_("Not a primitive type"));
T[] ns = (T[]) Array.newInstance(ncc, Array.getLength(o));
for (int i = 0; i < ns.length; i++)
ns[i] = (T) Array.get(o, i);
return ns;
}
@SuppressWarnings("unchecked")
public static <T> Object unwrap(T[] ns) throws IllegalArgumentException
{
Class<? extends T[]> ac = (Class<? extends T[]>) ns.getClass();
Class<T> cc = (Class<T>) ac.getComponentType();
Class<? extends Object> ncc = wrapperToPrimitive.get(cc);
if (null == ncc) throw new IllegalArgumentException(_("Not a wrapper type"));
Object o = Array.newInstance(ncc, ns.length);
for (int i = 0; i < ns.length; i++)
Array.set(o, i, ns[i]);
return o;
}
public static <T> List<T> listify(T[] ns) throws IllegalArgumentException
{
return Arrays.asList(ns);
}
@SuppressWarnings("unchecked")
public static <T> List<T> listify(Object o) throws IllegalArgumentException
{
if (o instanceof Object[]) return listify((T[]) o);
if (!o.getClass().isArray()) throw new IllegalArgumentException(_("Not an array"));
List<T> l = new ArrayList<T>(Array.getLength(o));
for (int i = 0; i < Array.getLength(o); i++)
l.add((T)Array.get(o, i));
return l;
}
@SuppressWarnings("unchecked")
public static <T> T[] delist(List<T> l, Class<T> c) throws IllegalArgumentException
{
return l.toArray((T[]) Array.newInstance(c, 0));
}
public static <T> Object delistprimitive(List<T> l, Class<T> c) throws IllegalArgumentException
{
Object o = Array.newInstance(c, l.size());
for (int i = 0; i < l.size(); i++)
Array.set(o, i, l.get(i));
return o;
}
@SuppressWarnings("unchecked")
public static Object convert(Object o, Class<? extends Object> c) throws IllegalArgumentException
{
/* Possible Conversions:
*
** List<Integer> -> List<Integer>
** List<Integer> -> int[]
** List<Integer> -> Integer[]
** int[] -> int[]
** int[] -> List<Integer>
** int[] -> Integer[]
** Integer[] -> Integer[]
** Integer[] -> int[]
** Integer[] -> List<Integer>
*/
try {
// List<Integer> -> List<Integer>
if (List.class.equals(c)
&& o instanceof List)
return o;
// int[] -> List<Integer>
// Integer[] -> List<Integer>
if (List.class.equals(c)
&& o.getClass().isArray())
return listify(o);
// int[] -> int[]
// Integer[] -> Integer[]
if (o.getClass().isArray()
&& c.isArray()
&& o.getClass().getComponentType().equals(c.getComponentType()))
return o;
// int[] -> Integer[]
if (o.getClass().isArray()
&& c.isArray()
&& o.getClass().getComponentType().isPrimitive())
return wrap(o);
// Integer[] -> int[]
if (o.getClass().isArray()
&& c.isArray()
&& c.getComponentType().isPrimitive())
return unwrap((Object[]) o);
// List<Integer> -> int[]
if (o instanceof List
&& c.isArray()
&& c.getComponentType().isPrimitive())
return delistprimitive((List<Object>) o, (Class<Object>) c.getComponentType());
// List<Integer> -> Integer[]
if (o instanceof List
&& c.isArray())
return delist((List<Object>) o, (Class<Object>) c.getComponentType());
if (o.getClass().isArray()
&& c.isArray())
return type((Object[]) o, (Class<Object>) c.getComponentType());
} catch (Exception e) {
if (AbstractConnection.EXCEPTION_DEBUG && Debug.debug) Debug.print(Debug.ERR, e);
throw new IllegalArgumentException(e);
}
throw new IllegalArgumentException(MessageFormat.format(_("Not An Expected Convertion type from {0} to {1}"), new Object[] { o.getClass(), c}));
}
public static Object[] type(Object[] old, Class<Object> c)
{
Object[] ns = (Object[]) Array.newInstance(c, old.length);
for (int i = 0; i < ns.length; i++)
ns[i] = old[i];
return ns;
}
}