// imports aqui public class ConsultaGenericaBusinessImpl implements ConsultaGenericaBusiness { @SuppressWarnings("unchecked") public ConsultaGenerica retornaConsultaGenericaByBean(Class c) throws BusinessException { ConsultaGenerica cgb = new ConsultaGenerica(); DaoFactory daoFactory = DaoFactory.getInstance(); // percorre todos os atributos declarados na classe e superclasses. for (Class clazz = c; clazz != null; clazz = clazz.getSuperclass()) { for (Field field : clazz.getDeclaredFields()) { String fieldName = field.getName(); Class fieldType = field.getType(); AtributoValor av = null; // se o atributo é um tipo complexo que está referenciado a uma lista então possui a // anotação @ManyToOne da JPA. if (isAnnotationPresent(field, ManyToOne.class)) { // a partir do tipo genérico retorna a respectiva Dao e obtem a quantidade de registros. Dao dao = daoFactory.getDao(fieldType); // se estiver anotado com FewElements indica que está relacionado à uma "lista de poucos itens". if (isAnnotationPresent(field, FewElements.class)) { av = new AtributoValorTipoLista(); av.setTipo(TipoAtributoValor.RELACIONAMENTO_LISTA); List listaOpcoes = dao.retornaTudo(); if (listaOpcoes.size() > 0) { // a partir do primeiro elemento da lista, descobre qual o tipo do objeto que ela agrega. Class objectGenericType = listaOpcoes.get(0).getClass(); // obtem a definição dos métodos acessores dos atributos de Id e Descrição. Method methodGetId = getIdFieldAccessor(objectGenericType); Method methodGetDescription = getDescriptionFieldAccessor(objectGenericType); for (Object object : listaOpcoes) { Object idValue = getValueFromField(methodGetId, object); String descriptionValue = (String)getValueFromField(methodGetDescription, object); ((AtributoValorTipoLista)av).addOpcao(new Long(idValue.toString()), descriptionValue); } } } else { // já que é uma lista com muitos elementos então define como um atributo complexo // e será buscado através de uma nova consulta. av = new AtributoValor(); av.setTipo(TipoAtributoValor.RELACIONAMENTO_COMPLEXO); } } else if (isAnnotationPresent(field, OneToMany.class)) { // atributos anotados com OneToMany não devem ser listados. } else if (fieldType.isEnum()){ av = new AtributoValorTipoLista(); av.setTipo(TipoAtributoValor.ENUMERACAO); for (Object enumConstant : fieldType.getEnumConstants()) { try { Long idValue = new Long(String.valueOf(enumConstant.getClass().getMethod("ordinal").invoke(enumConstant))); String descriptionValue = enumConstant.toString(); ((AtributoValorTipoLista)av).addOpcao(idValue, descriptionValue); } catch (Exception e) { throw new DevTimeException(e.toString()); } } // for opções } else { // o atributo é um tipo primitivo (ou um Wrapper) av = new AtributoValor(); av.setTipo(TipoAtributoValor.PRIMITIVO); } // end else av.setNomeAtributo(fieldName); av.setTipoAtributo(fieldType); cgb.addAtributoValor(av); } // end foreach } // end for return cgb; } @SuppressWarnings("unchecked") private Method getIdFieldAccessor(Class c) { try { for (Class clazz = c; clazz != null; clazz = clazz.getSuperclass()) { for (Method method : clazz.getDeclaredMethods()) { if (method.isAnnotationPresent(Id.class)) { return method; } } } } catch (Exception e) { throw new DevTimeException(e.toString()); } throw new DevTimeException("erro.janela.IdAnnotationMissing"); } @SuppressWarnings("unchecked") private Method getDescriptionFieldAccessor(Class c) { for (Class clazz = c; clazz != null; clazz = clazz.getSuperclass()) { for (Method method : clazz.getDeclaredMethods()) { if (method.isAnnotationPresent(DescriptionField.class)) { return method; } } } throw new DevTimeException("erro.janela.descriptionFieldAnnotationMissing"); } // obtem o valor do atributo de instância através do seu método get. private Object getValueFromField(Method method, Object object) { try { return method.invoke(object); } catch (Exception e) { throw new DevTimeException(e.toString()); } } @SuppressWarnings("unchecked") private boolean isAnnotationPresent(Field field, Class annotation) { if (field.isAnnotationPresent(annotation)) { return true; } else { // procura a anotação no seu getter. Class ownerClass = field.getDeclaringClass(); // descobre qual o nome do método a ser obtido. String fieldName = field.getName(); String firstChar = String.valueOf(fieldName.charAt(0)).toUpperCase(); fieldName = firstChar + fieldName.substring(1); String getterName = "get" + fieldName; try { Method methodDef = ownerClass.getMethod(getterName); return (methodDef.isAnnotationPresent(annotation)); } catch (Exception e) { throw new DevTimeException(e.toString()); } } } }