/*
 * Universidade Federal de Pernambuco
 * Centro de Informática
 *
 * SAC - Sociedade beneficente de Amparo aos portadores de AIDS e do Cancer
 *
 * Tipo: DBMedicamento
 *
 * Esta classe implementa o repositorio de medicamentos num banco persistente
 *
 * @author Centro de Informatica - UFPE
 * @version  0.1 -  25/10/2001
 * @since JDK 1.3
 */

package sac.medicamento;

import sac.persistencia.OID;
import sac.persistencia.PersistenceException;
import java.util.List;
import sac.droga.Droga;
import sac.cid.CID;
import sac.doenca.Doenca;
import sac.doenca.RepositorioDoenca;
import sac.doenca.DBDoenca;
import sac.doenca.DoencaNaoCadastradaException;
import sac.exception.NullArgumentException;

import java.util.List;
import java.util.LinkedList;
import java.lang.StringBuffer;

import java.sql.PreparedStatement;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;

import sac.persistencia.OIDFactory;
import sac.persistencia.CacheObjetos;
import sac.persistencia.OID;
import sac.persistencia.PoolConexoes;

public class DBMedicamento implements RepositorioMedicamento
{

    private final static String inserirMedicamentoSQL = "insert into Medicamento (CD_MEDICAMENTO, " +
                                "NM_MEDICAMENTO, DS_CONTRA_INDICACAO, DS_INDICACAO, " +
                                "CD_DROGA_PRINCIPAL, VL_PRECO_VAREJO, VL_PRECO_ATACADO_INFERIOR, " +
                                "VL_PRECO_ATACADO_SUPERIOR) VALUES (?, ?, ?, ?, ?, ?, ?, ?)";
    private final static String inserirDrogaSQL = "insert into Droga (CD_DROGA, NM_DROGA, DS_ACOES_TERAPEUTICAS, " +
                                          "DS_PROPRIEDADES, DS_DOSAGEM, DS_INDICACOES, DS_CONTRA_INDICACOES, " +
                                          "DS_REACOES_ADVERSAS, DS_PRECAUCOES, DS_INTERACOES) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
    private final static String inserirMedicamentoDrogaSecSQL = "insert into Medicamento_DrogaSecundaria " +
                         "(CD_DROGA, CD_MEDICAMENTO) VALUES (?,?)";
    private final static String excluirMedicamentoDrogasSecSQL = "delete from Medicamento_DrogaSecundaria " +
                         "where CD_MEDICAMENTO = ?";
    private final static String inserirMedicamentoLaboratorioSQL = "insert into Medicamento_Laboratorio " +
                         "(CD_LABORATORIO, CD_MEDICAMENTO) VALUES (?,?)";
    private final static String excluirMedicamentoLaboratorioSQL = "delete from Medicamento_Laboratorio " +
                         "where CD_MEDICAMENTO = ?";
    private final static String inserirMedicamentoDoencaSQL = "insert into Medicamento_Doenca " +
                         "(CD_DOENCA, CD_MEDICAMENTO) VALUES (?,?)";
    private final static String excluirMedicamentoDoencaSQL = "delete from Medicamento_Doenca " +
                         "where CD_MEDICAMENTO = ?";
    private final static String inserirLaboratorioSQL = "insert into Laboratorio " +
                         "(CD_LABORATORIO, NM_LABORATORIO) VALUES (?,?)";
    private final static String inserirMedicamentoApresentacaoSQL = "insert into Medicamento_Apresentacao " +
                         "(CD_APRESENTACAO, CD_MEDICAMENTO) VALUES (?,?)";
    private final static String excluirMedicamentoApresentacaoSQL = "delete from Medicamento_Apresentacao " +
                         "where CD_MEDICAMENTO = ?";
    private final static String inserirApresentacaoSQL = "insert into Apresentacao " +
                         "(CD_APRESENTACAO, NM_APRESENTACAO) VALUES (?,?)";
    private final static String getOIDSQL = "select CD_MEDICAMENTO from Medicamento " +
                                     "where NM_MEDICAMENTO like ?";
    private final static String procurarMedicamentoSQL =
                         "select CD_MEDICAMENTO, NM_MEDICAMENTO, DS_CONTRA_INDICACAO, " +
                         "DS_INDICACAO, CD_DROGA_PRINCIPAL, VL_PRECO_VAREJO, " +
                         "VL_PRECO_ATACADO_INFERIOR, VL_PRECO_ATACADO_SUPERIOR " +
                         "from Medicamento where CD_MEDICAMENTO = ?";
    private final static String procurarMedicamentoPelaDrogaSQL =
                         "select CD_MEDICAMENTO, NM_MEDICAMENTO, DS_CONTRA_INDICACAO, " +
                         "DS_INDICACAO, CD_DROGA_PRINCIPAL, VL_PRECO_VAREJO, " +
                         "VL_PRECO_ATACADO_INFERIOR, VL_PRECO_ATACADO_SUPERIOR " +
                         "from Medicamento where CD_DROGA_PRINCIPAL = ?";
    private final static String getLaboratorioMedicamentoSQL = "select CD_LABORATORIO from " +
                         "Medicamento_Laboratorio where CD_MEDICAMENTO = ?";
    private final static String getMedicamentoLaboratorioSQL = "select CD_MEDICAMENTO from " +
                         "Medicamento_Laboratorio where CD_LABORATORIO = ?";
    private final static String getOIDLaboratorioSQL = "select CD_LABORATORIO from " +
                         "Laboratorio where NM_LABORATORIO like ?";
    private final static String getNomeLaboratorioSQL = "select NM_LABORATORIO from " +
                         "Laboratorio where CD_LABORATORIO = ?";
    private final static String getApresentacaoMedicamentoSQL = "select CD_APRESENTACAO from " +
                         "Medicamento_Apresentacao where CD_MEDICAMENTO = ?";
    private final static String getOIDApresentacaoSQL = "select CD_APRESENTACAO from " +
                         "Apresentacao where NM_APRESENTACAO = ?";
    private final static String getNomeApresentacaoSQL = "select NM_APRESENTACAO from " +
                         "Apresentacao where CD_APRESENTACAO = ?";
    private final static String getDrogaPrincipalMedicamentoSQL = "select CD_DROGA_PRINCIPAL from Medicamento "+
                         "where CD_MEDICAMENTO = ?";
    private final static String getDrogaOIDSQL = "select CD_DROGA, NM_DROGA, DS_ACOES_TERAPEUTICAS, " +
                         "DS_PROPRIEDADES, DS_DOSAGEM, DS_INDICACOES, DS_CONTRA_INDICACOES, " +
                         "DS_REACOES_ADVERSAS, DS_PRECAUCOES, DS_INTERACOES from Droga where CD_DROGA = ?";
    private final static String getDoencaMedicamentoSQL = "select CD_DOENCA from " +
                         "Medicamento_Doenca where CD_MEDICAMENTO = ?";
    private final static String getMedicamentoDoencaSQL = "select CD_MEDICAMENTO from " +
                         "Medicamento_Doenca where CD_DOENCA = ?";
    private final static String getDoencaOIDSQL = "select CD_DOENCA, NM_DOENCA, CD_CID, DS_HISTORICO, " +
                                        "DS_SINTOMAS, DS_HEREDITARIEDADE, NM_CID from doenca where CD_DOENCA = ?";
    private final static String getDoencaNomeSQL = "select CD_DOENCA, NM_DOENCA, CD_CID, DS_HISTORICO, " +
                                        "DS_SINTOMAS, DS_HEREDITARIEDADE, NM_CID from doenca where NM_DOENCA = ?";
    private final static String getDrogaSecMedicamentoSQL = "select CD_DROGA from " +
                         "Medicamento_DrogaSecundaria where CD_MEDICAMENTO = ?";
    private final static String getMedicamentoDrogaSecSQL = "select CD_MEDICAMENTO from " +
                         "Medicamento_DrogaSecundaria where CD_DROGA = ?";
    private final static String alteraMedicamentoSQL = "update Medicamento set CD_MEDICAMENTO = ?, " +
                         "NM_MEDICAMENTO = ?, DS_CONTRA_INDICACAO = ?, DS_INDICACAO = ?, " +
                         "CD_DROGA_PRINCIPAL = ?, VL_PRECO_VAREJO = ?, VL_PRECO_ATACADO_INFERIOR = ?, " +
                         "VL_PRECO_ATACADO_SUPERIOR = ? where CD_MEDICAMENTO = ?";
    private final static String getTodosLaboratoriosSQL = "select * from Laboratorio";
    private PoolConexoes connectionPoll;
    private CacheObjetos cache;
    private OIDFactory oidfactory;
    private static DBMedicamento instancia;
    // Bancos
    private RepositorioDoenca repositorioDoenca;

