Reflection para atributo Array

4 respostas
black_fire

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(); } } }

4 Respostas

LecaDF

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

black_fire

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
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;
		}
	}
}
Classe Action Utils
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;
		}
	}	
}
cv1

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

black_fire

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(); }

Criado 14 de janeiro de 2005
Ultima resposta 15 de jan. de 2005
Respostas 4
Participantes 3