package com.isti.traceview.common; import java.io.File; import java.util.HashSet; import java.util.Observable; import java.util.Set; import java.util.StringTokenizer; import org.apache.log4j.Logger; import com.isti.traceview.TraceViewException; import com.isti.traceview.gui.ColorModeBySegment; import com.isti.traceview.gui.IColorModeState; import com.isti.traceview.gui.IScaleModeState; import com.isti.traceview.gui.ScaleModeAuto; import com.isti.traceview.gui.ScaleModeCom; import com.isti.traceview.gui.ScaleModeXhair; import edu.iris.dmc.seedcodec.B1000Types; /** * <p> * This class holds configuration data. Concrete realizations can add parameters and should define * method of initialization (reading configuration file, defaults, by command line options etc) * </p> * <p> * Extends {@link Observable} interface, i.e this class can report to listeners about configuration * changes * </p> * * @author Max Kokoulin */ public class Configuration extends Observable { private static final Logger logger = Logger.getLogger(Configuration.class); private String default_pattern_html = "<html><head><title>HTML report</title></head><body><h1>HTML report</h1> </body></html>"; protected static String listSeparator = ","; public Configuration() throws TraceViewException { setPanelCountUnit(PanelCountUnit.TRACE); setUnitsInFrame(20); setPanelOrder(ChannelSortType.TRACENAME); } /** * Enumeration for panel count units, we can define how many of this units we want to see on * graph panel */ public enum PanelCountUnit { /** * unit is one trace */ TRACE, /** * unit is one station */ STATION, /** * unit is one channel, with all locations */ CHANNEL, /** * Channel type is last character of channel. */ CHANNEL_TYPE, /** * All available data in one screen */ ALL } /** * Enumeration for channel sort type. Note that not all combinations of show * units and sorting options are permitted. For example, we can't show * stations and have a list sorted by channels */ public enum ChannelSortType { /** * Trace name is what you see on a plot, i.e * network/station/location/channel. See * {@link com.isti.traceview.data.NameComparator} for details */ TRACENAME, /** * Network - station - sample rate - location code -channel type order */ NETWORK_STATION_SAMPLERATE, /** * Really Channel - network - station - location order See * {@link com.isti.traceview.data.ChannelComparator} for details */ CHANNEL, /** * Channel type is last character of channel name. Channel type - * channel - network - station order. * @see com.isti.traceview.data.ChannelTypeComparator */ CHANNEL_TYPE, /** * Sorting by channel's events See * {@link com.isti.traceview.data.EventComparator} for details */ EVENT } /** * Name of configuration file */ public static String confFileName = "config.xml"; /** * Wildcarded mask of datafiles to search on startup */ private String dataPath = ""; private PanelCountUnit panelCountUnit; /** * Quantity of visible units on the screen, see {@link PanelCountUnit}. Correspond -f command * line option. */ private int unitsInFrame; /** * Order to sort traces to show, see {@link ChannelSortType} for options list. * Correspond -o command line option. */ private ChannelSortType panelOrder; /** * Flag to indicate if enabled mode for placing all locations for given channel in one graph * panel */ private boolean merge_locations = false; /** * Location of temporary data storage */ private String dataTempPath = ""; /** * Full pathname for stations definition file */ private String stationInfoFileName = ""; /** * Flag if we expect several channels in raw data provider. */ private boolean allowMultiplexedData = false; /** * Location of responses storage. */ private String responsePath; /** * Current scale mode */ private IScaleModeState scaleMode = new ScaleModeAuto(); /** * flag if we use color to draw graphs */ private IColorModeState colorModeState = new ColorModeBySegment(); /** * flag if we show big crosshair cursor or use ordinary cursor */ private boolean showBigCursor = false; /** * this values we use in mseed decompression the case of absence of blockette 1000 */ private int defaultCompression = B1000Types.STEIM1; /** * this values we use in mseed decompression the case of absence of blockette 1000 */ private int defaultBlockLength = 4096; private boolean useTempData = false; private boolean useDataPath = false; /** * If dumpData = true then we are in -T mode **/ private boolean dumpData = false; private Set<String> filterStation = null; private Set<String> filterNetwork = null; private Set<String> filterChannel = null; private Set<String> filterLocation = null; /** * Getter of the property <tt>dataPath</tt> * * @return wildcarded mask of datafiles to search on startup. */ public String getDataPath() { // MTH: The line below will take xmax -d '../xs0/seed/..' and turn it into path="./Users/mth/mth/../xs0/seed/.." ! //String ret = dataPath.replace("." + File.separator, getConfigFileDir()); //lg.debug("Configuration.getDataPath(): " + ret); //return ret; return dataPath; } /** * Setter of the property <tt>dataPath</tt> * * @param dataPath * The dataPath to set. */ public void setDataPath(String dataPath) { logger.debug("== dataPath: " + dataPath); this.dataPath = dataPath; } /** * Getter of the property <tt>dataTempPath</tt> * * @return location of temporary data storage. */ public String getDataTempPath() { return dataTempPath.replace("." + File.separator, getConfigFileDir()); } /** * Setter of the property <tt>dataTempPath</tt> * * @param dataTempPath * location of temporary data storage */ public void setDataTempPath(String dataTempPath) { this.dataTempPath = dataTempPath; } /** * Setter of the property <tt>allowMultiplexedData</tt> * * @param allowMultiplexedData * flag if we expect several channels in raw data provider. */ public void setAllowMultiplexedData(boolean allowMultiplexedData) { this.allowMultiplexedData = allowMultiplexedData; } /** * Getter of the property <tt>allowMultiplexedData</tt> * * @return flag if we expect several channels in raw data provider. */ public boolean isAllowMultiplexedData() { return allowMultiplexedData; } /** * Getter of the property <tt>stationInfoFileName</tt> * * @return full pathname for stations definition file. */ public String getStationInfoFileName() { return stationInfoFileName.replace("." + File.separator, getConfigFileDir()); } /** * Setter of the property <tt>stationInfoFileName</tt> * * @param stationInfoFileName * The stationInfoFileName to set. */ public void setStationInfoFileName(String stationInfoFileName) { this.stationInfoFileName = stationInfoFileName; } /** * Getter of the property <tt>unitsInFrame</tt> * * @return quantity of visible units on the screen, see {@link PanelCountUnit}. Correspond -f * command line option. */ public int getUnitsInFrame() { return unitsInFrame; } /** * Setter of the property <tt>unitsInFrame</tt> * * @param unitsInFrame * The unitsInFrame to set. */ public void setUnitsInFrame(int unitsInFrame) { this.unitsInFrame = unitsInFrame; } /** * Getter of the property <tt>panelCountUnit</tt> * * @return current panel count unit, * @see PanelCountUnit to reference. */ public PanelCountUnit getPanelCountUnit() { return panelCountUnit; } /** * Setter of the property <tt>panelCountUnit</tt> * * @param panelCountUnit * The panelCountUnit to set. */ public void setPanelCountUnit(PanelCountUnit panelCountUnit) { this.panelCountUnit = panelCountUnit; try { if (panelCountUnit == PanelCountUnit.STATION) { setPanelOrder(ChannelSortType.NETWORK_STATION_SAMPLERATE); } else if (panelCountUnit == PanelCountUnit.CHANNEL_TYPE) { setPanelOrder(ChannelSortType.CHANNEL_TYPE); } else if (panelCountUnit == PanelCountUnit.CHANNEL) { setPanelOrder(ChannelSortType.CHANNEL); } } catch (TraceViewException e) { // do nothing, all should be correct logger.error("TraceViewException:", e); } } /** * If true, we will load channel with the same location code in the one graph panel * * @return flag to indicate if enabled mode for placing all locations for given channel in one * graph panel */ public boolean getMergeLocations() { return merge_locations; } public void setMergeLocations(boolean merge) { this.merge_locations = merge; } /** * Getter of the property panelOrder * * @return order to sort traces to show, see {@link ChannelSortType} for options list. */ public ChannelSortType getPanelOrder() { return panelOrder; } /** * Setter of the property <tt>panelOrder</tt> * * @param po * The panelOrder to set. */ public void setPanelOrder(ChannelSortType po) throws TraceViewException { if (panelCountUnit == PanelCountUnit.STATION && !((po == ChannelSortType.TRACENAME) || (po == ChannelSortType.NETWORK_STATION_SAMPLERATE))) { throw new TraceViewException("Wrong display sorting option for display unit STATION"); } else if (panelCountUnit == PanelCountUnit.CHANNEL_TYPE && (po != ChannelSortType.CHANNEL_TYPE)) { throw new TraceViewException("Wrong display sorting option for display unit CHANNEL_TYPE"); } else if (panelCountUnit == PanelCountUnit.CHANNEL && (po != ChannelSortType.CHANNEL)) { throw new TraceViewException("Wrong display sorting option for display unit CHANNEL"); } if (this.getMergeLocations() && po != ChannelSortType.CHANNEL) { throw new TraceViewException("Wrong sorting option for locations merge mode, should be CHANNEL"); } this.panelOrder = po; } /* * public Set<String> getStationNames() { return stations.keySet(); } public Set<String> * getChannelNames(String stationName) { return stations.get(stationName).getChannelNames(); } * public List<String> getSelectedChannelNames(String stationName) { return null; } public Date * getChannelBegin(String channelName) { return null; } public Date getChannelEnd(String * channelName) { return null; } */ /** * @return current scale mode */ public IScaleModeState getScaleMode() { return scaleMode; } /** * Setter of scale mode * * @param sm * scale mode to set */ public void setScaleMode(IScaleModeState sm) { this.scaleMode = sm; setChanged(); notifyObservers(sm); } /** * Setter of scale mode * * @param str * scale mode to set - as string */ public void setScaleMode(String str) { if (str != null) { if (str.equals("AUTO")) { this.scaleMode = new ScaleModeAuto(); } else if (str.equals("COM")) { this.scaleMode = new ScaleModeCom(); } else if (str.equals("XHAIR")) { this.scaleMode = new ScaleModeXhair(); } setChanged(); notifyObservers(this.scaleMode); } } /** * Getter of the property <tt>useColor</tt> * * @return flag if we use color to draw graphs */ public IColorModeState getColorModeState() { return colorModeState; } public void setColorModeState(IColorModeState uc) { this.colorModeState = uc; } /** * Getter of the property <tt>responsePath</tt> * * @return location of responses storage. */ public String getResponsePath() { return responsePath.replace("." + File.separator, getConfigFileDir()); } /** * Setter of the property <tt>responsePath</tt> * * @param responsePath * The ResponsePath to set. */ public void setResponsePath(String responsePath) { this.responsePath = responsePath; } /** * Getter of the property <tt>showBigCursor</tt> * * @return flag if we show big crosshair cursor or use ordinary cursor */ public boolean getShowBigCursor() { return showBigCursor; } public void setShowBigCursor(boolean sbc) { this.showBigCursor = sbc; } /** * Setter of property defaultCompression. * * @param defaultCompressionStr * string name of compression type * @throws TraceViewException * in case of unsupported compression name */ public void setDefaultCompression(String defaultCompressionStr) throws TraceViewException { if (defaultCompressionStr.equals("ASCII")) { setDefaultCompression(B1000Types.ASCII); } else if (defaultCompressionStr.equals("SHORT")) { setDefaultCompression(B1000Types.SHORT); } else if (defaultCompressionStr.equals("INT24")) { setDefaultCompression(B1000Types.INT24); } else if (defaultCompressionStr.equals("INT32")) { setDefaultCompression(B1000Types.INTEGER); } else if (defaultCompressionStr.equals("FLOAT")) { setDefaultCompression(B1000Types.FLOAT); } else if (defaultCompressionStr.equals("DOUBLE")) { setDefaultCompression(B1000Types.DOUBLE); } else if (defaultCompressionStr.equals("STEIM1")) { setDefaultCompression(B1000Types.STEIM1); } else if (defaultCompressionStr.equals("STEIM2")) { setDefaultCompression(B1000Types.STEIM2); } else if (defaultCompressionStr.equals("CDSN")) { setDefaultCompression(B1000Types.CDSN); } else if (defaultCompressionStr.equals("RSTN")) { setDefaultCompression(B1000Types.CDSN); } else if (defaultCompressionStr.equals("DWW")) { setDefaultCompression(B1000Types.DWWSSN); } else if (defaultCompressionStr.equals("SRO")) { setDefaultCompression(B1000Types.SRO); } else if (defaultCompressionStr.equals("ASRO")) { setDefaultCompression(B1000Types.SRO); } else if (defaultCompressionStr.equals("HGLP")) { setDefaultCompression(B1000Types.SRO); } else { throw new TraceViewException("Unsupported compression type: '" + defaultCompressionStr + "'"); } } /** * Setter of property defaultCompression. For compression types list see {@link B1000Types} */ public void setDefaultCompression(int defaultCompression) { this.defaultCompression = defaultCompression; } /** * For compression types list see {@link B1000Types} * * @return compression type used in mseed decompression the case of absence of blockette 1000 */ public int getDefaultCompression() { return defaultCompression; } public void setDefaultBlockLength(int defaultBlockLength) { this.defaultBlockLength = defaultBlockLength; } /** * Getter of property defaultBlockLength. * * @return block length used in mseed decompression the case of absence of blockette 1000 */ public int getDefaultBlockLength() { return defaultBlockLength; } /** * Getter of the property <tt>useTempData</tt> * * @return Returns flag if we should load content of temporary storage */ public boolean getUseTempData() { return useTempData; } /** * Setter of the property <tt>useTempData</tt> * * @param useTempData * flag if we should load content of temporary storage */ public void setUseTempData(boolean useTempData) { this.useTempData = useTempData; } /** * MTH: Added useDataPath so we can know if user entered "-d dataPath" * on the command line in. * If -t was also entered, then we want to try to load data * from both locations (dataPath + TempData) */ public boolean getUseDataPath() { return useDataPath; } public void setUseDataPath(boolean useDataPath) { this.useDataPath = useDataPath; } public boolean getDumpData() { return dumpData; } public void setDumpData(boolean dumpData) { this.dumpData = dumpData; } /** * Setter of station filter * * @param filtStr * comma-separated list of stations */ public void setFilterStation(String filtStr) { if (filtStr == null || filtStr.equals("")) { filterStation = null; } else { filterStation = new HashSet<String>(); fillFilter(filterStation, filtStr); } } /** * Getter of station filter * * @return set of station names */ public Set<String> getFilterStation() { return filterStation; } /** * Setter of network filter * * @param filtStr * comma-separated list of networks */ public void setFilterNetwork(String filtStr) { if (filtStr == null || filtStr.equals("")) { filterNetwork = null; } else { filterNetwork = new HashSet<String>(); fillFilter(filterNetwork, filtStr); } } /** * Getter of network filter * * @return set of network names */ public Set<String> getFilterNetwork() { return filterNetwork; } /** * Setter of channel filter * * @param filtStr * comma-separated list of channels */ public void setFilterChannel(String filtStr) { if (filtStr == null || filtStr.equals("")) { filterChannel = null; } else { filterChannel = new HashSet<String>(); fillFilter(filterChannel, filtStr); } } /** * Getter of channel filter * * @return set of channel names */ public Set<String> getFilterChannel() { return filterChannel; } /** * Setter of location filter * * @param filtStr * comma-separated list of locations */ public void setFilterLocation(String filtStr) { if (filtStr == null || filtStr.equals("")) { filterLocation = null; } else { filterLocation = new HashSet<String>(); fillFilter(filterLocation, filtStr); } } /** * Getter of location filter * * @return set of location names */ public Set<String> getFilterLocation() { return filterLocation; } private static void fillFilter(Set<String> filter, String filtStr) { StringTokenizer st = new StringTokenizer(filtStr, listSeparator); while (st.hasMoreTokens()) { filter.add(st.nextToken()); } } public void setDefaultHTMLPattern(String pattern) { default_pattern_html = pattern; } /** * @return html code which placed in the beginning of every printed report */ public String getDefaultHTMLPattern() { return default_pattern_html; } /** * @return directory where current configuration file placed */ public String getConfigFileDir() { File confFile = new File(confFileName); String ret = confFile.getAbsolutePath().substring(0, confFile.getAbsolutePath().lastIndexOf(confFile.getName())); logger.debug("== fileDir: " + ret); return ret; } }