    /**
     * Construtor da Classe
     */
    public DBMedicamento() throws PersistenceException{
        connectionPoll = PoolConexoes.getInstancia();
        cache = CacheObjetos.getInstancia();
        oidfactory = OIDFactory.getInstancia();
        repositorioDoenca = DBDoenca.getInstancia();

    }

    public static synchronized DBMedicamento getInstancia() throws PersistenceException {
        if (instancia == null) {
            instancia = new DBMedicamento();
        }
        return instancia;
    }

    /**
     * Busca o ID dos medicamentos por seu nome
     *
     * @param nome <code>String</code> Nome do medicamento
     * @param conexao <code>Connection</code> Conexao do banco
     *
     * @return ID do medicamento que possui o nome requerido
     *
     * @exception MedicamentoNaoCadastradoException Para medicamentos nao cadastrados
     */
    private List getOIDsMedicamento(String nome, Connection conexao)
    throws MedicamentoNaoCadastradoException, PersistenceException, SQLException {
    PreparedStatement statement = null;
    OID oid;
    List oids = new LinkedList();
        try {
            statement =  conexao.prepareStatement(getOIDSQL);
            statement.setString(1, "%"+nome+"%");
            ResultSet resultSet = statement.executeQuery();

            while(resultSet.next()) {
               oid = new OID(resultSet.getLong("CD_MEDICAMENTO"));
               oids.add (oid);
            }
            return oids;
        } catch (SQLException excecao) {
            throw new PersistenceException();
        } finally {
            if (conexao != null) {
                if (statement != null) {
                    statement.close();
                }
            }
        }
    }

    /**
     * Busca um medicamento por sua ID
     *
     * @param id <code>OID</code> Identificador do medicamento
     *
     * @return Medicamento que possui o ID requerido
     *
     * @exception MedicamentoNaoCadastradoException Para medicamentos nao cadastrados
     */
    public Medicamento procurarMedicamento(OID id) throws MedicamentoNaoCadastradoException,
    PersistenceException, SQLException, NullArgumentException, DoencaNaoCadastradaException {
        Medicamento medicamento = null;
        Connection conexao = null;
        Object obj = null;

        try {
            conexao =  connectionPoll.obterConexao();
            obj = cache.pegarObjeto(id);
            if (obj == null) {
                medicamento = procurarMedicamento(id, conexao);
                cache.inserirObjeto(id, medicamento);
            } else if(obj instanceof Medicamento) {
              medicamento = (Medicamento) obj;
            } else {
              throw new PersistenceException("Objeto da cache nao eh uma instacia " +
                                             "de Medicamento");
            }
            return medicamento;
        } catch (SQLException excecao) {
            throw new PersistenceException(excecao.getMessage());
        } finally {
            if(conexao != null) {
              connectionPoll.liberarConexao(conexao);
            }
        }

    }

    private Medicamento procurarMedicamento(OID id, Connection conexao) throws PersistenceException,
    SQLException, MedicamentoNaoCadastradoException, NullArgumentException, DoencaNaoCadastradaException {
        Medicamento medicamento = null;
        PreparedStatement statement = null;
        try {
            statement = conexao.prepareStatement(procurarMedicamentoSQL);
            statement.setLong(1, id.getLongValue());
            ResultSet resultSet = statement.executeQuery();
            if(resultSet.next()) {
                medicamento = getMedicamento(resultSet, conexao);
            } else {
                throw new MedicamentoNaoCadastradoException ("O oid buscado não"+
                        "foi encontrado no sistema, oid = " + id+"." );
            }
        } catch (SQLException excecao) {
            throw new PersistenceException();
        } finally {
            if (conexao != null) {
                if (statement != null) {
                    statement.close();
                }
            }
        }
        return medicamento;
    }

