From: <ha...@us...> - 2009-11-22 19:16:44
|
Revision: 11776 http://jmol.svn.sourceforge.net/jmol/?rev=11776&view=rev Author: hansonr Date: 2009-11-22 19:16:27 +0000 (Sun, 22 Nov 2009) Log Message: ----------- version=11.9.10_dev # bug fix: occasional null pointer error during ZAP due to continued rendering by # previous graphic painting thread # code: refactoring of FileManager and clean-up of Viewer code # in relation to model loading. Modified Paths: -------------- trunk/Jmol/src/org/jmol/api/JmolViewer.java trunk/Jmol/src/org/jmol/applet/Jmol.java trunk/Jmol/src/org/jmol/script/ScriptEvaluator.java trunk/Jmol/src/org/jmol/viewer/ActionManager.java trunk/Jmol/src/org/jmol/viewer/FileManager.java trunk/Jmol/src/org/jmol/viewer/Jmol.properties trunk/Jmol/src/org/jmol/viewer/MouseManager.java trunk/Jmol/src/org/jmol/viewer/RepaintManager.java trunk/Jmol/src/org/jmol/viewer/Viewer.java Modified: trunk/Jmol/src/org/jmol/api/JmolViewer.java =================================================================== --- trunk/Jmol/src/org/jmol/api/JmolViewer.java 2009-11-22 19:15:53 UTC (rev 11775) +++ trunk/Jmol/src/org/jmol/api/JmolViewer.java 2009-11-22 19:16:27 UTC (rev 11776) @@ -361,7 +361,7 @@ abstract public boolean showModelSetDownload(); - abstract public void repaintView(); + abstract public void notifyViewerRepaintDone(); abstract public boolean getBooleanProperty(String propertyName); abstract public boolean getBooleanProperty(String key, boolean doICare); Modified: trunk/Jmol/src/org/jmol/applet/Jmol.java =================================================================== --- trunk/Jmol/src/org/jmol/applet/Jmol.java 2009-11-22 19:15:53 UTC (rev 11775) +++ trunk/Jmol/src/org/jmol/applet/Jmol.java 2009-11-22 19:16:27 UTC (rev 11776) @@ -494,7 +494,7 @@ if (REQUIRE_PROGRESSBAR && !isSigned && !hasProgressBar && paintCounter < 30 && (paintCounter & 1) == 0) { printProgressbarMessage(g); - viewer.repaintView(); + viewer.notifyViewerRepaintDone(); } else { //System.out.println("UPDATE1: " + source + " " + Thread.currentThread()); //System.out.println(fullName + " update gRight = " + gRight); @@ -513,7 +513,8 @@ private final static String[] progressbarMsgs = { "Jmol developer alert!", "", - "Please use jmol.js. You are missing the require 'progressbar' parameter.", + "Please use jmol.js. You are missing the ", + "required 'progressbar' parameter.", " <param name='progressbar' value='true' />", }; private void printProgressbarMessage(Graphics g) { Modified: trunk/Jmol/src/org/jmol/script/ScriptEvaluator.java =================================================================== --- trunk/Jmol/src/org/jmol/script/ScriptEvaluator.java 2009-11-22 19:15:53 UTC (rev 11775) +++ trunk/Jmol/src/org/jmol/script/ScriptEvaluator.java 2009-11-22 19:16:27 UTC (rev 11776) @@ -24,6 +24,8 @@ package org.jmol.script; import java.awt.Image; +import java.io.BufferedReader; +import java.io.StringReader; import java.util.BitSet; import java.util.Enumeration; import java.util.Hashtable; @@ -6516,8 +6518,9 @@ String modelName = null; String filename = null; String[] filenames = null; + String[] tempFileInfo = null; int tokType = 0; - boolean doLoadFiles = (!isSyntaxCheck || isCmdLine_C_Option); + boolean doLoadFiles = (!isSyntaxCheck || isCmdLine_C_Option); String errMsg = null; String sOptions = ""; if (statementLength == 1) { @@ -6535,14 +6538,15 @@ i = 2; loadScript.append(" " + modelName); isAppend = (modelName.equalsIgnoreCase("append")); - boolean atomDataOnly = Parser.isOneOf(modelName.toLowerCase(), - JmolConstants.LOAD_ATOM_DATA_TYPES); - if (atomDataOnly) { + tokType = (Parser.isOneOf(modelName.toLowerCase(), + JmolConstants.LOAD_ATOM_DATA_TYPES) ? Token + .getTokenFromName(modelName.toLowerCase()).tok : 0); + if (tokType > 0) { htParams.put("atomDataOnly", Boolean.TRUE); htParams.put("modelNumber", new Integer(1)); - tokType = Token.getTokenFromName(modelName.toLowerCase()).tok; if (tokType == Token.vibration) tokType = Token.vibXyz; + tempFileInfo = viewer.getFileInfo(); } if (isAppend && ((filename = optParameterAsString(2)) @@ -6552,7 +6556,7 @@ loadScript.append(" " + modelName); i++; } - if (atomDataOnly) + if (tokType > 0) isAppend = true; if (modelName.equalsIgnoreCase("trajectory") || modelName.equalsIgnoreCase("models")) { @@ -6752,15 +6756,29 @@ if (!doLoadFiles) return; if (filenames == null) { - //standard file loading here + // standard file loading here if (filename.startsWith("@") && filename.length() > 1) { htParams.put("fileData", getStringParameter(filename.substring(1), false)); filename = "string"; } } - errMsg = viewer.loadModelFromFile(filename, filenames, isAppend, htParams, tokType); + + // OK, we are ready to load the data and create the model set + + errMsg = viewer.loadModelFromFile(filename, filenames, isAppend, htParams, + tokType); + + if (tokType > 0) { + // we are just loading an atom property + // reset the file info in FileManager, check for errors, and return + viewer.setFileInfo(tempFileInfo); + if (errMsg != null && !isCmdLine_c_or_C_Option) + evalError(errMsg, null); + return; + } if (filenames == null) { + // a single file or string -- complete the loadScript loadScript.append(" "); if (!filename.equals("string") && !filename.equals("string[]")) loadScript.append("/*file*/"); @@ -6768,18 +6786,16 @@ .get("fullPathName"))); loadScript.append(sOptions); } - if (tokType == 0) - viewer.addLoadScript(loadScript.toString()); + viewer.addLoadScript(loadScript.toString()); if (errMsg != null && !isCmdLine_c_or_C_Option) { if (errMsg.indexOf("NOTE: file recognized as a script file:") == 0) { viewer.addLoadScript("-"); - errMsg = TextFormat.trim(errMsg,"\n"); + errMsg = TextFormat.trim(errMsg, "\n"); runScript("script \"" + errMsg.substring(40) + "\""); return; } evalError(errMsg, null); } - if (isAppend && (appendNew || nFiles > 1)) { viewer.setAnimationRange(-1, -1); viewer.setCurrentModelIndex(modelCount); @@ -6799,7 +6815,7 @@ } if (msg.length() > 0) Logger.info(msg); - if (defaultScript.length() > 0 && !isCmdLine_c_or_C_Option) + if (defaultScript.length() > 0 && !isCmdLine_c_or_C_Option) // NOT checking embedded scripts in some cases runScript(defaultScript); } @@ -12863,7 +12879,7 @@ sdata = TextFormat.replaceAllCharacters(sdata, "{,}|", ' '); if (logMessages) Logger.debug("pmesh inline data:\n" + sdata); - t = (isSyntaxCheck ? null : viewer.getBufferedReaderForString(sdata)); + t = (isSyntaxCheck ? null : new BufferedReader(new StringReader(sdata))); } else { if (thisCommand.indexOf("# FILE" + nFiles + "=") >= 0) filename = extractCommandOption("# FILE" + nFiles); Modified: trunk/Jmol/src/org/jmol/viewer/ActionManager.java =================================================================== --- trunk/Jmol/src/org/jmol/viewer/ActionManager.java 2009-11-22 19:15:53 UTC (rev 11775) +++ trunk/Jmol/src/org/jmol/viewer/ActionManager.java 2009-11-22 19:16:27 UTC (rev 11776) @@ -237,8 +237,10 @@ Binding dragBinding; Binding rasmolBinding; + ActionManager aman; ActionManager(Viewer viewer) { this.viewer = viewer; + aman = this; binding = jmolBinding = new JmolBinding(); } @@ -940,8 +942,7 @@ Thread.currentThread().setPriority(Thread.MIN_PRIORITY); int hoverDelay; try { - while (hoverWatcherThread != null - && (hoverDelay = viewer.getHoverDelay()) > 0) { + while (Thread.currentThread().equals(hoverWatcherThread) && (hoverDelay = viewer.getHoverDelay()) > 0) { Thread.sleep(hoverDelay); if (xCurrent == mouseMovedX && yCurrent == mouseMovedY && timeCurrent == mouseMovedTime) { // the last event was mouse @@ -949,12 +950,13 @@ long currentTime = System.currentTimeMillis(); int howLong = (int) (currentTime - mouseMovedTime); if (howLong > hoverDelay) { - if (hoverWatcherThread != null && !viewer.getInMotion() + if (Thread.currentThread().equals(hoverWatcherThread) && !viewer.getInMotion() && !viewer.getSpinOn() && !viewer.getNavOn() && !viewer.checkObjectHovered(xCurrent, yCurrent)) { int atomIndex = viewer.findNearestAtomIndex(xCurrent, yCurrent); - if (atomIndex >= 0) + if (atomIndex >= 0) { hoverOn(atomIndex); + } } } } @@ -964,7 +966,6 @@ } catch (Exception ie) { Logger.debug("Hover Exception: " + ie); } - hoverWatcherThread = null; } } Modified: trunk/Jmol/src/org/jmol/viewer/FileManager.java =================================================================== --- trunk/Jmol/src/org/jmol/viewer/FileManager.java 2009-11-22 19:15:53 UTC (rev 11775) +++ trunk/Jmol/src/org/jmol/viewer/FileManager.java 2009-11-22 19:16:27 UTC (rev 11776) @@ -61,44 +61,99 @@ import java.util.Hashtable; import java.util.Vector; -/* *************************************************************** - * will not work with applet - import java.net.URI; - import java.net.URISyntaxException; - import java.util.Enumeration; - import org.openscience.jmol.io.ChemFileReader; - import org.openscience.jmol.io.ReaderFactory; - */ - public class FileManager { protected Viewer viewer; - // for applet proxy - private URL appletDocumentBase = null; - private URL appletCodeBase = null; //unused currently - private String appletProxy; + FileManager(Viewer viewer) { + this.viewer = viewer; + clear(); + } - // for expanding names into full path names - //private boolean isURL; + void clear() { + setLoadScript("", false); + fullPathName = fileName = nameAsGiven = "zapped"; + } + + private String loadScript; + + String getLoadScript() { + return loadScript; + } + + private void setLoadScript(String script, boolean isAppend) { + if (loadScript == null || !isAppend) + loadScript = ""; + loadScript += viewer.getLoadState(); + addLoadScript(script); + } + + void addLoadScript(String script) { + if (script == null) + return; + if (script.equals("-")) { + loadScript = ""; + return; + } + loadScript += " " + script + ";\n"; + } + private String nameAsGiven = "zapped"; private String fullPathName; private String fileName; - private String fileType; - private String inlineData; + //TODO: We might consider an option to not preserve inlineData in certain cases where + // data are huge. The reason to save the data is that we can then use load "" + // + void setFileInfo(String[] fileInfo) { + // used by ScriptEvaluator dataFrame and load methods to temporarily save the state here + fullPathName = fileInfo[0]; + fileName = fileInfo[1]; + nameAsGiven = fileInfo[2]; + inlineData = fileInfo[3]; + loadScript = fileInfo[4]; + } + + String[] getFileInfo() { + // used by ScriptEvaluator dataFrame method + return new String[] { fullPathName, fileName, nameAsGiven, inlineData, loadScript }; + } + + String getFullPathName() { + return fullPathName != null ? fullPathName : nameAsGiven; + } + + String getFileName() { + return fileName != null ? fileName : nameAsGiven; + } + String getInlineData(int iData) { return (iData < 0 ? inlineData : ""); } - private String loadScript; + // for applet proxy + private URL appletDocumentBase = null; + private URL appletCodeBase = null; //unused currently + private String appletProxy; - FileManager(Viewer viewer) { - this.viewer = viewer; - clear(); + String getAppletDocumentBase() { + return (appletDocumentBase == null ? "" : appletDocumentBase.toString()); } + void setAppletContext(URL documentBase, URL codeBase, String jmolAppletProxy) { + appletDocumentBase = documentBase; + appletCodeBase = codeBase; + appletProxy = jmolAppletProxy; + Logger.info("appletDocumentBase=" + appletDocumentBase + + "\nappletCodeBase=" + appletCodeBase); + } + + void setAppletProxy(String appletProxy) { + this.appletProxy = (appletProxy == null || appletProxy.length() == 0 ? null + : appletProxy); + } + String getState(StringBuffer sfunc) { StringBuffer commands = new StringBuffer(); if (sfunc != null) { @@ -134,35 +189,22 @@ return null; } - void clear() { - setLoadScript("", false); - fullPathName = fileName = nameAsGiven = "zapped"; + private static BufferedReader getBufferedReaderForString(String string) { + return new BufferedReader(new StringReader(string)); } - String getLoadScript() { - return loadScript; + private String getZipDirectoryAsString(String fileName) { + return ZipUtil + .getZipDirectoryAsStringAndClose((InputStream) getInputStreamOrErrorMessageFromName( + fileName, false)); } - private void setLoadScript(String script, boolean isAppend) { - if (loadScript == null || !isAppend) - loadScript = ""; - loadScript += viewer.getLoadState(); - addLoadScript(script); - } - - void addLoadScript(String script) { - if (script == null) - return; - if (script.equals("-")) { - loadScript = ""; - return; - } - loadScript += " " + script + ";\n"; - } - + /////////////// createAtomSetCollectionFromXXX methods ///////////////// + // where XXX = File, Files, String, Strings, ArrayData, DOM, Reader + /* - * note -- getAtomSetCollectionFromXXX methods + * note -- createAtomSetCollectionFromXXX methods * were "openXXX" before refactoring 11/29/2008 -- BH * * The problem was that while they did open the file, they @@ -188,7 +230,7 @@ setLoadScript(loadScript, isAppend); int pt = name.indexOf("::"); nameAsGiven = (pt >= 0 ? name.substring(pt + 2) : name); - fileType = (pt >= 0 ? name.substring(0, pt) : null); + String fileType = (pt >= 0 ? name.substring(0, pt) : null); Logger.info("\nFileManager.getAtomSetCollectionFromFile(" + nameAsGiven + ")" + (name.equals(nameAsGiven) ? "" : " //" + name)); fullPathName = null; @@ -218,7 +260,7 @@ for (int i = 0; i < fileNames.length; i++) { int pt = fileNames[i].indexOf("::"); nameAsGiven = (pt >= 0 ? fileNames[i].substring(pt + 2) : fileNames[i]); - fileType = (pt >= 0 ? fileNames[i].substring(0, pt) : null); + String fileType = (pt >= 0 ? fileNames[i].substring(0, pt) : null); String[] names = classifyName(nameAsGiven, true); if (names.length == 1) return names[0]; @@ -326,138 +368,162 @@ Reader reader, Hashtable htParams) { this.fullPathName = fullPathName; fileName = name; - fileType = null; FileReader fileReader = new FileReader(fullPathName, fullPathName, - fileType, new BufferedReader(reader), htParams); + null, new BufferedReader(reader), htParams); fileReader.run(); return fileReader.atomSetCollection; } - public Object getFileAsBytes(String name) { - //?? used by eval of "WRITE FILE" - // will be full path name - if (name == null) - return null; - String[] subFileList = null; - if (name.indexOf("|") >= 0) - name = (subFileList = TextFormat.split(name, "|"))[0]; - Object t = getInputStreamOrErrorMessageFromName(name, false); - if (t instanceof String) - return "Error:" + t; - try { - BufferedInputStream bis = new BufferedInputStream((InputStream) t, 8192); - InputStream is = bis; - Object bytes = (ZipUtil.isZipFile(is) && subFileList != null - && 1 < subFileList.length ? ZipUtil.getZipFileContentsAsBytes(is, - subFileList, 1) : ZipUtil.getStreamAsBytes(bis)); - is.close(); - return bytes; - } catch (Exception ioe) { - return ioe.getMessage(); - } + /////////////// generally useful file I/O methods ///////////////// + + // mostly internal to FileManager and its enclosed classes + + BufferedInputStream getBufferedInputStream(String fullPathName) { + Object ret = getBufferedReaderOrErrorMessageFromName(fullPathName, + new String[2], true, true); + return (ret instanceof BufferedInputStream ? (BufferedInputStream) ret + : null); } - /** - * - * @param data - * [0] initially path name, but returned as full path name; [1]file - * contents (directory listing for a ZIP/JAR file) or error string - * @param nBytesMax - * @param doSpecialLoad - * @return true if successful; false on error - */ - - boolean getFileDataOrErrorAsString(String[] data, int nBytesMax, boolean doSpecialLoad) { - data[1] = ""; - String name = data[0]; - if (name == null) - return false; - Object t = getBufferedReaderOrErrorMessageFromName(name, data, false, doSpecialLoad); - if (t instanceof String) { - data[1] = (String) t; - return false; - } + Object getInputStreamOrErrorMessageFromName(String name, boolean showMsg) { + String errorMessage = null; + int iurlPrefix; + for (iurlPrefix = urlPrefixes.length; --iurlPrefix >= 0;) + if (name.startsWith(urlPrefixes[iurlPrefix])) + break; + boolean isURL = (iurlPrefix >= 0); + boolean isApplet = (appletDocumentBase != null); + InputStream in = null; + //int length; try { - BufferedReader br = (BufferedReader) t; - StringBuffer sb = new StringBuffer(8192); - String line; - if (nBytesMax == Integer.MAX_VALUE) { - while ((line = br.readLine()) != null) - sb.append(line).append('\n'); + if (isApplet || isURL) { + if (isApplet && isURL && appletProxy != null) + name = appletProxy + "?url=" + URLEncoder.encode(name, "utf-8"); + URL url = (isApplet ? new URL(appletDocumentBase, name) : new URL(name)); + name = url.toString(); + if (showMsg) + Logger.info("FileManager opening " + url.toString()); + URLConnection conn = url.openConnection(); + //length = conn.getContentLength(); + in = conn.getInputStream(); } else { - int n = 0; - int len; - while (n < nBytesMax && (line = br.readLine()) != null) { - if (nBytesMax - n < (len = line.length()) + 1) - line = line.substring(0, nBytesMax - n - 1); - sb.append(line).append('\n'); - n += len + 1; - } + if (showMsg) + Logger.info("FileManager opening " + name); + File file = new File(name); + //length = (int) file.length(); + in = new FileInputStream(file); } - br.close(); - data[1] = sb.toString(); - return true; - } catch (Exception ioe) { - data[1] = ioe.getMessage(); - return false; + return in; + } catch (Exception e) { + try { + if (in != null) + in.close(); + } catch (IOException e1) { + } + errorMessage = "" + e; } + return errorMessage; } - Object getFileAsImage(String name, Hashtable htParams) { - if (name == null) - return ""; + Object getBufferedReaderOrErrorMessageFromName(String name, + String[] fullPathNameReturn, + boolean isBinary, boolean doSpecialLoad) { String[] names = classifyName(name, true); if (names == null) return "cannot read file name: " + name; - Image image = null; - //try { - fullPathName = names[0].replace('\\', '/'); - if (urlTypeIndex(fullPathName) >= 0) - try { - image = Toolkit.getDefaultToolkit().createImage(new URL(fullPathName)); - } catch (Exception e) { - return "bad URL: " + fullPathName; + if (fullPathNameReturn != null) + fullPathNameReturn[0] = names[0].replace('\\', '/'); + return getUnzippedBufferedReaderOrErrorMessageFromName(names[0], false, + isBinary, false, doSpecialLoad); + } + + Object getUnzippedBufferedReaderOrErrorMessageFromName( + String name, + boolean allowZipStream, + boolean asInputStream, + boolean isTypeCheckOnly, + boolean doSpecialLoad) { + String[] subFileList = null; + String[] info = (doSpecialLoad ? viewer.getModelAdapter().specialLoad(name, + "filesNeeded?") : null); + if (info != null) { + if (isTypeCheckOnly) + return info; + if (info[2] != null) { + String header = info[1]; + Hashtable fileData = new Hashtable(); + if (info.length == 3) { + // we need information from the output file, info[2] + String name0 = getObjectAsSections(info[2], header, fileData); + fileData.put("OUTPUT", name0); + info = viewer.getModelAdapter().specialLoad(name, + (String) fileData.get(name0)); + if (info.length == 3) { + // might have a second option + name0 = getObjectAsSections(info[2], header, fileData); + fileData.put("OUTPUT", name0); + info = viewer.getModelAdapter().specialLoad(info[1], + (String) fileData.get(name0)); + } + } + // load each file individually, but return files IN ORDER + StringBuffer sb = new StringBuffer(); + sb.append(fileData.get(fileData.get("OUTPUT"))); + for (int i = 2; i < info.length; i++) { + name = info[i]; + name = getObjectAsSections(name, header, fileData); + Logger.info("reading " + name); + String s = (String) fileData.get(name); + sb.append(s); + } + return getBufferedReaderForString(sb.toString()); } - else - image = Toolkit.getDefaultToolkit().createImage(fullPathName); + // continuing... + // here, for example, for an SPT file load that is not just a type check + // (type check is only for application file opening and drag-drop to + // determine if + // script or load command should be used) + } + if (name.indexOf("|") >= 0) + name = (subFileList = TextFormat.split(name, "|"))[0]; + Object t = getInputStreamOrErrorMessageFromName(name, true); + if (t instanceof String) + return t; try { - MediaTracker mediaTracker = new MediaTracker(viewer.getDisplay()); - mediaTracker.addImage(image, 0); - mediaTracker.waitForID(0); - /* SUN but here for malformed URL - can't trap - Uncaught error fetching image: - java.lang.NullPointerException - at sun.net.www.ParseUtil.toURI(Unknown Source) - at sun.net.www.protocol.http.HttpURLConnection.plainConnect(Unknown Source) - at sun.net.www.protocol.http.HttpURLConnection.connect(Unknown Source) - at sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown Source) - at sun.awt.image.URLImageSource.getDecoder(Unknown Source) - at sun.awt.image.InputStreamImageSource.doFetch(Unknown Source) - at sun.awt.image.ImageFetcher.fetchloop(Unknown Source) - at sun.awt.image.ImageFetcher.run(Unknown Source) - */ - } catch (Exception e) { - return e.getMessage() + " opening " + fullPathName; + BufferedInputStream bis = new BufferedInputStream((InputStream) t, 8192); + InputStream is = bis; + if (CompoundDocument.isCompoundDocument(is)) { + CompoundDocument doc = new CompoundDocument(bis); + return getBufferedReaderForString(doc.getAllData("Molecule").toString()); + } else if (ZipUtil.isGzip(is)) { + do { + is = new BufferedInputStream(new GZIPInputStream(is)); + } while (ZipUtil.isGzip(is)); + } else if (ZipUtil.isZipFile(is)) { + if (allowZipStream) + return new ZipInputStream(bis); + if (asInputStream) + return (InputStream) ZipUtil.getZipFileContents(is, subFileList, 1, + true); + // danger -- converting bytes to String here. + // we lose 128-156 or so. + String s = (String) ZipUtil.getZipFileContents(is, subFileList, 1, + false); + is.close(); + return getBufferedReaderForString(s); + } + if (asInputStream) + return is; + return new BufferedReader(new InputStreamReader(is)); + } catch (Exception ioe) { + return ioe.getMessage(); } - if (image.getWidth(null) < 1) - return "invalid or missing image " + fullPathName; - htParams.put("fullPathName", fullPathName); - return image; } - private String getObjectAsSections(String[] info, Hashtable fileData) { - // load each file individually, but return files IN ORDER - String header = info[1]; - StringBuffer sb = new StringBuffer(); - sb.append(fileData.get(fileData.get("OUTPUT"))); - for (int i = 2; i < info.length; i++) { - String name = info[i]; - name = getObjectAsSections(name, header, fileData); - Logger.info("reading " + name); - String s = (String) fileData.get(name); - sb.append(s); - } - return sb.toString(); + String[] getZipDirectory(String fileName, boolean addManifest) { + return ZipUtil.getZipDirectoryAndClose( + (InputStream) getInputStreamOrErrorMessageFromName(fileName, false), + addManifest); } /** @@ -551,49 +617,118 @@ return name0; } - String getFullPathName() { - return fullPathName != null ? fullPathName : nameAsGiven; - } - - void setFileInfo(String[] fileInfo) { + Object getFileAsBytes(String name) { + //?? used by eval of "WRITE FILE" + // will be full path name + if (name == null) + return null; + String[] subFileList = null; + if (name.indexOf("|") >= 0) + name = (subFileList = TextFormat.split(name, "|"))[0]; + Object t = getInputStreamOrErrorMessageFromName(name, false); + if (t instanceof String) + return "Error:" + t; try { - fullPathName = fileInfo[0]; - fileName = fileInfo[1]; - inlineData = fileInfo[2]; - loadScript = fileInfo[3]; - } catch (Exception e) { - Logger.error("Exception saving file info: " + e.getMessage()); + BufferedInputStream bis = new BufferedInputStream((InputStream) t, 8192); + InputStream is = bis; + Object bytes = (ZipUtil.isZipFile(is) && subFileList != null + && 1 < subFileList.length ? ZipUtil.getZipFileContentsAsBytes(is, + subFileList, 1) : ZipUtil.getStreamAsBytes(bis)); + is.close(); + return bytes; + } catch (Exception ioe) { + return ioe.getMessage(); } } - String[] getFileInfo() { - return new String[] { fullPathName, fileName, inlineData, loadScript }; - } + /** + * + * @param data + * [0] initially path name, but returned as full path name; [1]file + * contents (directory listing for a ZIP/JAR file) or error string + * @param nBytesMax + * @param doSpecialLoad + * @return true if successful; false on error + */ - String getFileName() { - return fileName != null ? fileName : nameAsGiven; + boolean getFileDataOrErrorAsString(String[] data, int nBytesMax, boolean doSpecialLoad) { + data[1] = ""; + String name = data[0]; + if (name == null) + return false; + Object t = getBufferedReaderOrErrorMessageFromName(name, data, false, doSpecialLoad); + if (t instanceof String) { + data[1] = (String) t; + return false; + } + try { + BufferedReader br = (BufferedReader) t; + StringBuffer sb = new StringBuffer(8192); + String line; + if (nBytesMax == Integer.MAX_VALUE) { + while ((line = br.readLine()) != null) + sb.append(line).append('\n'); + } else { + int n = 0; + int len; + while (n < nBytesMax && (line = br.readLine()) != null) { + if (nBytesMax - n < (len = line.length()) + 1) + line = line.substring(0, nBytesMax - n - 1); + sb.append(line).append('\n'); + n += len + 1; + } + } + br.close(); + data[1] = sb.toString(); + return true; + } catch (Exception ioe) { + data[1] = ioe.getMessage(); + return false; + } } - String getAppletDocumentBase() { - if (appletDocumentBase == null) + Object getFileAsImage(String name, Hashtable htParams) { + if (name == null) return ""; - return appletDocumentBase.toString(); + String[] names = classifyName(name, true); + if (names == null) + return "cannot read file name: " + name; + Image image = null; + //try { + fullPathName = names[0].replace('\\', '/'); + if (urlTypeIndex(fullPathName) >= 0) + try { + image = Toolkit.getDefaultToolkit().createImage(new URL(fullPathName)); + } catch (Exception e) { + return "bad URL: " + fullPathName; + } + else + image = Toolkit.getDefaultToolkit().createImage(fullPathName); + try { + MediaTracker mediaTracker = new MediaTracker(viewer.getDisplay()); + mediaTracker.addImage(image, 0); + mediaTracker.waitForID(0); + /* SUN but here for malformed URL - can't trap + Uncaught error fetching image: + java.lang.NullPointerException + at sun.net.www.ParseUtil.toURI(Unknown Source) + at sun.net.www.protocol.http.HttpURLConnection.plainConnect(Unknown Source) + at sun.net.www.protocol.http.HttpURLConnection.connect(Unknown Source) + at sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown Source) + at sun.awt.image.URLImageSource.getDecoder(Unknown Source) + at sun.awt.image.InputStreamImageSource.doFetch(Unknown Source) + at sun.awt.image.ImageFetcher.fetchloop(Unknown Source) + at sun.awt.image.ImageFetcher.run(Unknown Source) + */ + } catch (Exception e) { + return e.getMessage() + " opening " + fullPathName; + } + if (image.getWidth(null) < 1) + return "invalid or missing image " + fullPathName; + htParams.put("fullPathName", fullPathName); + return image; } - void setAppletContext(URL documentBase, URL codeBase, String jmolAppletProxy) { - appletDocumentBase = documentBase; - appletCodeBase = codeBase; - Logger.info("appletDocumentBase=" + appletDocumentBase - + "\nappletCodeBase=" + appletCodeBase); - // dumpDocumentBase("" + documentBase); - appletProxy = jmolAppletProxy; - } - - void setAppletProxy(String appletProxy) { - this.appletProxy = (appletProxy == null || appletProxy.length() == 0 ? null - : appletProxy); - } - private final static int URL_LOCAL = 3; private final static String[] urlPrefixes = { "http:", "https:", "ftp:", "file:" }; @@ -607,10 +742,6 @@ return -1; } - static String shortNameOf(String name) { - name = TextFormat.trim(name.replace('\\', '/'), "/"); - return name.substring(name.lastIndexOf("/") + 1); - } /** * * @param name @@ -675,6 +806,20 @@ return names; } + private static String addDirectory(String defaultDirectory, String name) { + if (defaultDirectory.length() == 0) + return name; + char ch = (name.length() > 0 ? name.charAt(0) : ' '); + String s = defaultDirectory.toLowerCase(); + if ((s.endsWith(".zip") || s.endsWith(".tar")) && ch != '|' && ch != '/') + defaultDirectory += "|"; + return defaultDirectory + + (ch == '/' + || ch == '/' + || (ch = defaultDirectory.charAt(defaultDirectory.length() - 1)) == '|' + || ch == '/' ? "" : "/") + name; + } + String getDefaultDirectory(String name) { String[] names = classifyName(name, true); if (names == null) @@ -683,7 +828,7 @@ return (names == null ? "" : name.substring(0, name.lastIndexOf("/"))); } - public static String fixPath(String path) { + private static String fixPath(String path) { path = path.replace('\\', '/'); path = TextFormat.simpleReplace(path, "/./", "/"); int pt = path.lastIndexOf("//") + 1; @@ -705,7 +850,7 @@ return protocol + path; } - public String getFullPath(String name, boolean addUrlPrefix) { + String getFullPath(String name, boolean addUrlPrefix) { String[] names = classifyName(name, false); return (names == null ? "" : addUrlPrefix ? names[2] : names[0].replace( '\\', '/')); @@ -766,159 +911,6 @@ return (dir == null ? file : fixPath(dir.toString() + "/" + file)); } - private static String addDirectory(String defaultDirectory, String name) { - if (defaultDirectory.length() == 0) - return name; - char ch = (name.length() > 0 ? name.charAt(0) : ' '); - String s = defaultDirectory.toLowerCase(); - if ((s.endsWith(".zip") || s.endsWith(".tar")) && ch != '|' && ch != '/') - defaultDirectory += "|"; - return defaultDirectory - + (ch == '/' - || ch == '/' - || (ch = defaultDirectory.charAt(defaultDirectory.length() - 1)) == '|' - || ch == '/' ? "" : "/") + name; - } - - Object getInputStreamOrErrorMessageFromName(String name, boolean showMsg) { - String errorMessage = null; - int iurlPrefix; - for (iurlPrefix = urlPrefixes.length; --iurlPrefix >= 0;) - if (name.startsWith(urlPrefixes[iurlPrefix])) - break; - boolean isURL = (iurlPrefix >= 0); - boolean isApplet = (appletDocumentBase != null); - InputStream in = null; - //int length; - try { - if (isApplet || isURL) { - if (isApplet && isURL && appletProxy != null) - name = appletProxy + "?url=" + URLEncoder.encode(name, "utf-8"); - URL url = (isApplet ? new URL(appletDocumentBase, name) : new URL(name)); - name = url.toString(); - if (showMsg) - Logger.info("FileManager opening " + url.toString()); - URLConnection conn = url.openConnection(); - //length = conn.getContentLength(); - in = conn.getInputStream(); - } else { - if (showMsg) - Logger.info("FileManager opening " + name); - File file = new File(name); - //length = (int) file.length(); - in = new FileInputStream(file); - } - return in; - } catch (Exception e) { - try { - if (in != null) - in.close(); - } catch (IOException e1) { - } - errorMessage = "" + e; - } - return errorMessage; - } - - static BufferedReader getBufferedReaderForString(String string) { - return new BufferedReader(new StringReader(string)); - } - - Object getBufferedReaderOrErrorMessageFromName(String name, - String[] fullPathNameReturn, - boolean isBinary, boolean doSpecialLoad) { - String[] names = classifyName(name, true); - if (names == null) - return "cannot read file name: " + name; - if (fullPathNameReturn != null) - fullPathNameReturn[0] = names[0].replace('\\', '/'); - return getUnzippedBufferedReaderOrErrorMessageFromName(names[0], false, - isBinary, false, doSpecialLoad); - } - - Object getUnzippedBufferedReaderOrErrorMessageFromName( - String name, - boolean allowZipStream, - boolean asInputStream, - boolean isTypeCheckOnly, boolean doSpecialLoad) { - String[] subFileList = null; - String[] info = (doSpecialLoad ? viewer.getModelAdapter().specialLoad(name, "filesNeeded?") : null); - if (info != null) { - if (isTypeCheckOnly) - return info; - if (info[2] != null) { - String header = info[1]; - Hashtable fileData = new Hashtable(); - if (info.length == 3) { - // we need information from the output file, info[2] - String name0 = getObjectAsSections(info[2], header, fileData); - fileData.put("OUTPUT", name0); - info = viewer.getModelAdapter().specialLoad(name, - (String) fileData.get(name0)); - if (info.length == 3) { - // might have a second option - name0 = getObjectAsSections(info[2], header, fileData); - fileData.put("OUTPUT", name0); - info = viewer.getModelAdapter().specialLoad(info[1], - (String) fileData.get(name0)); - } - } - return getBufferedReaderForString(getObjectAsSections(info, fileData)); - } - // continuing... - // here, for example, for an SPT file load that is not just a type check - // (type check is only for application file opening and drag-drop to - // determine if - // script or load command should be used) - } - if (name.indexOf("|") >= 0) - name = (subFileList = TextFormat.split(name, "|"))[0]; - Object t = getInputStreamOrErrorMessageFromName(name, true); - if (t instanceof String) - return t; - try { - BufferedInputStream bis = new BufferedInputStream((InputStream) t, 8192); - InputStream is = bis; - if (CompoundDocument.isCompoundDocument(is)) { - CompoundDocument doc = new CompoundDocument(bis); - return getBufferedReaderForString(doc.getAllData("Molecule").toString()); - } else if (ZipUtil.isGzip(is)) { - do { - is = new BufferedInputStream(new GZIPInputStream(is)); - } while (ZipUtil.isGzip(is)); - } else if (ZipUtil.isZipFile(is)) { - if (allowZipStream) - return new ZipInputStream(bis); - if (asInputStream) - return (InputStream) ZipUtil.getZipFileContents(is, subFileList, 1, - true); - // danger -- converting bytes to String here. - // we lose 128-156 or so. - String s = (String) ZipUtil.getZipFileContents(is, subFileList, 1, - false); - is.close(); - return getBufferedReaderForString(s); - } - if (asInputStream) - return is; - return new BufferedReader(new InputStreamReader(is)); - } catch (Exception ioe) { - return ioe.getMessage(); - } - } - - String[] getZipDirectory(String fileName, boolean addManifest) { - return ZipUtil.getZipDirectoryAndClose( - (InputStream) getInputStreamOrErrorMessageFromName(fileName, false), - addManifest); - } - - String getZipDirectoryAsString(String fileName) { - return ZipUtil - .getZipDirectoryAsStringAndClose((InputStream) getInputStreamOrErrorMessageFromName( - fileName, false)); - } - /** * Sets all local file references in a script file to point to files within * dataPath. If a file reference contains dataPath, then the file reference is @@ -963,7 +955,7 @@ return TextFormat.replaceQuotedStrings(script, fileNames, newFileNames); } - static String[] scriptFilePrefixes = new String[] { "/*file*/", "FILE0=", "FILE1=" }; + private static String[] scriptFilePrefixes = new String[] { "/*file*/", "FILE0=", "FILE1=" }; public static void getFileReferences(String script, Vector fileList) { for (int ipt = 0; ipt < scriptFilePrefixes.length; ipt++) { String tag = scriptFilePrefixes[ipt]; Modified: trunk/Jmol/src/org/jmol/viewer/Jmol.properties =================================================================== --- trunk/Jmol/src/org/jmol/viewer/Jmol.properties 2009-11-22 19:15:53 UTC (rev 11775) +++ trunk/Jmol/src/org/jmol/viewer/Jmol.properties 2009-11-22 19:16:27 UTC (rev 11776) @@ -3,6 +3,8 @@ version=11.9.10_dev +# bug fix: occasional null pointer error during ZAP due to continued rendering by +# previous graphic painting thread # code: refactoring of FileManager and clean-up of Viewer code # in relation to model loading. Modified: trunk/Jmol/src/org/jmol/viewer/MouseManager.java =================================================================== --- trunk/Jmol/src/org/jmol/viewer/MouseManager.java 2009-11-22 19:15:53 UTC (rev 11775) +++ trunk/Jmol/src/org/jmol/viewer/MouseManager.java 2009-11-22 19:16:27 UTC (rev 11776) @@ -45,6 +45,8 @@ } void setActionManager(ActionManager actionManager) { + if (this.actionManager != null) + actionManager.clear(); this.actionManager = actionManager; } Modified: trunk/Jmol/src/org/jmol/viewer/RepaintManager.java =================================================================== --- trunk/Jmol/src/org/jmol/viewer/RepaintManager.java 2009-11-22 19:15:53 UTC (rev 11775) +++ trunk/Jmol/src/org/jmol/viewer/RepaintManager.java 2009-11-22 19:16:27 UTC (rev 11776) @@ -47,27 +47,22 @@ private int holdRepaint = 0; boolean repaintPending; + private boolean repaintInterrupted = false; void pushHoldRepaint() { ++holdRepaint; } void popHoldRepaint() { - --holdRepaint; - if (holdRepaint <= 0) { - holdRepaint = 0; - repaintPending = true; + if (--holdRepaint <= 0) repaintDisplay(); - } } boolean refresh() { if (repaintPending) return false; - repaintPending = true; - if (holdRepaint == 0) { + if (holdRepaint == 0) repaintDisplay(); - } return true; } @@ -80,12 +75,28 @@ } private void repaintDisplay() { + holdRepaint = 0; + repaintPending = true; + repaintInterrupted = false; Component display = viewer.getDisplay(); if (display == null) return; display.repaint(); } + synchronized void cancelRendering() { + if (!repaintPending || repaintInterrupted) + return; + repaintInterrupted = true; + try { + //System.out.println("repaintManager waiting for rendering to complete"); + wait(); + } catch (InterruptedException e) { + } + repaintInterrupted = false; + //System.out.println("repaintManager continuing"); + } + synchronized void repaintDone() { repaintPending = false; notify(); // to cancel any wait in requestRepaintAndWait() @@ -94,17 +105,19 @@ void render(Graphics3D g3d, ModelSet modelSet) {// , Rectangle rectClip if (!viewer.getRefreshing()) return; - render1(g3d, modelSet); // , rectClip - Rectangle band = viewer.getRubberBandSelection(); - if (band != null && g3d.setColix(viewer.getColixRubberband())) - g3d.drawRect(band.x, band.y, 0, 0, band.width, band.height); + try { + render1(g3d, modelSet); // , rectClip + } catch (Exception e) { + System.out.println("rendering Exception " + e.getMessage()); + } } private boolean logTime; private void render1(Graphics3D g3d, ModelSet modelSet) { // , Rectangle rectClip - if (modelSet == null || !viewer.mustRenderFlag()) + if (modelSet == null || !viewer.mustRenderFlag() + || repaintInterrupted) return; logTime = viewer.getTestFlag1(); @@ -118,12 +131,19 @@ g3d.renderBackground(); if (renderers == null) renderers = new ShapeRenderer[JmolConstants.SHAPE_MAX]; - for (int i = 0; i < JmolConstants.SHAPE_MAX && g3d.currentlyRendering(); ++i) { + for (int i = 0; i < JmolConstants.SHAPE_MAX + && g3d.currentlyRendering(); ++i) { + if (repaintInterrupted) + return; Shape shape = modelSet.getShape(i); if (shape == null) continue; + //System.out.println("rendering " + JmolConstants.getShapeClassName(i)); getRenderer(i, g3d).render(g3d, modelSet, shape); } + Rectangle band = viewer.getRubberBandSelection(); + if (band != null && g3d.setColix(viewer.getColixRubberband())) + g3d.drawRect(band.x, band.y, 0, 0, band.width, band.height); } catch (Exception e) { Logger Modified: trunk/Jmol/src/org/jmol/viewer/Viewer.java =================================================================== --- trunk/Jmol/src/org/jmol/viewer/Viewer.java 2009-11-22 19:15:53 UTC (rev 11775) +++ trunk/Jmol/src/org/jmol/viewer/Viewer.java 2009-11-22 19:16:27 UTC (rev 11776) @@ -1663,20 +1663,15 @@ return global.defaultDirectory; } - public Object getBufferedReaderForString(String sdata) { - return FileManager.getBufferedReaderForString(sdata); - } - public BufferedInputStream getBufferedInputStream(String fullPathName) { - Object ret = getBufferedReaderOrErrorMessageFromName(fullPathName, - new String[2], true); - return (ret instanceof BufferedInputStream ? (BufferedInputStream) ret - : null); + // used by some JVXL readers + return fileManager.getBufferedInputStream(fullPathName); } public Object getBufferedReaderOrErrorMessageFromName(String name, String[] fullPathNameReturn, boolean isBinary) { + // used by isosurface reader return fileManager.getBufferedReaderOrErrorMessageFromName(name, fullPathNameReturn, isBinary, true); } @@ -2006,7 +2001,7 @@ private String openStringInline(String strModel, Hashtable htParams, boolean isAppend) { - // loadInline, openFile, openStringInline + // loadInline, openStringInline if (!isAppend) zap(true, false); Object atomSetCollection = fileManager.createAtomSetCollectionFromString(strModel, @@ -2016,7 +2011,7 @@ private String openStringsInline(String[] arrayModels, Hashtable htParams, boolean isAppend) { - // loadInline, openFile, openStringInline + // loadInline if (!isAppend) zap(true, false); Object atomSetCollection = fileManager.createAtomSeCollectionFromStrings(arrayModels, @@ -3413,7 +3408,7 @@ statusManager.setSync(null); } - public void repaintView() { + public void notifyViewerRepaintDone() { repaintManager.repaintDone(); } @@ -3550,7 +3545,7 @@ render1(gRight, getImage(true), 0, 0); render1(gLeft, getImage(false), 0, 0); } - repaintView(); + notifyViewerRepaintDone(); } public void renderScreenImage(Graphics g, Dimension size, Rectangle clip) { @@ -6279,6 +6274,7 @@ setSpinOn(false); setNavOn(false); setAnimationOn(false); + repaintManager.cancelRendering(); } private void setNavigationMode(boolean TF) { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |