Crawler4j

profilelt4408
crawler_project.zip

Web Crawler/src/edu/smu/lyle/crawler/Controller.java

Web Crawler/src/edu/smu/lyle/crawler/Controller.java

package  edu . smu . lyle . crawler ;

public   class   Controller   {

             public   static   void  main ( String []  args )   throws   Exception   {
             String  crawlStorageFolder  =   "/data/crawl/root" ;
             int  numberOfCrawlers  =   1 ;

             CrawlConfig  config  =   new   CrawlConfig ();
            config . setCrawlStorageFolder ( crawlStorageFolder );

             /*
             * Instantiate the controller for this crawl.
             */
             PageFetcher  pageFetcher  =   new   PageFetcher ( config );
             RobotstxtConfig  robotstxtConfig  =   new   RobotstxtConfig ();
             RobotstxtServer  robotstxtServer  =   new   RobotstxtServer ( robotstxtConfig ,  pageFetcher );
             CrawlController  controller  =   new   CrawlController ( config ,  pageFetcher ,  robotstxtServer );

             /*
             * For each crawl, you need to add some seed urls. These are the first
             * URLs that are fetched and then the crawler starts following links
             * which are found in these pages
             */
            controller . addSeed ( "http://www.lyle.smu.edu/~fmoore/" );
            

             /*
             * Start the crawl. This is a blocking operation, meaning that your code
             * will reach the line after this only when crawling is finished.
             */
            controller . start ( MyCrawler . class ,  numberOfCrawlers );
         }
     }

Web Crawler/src/edu/smu/lyle/crawler/Main.java

Web Crawler/src/edu/smu/lyle/crawler/Main.java

package  edu . smu . lyle . crawler ;

import  java . nio . channels . Pipe ;
import  java . util . regex . Pattern ;

public   class   Main < WebURL >   {

     private   final   static   Pattern  FILTERS  =   Pattern . compile ( ".*(\\.(css|js|gif|jpg"
             +   "|png|mp3|mp3|zip|gz))$" );

/**
* This method receives two parameters. The first parameter is the page
* in which we have discovered this new url and the second parameter is
* the new url. You should implement this function to specify whether
* the given url should be crawled or not (based on your crawling logic).
* In this example, we are instructing the crawler to ignore urls that
* have css, js, git, ... extensions and to only accept urls that start
* with "http://www.lyle.smu.edu~fmoore/". In this case, we didn't need the
* referringPage parameter to make the decision.
*/
public   boolean  shouldVisit ( Package  referringPage ,   WebURL  url )   {
String  href  =   (( Object )  url ). getURL (). toLowerCase ();
return   ! FILTERS . matcher ( href ). matches ()
&&  href . startsWith ( "http://www.lyle.smu.edu~fmoore/" );
}

/**
* This function is called when a page is fetched and ready
* to be processed by your program.
*/
public   void  visit ( Pipe  page )   {
String  url  =   (( Object )  page )). getWebURL (). getURL ();
System . out . println ( "URL: "   +  url );

if   ( page . getParseData ()   instanceof   HtmlParseData )   {
HtmlParseData  htmlParseData  =   ( HtmlParseData )  page . getParseData ();
String  text  =  htmlParseData . getText ();
String  html  =  htmlParseData . getHtml ();
Set < WebURL >  links  =  htmlParseData . getOutgoingUrls ();

System . out . println ( "Text length: "   +  text . length ());
System . out . println ( "Html length: "   +  html . length ());
System . out . println ( "Number of outgoing links: "   +  links . size ());
}
}
}

Web Crawler/src/edu/smu/lyle/crawler/Spider.java

Web Crawler/src/edu/smu/lyle/crawler/Spider.java

package  edu . smu . lyle . crawler ;

import  java . util . HashSet ;
import  java . util . LinkedList ;
import  java . util . List ;
import  java . util . Set ;

public   class   Spider   {

    
     private   static   final   int  MAX_PAGES_TO_SEARCH  =   20 ;
       private   Set < String >  pagesVisited  =   new   HashSet < String > ();
       private   List < String >  pagesToVisit  =   new   LinkedList < String > ();