    /**
     * Busca os laboratorio do medicamento por sua ID (do medicamento)
     *
     * @param id <code>OID</code> Identificador do medicamento
     *
     * @return Lista de laboratorios do medicamento requerido
     *
     */
    private List procurarLaboratorio(OID idMed, Connection conexao)
    throws PersistenceException, MedicamentoNaoCadastradoException, SQLException,
    NullArgumentException {
        List laboratorios = new LinkedList();
        Laboratorio laboratorio = null;
        long idLab = 0;
        Object obj = null;
        String nomeLaboratorio = "";
        PreparedStatement statement = null, statement2 = null;
        OID oidLab;

        try {
            statement =  conexao.prepareStatement(getLaboratorioMedicamentoSQL);
            statement.setLong(1, idMed.getLongValue());
            ResultSet resultSet = statement.executeQuery();

            while (resultSet.next()) {
                idLab = resultSet.getLong("CD_LABORATORIO");
                oidLab = new OID (idLab);
                obj = cache.pegarObjeto(oidLab);
                if (obj == null) {
                    statement2 =  conexao.prepareStatement(getNomeLaboratorioSQL);
                    long aux = resultSet.getLong("CD_LABORATORIO");
                    statement2.setLong(1, aux);
                    ResultSet resultSetLab = statement2.executeQuery();
                    if (resultSetLab.next()) {
                        nomeLaboratorio = resultSetLab.getString("NM_LABORATORIO");
                        laboratorio = new Laboratorio (oidLab, nomeLaboratorio);
                        cache.inserirObjeto(oidLab, laboratorio);
                    }
                } else if (obj instanceof Laboratorio) {
                    laboratorio = (Laboratorio) obj;
                }  else {
                    throw new PersistenceException("Objeto da cache nao eh uma instacia " +
                                                   "de Laboratorio");
                }
                if (laboratorio != null) {
                    laboratorios.add(laboratorio);
                }
            }
            return laboratorios;
        } catch (SQLException excecao) {
            excecao.printStackTrace();
            throw new PersistenceException();
        } finally {
            if (conexao != null) {
                if (statement != null) {
                    statement.close();
                }
                if (statement2 != null) {
                    statement2.close();
                }
            }
        }
    }

    /**
     * Busca as apresentacoes do medicamento por sua ID
     *
     * @param id <code>OID</code> Identificador do medicamento
     * @param conexao <code>Connection</code> Conexao do banco
     *
     * @return Lista de apresentacoes do medicamento requerido
     *
     * @exception MedicamentoNaoCadastradoException Para medicamentos nao cadastrados
     */
    private List procurarApresentacao(OID idMed, Connection conexao)
    throws MedicamentoNaoCadastradoException, PersistenceException, SQLException,
    NullArgumentException {
        List apresentacao = new LinkedList();
        PreparedStatement statement2 = null, statement = null;
        OID oidApres;
        Apresentacao apres = null;
        long idApres;
        Object obj;
        String nomeApres = "";

        try {
            statement =  conexao.prepareStatement(getApresentacaoMedicamentoSQL);
            statement.setLong(1, idMed.getLongValue());
            ResultSet resultSet = statement.executeQuery();
            while (resultSet.next()) {
                idApres = resultSet.getLong("CD_APRESENTACAO");
                oidApres = new OID (idApres);
                obj = cache.pegarObjeto(oidApres);
                if (obj == null) {
                    statement2 =  conexao.prepareStatement(getNomeApresentacaoSQL);
                    statement2.setLong(1, resultSet.getLong("CD_APRESENTACAO"));
                    ResultSet resultSetApres = statement2.executeQuery();
                    if (resultSetApres.next()) {
                        nomeApres = resultSetApres.getString("NM_APRESENTACAO");
                        apres = new Apresentacao (oidApres, nomeApres);
                        cache.inserirObjeto(oidApres, apres);
                    }
                } else if (obj instanceof Apresentacao) {
                    apres = (Apresentacao) obj;
                } else {
                    throw new PersistenceException("Objeto da cache nao eh uma instacia " +
                                                   "de string");
                }
                if (apres != null) {
                    apresentacao.add(apres);
                }
            }
            return apresentacao;
        } catch (SQLException excecao) {
            throw new PersistenceException();
        } finally {
            if (conexao != null) {
                if (statement != null) {
                    statement.close();
                }
                if (statement2 != null) {
                    statement2.close();
                }
            }
        }
    }

    private Medicamento getMedicamento(ResultSet resultSet, Connection conexao)
    throws PersistenceException, MedicamentoNaoCadastradoException, NullArgumentException,
    DoencaNaoCadastradaException{
        Medicamento medicamento;

        try {
            OID oid = new OID(resultSet.getLong("CD_MEDICAMENTO"));
            String nome = resultSet.getString("NM_MEDICAMENTO");
            List laboratorios = procurarLaboratorio(oid, conexao);
            medicamento = new Medicamento(oid, nome, laboratorios);
            medicamento.setApresentacao(procurarApresentacao(oid, conexao));
//            medicamento.setConcentracao(resultSet.getString("DS_CONCENTRACAO"));
            medicamento.setcontraIndicacoes(resultSet.getString("DS_CONTRA_INDICACAO"));
            medicamento.setDoencasRelacionadas(procurarDoencasRelacionadas(oid, conexao));
            medicamento.setDrogaPrincipal(procurarDrogaPrincipal(oid, conexao));
            medicamento.setDrogasSecundarias(procurarDrogasSecundarias(oid, conexao));
            medicamento.setIndicacoes(resultSet.getString("DS_INDICACAO"));
            medicamento.setPrecoAtacadoInferior(resultSet.getDouble("VL_PRECO_ATACADO_INFERIOR"));
            medicamento.setPrecoAtacadoSuperior(resultSet.getDouble("VL_PRECO_ATACADO_SUPERIOR"));
            medicamento.setPrecoVarejo(resultSet.getDouble("VL_PRECO_VAREJO"));

            return medicamento;

        } catch (SQLException excecao) {
            throw new PersistenceException();
        }

    }

    private List procurarDoencasRelacionadas(OID idMed, Connection conexao)
    throws PersistenceException, SQLException, NullArgumentException, DoencaNaoCadastradaException {
        List doencas = new LinkedList();
        PreparedStatement statement2 = null, statement = null;
        Doenca doenca = null;
        OID oidDoenca;
        long idDoenca;
        Object obj;

        try {
            statement =  conexao.prepareStatement(getDoencaMedicamentoSQL);
            statement.setLong(1, idMed.getLongValue());
            ResultSet resultSet = statement.executeQuery();
            while (resultSet.next()) {
                idDoenca = resultSet.getLong("CD_DOENCA");
                oidDoenca = new OID (idDoenca);
                doenca =  repositorioDoenca.procurar(oidDoenca);//getDoenca (resultSetDoenca);
/*                obj = cache.pegarObjeto(oidDoenca);
                if (obj == null) {
                    statement2 =  conexao.prepareStatement(getDoencaOIDSQL);
                    statement2.setLong(1, resultSet.getLong("CD_DOENCA"));
                    ResultSet resultSetDoenca = statement2.executeQuery();
                    if (resultSetDoenca.next()) {

                        cache.inserirObjeto(oidDoenca, doenca);
                    }
                } else if (obj instanceof Doenca) {
                    doenca = (Doenca) obj;
                } else {
                    throw new PersistenceException("Objeto da cache nao eh uma instacia " +
                                                   "de Doenca");
                }
*/
                if (doenca != null) {
                    doencas.add(doenca);
                }
            }
            return doencas;
        } catch (SQLException excecao) {
            throw new PersistenceException();
        } finally {
            if (conexao != null) {
                if (statement != null) {
                    statement.close();
                }
                if (statement2 != null) {
                    statement2.close();
                }
            }
        }

    }

/*    private Doenca getDoenca(ResultSet resultSet) throws SQLException, NullArgumentException {
      Doenca doenca;

      OID oid = new OID(resultSet.getLong("CD_DOENCA"));
      String nome = resultSet.getString("NM_DOENCA");
      doenca = new Doenca(oid, nome);

      doenca.setCID(new CID(resultSet.getLong("CD_CID")));
      doenca.setHistorico(resultSet.getString("DS_HISTORICO"));
      doenca.setSintomas(resultSet.getString("DS_SINTOMAS"));
      doenca.setHereditariedade(resultSet.getString("DS_HEREDITARIEDADE"));
      // Ficou faltando doencas relacionadas
      return doenca;
    }
*/

