package org.autoplot.pds; import gov.nasa.pds.label.Label; import gov.nasa.pds.label.object.ArrayObject; import gov.nasa.pds.label.object.DataObject; import gov.nasa.pds.label.object.FieldDescription; import gov.nasa.pds.label.object.TableObject; import gov.nasa.pds.objectAccess.ParseException; import gov.nasa.pds.ppi.label.PDSException; import gov.nasa.pds.ppi.label.PDSLabel; import java.io.File; import java.io.IOException; import java.net.MalformedURLException; import java.net.URI; import java.net.URISyntaxException; import java.net.URL; import java.util.ArrayList; import java.util.Collections; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.xpath.XPath; import javax.xml.xpath.XPathConstants; import javax.xml.xpath.XPathExpression; import javax.xml.xpath.XPathExpressionException; import javax.xml.xpath.XPathFactory; import org.autoplot.datasource.AbstractDataSourceFactory; import org.autoplot.datasource.CompletionContext; import org.autoplot.datasource.DataSetURI; import static org.autoplot.datasource.DataSetURI.fromUri; import org.autoplot.datasource.DataSource; import org.autoplot.datasource.URISplit; import org.das2.datum.LoggerManager; import org.das2.util.monitor.NullProgressMonitor; import org.das2.util.monitor.ProgressMonitor; import org.w3c.dom.Document; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.SAXException; /** * * @author jbf */ public class PdsDataSourceFactory extends AbstractDataSourceFactory { private static Logger logger= LoggerManager.getLogger("apdss.pds"); @Override public DataSource getDataSource(URI uri) throws Exception { URISplit split= URISplit.parse(uri); if ( split.file.toLowerCase().endsWith(".lbl") ) { return new Pds3DataSource( uri ); } else { return new PdsDataSource( uri ); } } private DataObject getDataObject( URL url, String name ) throws MalformedURLException, ParseException, Exception { //Label label = Label.open( f ); // this doesn't work. Label label = Label.open( url ); // this works for ( TableObject t : label.getObjects( TableObject.class) ) { for ( FieldDescription fd: t.getFields() ) { if ( name.startsWith( fd.getName() ) ) { return t; } } } for ( ArrayObject a: label.getObjects(ArrayObject.class) ) { if ( a.getName().equals(name) ) { return a; } } return null; } protected static PDS3DataObject getDataObjectPds3( URL url, String name ) throws IOException, PDSException, XPathExpressionException { File f= DataSetURI.getFile( url, new NullProgressMonitor() ); URL fileUrl; PDSLabel label = new PDSLabel(); Document doc; if ( !label.parse( f.toPath() ) ) { throw new IllegalArgumentException("unable to use file "+url); } doc= label.getDocument(); XPathFactory factory = XPathFactory.newInstance(); XPath xpath = factory.newXPath(); Node dat= (Node) xpath.evaluate(String.format("/LABEL/TABLE/COLUMN[NAME='%s']",name),doc,XPathConstants.NODE); PDS3DataObject obj= new PDS3DataObject(); obj.name= name; //obj.description= (String)xpath.evaluate("/DESCRIPTION/text()",dat,XPathConstants.STRING); System.err.println("dat="+dat); return obj; } @Override public boolean reject(String suri, List problems, ProgressMonitor mon) { try { URISplit split= URISplit.parse( suri ); Map params= URISplit.parseParams(split.params); String id= params.get("arg_0"); if ( id==null ) id= params.get("id"); if ( id==null ) id= params.get("X"); if ( id==null ) id= params.get("Y"); if ( id==null ) id= params.get("Z"); File xmlfile = DataSetURI.getFile( split.resourceUri.toURL() ,new NullProgressMonitor()); URL fileUrl; try { fileUrl = getFileResource( split.resourceUri.toURL(), mon ); } catch ( IOException | URISyntaxException | ParserConfigurationException | XPathExpressionException | SAXException ex ) { problems.add("uri should point to xml or lblx file"); return true; } DataSetURI.getFile(fileUrl,mon ); if ( id==null ) { return true; } else { try { if (xmlfile.getName().endsWith("LBL") ) { getDataObjectPds3( xmlfile.toURI().toURL(), id ); return false; } else { getDataObject( xmlfile.toURI().toURL(), id ); return false; } } catch ( Exception ex ) { problems.add(ex.getMessage()); return true; } } } catch ( IOException | IllegalArgumentException | PDSException ex ) { logger.log(Level.SEVERE, null, ex); problems.add(ex.getMessage()); return false; } } /** * return a list of parameters. * @param f * @return */ private Map getDataObjectNames( URL url, ProgressMonitor mon) throws Exception { URL fileUrl= getFileResource( url, mon ); File xmlfile = DataSetURI.getFile( url,new NullProgressMonitor()); DataSetURI.getFile( fileUrl,mon ); Map result= new LinkedHashMap<>(); if ( xmlfile.getName().endsWith(".LBL") ) { // New handling for PDS3 File labelfile= xmlfile; PDSLabel label = new PDSLabel(); Document doc; if ( !label.parse( labelfile.toString() ) ) { throw new IllegalArgumentException("unable to use file "+labelfile); } doc= label.getDocument(); XPathFactory factory = XPathFactory.newInstance(); XPath xpath = factory.newXPath(); NodeList dat= (NodeList) xpath.evaluate("/LABEL/TABLE/COLUMN/NAME/text()",doc,XPathConstants.NODESET); for ( int i=0; iJAD_L50_LRS_ELC_ANY_DEF_2016240_V01.DAT } else { File xmlfile= file; DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance(); domFactory.setNamespaceAware(false); DocumentBuilder builder = domFactory.newDocumentBuilder(); Document doc = builder.parse(xmlfile); XPathExpression xp= XPathFactory.newInstance().newXPath().compile( "//Product_Observational/File_Area_Observational/File/file_name/text()"); String fname= (String)xp.evaluate( doc, XPathConstants.STRING ); if ( fname.length()==0 ) { throw new IllegalArgumentException("file name is empty or not found at "+ "//Product_Observational/File_Area_Observational/File/file_name/text()"); } URL fnameUrl= new URL( labelFile, fname ); return fnameUrl; } } @Override public List getCompletions(CompletionContext cc, ProgressMonitor mon) throws Exception { if ( cc.context.equals(CompletionContext.CONTEXT_PARAMETER_NAME) ) { logger.log(Level.FINE, "getCompletions {0}", cc.resourceURI); File xmlfile = DataSetURI.getFile(cc.resourceURI.toURL(),new NullProgressMonitor()); URL fileUrl; try { fileUrl = getFileResource( cc.resourceURI.toURL(), mon ); } catch ( IOException | URISyntaxException | ParserConfigurationException | XPathExpressionException | SAXException ex ) { List ccresult= new ArrayList<>(); ccresult.add( new CompletionContext( CompletionContext.CONTEXT_PARAMETER_NAME, "point to the xml or lblx file" ) ); return ccresult; } DataSetURI.getFile(fileUrl,mon ); Map result; result = getDataObjectNames(xmlfile.toURI().toURL(), mon); List ccresult= new ArrayList<>(); ccresult.add( new CompletionContext( CompletionContext.CONTEXT_PARAMETER_NAME, "", this, "arg_0", "Select parameter to plot", "", false ) ); for ( java.util.Map.Entry e:result.entrySet() ) { String key= e.getKey(); String desc= e.getValue(); CompletionContext cc1= new CompletionContext( CompletionContext.CONTEXT_PARAMETER_NAME, key, this, "arg_0", desc, "", true ); ccresult.add(cc1); } ccresult.add(new CompletionContext(CompletionContext.CONTEXT_PARAMETER_NAME, "X=", "values typically displayed in horizontal dimension")); ccresult.add(new CompletionContext(CompletionContext.CONTEXT_PARAMETER_NAME, "Y=", "values typically displayed in vertical dimension")); ccresult.add(new CompletionContext(CompletionContext.CONTEXT_PARAMETER_NAME, "Z=", "values typically color coded")); return ccresult; } else if ( cc.context==CompletionContext.CONTEXT_PARAMETER_VALUE ) { String parmname= CompletionContext.get( CompletionContext.CONTEXT_PARAMETER_NAME, cc ); if ( parmname.equals("id") || parmname.equals("X") || parmname.equals("Y") || parmname.equals("Z") ) { Map result= getDataObjectNames(cc.resourceURI.toURL(), mon); List ccresult= new ArrayList<>(); ccresult.add( new CompletionContext( CompletionContext.CONTEXT_PARAMETER_VALUE, "", this, "arg_0", "", null, true ) ); for ( java.util.Map.Entry e:result.entrySet() ) { String key= e.getKey(); String desc= e.getValue(); CompletionContext cc1= new CompletionContext( CompletionContext.CONTEXT_PARAMETER_VALUE, key, this, "arg_0", desc, null, true ); ccresult.add(cc1); } return ccresult; } } return Collections.emptyList(); } }