       /**
       * Our main launching point for the Spider's functionality. Internally it creates spider legs
       * that make an HTTP request and parse the response (the web page).
       * 
       *  @param  url
       *            - The starting point of the spider
       *  @param  searchWord
       *            - The word or string that you are searching for
       */
       public   void  search ( String  url ,   String  searchWord )
       {
           while ( this . pagesVisited . size ()   <  MAX_PAGES_TO_SEARCH )
           {
               String  currentUrl ;
               SpiderLeg  leg  =   new   SpiderLeg ();
               if ( this . pagesToVisit . isEmpty ())
               {
                  currentUrl  =  url ;
                   this . pagesVisited . add ( url );
               }
               else
               {
                  currentUrl  =   this . nextUrl ();
               }
               leg . crawl ( currentUrl );   // Lots of stuff happening here. Look at the crawl method in
                                      // SpiderLeg
              
               {
                   System . out . println ( String . format ( "**Success** Word %s found at %s" ,  searchWord ,  currentUrl ));
                   break ;
               }
           }
           System . out . println ( "\n**Done** Visited "   +   this . pagesVisited . size ()   +   " web page(s)" );
       }


       /**
       * Returns the next URL to visit (in the order that they were found). We also do a check to make
       * sure this method doesn't return a URL that has already been visited.
       * 
       *  @return
       */
       private   String  nextUrl ()
       {
           String  nextUrl ;
           do
           {
              nextUrl  =   this . pagesToVisit . remove ( 0 );
           }   while ( this . pagesVisited . contains ( nextUrl ));
           this . pagesVisited . add ( nextUrl );
           return  nextUrl ;
          }
}  

Web Crawler/src/edu/smu/lyle/crawler/SpiderLeg.java

Web Crawler/src/edu/smu/lyle/crawler/SpiderLeg.java

package  edu . smu . lyle . crawler ;

import  java . io . IOException ;
import  java . util . LinkedList ;
import  java . util . List ;

import  org . jsoup . Connection ;
import  org . jsoup . Jsoup ;
import  org . jsoup . nodes . Document ;
import  org . jsoup . nodes . Element ;
import  org . jsoup . select . Elements ;

public   class   SpiderLeg
{
     // We'll use a fake USER_AGENT so the web server thinks the robot is a normal web browser.
     private   static   final   String  USER_AGENT  =
             "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/13.0.782.112 Safari/535.1" ;
     private   List < String >  links  =   new   LinkedList < String > ();
     private   Document  htmlDocument ;


     /**
     * This performs all the work. It makes an HTTP request, checks the response, and then gathers
     * up all the links on the page. Perform a searchForWord after the successful crawl
     * 
     *  @param  url
     *            - The URL to visit
     *  @return  whether or not the crawl was successful
     */
    
     public   boolean  crawl ( String  url )
     {
         try
         {
             Connection  connection  =   Jsoup . connect ( url ). userAgent ( USER_AGENT );
             Document  htmlDocument  =  connection . get ();
             this . htmlDocument  =  htmlDocument ;
             if ( connection . response (). statusCode ()   ==   200 )   // 200 is the HTTP OK status code
                                                           // indicating that everything is great.
             {
                 System . out . println ( "\n**Visiting** Received web page at "   +  url );
             }
             if ( ! connection . response (). contentType (). contains ( "text/html" ))
             {
                 System . out . println ( "**Failure** Retrieved something other than HTML" );
                 return   false ;
             }
             Elements  linksOnPage  =  htmlDocument . select ( "a[href]" );
             System . out . println ( "Found ("   +  linksOnPage . size ()   +   ") links" );
             for ( Element  link  :  linksOnPage )
             {
                 this . links . add ( link . absUrl ( "href" ));
             }
             return   true ;
         }
         catch ( IOException  ioe )
         {
             // We were not successful in our HTTP request
             return   false ;
         }
     }