    private Droga procurarDrogaPrincipal (OID oidMed, Connection conexao)
    throws PersistenceException, SQLException, NullArgumentException {
        Droga droga = null;
        PreparedStatement statement = null, statement2 = null;
        OID idDroga;
        Object obj;

        try {
            statement =  conexao.prepareStatement(getDrogaPrincipalMedicamentoSQL);
            statement.setLong(1, oidMed.getLongValue());
            ResultSet resultSet = statement.executeQuery();

            if(resultSet.next()) {
                idDroga = new OID(resultSet.getLong("CD_DROGA_PRINCIPAL"));
                obj = cache.pegarObjeto(idDroga);
                if (obj == null) {
                    statement2 = conexao.prepareStatement(getDrogaOIDSQL);
                    statement2.setLong(1, idDroga.getLongValue());
                    ResultSet resultSet2 = statement2.executeQuery();
                    if (resultSet2.next()) {
                        droga = getDroga (resultSet2);
                        cache.inserirObjeto(idDroga, droga);
                    }
                } else if (obj instanceof Droga){
                    droga = (Droga) obj;
                } else {
                    throw new PersistenceException("Objeto da cache nao eh uma instacia " +
                                             "de Droga");
                }
            }
            return droga;
        } catch (SQLException excecao) {
            throw new PersistenceException();
        } finally {
            if (conexao != null) {
                if (statement != null) {
                    statement.close();
                }
            }
        }
    }

    private List procurarDrogasSecundarias(OID idMed, Connection conexao)
    throws PersistenceException, SQLException, NullArgumentException{
        List drogas = new LinkedList();
        PreparedStatement statement2 = null, statement = null;
        Droga droga = null;
        OID oidDroga;
        long idDroga;
        Object obj;

        try {
            statement =  conexao.prepareStatement(getDrogaSecMedicamentoSQL);
            statement.setLong(1, idMed.getLongValue());
            ResultSet resultSet = statement.executeQuery();
            while (resultSet.next()) {
                idDroga = resultSet.getLong("CD_DROGA");
                oidDroga = new OID (idDroga);
                obj = cache.pegarObjeto(oidDroga);
                if (obj == null) {
                    statement2 =  conexao.prepareStatement(getDrogaOIDSQL);
                    statement2.setLong(1, resultSet.getLong("CD_DROGA"));
                    ResultSet resultSetDroga = statement2.executeQuery();
                    if (resultSetDroga.next()) {
                        droga = getDroga(resultSetDroga);
                        cache.inserirObjeto(oidDroga, droga);
                    }
                } else if (obj instanceof Droga) {
                    droga = (Droga) obj;
                } else {
                    throw new PersistenceException("Objeto da cache nao eh uma instacia " +
                                                   "de Droga");
                }
                if (droga != null) {
                    drogas.add(droga);
                }
            }
            return drogas;
        } catch (SQLException excecao) {
            excecao.printStackTrace();
            throw new PersistenceException(excecao);
        } finally {
            if (conexao != null) {
                if (statement != null) {
                    statement.close();
                }
                if (statement2 != null) {
                    statement2.close();
                }
            }

        }

    }

    private Droga getDroga (ResultSet resultSet) throws SQLException,
    NullArgumentException {
        Droga droga;

        OID oid = new OID(resultSet.getLong("CD_DROGA"));
        String nome = resultSet.getString("NM_DROGA");
        droga = new Droga();
        droga.setID(oid);
        droga.setNome(nome);
        droga.setAcoesTerapeuticas(resultSet.getString("DS_ACOES_TERAPEUTICAS"));
        droga.setPropriedades(resultSet.getString("DS_PROPRIEDADES"));
        droga.setDosagem(resultSet.getString("DS_DOSAGEM"));
        droga.setIndicacoes(resultSet.getString("DS_INDICACOES"));
        droga.setContraIndicacoes(resultSet.getString("DS_CONTRA_INDICACOES"));
        droga.setReacoesAdversas(resultSet.getString("DS_REACOES_ADVERSAS"));
        droga.setPrecaucoes(resultSet.getString("DS_PRECAUCOES"));
        droga.setInteracoes(resultSet.getString("DS_INTERACOES"));

        return droga;

    }

    /**
     * Procurar medicamentos pelo nome
     *
     * @param nome <code>String</code> com o nome ou parte do nome do medicamento
     *
     * @return Lista de medicamento com o nome requerido
     *
     */
    public List procurarPeloNome(String nome, int start, int size) throws MedicamentoNaoCadastradoException,
    PersistenceException, NullArgumentException, SQLException, DoencaNaoCadastradaException {
        Medicamento medicamento;
        Connection conexao = null;
        List oids = new LinkedList(), medicamentos = new LinkedList(), response = new LinkedList();
        OID oid;
        Object obj;

        try {
            conexao = connectionPoll.obterConexao();
            oids = getOIDsMedicamento(nome, conexao);
            if (start < oids.size()) {
                if ((start+size)>oids.size()) {
                    oids = oids.subList(start, oids.size());
                } else {
                    oids = oids.subList(start, start+size);
                }
            }
            while (!oids.isEmpty()) {
                oid = (OID) oids.remove(0);
                obj = cache.pegarObjeto(oid);
                if (obj == null) {
                    medicamento = procurarMedicamento(oid, conexao);
                    cache.inserirObjeto(oid, medicamento);
                } else if (obj instanceof Medicamento) {
                    medicamento = (Medicamento) obj;
                } else {
                    throw new PersistenceException("Objeto da cache nao eh uma instacia " +
                                                   "de Medicamento");
                }
                if (medicamento != null) {
                    response.add(medicamento);
                }
            }
            System.out.println("DBMedicamento.procurarPeloNome.start=" + start);
            System.out.println("DBMedicamento.procurarPeloNome.medicamentos.size()=" + medicamentos.size());
            return response;
        } catch (SQLException excecao) {
            throw new PersistenceException(excecao.getMessage());
        } finally {
            if(conexao != null) {
                connectionPoll.liberarConexao(conexao);
            }
        }
    }

