Reflection para atributo Array

E ai galela, blz!

Como foi o final de ano? Um feliz 2005 pra todos… :stuck_out_tongue:

Bem, vamos ao problema.
Estou tentando fazer reflection de um valor que eu recebi da página para um campo Array.
Pra mim eu deveria tratar o array como um objeto, porém quando eu tento atribuir o valor do array tá subindo uma IllegalArgumentException.
Algém tem idéia de como identificar que tipo que é o array. se ele é um Object[], String[], int[], float[], etc…

Segue abaixo o que estou tentando fazer… Como não consegui identificar estou dando a possibilidade apenas de String[].

Valeu galera…
Qualquer ajuda vai quebra um galhão…

public void parameterReflection(Hashtable hashtable) { Enumeration e = hashtable.keys(); while (e.hasMoreElements()) { try { String key = (String) e.nextElement(); Field f = this.getClass().getDeclaredField(key); if (f.getType() == Integer.TYPE) f.setInt(this,new Integer((String)hashtable.get(key)).intValue()); else if (f.getType() == Boolean.TYPE) f.setBoolean(this,new Boolean((String)hashtable.get(key)).booleanValue()); else if (f.getType() == Byte.TYPE) f.setByte(this,new Byte((String)hashtable.get(key)).byteValue()); else if (f.getType() == Double.TYPE) f.setDouble(this,new Double((String)hashtable.get(key)).doubleValue()); else if (f.getType() == Character.TYPE) f.setChar(this,String.valueOf(hashtable.get(key)).charAt(0)); else if (f.getType() == Float.TYPE) f.setFloat(this,new Float((String)hashtable.get(key)).floatValue()); else if (f.getType() == Long.TYPE) f.setLong(this,new Long((String)hashtable.get(key)).longValue()); else if (f.getType() == Short.TYPE) f.setShort(this,new Short((String)hashtable.get(key)).shortValue()); else if (f.getType().isArray()) { // TODO Inplement other type of arrays. // Aqui que eu precisava identificar qual o tipo do array // para fazer o cast corretamente String s1 = (String) hashtable.get(key); if (s1 != null && s1.substring(0,1).equals("[") && s1.substring(s1.length() -1 ,s1.length()).equals("]") ) s1 = s1.substring(1 ,s1.length() -1); f.set(this,StringUtils.split(s1,",")); } else f.set(this,hashtable.get(key)); } catch (SecurityException e1) { e1.printStackTrace(); } catch (IllegalArgumentException e1) { e1.printStackTrace(); } catch (NoSuchFieldException e1) { e1.printStackTrace(); } catch (IllegalAccessException e1) { e1.printStackTrace(); } } }

Rodrigo para a manipularmos objetos do tipo array através da reflexão deve-se utilizar a classe java.lang.reflect.Array que possibilita atribuir/recuperar o(s) valore(s) do array. Realizei uma pequena modificação no seu método a título de exemplo conforme pode ser visualizado no código.

public class GUJ {

	private int[] numero = { 20, 30, 50 };

	public void parameterReflection(Hashtable hashtable) {
		Enumeration e = hashtable.keys();
		while (e.hasMoreElements()) {
			try {
				String key = (String) e.nextElement();
				Field f = this.getClass().getDeclaredField(key);
				if (f.getType() == Integer.TYPE)
					f.setInt(this, new Integer((String) hashtable.get(key)).intValue());
				else if (f.getType() == Boolean.TYPE)
					f.setBoolean(this, new Boolean((String) hashtable.get(key)).booleanValue());
				else if (f.getType() == Byte.TYPE)
					f.setByte(this, new Byte((String) hashtable.get(key)).byteValue());
				else if (f.getType() == Double.TYPE)
					f.setDouble(this, new Double((String) hashtable.get(key)).doubleValue());
				else if (f.getType() == Character.TYPE)
					f.setChar(this, String.valueOf(hashtable.get(key)).charAt(0));
				else if (f.getType() == Float.TYPE)
					f.setFloat(this, new Float((String) hashtable.get(key)).floatValue());
				else if (f.getType() == Long.TYPE)
					f.setLong(this, new Long((String) hashtable.get(key)).longValue());
				else if (f.getType() == Short.TYPE)
					f.setShort(this, new Short((String) hashtable.get(key)).shortValue());
				else if (f.getType().isArray()) {
					// TODO Inplement other type of arrays.
					// Aqui que eu precisava identificar qual o tipo do array 
					// para fazer o cast corretamente
					Object oo = f.get(this);

					int length = Array.getLength(oo);
					// TODO - poderia ser realizado um loop para obter todos os valores do array.

					// recuperando um valor
					Object o = Array.get(oo, length - 2);

					if (oo.getClass().isInstance(Array.newInstance(int.class, length))) {
						System.err.println(Array.getInt(oo, 0));
						// TODO - sua lógica.
					}                    
					/*String s1 = (String) hashtable.get(key);
					if (s1 != null
						&& s1.substring(0, 1).equals("[")
						&& s1.substring(s1.length() - 1, s1.length()).equals("]"))
						s1 = s1.substring(1, s1.length() - 1);
					f.set(this, StringUtils.split(s1, ",")); */
				} else
					f.set(this, hashtable.get(key));
			} catch (SecurityException e1) {
				e1.printStackTrace();
			} catch (IllegalArgumentException e1) {
				e1.printStackTrace();
			} catch (NoSuchFieldException e1) {
				e1.printStackTrace();
			} catch (IllegalAccessException e1) {
				e1.printStackTrace();
			}
		}
	}
	public static void main(String[] args) {
		GUJ g = new GUJ();
		Hashtable m = new Hashtable();
		m.put("numero", g);
		g.parameterReflection(m);
	}
}

Qualquer dúvida sinta-se a vontade.

Alessandro
JavaMail

Valeu kra…
Agora ficou 100%… brigadão… :wink:

Bem, minha classe final ficou assim…
Um abraço para todos…

Método para fazer a reflection

[code]public void parameterReflection(Hashtable params) {
String key = null;
String[] value = null;
Enumeration e = params.keys();

while (e.hasMoreElements()) {
	try {
		key   = (String) e.nextElement();
		value = (String[]) params.get(key);
		if (value == null || value.length == 0) 
			continue;
		
		Field f = this.getClass().getDeclaredField(key);
		
		if (f.getType() == Integer.TYPE) 
			f.setInt(this,new Integer(value[0]).intValue());
		else if (f.getType() == Boolean.TYPE) 
			f.setBoolean(this,new Boolean(value[0]).booleanValue());
		else if (f.getType() == Byte.TYPE)
			f.setByte(this,new Byte(value[0]).byteValue());
		else if (f.getType() == Double.TYPE)
			f.setDouble(this,new Double(value[0]).doubleValue());
		else if (f.getType() == Character.TYPE)
			f.setChar(this,value[0].charAt(0));
		else if (f.getType() == Float.TYPE)
			f.setFloat(this,new Float(value[0]).floatValue());
		else if (f.getType() == Long.TYPE)
			f.setLong(this,new Long(value[0]).longValue());
		else if (f.getType() == Short.TYPE)
			f.setShort(this,new Short(value[0]).shortValue());
		else if (f.getType().isArray()) {
			
			if (f.getType().isInstance(Array.newInstance(int.class, 0)))
				f.set(this, ActionUtils.strArrayToIntArray(value));
			else if (f.getType().isInstance(Array.newInstance(boolean.class, 0)))
				f.set(this, ActionUtils.strArrayToBooleanArray(value));
			else if (f.getType().isInstance(Array.newInstance(byte.class, 0)))
				f.set(this, ActionUtils.strArrayToByteArray(value));
			else if (f.getType().isInstance(Array.newInstance(double.class, 0)))
				f.set(this, ActionUtils.strArrayToDoubleArray(value));
			else if (f.getType().isInstance(Array.newInstance(char.class, 0)))
				f.set(this, ActionUtils.strArrayToCharArray(value));
			else if (f.getType().isInstance(Array.newInstance(float.class, 0)))
				f.set(this, ActionUtils.strArrayToFloatArray(value));
			else if (f.getType().isInstance(Array.newInstance(long.class, 0)))
				f.set(this, ActionUtils.strArrayToLongArray(value));
			else if (f.getType().isInstance(Array.newInstance(short.class, 0)))
				f.set(this, ActionUtils.strArrayToShortArray(value));
			else if (f.getType().isInstance(Array.newInstance(String.class, 0)))
				f.set(this, value);
			else
				f.set(this, ActionUtils.strArrayToObjectArray(value));
		}
		else
			f.set(this,value[0]);
		
	} catch (SecurityException e1) {
		e1.printStackTrace();
	} catch (IllegalArgumentException e1) {
		e1.printStackTrace();
	} catch (NoSuchFieldException e1) {
		e1.printStackTrace();
	} catch (IllegalAccessException e1) {
		e1.printStackTrace();
	}
	finally {
		key        = null;
		value      = null;
	}
}

}[/code]

Classe Action Utils

[code]import java.io.ByteArrayInputStream;
import java.io.ObjectInputStream;

public class ActionUtils {

public static int[] strArrayToIntArray(String[] value) {
	try {
		int [] a = new int[value.length];
		for (int i = 0; i < value.length; i++) {
			a[i] = new Integer(value[i]).intValue();
		}
		return a;
	}
	catch (Exception e) {
		return null;
	}
}

public static boolean[] strArrayToBooleanArray(String[] value) {
	try {
		boolean[] a = new boolean[value.length];
		for (int i = 0; i < value.length; i++) {
			a[i] = new Boolean((value[i])).booleanValue();
		}
		return a;
	}
	catch (Exception e) {
		return null;
	}
}

public static byte[] strArrayToByteArray(String[] value) {
	try {
		byte[] a = new byte[value.length];
		for (int i = 0; i < value.length; i++) {
			a[i] = new Byte((value[i])).byteValue();
		}
		return a;
	}
	catch (Exception e) {
		return null;
	}
}

public static double[] strArrayToDoubleArray(String[] value) {
	try {
		double[] a = new double[value.length];
		for (int i = 0; i < value.length; i++) {
			a[i] = new Double((value[i])).doubleValue();
		}
		return a;
	}
	catch (Exception e) {
		return null;
	}
}

public static char[] strArrayToCharArray(String[] value) {
	try {
		char[] a = new char[value.length];
		for (int i = 0; i < value.length; i++) {
			a[i] = value[i].charAt(0);
		}
		return a;
	}
	catch (Exception e) {
		return null;
	}
}

public static float[] strArrayToFloatArray(String[] value) {
	try {
		float[] a = new float[value.length];
		for (int i = 0; i < value.length; i++) {
			a[i] = new Float((value[i])).floatValue();
		}
		return a;
	}
	catch (Exception e) {
		return null;
	}
}

public static long[] strArrayToLongArray(String[] value) {
	try {
		long[] a = new long[value.length];
		for (int i = 0; i < value.length; i++) {
			a[i] = new Long((value[i])).longValue();
		}
		return a;
	}
	catch (Exception e) {
		return null;
	}
}

public static short[] strArrayToShortArray(String[] value) {
	try {
		short[] a = new short[value.length];
		for (int i = 0; i < value.length; i++) {
			a[i] = new Short((value[i])).shortValue();
		}
		return a;
	}
	catch (Exception e) {
		return null;
	}
}

public static Object[] strArrayToObjectArray(String[] value) {
	try {
		Object[] a = new Object[value.length];
		for (int i = 0; i < value.length; i++) {
			ByteArrayInputStream is = new ByteArrayInputStream(value[i].getBytes());
			ObjectInputStream s = new ObjectInputStream(is);				
			a[i] = (Object) s.readObject();
		}
		return a;
	}
	catch (Exception e) {
		return null;
	}
}	

}[/code]

Esse “catch exception return null” ficou lindo. Ah, extract method vai bem tambem. :twisted:

Pô Cv, sem humilhar né :oops: … rsrsrsrsrsr

É que se ele der exception preciso não retornar nada, pq pode ser que ele tenha feito alguma coisa tipo, preenchido alguns parâmetros e faltando outros.
Eu tentei usar o extract method, mas ele não retorna getter e setters…

Se vc tiver alguma idéia maneira, dá uma alô… :smiley:

Um abraço gralera…

private ActionForward reflectMethod(String methodName) { boolean reflectionError = false; try { Method method = this.getClass().getMethod(methodName, null); return (ActionForward) method.invoke(this, null); } catch (Exception e) { log.error(e.getMessage(), e); reflectionError = true; } finally { if (! reflectionError) log.info("Método ["+methodName+"()] chamado com sucesso."); } return exceptionForward(); }