/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.autoplot.pdsppi;
import java.awt.Window;
import java.io.IOException;
import java.net.URISyntaxException;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.logging.ConsoleHandler;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.DefaultComboBoxModel;
import javax.swing.DefaultListModel;
import javax.swing.ImageIcon;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.ListModel;
import javax.swing.SwingUtilities;
import javax.swing.tree.TreeModel;
import javax.swing.tree.TreePath;
import org.das2.util.LoggerManager;
import org.das2.util.filesystem.FSTreeModel;
import org.das2.util.filesystem.FileSystem;
import org.das2.util.monitor.NullProgressMonitor;
import org.das2.util.monitor.ProgressMonitor;
import org.autoplot.datasource.DataSourceEditorPanel;
import org.autoplot.datasource.URISplit;
/**
* Editor panel for getting data from PDS/PPI node.
* @author jbf
*/
public class PDSPPIDataSourceEditorPanel extends javax.swing.JPanel implements DataSourceEditorPanel {
private static final Logger logger= LoggerManager.getLogger("apdss.pdsppi");
/**
* Creates new form PPARAMPPIDataSourceEditorPanel
*/
public PDSPPIDataSourceEditorPanel() {
initComponents();
if ( FileSystem.settings().isOffline() ) {
JOptionPane.showMessageDialog(this,"internet is not available");
this.setEnabled(false);
return;
}
updateSpacecraftSoon();
}
/**
* 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() {
productTextField = new javax.swing.JTextField();
jLabel1 = new javax.swing.JLabel();
inventoryScComboBox = new javax.swing.JComboBox();
datasetComboBox = new javax.swing.JComboBox();
pickProductButton = new javax.swing.JButton();
jScrollPane1 = new javax.swing.JScrollPane();
paramList = new javax.swing.JList();
jLabel2 = new javax.swing.JLabel();
jLabel3 = new javax.swing.JLabel();
jLabel4 = new javax.swing.JLabel();
productTextField.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
productTextFieldActionPerformed(evt);
}
});
jLabel1.setText("Spacecraft:");
inventoryScComboBox.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "voyager", "galileo", "cassini" }));
inventoryScComboBox.addItemListener(new java.awt.event.ItemListener() {
public void itemStateChanged(java.awt.event.ItemEvent evt) {
inventoryScComboBoxItemStateChanged(evt);
}
});
datasetComboBox.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
datasetComboBoxActionPerformed(evt);
}
});
pickProductButton.setText("Pick...");
pickProductButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
pickProductButtonActionPerformed(evt);
}
});
jScrollPane1.setViewportView(paramList);
jLabel2.setText("Dataset:");
jLabel3.setText("Product:");
jLabel4.setText("Parameters:");
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jScrollPane1, javax.swing.GroupLayout.Alignment.TRAILING)
.addGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jLabel2)
.addComponent(jLabel3))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addComponent(productTextField)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(pickProductButton))
.addComponent(datasetComboBox, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
.addGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jLabel4)
.addGroup(layout.createSequentialGroup()
.addComponent(jLabel1)
.addGap(18, 18, 18)
.addComponent(inventoryScComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 192, javax.swing.GroupLayout.PREFERRED_SIZE)))
.addGap(0, 197, Short.MAX_VALUE)))
.addContainerGap())
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(jLabel1)
.addComponent(inventoryScComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(datasetComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(jLabel2))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(productTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(pickProductButton)
.addComponent(jLabel3))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jLabel4)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 182, Short.MAX_VALUE)
.addContainerGap())
);
}// //GEN-END:initComponents
/**
* apparently the id needs to have underscores where there are slashes... e.g.
* PPI/CO-E/J/S/SW-CAPS-5-DDR-ELE-MOMENTS-V1.0 -> PPI/CO-E_J_S_SW-CAPS-5-DDR-ELE-MOMENTS-V1.0
* @param root like PPI/CO-E/J/S/SW-CAPS-5-DDR-ELE-MOMENTS-V1.0/
* @return result like PPI/CO-E_J_S_SW-CAPS-5-DDR-ELE-MOMENTS-V1.0
*/
private String removeExtraSlashes( String root ) {
int i= root.indexOf("/"); // 4 for PPI/
i++;
return root.substring(0,i) + root.substring(i).replaceAll("/","_");
}
/**
* return the current dataset.
* @return
*/
private String getCurrentRoot() {
return removeExtraSlashes( datasetComboBox.getSelectedItem().toString() );
}
/**
* there's a little problem that we can't set this on the event thread, because it
* involves listing files.
* @param tree
* @param m
* @param s
*/
private void setSelectedProduct( JTree tree, TreeModel m, String s ) {
String[] ss= s.split("/",-2);
Object parent= m.getRoot();
TreePath p= new TreePath(parent);
for ( String s1 : ss ) {
s1= s1+"/";
int idx= -1;
for ( int i=0; i dss ) {
Runnable run= new Runnable() {
@Override
public void run() {
String[] ss= new String[ dss.size() ];
int i= 0;
for ( Entry e: dss.entrySet() ) {
ss[i]= e.getKey()+": "+ e.getValue();
i=i+1;
}
if ( ss.length==0 ) {
paramList.setModel( getMessageModel("(No plottable parameters)") );
return;
}
String lparam= param;
if ( lparam!=null ) lparam= lparam.replaceAll("\\+"," ");
String selectedParam= null;
DefaultListModel lm= new DefaultListModel();
for ( String s: ss ) {
lm.addElement(s);
int j= s.indexOf(":");
if ( j==-1 ) j= s.length();
if ( s.substring(0,j).equals(lparam) ) {
selectedParam= s;
}
}
paramList.setModel( lm );
if ( selectedParam==null && lparam!=null && lparam.matches("col\\d+") ) {
paramList.setSelectedIndex( Integer.parseInt( lparam.substring(3) )-1 );
} else if ( selectedParam!=null ) {
paramList.setSelectedValue( selectedParam, true );
}
}
};
SwingUtilities.invokeLater(run);
}
ListModel getMessageModel( final String message ) {
return new DefaultListModel() {
@Override
public Object getElementAt(int index) {
return message;
}
@Override
public int getSize() {
return 1;
}
};
};
/**
* given the new ID, update the available params.
* @param id
*/
private void updateParamsSoon( final String id ) {
paramList.setModel( getMessageModel("(Please Wait...)") );
Runnable run= new Runnable() {
@Override
public void run() {
try {
final Map dss= PDSPPIDB.getInstance().getParams( id, new NullProgressMonitor() );
updateParamComboBoxSoon(dss);
} catch ( final IllegalArgumentException ex ) {
Runnable run= new Runnable() {
public void run() {
paramList.setModel( getMessageModel("("+ex.getMessage()+")" ) );
}
};
SwingUtilities.invokeLater(run);
}
}
};
new Thread(run).start();
}
private void productTextFieldActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_productTextFieldActionPerformed
String lid= productTextField.getText();
String root= getCurrentRoot();
lid= root+"/"+lid;
updateParamsSoon(lid);
}//GEN-LAST:event_productTextFieldActionPerformed
private void datasetComboBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_datasetComboBoxActionPerformed
productTextField.setText("");
paramList.setModel( getMessageModel("") );
}//GEN-LAST:event_datasetComboBoxActionPerformed
private void inventoryScComboBoxItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_inventoryScComboBoxItemStateChanged
this.sc= evt.getItem().toString().replaceAll("\\+"," ");
updateInventorySoon();
}//GEN-LAST:event_inventoryScComboBoxItemStateChanged
private void updateSpacecraftSoon() {
Runnable run= new Runnable() {
@Override
public void run() {
final String[] scs= PDSPPIDB.getInstance().getSpacecraft();
logger.fine("updateFacetSoon");
Runnable run= new Runnable() { public void run() {
inventoryScComboBox.setModel( new DefaultComboBoxModel(scs) );
if ( sc==null ) {
logger.finer("picking arbitrary spacecraft for GUI");
sc=scs[0].replaceAll("\\+"," ");
} //TODO: pref for last spacecraft
inventoryScComboBox.setSelectedItem( sc );
updateInventorySoon();
} };
SwingUtilities.invokeLater(run);
}
};
new Thread(run).start();
}
/**
* test if the two are the same, where t is at least as long as s, and
* slashes in s are ignored.
* PPI/CO-E/J/S/SW... is the same as PPI/CO-E_J_S_SW...
* @param s e.g. PPI/CO-E/J/S/SW
* @param t e.g. PPI/CO-E_J_S_SW/foo/
* @return true if they are referreinf to the same dataset, e.g. true in the example case.
*/
private static boolean isSameId( String s, String t ) {
if ( s.length()>t.length() ) {
return false;
}
for ( int i=0; ii+1 ) {
updateParamsSoon(id);
}
}
}
}
private void updateInventorySoon() {
Runnable run= new Runnable() {
@Override
public void run() {
logger.fine("updateInventorySoon");
try {
final String[] dss= PDSPPIDB.getInstance().getIds("sc="+sc,"PPI/");
Runnable run= new Runnable() { public void run() {
datasetComboBox.setModel( new DefaultComboBoxModel(dss) );
doCheckIdSelectedItem();
} };
SwingUtilities.invokeLater(run);
} catch ( final IOException ex ) {
String msg= "PDS/PPI Database is not available
"+ex.getMessage();
JOptionPane.showMessageDialog( PDSPPIDataSourceEditorPanel.this, msg );
}
}
};
new Thread(run).start();
}
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JComboBox datasetComboBox;
private javax.swing.JComboBox inventoryScComboBox;
private javax.swing.JLabel jLabel1;
private javax.swing.JLabel jLabel2;
private javax.swing.JLabel jLabel3;
private javax.swing.JLabel jLabel4;
private javax.swing.JScrollPane jScrollPane1;
private javax.swing.JList paramList;
private javax.swing.JButton pickProductButton;
private javax.swing.JTextField productTextField;
// End of variables declaration//GEN-END:variables
@Override
public boolean reject(String uri) throws Exception {
return false;
}
/**
*
* @param uri
* @param parent
* @param mon
* @return
* @throws Exception
*/
@Override
public boolean prepare(String uri, Window parent, ProgressMonitor mon) throws Exception {
return true;
}
Map params; // hold on to original values for a reference.
@Override
public void setURI(String uri) {
URISplit split= URISplit.parse(uri);
Map lparams= URISplit.parseParams(split.params);
this.sc= lparams.get(SC);
if ( sc!=null ) {
sc= sc.replaceAll("\\+"," ");
this.inventoryScComboBox.setSelectedItem(sc);
}
this.id= lparams.get(ID);
if ( id!=null && id.startsWith("/") ) {
logger.warning("id ought not start with slash, just PPI/CO-E...");
id= id.substring(1);
}
if ( id!=null && id.startsWith("pds://") ) {
logger.warning("id ought not start with pds://, just PPI/CO-E...");
id= id.substring(6);
}
this.param= lparams.get(PARAM);
updateSpacecraftSoon();
}
private String sc;
private String id;
private String param;
public static final String PARAM = "param";
public static final String ID = "id";
public static final String SC = "sc"; // spacecraft facet
@Override
public void markProblems(List problems) {
}
@Override
public JPanel getPanel() {
return this;
}
@Override
public String getURI() {
String lid= getCurrentRoot() + "/" + this.productTextField.getText(); //TODO: why must I add PPI??
lid= lid.replaceAll(" ","+");
String lparam= (String) this.paramList.getSelectedValue();
if ( lparam!=null ) {
int i= lparam.indexOf(": ");
if ( i>-1 ) {
lparam= lparam.substring(0,i);
}
lparam= lparam.replaceAll(" ","+");
}
String lsc= inventoryScComboBox.getSelectedItem().toString().replaceAll(" ","+");
if ( lparam==null || lparam.startsWith("(") ) {
return "vap+pdsppi:" + SC+"="+ lsc + "&" + ID + "="+ lid;
} else {
return "vap+pdsppi:" + SC+"="+ lsc + "&" + ID + "="+ lid + "&" + PARAM + "="+ lparam;
}
}
public static void main( String[] args ) {
LoggerManager.getLogger( "apdss.pdsppi" ).setLevel(Level.ALL);
ConsoleHandler h= new ConsoleHandler();
h.setLevel(Level.ALL);
Logger.getLogger("").addHandler(h);
Logger.getLogger("apdss.pdsppi").fine("run from main");
PDSPPIDataSourceEditorPanel test= new PDSPPIDataSourceEditorPanel();
//test.setURI("vap+pdsppi:sc=Voyager+2&id=PPI/VG2-J-CRS-5-SUMM-FLUX-V1.0/DATA/BS2E_RATE¶m=BS2E RATE2");
//test.setURI("vap+pdsppi:sc=Cassini&id=PPI/CO-E_J_S_SW-CAPS-5-DDR-ELE-MOMENTS-V1.0/");
test.setURI("vap+pdsppi:id=PPI/VG1-J-CRS-5-SUMM-FLUX-V1.0/DATA/FPHA_RATE¶m=PROTON_FLUX_1&sc=Voyager+1");
JOptionPane.showMessageDialog( null, test);
System.err.println( test.getURI() );
}
}