package org.das2.jythoncompletion; import java.io.IOException; import java.net.URL; import java.util.Collections; import java.util.LinkedHashMap; import java.util.List; import java.util.Map.Entry; import java.util.Set; import java.util.logging.Logger; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.das2.util.LoggerManager; import org.das2.util.filesystem.HtmlUtil; import org.das2.util.monitor.CancelledOperationException; /** * Provide a class for keeping track of the Javadoc lookups, * so this is not buried in code (so much). * @author faden@cottagesystems.com */ public class JavadocLookup { private static JavadocLookup instance; private static final Logger logger= LoggerManager.getLogger("jython.editor.completion"); /** * get the one instance * @return the instance */ public static synchronized JavadocLookup getInstance() { if ( instance==null ) { instance= new JavadocLookup(); // note the order is important, so that org.w3c.dom is matched before org. instance.setLinkForJavaSignature("javax","https://docs.oracle.com/javase/8/docs/api/"); // Java 7 docs look terrible in the popup, so there's work to be done. instance.setLinkForJavaSignature("java","https://docs.oracle.com/javase/8/docs/api/"); instance.setLinkForJavaSignature("org/w3c/dom","https://docs.oracle.com/javase/8/docs/api/"); instance.setLinkForJavaSignature("org/xml/sax","https://docs.oracle.com/javase/8/docs/api/"); instance.setLinkForJavaSignature("org/jdesktop","https://docs.oracle.com/javase/8/docs/api/"); instance.setLinkForJavaSignature("org/apache/commons/math3", "https://commons.apache.org/proper/commons-math/javadocs/api-3.6/" ); instance.setLinkForJavaSignature("org/apache/commons/math", "https://commons.apache.org/proper/commons-math/javadocs/api-2.0/" ); instance.setLinkForJavaSignature("gov/nasa/gsfc/spdf/cdfj", "https://jfaden.net/~jbf/autoplot/cdf/doc/" ); instance.setLinkForJavaSignature("org/json", "https://stleary.github.io/JSON-java/" ); instance.setLinkForJavaSignature("org/autoplot", JythonCompletionProvider.getInstance().settings.getDocHome() ); instance.setLinkForJavaSignature("org/das2", JythonCompletionProvider.getInstance().settings.getDocHome() ); instance.setLinkForJavaSignature("com/matio", JythonCompletionProvider.getInstance().settings.getDocHome() ); instance.setLinkForJavaSignature("ProGAL", JythonCompletionProvider.getInstance().settings.getDocHome() ); instance.setLinkForJavaSignature("external", JythonCompletionProvider.getInstance().settings.getDocHome() ); } return instance; } private final LinkedHashMap lookups= new LinkedHashMap<>(); /** * lookupVersions maps from URL to javadoc version. */ private final LinkedHashMap lookupVersions= new LinkedHashMap<>(); /** * return a link to the documentation for a java signature. For standard library * things, this goes to Oracle's website. For other things, this goes * to the Autoplot/Das2 javadocs. * Java8 http://docs.oracle.com/javase/8/docs/api/java/io/File.html#createTempFile-java.lang.String-java.lang.String-java.io.File- * @param signature signature like javax.swing.JCheckBox#paramString() * @return null or the link, like http://docs.oracle.com/javase/6/docs/api/javax/swing/JCheckBox#paramString() * TODO: it appears that this needs /x/y/z.html! */ public String getLinkForJavaSignature(String signature) { if ( signature==null ) return null; String lookfor= signature.replaceAll("\\.","/"); Set> entries= lookups.entrySet(); for ( Entry entry : entries ) { String key= entry.getKey(); if ( lookfor.startsWith(key) ) { String s= entry.getValue(); if ( s.startsWith("http://docs.oracle.com/javase/8/docs/api/") ) { return s + signature.replaceAll("[\\(\\)\\,]", "-"); } else if ( s.startsWith("http://www-pw.physics.uiowa.edu/~jbf/autoplot/javadoc2018/") ) { return s + signature.replaceAll("[\\(\\)\\,]", "-"); } else if ( s.startsWith("http://www-pw.physics.uiowa.edu/~jbf/autoplot/doc") || s.startsWith("https://jfaden.net/~jbf/autoplot/doc" ) ) { int i= signature.indexOf('('); if ( i>0 ) { signature= signature.substring(0,i); } if ( signature.startsWith("org/das2/qds/ops/Ops.html") ) { char let= signature.charAt(26); return s + signature.substring(0,20) + "_" + let + signature.substring(20); } else { return s + signature; } } else { String v= lookupVersions.get(s); if ( v==null || v.startsWith("1.8") ) { //v==null when there is no internet (Dallas flight) It might be nice to have offline message. return s + signature.replaceAll("[\\(\\)\\,]", "-"); } else { if ( s.endsWith("/") ) { if ( s.startsWith("file:") ) { if ( !signature.endsWith(".html") ) { signature= signature+ ".html"; } return s + signature.replaceAll(",", ", "); } else { return s + signature.replaceAll(",", ", "); } } else { // Note .zip files do not work! I thought they did... return s + "/" + signature.replaceAll(",", ", "); } } } } } return null; // old code where it's not clear what I was trying to support: //String docHome= JythonCompletionProvider.getInstance().settings().getDocHome(); //docHome= docHome.replaceAll("AUTOPLOT_HOME", FileSystem.settings().getLocalCacheDir().toString() ); //link = JythonCompletionProvider.getInstance().settings().getDocHome() + signature; } /** * add the location of the javadocs for the given path. The path should * be / separated, not period separated. * @param signatureStart e.g. "gov/nasa/gsfc/spdf/cdfj" * @param link e.g. "https://cdaweb.sci.gsfc.nasa.gov/~nand/cdfj/docs/" */ public void setLinkForJavaSignature( String signatureStart, String link ) { if ( signatureStart.startsWith("/") ) { signatureStart= signatureStart.substring(1); } if ( signatureStart.endsWith("/") ) { signatureStart= signatureStart.substring(0,signatureStart.length()-1); } if ( link.endsWith(".jar") ) { logger.fine("link cannot end with .jar, skipping."); return; } lookups.put( signatureStart+"/", link ); String tversion= lookupVersions.get(link); if ( tversion==null ) { try { String htmls= HtmlUtil.readToString( new URL(link) ); String[] ss= htmls.split("\n"); int iline=0; String version=""; Pattern p= Pattern.compile("Generated by javadoc \\((.*)\\)"); for ( String s: ss ) { iline++; Matcher m= p.matcher(s); if ( m.find() ) { version= m.group(1); break; } if ( iline>50 ) { break; } } lookupVersions.put( link, version ); } catch ( IOException | CancelledOperationException ex ) { } } } /** * given a class name, what are fully-qualified class names which match? * * @param clas * @return */ public List searchForSignature(String clas) { if ( clas.startsWith("URIT") ) { return Collections.singletonList("org.hapiserver.URITemplate"); } else { for ( Entry e: lookups.entrySet() ) { // look for list file that has all classnames in each library. } return Collections.emptyList(); } } }