/*************************************************** File: SearchResultsWorld.java Author: Hermes Roferos Created: October 21, 1999 Last Modified: November 3, 1999 HRR: added collection retrieval functionality 10/29/99 - Scott - Adapt for SearchResult collection ***************************************************/ import vrml.*; import vrml.field.*; import vrml.node.*; import java.util.Date; import java.net.*; public class SearchResultsWorld extends Script { public static int LAP_RADIUS = 12; public static int FONT_SIZE = 10; // 10/26/99 - Scott rename targetNode to newNode; private SFString queryText; private SFString sessionId; private MFNode newNode; private Browser clientBrowser; private SFTime getNextResult; private SFBool isRunning; private int nextResultIndex = 0; private SearchResultsCollector theCollector; private AdditionalResultsFacade m_Engine; public void initialize() { clientBrowser = this.getBrowser(); theCollector = new SearchResultsCollector(); m_Engine = new AdditionalResultsFacade(); sessionId = (SFString) getField( "sessionId"); m_Engine.setSessionId( sessionId.toString()); theCollector.setEngine( m_Engine); //vrml.external.Browser.print( "Getting Fields"); // get a reference to the childList script event queryText = (SFString)getField( "queryText"); theCollector.setQueryText( queryText.getValue()); theCollector.start(); //vrml.external.Browser.print( "getting newNode event"); newNode = (MFNode)getEventOut( "newNode" ); //vrml.external.Browser.print( "getting getNextResult event"); getNextResult = (SFTime)getEventIn( "getNextResult"); //vrml.external.Browser.print( "getting isRunning event"); isRunning = (SFBool)getEventOut( "isRunning"); // get a reference to the client browser //vrml.external.Browser.print( "getting browser"); } public void processEvent( Event e ) { if ( e.getName().equals( "getNextResult" ) ) { if ( theCollector.getCount() > nextResultIndex ) { try { generateNode( theCollector.getSearchResult( nextResultIndex++ ) ); } catch( InvalidVRMLSyntaxException ex ) { clientBrowser.setDescription( ex.getMessage()); } } else if( theCollector.getState() >= SearchResultsCollector.S_Done) { isRunning.setValue( false); if( theCollector.getState() == SearchResultsCollector.S_Exception) clientBrowser.setDescription( theCollector.getLastException().getMessage()); } } } // 10/29/99 - Scott - Break node generation into its own function // - Also, throw Syntax Errors /* real declaration should be: private void generateNode( SearchResult r) throws InvalidVRMLSyntaxException */ private void generateNode( SearchResult r ) throws InvalidVRMLSyntaxException { vrml.external.Browser.print( "Generating Node for " + r.getTitle() ); StringBuffer vrmlString = new StringBuffer(); MFNode nodes = new MFNode(); // create the VRML string to display the search result vrmlString.append( "EXTERNPROTO SearchResultNode [" + " field MFString title" + " field SFTime age" + " field SFColor hostIP" + " field SFColor domainName" + " ] \"SearchResultNode.wrl\"" ); // the fish's text is the document title String title = r.getTitle(); // calculate age of a document to determine how fast the fish swims // the # of mS in a month is: 1000 mS * 60 secs * 60 min * 24 hours * 7 days * 4 weeks // each month older, the cycle time goes up by 1 with a minimum cycle time of 6 Date today = new Date(); Date docDate = r.getLastModifiedDate(); double elapsedMonths = (double)( today.getTime() - docDate.getTime() ) / (1000.0*60.0*60.0*24.0*7.0*4.0 ); if ( elapsedMonths < 6 ) elapsedMonths = 6; String age = Double.toString( elapsedMonths ); // Calculate the color of the fish's fins // determinge the high-level domain and convert it to an RGB value // rgb color is the char's relative position in the alphabet String alphabet = "abcdefghijklmnopqrstuvwxyz"; double[] rgb = new double[3]; rgb[2] = 0.0; // default blue component = 0 in case it is only a 2-char domain URL docUrl = r.getURL(); String host = docUrl.getHost().toLowerCase(); String hLevelDomain = host.substring( host.lastIndexOf( '.' ) + 1 ); int hLDnameLength = hLevelDomain.length(); if ( hLDnameLength > 3 ) // for this purpose, we limit it to 3 characters hLDnameLength = 3; for ( int i = 0 ; i < hLDnameLength ; i++ ) rgb[i] = (double)alphabet.indexOf( hLevelDomain.charAt( i ) ) / 26.0; String finColor = " " + Double.toString( rgb[0] ) + " " + Double.toString( rgb[1] ) + " " + Double.toString( rgb[2] ) + " "; vrml.external.Browser.print( "tail/fin RGB: " + finColor ); // fish's body color rgb values are the first 3 numbers in the ip address divide by 255 byte[] ipAddr = new byte[4]; try { vrml.external.Browser.print( "Looking up address of " + host ); InetAddress hostAddress = InetAddress.getByName( host ); ipAddr = hostAddress.getAddress(); } catch ( Exception ex ) { vrml.external.Browser.print( "Unable to get address for " + host ); // if can't get the ip address, make the fish red ipAddr[0] = (byte)200; ipAddr[1] = ipAddr[2] = (byte)0; } for ( int i = 0 ; i < 3 ; i++ ) // cast to a char first because bytes are signed 2's complement; mask out upper 8 bits rgb[i] = (double)( (char)ipAddr[i] & 0xff ) / 255.0; String bodyColor = " " + Double.toString( rgb[0] ) + " " + Double.toString( rgb[1] ) + " " + Double.toString( rgb[2] ) + " "; vrml.external.Browser.print( "Body RGB: " + bodyColor ); // use document rank for the y location of the fish int docRank = r.getRank(); vrmlString.append( "Transform { translation 0 -" + Integer.toString( docRank * 3) +" 0 " + " children [ " + " SearchResultNode {" + " title \"" + title + "\"" + " age " + age + " hostIP " + bodyColor + " domainName " + finColor + " } ] }" ); // create VRML and attach it to the target node newNode.setValue( clientBrowser.createVrmlFromString( vrmlString.toString() ) ); } }