package org.hwo.pulscounter; import static org.hwo.logging.Logging.log; import static org.hwo.logging.LogLevel.*; import java.awt.EventQueue; import java.awt.Frame; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.lang.reflect.Constructor; import java.util.ArrayList; import java.util.Arrays; import java.util.InvalidPropertiesFormatException; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Properties; import java.util.Vector; import java.util.prefs.BackingStoreException; import java.util.prefs.Preferences; import javax.swing.JFrame; import org.hsqldb.persist.EventLogInterface; import org.hwo.StringHelper; import org.hwo.configuration.ConfigurableObjects; import org.hwo.io.NewSerialPort.NewSerialPort; import org.hwo.platform.Platform; import org.hwo.servicelink.ServiceLink; import org.hwo.servicelink.ServiceLinkListener; import org.hwo.pulscounter.device.IDeviceConnector; import org.hwo.pulscounter.device.ServiceLinkDeviceConnector; import org.hwo.pulscounter.device.SimulatedCounter; import org.hwo.pulscounter.ui.AppSettingsListener; import org.hwo.pulscounter.ui.BatchRunner; import org.hwo.pulscounter.ui.NewMainWindow; import org.hwo.scheduler.Scheduler; public class PulsCounterApplication implements ServiceLinkListener{ static PulsCounterApplication _application; public static PulsCounterApplication getApplication(){ if (_application == null) _application = new PulsCounterApplication(null); return _application; } private Properties applicationConfiguration; private List deviceConnectors; private Object uiSynchronization; private boolean uiIsFinished; private boolean shouldSaveConfiguration; private List applicationListeners; private Vector unseenMessages; private List> interfaceClasses; private List interfaces; private NewSerialPort serialPort; private ServiceLink serviceLink; private List appSettingsListeners; private boolean snapshotLock; private SnapshotManager snapshotManager; private List exportSettings; private Scheduler scheduler; private String[] channelDescriptions; public PulsCounterApplication(String[] args) { /* Initialize Logging Framework */ logStartup(); /* Check... */ if (_application != null){ throw new InstantiationError("Only one Instance of PulsCounterApplication can exist!"); } else { _application = this; } /* Initialize fields... */ uiIsFinished = false; uiSynchronization = new Object(); deviceConnectors = new ArrayList<>(); applicationListeners = new LinkedList(); unseenMessages = new Vector(); interfaceClasses = new ArrayList<>(); interfaces = new ArrayList<>(); /* Prepare for Startup */ loadApplicationConfiguration(); /* Parse Command Line Arguments */ Iterator options = Arrays.asList(args).iterator(); while (options.hasNext()){ String option = options.next(); switch (option){ case "--gui": if (!options.hasNext()){ log(FATAL,"Argument to --gui is missing"); throw new IllegalArgumentException("Argument to --gui is missing"); } else { applicationConfiguration.setProperty("ui.class", options.next()); } break; case "--batch": case "-B": applicationConfiguration.setProperty("ui.class", BatchRunner.class.getCanonicalName()); break; case "-G": applicationConfiguration.setProperty("ui.class", NewMainWindow.class.getCanonicalName()); break; default: log(WARN,"Unknown command line parameter: %s", option); } } /* Old stuff... */ // this.initialize(); } private void loadApplicationConfiguration(){ applicationConfiguration = new Properties(); /* Initialize default configuration */ applicationConfiguration.setProperty("ui.class", NewMainWindow.class.getCanonicalName()); applicationConfiguration.setProperty("interface.classes", StringHelper.join(new String[]{ ServiceLinkDeviceConnector.class.getCanonicalName(), SimulatedCounter.class.getCanonicalName() }, ",")); try { /* Try to load configuration from file */ FileInputStream fis = new FileInputStream("synololog.cfg"); applicationConfiguration.loadFromXML(fis); fis.close(); } catch (InvalidPropertiesFormatException e) { log(WARN,"synololog.cfg is misformated"); } catch (FileNotFoundException e) { log(WARN,"synololog.cfg not found"); } catch (IOException e) { log(ERROR,"I/O Error reading synololog.cfg"); } } public Properties getApplicationConfiguration(){ return this.applicationConfiguration; } private static void logStartup(){ log("Synololog Application Startup"); log("JAVA Environment: %s (%s)", System.getProperty("java.version"), System.getProperty("java.vendor")); log("Operating System: %s [%s] %s", System.getProperty("os.name"), System.getProperty("os.arch"), System.getProperty("os.version")); log("User Environment: %s (%s) (CWD:%s)", System.getProperty("user.name"), System.getProperty("user.home"), System.getProperty("user.dir")); log("Hostname: %s",Platform.getHostName()); log("OS Search Path: %s", System.getenv("PATH")); } public void start(){ initialize(); String uiClassName = applicationConfiguration.getProperty("ui.class"); try { Class uiClazz = PulsCounterApplication.class.getClassLoader().loadClass(uiClassName); Constructor constructor = uiClazz.getConstructor(PulsCounterApplication.class); Object ui = (Object) constructor.newInstance(this); } catch (ClassNotFoundException e) { log(FATAL,"user interface class could not be loaded [%s] %s",uiClassName,e.getMessage()); } catch (NoSuchMethodException e) { log(FATAL,"user interface class misses valid constructor [%s] %s",uiClassName,e.getMessage()); } catch (SecurityException e) { e.printStackTrace(); } catch (Exception e) { log(FATAL,"user interface class could not be instantiated. [%s] %s",uiClassName,e.getMessage()); e.printStackTrace(); } waitUiFinished(); try { shutdown(); } catch (Exception e){ log(e); } } private void initialize(){ String[] interfaceClassNames = applicationConfiguration.getProperty("interface.classes").split(","); for (String interfaceClassName: interfaceClassNames){ try { Class clazz = (Class)PulsCounterApplication.class.getClassLoader().loadClass(interfaceClassName); interfaceClasses.add(clazz); } catch (ClassNotFoundException e) { log(ERROR,"Interface class could not be loaded: %s",interfaceClassName); } } Integer nIntf = Integer.parseInt(applicationConfiguration.getProperty("interfaces.n","0")); for (int n=0;n clazz = getInterfaceClass(applicationConfiguration.getProperty(String.format("interfaces.%d.class",n))); addInterface(clazz, applicationConfiguration.getProperty(String.format("interfaces.%d.settings",n))); } } private void shutdown(){ log(INFO,"Application shutdown..."); /* Dispose all left frames */ for (Frame frame: JFrame.getFrames()){ frame.setVisible(false); frame.dispose(); } if (shouldSaveConfiguration){ applicationConfiguration.setProperty("interfaces.n", Integer.toString(interfaces.size())); for (int n=0;n> getInterfaceClasses(){ return this.interfaceClasses; } private Class getInterfaceClass(String className){ for (Class c:interfaceClasses){ if (c.getCanonicalName().equals(className)) return c; } return null; } /* Physical Interfaces */ public List getInterfaces(){ return this.interfaces; } public void addInterface(Class clazz,String connectionSettings){ try { IDeviceConnector idc = clazz.newInstance(); idc.setConnectionSettings(connectionSettings); interfaces.add(idc); fireinterfacesChanged(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } } public void removeInterface(IDeviceConnector intf){ interfaces.remove(intf); fireinterfacesChanged(); } private void fireinterfacesChanged(){ log(INFO,"interfaces changed"); for (PulsCounterApplicationListener l: applicationListeners){ l.interfacesChanged(this); } } /* ToDO: Upgrade the old stuff ... */ /* private void initialize(){ appSettingsListeners = new LinkedList(); exportSettings = new LinkedList(); scheduler = new Scheduler(); channelDescriptions = new String[32]; loadPrefs(); try { snapshotManager = new SnapshotManager(); snapshotManager.notify(Notification.INITIALIZE); } catch (FileNotFoundException e){ e.printStackTrace(); } } */ public void addAppSettingsListener(AppSettingsListener listener){ appSettingsListeners.add(listener); } public void removeAppSettingsListener(AppSettingsListener listener){ appSettingsListeners.remove(listener); } public void addPulsCounterApplicationListener(PulsCounterApplicationListener listener){ applicationListeners.add(listener); } public void removePulsCounterApplicationListener(PulsCounterApplicationListener listener){ applicationListeners.remove(listener); } public void fireServiceLinkChanged(){ for (AppSettingsListener l: appSettingsListeners){ l.ServiceLinkChanged(serviceLink); } } public void message(String message){ if (applicationListeners.size() == 0){ unseenMessages.addElement(message); } else { while (!unseenMessages.isEmpty()){ String msg = unseenMessages.remove(0); for (PulsCounterApplicationListener listener: applicationListeners){ listener.messageArrived(msg); } } for (PulsCounterApplicationListener listener: applicationListeners){ listener.messageArrived(message); } }; } public synchronized NewSerialPort getSerialPort() { if (serialPort == null){ serialPort = new NewSerialPort("COM1:"); } return serialPort; } public synchronized void setSerialPort(NewSerialPort serialPort) { if (serviceLink != null){ serviceLink.close(); serviceLink = null; } this.serialPort = serialPort; getServiceLink(); fireServiceLinkChanged(); } public synchronized ServiceLink getServiceLink() { if (serviceLink == null){ serviceLink = new ServiceLink(getSerialPort()); serviceLink.getSerialPort().setTimeOut(200); serviceLink.addServiceLinkListener(this); } return serviceLink; } public synchronized void setServiceLink(ServiceLink serviceLink) { if (serviceLink != null){ serviceLink.close(); } this.serviceLink = serviceLink; fireServiceLinkChanged(); } private Preferences getPreferencesNode(){ return Preferences.userNodeForPackage(getClass()); } public void savePrefs(){ Preferences prefs = getPreferencesNode(); if (serialPort != null) prefs.put("io.port", getSerialPort().getPortName()); System.out.println(String.format("savePrefs(): %d exportSettings werden gesichert.", exportSettings.size())); if (exportSettings.size()>0) { for (int n=0;n getExportSettings() { return exportSettings; } }