     /**
     * Performs a search on the body of on the HTML document that is retrieved. This method should
     * only be called after a successful crawl.
     * 
     *  @param  searchWord
     *            - The word or string to look for
     *  @return  whether or not the word was found
     */
     public   boolean  searchForWord ( String  searchWord )
     {
         // Defensive coding. This method should only be used after a successful crawl.
         if ( this . htmlDocument  ==   null )
         {
             System . out . println ( "ERROR! Call crawl() before performing analysis on the document" );
             return   false ;
         }
         System . out . println ( "Searching for the word "   +  searchWord  +   "..." );
         String  bodyText  =   this . htmlDocument . body (). text ();
         return  bodyText . toLowerCase (). contains ( searchWord . toLowerCase ());
     }


     public   List < String >  getLinks ()
     {
         return   this . links ;
     }


    
     }


    
        
    

Web Crawler/src/edu/smu/lyle/crawler/Stemmer.java

Web Crawler/src/edu/smu/lyle/crawler/Stemmer.java

package  edu . smu . lyle . crawler ;



     import  java . io . * ;

     /**
    * Stemmer, implementing the Porter Stemming Algorithm
    *
    * The Stemmer class transforms a word into its root form.  The input
    * word can be provided a character at time (by calling add()), or at once
    * by calling one of the various stem(something) methods.
    */

     class   Stemmer
     {    private   char []  b ;
     private   int  i ,       /* offset into b */
                i_end ,   /* offset to end of stemmed word */
                j ,  k ;
     private   static   final   int  INC  =   50 ;
     private   static   FileInputStream  fileInputStream ;
                       /* unit of size whereby b is increased */
     public   Stemmer ()
     {   b  =   new   char [ INC ];
       i  =   0 ;
       i_end  =   0 ;
     }

     /**
     * Add a character to the word being stemmed.  When you are finished
     * adding characters, you can call stem(void) to stem the word.
     */

     public   void  add ( char  ch )
     {    if   ( ==  b . length )
        {    char []  new_b  =   new   char [ i + INC ];
           for   ( int  c  =   0 ;  c  <  i ;  c ++ )  new_b [ c ]   =  b [ c ];
          b  =  new_b ;
        }
       b [ i ++ ]   =  ch ;
     }


     /** Adds wLen characters to the word being stemmed contained in a portion
     * of a char[] array. This is like repeated calls of add(char ch), but
     * faster.
     */

     public   void  add ( char []  w ,   int  wLen )
     {    if   ( i + wLen  >=  b . length )
        {    char []  new_b  =   new   char [ i + wLen + INC ];
           for   ( int  c  =   0 ;  c  <  i ;  c ++ )  new_b [ c ]   =  b [ c ];
          b  =  new_b ;
        }
        for   ( int  c  =   0 ;  c  <  wLen ;  c ++ )  b [ i ++ ]   =  w [ c ];
     }

     /**
     * After a word has been stemmed, it can be retrieved by toString(),
     * or a reference to the internal buffer can be retrieved by getResultBuffer
     * and getResultLength (which is generally more efficient.)
     */
     public   String  toString ()   {   return   new   String ( b , 0 , i_end );   }

     /**
     * Returns the length of the word resulting from the stemming process.
     */
     public   int  getResultLength ()   {   return  i_end ;   }

     /**
     * Returns a reference to a character buffer containing the results of
     * the stemming process.  You also need to consult getResultLength()
     * to determine the length of the result.
     */
     public   char []  getResultBuffer ()   {   return  b ;   }

     /* cons(i) is true <=> b[i] is a consonant. */

     private   final   boolean  cons ( int  i )
     {    switch   ( b [ i ])
        {    case   'a' :   case   'e' :   case   'i' :   case   'o' :   case   'u' :   return   false ;
           case   'y' :   return   ( i == 0 )   ?   true   :   ! cons ( i - 1 );
           default :   return   true ;
        }
     }

     /* m() measures the number of consonant sequences between 0 and j. if c is
       a consonant sequence and v a vowel sequence, and <..> indicates arbitrary
       presence,

          <c><v>       gives 0
          <c>vc<v>     gives 1
          <c>vcvc<v>   gives 2
          <c>vcvcvc<v> gives 3
          ....
    */

     private   final   int  m ()
     {    int  n  =   0 ;
        int  i  =   0 ;
        while ( true )
        {    if   ( >  j )   return  n ;
           if   ( !  cons ( i ))   break ;  i ++ ;
        }
       i ++ ;
        while ( true )
        {    while ( true )
           {    if   ( >  j )   return  n ;
                 if   ( cons ( i ))   break ;
                i ++ ;
           }
          i ++ ;
          n ++ ;
           while ( true )
           {    if   ( >  j )   return  n ;
              if   ( !  cons ( i ))   break ;
             i ++ ;
           }
          i ++ ;
         }
     }

     /* vowelinstem() is true <=> 0,...j contains a vowel */

     private   final   boolean  vowelinstem ()
     {    int  i ;   for   ( =   0 ;  i  <=  j ;  i ++ )   if   ( !  cons ( i ))   return   true ;
        return   false ;
     }

     /* doublec(j) is true <=> j,(j-1) contain a double consonant. */

     private   final   boolean  doublec ( int  j )
     {    if   ( <   1 )   return   false ;
        if   ( b [ j ]   !=  b [ j - 1 ])   return   false ;
        return  cons ( j );
     }

     /* cvc(i) is true <=> i-2,i-1,i has the form consonant - vowel - consonant
       and also if the second c is not w,x or y. this is used when trying to
       restore an e at the end of a short word. e.g.

          cav(e), lov(e), hop(e), crim(e), but
          snow, box, tray.

    */

     private   final   boolean  cvc ( int  i )
     {    if   ( <   2   ||   ! cons ( i )   ||  cons ( i - 1 )   ||   ! cons ( i - 2 ))   return   false ;
        {    int  ch  =  b [ i ];
           if   ( ch  ==   'w'   ||  ch  ==   'x'   ||  ch  ==   'y' )   return   false ;
        }
        return   true ;
     }

     private   final   boolean  ends ( String  s )
     {    int  l  =  s . length ();
        int  o  =  k - l + 1 ;
        if   ( <   0 )   return   false ;
        for   ( int  i  =   0 ;  i  <  l ;  i ++ )   if   ( b [ o + i ]   !=  s . charAt ( i ))   return   false ;
       j  =  k - l ;
        return   true ;
     }

     /* setto(s) sets (j+1),...k to the characters in the string s, readjusting
       k. */

     private   final   void  setto ( String  s )
     {    int  l  =  s . length ();
        int  o  =  j + 1 ;
        for   ( int  i  =   0 ;  i  <  l ;  i ++ )  b [ o + i ]   =  s . charAt ( i );
       k  =  j + l ;
     }

     /* r(s) is used further down. */

     private   final   void  r ( String  s )   {   if   ( m ()   >   0 )  setto ( s );   }

     /* step1() gets rid of plurals and -ed or -ing. e.g.

           caresses  ->  caress
           ponies    ->  poni
           ties      ->  ti
           caress    ->  caress
           cats      ->  cat

           feed      ->  feed
           agreed    ->  agree
           disabled  ->  disable

           matting   ->  mat
           mating    ->  mate
           meeting   ->  meet
           milling   ->  mill
           messing   ->  mess

           meetings  ->  meet

    */

     private   final   void  step1 ()
     {    if   ( b [ k ]   ==   's' )
        {    if   ( ends ( "sses" ))  k  -=   2 ;   else
           if   ( ends ( "ies" ))  setto ( "i" );   else
           if   ( b [ k - 1 ]   !=   's' )  k -- ;
        }
        if   ( ends ( "eed" ))   {   if   ( m ()   >   0 )  k -- ;   }   else
        if   (( ends ( "ed" )   ||  ends ( "ing" ))   &&  vowelinstem ())
        {   k  =  j ;
           if   ( ends ( "at" ))  setto ( "ate" );   else
           if   ( ends ( "bl" ))  setto ( "ble" );   else
           if   ( ends ( "iz" ))  setto ( "ize" );   else
           if   ( doublec ( k ))
           {   k -- ;
              {    int  ch  =  b [ k ];
                 if   ( ch  ==   'l'   ||  ch  ==   's'   ||  ch  ==   'z' )  k ++ ;
              }
           }
           else   if   ( m ()   ==   1   &&  cvc ( k ))  setto ( "e" );
       }
     }

     /* step2() turns terminal y to i when there is another vowel in the stem. */

     private   final   void  step2 ()   {   if   ( ends ( "y" )   &&  vowelinstem ())  b [ k ]   =   'i' ;   }

     /* step3() maps double suffices to single ones. so -ization ( = -ize plus
       -ation) maps to -ize etc. note that the string before the suffix must give
       m() > 0. */

     private   final   void  step3 ()   {   if   ( ==   0 )   return ;   /* For Bug 1 */   switch   ( b [ k - 1 ])
     {
         case   'a' :   if   ( ends ( "ational" ))   {  r ( "ate" );   break ;   }
                   if   ( ends ( "tional" ))   {  r ( "tion" );   break ;   }
                   break ;
         case   'c' :   if   ( ends ( "enci" ))   {  r ( "ence" );   break ;   }
                   if   ( ends ( "anci" ))   {  r ( "ance" );   break ;   }
                   break ;
         case   'e' :   if   ( ends ( "izer" ))   {  r ( "ize" );   break ;   }
                   break ;
         case   'l' :   if   ( ends ( "bli" ))   {  r ( "ble" );   break ;   }
                   if   ( ends ( "alli" ))   {  r ( "al" );   break ;   }
                   if   ( ends ( "entli" ))   {  r ( "ent" );   break ;   }
                   if   ( ends ( "eli" ))   {  r ( "e" );   break ;   }
                   if   ( ends ( "ousli" ))   {  r ( "ous" );   break ;   }
                   break ;
         case   'o' :   if   ( ends ( "ization" ))   {  r ( "ize" );   break ;   }
                   if   ( ends ( "ation" ))   {  r ( "ate" );   break ;   }
                   if   ( ends ( "ator" ))   {  r ( "ate" );   break ;   }
                   break ;
         case   's' :   if   ( ends ( "alism" ))   {  r ( "al" );   break ;   }
                   if   ( ends ( "iveness" ))   {  r ( "ive" );   break ;   }
                   if   ( ends ( "fulness" ))   {  r ( "ful" );   break ;   }
                   if   ( ends ( "ousness" ))   {  r ( "ous" );   break ;   }
                   break ;
         case   't' :   if   ( ends ( "aliti" ))   {  r ( "al" );   break ;   }
                   if   ( ends ( "iviti" ))   {  r ( "ive" );   break ;   }
                   if   ( ends ( "biliti" ))   {  r ( "ble" );   break ;   }
                   break ;
         case   'g' :   if   ( ends ( "logi" ))   {  r ( "log" );   break ;   }
     }   }

     /* step4() deals with -ic-, -full, -ness etc. similar strategy to step3. */

     private   final   void  step4 ()   {   switch   ( b [ k ])
     {
         case   'e' :   if   ( ends ( "icate" ))   {  r ( "ic" );   break ;   }
                   if   ( ends ( "ative" ))   {  r ( "" );   break ;   }
                   if   ( ends ( "alize" ))   {  r ( "al" );   break ;   }
                   break ;
         case   'i' :   if   ( ends ( "iciti" ))   {  r ( "ic" );   break ;   }
                   break ;
         case   'l' :   if   ( ends ( "ical" ))   {  r ( "ic" );   break ;   }
                   if   ( ends ( "ful" ))   {  r ( "" );   break ;   }
                   break ;
         case   's' :   if   ( ends ( "ness" ))   {  r ( "" );   break ;   }
                   break ;
     }   }

     /* step5() takes off -ant, -ence etc., in context <c>vcvc<v>. */

     private   final   void  step5 ()
     {     if   ( ==   0 )   return ;   /* for Bug 1 */   switch   ( b [ k - 1 ])
         {    case   'a' :   if   ( ends ( "al" ))   break ;   return ;
            case   'c' :   if   ( ends ( "ance" ))   break ;
                      if   ( ends ( "ence" ))   break ;   return ;
            case   'e' :   if   ( ends ( "er" ))   break ;   return ;
            case   'i' :   if   ( ends ( "ic" ))   break ;   return ;
            case   'l' :   if   ( ends ( "able" ))   break ;
                      if   ( ends ( "ible" ))   break ;   return ;
            case   'n' :   if   ( ends ( "ant" ))   break ;
                      if   ( ends ( "ement" ))   break ;
                      if   ( ends ( "ment" ))   break ;
                      /* element etc. not stripped before the m */
                      if   ( ends ( "ent" ))   break ;   return ;
            case   'o' :   if   ( ends ( "ion" )   &&  j  >=   0   &&   ( b [ j ]   ==   's'   ||  b [ j ]   ==   't' ))   break ;
                                      /* j >= 0 fixes Bug 2 */
                      if   ( ends ( "ou" ))   break ;   return ;
                      /* takes care of -ous */
            case   's' :   if   ( ends ( "ism" ))   break ;   return ;
            case   't' :   if   ( ends ( "ate" ))   break ;
                      if   ( ends ( "iti" ))   break ;   return ;
            case   'u' :   if   ( ends ( "ous" ))   break ;   return ;
            case   'v' :   if   ( ends ( "ive" ))   break ;   return ;
            case   'z' :   if   ( ends ( "ize" ))   break ;   return ;
            default :   return ;
         }
         if   ( m ()   >   1 )  k  =  j ;
     }

     /* step6() removes a final -e if m() > 1. */

     private   final   void  step6 ()
     {   j  =  k ;
        if   ( b [ k ]   ==   'e' )
        {    int  a  =  m ();
           if   ( >   1   ||  a  ==   1   &&   ! cvc ( k - 1 ))  k -- ;
        }
        if   ( b [ k ]   ==   'l'   &&  doublec ( k )   &&  m ()   >   1 )  k -- ;
     }

     /** Stem the word placed into the Stemmer buffer through calls to add().
     * Returns true if the stemming process resulted in a word different
     * from the input.  You can retrieve the result with
     * getResultLength()/getResultBuffer() or toString().
     */
     public   void  stem ()
     {   k  =  i  -   1 ;
        if   ( >   1 )   {  step1 ();  step2 ();  step3 ();  step4 ();  step5 ();  step6 ();   }
       i_end  =  k + 1 ;  i  =   0 ;
     }

     /** Test program for demonstrating the Stemmer.  It reads text from a
     * a list of files, stems each word, and writes the result to standard
     * output. Note that the word stemmed is expected to be in lower case:
     * forcing lower case must be done outside the Stemmer class.
     * Usage: Stemmer file-name file-name ...
     */
     public   static   void  main ( String []  args )   throws   FileNotFoundException
     {
        char []  w  =   new   char [ 501 ];
        Stemmer  s  =   new   Stemmer ();
        for   ( int  i  =   0 ;  i  <  args . length ;  i ++ )
         try
           {   while ( true )

             {   fileInputStream  =   new   FileInputStream ( args [ i ]);
             int  ch  =  fileInputStream . read ();
                if   ( Character . isLetter (( char )  ch ))
                {
                   int  j  =   0 ;
                   while ( true )
                   {   ch  =   Character . toLowerCase (( char )  ch );
                    w [ j ]   =   ( char )  ch ;
                      if   ( <   500 )  j ++ ;
                     ch  =  fileInputStream . read ();
                      if   ( ! Character . isLetter (( char )  ch ))
                      {
                         /* to test add(char ch) */
                         for   ( int  c  =   0 ;  c  <  j ;  c ++ )  s . add ( w [ c ]);

                         /* or, to test add(char[] w, int j) */
                         /* s.add(w, j); */

                        s . stem ();
                         {    String  u ;

                            /* and now, to test toString() : */
                           u  =  s . toString ();

                            /* to test getResultBuffer(), getResultLength() : */
                            /* u = new String(s.getResultBuffer(), 0, s.getResultLength()); */

                            System . out . print ( u );
                         }
                         break ;
                      }
                   }
                }
                if   ( ch  <   0 )   break ;
                System . out . print (( char ) ch );
             }
           }
           catch   ( IOException  e )
           {    System . out . println ( "error reading "   +  args [ i ]);
              break ;
           }
     }
     }

