/* * ALMA - Atacama Large Millimiter Array * (c) European Southern Observatory, 2002 * Copyright by ESO (in the framework of the ALMA collaboration) * and Cosylab 2002, All rights reserved * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA */ package alma.acs.logging.archive; import javax.swing.ImageIcon; import com.cosylab.logging.LoggingClient; import java.lang.reflect.Constructor; import java.lang.reflect.Method; import java.util.Collection; import java.util.logging.Logger; /** * A class to connect and interact with the archive * * The connection with the database is not always available. * There are 2 possibilities: * 1. the code to connect to the DB is not available (it comes from * a module in ARCHIVE) * 2. the code is available but for some reason something in the * communication with the DB doesn't work as expected * * @author acaproni * */ public class ArchiveConnectionManager { /** * The name of the class, the method and so on to load. * * Generated by ARCHIVE and could not be present at run time */ private final String ARCHIVE_CLASS_NAME = "alma.archive.logging.ArchiveLoggingQuery"; /** * The name of the method to read logs from the database * * Generated by ARCHIVE and could not be present at run time */ private final String METHOD_NAME = "getLog"; /** * The possible states of the database * * @author acaproni * */ public enum DBState { DATABASE_OK("/databaseLink.png"), DATABASE_NOP("/databaseNOP.png"), DATABASE_WORKING("/databaseBusy.png"); public final ImageIcon icon; /** * Constructor * * @param iconStr The icon of the state */ private DBState(String iconStr) { icon=new ImageIcon(ArchiveConnectionManager.class.getResource(iconStr)); } } /** * The status of the connection with the DB */ private DBState status; /** * The class to talk to the archive */ private Object archive = null; /** * The method to get logs from the database */ private Method getLogMethod; /** * The application */ private LoggingClient logging; /** * Constructor * * @param loggingClient The logging client */ public ArchiveConnectionManager(LoggingClient loggingClient) { if (loggingClient==null) { throw new IllegalArgumentException("Invalid null LoggingClient reference"); } logging = loggingClient; archive = loadArchiveClass(); if (archive==null) { // The code for the archive is not available status = DBState.DATABASE_NOP; showDBStatus("Database connection not available"); } else { getLogMethod = getMethod(archive); if (getLogMethod==null) { // The method for the archive is not available status = DBState.DATABASE_NOP; showDBStatus("Database connection not available"); } else { status = DBState.DATABASE_OK; showDBStatus("Database ready"); } } } /** * Load the class to talk with the archive * * @return An object to submit wueries to the database * null if something went wrong loading the class */ private Object loadArchiveClass() { try { Thread t = Thread.currentThread(); ClassLoader loader = t.getContextClassLoader(); Class cl =loader.loadClass(ARCHIVE_CLASS_NAME); Class[] classes = { Class.forName("java.util.logging.Logger")}; Constructor constructor = cl.getConstructor(classes); Object obj = constructor.newInstance((Logger)null); return cl.cast(obj); } catch (Throwable t) { //System.out.println("alma.archive.logging.ArchiveLoggingQuery not found:"); //System.out.println("\tDatabase connection not available "+t.getMessage()); //t.printStackTrace(); return null; } } /** * Get the method to retrieve log from the database * * @param obj The object containing the method * @return The getLog method of the object */ private Method getMethod(Object obj) { if (obj==null) { throw new IllegalArgumentException("Invalid null parameter in getMethod"); } Method ret = null; Class cl = obj.getClass(); try { cl = Class.forName(ARCHIVE_CLASS_NAME); } catch (ClassNotFoundException cnfe) { //System.out.println("Class not found: "+cnfe.getMessage()); return null; } Class[] paramClasses=null; // Build the list of parameters try { paramClasses = new Class[] { Class.forName("java.lang.String"), // String timeFrom Class.forName("java.lang.String"), // String timeTo java.lang.Short.TYPE, // short minType java.lang.Short.TYPE, //short maxType, Class.forName("java.lang.String"), // String routine Class.forName("java.lang.String"), // String source Class.forName("java.lang.String"), //String process java.lang.Integer.TYPE //, int maxRow }; } catch (Exception e) { //System.out.println("Error building the array of parameters:"+e.getMessage()); //e.printStackTrace(); return null; } // Look for the given method try { ret = cl.getMethod(METHOD_NAME,paramClasses); } catch (Throwable t) { System.out.println("This mehtod does not exist in "+cl.getName()); System.out.println("\t"+METHOD_NAME+"("); for (int temp=0; temp<paramClasses.length; temp++) { System.out.println("\t\t"+paramClasses[temp].getName()+","); } System.out.println("\t\t(\n\tDatabase connection not available:\n"+t.getMessage()); t.printStackTrace(); return null; } // Check the return type if (!ret.getReturnType().getName().equals("java.util.Collection")) { System.out.println("The method returns "+ret.getReturnType().getName()+" instead of java.util.Collection"); System.out.println("Database connection not available"); return null; } return ret; } /** * Notify the LoggingClient about the status of the connection with the database * * The icon in the LC is set depending on the actual state of the connection. * The tooltip of the icon is set equal to the msg parameter * * @param msg A message to show as tool tip in the icon of the status * of the DB connection */ private void showDBStatus(String msg) { logging.showDBStatus(status.icon,msg); } /** * * @return The status of the DB */ public DBState getDBStatus() { if (logging.inDebugMode()) { return DBState.DATABASE_OK; } else { return status; } } /** * Get the logs from the archive * * @param from Start time * @param to End time * @param minType Minimum log type * @param maxType Maximum log type * @param routine The routine name * @param source The source * @param process The process * @param maxRows Max number of logs to read from the database * @return The logs read from the database * @throws Exception */ public Collection getLogs( String from, String to, short minType, short maxType, String routine, String source, String process, int maxRows) throws Exception { status = DBState.DATABASE_WORKING; showDBStatus("Executing a query"); Object params[] = { from, to, minType, maxType, routine, source, process, maxRows }; Object ret = null; try { ret = getLogMethod.invoke(archive,params); } catch (Throwable t) { status = DBState.DATABASE_OK; showDBStatus("Database ready."); System.out.println("Exception thrown: "+t); throw new Exception ("Error executing a query.",t); } status=DBState.DATABASE_OK; showDBStatus("Database ready"); return (Collection)ret; } }