Recursividade
Autor: Arthur Tavares | Publicado: 2013-12-12T08:48:00-08:00


Para entender um método recursivo, primeiro você deve entender um método recursivo.



Eu me orgulho de poucos códigos. ESTE é um deles.



--------------------------------------------



public class DataObjectMetadataService {



 @Resource(name = "dataObjectMetadataDAOImpl")

 private DataObjectMetadataDAO domDAO;

 

 private List&lt;Programa&gt; progs = new ArrayList&lt;Programa&gt;();

 private Boolean carregaCampos;



 public List&lt;DataObjectMetadata&gt; createOrRetrieveByClassName(DataObjectMetadataFilter filter) {

  List&lt;DataObjectMetadata&gt; newDatas = null;

  this.carregaCampos = filter.getCarregaCampos();



  filter.setNmPrograma(domDAO.buscaClassNameCompleto(filter));

  progs = domDAO.pesquisaPrograma(filter);

    

  if(filter.getNmPrograma() != null) {

   List&lt;DataObjectMetadata&gt; impedeRetorno = new ArrayList&lt;DataObjectMetadata&gt;();

   newDatas = criaEstruturaClasse(filter.getNmPrograma(), impedeRetorno);

   

   if(this.carregaCampos){

    percorreNivelCampos(newDatas);    

    while(newDatas.get(0).getLevel() == null) {

     defineNivel(newDatas);

    }

   }&nbsp;

  }



  return newDatas;

 }



 private List&lt;DataObjectMetadata&gt; criaEstruturaClasse(String className, List&lt;DataObjectMetadata&gt; impedeRetorno) {



  List&lt;DataObjectMetadata&gt; datas = null;



  try {



   AbstractEntityPersister persister = buscaPropriedadesBanco(Class.forName(className));



   DataObjectMetadata data = new DataObjectMetadata();

   data.setClassName(persister.getName());

   impedeRetorno.add(data);

   

   if(carregaCampos){

    datas = montaDadosClasse(persister, impedeRetorno);

    completaDadosData(datas);    

   } else {

    datas = montaDadosProgs(persister, impedeRetorno);

   }

  } catch(ClassNotFoundException e) {

   e.printStackTrace();

  }



  return datas;



 }



 private &lt;T&gt; AbstractEntityPersister buscaPropriedadesBanco(Object cls) {

  AbstractEntityPersister persister = null;

  ClassMetadata hibernateMetadata = domDAO.findHibernateMetadata((Class&lt;?&gt;) cls);



  if(hibernateMetadata != null) {

   if(hibernateMetadata instanceof AbstractEntityPersister) {

    persister = (AbstractEntityPersister) hibernateMetadata;

   }

  }

  return persister;

 }



