All Downloads are FREE. Search and download functionalities are using the official Maven repository.

decodes.dbeditor.RoutingSpecEditPanel Maven / Gradle / Ivy

Go to download

A collection of software for aggregatting and processing environmental data such as from NOAA GOES satellites.

The newest version!
/*
 *  $Id$
 */
package decodes.dbeditor;

import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.io.StringReader;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Properties;
import java.util.ResourceBundle;

import javax.swing.JCheckBox;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;

import org.slf4j.LoggerFactory;

import ilex.gui.Help;
import lrgs.common.DcpAddress;
import lrgs.common.DcpMsgFlag;
import lrgs.common.SearchCriteria;
import lrgs.gui.SearchCriteriaEditPanel;

import ilex.util.LoadResourceBundle;
import ilex.util.Logger;
import ilex.util.PropertiesUtil;
import ilex.util.TextUtil;

import decodes.consumer.DataConsumer;
import decodes.consumer.OutputFormatter;
import decodes.datasource.DataSourceExec;
import decodes.datasource.HotBackupGroup;
import decodes.datasource.LrgsDataSource;
import decodes.db.Constants;
import decodes.db.DataSource;
import decodes.db.Database;
import decodes.db.DatabaseException;
import decodes.db.InvalidDatabaseException;
import decodes.db.RoutingSpec;
import decodes.dbeditor.routing.RSListTableModel;
import decodes.gui.EnumComboBox;
import decodes.gui.PropertiesEditPanel;
import decodes.util.PropertiesOwner;
import decodes.util.PropertySpec;

/**
 * This panel edits an open routing spec. Opened from the RoutingSpecListPanel.
 */
