/* * BioJava development code * * This code may be freely distributed and modified under the * terms of the GNU Lesser General Public Licence. This should * be distributed with the code. If you do not have a copy, * see: * * http://www.gnu.org/copyleft/lesser.html * * Copyright for this code is held jointly by the individual * authors. These should be listed in @author doc comments. * * For more information on the BioJava project and its aims, * or to join the biojava-l mailing list, visit the home page * at: * * http://www.biojava.org/ * * created at Sep 7, 2007 */ package org.biojava.bio.structure.server; import java.util.ArrayList; import java.util.List; import java.util.logging.Logger; import org.biojava.bio.structure.Structure; public class SimpleStructureServer implements StructureServer, StructureListener { public static final Logger logger = Logger.getLogger("org.biojava.bio.structure"); List queue; List listeners; PDBInstallation installation; int cacheSize; int countLoading; List waitingList; public SimpleStructureServer(){ listeners = new ArrayList(); queue = new ArrayList(); cacheSize = 1; countLoading = 0; waitingList = new ArrayList(); } public void initCache(){ checkStatus(); } public void addStructureListener(StructureListener listener) { listeners.add(listener); } public void clearStructureListeners() { listeners.clear(); } public int getNrCPUs() { // TODO Auto-generated method stub return 0; } public PDBInstallation getPDBInstallation() { return installation; } public synchronized void requestNextStructure(StructureListener listener) { if (installation ==null) { logger.warning("no PDB installation has been set, yet. Can not load next structure"); triggerNextStructure(null, listener); return; } if (queue.size() > 0){ // give the requestor a structure from the queue. Structure s = getStructureFromQueue(); checkStatus(); // and send the notification to requestor triggerNextStructure(s, listener); } // queue.size() == 0 // on a multi CPU system this should not happen. // most likely we are on a single CPU system... // other possibility is that we are still loading the structures? if ( countLoading > 0 ){ // will be the first one to be informed. waitingList.add(listener); checkStatus(); return ; } System.err.println("queue is empty on server!"); addNextToQueue(listener); checkStatus(); return; } private synchronized void checkStatus(){ System.out.println("server check status "+ queue.size() + "+" + countLoading + " == " + cacheSize + "?"); while ( queue.size() + countLoading <= cacheSize ) { // refill the cache addNextToQueue(this); countLoading++; } } private void addNextToQueue(StructureListener listener){ //System.out.println("server: addNextToQueue: queue:" + queue.size() + " " + installation.hasNext()); if ( installation.hasNext()){ StructureFetcherRunnable r = new StructureFetcherRunnable(installation); r.addStructureListener(listener); Thread t = new Thread(r); t.start(); } } /** a new structure is loaded from the queue. * remove it from queue and trigger loading of a new Structure * * @return Structure */ private synchronized Structure getStructureFromQueue(){ if ( queue.size() == 0){ return null; } Structure s = queue.get(0); queue.remove(0); return s; } public void setCacheSize(int cacheSize) { this.cacheSize = cacheSize; } public int getCacheSize(){ return cacheSize; } public void setPDBInstallation(PDBInstallation installation) { this.installation = installation; } public boolean hasNextStructure() { //System.out.println("server hasNextStructure loading:" +countLoading); if (queue.size() > 0) return true; if ( countLoading > 0) return true; boolean hasNext = installation.hasNext(); if ( hasNext) return true; return false; } private void triggerNextStructure(Structure s, StructureListener li){ StructureEvent event = new StructureEventImpl(s); li.newStructure(event); } public void modifiedStructure(StructureEvent event) { // TODO Auto-generated method stub } public synchronized void newStructure(StructureEvent event) { countLoading--; Structure s = event.getStructure(); if ( s == null) { System.err.println("StructureServer: could not load structure for " + event.getPDBCode()); } else { //System.out.println("server got new structure " + s.getPDBCode()); if ( waitingList.size() > 0){ StructureListener listener = waitingList.get(0); waitingList.remove(0); triggerNextStructure(s, listener); return; } // nobody is waiting for this structure, cache is queue.add(s); } } public void obsoleteStructure(StructureEvent event) { // TODO Auto-generated method stub } }