 private List&lt;DataObjectMetadata&gt; montaDadosClasse(AbstractEntityPersister persister, List&lt;DataObjectMetadata&gt; impedeRetorno) {



  List&lt;DataObjectMetadata&gt; ir = copiaListaRetorno(impedeRetorno);



  List&lt;DataObjectMetadata&gt; datas = new ArrayList&lt;DataObjectMetadata&gt;();

  DataObjectMetadata data = null;



  if(persister != null) {

   String[] columnKey = persister.getKeyColumnNames();

   String[] columnNames = persister.getPropertyNames();

   Type[] columnTypes = persister.getPropertyTypes();

   boolean[] columnNullable = persister.getPropertyNullability();



   if(columnKey != null) {

    List&lt;String&gt; keys = new ArrayList&lt;String&gt;(Arrays.asList(columnKey));

    for(String key : keys) {

     data = new DataObjectMetadata();



     data.setDataStamp(new Date());



     data.setTableName(persister.getTableName());

     data.setClassName(persister.getName());

     data.setColumnName(key);

     data.setColumnType("Integer");

     data.setIsNullable(SimNao.NAO);

     data.setIsClassAntara(SimNao.NAO);

     data.setMustInspectElement(SimNao.NAO);



     data.setDataObjectMetadata(verificaSubObjetos(data, ir));



     datas.add(data);

    }

   }



   if((columnNames != null) &amp;&amp; (columnTypes != null)) {

    List&lt;String&gt; colunas = new ArrayList&lt;String&gt;(Arrays.asList(columnNames));

    List&lt;Type&gt; tipos = new ArrayList&lt;Type&gt;(Arrays.asList(columnTypes));



    if((colunas != null) &amp;&amp; (tipos != null)) {

     for(int i = 0; i &lt; colunas.size(); i++) {

      data = new DataObjectMetadata();



      data.setDataStamp(new Date());



      data.setTableName(persister.getTableName());

      data.setClassName(persister.getName());

      data.setColumnName(colunas.get(i));

      data.setColumnType(tipos.get(i).getName());

      data.setIsNullable(columnNullable[i] ? SimNao.SIM : SimNao.NAO);

      data.setIsClassAntara(isClasseAntara(data.getColumnType()));

      if(SimNao.SIM.equals(data.getIsClassAntara())) {

       data.setMustInspectElement(deveInspecionarElemento(data.getColumnType(), ir));

      } else {

       data.setMustInspectElement(SimNao.NAO);

      }



      data.setDataObjectMetadata(verificaSubObjetos(data, ir));



      datas.add(data);



     }

    }

   }

  }



  return datas;

 }



 private void completaDadosData(List&lt;DataObjectMetadata&gt; datas) {



  List&lt;DataObjectMetadata&gt; loadDatas = new ArrayList&lt;DataObjectMetadata&gt;();

  loadDatas = domDAO.loadMedatadas(datas);

  if(loadDatas != null) {

   for(ListIterator&lt;DataObjectMetadata&gt; it = datas.listIterator(); it.hasNext();) {

    DataObjectMetadata dom = it.next();

    for (DataObjectMetadata load : loadDatas) {

     if(dom.getTableName().equals(load.getTableName()) &amp;&amp; dom.getColumnName().equals(load.getColumnName())){

      it.remove();

      it.add(load);

      load.setLevel(null);

      load.setMustInspectElement(dom.getMustInspectElement());

      load.setDataObjectMetadata(dom.getDataObjectMetadata());

      if(!StrUtil.validateString(load.getProgramName()) || !StrUtil.validateString(load.getProgramCode())){

       completaDadosCampos(load);       

      }

      break;

     }

    }

   }

  }

  loadDatas.clear();

 }



 private List&lt;DataObjectMetadata&gt; copiaListaRetorno(List&lt;DataObjectMetadata&gt; impedeRetorno) {



  List&lt;DataObjectMetadata&gt; copia = new ArrayList&lt;DataObjectMetadata&gt;();

  DataObjectMetadata c = null;



  for(DataObjectMetadata dom : impedeRetorno) {

   c = new DataObjectMetadata();



   c.setClassName(dom.getClassName());



   copia.add(c);



  }

  return copia;

 }



 private List&lt;DataObjectMetadata&gt; verificaSubObjetos(DataObjectMetadata data, List&lt;DataObjectMetadata&gt; impedeRetorno) {

  List&lt;DataObjectMetadata&gt; datas = null;



  if(SimNao.SIM.equals(data.getMustInspectElement())) {

   datas = criaEstruturaClasse(data.getColumnType(), impedeRetorno);

  }



  return datas;



 }



 private SimNao isClasseAntara(String columnType) {

  if(columnType.contains(".")) {

   String[] caminho = columnType.split(Pattern.quote("."));

   int tam = caminho.length;



   for(int j = 0; j &lt; tam; j++) {

    if("domain".equals(caminho[j])) {

     return SimNao.SIM;

    } else {

     if("util".equals(caminho[j])) {

      return SimNao.NAO;

     }

     if("java".equals(caminho[j])) {

      return SimNao.NAO;

     }

     if("hibernate".equals(caminho[j])) {

      return SimNao.NAO;

     }

    }

   }



   return SimNao.SIM;



  }



  return SimNao.NAO;

 }



