package combdServlet; import java.io.*; import javax.servlet.*; import javax.servlet.http.*; import java.util.Date; import combd.*; /** * Servlet que fornece comunicação com o BD. * * @author Marcos V. S. Godinho */ public class CombdServlet extends HttpServlet{ //Parâmetros para conexão com o banco de dados private static String DRIVER = "com.mysql.jdbc.Driver"; private static String URL = "jdbc:mysql://fmc2.graco.unb.br:3306/webmachining_temp"; private static String USER = "webmachining"; private static String PSW = "webmachining"; private BancoDeDados banco; private Thread ThreadReiniciadora; private volatile int contador = 0; //Métodos para controle de requisições de query. private final synchronized int contagem(){ return contador; } private final synchronized void incrementa(){ ++contador; } private final synchronized void decrementa(){ --contador; } private volatile boolean erro = false; //Métodos para controle de erros. private final synchronized boolean houveErro(){ return erro; } private final synchronized void sinalizaErro(){ erro = true; } private final synchronized void erroCorrigido(){ erro = false; } private final synchronized void reinicializaBD(){ banco.desconecta(); banco.conecta(DRIVER, URL, USER, PSW); System.out.println(new Date() + " CombdServlet reinicializado com sucesso."); } //Realiza a conexão com o banco ao ser chamado no start do servlet public void init(ServletConfig config) throws ServletException{ super.init(config); banco = BancoDeDados.getBancoDeDados(); banco.conecta(DRIVER, URL, USER, PSW); System.out.println(new Date() + " CombdServlet iniciado com sucesso."); //Constroi a thread reiniciadora. ThreadReiniciadora = new Thread(){ long UM_SEGUNDO = 1000; long UM_MINUTO = 60 * UM_SEGUNDO; long UMA_HORA = 60 * UM_MINUTO; Date antes; public void run(){ while(banco != null){ antes = new Date(); try {//Calcula o que falta para meia-noite. Thread.sleep(UMA_HORA*(23 - antes.getHours()) + UM_MINUTO*(59 - antes.getMinutes()) + UM_SEGUNDO*(60 - antes.getSeconds())); } catch (InterruptedException ie){} //Reinicializa uma vez por dia. if(antes.getDay() != new Date().getDay()) reinicializaBD(); }//while }//run }; ThreadReiniciadora.start(); } public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{ } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{ synchronized(this){ try{//Espera correção de erro. while( houveErro() ) wait(); } catch(InterruptedException ie){} } incrementa(); ObjectInputStream objin = new ObjectInputStream(request.getInputStream()); ObjectOutputStream objout = new ObjectOutputStream(response.getOutputStream()); ProcedimentoPSttmt proc = null; try{//Obtem pedido. PedidoQuery pedido = (PedidoQuery)objin.readObject(); //Prepara conexão com o BD. proc = new ProcedimentoPSttmt( banco.preparaPrepared(pedido.getQuery()) ); proc.setParamIN(pedido.getParametros()); //Executa a query e analiza o resultado. int resultado = proc.executeProcedimento(); if(resultado == -1)//Houve erro. throw new Exception(); else if( resultado == proc.EXISTE_RESULTADO)//Existe Resultado de busca. objout.writeObject(proc.getTabelaDeResultado()); else objout.writeObject(new Integer(resultado)); } catch(Exception e){ sinalizaErro();//Deve reiniciar o BD. System.err.println("Erro no processamento de requisição ao Servlet"); e.printStackTrace(); } finally{ //fecha as streams de entreda e saída. objin.close(); objout.close(); if(proc != null) proc.fechaStatement(); decrementa(); //Se houve erro e não há ninguem dentro deste método. if(houveErro() && contagem() == 0){ synchronized(this){ //Reinicia... reinicializaBD(); //Notifica o reinicio. erroCorrigido(); notifyAll(); } }//if }//finally }//doPost //Fecha conexão com o banco de dados public void destroy(){ banco.desconecta(); banco = null; ThreadReiniciadora.interrupt(); System.out.println(new Date() + " CombdServlet finalizado com sucesso."); } }