package org.autoplot.datasource.jython; import java.io.File; import java.io.IOException; import java.net.URI; import java.net.URL; import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; import org.autoplot.datasource.AbstractDataSourceFactory; import org.autoplot.datasource.DataSetURI; import static org.autoplot.datasource.DataSetURI.getFile; import org.autoplot.datasource.DataSource; import org.autoplot.datasource.DataSourceRecognizer; import org.autoplot.datasource.DataSourceRegistry; import org.autoplot.datasource.URISplit; import org.das2.datum.LoggerManager; import org.das2.util.monitor.AlertNullProgressMonitor; import org.das2.util.monitor.NullProgressMonitor; /** * Creates JythonExceptionDataSource's, which are data sources defined * by Jython scripts, but the script need not be in the URI. * @author jbf */ public class JythonExtensionDataSourceFactory extends AbstractDataSourceFactory { private static final Logger logger= LoggerManager.getLogger("apdss.jyds"); /** * this is the lookup table from URI (*.sps) to script (readTypeSps.jyds) * @param uri the Autoplot URI. * @return string containing the script. */ public static String getScriptForResource( URI uri ) { String script; URISplit split= URISplit.parse(uri); String scheme= split.vapScheme; if ( scheme==null ) { scheme= "vap+"+split.ext.substring(1); } switch (scheme) { case "vap+sps": script= "https://github.com/autoplot/scripts/blob/master/formats/sps/readTypeSps.jyds"; break; case "vap+spd": script= "https://github.com/autoplot/scripts/blob/master/formats/sps/readTypeSpd.jyds"; break; case "vap+wdc": script= "https://raw.githubusercontent.com/autoplot/jyds/master/wdc_kp_ap.jyds"; break; case "vap+tfcat": script= "https://github.com/autoplot/scripts/blob/master/formats/tfcat/tfcat.jyds"; break; default: try { File f; f = getFile( uri.getRawSchemeSpecificPart(), new AlertNullProgressMonitor() ); String extr= DataSourceRecognizer.guessDataSourceType(f); if ( extr!=null ) { if ( extr.equals("vap+tfcat") ) { script= "https://github.com/autoplot/scripts/blob/master/formats/tfcat/tfcat.jyds"; break; } } } catch (IOException ex) { logger.log(Level.SEVERE, null, ex); } throw new IllegalArgumentException("resource extension is not supported: "+split.ext); } String ext= scheme.substring(4); String alt; alt= System.getProperty("jydsExtension_"+ext,""); if ( alt.length()>0 ) { logger.log(Level.FINE, "system property jydsExtension_{0}={1}", new Object[]{ ext, alt}); script= alt; } else { logger.log(Level.FINER, "System.getProperty(\"jydsExtension_{0}\",\"\") returns \"\"", new Object[]{ ext }); } logger.log(Level.FINE, "Using script {0}", script); return script; } /** * include an internal version of the script, so that the data source will * work offline, for example when presenting the data source to a group * of new users at a conference without network access. * @param uri the Autoplot URI. * @return null or the name of the file to use. */ public static String getInternalScriptForResource(URI uri) { String script; URISplit split= URISplit.parse(uri); String scheme= split.vapScheme; if ( scheme==null ) { scheme= "vap+"+split.ext.substring(1); } switch (scheme) { case "vap+sps": script= "/readTypeSps.jyds"; break; case "vap+spd": script= "/readTypeSpd.jyds"; break; case "vap+wdc": script= "/wdc_kp_ap.jyds"; break; default: throw new IllegalArgumentException("resource extension is not supported: "+split.ext); } try { File scriptFile= DataSetURI.downloadResourceAsTempFile( JythonExtensionDataSourceFactory.class.getResource(script), new NullProgressMonitor() ); return scriptFile.toURI().toString(); } catch ( IOException ex ) { logger.log( Level.WARNING, ex.getMessage(), ex ); return null; } } /** * return the URI which would be used for this resource, if it were * called directly. * @param uri * @return */ public static String getJydsUri( URI uri ) { String script= getScriptForResource(uri); try { File scriptFile= DataSetURI.getFile( new URL(script), new NullProgressMonitor() ); logger.log(Level.FINE, "can be downloaded: {0}", scriptFile); } catch ( IOException ex ) { logger.log(Level.INFO, "unable to read remote script {0}, using internal copy", script); script= JythonExtensionDataSourceFactory.getInternalScriptForResource(uri); if ( script==null ) { throw new IllegalArgumentException("Unable to locate script"); } } URISplit split= URISplit.parse(uri); Map params= URISplit.parseParams(split.params); params.put( JythonDataSource.PARAM_SCRIPT, script ); split.params= URISplit.formatParams(params); return URISplit.format(split); } @Override public DataSource getDataSource(URI uri) throws Exception { return new JythonExtensionDataSource(uri); } }