/******************************************************************************* * Copyright © 2012, 2013 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation * *******************************************************************************/ package org.eclipse.edt.java.jtopen; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import org.eclipse.edt.java.jtopen.access.AS400Array; import org.eclipse.edt.java.jtopen.access.AS400Timestamp; import org.eclipse.edt.javart.AnyBoxedObject; import org.eclipse.edt.javart.Executable; import org.eclipse.edt.javart.resources.ExecutableBase; import org.eclipse.edt.runtime.java.eglx.lang.EBigint; import org.eclipse.edt.runtime.java.eglx.lang.EDate; import org.eclipse.edt.runtime.java.eglx.lang.EDecimal; import org.eclipse.edt.runtime.java.eglx.lang.EFloat; import org.eclipse.edt.runtime.java.eglx.lang.EInt; import org.eclipse.edt.runtime.java.eglx.lang.EList; import org.eclipse.edt.runtime.java.eglx.lang.ESmallfloat; import org.eclipse.edt.runtime.java.eglx.lang.ESmallint; import org.eclipse.edt.runtime.java.eglx.lang.EString; import org.eclipse.edt.runtime.java.eglx.lang.ETime; import org.eclipse.edt.runtime.java.eglx.lang.ETimestamp; import com.ibm.as400.access.AS400DataType; import com.ibm.as400.access.AS400Structure; import eglx.lang.AnyException; import eglx.lang.AnyValue; import eglx.lang.InvalidArgumentException; public class AS400Converter { public AS400Converter xx; @SuppressWarnings({ "unchecked", "rawtypes" }) public static Object convertFromAS400(final Object eglObject, final Object as400ConvertedData)throws AnyException { if(eglObject instanceof AnyBoxedObject<?>){ ((AnyBoxedObject)eglObject).ezeCopy(convertFromAS400(((AnyBoxedObject<?>)eglObject).ezeUnbox(), as400ConvertedData)); return eglObject; } if(eglObject instanceof List<?>){ for(int idx = 0; idx < ((List<?>)eglObject).size(); idx++){ ((List)eglObject).set(idx, convertFromAS400(((List<?>)eglObject).get(idx), ((Object[])as400ConvertedData)[idx])); } return eglObject; } else if(eglObject instanceof AnyValue){ //record return convertFromAS400Structure(eglObject, as400ConvertedData); } else if(eglObject instanceof ExecutableBase){ //handler return convertFromAS400Structure(eglObject, as400ConvertedData); } else{ return as400ConvertedData; } } private static Object convertFromAS400Structure(final Object object, final Object as400ConvertedData)throws AnyException { int idx = 0; for(Field field : getFields(object.getClass())){ String name = field.getName(); try { StringBuilder setterName = new StringBuilder(field.getName().substring(0,1).toUpperCase()); setterName.append(field.getName().substring(1)); Method setMethod = null; try{ setMethod = object.getClass().getMethod(new StringBuilder("set").append(setterName).toString(), field.getType()); } catch(NoSuchMethodException nsme){ } Method getMethod = null; try{ getMethod = object.getClass().getMethod(new StringBuilder("get").append(setterName).toString(), (Class<?>[])null); } catch(NoSuchMethodException nsme){ } if(getMethod == null){ try{ getMethod = object.getClass().getMethod(new StringBuilder("is").append(setterName).toString(), (Class<?>[])null); } catch(NoSuchMethodException nsme){ } } Object existingFieldObject = null; if(getMethod != null && Modifier.isPublic(getMethod.getModifiers())){ existingFieldObject = getMethod.invoke(object, (Object[])null); } else if(Modifier.isPublic(field.getModifiers())){ existingFieldObject = field.get(object); } if((getMethod != null && Modifier.isPublic(getMethod.getModifiers()) || Modifier.isPublic(field.getModifiers()))){ Object newEglValue = convertFromAS400(existingFieldObject, ((Object[])as400ConvertedData)[idx++]); if(setMethod != null && Modifier.isPublic(setMethod.getModifiers())){ setMethod.invoke(object, newEglValue); } else if(Modifier.isPublic(field.getModifiers())){ field.set(object, newEglValue); } } } catch (Throwable t) { InvalidArgumentException ex = new InvalidArgumentException(); ex.initCause(t); ex.setMessageID("convertFromAS400Structure"); ex.setMessage("Error convertFromAS400Structure field:" + name); throw ex; } } return object; } @SuppressWarnings("unchecked") public static Object convertToObjects(Object object, AS400DataType as400Datatype){ if(object instanceof AnyBoxedObject<?>) return convertToObjects(((AnyBoxedObject<?>)object).ezeUnbox(), as400Datatype); else if(object instanceof List<?> && as400Datatype instanceof AS400Array){ List<Object> array = new ArrayList<Object>(); AS400DataType arrayElementsAS400Type = ((AS400Array)as400Datatype).getType(); if(array.size() != ((AS400Array)as400Datatype).getNumberOfElements()){ resizeList((List<Object>)object, (AS400Array)as400Datatype); } for(Object element : (List<?>)object){ array.add(convertToObjects(element, arrayElementsAS400Type)); } return array.toArray(new Object[array.size()]); } else if(object instanceof AnyValue && as400Datatype instanceof AS400Structure){ //record return convertStructureToObjects(object, (AS400Structure)as400Datatype); } else if(object instanceof ExecutableBase && as400Datatype instanceof AS400Structure){ //handler return convertStructureToObjects(object, (AS400Structure)as400Datatype); } else{ return object; } } private static Object convertStructureToObjects(final Object object, AS400Structure as400Datatype)throws AnyException { List<Object> convertedFields = new ArrayList<Object>(); AS400DataType[] as400Fields = as400Datatype.getMembers(); int as400Idx = 0; for(Field field : getFields(object.getClass())){ String name = field.getName(); try { StringBuilder getterName = new StringBuilder(field.getName().substring(0,1).toUpperCase()); getterName.append(field.getName().substring(1)); Method method = null; try{ method = object.getClass().getMethod(new StringBuilder("get").append(getterName).toString(), (Class<?>[])null); } catch(NoSuchMethodException nsme){ } if(method == null){ try{ method = object.getClass().getMethod(new StringBuilder("is").append(getterName).toString(), (Class<?>[])null); } catch(NoSuchMethodException nsme){ } } if(method != null && Modifier.isPublic(method.getModifiers())){ convertedFields.add(convertToObjects(method.invoke(object, (Object[])null), as400Fields[as400Idx++])); } else if(Modifier.isPublic(field.getModifiers())){ convertedFields.add(convertToObjects(field.get(object), as400Fields[as400Idx++])); } } catch (Throwable t) { InvalidArgumentException ex = new InvalidArgumentException(); ex.initCause(t); ex.setMessageID("convertStructureToObjects"); ex.setMessage("Error convert AS400 objects to a structure field:" + name); throw ex; } } return convertedFields.toArray(new Object[convertedFields.size()]); } @SuppressWarnings({ "rawtypes", "unchecked" }) private static void resizeList(List list, AS400Array as400Array){ if(EBigint.class.equals(as400Array.getEGLElementType())){ EList.resize(list, as400Array.getNumberOfElements(), EList.BigintFactory); } else if(EDate.class.equals(as400Array.getEGLElementType())){ EList.resize(list, as400Array.getNumberOfElements(), EList.DateFactory); } else if(EDecimal.class.equals(as400Array.getEGLElementType())){ EList.resize(list, as400Array.getNumberOfElements(), EList.DecimalFactory); } else if(EFloat.class.equals(as400Array.getEGLElementType())){ EList.resize(list, as400Array.getNumberOfElements(), EList.FloatFactory); } else if(EInt.class.equals(as400Array.getEGLElementType())){ EList.resize(list, as400Array.getNumberOfElements(), EList.IntFactory); } else if(ESmallfloat.class.equals(as400Array.getEGLElementType())){ EList.resize(list, as400Array.getNumberOfElements(), EList.SmallfloatFactory); } else if(ESmallint.class.equals(as400Array.getEGLElementType())){ EList.resize(list, as400Array.getNumberOfElements(), EList.SmallintFactory); } else if(EString.class.equals(as400Array.getEGLElementType())){ EList.resize(list, as400Array.getNumberOfElements(), EList.StringFactory); } else if(ETime.class.equals(as400Array.getEGLElementType())){ EList.resize(list, as400Array.getNumberOfElements(), EList.TimeFactory); } else if(ETimestamp.class.equals(as400Array.getEGLElementType())){ AS400DataType elementType = as400Array.getType(); while(elementType instanceof AS400Array){ elementType = ((AS400Array)elementType).getType(); } if(elementType instanceof AS400Timestamp){ EList.resize(list, as400Array.getNumberOfElements(), new EList.TimestampFactory(((AS400Timestamp)elementType).getStartCode(), ((AS400Timestamp)elementType).getEndCode())); } } else if(AnyValue.class.isAssignableFrom(as400Array.getEGLElementType())){ EList.resize(list, as400Array.getNumberOfElements(), new EList.ElementFactory(as400Array.getEGLElementType())); } else if(ExecutableBase.class.isAssignableFrom(as400Array.getEGLElementType())){ EList.resize(list, as400Array.getNumberOfElements(), new EList.ElementFactory(as400Array.getEGLElementType())); } } private static List<Field> getFields(Class<?> clazz){ List<Field> fields = new ArrayList<Field>(); do{ fields.addAll(Arrays.asList(clazz.getDeclaredFields())); clazz = clazz.getSuperclass(); }while(eglx.lang.EAny.class.isAssignableFrom(clazz) || Executable.class.isAssignableFrom(clazz)); return fields; } }