Web Crawler/src/edu/smu/lyle/crawler/Wordfrequency.java

Web Crawler/src/edu/smu/lyle/crawler/Wordfrequency.java

package  edu . smu . lyle . crawler ;
import  java . io . FileInputStream ;
import  java . io . IOException ;
import  java . util . List ;
import  java . util . ArrayList ;
import  java . util . Collections ;
import  java . util . Enumeration ;
import  java . util . Hashtable ;
import  java . util . Iterator ;
import  java . util . LinkedHashMap ;
import  java . util . Scanner ;
import  java . util . StringTokenizer ;

public   class   Wordfrequency   {

     private   static   final   Hashtable < String ,   Integer >   Null   =   null ;     

     public   static   void  main ( String []  args )   throws   IOException   {
         System . out . println ( "in to the main" );
         Wordfrequency  test  =   new   Wordfrequency ();
        test . countWordFre ( args );   // for accessing the countWordFre method
     }

     // countWordFre method      
     public   void  countWordFre ( String []  fileNames )   throws   IOException   {

         int  i ;

         Scanner  fileReader  =   null ;

         Hashtable < String ,   Integer >  map  =   new   Hashtable < String ,   Integer > ();

         System . out . println ( "reading files" );

         System . out . println ( "enter how many number of files to read" );
         System . out . println ( " enter the filename" );

         // as command line arguments

         for   (  i  =   0   ;  i  <  fileNames . length  ;  i ++   )   {

            fileReader  =   new   Scanner ( new   FileInputStream ( fileNames  [ i ]));
         }


         while   ( fileReader . hasNextLine ())   {

             String  line  =  fileReader . nextLine ();

             String  word ;
             // to read each tokens of a line

             StringTokenizer  st  =   new   StringTokenizer ( line );


             while   ( st . hasMoreTokens ())   {

                word  =  st . nextToken (). toLowerCase ();

                 System . out . println ( "converting the words to lower case" );    


                 if   ( map . containsKey ( word ))   {

                     int  count  =   ( Integer )  map . get ( word );

                    map . put ( word ,  count  +   1 );

                 }   else   {

                    map . put ( word ,   1 );

                 }

             }

         }

         Enumeration < String >  e  =  map . keys ();

         while   ( e . hasMoreElements ())   {

             String  word  =  e . nextElement ();

             System . out . println ( word  +   " "   +  map . get ( word ));
         }  
     }
    // System.out.println(map.size());