    /**
     * Procurar medicamentos pela droga
     *
     * @param droga Objeto <code>Droga</code> para consulta em medicamentos
     *
     * @return Lista de medicamentos com a droga requerida
     */
    public List procurarPelaDroga(Droga droga, int start, int size) throws MedicamentoNaoCadastradoException,
    PersistenceException, NullArgumentException, SQLException, DoencaNaoCadastradaException{
        Medicamento medicamento;
        Connection conexao = null;
        List oids = new LinkedList(), medicamentos = new LinkedList(), med2 = new LinkedList(), response = new LinkedList();
        OID oid;
        Object obj;

        try {
            conexao = connectionPoll.obterConexao();
            medicamentos = procurarPelaDrogaPrincipal(droga, conexao);
            med2 = procurarPelaDrogaSecundaria(droga, conexao);
            if (medicamentos.size() > 0) {
                if (med2.size() > 0) {
                    medicamentos.addAll(med2);
                }
            } else {
                if (med2.size() > 0) {
                    medicamentos = med2;
                }
            }
            if (start < medicamentos.size()) {
                if ((start+size)>medicamentos.size()) {
                    response = medicamentos.subList(start, medicamentos.size());
                } else {
                    response = medicamentos.subList(start, start+size);
                }
            }
        } catch (SQLException excecao) {
            throw new PersistenceException(excecao.getMessage());
        } finally {
            if(conexao != null) {
                connectionPoll.liberarConexao(conexao);
            }
            return response;
        }
    }

    /**
     * Procurar medicamentos pela droga principal
     *
     * @param droga <code>Droga</code> A ser procurada no medicamento
     * @param conexao <code>Connection</code> Conexao do banco
     *
     * @return Lista de medicamentos com a droga requerida como droga principal
     */
    private List procurarPelaDrogaPrincipal (Droga droga, Connection conexao) throws PersistenceException,
    SQLException, NullArgumentException, MedicamentoNaoCadastradoException, DoencaNaoCadastradaException{
        List medicamentos = new LinkedList();
        Medicamento medicamento;
        PreparedStatement statement = null;
        Object obj;
        OID oidMed;

        try {
            statement = conexao.prepareStatement(procurarMedicamentoPelaDrogaSQL);
            statement.setLong(1, droga.getID().getLongValue());
            ResultSet resultSet = statement.executeQuery();

            while (resultSet.next()) {
                oidMed = new OID(resultSet.getLong("CD_MEDICAMENTO"));
                obj = cache.pegarObjeto(oidMed);
                if (obj == null) {
                    medicamento = getMedicamento(resultSet,conexao);
                    cache.inserirObjeto(oidMed, medicamento);
                } else if (obj instanceof Medicamento) {
                    medicamento = (Medicamento) obj;
                } else {
                    throw new PersistenceException("Objeto da cache nao eh uma instacia " +
                                                   "de Medicamento");
                }
                if (medicamento != null) {
                    medicamentos.add(medicamento);
                }
            }
            return medicamentos;
        } catch (SQLException excecao) {
            throw new PersistenceException(excecao.getMessage());
        } finally {
            if (conexao != null) {
                if (statement != null) {
                    statement.close();
                }
            }
        }
    }

    /**
     * Procurar medicamentos pela droga secundaria
     *
     * @param droga <code>Droga</code> A ser procurada no medicamento
     * @param conexao <code>Connection</code> Conexao do banco
     *
     * @return Lista de medicamentos com a droga requerida como droga secundaria
     */
    private List procurarPelaDrogaSecundaria(Droga droga, Connection conexao) throws PersistenceException,
    SQLException, NullArgumentException, MedicamentoNaoCadastradoException, DoencaNaoCadastradaException{
        List medicamentos = new LinkedList();
        PreparedStatement statement = null;
        Object obj;
        OID oidMed;
        Medicamento medicamento;

        try {
            statement =  conexao.prepareStatement(getMedicamentoDrogaSecSQL);
            statement.setLong(1, droga.getID().getLongValue());
            ResultSet resultSet = statement.executeQuery();
            while (resultSet.next()) {
                oidMed = new OID (resultSet.getLong("CD_MEDICAMENTO"));
                obj = cache.pegarObjeto(oidMed);
                if (obj == null) {
                    medicamento = procurarMedicamento(oidMed);
                    cache.inserirObjeto(oidMed, medicamento);
                } else if (obj instanceof Medicamento) {
                    medicamento = (Medicamento) obj;
                } else {
                    throw new PersistenceException("Objeto da cache nao eh uma instacia " +
                                                   "de Medicamento");
                }
                if (medicamento != null) {
                    medicamentos.add(medicamento);
                }
            }
            return medicamentos;
        } catch (SQLException excecao) {
            throw new PersistenceException();
        } finally {
            if (conexao != null) {
                if (statement != null) {
                    statement.close();
                }
            }

        }
    }

    /**
     * Procurar medicamentos pelo laboratorio
     *
     * @param laboratorio Objeto <code>Laboratorio</code> para consultar em medi-
     *                     dicamentos
     * @return Lista de medicamentos do laboratorio requerido
     */
    public List procurarPeloLaboratorio(Laboratorio laboratorio, int start, int size) throws MedicamentoNaoCadastradoException,
    PersistenceException, SQLException, NullArgumentException, DoencaNaoCadastradaException{
        Medicamento medicamento;
        PreparedStatement statement = null;
        Connection conexao = null;
        List medicamentos = new LinkedList(), response = new LinkedList();
        OID oid, oidLab;
        Object obj;

        try {
            conexao = connectionPoll.obterConexao();
            if (laboratorio.getId() == null) {
                oidLab = getOIDLaboratorio(laboratorio, conexao);
            } else {
                oidLab = laboratorio.getId();
            }
            statement =  conexao.prepareStatement(getMedicamentoLaboratorioSQL);
            statement.setLong(1, oidLab.getLongValue());
            ResultSet resultSet = statement.executeQuery();
            while (resultSet.next()) {
                oid = new OID (resultSet.getLong("CD_MEDICAMENTO"));
                obj = cache.pegarObjeto(oid);
                if (obj == null) {
                    medicamento = procurarMedicamento(oid, conexao);
                    cache.inserirObjeto(oid, medicamento);
                } else if (obj instanceof Medicamento) {
                    medicamento = (Medicamento) obj;
                } else {
                    throw new PersistenceException("Objeto da cache nao eh uma instacia " +
                                                   "de Medicamento");
                }
                if (medicamento != null) {
                    medicamentos.add(medicamento);
                }
            }
            if ((start+size) > medicamentos.size()) {
                response = medicamentos.subList(start, medicamentos.size());
            } else {
                response = medicamentos.subList(start, start+size);
            }
            return response;
        } catch (SQLException excecao) {
            throw new PersistenceException(excecao.getMessage());
        } finally {
            if(conexao != null) {
                connectionPoll.liberarConexao(conexao);
            }
            if (conexao != null) {
                if (statement != null) {
                    statement.close();
                }
            }

        }

    }

