/**
   * Obtém uma categoria/atributo de talento a partir da chave
   *
   * @param strChave Chave do registro a ser obtido
   * @return CategoriaAtributoTalento POJO representando o registro obtido
   * @throws CDException se ocorrer algum erro relacionado ao negócio
   */
  public CategoriaAtributoTalento obterCategoriaAtributoTalentoPelaChave(String strChave)
      throws CDException {
    if (log.isDebugEnabled()) {
      log.debug("Entrada no metodo");
    }

    // Instancia DAO e obtém o registro pela chave
    CategoriaAtributoTalentoDAO objCategoriaAtributoTalentoDAO = new CategoriaAtributoTalentoDAO();
    CategoriaAtributoTalento objCategoriaAtributoTalento = null;
    try {
      objCategoriaAtributoTalento =
          (CategoriaAtributoTalento) objCategoriaAtributoTalentoDAO.obterPelaChave(strChave);
    } catch (Exception daoe) {
      CDException.dispararExcecao(daoe);
    } finally {
      DAO.desconectar();
    }
    return objCategoriaAtributoTalento;
  }
  /**
   * Obtém categoria/atributo de acordo com a categoria e o atributo passados
   *
   * @param objCategoriaTalento Categoria de talento a ser consultada
   * @param objAtributoTalento Atributo de talento a ser consultado
   * @return CategoriaAtributoTalento Contendo a categoria/atributo
   * @throws DAOException se ocorrer algum erro relacionado com o acesso a banco de dados
   */
  public CategoriaAtributoTalento obterCategoriaAtributoTalentoPorCategoriaTalentoAtributoTalento(
      CategoriaTalento objCategoriaTalento, AtributoTalento objAtributoTalento) throws CDException {
    if (log.isDebugEnabled()) {
      log.debug("Entrada no metodo");
    }

    // Instancia DAO e obtém todos os registros
    CategoriaAtributoTalentoDAO objCategoriaAtributoTalentoDAO = new CategoriaAtributoTalentoDAO();
    CategoriaAtributoTalento objCategoriaAtributoTalento = null;
    try {
      objCategoriaAtributoTalento =
          objCategoriaAtributoTalentoDAO.obterPorCategoriaTalentoAtributoTalento(
              objCategoriaTalento, objAtributoTalento);
    } catch (Exception daoe) {
      CDException.dispararExcecao(daoe);
    } finally {
      DAO.desconectar();
    }
    return objCategoriaAtributoTalento;
  }
  /**
   * Verifica se determinado atributo de talento têm filhos na relação categoria/atributo
   *
   * @param objCategoriaAtributoTalento Categoria/atributo de talento desejado
   * @return boolean Com a verificação
   * @throws CDException se ocorrer algum erro relacionado ao negócio
   */
  public boolean verificarExistenciaCategoriaAtributosFilhos(
      CategoriaAtributoTalento objCategoriaAtributoTalento) throws CDException {
    if (log.isDebugEnabled()) {
      log.debug("Entrada no metodo");
    }

    // Instancia DAO e obtém o registro pela chave
    CategoriaAtributoTalentoDAO objCategoriaAtributoTalentoDAO = new CategoriaAtributoTalentoDAO();
    boolean blnExistenciaFilhos = false;
    try {
      blnExistenciaFilhos =
          objCategoriaAtributoTalentoDAO.verificarExistenciaCategoriaAtributosTalentoFilhos(
              objCategoriaAtributoTalento);
    } catch (Exception daoe) {
      CDException.dispararExcecao(daoe);
    } finally {
      DAO.desconectar();
    }
    return blnExistenciaFilhos;
  }
  /**
   * Obtém os relacionamentos categoria/atributo que são filhos da categoria/atributo informado
   *
   * @param objCategoriaAtributoTalento Categoria/atributo de talento desejado
   * @return List Contendo os registros
   * @throws CDException se ocorrer algum erro relacionado ao negócio
   */
  public List obterCategoriaAtributosTalentoFilhos(
      CategoriaAtributoTalento objCategoriaAtributoTalento) throws CDException {
    if (log.isDebugEnabled()) {
      log.debug("Entrada no metodo");
    }

    // Instancia DAO e obtém o registro pela chave
    CategoriaAtributoTalentoDAO objCategoriaAtributoTalentoDAO = new CategoriaAtributoTalentoDAO();
    List lstCategoriaAtributosTalentoFilhos = null;
    try {
      lstCategoriaAtributosTalentoFilhos =
          objCategoriaAtributoTalentoDAO.obterTodosOsFilhos(objCategoriaAtributoTalento);
      objCategoriaAtributoTalentoDAO.inicializarAtributoTalento(lstCategoriaAtributosTalentoFilhos);
    } catch (Exception daoe) {
      CDException.dispararExcecao(daoe);
    } finally {
      DAO.desconectar();
    }
    return lstCategoriaAtributosTalentoFilhos;
  }
  private void incluirValoracoes(Talento objTalento, List lstAtributosTalentoValorados)
      throws CDException {
    // Declarações
    CategoriaAtributoTalentoDAO objCategoriaAtributoTalentoDAO = new CategoriaAtributoTalentoDAO();
    AtributoTalentoOpcaoDAO objAtributoTalentoOpcaoDAO = new AtributoTalentoOpcaoDAO();
    AtributoTalentoValoradoDAO objAtributoTalentoValoradoDAO = new AtributoTalentoValoradoDAO();

    try {

      // Inclui valorações
      Iterator itrAtributosTalentoValorados = lstAtributosTalentoValorados.iterator();
      while (itrAtributosTalentoValorados.hasNext()) {
        // Obtém valoração
        AtributoTalentoValorado objAtributoTalentoValorado =
            (AtributoTalentoValorado) itrAtributosTalentoValorados.next();

        // INICIO - Lucene no Banco de Talentos
        if (objAtributoTalentoValorado.getValoracao() == null
            || "".equals(objAtributoTalentoValorado.getValoracao())) {
          continue;
        }
        // FIM - Lucene no Banco de Talentos

        // Seta talento
        objAtributoTalentoValorado.setTalento(objTalento);

        // Obtém categoria/atributo relacionado
        CategoriaAtributoTalento objCategoriaAtributoTalento =
            (CategoriaAtributoTalento)
                objCategoriaAtributoTalentoDAO.obterPelaChave(
                    String.valueOf(
                        objAtributoTalentoValorado
                            .getCategoriaAtributoTalento()
                            .getIdentificador()));

        // INICIO - Lucene no Banco de Talentos
        objAtributoTalentoValorado.setCategoriaAtributoTalento(objCategoriaAtributoTalento);
        // Obtem o AtributoTalento correspondente a CategoriaAtributoTalento porque sera necessario
        // usar no Lucene depois
        // objCategoriaAtributoTalentoDAO.inicializarAtributoTalento(objAtributoTalentoValorado.getCategoriaAtributoTalento());
        // O codigo acima tambem nao funcionou, mas neste caso pode ser porque nem mesmo o id de
        // AtributoTalento estava na classe CategoriaAtributoTalento
        // Para resolver alterei o mapeamento e tornei o atributo AtributoTalento não lazy na classe
        // CategoriaAtributoTalento
        // FIM - Lucene no Banco de Talentos

        // Verifica o nome do atributo de talento
        String strNomeCampo;
        if (objCategoriaAtributoTalento.getApelido() == null
            || "".equals(objCategoriaAtributoTalento.getApelido())) {
          strNomeCampo = objCategoriaAtributoTalento.getAtributoTalento().getNome();
        } else {
          // TODO Analisar se deve prevalecer o código do Christian que está abaixo
          // strNomeCampo = objAtributoTalentoValorado.getCategoriaAtributoTalento().getApelido();

          strNomeCampo = objCategoriaAtributoTalento.getApelido();
        }

        // Trata atributo virtual
        if (GerenciadorAtributoVirtual.isAtributoVirtual(
            objCategoriaAtributoTalento.getAtributoTalento().getNome())) {
          // se for um atributo virtual já tem que ir direto para inclusão
        }
        // Verifica se a categoria/atributo recebido tem opções, e se tiver, cria o objeto
        // AtributoTalentoOpcao
        // e o relaciona, se não tiver, valida o tipo de dado
        else if ("U"
                .equals(
                    objCategoriaAtributoTalento
                        .getAtributoTalento()
                        .getTipoHTML()
                        .getMultiplicidade())
            || "M"
                .equals(
                    objCategoriaAtributoTalento
                        .getAtributoTalento()
                        .getTipoHTML()
                        .getMultiplicidade())) {
          if (objAtributoTalentoValorado.getValoracao() != null
              && !"".equals(objAtributoTalentoValorado.getValoracao())) {
            AtributoTalentoOpcao objAtributoTalentoOpcao = new AtributoTalentoOpcao();
            objAtributoTalentoOpcao.setIdentificador(
                Integer.valueOf(objAtributoTalentoValorado.getValoracao()));
            objAtributoTalentoOpcao =
                (AtributoTalentoOpcao)
                    objAtributoTalentoOpcaoDAO.obterPelaChave(
                        String.valueOf(objAtributoTalentoOpcao.getIdentificador()));
            objAtributoTalentoValorado.setAtributoTalentoOpcao(objAtributoTalentoOpcao);
            objAtributoTalentoValorado.setValoracao(objAtributoTalentoOpcao.getDescricao());
          }
        } else {
          // Valida o tipo de dado
          if ("T".equals(objCategoriaAtributoTalento.getAtributoTalento().getTipoDado())) {
            if (objCategoriaAtributoTalento.getAtributoTalento().getMascara() != null
                && !"".equals(objCategoriaAtributoTalento.getAtributoTalento().getMascara())
                && objAtributoTalentoValorado.getValoracao() != null
                && !"".equals(objAtributoTalentoValorado.getValoracao())) {
              if (!ExpressaoRegular.validar(
                  objCategoriaAtributoTalento.getAtributoTalento().getMascara(),
                  objAtributoTalentoValorado.getValoracao())) {
                throw new CDException("O atributo " + strNomeCampo + " deve ser numérico");
              }
            }
          }
          if ("N".equals(objCategoriaAtributoTalento.getAtributoTalento().getTipoDado())) {
            if (objAtributoTalentoValorado.getValoracao() != null
                && !"".equals(objAtributoTalentoValorado.getValoracao())
                && !Numero.validarNumero(objAtributoTalentoValorado.getValoracao())) {
              throw new CDException("O atributo " + strNomeCampo + " deve ser numérico");
            }
          }
          if ("D".equals(objCategoriaAtributoTalento.getAtributoTalento().getTipoDado())) {
            if (objAtributoTalentoValorado.getValoracao() != null
                && !"".equals(objAtributoTalentoValorado.getValoracao())
                && (objAtributoTalentoValorado.getValoracao().trim().length() != 10
                    || !DataNova.validarData(objAtributoTalentoValorado.getValoracao()))) {
              throw new CDException("O atributo " + strNomeCampo + " deve ser uma data válida");
            }
          }
        }

        // Inclui valoração
        objAtributoTalentoValoradoDAO.incluir(objAtributoTalentoValorado);

        // INICIO - Lucene no Banco de Talentos
        // Trata insercao no Lucene
        // Se der algum problema, a transacao no banco vai continuar e um log com o
        // erro no Lucene será gerado
        IndexaTalento idx = null;
        try {
          // Tenta excluir campos do tipo "D"ata e "N"umero
          // Nem sempre o tipo de dado esta preenchido
          if (objAtributoTalentoValorado
                      .getCategoriaAtributoTalento()
                      .getAtributoTalento()
                      .getTipoDado()
                  == null
              || "T"
                  .equals(
                      objAtributoTalentoValorado
                          .getCategoriaAtributoTalento()
                          .getAtributoTalento()
                          .getTipoDado())) {
            // Incluir no Lucene
            idx = IndexaTalento.getInstance();
            idx.addTalento(
                objTalento.getPessoa().getIdentificador().toString(),
                objAtributoTalentoValorado.getValoracao());
          }
        } catch (IOException e) {
          if (log.isErrorEnabled()) {
            log.error(e);
          }
        } finally {
          if (idx != null) {
            try {
              idx.close();
            } catch (Exception e) {
            }
          }
        }
        // FIM - Lucene no Banco de Talentos

      }
    } catch (Exception daoe) {
      DAO.desfazerTransacao();
      CDException.dispararExcecao(daoe);
    } finally {
      DAO.desconectar();
    }
  }
  private void verificarValoracoesObrigatorias(
      CategoriaTalento objCategoriaTalento, List lstAtributosTalentoValorados) throws CDException {
    try {
      // Declarações
      CategoriaAtributoTalentoDAO objCategoriaAtributoTalentoDAO =
          new CategoriaAtributoTalentoDAO();

      // Obtém categoria/atributos da categoria
      List lstCategoriaAtributosTalento =
          objCategoriaAtributoTalentoDAO.obterPorCategoriaTalento(objCategoriaTalento);

      // Verifica os atributos de talento obrigatórios
      Iterator itrCategoriaAtributosTalento = lstCategoriaAtributosTalento.iterator();
      while (itrCategoriaAtributosTalento.hasNext()) {
        // Obtém categoria/atributo atual e marca a presença como falsa
        CategoriaAtributoTalento objCategoriaAtributoTalento =
            (CategoriaAtributoTalento) itrCategoriaAtributosTalento.next();
        boolean blnPresente = false;
        boolean blnPreenchido = false;

        // Verifica o nome do atributo de talento
        String strNomeCampo;
        if (objCategoriaAtributoTalento.getApelido() == null
            || "".equals(objCategoriaAtributoTalento.getApelido())) {
          strNomeCampo = objCategoriaAtributoTalento.getAtributoTalento().getNome();
        } else {
          strNomeCampo = objCategoriaAtributoTalento.getApelido();
        }

        // Verifica se o atributo está presente e foi preenchido
        Iterator itrAtributosTalentoValorados = lstAtributosTalentoValorados.iterator();
        while (itrAtributosTalentoValorados.hasNext()) {
          AtributoTalentoValorado objAtributoTalentoValorado =
              (AtributoTalentoValorado) itrAtributosTalentoValorados.next();
          if (objCategoriaAtributoTalento
              .getIdentificador()
              .equals(
                  objAtributoTalentoValorado.getCategoriaAtributoTalento().getIdentificador())) {
            blnPresente = true;
            if (objAtributoTalentoValorado.getValoracao() != null
                && !"".equals(objAtributoTalentoValorado.getValoracao())) {
              blnPreenchido = true;
              break;
            }
          }
        }

        // Verifica se o atributo não está presente e é obrigatório
        if (!blnPreenchido
            && "S".equals(objCategoriaAtributoTalento.getIndicativoObrigatoriedade())) {
          // Se for obrigatório, dispara um erro
          throw new CDException("O atributo " + strNomeCampo + " é obrigatório");
        } else if (!blnPresente) {
          // Se não for obrigatório, cria valoração vazia e insere na lista
          AtributoTalentoValorado objAtributoTalentoValorado = new AtributoTalentoValorado();
          objAtributoTalentoValorado.setCategoriaAtributoTalento(objCategoriaAtributoTalento);
          objAtributoTalentoValorado.setValoracao("");
          lstAtributosTalentoValorados.add(objAtributoTalentoValorado);
        }
      }

    } catch (Exception daoe) {
      CDException.dispararExcecao(daoe);
    } finally {
      DAO.desconectar();
    }
  }