     public   void   List ()   throws   IOException

     {

         System . out . println ( "to find 20 frq word" );


         Hashtable < String ,   Integer >  map  =   Null ;



         List < String >  mapKeys  =   new   ArrayList < String > ();

         List < Integer >  mapValues  =   new   ArrayList < Integer > ( map . values ());   


         Collections . sort ( mapValues );
         Collections . reverse ( mapValues );   //descending order sort
         Collections . sort ( mapKeys );
         Collections . reverse ( mapValues );

         LinkedHashMap < String ,   Integer >  sortedMap  =   new   LinkedHashMap < String ,   Integer > ();  

         Iterator < Integer >  valueIt  =  mapValues . iterator ();

         while   ( valueIt . hasNext ())   {

             Object  val  =  valueIt . next ();


             Iterator < String >  keyIt  =  mapKeys . iterator ();

             while   ( keyIt . hasNext ())   {

                Object  key  =  keyIt . next ();

                String  valueFromOriginalMap  =  map . get ( key ). toString ();

                String  valueFromCurrentIteration  =  val . toString ();

                if   ( valueFromOriginalMap  . equals ( valueFromCurrentIteration  ))   {                                                  

                    map . remove ( key );                                                     
                    mapKeys . remove ( key );                                              
                    sortedMap . put (( String ) key  ,   ( Integer ) val );

                     break ;
                }        


            }

      }

   }

}