    /**
     * Procurar medicamentos pelo CID
     *
     * @param cid Objeto <code>CID</code> para consultar medicamentos
     *
     * @return Lista de medicamentos com o CID requerido
     */
   public List procurarPeloCID(CID cid) throws MedicamentoNaoCadastradoException
   {
        return null;
   }

    /**
     * Procurar medicamentos pela doenca
     *
     * @param doenca Objeto <code>Doenca</code> para pesquisa medicamentos
     *
     * @return Lista de medicamentos com a doenca requerida
     */
    public List procurarPelaDoenca(Doenca doenca, int start, int size) throws MedicamentoNaoCadastradoException,
    PersistenceException, SQLException, NullArgumentException, MedicamentoNaoCadastradoException,
    DoencaNaoCadastradaException{
        Medicamento medicamento = null;
        PreparedStatement statement = null;
        Connection conexao = null;
        List medicamentos = new LinkedList();
        OID oid;
        Object obj;
        int count;

        try {
            conexao = connectionPoll.obterConexao();
            statement =  conexao.prepareStatement(getMedicamentoDoencaSQL);
            statement.setLong(1, doenca.getId().getLongValue());
            ResultSet resultSet = statement.executeQuery();
            if (start > 0) {
                resultSet.absolute(start);
            }
            if (resultSet.next()) {
                count = 0;
                do {
                    oid = new OID (resultSet.getLong("CD_MEDICAMENTO"));
                    obj = cache.pegarObjeto(oid);
                    if (obj == null) {
                        medicamento = procurarMedicamento(oid, conexao);
                        cache.inserirObjeto(oid, medicamento);
                    } else if (obj instanceof Medicamento) {
                        medicamento = (Medicamento) obj;
                    } else {
                        throw new PersistenceException("Objeto da cache nao eh uma instacia " +
                                                   "de Medicamento");
                    }
                    if (medicamento != null) {
                        medicamentos.add(medicamento);
                    }
                    count++;
                } while (resultSet.next() && count<size);
            }
            return medicamentos;
        } catch (SQLException excecao) {
            throw new PersistenceException(excecao.getMessage());
        } finally {
            if(conexao != null) {
                connectionPoll.liberarConexao(conexao);
            }
            if (conexao != null) {
                if (statement != null) {
                    statement.close();
                }
            }

        }
    }

    /**
     * Inserir um medicamento no repositorio
     *
     * @param newMedicamento Objeto <code>Medicamento</code> para ser cadastrado
     *
     * @exception MedicamentoJaCadastradoException Caso o objeto ja tenha sido
     *                                              cadastrado
     */
   public void inserir(Medicamento newMedicamento) throws MedicamentoJaCadastradoException,
   PersistenceException, SQLException, NullArgumentException {
        Connection conexao = null;
        OID oid = null;
        Object obj;
        OIDFactory oidfactory = OIDFactory.getInstancia();

        try {
            conexao =  connectionPoll.obterConexao();
            conexao.setAutoCommit(false);
            oid = oidfactory.novoOID();
            newMedicamento.setId(oid);
            if (existe(newMedicamento.getNome(),conexao) == false) {
                inserir(newMedicamento, conexao);
                cache.inserirObjeto(oid, newMedicamento);
            } else {
                throw new MedicamentoJaCadastradoException("Medicamento " + newMedicamento.getNome() +
                                                           " ja foi cadastrado!");
            }
        } catch (NullArgumentException exc) {
            throw new NullArgumentException ("OID nulo");
        } catch (SQLException excecao) {
            if(oid != null) {
              cache.invalidarObjeto(oid);
            }
            try {
                conexao.rollback();
            }catch (SQLException sqle1) {
                sqle1.printStackTrace();
            }
            throw new PersistenceException(excecao.getMessage());
        } finally {
            if(conexao != null) {
              conexao.commit();
              conexao.setAutoCommit(true);
              connectionPoll.liberarConexao(conexao);
            }
        }
   }

    private void inserir(Medicamento newMedicamento, Connection conexao) throws SQLException,
    PersistenceException {
        PreparedStatement statement = null;
        try {
            statement =  conexao.prepareStatement(inserirMedicamentoSQL);
            statement.setLong(1, newMedicamento.getId().getLongValue());
            statement.setString(2, newMedicamento.getNome());
            statement.setString(3, newMedicamento.getcontraIndicacoes());
            statement.setString(4, newMedicamento.getIndicacoes());
            if (newMedicamento.getDrogaPrincipal() != null) {
                statement.setLong(5, newMedicamento.getDrogaPrincipal().getID().getLongValue());
            } else {
                statement.setLong(5, 0);
            }
            statement.setDouble(6, newMedicamento.getPrecoVarejo());
            statement.setDouble(7, newMedicamento.getPrecoAtacadoInferior());
            statement.setDouble(8, newMedicamento.getPrecoAtacadoSuperior());
            setLaboratorios(newMedicamento.getId(), newMedicamento.getLaboratorios(), conexao);
            setApresentacao(newMedicamento.getId(),newMedicamento.getApresentacao(),conexao);
            setDrogasSecundarias(newMedicamento.getId(),newMedicamento.getDrogasSecundarias(), conexao);
            setDoencasRelac(newMedicamento.getId(),newMedicamento.getDoencasRelacionadas(), conexao);
            statement.execute();
        } finally {
            if (conexao != null) {
                if (statement != null) {
                    statement.close();
                }
            }
        }
    }

    private void setLaboratorios(OID oidMed, List laboratorios, Connection conexao)
    throws SQLException, PersistenceException {
        Laboratorio laboratorio;
        OID oidLab;

        excluirMedicamentoLaboratorio(oidMed, conexao);
        while (!laboratorios.isEmpty()) {
            laboratorio = (Laboratorio) laboratorios.remove(0);
            oidLab = getOIDLaboratorio(laboratorio, conexao);
            if (oidLab == null) {
            	oidLab = oidfactory.novoOID();
            	laboratorio.setID(oidLab);
            	inserirLaboratorio(laboratorio, conexao);
            	cache.inserirObjeto(oidLab, laboratorio);
            }
            inserirMedicamentoLaboratorio(oidMed,oidLab, conexao);
        }
    }

    private void excluirMedicamentoLaboratorio(OID oidMed, Connection conexao)
    throws SQLException{
        PreparedStatement statement = null;

        try {
            statement = conexao.prepareStatement(excluirMedicamentoLaboratorioSQL);
            statement.setLong(1, oidMed.getLongValue());
            statement.execute();
        } finally {
            if (conexao != null) {
                if (statement != null) {
                    statement.close();
                }
            }
        }
    }