@SuppressWarnings("serial")
public class RoutingSpecEditPanel 
	extends DbEditorTab 
	implements ChangeTracker, EntityOpsController, PropertiesOwner
{
	private static final org.slf4j.Logger log = LoggerFactory.getLogger(RoutingSpecEditPanel.class);
	static ResourceBundle genericLabels = DbEditorFrame.getGenericLabels();
	static ResourceBundle dbeditLabels = DbEditorFrame.getDbeditLabels();

	private EntityOpsPanel entityOpsPanel = new EntityOpsPanel(this);
	private PropertiesEditPanel propertiesEditPanel = PropertiesEditPanel.from(new Properties());
	private SearchCriteriaEditPanel scEditPanel = new SearchCriteriaEditPanel();
	private JTextField nameField = new JTextField();
	private JLabel consumerArgLabel = new JLabel();
	private JTextField consumerArgsField = new JTextField();
	private EnumComboBox outputFormatCombo = new EnumComboBox(Constants.enum_OutputFormat);
	private EnumComboBox consumerTypeCombo = new EnumComboBox(Constants.enum_DataConsumer);
	private JCheckBox enableEquationsCheck = new JCheckBox();
	private DataSourceCombo dataSourceCombo = new DataSourceCombo();
	private TimeZoneSelector outputTimezoneCombo = new TimeZoneSelector();
	private PresentationGroupCombo presentationGroupCombo = new PresentationGroupCombo();
	private JCheckBox productionCheck = new JCheckBox();
	private JPanel paramPanel = new JPanel(new GridBagLayout());


	private DbEditorFrame parent = null;
	private RoutingSpec theObject, origObject;
	private DataSource selectedDataSource = null;
	private DataConsumer selectedConsumer = null;
	private OutputFormatter selectedFormatter = null;
	private Properties editProps = new Properties();


	private static PropertySpec rsPropSpecs[] = 
	{
		// Properties implemented directly by RoutingSpecThread:
		new PropertySpec("noLimits", PropertySpec.BOOLEAN,
			"Do NOT Apply Sensor min/max limits."),
		new PropertySpec("removeRedundantData", PropertySpec.BOOLEAN,
			"Remove Redundant DCP Message Data."),
		new PropertySpec("compConfig", PropertySpec.FILENAME,
			"Name of in-line computations config file"),
		new PropertySpec("usgsSummaryFile", PropertySpec.FILENAME,
			"Optional USGS-Format Summary File"),
		new PropertySpec("RawArchivePath", PropertySpec.STRING, 
			"Path to raw archive file. Defining this turns on the raw-archive function. " +
			"Example: $DCSTOOL_HOME/raw-archive/fts/$DATE(yyMMdd).fts"),
		new PropertySpec("RawArchiveStartDelim", PropertySpec.STRING, 
			"String placed before each message in the file"),
		new PropertySpec("RawArchiveEndDelim", PropertySpec.STRING, 
			"String placed after each message in the file"),
		new PropertySpec("RawArchiveMaxAge", PropertySpec.STRING, 
			"Example: '1 year'. Files older than this are deleted."),
		new PropertySpec("debugLevel", PropertySpec.INT,
			"(default=0) Set to 1, 2, 3 for increasing levels of debug information" +
			" when this routing spec is run."),
		new PropertySpec("updatePlatformStatus", PropertySpec.BOOLEAN,
			"(default=true) set to false to NOT update platform status records as messages are processed."),
		new PropertySpec("purgeOldEvents", PropertySpec.BOOLEAN,
			"(default=true) Set to false to tell this routing spec to NOT attempt to "
			+ "purge expired events from the database. Also see DecodesSettings.eventPurgeDays")
	};
	
	private PropertySpec combinedProps[] = rsPropSpecs;


	/**
	 * Construct new panel to edit specified object.
	 * @param ob the object to edit in this panel.
	 */
	public RoutingSpecEditPanel(RoutingSpec ob)
	{
		origObject = ob;
		theObject = origObject.copy();
		setTopObject(origObject);

		try
		{
			guiInit();
			fillFields();
		}
		catch (Exception ex)
		{
			ex.printStackTrace();
		}
	}

	/**
	 * This method only called in dbedit. Associates this panel with enclosing
	 * frame.
	 * 
	 * @param parent
	 *            Enclosing frame
	 */
	void setParent(DbEditorFrame parent)
	{
		Logger.instance().debug3("RoutingSpecEditPanel.setParent("
			+ (parent == null ? "NULL" : "") + ")");
		this.parent = parent;
		scEditPanel.setTopFrame(parent);
	}

	/** Fills the GUI controls with values from the object. */
	private void fillFields()
	{
		nameField.setText(theObject.getName());
		if (theObject.dataSource != null && theObject.dataSource.getName() != null)
			dataSourceCombo.setSelection(theObject.dataSource.getName());

		if (theObject.consumerType != null)
			consumerTypeCombo.setSelection(theObject.consumerType);
		if (theObject.consumerArg != null)
			consumerArgsField.setText(theObject.consumerArg);
		
		productionCheck.setSelected(theObject.isProduction);
		enableEquationsCheck.setSelected(theObject.enableEquations);

		if (theObject.outputFormat != null)
			outputFormatCombo.setSelection(theObject.outputFormat);
		if (theObject.outputTimeZoneAbbr != null)
			outputTimezoneCombo.setTZ(theObject.outputTimeZoneAbbr);
		
		if (theObject.presentationGroupName != null)
			presentationGroupCombo.setSelection(theObject.presentationGroupName);

		// Map sinceTime, untilTime, netlists, and properties into searchcrit object.
		StringBuilder scString = new StringBuilder();
		editProps.clear();
		PropertiesUtil.copyProps(editProps, theObject.getProperties());
		String timeApplyTo = PropertiesUtil.getIgnoreCase(theObject.getProperties(), "rs.timeApplyTo");
		if (timeApplyTo == null)
			timeApplyTo = "l"; // default to local
		if (theObject.sinceTime != null && theObject.sinceTime.trim().length() > 0)
		{
			if (timeApplyTo.equalsIgnoreCase("l") || timeApplyTo.equalsIgnoreCase("b"))
				scString.append("LRGS_SINCE: " + theObject.sinceTime + "\n");
			if (timeApplyTo.equalsIgnoreCase("m") || timeApplyTo.equalsIgnoreCase("b"))
				scString.append("DAPS_SINCE: " + theObject.sinceTime + "\n");
		}
		if (theObject.untilTime != null && theObject.untilTime.trim().length() > 0)
		{
			if (timeApplyTo.equalsIgnoreCase("l") || timeApplyTo.equalsIgnoreCase("b"))
				scString.append("LRGS_UNTIL: " + theObject.untilTime + "\n");
			if (timeApplyTo.equalsIgnoreCase("m") || timeApplyTo.equalsIgnoreCase("b"))
				scString.append("DAPS_UNTIL: " + theObject.untilTime + "\n");
		}
		PropertiesUtil.rmIgnoreCase(editProps, "rs.timeApplyTo");
		for(String nlName : theObject.networkListNames)
			scString.append("NETWORKLIST: " + nlName + "\n");

		for(Object key : theObject.getProperties().keySet())
		{
			String propName = (String)key;
			if (TextUtil.startsWithIgnoreCase(propName, "sc:CHANNEL"))
				scString.append("CHANNEL: " + editProps.getProperty(propName) + "\n");
			else if (propName.equalsIgnoreCase("sc:DAPS_STATUS"))
				scString.append("DAPS_STATUS: " + editProps.getProperty(propName) + "\n");
			else if (TextUtil.startsWithIgnoreCase(propName, "sc:DCP_ADDRESS"))
				scString.append("DCP_ADDRESS: " + editProps.getProperty(propName) + "\n");
			else if (TextUtil.startsWithIgnoreCase(propName, "sc:DCP_NAME"))
				scString.append("DCP_NAME: " + editProps.getProperty(propName) + "\n");
			else if (propName.equalsIgnoreCase("sc:SPACECRAFT"))
				scString.append("SPACECRAFT: " + editProps.getProperty(propName) + "\n");
			else if (TextUtil.startsWithIgnoreCase(propName, "sc:SOURCE"))
				scString.append("SOURCE: " + editProps.getProperty(propName) + "\n");
			else if (propName.equalsIgnoreCase("sc:PARITY_ERROR"))
				scString.append("PARITY_ERROR: " + editProps.getProperty(propName) + "\n");
			else if (propName.equalsIgnoreCase("sc:ASCENDING_TIME"))
				scString.append("ASCENDING_TIME: " + editProps.getProperty(propName) + "\n");
			else if (propName.equalsIgnoreCase("sc:RT_SETTLE_DELAY"))
				scString.append("RT_SETTLE_DELAY: " + editProps.getProperty(propName) + "\n");
			else
				continue; // without removing the propname from editProps!
			PropertiesUtil.rmIgnoreCase(editProps, propName);
		}
		try
		{
			SearchCriteria searchcrit = new SearchCriteria();
			searchcrit.parseFile(new StringReader(scString.toString()));
			scEditPanel.setSearchCrit(searchcrit);
		}
		catch (Exception ex)
		{
			Logger.instance().warning("Cannot parse searchcrit: " + ex);
			Logger.instance().warning("searchcrit image was: \n" + scString.toString());
		}

		// Now the properties edit panel will edit the props with the SC stuff removed.
		dataSourceSelected();
		consumerTypeSelected();
		outputFormatSelected();

		propertiesEditPanel.getModel().setProperties(editProps);
		propertiesEditPanel.getModel().setPropertiesOwner(this);
	}

	/**
	 * Gets the data from the fields & puts it back into the object.
	 */
	private void getDataFromFields()
	{
		theObject.dataSource = dataSourceCombo.getSelection();
		theObject.consumerType = consumerTypeCombo.getSelection();
		theObject.consumerArg = consumerArgsField.getText().trim();
		if (theObject.consumerArg.length() == 0)
			theObject.consumerArg = null;
		theObject.isProduction = productionCheck.isSelected();
		theObject.enableEquations = enableEquationsCheck.isSelected();
		theObject.outputFormat = outputFormatCombo.getSelection();
		theObject.outputTimeZoneAbbr = outputTimezoneCombo.getTZ();
		theObject.presentationGroupName = 
			presentationGroupCombo.getSelectedIndex() == 0 ? null :
				(String)presentationGroupCombo.getSelectedItem();

		// Get the properties
		propertiesEditPanel.getModel().saveChanges(); // saves to editProps
		
		theObject.getProperties().clear();
		PropertiesUtil.copyProps(theObject.getProperties(), editProps);
		SearchCriteria sc = new SearchCriteria();
		scEditPanel.fillSearchCrit(sc);

		String timeApplyTo = "l";
		if ((theObject.sinceTime = sc.getLrgsSince()) != null) // LRGS since time specified
		{
			if (sc.getDapsSince() != null) // Daps Since also specified
				timeApplyTo = "b";
			else // only LRGS since time specified 
				timeApplyTo = "l";
		}
		else if ((theObject.sinceTime = sc.getDapsSince()) != null)
			timeApplyTo = "m";
		
		theObject.untilTime = sc.getLrgsUntil();
		if (theObject.untilTime == null)
			theObject.untilTime = sc.getDapsUntil();
		
		theObject.networkListNames.clear();
		theObject.networkLists.clear();
		theObject.getProperties().setProperty("rs.timeApplyTo", timeApplyTo);
		for(String nln : sc.NetlistFiles)
		{
Logger.instance().debug3("Added netlist name '" + nln + "'");
			theObject.networkListNames.add(nln);
		}
		
		NumberFormat nf = NumberFormat.getIntegerInstance();
		nf.setMinimumIntegerDigits(4);
		nf.setGroupingUsed(false);
		for(int i=0; sc.channels != null && i < sc.channels.length; i++)
			theObject.getProperties().setProperty("sc:CHANNEL_" + nf.format(i), "|"+sc.channels[i]);

		int i=0;
		for(DcpAddress addr : sc.ExplicitDcpAddrs)
			theObject.getProperties().setProperty("sc:DCP_ADDRESS_" + nf.format(i++), addr.toString());
		i=0;
		for(String nm : sc.DcpNames)
			theObject.getProperties().setProperty("sc:DCP_NAME_" + nf.format(i++), nm);

		i = 0;
		for(int idx = 0; idx < sc.sources.length; idx++)
			if (sc.sources[idx] != 0)
				theObject.getProperties().setProperty("sc:SOURCE_" + nf.format(i++),
					DcpMsgFlag.sourceValue2Name(sc.sources[idx]));
		
		if (sc.DapsStatus != SearchCriteria.UNSPECIFIED)
			theObject.getProperties().setProperty("sc:DAPS_STATUS", "" + sc.DapsStatus);
		if (sc.spacecraft != SearchCriteria.SC_ANY)
			theObject.getProperties().setProperty("sc:SPACECRAFT", "" + sc.spacecraft);
		if (sc.parityErrors != SearchCriteria.ACCEPT)
			theObject.getProperties().setProperty("sc:PARITY_ERROR", "" + sc.parityErrors);
		if (sc.getAscendingTimeOnly())
			theObject.getProperties().setProperty("sc:ASCENDING_TIME", "true");
		if (sc.getRealtimeSettlingDelay())
			theObject.getProperties().setProperty("sc:RT_SETTLE_DELAY", "true");
	}

	/** Initializes GUI components */
	private void guiInit() throws Exception
	{
		this.setLayout(new BorderLayout());
		this.add(entityOpsPanel, BorderLayout.SOUTH);
		JPanel rsPanel = new JPanel(new GridBagLayout());
		this.add(rsPanel, BorderLayout.CENTER);
		scEditPanel.setTopFrame(parent);
		scEditPanel.setAllowRealTime(true);
		
		rsPanel.add(paramPanel,
			new GridBagConstraints(0, 0, 1, 1, 0.0, 0.5,
			GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, 
			new Insets(4, 4, 4, 4), 0, 0));
		propertiesEditPanel.setOwnerFrame(parent);
		rsPanel.add(propertiesEditPanel,
			new GridBagConstraints(1, 0, 1, 1, 1.0, 0.5,
			GridBagConstraints.CENTER, GridBagConstraints.BOTH, 
			new Insets(4, 4, 4, 4), 0, 0));
		rsPanel.add(scEditPanel,
			new GridBagConstraints(0, 1, 2, 1, 1.0, 0.5,
			GridBagConstraints.CENTER, GridBagConstraints.BOTH, 
			new Insets(4, 4, 4, 4), 0, 0));

		paramPanel.add(new JLabel(genericLabels.getString("nameLabel")),
			new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0, 
				GridBagConstraints.EAST, GridBagConstraints.NONE, 
				new Insets(2, 4, 1, 2), 0, 0));
		nameField.setEditable(false);
		paramPanel.add(nameField, 
			new GridBagConstraints(1, 0, 1, 1, 0.0, 0.0,
				GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, 
				new Insets(2, 0, 1, 10), 0, 0));
	
		paramPanel.add(new JLabel(dbeditLabels.getString("RoutingSpecEditPanel.dataSource")),
			new GridBagConstraints(0, 1, 1, 1, 0.0, 0.0, 
				GridBagConstraints.EAST, GridBagConstraints.NONE, 
				new Insets(1, 4, 1, 2), 0, 0));
		paramPanel.add(dataSourceCombo, 
			new GridBagConstraints(1, 1, 1, 1, 0.0, 0.0,
				GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, 
				new Insets(1, 0, 1, 10), 0, 0));
		dataSourceCombo.addActionListener(
			new java.awt.event.ActionListener()
			{
	            public void actionPerformed(ActionEvent e) 
	            {
	                dataSourceSelected();
	            }
	        });

		paramPanel.add(new JLabel(dbeditLabels.getString("RoutingSpecEditPanel.consumerType")),
			new GridBagConstraints(0, 2, 1, 1, 0.0, 0.0, 
				GridBagConstraints.EAST, GridBagConstraints.NONE,
				new Insets(1, 4, 1, 2), 0, 0));
		paramPanel.add(consumerTypeCombo, 
			new GridBagConstraints(1, 2, 1, 1, 0.0, 0.0,
				GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, 
				new Insets(1, 0, 1, 10), 0, 0));
		consumerTypeCombo.addActionListener(
			new java.awt.event.ActionListener()
			{
	            public void actionPerformed(ActionEvent e) 
	            {
	                consumerTypeSelected();
	            }
	        });

		// The generic label will be overwritten by the specific one when a consumer
		// type is selected.
		consumerArgLabel.setText(dbeditLabels.getString("RoutingSpecEditPanel.consumerArgs"));
		paramPanel.add(consumerArgLabel,
			new GridBagConstraints(0, 3, 1, 1, 0.0, 0.0, 
				GridBagConstraints.EAST, GridBagConstraints.NONE,
				new Insets(1, 4, 1, 2), 0, 0));
		paramPanel.add(consumerArgsField, 
			new GridBagConstraints(1, 3, 1, 1, 1.0, 0.0,
				GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, 
				new Insets(1, 0, 1, 10), 0, 0));
	
		paramPanel.add(new JLabel(dbeditLabels.getString("RoutingSpecEditPanel.outFormat")),
			new GridBagConstraints(0, 4, 1, 1, 0.0, 0.0, 
				GridBagConstraints.EAST, GridBagConstraints.NONE,
				new Insets(1, 4, 1, 2), 0, 0));
		outputFormatCombo.addActionListener(
			new java.awt.event.ActionListener()
			{
	            public void actionPerformed(ActionEvent e) 
	            {
	                outputFormatSelected();
	            }
	        });
		paramPanel.add(outputFormatCombo, 
			new GridBagConstraints(1, 4, 1, 1, 1.0, 0.0,
				GridBagConstraints.WEST, GridBagConstraints.NONE, 
				new Insets(1, 0, 1, 10), 0, 0));
		
		paramPanel.add(new JLabel(genericLabels.getString("timeZoneLabel")),
			new GridBagConstraints(0, 5, 1, 1, 0.0, 0.0, 
				GridBagConstraints.EAST, GridBagConstraints.NONE,
				new Insets(1, 4, 1, 2), 0, 0));
		paramPanel.add(outputTimezoneCombo, 
			new GridBagConstraints(1, 5, 1, 1, 0.0, 0.0,
				GridBagConstraints.WEST, GridBagConstraints.NONE, 
				new Insets(1, 0, 1, 10), -30, 0));
	
		paramPanel.add(new JLabel(dbeditLabels.getString("RoutingSpecEditPanel.presGroup")),
			new GridBagConstraints(0, 6, 1, 1, 0.0, 0.0, 
				GridBagConstraints.EAST, GridBagConstraints.NONE,
				new Insets(2, 4, 2, 2), 0, 0));
		paramPanel.add(presentationGroupCombo, 
			new GridBagConstraints(1, 6, 1, 1, 0.0, 0.0,
				GridBagConstraints.WEST, GridBagConstraints.NONE, 
				new Insets(1, 0, 1, 10), 0, 0));

		JPanel checkPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 15, 1));
		enableEquationsCheck.setText(
			dbeditLabels.getString("RoutingSpecEditPanel.enableEquations"));
		checkPanel.add(enableEquationsCheck);
		productionCheck.setText(genericLabels.getString("isProduction"));
		checkPanel.add(productionCheck);
		paramPanel.add(checkPanel, 
			new GridBagConstraints(0, 7, 4, 1, 0.0, 0.0,
				GridBagConstraints.CENTER, GridBagConstraints.NONE, 
				new Insets(1, 10, 1, 10), 0, 0));
	}


	private void dataSourceSelected()
	{
		selectedDataSource = dataSourceCombo.getSelection();
		rebuildCombinedProps();
		SwingUtilities.invokeLater(
		new Runnable()
		{
			public void run()
			{
				paramPanel.revalidate();
				paramPanel.repaint();
			}
		});
	}

	protected void outputFormatSelected()
	{
		String formatName = outputFormatCombo.getSelection();
		if (formatName != null && formatName.length() > 0)
		{
			try
			{
				selectedFormatter = 
					OutputFormatter.makeOutputFormatter(formatName, null, null, null, null);
				outputTimezoneCombo.setEnabled(selectedFormatter.usesTZ());
				// Update this PropertiesOwner
				rebuildCombinedProps();
			}
			catch (Exception ex)
			{
				Logger.instance().warning("Cannot instantiate formatter '" 
					+ formatName + "': " + ex);
			}
		}
		SwingUtilities.invokeLater(
		new Runnable()
		{
			public void run()
			{
				paramPanel.revalidate();
				paramPanel.repaint();
			}
		});

	}

	private void rebuildCombinedProps()
	{
		ArrayList propSpecs = new ArrayList();
		for(PropertySpec ps : rsPropSpecs)
			propSpecs.add(ps);
		
		if (selectedDataSource != null)
		{
			try
			{
				DataSourceExec currentDataSource = selectedDataSource.makeDelegate();
				for(PropertySpec ps : currentDataSource.getSupportedProps())
					propSpecs.add(ps);
				adjustSearchCritFor(currentDataSource);
			}
			catch (InvalidDatabaseException ex)
			{
				Logger.instance().warning("Cannot instantiate data source of type '"
					+ dataSourceCombo.getSelectedItem() + "': " + ex);
			}
		}
		
		if (selectedFormatter != null)
		{
			for(PropertySpec ps : selectedFormatter.getSupportedProps())
				propSpecs.add(ps);
		}

		if (selectedConsumer != null)
		{
			for(PropertySpec ps : selectedConsumer.getSupportedProps())
				propSpecs.add(ps);
		}
		
		combinedProps = new PropertySpec[propSpecs.size()];
		propSpecs.toArray(combinedProps);
		propertiesEditPanel.getModel().setPropertiesOwner(this);
	}

	private void adjustSearchCritFor(DataSourceExec currentDataSource)
	{
		boolean isLrgsType = currentDataSource != null
			&& (currentDataSource instanceof LrgsDataSource
				|| currentDataSource instanceof HotBackupGroup);
		scEditPanel.setIsLrgs(isLrgsType);
		if (!isLrgsType && currentDataSource.supportsTimeRanges())
			scEditPanel.enableSinceUntil();
	}

	@SuppressWarnings("rawtypes")
	protected void consumerTypeSelected()
	{
		String consumerName = consumerTypeCombo.getSelection();

		try
		{
			selectedConsumer = DataConsumer.makeDataConsumer(consumerName);
		}
		catch (Exception ex)
		{
			Logger.instance().warning("Cannot instantiate consumer '"
				+ consumerTypeCombo.getSelectedItem() + "': " + ex);
			selectedConsumer = null;
		}
		if (selectedConsumer != null)
			consumerArgLabel.setText(selectedConsumer.getArgLabel());
		
		// Update this PropertiesOwner
		rebuildCombinedProps();

		//TODO update this PropertiesOwner
		SwingUtilities.invokeLater(
		new Runnable()
		{
			public void run()
			{
				paramPanel.revalidate();
				paramPanel.repaint();
			}
		});
	}

	/**
	 * From ChangeTracker interface.
	 * 
	 * @return true if changes have been made to this screen since the last time
	 *         it was saved.
	 */
	public boolean hasChanged()
	{
		getDataFromFields();
		return !theObject.equals(origObject);
	}

	/**
	 * From ChangeTracker interface, save the changes back to the database &
	 * reset the hasChanged flag.
	 * 
	 * @return true if object was successfully saved.
	 */
	public boolean saveChanges()
	{
		getDataFromFields();
		try
		{
			theObject.lastModifyTime = new Date();
			theObject.write();
		}
		catch (DatabaseException e)
		{
			final String msg =
				LoadResourceBundle.sprintf(genericLabels.getString("cannotSave"), getEntityName(), e.toString());
			log.atError()
			   .setCause(e)
			   .log(msg);
			DbEditorFrame.instance().showError(msg);
			return false;
		}

		RSListTableModel model = parent.getRoutingSpecListPanel().getModel();
		model.deleteObject(origObject);
		model.addObject(theObject);

		// Make a new copy in case user wants to keep editing.
		origObject = theObject;
		theObject = origObject.copy();
		setTopObject(origObject);

		return true;
	}

	/** @see EntityOpsController */
	public String getEntityName()
	{
		return "RoutingSpec";
	}

	/** @see EntityOpsController */
	public void commitEntity()
	{
		saveChanges();
	}

	/** @see EntityOpsController */
	public void closeEntity()
	{
		if (hasChanged())
		{
			int r = JOptionPane.showConfirmDialog(this, genericLabels.getString("saveChanges"));
			if (r == JOptionPane.CANCEL_OPTION)
				return;
			else if (r == JOptionPane.YES_OPTION)
			{
				if (!saveChanges())
					return;
			}
			else if (r == JOptionPane.NO_OPTION)
				;
		}
		DbEditorTabbedPane tp = parent.getRoutingSpecTabbedPane();
		tp.remove(this);
	}

	/**
	 * Called from File - CloseAll to close this tab, abandoning any changes.
	 */
	public void forceClose()
	{
		DbEditorTabbedPane tp = parent.getRoutingSpecTabbedPane();
		tp.remove(this);
	}

	@Override
	public void help()
	{
		Help.open();
	}

	@Override
	public PropertySpec[] getSupportedProps()
	{
		return combinedProps;
	}

	@Override
	public boolean additionalPropsAllowed()
	{
		// Don't assume all output formats, sources, & consumers are up to date.
		// So DO allow additional unknown props.
		return true;
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy