/* Copyright Astex Technology Ltd. 1999 */ /* Copyright David Hall, Boston University, 2011 */ /* * 17-11-99 mjh * created */ import astex.*; import astex.parser.*; import java.applet.*; import java.awt.*; import java.net.*; import java.io.*; import java.util.List; import java.util.LinkedList; import astex.splitter.*; import astex.thinlet.*; /** * An applet container for the MoleculeViewer. */ public class MoleculeViewerApplet extends Applet implements Runnable{ /** The MoleculeViewer. */ public MoleculeViewer moleculeViewer; /** Should we output debugging info. */ private boolean debug = false; /** What stage of initialisation are we at. */ private int initStep = 0; /** The thread that will drive the progress bar. */ private Thread prepareThread = null; public MoleculeViewerApplet(){ super(); setBackground(Color.white); } public void init(){ // if we display the splash screen the applet gets init'ed // before it really is inited. This breaks every single // application that does an onload() initialisation from // javascript // set splashscreen to something to initialise the splashscreen // at startup if(getParameter("splashscreen") == null){ run(); }else{ prepareThread = new Thread(this); prepareThread.start(); } } private void reportProgress(){ initStep++; repaint(0); getToolkit().sync(); try { Thread.sleep(20); }catch(InterruptedException e){ System.out.println("Interrupted thread=" + Thread.currentThread() + " " + initStep); } } public void publicInit(){ if(getParameter("appletui") != null){ try { setLayout(new SplitterLayout(SplitterLayout.Orientation.HORIZONTAL)); add("3", moleculeViewer); String ui = new URL(getDocumentBase(), getParameter("appletui")).toString(); ThinletUI tui = new ThinletUI(moleculeViewer, ui); SplitterBar sb = new SplitterBar(); add(sb); add("1", tui); MoleculeRenderer moleculeRenderer = moleculeViewer.getMoleculeRenderer(); moleculeRenderer.removeMoleculeRendererListener(tui); moleculeRenderer.renderer.removeRendererEventListener(tui); }catch(Exception e){ e.printStackTrace(); } }else{ setLayout(new BorderLayout()); add(moleculeViewer, BorderLayout.CENTER); } doLayout(); } public void run(){ reportProgress(); moleculeViewer = new MoleculeViewer(); moleculeViewer.ready = false; reportProgress(); String host = getCodeBase().getHost(); System.out.println("host = [" + host + "]"); System.out.println("documentbase = [" + getDocumentBase() + "]"); System.out.println("codebase = [" + getCodeBase() + "]"); FILE.setDebug(false); FILE.setDocumentBase(getDocumentBase()); FILE.setCodeBase(getCodeBase()); if(getDocumentBase().toString().startsWith("file")){ // we seem to be running off a file system System.out.println("filesystem = [true]"); FILE.setTryFiles(true); } reportProgress(); moleculeViewer.setUsePopupMenu(true); moleculeViewer.createMenuBar(); moleculeViewer.getMoleculeRenderer().renderer.setColor(0x00ff00); reportProgress(); initialiseApplet(); reportProgress(); try { publicInit(); }catch(Exception e){ System.out.println("some terrible error occurred loading user extension"); e.printStackTrace(); } moleculeViewer.ready = true; repaint(); moleculeViewer.repaint(); } public void update(Graphics g){ paint(g); } public void paint(Graphics g){ if(moleculeViewer != null && moleculeViewer.ready){ super.paintComponents(g); }else{ paintSplashScreen(g); } } private static final int progressHeight = 12; private static final int barWidth = 280; private static final int maxProgress = 15; private Image splashImage = null; private int splashWidth = -1; private int splashHeight = -1; private void paintSplashScreen(Graphics g){ int width = getSize().width; int height = getSize().height; int midx = width/2; int midy = height/2; int halfWidth = Math.min(barWidth/2, midx - 10); if(splashImage == null){ //g.setColor(Color.white); //g.fillRect(0, 0, width, height); splashImage = Texture.loadImage("splash.gif"); if (splashImage != null){ MediaTracker mediatracker = new MediaTracker(this); mediatracker.addImage(splashImage, 1); try { mediatracker.waitForID(1, 5000); } catch (InterruptedException ie) { } }else{ return; } splashWidth = splashImage.getWidth(null); splashHeight = splashImage.getHeight(null); } if(splashImage != null){ g.drawImage(splashImage, midx - splashWidth/2, midy - splashHeight/2, this); } int frac = Math.min(maxProgress, initStep); // background g.setColor(Color.lightGray); g.fillRect(midx - halfWidth, midy - progressHeight/2, (int)(2 * halfWidth * (double)frac / maxProgress), progressHeight); g.drawRect(0, 0, width - 1, height - 1); g.setColor(Color.black); g.drawRect(midx - halfWidth, midy - progressHeight/2, 2 * halfWidth, progressHeight); } /** Initialise the applet. */ public void initialiseApplet(){ // stop the applet trying to find resources // on the local file system. FILE.setTryFiles(false); String arraycopy = getParameter("arraycopy"); if("true".equals(arraycopy)){ moleculeViewer.setArrayCopy(true); } List<String> moleculeNames = getParameterList("molecule"); for(String moleculeName : moleculeNames){ Molecule molecule = MoleculeIO.read(moleculeName); moleculeViewer.addMolecule(molecule); } reportProgress(); List<String> mapNames = getParameterList("map"); for(String mapName : mapNames){ Map map = Map.create(); //System.out.println("map name is " + mapName); map.setFile(mapName); moleculeViewer.addMap(map); } reportProgress(); String centerString = getParameter("center"); MoleculeRenderer moleculeRenderer = moleculeViewer.getMoleculeRenderer(); if(centerString != null){ String words[] = FILE.split(centerString); // its a x y z specification if(words.length == 3){ double x = FILE.readDouble(words[0]); double y = FILE.readDouble(words[1]); double z = FILE.readDouble(words[2]); moleculeRenderer.setCenter(x, y, z); }else{ // its an atom selection List<Atom> centerSelection = moleculeRenderer.getAtomsInSelection(centerString); moleculeRenderer.setCenter(centerSelection); } } reportProgress(); String clipString = getParameter("clip"); if(clipString != null){ double clip = FILE.readDouble(clipString); moleculeRenderer.setClip(clip); } reportProgress(); String wideBondsString = getParameter("wide"); if(wideBondsString != null){ moleculeRenderer.resetWideBonds(); List<Atom> wideBondsSelection = moleculeRenderer.getAtomsInSelection(wideBondsString); for(Atom atom : wideBondsSelection){ int bondCount = atom.getBondCount(); for(int b = 0; b < bondCount; b++){ Bond bond = atom.getBond(b); bond.setWideBond(true); } } } reportProgress(); String bumpString = getParameter("bump"); if(bumpString != null){ // switch on bump checking. moleculeRenderer.setDisplayBumps(true); List<Atom> bumpAtoms = moleculeRenderer.getAtomsInSelection(bumpString); moleculeRenderer.generateBumps(bumpAtoms); } reportProgress(); String scriptFile = getParameter("scriptFile"); //System.out.println("executing script from " + scriptFile); if(scriptFile != null){ executeFile(scriptFile); } reportProgress(); String scriptString = getParameter("script"); if(scriptString != null){ //System.out.println("about to execute start script"); //System.out.println(scriptString); moleculeRenderer.execute(scriptString); } reportProgress(); } /** Destroy the applet. */ public void destroy(){ super.destroy(); //System.out.println("MoleculeViewerApplet.destroy()"); if(moleculeViewer != null){ //moleculeViewer.finalize(); //moleculeViewer.getMoleculeRenderer().moleculeViewer = null; moleculeViewer = null; System.gc(); System.runFinalization(); } } public void stop(){ super.stop(); System.out.println("MoleculeViewerApplet.stop()"); removeAll(); moleculeViewer = null; } /** Return a DynamicArray of parameters that begin with the String. */ private List<String> getParameterList(String prefix){ List<String> parameters = new LinkedList<String>(); String value = getParameter(prefix); if(value != null){ parameters.add(value); } for(int i = 1; /* nothing */; i++){ value = getParameter(prefix + i); if(value == null){ break; }else{ parameters.add(value); } } return parameters; } /* * Execute a set of commands. */ public synchronized void execute(String command){ MoleculeRenderer renderer = moleculeViewer.getMoleculeRenderer(); if(debug){ System.out.println("command: " + command); } renderer.execute(command); moleculeViewer.repaint(); } /** Open a file and execute the script in it. */ public void executeFile(String scriptFile){ FILE f = FILE.open(scriptFile); StringBuilder sb = new StringBuilder(128); int c = 0; while((c = f.read()) != FILE.EOF){ sb.append((char)c); } execute(sb.toString()); moleculeViewer.repaint(); } /** Turn on debugging. */ public void debugOn(){ debug = true; } /** Turn on debugging. */ public void debugOff(){ debug = false; } /** * Return the contents of the specified url. * This provides some functionality around the parser * to allow it to return a string. * * If this is used in an applet, it will only * be possible to open urls from the server that * the applet came from. */ public String fetch(String urlName){ if(debug){ System.out.println("about to call fetch"); System.out.println("url="+urlName); } MoleculeRenderer renderer = moleculeViewer.getMoleculeRenderer(); renderer.execute("fetch '" + urlName + "';"); if(debug){ System.out.println("back from fetch"); System.out.println("data="+parser.getUrlContents()); } return parser.getUrlContents(); } /** Fetch using method=POST. */ private String fetchPost(String urlString){ //System.out.println("URLFetchPost"); StringBuilder contents = new StringBuilder(2048); int questionPos = urlString.indexOf('?'); String urlSection = urlString; String parameterSection = null; if(questionPos != -1){ urlSection = urlString.substring(0, questionPos); parameterSection = urlString.substring(questionPos + 1, urlString.length()); } try { URL url = new URL(urlSection); URLConnection con = url.openConnection(); con.setDoInput(true); con.setDoOutput(true); con.setUseCaches(false); con.setRequestProperty("CONTENT_LENGTH", Integer.toString(parameterSection.length())); OutputStream os = con.getOutputStream(); OutputStreamWriter osw = new OutputStreamWriter(os); osw.write(parameterSection); osw.flush(); osw.close(); InputStream is = con.getInputStream(); // any response? InputStreamReader isr = new InputStreamReader(is); BufferedReader br = new BufferedReader(isr); String line = null; String lineSeparator = java.lang.System.getProperty("line.separator"); while ( (line = br.readLine()) != null) { contents.append(line); contents.append(lineSeparator); } br.close(); } catch(Throwable t) { System.out.println("URLFetch - fetchPost(): " + "error opening url: " + urlString); t.printStackTrace(); } return contents.toString(); } /** Fetch using method=GET. */ private String fetchNormal(String urlString){ //System.out.println("URLFetch"); StringBuilder contents = new StringBuilder(2048); try { URL url = new URL(urlString); BufferedReader br = new BufferedReader(new InputStreamReader(url.openStream())); String line; String lineSeparator = java.lang.System.getProperty("line.separator"); while((line = br.readLine()) != null){ System.out.println("|" + line + "|"); contents.append(line); contents.append(lineSeparator); } br.close(); }catch(Exception e){ System.out.println("URLFetch - fetchNormal(): " + "error opening url: " + urlString); System.out.println(e); } return contents.toString(); } /** * Safe url fetcher. * Will use POST if URL data is too long. */ public String fetchSafe(String urlString){ String output = null; if(urlString.length() > 2048){ output = fetchPost(urlString); } else { output = fetchNormal(urlString); } return output; } /** Return scripting language to restore the current view. */ public String getView(){ return moleculeViewer.getView(); } public String getSelection(){ MoleculeRenderer renderer = moleculeViewer.getMoleculeRenderer(); StringBuilder selection = new StringBuilder(100); int molCount = renderer.getMoleculeCount(); for(int m = 0; m < molCount; m++){ boolean alreadySelected = false; Molecule mol = renderer.getMolecule(m); int atomCount = mol.getAtomCount(); for(int a = 0; a < atomCount; a++){ Atom atom = mol.getAtom(a); if(atom.isSelected()){ if(!alreadySelected){ if(selection.length() > 0){ selection.append("|"); } selection.append(mol.getName()); alreadySelected = true; } selection.append(",").append(atom.getId()); } } } return selection.toString(); } public String getCoordinates(){ MoleculeRenderer renderer = moleculeViewer.getMoleculeRenderer(); StringBuilder buf = new StringBuilder(30); AtomIterator iterator = renderer.getAtomIterator(); while(iterator.hasMoreElements()){ Atom atom = iterator.getNextAtom(); if(atom.isSelected()){ if(buf.length() > 0){ buf.append("|"); } buf.append("").append(atom.x); buf.append(",").append(atom.y); buf.append(",").append(atom.z); } } return buf.toString(); } public String getSelectedAtoms(){ MoleculeRenderer renderer = moleculeViewer.getMoleculeRenderer(); StringBuilder buf = new StringBuilder(2048); AtomIterator iterator = renderer.getAtomIterator(); boolean first = true; while(iterator.hasMoreElements()){ Atom atom = iterator.getNextAtom(); if(atom.isSelected()){ if(!first){ buf.append(","); } Residue res = atom.getResidue(); Chain chain = res.getParent(); Molecule mol = chain.getParent(); buf.append(mol.getName()); buf.append("|"); buf.append(chain.getName()); buf.append("|"); buf.append(res.getNumber()); buf.append("|"); buf.append(res.getInsertionCode()); buf.append("|"); buf.append(res.getName()); buf.append("|"); buf.append(atom.getAtomSymbol()); buf.append("|"); buf.append(atom.getAttribute(Atom.X)); buf.append("|"); buf.append(atom.getAttribute(Atom.Y)); buf.append("|"); buf.append(atom.getAttribute(Atom.Z)); buf.append("|"); buf.append(atom.getAttribute(Atom.B)); buf.append("|"); buf.append(atom.getAttribute(Atom.O)); buf.append("|"); buf.append(atom.getAtomLabel()); first = false; } } return buf.toString(); } Format hexFormat = new Format("0x%06x"); /** * Instruct MoleculeViewer to display its color gadget * so that something can use it for picking colours. */ public String getColor(int x, int y){ return moleculeViewer.getColor(x, y); } }