    private void inserirMedicamentoLaboratorio(OID oidMed, OID oidLab, Connection conexao) throws SQLException{
        PreparedStatement statement = null;

        try {
            statement = conexao.prepareStatement(inserirMedicamentoLaboratorioSQL);
            statement.setLong(1, oidLab.getLongValue());
            statement.setLong(2, oidMed.getLongValue());
            statement.execute();
        } finally {
            if (conexao != null) {
                if (statement != null) {
                    statement.close();
                }
            }
        }
    }

    private OID getOIDLaboratorio(Laboratorio laboratorio, Connection conexao)
    throws SQLException {
        PreparedStatement statement = null;
        OID oid = null;
        Object obj;

        try {
            obj = cache.pegarObjeto(laboratorio.getId());
            if (obj == null) {
                statement = conexao.prepareStatement(getOIDLaboratorioSQL);
                statement.setString(1, "%"+laboratorio.getNome()+"%");
                ResultSet resultSet = statement.executeQuery();
                if (resultSet.next()) {
                    oid = new OID (resultSet.getLong("CD_LABORATORIO"));
                }
            } else if (obj instanceof Laboratorio) {
                oid = ((Laboratorio) obj).getId();
            }
          return oid;
        } finally {
            if (conexao != null) {
                if (statement != null) {
                    statement.close();
                }
            }
        }
    }

    private void inserirLaboratorio(Laboratorio laboratorio, Connection conexao)
    throws SQLException{
        PreparedStatement statement = null;

        try {
            statement = conexao.prepareStatement(inserirLaboratorioSQL);
            statement.setLong(1, laboratorio.getId().getLongValue());
            statement.setString(2, laboratorio.getNome());
            statement.execute();
        } finally {
            if (conexao != null) {
                if (statement != null) {
                    statement.close();
                }
            }
        }
    }

    private void setApresentacao(OID oidMed, List apresentacoes, Connection conexao)
    throws SQLException, PersistenceException{
        Apresentacao apresentacao;
        OID oidApres;

        excluirMedicamentoApresentacao(oidMed, conexao);
        while (!apresentacoes.isEmpty()) {
            apresentacao = (Apresentacao) apresentacoes.remove(0);
            oidApres = getOIDApresentacao(apresentacao, conexao);
            if (oidApres == null){
            	oidApres = oidfactory.novoOID();
            	apresentacao.setID(oidApres);
            	inserirApresentacao(apresentacao, conexao);
            	cache.inserirObjeto(oidApres, apresentacao);
            }
            inserirMedicamentoApresentacao(oidMed,oidApres, conexao);
        }
    }

    private void excluirMedicamentoApresentacao(OID oidMed, Connection conexao)
    throws SQLException{
        PreparedStatement statement = null;

        try {
            statement = conexao.prepareStatement(excluirMedicamentoApresentacaoSQL);
            statement.setLong(1, oidMed.getLongValue());
            statement.execute();
        } finally {
            if (conexao != null) {
                if (statement != null) {
                    statement.close();
                }
            }
        }
    }

    private void inserirMedicamentoApresentacao(OID oidMed, OID oidApres, Connection conexao)
    throws SQLException{
        PreparedStatement statement = null;

        try {
            statement = conexao.prepareStatement(inserirMedicamentoApresentacaoSQL);
            statement.setLong(1, oidApres.getLongValue());
            statement.setLong(2, oidMed.getLongValue());
            statement.execute();
        } finally {
            if (conexao != null) {
                if (statement != null) {
                    statement.close();
                }
            }
        }
    }

    private OID getOIDApresentacao(Apresentacao apresentacao, Connection conexao)
    throws SQLException {
        PreparedStatement statement = null;
        OID oidApres = null;
        Object obj;

        try {
            obj = cache.pegarObjeto(apresentacao.getId());
            if (obj == null) {
                statement = conexao.prepareStatement(getOIDApresentacaoSQL);
                statement.setString(1, apresentacao.getNome());
                ResultSet resultSet = statement.executeQuery();
                if (resultSet.next()) {
                    oidApres = new OID(resultSet.getLong("CD_APRESENTACAO"));
                }
            } else if (obj instanceof Apresentacao) {
                oidApres = ((Apresentacao) obj).getId();
            }
            return oidApres;
        } finally {
            if (conexao != null) {
                if (statement != null) {
                    statement.close();
                }
            }
        }
    }

    private void inserirApresentacao(Apresentacao apresentacao, Connection conexao)
    throws SQLException{
        PreparedStatement statement = null;

        try {
            statement = conexao.prepareStatement(inserirApresentacaoSQL);
            statement.setLong(1, apresentacao.getId().getLongValue());
            statement.setString(2, apresentacao.getNome());
            statement.execute();
        } finally {
            if (conexao != null) {
                if (statement != null) {
                    statement.close();
                }
            }
        }
    }

    private void setDrogasSecundarias(OID oidMed, List drogasSec, Connection conexao)
    throws SQLException {
        Droga drogaSec;

        excluirMedicamentoDrogasSec(oidMed, conexao);
        while (!drogasSec.isEmpty()) {
            drogaSec = (Droga) drogasSec.remove(0);
            inserirMedicamentoDrogaSec(oidMed, drogaSec.getID(), conexao);
        }
    }

    private void excluirMedicamentoDrogasSec(OID oidMed, Connection conexao)
    throws SQLException{
        PreparedStatement statement = null;

        try {
            statement = conexao.prepareStatement(excluirMedicamentoDrogasSecSQL);
            statement.setLong(1, oidMed.getLongValue());
            statement.execute();
        } finally {
            if (conexao != null) {
                if (statement != null) {
                    statement.close();
                }
            }
        }
    }

    private void inserirMedicamentoDrogaSec(OID oidMed, OID oidDroga, Connection conexao)
    throws SQLException{
        PreparedStatement statement = null;

        try {
            statement = conexao.prepareStatement(inserirMedicamentoDrogaSecSQL);
            statement.setLong(1, oidDroga.getLongValue());
            statement.setLong(2, oidMed.getLongValue());
            statement.execute();
        } finally {
            if (conexao != null) {
                if (statement != null) {
                    statement.close();
                }
            }
        }
    }

    private void inserirDrogaSec(Droga droga, Connection conexao) throws SQLException {
        PreparedStatement statement = null;
        try {
            statement =  conexao.prepareStatement(inserirDrogaSQL);
            statement.setLong(1, Long.parseLong(droga.getID().toString()));
            statement.setString(2, droga.getNome());
            statement.setString(3, droga.getAcoesTerapeuticas());
            statement.setString(4, droga.getPropriedades());
            statement.setString(5, droga.getDosagem());
            statement.setString(6, droga.getIndicacoes());
            statement.setString(7, droga.getContraIndicacoes());
            statement.setString(8, droga.getReacoesAdversas());
            statement.setString(9, droga.getPrecaucoes());
            statement.setString(10, droga.getInteracoes());

            statement.execute();
        } finally {
            if (conexao != null) {
                if (statement != null) {
                    statement.close();
                }
            }
        }
    }