 private SimNao deveInspecionarElemento(String columnType, List&lt;DataObjectMetadata&gt; impedeRetorno) {



  for(DataObjectMetadata tipoJaUsado : impedeRetorno) {

   if(columnType.equals(tipoJaUsado.getClassName())) {

    return SimNao.NAO;

   }

  }



  DataObjectMetadata aux = new DataObjectMetadata();

  aux.setClassName(columnType);

  impedeRetorno.add(aux);



  return SimNao.SIM;

 }



 private void percorreNivelCampos(List&lt;DataObjectMetadata&gt; datas) {



  Boolean encontrouUltimoNivel = false;



  for(DataObjectMetadata data : datas) {

   if(SimNao.SIM.equals(data.getMustInspectElement())) {

    percorreNivelCampos(data.getDataObjectMetadata());

    encontrouUltimoNivel = false;

   }

  }



  if(!encontrouUltimoNivel) {

   for(DataObjectMetadata dom : datas) {

    if(SimNao.NAO.equals(dom.getMustInspectElement())) {

     encontrouUltimoNivel = true;

    } else {

     encontrouUltimoNivel = false;

     break;

    }

   }

  }



  if(encontrouUltimoNivel) {

   for(DataObjectMetadata data : datas) {

    data.setLevel(new Integer(1));



    if(data.getDataObjectMetadata() == null) {

     List&lt;DataObjectMetadata&gt; dates = Collections.emptyList();

     data.setDataObjectMetadata(dates);

    }

   }

  }

 }



 private void defineNivel(List&lt;DataObjectMetadata&gt; datas) {



  Boolean recebeuLevel = false;

  Integer level = new Integer(0);

  

  for(DataObjectMetadata data : datas) {

   if(SimNao.SIM.equals(data.getIsClassAntara()) &amp;&amp; SimNao.SIM.equals(data.getMustInspectElement())) {

    if(data.getDataObjectMetadata().get(1).getLevel() != null) {

     if(data.getLevel() == null) {

      if(level &lt; (data.getDataObjectMetadata().get(1).getLevel() + new Integer(1))) {

       level = (data.getDataObjectMetadata().get(1).getLevel() + new Integer(1));

      }

      recebeuLevel = true;

     } else if(data.getLevel() &lt; (data.getDataObjectMetadata().get(1).getLevel() + new Integer(1))) {

      if(level &lt; (data.getDataObjectMetadata().get(1).getLevel() + new Integer(1))) {

       level = (data.getDataObjectMetadata().get(1).getLevel() + new Integer(1));

      }

      recebeuLevel = true;

     }

    } else {

     defineNivel(data.getDataObjectMetadata());

     if(data.getLevel() == null) {

      if(level &lt; (data.getDataObjectMetadata().get(1).getLevel() + new Integer(1))) {

       level = (data.getDataObjectMetadata().get(1).getLevel() + new Integer(1));

      }

      recebeuLevel = true;

     }

    }

   }

  }



  if(recebeuLevel) {

   for(DataObjectMetadata dom : datas) {

    if(dom.getLevel() == null) {

     dom.setLevel(level);



     if(dom.getDataObjectMetadata() == null) {

      List&lt;DataObjectMetadata&gt; dates = Collections.emptyList();

      dom.setDataObjectMetadata(dates);

     }

    }

   }

  }

 }



 public void save(List&lt;DataObjectMetadata&gt; datas, String usuario) {



  List&lt;DataObjectMetadata&gt; saves = new ArrayList&lt;DataObjectMetadata&gt;();



  desmembraObjetos(datas, saves);



  for(DataObjectMetadata save : saves) {

   save.setUsuarioStamp(usuario);



   domDAO.save(save);

  }



 }



