package org.autoplot.cdf; import gov.nasa.gsfc.spdf.cdfj.CDFException; import gov.nasa.gsfc.spdf.cdfj.CDFReader; import java.io.File; import java.io.IOException; import java.lang.reflect.Array; import java.net.URI; import java.net.URISyntaxException; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.TreeMap; import java.util.logging.Level; import java.util.logging.Logger; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.regex.PatternSyntaxException; import javax.swing.DefaultComboBoxModel; import javax.swing.JComponent; import javax.swing.JPanel; import javax.swing.JTree; import javax.swing.SwingUtilities; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.DefaultTreeModel; import javax.swing.tree.TreePath; import javax.swing.tree.TreeSelectionModel; import org.autoplot.cdf.CdfUtil.CdfVariableDescription; import org.autoplot.help.AutoplotHelpSystem; import org.das2.util.DasExceptionHandler; import org.das2.util.filesystem.FileSystem; import org.das2.util.monitor.NullProgressMonitor; import org.das2.util.monitor.ProgressMonitor; import org.das2.qds.QDataSet; import org.autoplot.datasource.DataSetSelector; import org.autoplot.datasource.DataSetURI; import org.autoplot.datasource.DataSourceEditorPanel; import org.autoplot.datasource.URISplit; /** * Editor panel for CDF files. The "Java" part of the name comes from this is a * second implementation of the CDF reader, where the first was a native reader * interfaced to Autoplot via Java Native Interface. * @author jbf */ public final class CdfJavaDataSourceEditorPanel extends javax.swing.JPanel implements DataSourceEditorPanel { public static final String NO_PLOTTABLE_PARAMETERS_MSG = "No plottable parameters"; /** the maximum number of DEPEND_1 channels where we should show option for depend_1. */ private static final int MAX_SLICE1_OFFER = 32; private final static Logger logger= Logger.getLogger( "apdss.cdf" ); private boolean isValidCDF= false; /** Creates new form AggregatingDataSourceEditorPanel */ public CdfJavaDataSourceEditorPanel() { initComponents(); parameterTree.getSelectionModel().setSelectionMode( TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION ); xParameterTree.getSelectionModel().setSelectionMode( TreeSelectionModel.SINGLE_TREE_SELECTION ); yParameterTree.getSelectionModel().setSelectionMode( TreeSelectionModel.SINGLE_TREE_SELECTION ); jPanel3.setVisible(false); if ( AutoplotHelpSystem.getHelpSystem()!=null ) { // to help with debugging, check for null so we needn't initialize all of Autoplot to debug. AutoplotHelpSystem.getHelpSystem().registerHelpID(this, "cdf_main"); } } /** This method is called from within the constructor to * initialize the form. * WARNING: Do NOT modify this code. The content of this method is * always regenerated by the Form Editor. */ @SuppressWarnings("unchecked") // //GEN-BEGIN:initComponents private void initComponents() { bindingGroup = new org.jdesktop.beansbinding.BindingGroup(); jPanel1 = new javax.swing.JPanel(); jSplitPane2 = new javax.swing.JSplitPane(); jSplitPane1 = new javax.swing.JSplitPane(); jPanel3 = new javax.swing.JPanel(); jLabel4 = new javax.swing.JLabel(); subsetComboBox = new javax.swing.JComboBox(); interpretMetadataLabel = new javax.swing.JLabel(); noInterpMeta = new javax.swing.JCheckBox(); noDep = new javax.swing.JCheckBox(); showAllVarTypeCB = new javax.swing.JCheckBox(); whereCB = new javax.swing.JCheckBox(); whereParamList = new javax.swing.JComboBox(); whereOp = new javax.swing.JComboBox(); whereTF = new javax.swing.JTextField(); filterComboBox = new org.autoplot.datasource.RecentComboBox(); sortAlphaCheckBox = new javax.swing.JCheckBox(); emptyVariablesCB = new javax.swing.JCheckBox(); jTabbedPane1 = new javax.swing.JTabbedPane(); jScrollPane3 = new javax.swing.JScrollPane(); parameterTree = new javax.swing.JTree(); jPanel2 = new javax.swing.JPanel(); jScrollPane4 = new javax.swing.JScrollPane(); xParameterTree = new javax.swing.JTree(); xCheckBox = new javax.swing.JCheckBox(); jPanel4 = new javax.swing.JPanel(); jScrollPane5 = new javax.swing.JScrollPane(); yParameterTree = new javax.swing.JTree(); yCheckBox = new javax.swing.JCheckBox(); jScrollPane2 = new javax.swing.JScrollPane(); paramInfo = new javax.swing.JLabel(); setName("cdfDataSourceEditorPanel"); // NOI18N setPreferredSize(new java.awt.Dimension(615, 452)); jPanel1.setBorder(javax.swing.BorderFactory.createEtchedBorder()); jPanel1.setPreferredSize(new java.awt.Dimension(615, 452)); jSplitPane2.setDividerLocation(230); jSplitPane2.setOrientation(javax.swing.JSplitPane.VERTICAL_SPLIT); jSplitPane1.setDividerLocation(320); jSplitPane1.setResizeWeight(1.0); jPanel3.setBorder(javax.swing.BorderFactory.createTitledBorder("Advanced")); jPanel3.setMaximumSize(new java.awt.Dimension(285, 32767)); jLabel4.setText("Load subset of the data:"); jLabel4.setToolTipText("Load a subset of the data records, for example:
[0:100] first 100 records
[-100:] last 100 records
[::10] every tenth record
"); subsetComboBox.setEditable(true); subsetComboBox.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "", "::10", "0:100", "-100:", "0:10000:5" })); subsetComboBox.setToolTipText("Load a subset of the data records, for example:
[0:100] first 100 records
[-100:] last 100 records
[::10] every tenth record
"); interpretMetadataLabel.setText("Interpret Metadata:"); noInterpMeta.setText("no ISTP"); noInterpMeta.setToolTipText("Don't interpret metadata to get titles and units."); noDep.setText("no dependencies"); noDep.setToolTipText("Ignore connections between variables like \"DEPEND_0\"\n"); showAllVarTypeCB.setText("show all"); showAllVarTypeCB.setToolTipText("show all parameters, even if ISTP VAR_TYPE is not \"data\""); showAllVarTypeCB.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { showAllVarTypeCBActionPerformed(evt); } }); whereCB.setText("Only load data where:"); whereCB.setToolTipText("return only the records where the condition is true"); whereParamList.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" })); org.jdesktop.beansbinding.Binding binding = org.jdesktop.beansbinding.Bindings.createAutoBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ_WRITE, whereCB, org.jdesktop.beansbinding.ELProperty.create("${selected}"), whereParamList, org.jdesktop.beansbinding.BeanProperty.create("enabled")); bindingGroup.addBinding(binding); whereOp.setModel(new javax.swing.DefaultComboBoxModel(new String[] { ".eq", ".gt", ".lt", ".ne", ".within" })); binding = org.jdesktop.beansbinding.Bindings.createAutoBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ_WRITE, whereCB, org.jdesktop.beansbinding.ELProperty.create("${selected}"), whereOp, org.jdesktop.beansbinding.BeanProperty.create("enabled")); bindingGroup.addBinding(binding); whereTF.setText("0"); whereTF.setToolTipText("enter the value, or \"mode\" for the most frequently occuring value."); binding = org.jdesktop.beansbinding.Bindings.createAutoBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ_WRITE, whereCB, org.jdesktop.beansbinding.ELProperty.create("${selected}"), whereTF, org.jdesktop.beansbinding.BeanProperty.create("enabled")); bindingGroup.addBinding(binding); filterComboBox.setToolTipText("Pattern to match in variables names. If this is a valid regular expression, it will be used as such, otherwise the variables containing the string are used."); filterComboBox.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { filterComboBoxActionPerformed(evt); } }); sortAlphaCheckBox.setText("sort alpha"); sortAlphaCheckBox.setToolTipText("Sort the names alphabetically."); sortAlphaCheckBox.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { sortAlphaCheckBoxActionPerformed(evt); } }); emptyVariablesCB.setSelected(true); emptyVariablesCB.setText("empty variables"); emptyVariablesCB.setToolTipText("show variables which have no records"); emptyVariablesCB.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { emptyVariablesCBActionPerformed(evt); } }); org.jdesktop.layout.GroupLayout jPanel3Layout = new org.jdesktop.layout.GroupLayout(jPanel3); jPanel3.setLayout(jPanel3Layout); jPanel3Layout.setHorizontalGroup( jPanel3Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) .add(jPanel3Layout.createSequentialGroup() .addContainerGap() .add(whereParamList, 0, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) .add(whereOp, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 84, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE) .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) .add(whereTF, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 53, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)) .add(jPanel3Layout.createSequentialGroup() .add(jPanel3Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) .add(jLabel4) .add(whereCB) .add(interpretMetadataLabel) .add(jPanel3Layout.createSequentialGroup() .add(12, 12, 12) .add(jPanel3Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) .add(jPanel3Layout.createSequentialGroup() .add(jPanel3Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) .add(noInterpMeta) .add(showAllVarTypeCB) .add(sortAlphaCheckBox)) .addPreferredGap(org.jdesktop.layout.LayoutStyle.UNRELATED) .add(jPanel3Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) .add(filterComboBox, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE) .add(noDep) .add(emptyVariablesCB))) .add(subsetComboBox, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 160, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)))) .add(0, 0, Short.MAX_VALUE)) ); jPanel3Layout.setVerticalGroup( jPanel3Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) .add(jPanel3Layout.createSequentialGroup() .add(jLabel4) .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) .add(subsetComboBox, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE) .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) .add(whereCB) .add(8, 8, 8) .add(jPanel3Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE) .add(whereParamList, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE) .add(whereOp, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE) .add(whereTF, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)) .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) .add(interpretMetadataLabel) .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) .add(jPanel3Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE) .add(noInterpMeta) .add(noDep)) .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) .add(jPanel3Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE) .add(showAllVarTypeCB) .add(filterComboBox, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)) .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) .add(jPanel3Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE) .add(sortAlphaCheckBox) .add(emptyVariablesCB))) ); jSplitPane1.setRightComponent(jPanel3); jTabbedPane1.addChangeListener(new javax.swing.event.ChangeListener() { public void stateChanged(javax.swing.event.ChangeEvent evt) { jTabbedPane1StateChanged(evt); } }); parameterTree.addTreeSelectionListener(new javax.swing.event.TreeSelectionListener() { public void valueChanged(javax.swing.event.TreeSelectionEvent evt) { parameterTreeValueChanged(evt); } }); jScrollPane3.setViewportView(parameterTree); jTabbedPane1.addTab("Data", jScrollPane3); xParameterTree.addTreeSelectionListener(new javax.swing.event.TreeSelectionListener() { public void valueChanged(javax.swing.event.TreeSelectionEvent evt) { xParameterTreeValueChanged(evt); } }); jScrollPane4.setViewportView(xParameterTree); xCheckBox.setText("Set Variable for X"); xCheckBox.setToolTipText("Specify the parameter to use for the X tags, overriding any settings found in the file."); xCheckBox.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { xCheckBoxActionPerformed(evt); } }); org.jdesktop.layout.GroupLayout jPanel2Layout = new org.jdesktop.layout.GroupLayout(jPanel2); jPanel2.setLayout(jPanel2Layout); jPanel2Layout.setHorizontalGroup( jPanel2Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) .add(xCheckBox, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 401, Short.MAX_VALUE) .add(jScrollPane4) ); jPanel2Layout.setVerticalGroup( jPanel2Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) .add(jPanel2Layout.createSequentialGroup() .add(xCheckBox) .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) .add(jScrollPane4, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 169, Short.MAX_VALUE)) ); jTabbedPane1.addTab("X", jPanel2); yParameterTree.addTreeSelectionListener(new javax.swing.event.TreeSelectionListener() { public void valueChanged(javax.swing.event.TreeSelectionEvent evt) { yParameterTreeValueChanged(evt); } }); jScrollPane5.setViewportView(yParameterTree); yCheckBox.setText("Set Variable for Y"); yCheckBox.setToolTipText("Specify the parameter to use for the Y tags, overriding any settings found in the file."); org.jdesktop.layout.GroupLayout jPanel4Layout = new org.jdesktop.layout.GroupLayout(jPanel4); jPanel4.setLayout(jPanel4Layout); jPanel4Layout.setHorizontalGroup( jPanel4Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) .add(yCheckBox, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 401, Short.MAX_VALUE) .add(jScrollPane5) ); jPanel4Layout.setVerticalGroup( jPanel4Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) .add(jPanel4Layout.createSequentialGroup() .add(yCheckBox) .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) .add(jScrollPane5, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 169, Short.MAX_VALUE)) ); jTabbedPane1.addTab("Y", jPanel4); jSplitPane1.setLeftComponent(jTabbedPane1); jSplitPane2.setTopComponent(jSplitPane1); jScrollPane2.setMaximumSize(new java.awt.Dimension(1000, 600)); paramInfo.setText("Variable"); paramInfo.setVerticalAlignment(javax.swing.SwingConstants.TOP); paramInfo.setMaximumSize(new java.awt.Dimension(1000, 4000)); paramInfo.setPreferredSize(new java.awt.Dimension(600, 100)); paramInfo.setVerticalTextPosition(javax.swing.SwingConstants.TOP); jScrollPane2.setViewportView(paramInfo); jSplitPane2.setRightComponent(jScrollPane2); org.jdesktop.layout.GroupLayout jPanel1Layout = new org.jdesktop.layout.GroupLayout(jPanel1); jPanel1.setLayout(jPanel1Layout); jPanel1Layout.setHorizontalGroup( jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) .add(org.jdesktop.layout.GroupLayout.TRAILING, jPanel1Layout.createSequentialGroup() .addContainerGap() .add(jSplitPane2, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 675, Short.MAX_VALUE) .addContainerGap()) ); jPanel1Layout.setVerticalGroup( jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) .add(jPanel1Layout.createSequentialGroup() .addContainerGap() .add(jSplitPane2, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 425, Short.MAX_VALUE) .addContainerGap()) ); org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(this); this.setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) .add(jPanel1, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) ); layout.setVerticalGroup( layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) .add(org.jdesktop.layout.GroupLayout.TRAILING, jPanel1, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) ); bindingGroup.bind(); }//
//GEN-END:initComponents private void showAllVarTypeCBActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_showAllVarTypeCBActionPerformed org.das2.util.LoggerManager.logGuiEvent(evt); setURI( getURI() ); }//GEN-LAST:event_showAllVarTypeCBActionPerformed private void jTabbedPane1StateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_jTabbedPane1StateChanged int tab= jTabbedPane1.getSelectedIndex(); updateMetadata(tab); }//GEN-LAST:event_jTabbedPane1StateChanged private void yParameterTreeValueChanged(javax.swing.event.TreeSelectionEvent evt) {//GEN-FIRST:event_yParameterTreeValueChanged yCheckBox.setSelected(true); TreePath tp= evt.getPath(); if ( isValidCDF ) { yparameter= String.valueOf(tp.getPathComponent(1)); String longName= yparameterInfo.get(yparameter); paramInfo.setText( longName ); } }//GEN-LAST:event_yParameterTreeValueChanged private void xCheckBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_xCheckBoxActionPerformed // TODO add your handling code here: }//GEN-LAST:event_xCheckBoxActionPerformed private void xParameterTreeValueChanged(javax.swing.event.TreeSelectionEvent evt) {//GEN-FIRST:event_xParameterTreeValueChanged xCheckBox.setSelected(true); TreePath tp= evt.getPath(); if ( isValidCDF ) { xparameter= String.valueOf(tp.getPathComponent(1)); String longName= xparameterInfo.get(xparameter); paramInfo.setText( longName ); } }//GEN-LAST:event_xParameterTreeValueChanged private void parameterTreeValueChanged(javax.swing.event.TreeSelectionEvent evt) {//GEN-FIRST:event_parameterTreeValueChanged TreePath tp= evt.getPath(); if ( isValidCDF ) { parameter= String.valueOf(tp.getPathComponent(1)); updateMetadata(); String s; String slice1; s= getParamAndSubset(xParameterTree,""); slice1= s.length()==0 ? "" : s.substring(xparameter.length()); LinkedHashMap xx= getCompatible( parameter, X_PARAMETER ); fillTree( xParameterTree, toDescriptions(xx), cdf, xparameter, slice1 ); s= getParamAndSubset(yParameterTree,""); slice1= s.length()==0 ? "" : s.substring(xparameter.length()); LinkedHashMap yy= getCompatible( parameter, Y_PARAMETER ); fillTree( yParameterTree, toDescriptions(yy), cdf, yparameter, slice1 ); } }//GEN-LAST:event_parameterTreeValueChanged /** * convert the CdfVariableDescription blocks into an html page describing the variables. * @param xx * @return */ private Map toDescriptions( LinkedHashMap xx ) { LinkedHashMap result= new LinkedHashMap<>(); for ( Entry e: xx.entrySet() ) { CdfVariableDescription desc=e.getValue(); result.put( e.getKey(), desc.htmlDescription ); } return result; } /** * return the list of variables which are compatible with this parameter, having the same number * of records, etc. * @param parameter * @param whichIndependentParameter * @return a linked hash map of name to descriptions. */ private LinkedHashMap getCompatible( String parameter, Object whichIndependentParameter ) { CdfVariableDescription dependent= cdfParameterInfo.get(parameter); LinkedHashMap result= new LinkedHashMap<>(); for ( Entry cvds : cdfParameterInfo.entrySet() ) { CdfVariableDescription cvd = cvds.getValue(); if ( whichIndependentParameter==X_PARAMETER ) { if ( cvd.numberOfRecords==dependent.numberOfRecords ) { if ( cvd.dimensions.length==0 || ( cvd.dimensions.length==1 && cvd.dimensions[0]==2 ) ) { result.put( cvd.name, cvd ); } } } else if ( whichIndependentParameter==Y_PARAMETER) { if ( cvd.dimensions.length==1 && dependent.dimensions.length==1 && cvd.dimensions[0]==dependent.dimensions[0] ) { if ( cvd.numberOfRecords==1 ) { result.put( cvd.name, cvd ); } else if ( cvd.numberOfRecords==dependent.numberOfRecords ) { result.put( cvd.name, cvd ); } } else if ( cvd.dimensions.length==0 && dependent.dimensions.length==0 && cvd.numberOfRecords==dependent.numberOfRecords ) { result.put( cvd.name, cvd ); } } } return result; } private void filterComboBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_filterComboBoxActionPerformed updateTree(); }//GEN-LAST:event_filterComboBoxActionPerformed private void sortAlphaCheckBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_sortAlphaCheckBoxActionPerformed updateTree(); }//GEN-LAST:event_sortAlphaCheckBoxActionPerformed private void emptyVariablesCBActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_emptyVariablesCBActionPerformed setURI( getURI() ); }//GEN-LAST:event_emptyVariablesCBActionPerformed private void updateTree() { String param = getParam(); fillTree( this.parameterTree, parameterInfo, cdf, param, "" ); } private void updateMetadata() { updateMetadata(0); } private void updateMetadata( int tab ) { switch (tab) { case 0: if ( parameter!=null ) { String longName= parameterInfo.get(parameter); paramInfo.setText( longName ); break; } case 1: if ( xparameter!=null ) { String longName= xparameterInfo.get(xparameter); paramInfo.setText( longName ); break; } case 2: if ( yparameter!=null ) { String longName= yparameterInfo.get(yparameter); paramInfo.setText( longName ); break; } default: break; } } // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JCheckBox emptyVariablesCB; private org.autoplot.datasource.RecentComboBox filterComboBox; private javax.swing.JLabel interpretMetadataLabel; private javax.swing.JLabel jLabel4; private javax.swing.JPanel jPanel1; private javax.swing.JPanel jPanel2; private javax.swing.JPanel jPanel3; private javax.swing.JPanel jPanel4; private javax.swing.JScrollPane jScrollPane2; private javax.swing.JScrollPane jScrollPane3; private javax.swing.JScrollPane jScrollPane4; private javax.swing.JScrollPane jScrollPane5; private javax.swing.JSplitPane jSplitPane1; private javax.swing.JSplitPane jSplitPane2; private javax.swing.JTabbedPane jTabbedPane1; private javax.swing.JCheckBox noDep; private javax.swing.JCheckBox noInterpMeta; private javax.swing.JLabel paramInfo; private javax.swing.JTree parameterTree; private javax.swing.JCheckBox showAllVarTypeCB; private javax.swing.JCheckBox sortAlphaCheckBox; private javax.swing.JComboBox subsetComboBox; private javax.swing.JCheckBox whereCB; private javax.swing.JComboBox whereOp; private javax.swing.JComboBox whereParamList; private javax.swing.JTextField whereTF; private javax.swing.JCheckBox xCheckBox; private javax.swing.JTree xParameterTree; private javax.swing.JCheckBox yCheckBox; private javax.swing.JTree yParameterTree; private org.jdesktop.beansbinding.BindingGroup bindingGroup; // End of variables declaration//GEN-END:variables @Override public JPanel getPanel() { if (showAllInitially) { SwingUtilities.invokeLater( new Runnable() { @Override public void run() { showAllVarTypeCB.setSelected(true); setURI( getURI() ); } }); } return this; } JComponent delegateComponent = null; DataSetSelector delegateDataSetSelector=null; DataSourceEditorPanel delegateEditorPanel= null; /** * extra URI parameters that are not supported in the dialog. */ Map params; String vapScheme; /** * the location of the CDF file. */ URI resourceUri; /** * short descriptions of the parameters */ Map parameterDescriptions; /** * long descriptions html formatted metadata about each parameter. */ Map parameterInfo; /** * long descriptions html formatted metadata about each parameter. */ Map xparameterInfo; /** * long descriptions html formatted metadata about each parameter. */ Map yparameterInfo; /** * new descriptions of variables with size and lengths */ LinkedHashMap cdfParameterInfo; String parameter; String xparameter; String yparameter; private static final String X_PARAMETER = "X_PARAMETER"; private static final String Y_PARAMETER = "Y_PARAMETER"; boolean showAllInitially= false; /** * can I reuse the slice? Only if the maxRec doesn't change. */ long subsetMaxRec=-1; File cdfFile; CDFReader cdf; Throwable cdfException; /** * allow more abstract sources, namely cdaweb, to turn off these controls. * @param v */ public void setShowAdvancedSubpanel( boolean v ) { noDep.setVisible(v); noInterpMeta.setVisible(v); showAllVarTypeCB.setVisible(v); } @Override public boolean reject( String url ) throws IOException, URISyntaxException { URISplit split = URISplit.parse(url); if ( split.resourceUri==null ) { return true; } FileSystem fs = FileSystem.create( DataSetURI.getWebURL( DataSetURI.toUri(split.path) ).toURI() ); return fs.isDirectory( split.file.substring(split.path.length()) ); } @Override public boolean prepare( String url, java.awt.Window parent, ProgressMonitor mon) throws Exception { URISplit split= URISplit.parse(url); cdfFile= DataSetURI.getFile( split.resourceUri, mon ); DataSetURI.checkLength(cdfFile); logger.log(Level.FINE, "opening cdf file {0}", cdfFile.toString()); try { CdfDataSource.checkCdf(cdfFile); cdf = CdfDataSource.getCdfFile(cdfFile.toString()); if ( cdf==null ) { throw new IllegalArgumentException("file is not a CDF file"); } cdfException= null; } catch ( IOException | IllegalArgumentException ex ) { cdfException= ex; } return true; } public static String getKeyForFile( String filename ) { int j=filename.indexOf("19"); if ( j==-1 ) j= filename.indexOf("20"); if ( j==-1 ) j= filename.length(); while ( j>0 && filename.charAt(j-1)=='_' ) j=j-1; String key= filename.substring(0,j); return key; } @Override public void setURI(String url) { URISplit split= URISplit.parse(url); vapScheme= split.vapScheme; Map lparams= URISplit.parseParams(split.params); try { resourceUri= split.resourceUri; cdfFile= DataSetURI.getFile( split.resourceUri, new NullProgressMonitor() ); DataSetURI.checkLength(cdfFile); String fileName= cdfFile.toString(); String key= getKeyForFile( split.file.substring(split.path.length()) ); filterComboBox.setPreferenceNode("cdf_"+key); filterComboBox.setToolTipText("Filter parameters"); logger.log(Level.FINE, "opening cdf file {0}", fileName); if ( cdf==null && cdfException==null ) { try { cdf = CdfDataSource.getCdfFile(fileName); } catch (Exception ex) { throw new RuntimeException(ex); } } if ( cdfException!=null ) { this.parameterTree.setModel( new DefaultTreeModel( new DefaultMutableTreeNode("") ) ); this.paramInfo.setText( "Unable to read CDF file:
"+cdfException.getMessage() ); return; } logger.finest("inspect cdf for plottable parameters"); boolean isMaster= fileName.contains("MASTERS"); Map options= new HashMap<>(); options.put( org.autoplot.cdf.CdfUtil.OPTION_INCLUDE_EMPTY_RECORDS, String.valueOf(this.emptyVariablesCB.isSelected()) ); options.put( org.autoplot.cdf.CdfUtil.OPTION_IS_MASTER, String.valueOf(isMaster) ); options.put( org.autoplot.cdf.CdfUtil.OPTION_DEEP, String.valueOf(true) ); try { parameterDescriptions= org.autoplot.cdf.CdfUtil.getPlottable(cdf, !this.showAllVarTypeCB.isSelected(), QDataSet.MAX_RANK); } catch ( Exception ex ) { this.parameterTree.setModel( new DefaultTreeModel( new DefaultMutableTreeNode("") ) ); this.paramInfo.setText( "Unable to work with metadata in CDF file:
"+ex ); throw ex; } Map allParameterInfo= org.autoplot.cdf.CdfUtil.getPlottable(cdf, false, QDataSet.MAX_RANK, options ); Map dataParameterInfo= org.autoplot.cdf.CdfUtil.getPlottable(cdf, true, QDataSet.MAX_RANK, options ); options.put( org.autoplot.cdf.CdfUtil.OPTION_DEEP, String.valueOf( false ) ); Map whereParameterInfo= org.autoplot.cdf.CdfUtil.getPlottable(cdf, false, 2, options); cdfParameterInfo= org.autoplot.cdf.CdfUtil.getPlottable(cdf, options); String param= lparams.remove("arg_0"); if ( isSupportParameter( cdfParameterInfo, param ) ) { this.showAllVarTypeCB.setSelected(true); parameterDescriptions= org.autoplot.cdf.CdfUtil.getPlottable(cdf, !this.showAllVarTypeCB.isSelected(), QDataSet.MAX_RANK, new HashMap()); this.showAllVarTypeCB.setEnabled(false); } String label; if ( this.showAllVarTypeCB.isSelected() ) { parameterInfo= allParameterInfo; label= "Select CDF Variable (%d data, %d support):"; } else { parameterInfo= dataParameterInfo; label= "Select CDF Variable (%d data, %d support not shown):"; } xparameterInfo= allParameterInfo; yparameterInfo= allParameterInfo; this.isValidCDF= true; jPanel3.setVisible(true); int numData= dataParameterInfo.size(); int numSupport= allParameterInfo.size() - numData; //this.selectVariableLabel.setText( String.format( label, numData, numSupport ) ); if ( this.showAllVarTypeCB.isSelected() ) { this.jTabbedPane1.setTitleAt( 0, String.format( "Select CDF Variable (of %d)", numData+numSupport ) ); } else { this.jTabbedPane1.setTitleAt( 0, String.format( "Select CDF Variable (of %d)", numData ) ); } this.jTabbedPane1.setToolTipText( String.format( label, numData, numSupport ) ); if ( this.showAllVarTypeCB.isSelected() ) { this.showAllVarTypeCB.setText("show all ("+numSupport+" support shown)"); } else { this.showAllVarTypeCB.setText("show all ("+numSupport+" support not shown)"); } Pattern slice1pattern= Pattern.compile("\\[\\:\\,(\\d+)\\]"); String slice1= lparams.remove("slice1"); // legacy String subset= null; if ( param!=null ) { int i= param.indexOf("["); if ( i!=-1 ) { subset= param.substring(i); param= param.substring(0,i); Matcher m= slice1pattern.matcher(subset); if ( m.matches() ) { slice1= m.group(1); subset= null; } } } if ( allParameterInfo.containsKey(param) ) { if ( !dataParameterInfo.containsKey(param) ) { showAllInitially= true; } } fillTree( this.parameterTree, parameterInfo, cdf, param, slice1 ); Map parameterDescriptions2= org.autoplot.cdf.CdfUtil.getPlottable(cdf, false, 2 ); String xparam= lparams.remove("depend0"); String xslice1= null; if ( xparam==null ) xparam= lparams.remove("X"); if ( xparam==null ) xparam= lparams.remove("x"); if ( xparam!=null ) { int i= xparam.indexOf("["); if ( i!=-1 ) { String xsubset= xparam.substring(i); xparam= xparam.substring(0,i); Matcher m= slice1pattern.matcher(xsubset); if ( m.matches() ) { xslice1= m.group(1); } } } fillTree(this.xParameterTree, parameterDescriptions2, cdf, xparam, xslice1 ); String yslice1= null; String yparam= lparams.remove("Y"); if ( yparam==null ) yparam= lparams.remove("y"); if ( yparam!=null ) { int i= yparam.indexOf("["); if ( i!=-1 ) { String ysubset= yparam.substring(i); yparam= yparam.substring(0,i); Matcher m= slice1pattern.matcher(ysubset); if ( m.matches() ) { yslice1= m.group(1); } } } fillTree(this.yParameterTree, parameterDescriptions2, cdf, yparam, yslice1 ); logger.finest("close cdf"); DefaultComboBoxModel cbmodel= new DefaultComboBoxModel(); for ( String p: parameterDescriptions.keySet() ) { cbmodel.addElement(p); } if ( param!=null ) { if ( subset!=null ) { if ( subset.startsWith("[") ) subset= subset.substring(1); if ( subset.endsWith("]") ) subset= subset.substring(0,subset.length()-1); subsetComboBox.setSelectedItem( subset ); } else { subsetComboBox.setSelectedItem(""); } } else { if ( !parameterDescriptions.isEmpty() ) { parameter= parameterDescriptions.entrySet().iterator().next().getKey(); subsetComboBox.setSelectedItem(""); param= parameter; paramInfo.setText(""); } else { param= ""; if ( this.parameterTree.getRowCount()==0 && numSupport>0 && numData==0 && !this.showAllVarTypeCB.isSelected() ) { paramInfo.setText("(all parameters are marked as support data, select \"show all\" above)"); } else { paramInfo.setText("(no plottable parameters)"); } } } parameter= param.replaceAll("%3D", "="); if ( "no".equals( lparams.remove("interpMeta")) ) { noInterpMeta.setSelected(true); } if ( "no".equals( lparams.remove("doDep" ) ) ) { noDep.setSelected(true); } whereParamList.setModel( new DefaultComboBoxModel( whereParameterInfo.keySet().toArray() ) ); String where= lparams.remove("where"); if ( where!=null && where.length()>0 ) { whereCB.setSelected(true); int i= where.indexOf("."); if ( i>-1 ) { whereParamList.setSelectedItem(where.substring(0,i)); int i0= where.indexOf("("); int i1= where.indexOf(")",i0); whereOp.setSelectedItem(where.substring(i,i0)); whereTF.setText( where.substring(i0+1,i1).replaceAll("\\+"," ")); } } else { whereCB.setSelected(false); } updateMetadata(); } catch (IOException ex) { DasExceptionHandler.handle( ex ); logger.log(Level.SEVERE, ex.getMessage(), ex); } catch (IllegalArgumentException ex) { DasExceptionHandler.handle( ex ); logger.log(Level.SEVERE, ex.getMessage(), ex); } catch (Exception ex) { DasExceptionHandler.handle( ex ); logger.log(Level.SEVERE, ex.getMessage(), ex); } this.params= lparams; } /** * return the name of the selected parameter, or null. * @return */ private String getParam() { TreePath treePath= parameterTree.getSelectionPath(); String p; if ( treePath==null ) { return null; } else { p= String.valueOf( treePath.getPathComponent(1) ); p= p.replaceAll("=", "%3D"); } return p; } /** * return the parameter, if something is selected, possibly with [:,n] to indicate a slice should be done. * @param jtree the tree showing the selection * @param subset subset by index, like [::2] for every other element. * @return empty string if no selection, or the path. */ private String getParamAndSubset( JTree jtree, String subset ) { StringBuilder ps= new StringBuilder(); TreePath[] tps= jtree.getSelectionPaths(); // typically this will be a one-element array. if ( tps==null ) tps= new TreePath[] { jtree.getSelectionPath() }; for ( TreePath treePath : tps ) { if ( ps.length()>0 ) ps.append(";"); if ( treePath==null ) { logger.fine("param was null"); } else if ( treePath.getPathCount()==3 ) { String p= String.valueOf( treePath.getPathComponent(1) ); p= p.replaceAll("=", "%3D"); String val= String.valueOf( treePath.getPathComponent(2) ); int idx= val.indexOf(":"); ps.append(p).append("[:,").append(val.substring(0,idx).trim()).append("]"); } else { String p= String.valueOf( treePath.getPathComponent(1) ); p= p.replaceAll("=", "%3D"); ps.append(p).append(subset); } } return ps.toString(); } @Override public String getURI() { URISplit split= URISplit.parse(resourceUri); split.vapScheme= this.vapScheme; String subset= subsetComboBox.getSelectedItem().toString().trim(); if ( subset.length()>0 && subset.charAt(0)!='[' ) { subset= "["+subset+"]"; } Map lparams= this.params; if ( lparams!=null ) { lparams= new HashMap(lparams); } else { lparams= new HashMap(); } if ( isValidCDF ) { TreePath[] tps= parameterTree.getSelectionPaths(); StringBuilder arg0= new StringBuilder(); if ( tps!=null ) { String p= getParamAndSubset(parameterTree,subset); if ( p.length()>0 ) lparams.put( "arg_0", p ); } if ( xCheckBox.isSelected() ) { String p = getParamAndSubset(xParameterTree,""); if ( p.length()>0 ) lparams.put( "x", p ); } if ( yCheckBox.isSelected() ) { String p= getParamAndSubset(yParameterTree,""); if ( p.length()>0 ) lparams.put( "y", p ); } if ( noDep.isSelected() ) { lparams.put("doDep","no"); } if ( noInterpMeta.isSelected() ) { lparams.put("interpMeta", "no"); } if ( whereCB.isSelected() ) { if ( whereParamList.getSelectedItem()!=null ) { lparams.put( "where", String.format( "%s%s(%s)", whereParamList.getSelectedItem(), whereOp.getSelectedItem(), whereTF.getText().replaceAll(" ","+") ) ); } else { lparams.remove("where"); } } else { lparams.remove("where"); } } split.params= URISplit.formatParams(lparams); if ( split.params!=null && split.params.length()==0 ) split.params= null; return URISplit.format(split); } @Override public void markProblems(List problems) { } /** * fill the parameter tree using metadata. * @param parameterTree the tree which will contain the parameter list. * @param mm the metadata map from parameter names to html descriptions. * @param cdf the cdf file. * @param param null or the name of the parameter which should be selected. * @param slice1 null or the slice selection (X,Y,Z of BGSM, for example). */ private void fillTree( JTree parameterTree, Map mm, gov.nasa.gsfc.spdf.cdfj.CDFReader cdf, String param, String slice1 ) { logger.entering( "CdfJavaDataSourceEditorPanel", "fillTree" ); DefaultMutableTreeNode root= new DefaultMutableTreeNode(""); List expand=new ArrayList(mm.size()); String filter= filterComboBox.getText().trim(); Pattern filterPattern= null; if ( filter.length()>0 ) { try { filterPattern= Pattern.compile(filter,Pattern.CASE_INSENSITIVE); } catch ( PatternSyntaxException ex ) { filterPattern= Pattern.compile( Pattern.quote(filter), Pattern.CASE_INSENSITIVE ); } } boolean sortAlpha= sortAlphaCheckBox.isSelected(); if ( sortAlpha ) { Map sortedMM= new TreeMap<>(); sortedMM.putAll(mm); mm= sortedMM; } List selections= new ArrayList<>(); List params; if ( param!=null ) { params = Arrays.asList(param.split(";")); } else { params= new ArrayList<>(); } TreePath selection=null; for ( Entry e: mm.entrySet() ) { if ( filterPattern!=null ) { if ( filterPattern.matcher( e.getKey() ).find() || filterPattern.matcher( e.getValue() ).find() ) { logger.log(Level.FINER, "found pattern for {0}", e.getKey()); } else { continue; } } try { Object oattr= cdf.getAttribute( e.getKey(), "LABL_PTR_1"); String lablPtr1=null; if ( oattr!=null && oattr instanceof List ) { List voattr= (List)oattr; if ( voattr.size()>0 ) { lablPtr1= (String)((List)oattr).get(0); } else { oattr= null; } } int[] dimensions= cdf.getDimensions( e.getKey() ); boolean doComponents= oattr!=null && dimensions.length==1 && dimensions[0]<=MAX_SLICE1_OFFER; if ( doComponents ) { String s= lablPtr1; DefaultMutableTreeNode node= new DefaultMutableTreeNode( e.getKey() ); try { Object o = cdf.get(s); String[] rec; if ( o.getClass().isArray() && String.class.isAssignableFrom( o.getClass().getComponentType() ) ) { rec= (String[])o; } else { Object oo= Array.get(o,0); if ( !oo.getClass().isArray() || !( String.class.isAssignableFrom( oo.getClass().getComponentType() ) ) ) { logger.log(Level.FINE, "Expected string array in element: {0}", s); continue; } rec= (String[])Array.get(o,0); } for ( int i=0; i0 ) { parameterTree.setSelectionPaths( selections.toArray(new TreePath[selections.size()]) ); } for ( TreePath tp: expand ) { parameterTree.expandPath(tp); } logger.exiting("CdfJavaDataSourceEditorPanel", "fillTree" ); } private static boolean isSupportParameter(Map dataParameterInfo, String param) { if ( param==null || param.trim().length()==0 ) { return false; } String[] params; if ( param.contains(";") ) { params= param.split(";"); } else { params= new String[] { param }; } for ( String p: params ) { CdfVariableDescription cdfvd= dataParameterInfo.get(p); if ( cdfvd!=null ) { // sure hope so if ( cdfvd.isSupport ) return true; } } return false; } }