/* * ALMA - Atacama Large Millimiter Array (c) European Southern Observatory, 2012 * * 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.alarm.gui.senderpanel; import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import javax.swing.JFileChooser; import alma.acs.container.ContainerServices; /** * Send the alarms read from a file by extending {@link BaseAlarmsSender}. * <P> * <EM>Format of the file of alarms.</EM><BR> * The file has one line for each alarm with the format triplet properties. * * Where: * <UL> * <LI> triplet is <CODE>FaultFamily,FaultMember,FaultCode</CODE> * <LI> properties is a list of key=value: <CODE>key1=value1, key2=value2,...</CODE> * </UL> * The properties string is optional. * <BR>Comments starts with a '#' character. * * @author acaproni */ public class FileSender extends BaseAlarmsSender { /** * The start of a comment */ private static final String commentMarker ="#"; /** * The name of the file selected by the user */ private String fileName=null; /** * The file selected by the user (can be <code>null</code>) */ private File selectedFile=null; /** * Constructor * * @param parent the parent component of the dialog * @param contSvcs The ContainerServices * @param sender The object to send alarms */ public FileSender(SenderPanel parent,ContainerServices contSvcs, ParallelAlarmSender sender) { super(parent, contSvcs, sender,FileSender.class.getName()+"_"); } /** * Select the file of alarms offering a dialog to the user. * <P> * {@link #selectFile()} does not check if the content of the file is well * formed but checks if it is readable. * * @return The name of the file or * <code>null</code> if the file is not readable */ public synchronized String selectFile() { JFileChooser fileChooser = new JFileChooser(); if (fileChooser.showOpenDialog(panel)==JFileChooser.APPROVE_OPTION) { selectedFile=fileChooser.getSelectedFile(); } else if (fileChooser.showOpenDialog(panel)==JFileChooser.CANCEL_OPTION) { return fileName; } else { selectedFile=null; } if (selectedFile!=null && selectedFile.canRead() ) { fileName=selectedFile.getName(); } else { fileName=null; } try { buildAlarmsFromFile(); } catch (Throwable t) { t.printStackTrace(); } finally { notifyAlarmsRead(); // Dump the alarms in the stdout. It is more for debugging but can be // useful while testing to let the user knows what to expect dumpAlarms(); } return fileName; } /** * * @return The name of the file selected by the user (can be <code>null</code>) */ public synchronized String getFileName() { return fileName; } /** * Read the alarms from the file selected by the user. * <P> * The alarms read from the file are stored in memory ready to be sent * when the user presses one of the control buttons of the panel. * * @throws Exception in case of error reading the file */ private void buildAlarmsFromFile() throws Exception { alarms.clear(); if (selectedFile==null) { return; } FileReader fReader = new FileReader(selectedFile); BufferedReader reader = new BufferedReader(fReader); String strLine; while ((strLine = reader.readLine()) != null) { // Print the content on the console parseLine(strLine.trim()); } } /** * Build an alarm from the passed line. * * @param line The line read from the file * @return The alarm defined in the line or <code>null</code> * if the line does not define an alarm */ private AlarmRead parseLine(String line) { if (line==null || line.isEmpty()) { return null; } // Remove comments String str=removeComment(line).trim(); boolean isAlarm=SenderPanelUtils.isAnAlarm(str); if (isAlarm) { String[] parts=SenderPanelUtils.propertyRegExp.split(str); String theTriplet=parts[0]; parts = SenderPanelUtils.alarmRegExp.split(str); String theProperties=str.substring(theTriplet.length()).trim(); try { alarms.add(new AlarmRead(theTriplet, theProperties)); } catch (Throwable t) { System.out.println("Alarm discarded. Triplet = "+theTriplet+", Properties="+theProperties); System.out.println("\tTriplet and properties have been generated by parsing ["+str+"]"); t.printStackTrace(); } } else { if (!str.isEmpty()) { System.out.println("["+str+"] discarded. Is it a malformed alarm?"); } } return null; } /** * Return a copy of the passed string without comments. * <P> * A comment starts with {@value #commentMarker} and terminates at the end of the line * * @param str The string to check * @return The string without comments */ private String removeComment(String str) { if (str==null) { throw new IllegalArgumentException("A null String is invalid"); } int pos = str.indexOf(commentMarker); if (pos==-1) { // No comment in the string return str; } if (pos==0) { return ""; } return str.substring(0,pos).trim(); } }