    private void setDoencasRelac(OID oidMed, List doencas, Connection conexao)
    throws SQLException {
        Doenca doenca;

        excluirMedicamentoDoencaRelac(oidMed, conexao);
        while (!doencas.isEmpty()) {
            doenca = (Doenca) doencas.remove(0);
            inserirMedicamentoDoenca(oidMed, doenca.getId(), conexao);
        }
    }

    private void excluirMedicamentoDoencaRelac(OID oidMed, Connection conexao)
    throws SQLException{
        PreparedStatement statement = null;

        try {
            statement = conexao.prepareStatement(excluirMedicamentoDoencaSQL);
            statement.setLong(1, oidMed.getLongValue());
            statement.execute();
        } finally {
            if (conexao != null) {
                if (statement != null) {
                    statement.close();
                }
            }
        }
    }

    private void inserirMedicamentoDoenca(OID oidMed, OID oidDoenca, Connection conexao)
    throws SQLException{
        PreparedStatement statement = null;

        try {
            statement = conexao.prepareStatement(inserirMedicamentoDoencaSQL);
            statement.setLong(1, oidDoenca.getLongValue());
            statement.setLong(2, oidMed.getLongValue());
            statement.execute();
        } finally {
            if (conexao != null) {
                if (statement != null) {
                    statement.close();
                }
            }
        }
    }

    /**
     * Alterar medicamento cadastrado
     *
     * @param oldMedicamento Objeto <code>Medicamento</code> antigo
     * @param newMedicamento Objeto <code>Medicamento</code> novo
     *
     * @exception MedicamentoNaoCadastradoException Caso objeto procurado nao
     *                                              esteja cadastrado
     */
   public void alterar(Medicamento oldM, Medicamento newM) throws MedicamentoNaoCadastradoException,
   PersistenceException, NullArgumentException, SQLException, MedicamentoJaCadastradoException{
        Connection conexao = null;
        OID oid;

        try {
            conexao =  connectionPoll.obterConexao();
            conexao.setAutoCommit(false);
            oid = oldM.getId();
            if (existe(newM.getNome(), conexao)) {
                throw new MedicamentoJaCadastradoException("Nome : " +newM.getNome());
            }
            if(existe(oid, conexao)) {
              alterar(oid, newM, conexao);
              cache.inserirObjeto(oid, newM);
            } else {
              throw new MedicamentoNaoCadastradoException("oid : " +oid);
            }

        } catch (SQLException excecao) {
            try {
                conexao.rollback();
            }catch (SQLException sqle1) {
                sqle1.printStackTrace();
            }
            throw new PersistenceException(excecao.getMessage());
        } finally {
            if(conexao != null) {
               connectionPoll.liberarConexao(conexao);
               conexao.commit();
               conexao.setAutoCommit(true);
            }
        }
   }

    private void alterar(OID oid, Medicamento medicamento, Connection conexao) throws SQLException, PersistenceException {
        PreparedStatement statement = null;
        try {
            statement =  conexao.prepareStatement(alteraMedicamentoSQL);
            statement.setLong(1, oid.getLongValue());
            statement.setString(2, medicamento.getNome());
            statement.setString(3, medicamento.getcontraIndicacoes());
            statement.setString(4, medicamento.getIndicacoes());
            statement.setLong(5, medicamento.getDrogaPrincipal().getID().getLongValue());
            statement.setDouble(6, medicamento.getPrecoVarejo());
            statement.setDouble(7, medicamento.getPrecoAtacadoInferior());
            statement.setDouble(8, medicamento.getPrecoAtacadoSuperior());
            statement.setLong(9, oid.getLongValue());
            statement.executeUpdate();
            setApresentacao(oid, medicamento.getApresentacao(), conexao);
            setDoencasRelac(oid, medicamento.getDoencasRelacionadas(), conexao);
            setDrogasSecundarias(oid, medicamento.getDrogasSecundarias(), conexao);
            setLaboratorios(oid, medicamento.getLaboratorios(), conexao);
        } finally {
            if (conexao != null) {
                if (statement != null) {
                    statement.close();
                }
            }
        }
    }

    public boolean existe(Medicamento medicamento) throws NullArgumentException, SQLException{
        Connection conexao = null;
        Object obj;
        boolean teste;

        try {
            obj = cache.pegarObjeto(medicamento.getId());
            conexao =  connectionPoll.obterConexao();
            if (obj == null) {
                teste = existe(medicamento.getId(), conexao);
            } else if (obj instanceof Medicamento) {
                teste = true;
            } else {
                teste = false;
            }
            return teste;
        } finally {
            if(conexao != null) {
              connectionPoll.liberarConexao(conexao);
            }
        }
    }

    private boolean existe(String nome, Connection conexao) throws SQLException, NullArgumentException {
        PreparedStatement statement= null;
        boolean saida = false;
        try {
            if(nome.equals("")) {
              throw new NullArgumentException("nome vazio");
            }

            statement = conexao.prepareStatement(getOIDSQL);
            statement.setString(1, nome);
            ResultSet resultSet = statement.executeQuery();
            saida = resultSet.next();
        } finally {
            if (conexao != null) {
                if (statement != null) {
                    statement.close();
                }
            }
            return saida;
        }
    }

    private boolean existe(OID id, Connection conexao) throws SQLException, NullArgumentException {
        PreparedStatement statement= null;
        boolean saida = false;
        try {
            if(id == null) {
              throw new NullArgumentException("oid == null");
            }

            statement = conexao.prepareStatement(procurarMedicamentoSQL);
            statement.setLong(1, Long.parseLong(id.toString()));
            ResultSet resultSet = statement.executeQuery();
            saida = resultSet.next();
        } finally {
            if (conexao != null) {
                if (statement != null) {
                    statement.close();
                }
            }
            return saida;
        }
    }

    public List getTodosLaboratorios () throws SQLException, NullArgumentException {
        Connection conexao = null;
        PreparedStatement statement= null;
        List labs = new LinkedList();
        Object obj;

        try {
            conexao =  connectionPoll.obterConexao();
            statement = conexao.prepareStatement(getTodosLaboratoriosSQL);
            ResultSet resultSet = statement.executeQuery();
            while (resultSet.next()) {
                Laboratorio lab = new Laboratorio ();
                lab.setID(new OID(resultSet.getLong("CD_LABORATORIO")));
                lab.setNome(resultSet.getString("NM_LABORATORIO"));
                labs.add(lab);
            }

        } finally {
            if (conexao != null) {
                if (statement != null) {
                    statement.close();
                }
                if (!conexao.isClosed()) {
                    conexao.close();
                }
            }
            return labs;
        }

    }

}