 private void desmembraObjetos(List&lt;DataObjectMetadata&gt; datas, List&lt;DataObjectMetadata&gt; saves) {



  for(DataObjectMetadata dom : datas) {

   if(SimNao.SIM.equals(dom.getMustInspectElement())) {

    desmembraObjetos(dom.getDataObjectMetadata(), saves);

    adicionaObj(saves, dom);

   } else {

    adicionaObj(saves, dom);

   }

  }

 }



 private void adicionaObj(List&lt;DataObjectMetadata&gt; saves, DataObjectMetadata dom) {

  Boolean add = true;

  for(DataObjectMetadata save : saves) {

   if(save.getClassName().equals(dom.getClassName())) {

    if(save.getColumnName().equals(dom.getColumnName())) {

     add = false;

     break;

    }

   }

  }



  if(add) {

   saves.add(dom);

  }

 }



 public List&lt;DataObjectMetadata&gt; findToExport(DataObjectMetadata data) {

  return domDAO.findToExport(data);

 }



 public List&lt;DataObjectMetadata&gt; getEstruturaExportacaoXml(List&lt;DataObjectMetadata&gt; metadatasRequisitados) {

  List&lt;DataObjectMetadata&gt; retorno = new ArrayList&lt;DataObjectMetadata&gt;(metadatasRequisitados);

  List&lt;DataObjectMetadata&gt; metadatas = domDAO.findAll();

  metadatas.removeAll(retorno);



  adicionaSubNiveis(retorno, metadatas);

  return retorno;

 }



 private void adicionaSubNiveis(List&lt;DataObjectMetadata&gt; niveisSelecionados, List&lt;DataObjectMetadata&gt; todosMetadatas) {

  List&lt;DataObjectMetadata&gt; subniveis = new ArrayList&lt;DataObjectMetadata&gt;();

  List&lt;String&gt; classesEsperadasSubniveis = getSubniveisEsperadosParaListaDeDatas(niveisSelecionados);



  // adiciona os metadatas relacionados aos subníveis selecionados

  for(DataObjectMetadata metadata : todosMetadatas) {

   if(classesEsperadasSubniveis.contains(metadata.getClassName())) {

    subniveis.add(metadata);

   }

  }



  // remove os metadatas adicionados da lista geral

  todosMetadatas.removeAll(subniveis);



  if(!subniveis.isEmpty()) {

   adicionaSubNiveis(subniveis, todosMetadatas);

  }



  niveisSelecionados.addAll(subniveis);

 }



 private List&lt;String&gt; getSubniveisEsperadosParaListaDeDatas(List&lt;DataObjectMetadata&gt; metadatasParaAnalisar) {

  List&lt;String&gt; classesEsperadasSubniveis = new ArrayList&lt;String&gt;(metadatasParaAnalisar.size());



  for(DataObjectMetadata metadata : metadatasParaAnalisar) {

   if(isClasseAntara(metadata.getColumnType()) == SimNao.SIM) {

    classesEsperadasSubniveis.add(metadata.getColumnType());

   }

  }



  return classesEsperadasSubniveis;

 }

 

 

 private List&lt;DataObjectMetadata&gt; montaDadosProgs(AbstractEntityPersister persister, List&lt;DataObjectMetadata&gt; impedeRetorno) {

  

  List&lt;DataObjectMetadata&gt; ir = copiaListaRetorno(impedeRetorno);

  

  List&lt;DataObjectMetadata&gt; datas = new ArrayList&lt;DataObjectMetadata&gt;();

  DataObjectMetadata data = null;

  

  if(persister != null) {

   String[] &nbsp;columnNames &nbsp; &nbsp;= persister.getPropertyNames();

   Type[] &nbsp; &nbsp;columnTypes &nbsp; &nbsp;= persister.getPropertyTypes();

   

   if((columnNames != null) &amp;&amp; (columnTypes != null)) {

    List&lt;String&gt; colunas = new ArrayList&lt;String&gt;(Arrays.asList(columnNames));

    List&lt;Type&gt; tipos = new ArrayList&lt;Type&gt;(Arrays.asList(columnTypes));

    

    if((colunas != null) &amp;&amp; (tipos != null)) {

     for(int i = 0; i &lt; colunas.size(); i++) {

      data = new DataObjectMetadata();

      

      if(SimNao.SIM.equals(isClasseAntara(tipos.get(i).getName()))){

       data.setDataStamp(new Date());

       

       data.setTableName(persister.getTableName());

       data.setClassName(persister.getName());

       data.setColumnName(colunas.get(i));

       data.setColumnType(tipos.get(i).getName());

       data.setIsClassAntara(isClasseAntara(data.getColumnType()));

       data.setMustInspectElement(deveInspecionarElemento(data.getColumnType(), ir));

       

       data.setDataObjectMetadata(verificaSubObjetos(data, ir));

       

       completaDadosProg(data);

       

       datas.add(data);

       

      }

     }

    }

   }

  }

  

  return datas;

 }





