Coverage Report - org.paneris.bibliomania.metasearch.bob.Session
 
Classes in this File Line Coverage Branch Coverage Complexity
Session
0%
0/69
0%
0/14
2.583
Session$SessionRenewer
0%
0/16
N/A
2.583
 
 1  
 package org.paneris.bibliomania.metasearch.bob;
 2  
 
 3  
 import java.io.FileOutputStream;
 4  
 import java.io.IOException;
 5  
 import java.io.OutputStream;
 6  
 import java.net.URL;
 7  
 
 8  
 import org.apache.oro.text.regex.MalformedPatternException;
 9  
 import org.apache.oro.text.regex.Perl5Compiler;
 10  
 import org.apache.oro.text.regex.Perl5Matcher;
 11  
 import org.apache.oro.text.regex.Perl5Pattern;
 12  
 import org.apache.oro.text.regex.StringSubstitution;
 13  
 import org.apache.oro.text.regex.Util;
 14  
 import org.melati.util.IoUtils;
 15  
 import org.melati.util.MelatiRuntimeException;
 16  
 import org.melati.util.UnexpectedExceptionException;
 17  
 import org.paneris.bibliomania.metasearch.util.HackParser;
 18  
 import org.paneris.bibliomania.metasearch.util.TimeoutThread;
 19  
 
 20  0
 public class Session {
 21  
   public static final String frontPageURL =
 22  
     "http://bookshop.blackwell.co.uk/cgi-bin/BOB2?BV_Operation=Dyn_LoginReceive&BV_ServiceName=BOB&form%25login_type=guest&form%25failure=/service_error.html&form%25success=/bob/bob_main.html.tmpl";
 23  
 
 24  
   public String sessionID, engineID;
 25  
 
 26  0
   public Session(String sessionID, String engineID) {
 27  0
     this.sessionID = sessionID;
 28  0
     this.engineID = engineID;
 29  0
   }
 30  
 
 31  
   public String queryParams() {
 32  0
     return "BV_SessionID=" + sessionID + "&BV_EngineID=" + engineID;
 33  
   }
 34  
 
 35  
   public String toString() {
 36  0
     return queryParams();
 37  
   }
 38  
 
 39  0
   private static final Object bobSessionMon = new Object();
 40  
 
 41  0
   private static Session bobSession = null;
 42  
 
 43  0
   private static Exception bobSessionException = null;
 44  
 
 45  
   public static class NoSessionIDException extends MelatiRuntimeException {
 46  
     /**
 47  
      * 
 48  
      */
 49  
     private static final long serialVersionUID = 1L;
 50  
 
 51  
     public String getMessage() {
 52  
       return "Couldn't extract session ID from front page";
 53  
     }
 54  
   }
 55  
 
 56  
   private static void newSession() throws OpenException {
 57  0
     System.err.println("BOB: establishing new session");
 58  
     try {
 59  0
       TimeoutThread timeout = TimeoutThread.forCurrentThread(20000);
 60  
       try {
 61  0
         FrontPage fp =
 62  
           new FrontPage(IoUtils.slurp(new URL(frontPageURL), 32768));
 63  0
         if (fp.sessionID == null)
 64  0
           throw new NoSessionIDException();
 65  
 
 66  0
         bobSession = new Session(fp.sessionID, fp.engineID);
 67  0
         bobSessionException = null;
 68  
       } finally {
 69  0
         timeout.stop();
 70  0
       }
 71  0
     } catch (Exception e) {
 72  0
       bobSessionException = e;
 73  0
       throw new OpenException(e);
 74  0
     }
 75  0
   }
 76  
 
 77  
   private static class SessionRenewer extends Thread {
 78  0
     public SessionRenewer() {
 79  0
       setDaemon(true);
 80  0
     }
 81  
 
 82  
     public void run() {
 83  
       try {
 84  
         for (;;) {
 85  
           try {
 86  0
             newSession();
 87  0
           } catch (Exception e) {
 88  0
             System.err.println("BOB SessionRenewer:");
 89  0
             e.printStackTrace();
 90  
           } finally {
 91  0
             synchronized (bobSessionMon) {
 92  0
               bobSessionMon.notifyAll();
 93  0
             }
 94  0
           }
 95  
 
 96  0
           Thread.sleep(5 * 60 * 1000);
 97  
         }
 98  0
       } catch (InterruptedException e) {
 99  
       } finally {
 100  0
         sessionRenewer = null;
 101  0
       }
 102  0
     }
 103  
   }
 104  
 
 105  0
   private static SessionRenewer sessionRenewer = null;
 106  
 
 107  
   private static synchronized void checkSessionRenewer() {
 108  0
     if (sessionRenewer == null)
 109  0
        (sessionRenewer = new SessionRenewer()).start();
 110  0
   }
 111  
 
 112  
   static Session bobSession() {
 113  0
     checkSessionRenewer();
 114  
 
 115  0
     if (bobSession == null) {
 116  
       try {
 117  0
         synchronized (bobSessionMon) {
 118  0
           if (bobSession == null)
 119  0
             bobSessionMon.wait();
 120  0
         }
 121  0
       } catch (InterruptedException e) {
 122  0
         throw new OpenException(e);
 123  0
       }
 124  
     }
 125  
 
 126  0
     if (bobSession == null)
 127  0
       throw new OpenException(bobSessionException);
 128  
 
 129  0
     return bobSession;
 130  
   }
 131  
 
 132  
   private static Perl5Pattern bv__IDParam;
 133  
 
 134  
   static {
 135  
     try {
 136  0
       bv__IDParam =
 137  
         (Perl5Pattern) (new Perl5Compiler()).compile(
 138  
           "BV_(Session|Engine)ID=[^&]*&?",
 139  
           0);
 140  0
     } catch (MalformedPatternException e) {
 141  0
       throw new UnexpectedExceptionException(e);
 142  0
     }
 143  
   }
 144  
 
 145  0
   private static final StringSubstitution empty = new StringSubstitution();
 146  
 
 147  
   public static String urlInCurrentSession(String url) {
 148  0
     String urlWithoutSession =
 149  
       Util.substitute(
 150  
         new Perl5Matcher(),
 151  
         bv__IDParam,
 152  
         empty,
 153  
         url,
 154  
         Util.SUBSTITUTE_ALL);
 155  
 
 156  0
     return urlWithoutSession + '&' + bobSession().queryParams();
 157  
   }
 158  
 
 159  0
   private static String contentDumpPrefix = null;
 160  0
   private static int contentDumpIndex = 0;
 161  
 
 162  
   private static byte[] contentUsingCurrentSession(
 163  
     String url,
 164  
     int estimate,
 165  
     int limit)
 166  
     throws IOException {
 167  0
     byte[] content = IoUtils.slurp(new URL(urlInCurrentSession(url)), 32768);
 168  
 
 169  0
     String dp = contentDumpPrefix;
 170  0
     if (dp != null) {
 171  
       try {
 172  0
         OutputStream o =
 173  
           new FileOutputStream(contentDumpPrefix + contentDumpIndex++ +".html");
 174  
         try {
 175  0
           o.write(content);
 176  
         } finally {
 177  0
           try {
 178  0
             o.close();
 179  0
           } catch (IOException e) {
 180  0
           }
 181  0
         }
 182  0
       } catch (Exception e) {
 183  0
         System.err.println("Can't write dump!");
 184  0
       }
 185  
     }
 186  
 
 187  0
     return content;
 188  
   }
 189  
 
 190  0
   private static final byte[] timeoutExplan =
 191  
     "current session timing out".getBytes();
 192  
 
 193  
   public static byte[] content(String url, int estimate, int limit)
 194  
     throws IOException {
 195  0
     byte[] it = contentUsingCurrentSession(url, estimate, limit);
 196  0
     if (HackParser.indexOf(it, timeoutExplan) != -1) {
 197  0
       newSession();
 198  0
       return contentUsingCurrentSession(url, estimate, limit);
 199  
     } else
 200  0
       return it;
 201  
   }
 202  
 }