 private void completaDadosCampos(DataObjectMetadata data) {

  Integer indexInicio = data.getClassName().lastIndexOf(".");

  Integer indexFinal &nbsp;= data.getClassName().length();

  

  String nmBean = data.getClassName().substring((indexInicio+1), (indexFinal));

    

  for (Programa prog : progs) {

      

   indexInicio = prog.getNmPrograma().lastIndexOf(".");

   indexFinal &nbsp;= prog.getNmPrograma().length();

   

   String nmPrograma = prog.getNmPrograma().substring((indexInicio+1), (indexFinal));

   if(!nmPrograma.contains("Rep")){

    if("Frm".equals(prog.getNmPrograma().substring((indexFinal-3), indexFinal))){

     nmPrograma = prog.getNmPrograma().substring((indexInicio+1), (indexFinal-3));    

    }

    

    if(nmPrograma.equals(nmBean)){

     data.setProgramName(prog.getProgramaIdioma(new Locale("pt", "BR")).getNmTituloPrograma());

     data.setProgramCode(prog.getCdPrograma());

     break;

    } 

   }

  }

 }

 

 private void completaDadosProg(DataObjectMetadata data) {

  Integer indexInicio = data.getColumnType().lastIndexOf(".");

  Integer indexFinal &nbsp;= data.getColumnType().length();

  

  String nmBean = data.getColumnType().substring((indexInicio+1), (indexFinal));

    

  for (Programa prog : progs) {

   

   indexInicio = prog.getNmPrograma().lastIndexOf(".");

   indexFinal &nbsp;= prog.getNmPrograma().length();

   

   String nmPrograma = prog.getNmPrograma().substring((indexInicio+1), (indexFinal));    

   if("Frm".equals(prog.getNmPrograma().substring((indexFinal-3), indexFinal))){

    nmPrograma = prog.getNmPrograma().substring((indexInicio+1), (indexFinal-3));    

   }

   

   if(nmPrograma.equals(nmBean)){

    if(carregaCampos){

     data.setProgramName(prog.getProgramasIdiomas().get(0).getNmTituloPrograma());

    } else {

     data.setClassName(prog.getProgramaIdioma(new Locale("pt", "BR")).getNmTituloPrograma());     

    }

    data.setProgramCode(prog.getCdPrograma());

    break;

   } 

  }  

 }

}





-------------------------------------------------




public String buscaClassNameCompleto(String className) {

  SessionFactory sf = getSessionFactory();

  Map&lt;String, ClassMetadata&gt; classes = sf.getAllClassMetadata();



  for(Map.Entry&lt;String, ClassMetadata&gt; entry : classes.entrySet()) {

   ClassMetadata classMetadata = (ClassMetadata) entry.getValue();

   String clazz = classMetadata.getMappedClass(EntityMode.POJO).getName();

   int indexInicio = clazz.indexOf("domain.");

   indexInicio += "domain.".length();

   String objetoRetornado = clazz.substring(indexInicio, clazz.length());

   

   if(objetoRetornado.equals(className)) {

    return clazz;

   }

  }

  

  return null;

 }