JavaCreating a Portable Bookmark Library using Java, Part 2

Creating a Portable Bookmark Library using Java, Part 2

Developer.com content and product recommendations are editorially independent. We may make money when you click on links to our partners. Learn More.

Java Programming Notes # 2408


Preface

This is Part 2 of a two-part lesson that will teach you how to write a Java program to create and maintain a
portable bookmark (Favorites) library that will follow you from browser to browser, machine to machine, and operating
system to operating system.  Part 1 of this lesson was entitled
Creating a
Portable Bookmark Library using Java
.

Viewing tip

You may find it useful to open another copy of this lesson in a
separate browser window.  That will make it easier for you to
scroll back
and forth among the different listings and figures while you are
reading
about them.

Supplementary material

I recommend that you also study the other lessons in my extensive
collection of online Java tutorials.  You will find those lessons
published
at Gamelan.com
However, as of the date of this writing, Gamelan doesn’t maintain a
consolidated index of my Java tutorial lessons, and sometimes they are
difficult to locate there.  You will find a consolidated index at www.DickBaldwin.com.

General Background Information

Part 1 of this lesson provided general background information on
creating and maintaining a portable bookmark library. 
I won’t repeat that information here, but will simply refer you to that
document.

We need a program

Having suggested how you can use your web mail account as a portable bookmark
library, I provided and explained a program that you can:

  • Run initially to populate your web mail bookmark
    library with the hundreds or thousands of bookmarks that you have accumulated
    in the past.
  • Run periodically thereafter to update and consolidate your
    web mail
    bookmark library to incorporate new bookmarks that you have created using one or more
    different browsers on one or more different computers as you do your normal web research.

Firefox, Netscape, and Internet Explorer

The program that I provided in
Part 1 can be used to consolidate Firefox, Netscape,
and Internet Explorer bookmarks into your web mail
bookmark library.  The code that is specific to the different browser
formats is isolated in two methods.  If you use a browser that
creates and maintains its bookmarks in a format that is different from the
list of browsers given above, you should be able to write a new method to handle the bookmark format
for that browser.

My favorite web mail is
Google Gmail

Although I occasionally use three different web mail accounts, the one that I
use most consistently and the one that I know the most about is
Google Gmail.  Therefore, most of the
discussion in this lesson has been slanted toward the use of Gmail for this
purpose.  However, this approach should work equally well with just about
any web mail account provided that it has sufficient capacity, search
capability, and longevity.

Preview

As mentioned earlier, this document is the second part of a two-part lesson. 
Part 1 explained the overall control code, using method stubs for the
following two methods in place of the methods that actually extract bookmarks
from specific browser bookmark libraries.

  • getFireFoxBookmarks
  • getIEBookmarks

This part of the lesson provides and explains those two methods in detail. 
At the completion of this lesson you should have everything you need to create,
populate, and maintain your own portable bookmark library.

Discussion
and Sample Code


This program, named Bookmarks02 that I will provide and explain in this
lesson is the same as the program named
Bookmarks02a
(that I provided and explained in
Part 1)
, except that the two
methods listed above have been replaced in this version by
actual methods instead of the stubs used in
Part 1.

Purpose of the program

The purpose of this program is to:

  • Extract bookmarks from one or more Firefox, Netscape, or Internet
    Explorer (IE) browsers within a specified range of bookmark indices.
  • Construct an Email message containing the name and the URL of each
    extracted bookmark.
  • Send the messages to a specified destination Email address.

Email message format

Each Email message is formatted with the name of the bookmark as the Subject
and the URL for the bookmark in the body of the message.  To use this
message as a bookmark later, simply open the message in the archives of your web
mail account and double-click the
URL.

A bookmark code

The Subject of the Email message may optionally be prepended with a text string provided by the
user and identified as bkMrkCode below.  The string that is prepended to the
subject can be used by the Email client to recognize the message as a bookmark
message.

A bookmark history list

The program maintains a list of bookmarks that have previously been sent to
the destination Email address.  The purpose of this list is to prevent the
sending of duplicate bookmark messages to the destination Email address during
successive runs of the program.

The history list is maintained in a text
file that can easily be edited by the user if such editing becomes necessary. 
Several backup copies of the file are automatically generated and maintained by
the program. 

History file is automatically created, backed up,
and maintained

The history file is named BkMrkHistory.txt.  If it doesn’t
already exist, it is automatically created (in a folder specified by the user and
identified below as dataOutPath)
the first time the program is run. 
Once the file is created, it is backed up at the beginning of each successive run of
the program.  Then it is updated during that run.

Prevention of duplicate Email messages

Bookmarks identified in the history list are not sent to the destination Email
address.  This prevents the sending of duplicate bookmark messages during
successive runs of the program.

Once all the bookmarks in the Firefox or
Netscape bookmark file (or the IE Favorites folder) have been sent to the
destination Email address, this program will send only those bookmarks that have
been added or changed since the last time the program was run.

Don’t overwhelm the SMTP server

Because the number of messages that could be sent the first time the program
is run could overwhelm the SMTP server, (causing your ISP to erroneously
conclude that you are distributing SPAM email)
, the program allows the user to specify
the index of the first bookmark to be sent and the maximum number of bookmarks
to be sent during any particular run.

Controlled by command-line parameters

This program is controlled using command-line parameters making it very easy
to run the program periodically using a batch file or a script.

(Once you create the batch file, all that you need to do to run the
program is to start the batch file.  If you put a shortcut to the batch
file on your desktop, you can run the program simply by double-clicking the
shortcut icon.)

The required command-line parameters

The following
values must be provided as command-line parameters.  Although all command-line
parameters are provided as strings, several of the parameters must be convertible to the
int and boolean types shown
below.

  • String destAdr:  Email address to which bookmarks are to be
    sent.
  • String smtpServer:  An SMTP server that can be used to send
    the messages.
  • String bkMrkPath:  Path to the folder containing the Firefox
    or Netscape bookmark file, (which is an HTML file) or containing the IE
    Favorites files (which Microsoft refers to as Internet Shortcut
    files)
    .
  • String bkMrkFile:  Name of the Firefox or Netscape bookmark
    file.  (Provide a dummy file name if you are processing IE
    Favorites.)
  • String dataOutPath:  Path to a folder where output files
    will be stored.  (Make sure this folder is on the path for your regular
    backups because you don’t want to lose these files in case of a disk
    failure.)
  • String bkMrkCode:  Unique code that is prepended to the
    Subject of the Email message to identify the message as a bookmark message.
  • int lowBkMrkLimit:  First bookmark index to process.
  • int numToProc:  Number of bookmarks to process.
  • String browser:  Type of browser: F for Firefox, N for
    Navigator, or I for Internet Explorer.
  • boolean sendMsgs:  Specify true or false.  Messages
    will be sent on true.  Message will not be sent, but bookmark
    statistics will be displayed on false.

Program testing

This program was tested using J2SE 5.0 under WinXP.  J2SE 5.0 or later
is required due to the use of
generics.

The Bookmarks02 class

The class definition and the main method begin in Listing 1. 
Much of the code in Listing 1 was deleted for brevity.  However, all
of the code that was deleted from Listing 1 was explained in
Part 1 of this
lesson.

Listing 1 picks up at the point in the program code that is significant
relative to the explanation of the following two methods in this part of the
lesson.

  • getFireFoxBookmarks
  • getIEBookmarks
class Bookmarks02{

  public static void main(String[] args){

    //Code deleted for brevity

    if(browser.toUpperCase().equals("F")){
      //Process FireFox bookmarks.
      thisObj.copyBkMrkFile(bkMrkPath,bkMrkFile,
                                dataOutPath,tempBkMrkFile);
      theBookmarks = thisObj.getFireFoxBookmarks(
                                dataOutPath,tempBkMrkFile);
    }else if(browser.toUpperCase().equals("N")){
      //Process Netscape Navigator bookmarks.  Same format
      // as FireFox
      thisObj.copyBkMrkFile(bkMrkPath,bkMrkFile,
                                dataOutPath,tempBkMrkFile);
      theBookmarks = thisObj.getFireFoxBookmarks(
                                dataOutPath,tempBkMrkFile);
    }else if(browser.toUpperCase().equals("I")){
      //Process Inernet Explorer favorites.
      theBookmarks = thisObj.getIEBookmarks(
                                   bkMrkPath,theBookmarks);
    }else{
      System.out.println("Don't recognize browser");
      System.out.println("Terminating program");
      System.exit(0);
    }//end else

Listing 1

Decide among Firefox, Netscape, and IE

The code in Listing 1 uses one of the command-line parameters to decide
whether to invoke the getFireFoxBookmarks method or the getIEBookmarks
to extract the bookmark information from the browser file(s) and to save the
results in an ArrayList object.

Firefox and Netscape bookmark formats are the same

As near as I can determine, the bookmark file format for Firefox and Netscape are the same.  Therefore, the code in
Listing 1 invokes the same
method regardless of whether the user specifies Firefox or Netscape Navigator in
the command-line parameter.

(If I learn later that the Netscape format is different from the
Firefox format, I will write a new method to accommodate the Netscape format
and reference the new method in
Listing 1.  This is also the place where you would need to modify the program if
you were to develop a method to extract bookmark information from some
browser other than the three supported by this program as written.)

The code in Listing 1 causes the bookmark information to be extracted from the browser file(s) and
stored as objects of type Bookmark in the ArrayList object that was
instantiated in Listing 6.  That ArrayList object is referred to by theBookmarks.

Very little browser-specific code

When these methods return, the bookmark information is ready to be processed, independently of the
specific browser involved.  The only code in this program that is
browser-specific is the code in Listing 1 and the two methods named
getFireFoxBookmarks
and getIEBookmarks.  These two methods extract bookmark
information from the browser file(s).

At this point, I will set the main method aside and explain these two methods in
detail.  I will return to my explanation of the main method
later.

The getFireFoxBookmarks method

The getFireFoxBookmarks method begins in Listing 2.  The purpose of this method is to extract all of the bookmarks
from a Firefox or Netscape bookmark file and to encapsulate them in an ArrayList object.  Each element in the
ArrayList object is an object of the inner class named Bookmark
Each Bookmark object contains the name and the URL for one bookmark.

The Bookmark class

The Bookmark class is a very simple class whose sole purpose is to
encapsulate two String objects:

  • The name of the bookmark
  • The URL for the bookmark

You can view the definition of the Bookmark class in Listing 17.

Some background information on bookmarks

Before getting into the details of the getFireFoxBookmarks method, I
need to provide you with some background information regarding the Firefox,
Netscape, and IE approaches to bookmarks.

Entirely different approaches

Firefox and Netscape use an entirely different approach to the creation and
maintenance of the bookmark library.  Therefore, the ability to handle
these two different approaches is written into two completely different methods
in this program.

A well-behaved HTML file

The Firefox approach is to encapsulate the bookmark information into a well
behaved HTML file.  This file can have quite a lot of structure,
particularly if the user has created a complex system of folders.  In the
final analysis, however, all of the information of interest for each bookmark is
contained in an HTML element named A.  The URL for the bookmark is defined
by the value of an attribute named HREF.  The name of the bookmark is
provided as the content of the element.

(If you are unfamiliar with this terminology, see my previously
published tutorials in the section entitled
XML for Beginners.)

A sample element

Figure 1 shows an example of such an element.  Note, however, that all
of this material appears on a single line of text in the Firefox HTML file. 
It was necessary for me to manually insert several line breaks in Figure 1 to
cause the material to fit in this narrow publication format.


<A HREF="http://www.austinjug.org/" 
ADD_DATE="989249911" 
LAST_VISIT="989249897" 
LAST_MODIFIED="989249897" 
ID="rdf:#$FOszP3">
Austin Java Users Group
</A>

Figure 1

The name and the URL are shown in boldface

The information of interest is shown in boldface in Figure 1.  The URL
(the value of the HREF attribute) is shown in boldface on the first line. 
The content of the element is shown in boldface near the end.

Other attributes

The element in Figure 1 shows four other attributes that this program
ignores:

  • ADD_DATE
  • LAST_VISIT
  • LAST_MODIFIED
  • ID

You may decide that you want to modify the program to also include this
information in your portable bookmark library, and it wouldn’t be difficult to
do so.

In addition, some of the elements have attributes not shown in Figure 1, (such as an ICON
attribute)
, which are also ignored by this program.

Not difficult to parse

Fortunately, it is not difficult to parse this HTML file to extract the URL
and the name for each bookmark.  The code to accomplish that begins in
Listing 2, which shows the beginning of the getFireFoxBookmarks method.

  ArrayList <Bookmark> getFireFoxBookmarks(
                  String dataOutPath,String tempBkMrkFile){
    int urlIndex = 0;
    int startIndex = 0;
    int endIndex = 0;
    ArrayList <Bookmark> theBookmarks = 
                                new ArrayList <Bookmark>();

Listing 2

The code in listing 2 declares and initializes some local working variables. 
It also instantiates the ArrayList object that will be populated with
bookmark data and returned when the method terminates.

Read each line of text

Listing 3 shows the beginning of a while loop that reads each line of text from the bookmark file.

    try{
      BufferedReader bufRdr = new BufferedReader(
          new InputStreamReader(new FileInputStream(
                            dataOutPath + tempBkMrkFile)));
      String theName = null;
      String theUrl = null;
      String data = null;

      while((data = bufRdr.readLine()) != null){

Listing 3

Does the line contain a URL?

Each line of text will be tested to determine if it contains an HREF
attribute.  If so, the program will conclude that the line of text contains
one (and only one) element named A.  The code in the loop
will extract the URL from the value of the HREF attribute, and will extract the
name of the bookmark from the content of the element named A that is
contained in that line of text.

(The fact that one, and only one entire element named A is contained
in a single line of text greatly simplifies the code required to parse the
file and to extract the name and URL of each bookmark.)

Test for existence of HREF attribute

Listing 4 invokes the indexOf method on the String object that
describes the line of text to determine if it contains an attribute
named HREF.  This method attempts to find a numeric index that defines the location of
the following substring:

A HREF=".

        urlIndex = data.indexOf("A HREF="");

Listing 4

The index value that is returned by the indexOf method is stored in the variable named urlIndex.

The
value of urlIndex will be -1 if the line doesn’t contain the specified substring. 
In that case, the program will simply ignore that line of text and read the next
line.  If the value of the index is not -1, that value will be used later
to extract the URL.

Get the URL for the bookmark

The code in Listing 5 extracts and saves the URL for the case where the value
of the index is not -1.

        if(urlIndex != -1){
          //Find the index of the quotation marks at the
          // beginning and the end of the URL.
          startIndex = urlIndex+8;//Index of first quote+1
          //Index of quotation mark at the end of the URL.
          endIndex = data.indexOf(""",startIndex);
          //Extract and save the URL
          theUrl = data.substring(startIndex,endIndex);

Listing 5

The code in Listing 5, (as explained by the comments), is
straightforward and shouldn’t require further explanation.

Get the name of the bookmark

The code in Listing 6 gets and saves the name of the bookmark, which is the
content of the element named A.  You may want to refer back to
Figure 1 to gain a better understanding of exactly how this code works.

          // Get the index of the beginning of the content.
          startIndex = data.indexOf(">",urlIndex) +1;
          //Get the index of the end of the content.
          endIndex = data.indexOf("</A>",startIndex);
          //Get and save the content
          if(endIndex > startIndex){
            //The A element is not empty.
            theName = data.substring(startIndex,endIndex);
          }else{
            //The A element is empty
            theName = "No bookmark name found.";
          }//end else

Listing 6

Once again, the code in Listing 6, (as explained by the comments), is
straightforward and shouldn’t require further explanation.  Note, however,
that in the unlikely event that there is no content, an artificial name for the
bookmark is generated.

Process next line of text

The code in Listing 7 adds the bookmark just extracted to the ArrayList
object, and then goes back to the top of the while loop that began in
Listing 3 to process the next line of text.  As you can see, the name and
the URL are encapsulated in a Bookmark object, whose reference is added
to the ArrayList object.

          theBookmarks.add(new Bookmark(theName,theUrl));
        }//end if
      }//end while

Listing 7

Return the populated ArrayList object

When all of the lines of text in the bookmark file have been processed,
control transfers from the while loop to the code in Listing 8.

The code in Listing 8 terminates the getFireFoxBookmarks method,
returning a reference to the ArrayList object in the process.  This
returns control to that portion of the main method shown in Listing 1.

      bufRdr.close();
    }catch(Exception e){
      e.printStackTrace();
      System.exit(0);
    }//end catch
    
    return theBookmarks;
  }//end getFireFoxBookmarks

Listing 8

As you will recall from
Part 1 of this lesson, the program goes on at that
point to invoke the processBkMrks method to process the contents of the
ArrayList object.

Processing IE Favorites

As mentioned earlier, the approach that Microsoft uses to create and maintain
the IE Favorites library is entirely different from the approach used by
Firefox.  The IE Favorites library is simply a directory tree structure
rooted in a Windows folder at a location similar to the following:

C:Documents and SettingsOwnerFavorites

Each bookmark is stored in a separate text file having an extension of URL.

(The Microsoft properties dialog refers to these files as Internet
Shortcut files.)

The name and the URL for the bookmark

The name of the bookmark is simply the name of the Internet Shortcut file.

The URL for the bookmark and some other information as well, is stored in
the Internet Shortcut file.

Bookmark library structure

Folders in the bookmark library are created by creating ordinary Windows
folders as children, grandchildren, etc., of the folder named Favorites.

A typical Internet Shortcut file

Figure 2 shows the contents of a typical Internet Shortcut file.  Note,
however, that it was necessary for me to manually insert several line breaks to
cause this material to fit in this narrow publication format.

[DEFAULT]
BASEURL=http://securityresponse.symantec.com/avcenter/
download/pages/US-NAVCE.html
[InternetShortcut]
URL=http://securityresponse.symantec.com/avcenter/
download/pages/US-NAVCE.html
Modified=90C11AFFF005C40124
IconFile=http://securityresponse.symantec.com/favicon.ico
IconIndex=1
Figure 2

The BASEURL item

I’m unsure as to the purpose of the item at the beginning of the file
identified as BASEURL=http…  This item isn’t contained in all
Internet Shortcut files.  When it is contained in the file, it is often a
duplicate of the item that begins with URL=http…

The URL item

The boldface item that begins with URL=http…, does seem to be
contained in all Internet Shortcut files.  Rightly or wrongly, while
writing this program, I assumed that this is the bookmark URL that needs to be
extracted.

The getTheUrl method

Since one of the obvious tasks of this program is to extract the URL from the
Internet Shortcut file, I will begin the discussion with a helper method named
getTheUrl
.  As you will see later, this is a helper method that
is called by the getIEBookmarks method.  The purpose of the
getTheUrl
method is to extract the URL from a Microsoft Internet Shortcut
file.

This method is shown in its entirety in Listing 9.

  String getTheUrl(String pathAndFile){
    try{
      BufferedReader inData = new BufferedReader(
                              new FileReader(pathAndFile));
      String data; //temp holding area

      while((data = inData.readLine()) != null){
        if(data.startsWith("URL=")){
          String theUrl = data.substring(4);
          inData.close();//Close input file
          return theUrl;
        }//end if
      }//end while loop
      inData.close();//Close input file
    }catch(Exception e){
      e.printStackTrace();
    }//end catch
    System.out.println("No URL Found");
    return "No URL Found";
  }//end getTheUrl

Listing 9

This method is straightforward.  Given what you have been told, and
given the sample in Figure 2 to look at, no further explanation should be
required. 

However, it is worth mentioning that the entire URL is contained in a single
line of text in the Internet Shortcut file, whereas it was necessary for me to
break the boldface URL into two lines for display purposes in Figure 2.

For the unexpected case where the Internet Shortcut file doesn’t contain a
line that matches the template used in Listing 9, the code in Listing 9 returns
a String containing an artificial URL.

The getIEBookmarks method

The code in Listing 1 invokes the getIEBookmarks method to extract the
names and the URLs from IE Favorites.  The getIEBookmarks method
begins in Listing 10.

The code in Listing 10 declares and initializes some local working variables.

  ArrayList <Bookmark> getIEBookmarks(
       String bkMrkPath,ArrayList <Bookmark> theBookmarks){
   
    String theName = null;
    String theUrl = null;
    String fileName = null;
    String pathAndFile = null;

Listing 10

It is important to note that one of the incoming parameter to the
getIEBookmarks
method is a reference to the ArrayList object that is
to be populated and returned by the method.  The other incoming parameter
is a String that identifies the Favorites directory.

A recursive method

Recall that the getFireFoxBookmarks method does not receive a
reference to the ArrayList object as an incoming parameter.  Rather,
that method instantiates, populates, and returns such an object completely
internal to the method.

However, the method named getIEBookmarks is a recursive method. 
This dictates that the method receive a reference to the ArrayList object
as an incoming parameter.

Conceptually more difficult

Depending on your prior experience with recursion, you may or may not find
this method to be conceptually more difficult than the getFireFoxBookmarks
method.

If you are unfamiliar with recursion in programming, you would do well to
search the web for some tutorial material on that topic before continuing with
this lesson.  One reference that you will probably find on the web is a
tutorial that I published several years ago involving recursion in
JavaScript
You will undoubtedly find many other, possibly better references as well.

Traversal of the directory tree

The getIEBookmarks method uses recursion to traverse the directory tree containing
Internet Shortcut files and other directories.  Each bookmark is represented by
an Internet Shortcut file.  An Internet Shortcut file has an extension of
url.  The name of the file is the name of the bookmark.  The URL for the bookmark is contained as a line of text in the
Internet Shortcut file.

Get a directory listing

The first task is to get a directory listing for the Favorites directory. 
The code in Listing 11:

  • Gets an object of type File that represents the directory
    specified by the incoming parameter.
  • Confirms that the directory actually exists (a File object
    representing a directory can exist in the absence of the directory that it
    represents)
    .
  • Confirms that it really represents a directory and not a file.
  • Gets and saves a directory listing for the directory.
  • Sorts the contents of the directory listing.
    //Get a File object that represents the directory.
    File fileObj = new File(bkMrkPath);
    //Make certain that the directory exists.
    if(fileObj.exists()){
      //Confirm that the File object represents a directory
      // and not a file.
      if(fileObj.isDirectory()){
        //Get a list of the directory contents in an array
        // object.
        File[] dirContents = fileObj.listFiles();
        //Sort the directory contents according to the
        // natural order.
        Arrays.sort(dirContents);
        //Process the contents of the directory that were
        // saved in the list of contents.

Listing 11

At this point, the program is ready to process the elements in the directory
listing.  Each of those elements can be a file, or can be another directory
(sub-directory).

Iterate on the directory listing

Listing 12 contains the beginning of a for loop that iterates on the
directory listing, processing each element in the listing.

        for(int cnt = 0;cnt < dirContents.length;cnt++){
          if(dirContents[cnt].isDirectory()){
            //Make a recursive call to process this
            // directory before processing the remaining
            // contents in the list of contents.
            theBookmarks = getIEBookmarks(
                  dirContents[cnt].getPath(),theBookmarks);

Listing 12

Is a recursive call necessary?

The code in the for loop begins by testing the element to determine if
it is another directory (sub directory).  If so, it makes a
recursive call to itself, passing the path to the sub directory and a reference
to the partially populated ArrayList object as parameters.

Another instance of the getIEBookmarks method is executed to process
the directory just discovered in the directory listing.  (The word
instance might not be a good word to use here, but I don’t know of a better word
to use.)

When this instance of the method returns, it returns a reference to the
ArrayList
object, which may have had additional bookmarks added to it.

Process a file

Listing 13 shows the beginning of the code that is executed if the directory
element is found to be a file instead of a directory.

          }else if(dirContents[cnt].isFile()){
            pathAndFile = dirContents[cnt].getPath();
            fileName = dirContents[cnt].getName();

Listing 13

The code in Listing 13 gets and saves:

  • The path to the file.
  • The name of the file.

Is this an Internet Shortcut file?

All Internet Shortcut files that represent bookmarks must have an extension
of url (but apparently the case is not consistent).  The code in
Listing 14 tests to confirm that the directory element meets this criterion.

            if(fileName.toUpperCase().endsWith(".URL")){
              theName = fileName.substring(
                 0,fileName.toUpperCase().indexOf(".URL"));
              theUrl = getTheUrl(pathAndFile);
              theBookmarks.add(
                             new Bookmark(theName,theUrl));
            }//end if

Listing 14

If the file is not an Internet Shortcut file, the file is simply ignored.

Process an Internet Shortcut file

If the file is an Internet Shortcut file, the code in Listing 14 extracts and
saves the name of the file (without the extension) as the name of the
bookmark.

Then the code in Listing 14 invokes the method named getTheUrl to get
and save the bookmark URL from the contents of the file.

Update the ArrayList object

Having gotten the name and the URL for the bookmark, the code in Listing 14
encapsulates those items in a new object of type Bookmark and adds that
object to the ArrayList object that is being populated with bookmark
information.

Cleanup and return the ArrayList object

Listing 15 does some necessary cleanup work and then returns a reference to
the now populated ArrayList object

          }//end else
        }//end for loop
      }else{
        System.out.println(
                  bkMrkPath + ": not a directory.");
      }//end else
    }else{
      System.out.println("Directory " + bkMrkPath
                                     + " does not exist.");
    }//end else
    return theBookmarks;
  }//end getIEBookmarks

Listing 15

The code in Listing 15 returns control to the main method shown in
Listing 1.  This is the end of the code that is specific to a particular
browser.

Process the bookmark data 

As before, the main method goes on to invoke the processBkMrks
method to process the now-populated ArrayList object as explained in
Part 1 of this lesson.  The code to accomplish this is shown in
Listing 16.

    //Process the ArrayList object, either extracting and
    // sending bookmarks as messages to destAdr, or simply
    // extracting and displaying the statistics.  The
    // TreeSet object will be updated to contain an
    // identification of all bookmarks sent to destAdr.
    thisObj.processBkMrks(destAdr,
                          smtpServer,
                          bkMrkCode,
                          lowBkMrkLimit,
                          numToProc,
                          sendMsgs,
                          bkMrkHistList,
                          theBookmarks);
    //Write a new bookmark history file containing the
    // final contents of the TreeSet object.
    thisObj.writeBkMrkHistFile(
                              bkMrkHistFile,bkMrkHistList);
  }// end main

Listing 16

I explained the processBkMrks method in
Part 1, and
won’t repeat that explanation here.

Run the Program

I encourage you to copy the code from Listing 17 into your text
editor, compile it, and execute it.  Experiment with it, making
changes, and observing the results of your changes.

Make the program interactive, providing the
capability for the user to edit the bookmark name and/or to enter keywords and a description
of the bookmark into the body of the
Email message that will be sent to your web mail account for each bookmark. 
See Part 1 for an indication of where to insert the code to accomplish
this upgrade.

If you use a browser other than Firefox, Netscape, or IE, modify the
code in Listing 1 to accommodate this new browser.  Then write a method
similar to the getFireFoxBookmarks method or the getIEBookmarks
method to support your browser.

Remember that you can disable the actual sending of Email messages to avoid cluttering
you inbox while performing these experiments, as explained in Listing 14 of
Part 1.

Summary

In Part 1 and Part 2 of this lesson, I have taught you how to use Java
to create and maintain a portable bookmark library that will
follow you from browser to browser, machine to machine, and operating system to
operating system.

Complete Program Listing


A complete listing of the program discussed in this lesson is shown in
Listing 17 below.
 

/* File Bookmarks02.java 
Copyright 2005, R.G.Baldwin
Revised 08/30/05

The purpose of this program is to:

1-Extract bookmarks from one or more FireFox, Netscape, or 
 Internet Explorer (IE) browsers within a specified range 
 of bookmark indices.
2-Construct an email message containing the name and the
 URL of each extracted bookmark.
3-Send the message to a specified destination email
 address.
  
(Note that the actual sending of the messages may have been
disabled for test purposes.  Search for the word disable to
find the code that may have been disabled.)

Each email message is formatted with the name of the 
bookmark as the subject and the URL for the bookmark in the
body of the message.

To use this message as a bookmark later, simply open the
message and double-click on the URL.

The subject may optionally be prepended with a text string 
provided by the user as bkMrkCode below.  The string that 
is prepended to the subject can be used by the email client
to recognize the message as a bookmark message.  If you 
don't want an actual string prepended to the subject, 
specify this parameter as an empty string, "".

The program also maintains a historical list of bookmarks 
that have previously been sent to the destination email 
address. The historical list is maintained in a text file 
that can easily be edited by the user if such editing 
becomes necessary.  Several backup copies of the file are 
automatically generated and maintained.

The historical file is named BkMrkHistory.txt.  If it 
doesn't already exist, it is automatically created in a 
folder specified by the user and identified below as
dataOutPath.  Once the file exists, it is backed up at the 
beginning of each successive run of the program.  Then it 
is updated during that run.

Bookmarks in the historical list are not sent to the
destination email address.  This prevents the sending of 
duplicate bookmark messages during successive runs of the 
program.

Once all the bookmarks in the FireFox or Netscape bookmark 
file (or the IE Favorites folder) have been sent to the 
destination email address, this program will send only 
those bookmarks that have been added or changed since the 
last time the program was run.

Because the number of messages that could be sent the first
time the program is run could overwhelm the SMTP server,
the program allows the user to specify the index of the
first bookmark to be sent and the maximum number of
bookmarks to be sent during any particular run.  For 
example, if values of 0 and 100 are used the first time the
program is run, it can be expected that 100 messages will 
be sent (assuming that there are at least 100 bookmarks).
These are the messages required to send bookmarks with 
indices of 0 through 99.

If values of 0 and 200 are used the second time the program
is run, it can be expected that 100 or more messages will 
be sent (assuming that there are at least 200 bookmarks).
This will consist of any new bookmarks in the index range 
of 0 through 99 plus all of the bookmarks in the index 
range of 100 through 199.

The following values must be provided as command-line 
parameters.  All command-line parameters are provided as
strings, but must be convertible to the types shown below.

String destAdr: Email address to which bookmarks are to
 be sent.
String smtpServer: An SMTP server that can be used to send
 the messages.
String bkMrkPath: Path to the folder containing the FireFox
 bookmark file, or containing the IE Favorites files.
String bkMrkFile: Name of the FireFox or Netscape bookmark
 file. Provide a dummy name if you are processing IE
 favorites.
String dataOutPath: Path to a folder where output files 
 will be stored.  Make sure that this folder is on the path
 for your regular backups, because you don't want to lose 
 these files in case of a disk failure.
String bkMrkCode: Unique code that is prepended to the
 Subject of the email message to identify the message as a 
 bookmark message.
int lowBkMrkLimit:  First bookmark index to process.
int numToProc: Number of bookmarks to process.
String browser: Type of browser: F for FireFox, N for
 Navigator, or I for Internet Explorer.
boolean sendMsgs: Specify true or false.  Messages will be
 sent on true.  Message will not be sent, but statistics
 will be displayed on false.

Tested using J2SE 5.0 under WinXP.  J2SE 5.0 or later is
required due to the use of generics.
**********************************************************/

import java.io.*;
import java.nio.channels.*;
import java.util.*;
import sun.net.smtp.SmtpClient;
import java.awt.*;

class Bookmarks02{

  public static void main(String[] args){
    //Confirm correct number of command-line parameters.
    // If the number is not correct, display a usage msg
    // and terminate the program.
    if(args.length != 10){
      System.out.println("Command-line parameter error");
      System.out.println();
      System.out.println("Usage: java Bookmarks02");
      System.out.println("followed by:");
      System.out.println("Destination email address");
      System.out.println("SMTP Server");
      System.out.println("Bookmark path");
      System.out.println("Bookmark file");
      System.out.println("Output data path");
      System.out.println("Bookmark code");
      System.out.println("Low bookmark limit");
      System.out.println("Number bookmarks to process");
      System.out.println("Browser, F, N, or I");
      System.out.println("Permission to send messages");
      System.out.println();
      System.out.println("Terminating Program");
      System.exit(0);      
    }//end if
    
    //The following values are provided as command-line
    // parameters.
    //Email address to which bookmarks are to be sent.
    String destAdr = args[0];
    //An SMTP server that can be used to send the messages.
    String smtpServer = args[1];
    //Path to the folder containing a FireFox bookmark
    // file or containing a multitude of IE .url files.
    String bkMrkPath = args[2];
    //Name of the FireFox bookmark file.  Just use a 
    // dummy name for this parameter when processing IE
    // favorites
    String bkMrkFile = args[3];
    //Path to the folder where output files will be stored.
    String dataOutPath = args[4];
    //Unique code that identifies a bookmark msg to
    // destAdr.  This code is prepended onto the name of
    // the bookmark and the name is put in the Subject line
    // of the message.
    String bkMrkCode = args[5];
    //Index of first bookmark to process.
    int lowBkMrkLimit = Integer.parseInt(args[6]);
    //Number of bookmarks to process.
    int numToProc = Integer.parseInt(args[7]);
    //Type of browser: F for FireFox, N for Navigator,
    // or I for Internet Explorer.
    String browser = args[8];
    //Send msgs on true.  Just display statistics on false.
    boolean sendMsgs = false;//default value
    //End of command-line parameters
    
    //Convert the last parameter from String to  boolean
    // and overwrite default if appropriate.
    if(args[9].toUpperCase().equals("TRUE")){
      sendMsgs = true;
    }//end if

    //Instantiate a new object of this class.    
    Bookmarks02 thisObj = new Bookmarks02();
    
    //Create a new bookmark history file if it doesn't
    // already exist.  If it does exist, just leave it
    // alone.
    String bkMrkHistFile = 
                          dataOutPath + "BkMrkHistory.txt";
    thisObj.createHistFile(bkMrkHistFile);
    
    //Create a TreeSet object to contain the bookmarks from
    // the bookmark history file.
    //This collection is used to store the contents
    // of the history file for processing.  It gets updated
    // when bookmarks are sent to the destAdr and the final
    // contents are written out into a new history file.
    TreeSet <String>bkMrkHistList = 
                  thisObj.makeBkMrkHistList(bkMrkHistFile);

    //Get the name and the URL for each of the bookmarks.
    // Encapsulate them in an object of type Bookmark.
    // Encapsulate all of the Bookmark objects in an object
    // of type ArrayList.
    
    //When processing bookmarks from a FireFox or Navigator
    // browser,  make a copy of the bookmark file.  Process
    // the copy instead of the original in order to reduce
    // the likelihood of inadvertently  corrupting the
    // original bookmark file.
    
    //The following collection encapsulates all of the
    // bookmarks awaiting final processing.  The
    // getIEBookmarks method requires that a method
    // parameter points to the ArrayList object on input
    // because of its recursive nature.  The
    // getFireFoxBookmarks method is not recursive and it
    // overwrites this object with a new ArrayList object
    // that it creates.
    ArrayList <Bookmark> theBookmarks = 
                                new ArrayList <Bookmark>();
    String tempBkMrkFile = "BkMrkTemp.html";
    if(browser.toUpperCase().equals("F")){
      //Process FireFox bookmarks.
      thisObj.copyBkMrkFile(bkMrkPath,bkMrkFile,
                                dataOutPath,tempBkMrkFile);
      theBookmarks = thisObj.getFireFoxBookmarks(
                                dataOutPath,tempBkMrkFile);
    }else if(browser.toUpperCase().equals("N")){
      //Process Netscape Navigator bookmarks.  Same format
      // as FireFox
      thisObj.copyBkMrkFile(bkMrkPath,bkMrkFile,
                                dataOutPath,tempBkMrkFile);
      theBookmarks = thisObj.getFireFoxBookmarks(
                                dataOutPath,tempBkMrkFile);
    }else if(browser.toUpperCase().equals("I")){
      //Process Inernet Explorer favorites.
      theBookmarks = thisObj.getIEBookmarks(
                                   bkMrkPath,theBookmarks);
    }else{
      System.out.println("Don't recognize browser");
      System.out.println("Terminating program");
      System.exit(0);
    }//end else

    //Process the ArrayList object, either extracting and
    // sending bookmarks as messages to destAdr, or simply
    // extracting and displaying the statistics.  The
    // TreeSet object will be updated to contain an
    // identification of all bookmarks sent to destAdr.
    thisObj.processBkMrks(destAdr,
                          smtpServer,
                          bkMrkCode,
                          lowBkMrkLimit,
                          numToProc,
                          sendMsgs,
                          bkMrkHistList,
                          theBookmarks);
    //Write a new bookmark history file containing the
    // final contents of the TreeSet object.
    thisObj.writeBkMrkHistFile(
                              bkMrkHistFile,bkMrkHistList);
  }// end main
  //-----------------------------------------------------//

  //This method creates a new history file if it doesn't
  // already exist.
  void createHistFile(String bkMrkHistFile){
    try{
      new File(bkMrkHistFile).createNewFile();
    }catch(Exception e){
      e.printStackTrace();
    }//end catch
  }//end createHostFile
  //-----------------------------------------------------//
  
  //This method processes bookmarks previously stored in an
  // ArrayList object.
  //If the value of sendMsgs is true, the method constructs
  // an email message for each bookmark and sends it to 
  // destAdr. Otherwise the method simply displays
  // statistics regarding the number of messages that would
  // be sent if the value of sendMsgs were true.
  void processBkMrks(String destAdr,
                     String smtpServer,
                     String bkMrkCode,
                     int lowBkMrkLimit,
                     int numToProc,
                     boolean  sendMsgs,
                     TreeSet <String>bkMrkHistList,
                     ArrayList <Bookmark> theBookmarks){
                      
    //Process the name and the URL for the bookmark.  The
    // bookmark is ignored unless it is within the range of
    // bookmarks specified for processing and it is not
    // contained in the bookmark history file.  If it is in
    // the bookmark history file, that means that it was
    // previously sent to the destination address. In this
    // case, it is ignored to avoid creating duplicate
    // bookmark at destAdr.
    
    //The following counter counts the number of bookmarks
    // that are eligible for sending to destAdr according
    // to the criteria given above.
    int msgCounter = 0;
    String theName = null;
    String theUrl = null;
    
    for(int cnt = 0;cnt < theBookmarks.size();cnt++){
      theName = theBookmarks.get(cnt).bkMrkName;
      theUrl = theBookmarks.get(cnt).bkMrkUrl;
      if((cnt >= lowBkMrkLimit) && 
         (cnt < lowBkMrkLimit + numToProc) &&
         (!bkMrkHistList.contains(theName + theUrl))){
        //This bookmark is eligible for sending to destAdr.
        msgCounter++;
        //Display the names of the eligible bookmark
        // on the command-line screen.
        System.out.println(cnt + " " + theName);
                         
        //Decide whether to send the bookmark to destAdr,
        // or to simply display the statistics on eligible
        // bookmarks.
        if(sendMsgs){
          //sendMsgs is true
          //Construct the message.  Put the name of the
          // bookmark in the Subject line, prepended
          // by bkMrkCode + ":".  Put three dots and the
          // URL on the first line of the body of the
          // message.  Leave the third line blank.  Put a
          // unique code on the fourth line to make the
          // message identifiable by a search regardless of
          // the bookmark name and URL.
          String message ="Subject: " + bkMrkCode + ":" + 
              theName + "nn" + " ... " + theUrl + "nn"
                               + "aiNy4DpjnVCgP190KrbCoP";
                          
          try{
            //Call the method to actually send the
            // message.  The method will return false
            // if it is unable to send the message.
            boolean success = true;
            //Disable the following statement to avoid
            // sending messages during testing.
            success = sendBkMrk(
                             destAdr,smtpServer,message);
            if(!success){
              //If unable to send the message.  This will
              // terminate the program and print the
              // error message shown.
              throw new Exception(
                         "Unable to send: " + theName);
            }//end if
            
            //Update the history list to contain the
            // bookmark that was just sent to the
            // destAdr.  Concatenate the name and the
            // URL of the bookmark and put that string
            // in the history list.
            bkMrkHistList.add(theName + theUrl);
          }catch(Exception ex){
            ex.printStackTrace();
            System.exit(0);
          }//end catch
        }//end if
      }//end if
    }//end for loop

    //Display summary information about the run.
    System.out.println(
              "Number eligible bookmarks = " + msgCounter);
    if(sendMsgs){
      //sendMgs is true.
      //All eligigle bookmarks will have been sent.
      System.out.println("Bookmarks sent = " + msgCounter);
    }else{
      //sendMsgs is false.
      System.out.println("Bookmarks sent = " + 0);
    }//end else
    
    System.out.println(
                   "Bookmark range = " + lowBkMrkLimit
                   + " to " + (lowBkMrkLimit + numToProc));
    System.out.println(
        "Total number bookmarks = " + theBookmarks.size());
  }//end processBkMrks
  //-----------------------------------------------------//
  
  //The purpose of this method is to send the message
  // to the destAdr.
  boolean sendBkMrk(String destAdr,
                    String smtpServer,
                    String message){
    try{
      //Pass a string containing the name of the smtp
      // server as a parameter to the  following
      // constructor.
      SmtpClient smtp = new SmtpClient(smtpServer);

      //Pass any valid email address to the from() method.
      smtp.from(destAdr);

      //Pass the email address of the destAdr to the
      // to() method.
      smtp.to(destAdr);

      //Get an output stream for the message
      PrintStream msg = smtp.startMessage();
      //Write the message into the output stream.
      msg.println(message);
      //Close the stream, sending the message
      smtp.closeServer();

      return true;//on successful send
    }catch( Exception e ){
      e.printStackTrace();
      System.out.println("while sending email");
      //Sound an alarm.
      try{
        Thread.currentThread().sleep(500);
        Toolkit.getDefaultToolkit().beep();
        Thread.currentThread().sleep(500);
        Toolkit.getDefaultToolkit().beep();
        Thread.currentThread().sleep(500);
        Toolkit.getDefaultToolkit().beep();
        Thread.currentThread().sleep(500);
      }catch(Exception ex){
        ex.printStackTrace();
      }//end catch
      //Return false to indicate that the msg
      // was not successfully forwarded.
      return false;
    }//end catch

  }//end sendBkMrk
  //-----------------------------------------------------//
  
  //This method reads a text file and causes each line of
  // text in the file to become an element in a TreeSet
  // object.  A TreeSet object contains no duplicates.
  
  //After creating the TreeSet object, the method writes
  // the data from the TreeSet into a backup file named
  // ....bakN, where the value of N is explained below.

  //A new backup file with a unique name based on N is
  // created each time the method is executed. Once the
  // number of backup files reaches 5, the method
  // automatically deletes the oldest file before creating
  // a new backup file.  Thus the method automatically
  // maintains a sequence of five backup files with
  // extensions .bak0 through bak5 with one number missing.
  // The age-order of the files should be determined by
  // the modification date and not by the name of the file.

  TreeSet <String> makeBkMrkHistList(String bkMrkHistFile){
    TreeSet <String> bkMrkHistList = new TreeSet<String>();

    //Read lines of text from text file and populate the
    // TreeSet object.
    try{
      BufferedReader inData = new BufferedReader(
                            new FileReader(bkMrkHistFile));
      String data; //temp holding area

      while((data = inData.readLine()) != null){
        bkMrkHistList.add(data);
      }//end while loop

      inData.close();//Close input file

      //Write a backup file before terminating the method.

      //First determine the name of the next backup file
      // allowed in the directory.
      int N = 0;
      File theFile = null;
      String baseFileName = bkMrkHistFile.
                substring(0,bkMrkHistFile.indexOf(".txt"));
      for(N = 0;N < 6;N++){
        theFile = new File(baseFileName + ".bak" + N);
        if(!(theFile.exists()))break;
      }//end for loop

      //Cause N to rotate from 0 through 5
      if(N == 5){//del file 0 for use next time
        new File(baseFileName + ".bak0").delete();
      }//end if
      else{//delete the next file in sequence
        if(new File(baseFileName + ".bak"
                                      + (N + 1)).exists()){
          new File(
                  baseFileName + ".bak"+ (N + 1)).delete();
        }//end if
      }//end else

      //Now write the output file
      DataOutputStream dataOut = new DataOutputStream(
                            new FileOutputStream(theFile));

      //Use an Iterator object to access the data
      // in the TreeSet object.
      Iterator <String>iter = bkMrkHistList.iterator();

      while(iter.hasNext()){
        data = iter.next();
        dataOut.writeBytes(data + "n");
      }//end while

      dataOut.close();
      
    }catch(Exception e){
      e.printStackTrace();
    }//end catch
    
    return bkMrkHistList;
  }//end makeBkMrkHistList
  //-----------------------------------------------------//
  
  //This method writes the data from a TreeSet object into
  // an output file.
  void writeBkMrkHistFile(String bkMrkHistFile,
                            TreeSet <String>bkMrkHistList){
    try{
      DataOutputStream dataOut = new DataOutputStream(
                      new FileOutputStream(bkMrkHistFile));

      //Use an iterator to access the data in
      // the TreeSet object.
      Iterator <String>iter = bkMrkHistList.iterator();
      String data;

      while(iter.hasNext()){
        data = iter.next();
        dataOut.writeBytes(data + "n");
      }//end while

      dataOut.close();
    }catch(Exception e){e.printStackTrace();}

  }//end writeBkMrkHistFile
  //-----------------------------------------------------//
  
  //This method copies the "official" book mark file into a
  // temporary book mark file to avoid any possibility of
  // corrupting the official book mark file during 
  // processing.
  void copyBkMrkFile(String bkMrkPath,
                     String bkMrkFile,
                     String dataOutPath,
                     String tempBkMrkFile){
    try{
      FileChannel inputChannel = new FileInputStream(
                       bkMrkPath + bkMrkFile).getChannel();
      FileChannel outputChannel = new FileOutputStream(
                 dataOutPath + tempBkMrkFile).getChannel();

      // Copy file contents from input file to output file
      outputChannel.transferFrom(
                     inputChannel, 0, inputChannel.size());
      inputChannel.close();
      outputChannel.close();
    }catch (IOException e){
      e.printStackTrace();
    }//end catch
  }//end copyFile
  //-----------------------------------------------------//
  
  //The purpose of this method is to extract all of the
  // bookmarks and to encapsulate them in an ArrayList
  // object.  Each element in the ArrayList object is an
  // object of the inner class named Bookmark.
  //This version of the method is designed to extract
  // bookmarks from FireFox and Netscape bookmark files.
  ArrayList <Bookmark> getFireFoxBookmarks(
                  String dataOutPath,String tempBkMrkFile){
    int urlIndex = 0;
    int startIndex = 0;
    int endIndex = 0;
    ArrayList <Bookmark> theBookmarks = 
                                new ArrayList <Bookmark>();
    try{
      BufferedReader bufRdr = new BufferedReader(
          new InputStreamReader(new FileInputStream(
                            dataOutPath + tempBkMrkFile)));
      //Read each line of text from the copy of the
      // bookmark file.  If the line contains a URL,
      // extract the URL and the name of the bookmark.
      String theName = null;
      String theUrl = null;
      String data = null;
      while((data = bufRdr.readLine()) != null){
        urlIndex = data.indexOf("A HREF="");
        
        //urlIndex will be -1 if line doesn't contain
        // a URL indicated by A HREF...  In that case, just
        // ignore the line of text.
        if(urlIndex != -1){
          //Find the index of the quotation marks at the
          // beginning and the end of the URL.
          startIndex = urlIndex+8;//Index of first quote+1
          //Index of quotation mark at the end of the URL.
          endIndex = data.indexOf(""",startIndex);
          //Extract and save the URL
          theUrl = data.substring(startIndex,endIndex);
          
          //Get and save the content of the element
          // named A.
          // Get the index of the beginning of the content.
          startIndex = data.indexOf(">",urlIndex) +1;
          //Get the index of the end of the content.
          endIndex = data.indexOf("</A>",startIndex);
          //Get and save the content
          if(endIndex > startIndex){
            //The A element is not empty.
            theName = data.substring(startIndex,endIndex);
          }else{
            //The A element is empty
            theName = "No bookmark name found.";
          }//end else

          theBookmarks.add(new Bookmark(theName,theUrl));
        }//end if
      }//end while
      bufRdr.close();
    }catch(Exception e){
      e.printStackTrace();
      System.exit(0);
    }//end catch
    
    return theBookmarks;
  }//end getFireFoxBookmarks
  //-----------------------------------------------------//
  
  //This method uses recursion to traverse the directory
  // tree containing IE Favorites.  Each bookmark is 
  // represented by a file with an extension of .url. The
  // name of the file is the name of the bookmark.  The
  // URL for the bookmark is contained as a line of text
  // in the file.
  ArrayList <Bookmark> getIEBookmarks(
       String bkMrkPath,ArrayList <Bookmark> theBookmarks){
   
    String theName = null;
    String theUrl = null;
    String fileName = null;
    String pathAndFile = null;
    
    //Get a File object that represents the directory.
    File fileObj = new File(bkMrkPath);
    //Make certain that the directory exists.
    if(fileObj.exists()){
      //Confirm that the File object represents a directory
      // and not a file.
      if(fileObj.isDirectory()){
        //Get a list of the directory contents in an array
        // object.
        File[] dirContents = fileObj.listFiles();
        //Sort the directory contents according to the
        // natural order.
        Arrays.sort(dirContents);
        //Process the contents of the directory that were
        // saved in the list of contents.
        for(int cnt = 0;cnt < dirContents.length;cnt++){
          if(dirContents[cnt].isDirectory()){
            //Make a recursive call to process this
            // directory before processing the remaining
            // contents in the list of contents.
            theBookmarks = getIEBookmarks(
                  dirContents[cnt].getPath(),theBookmarks);
          }else if(dirContents[cnt].isFile()){
            pathAndFile = dirContents[cnt].getPath();
            fileName = dirContents[cnt].getName();

            //All file names that represent bookmarks
            // should end with .url.
            if(fileName.toUpperCase().endsWith(".URL")){
              theName = fileName.substring(
                 0,fileName.toUpperCase().indexOf(".URL"));
              theUrl = getTheUrl(pathAndFile);
              theBookmarks.add(
                             new Bookmark(theName,theUrl));
            }//end if
          }//end else
        }//end for loop
      }else{
        System.out.println(
                  bkMrkPath + ": not a directory.");
      }//end else
    }else{
      System.out.println("Directory " + bkMrkPath
                                     + " does not exist.");
    }//end else
    return theBookmarks;
  }//end getIEBookmarks
  //-----------------------------------------------------//
  
  //This is a helper method called by getIEBookmarks.  The
  // purpose of this method is to extract the URL from a
  // Microsoft .url file.
  String getTheUrl(String pathAndFile){
    try{
      BufferedReader inData = new BufferedReader(
                              new FileReader(pathAndFile));
      String data; //temp holding area

      while((data = inData.readLine()) != null){
        if(data.startsWith("URL=")){
          String theUrl = data.substring(4);
          inData.close();//Close input file
          return theUrl;
        }//end if
      }//end while loop
      inData.close();//Close input file
    }catch(Exception e){
      e.printStackTrace();
    }//end catch
    System.out.println("No URL Found");
    return "No URL Found";
  }//end getTheUrl
  //-----------------------------------------------------//
  
  //This is an inner class, the purpose of which is to
  // encapsulate the name and the URL for a bookmark.
  class Bookmark{
    String bkMrkName;
    String bkMrkUrl;
    
    Bookmark(String bkMrkName,String bkMrkUrl){
      this.bkMrkName = bkMrkName;
      this.bkMrkUrl = bkMrkUrl;
    }//end constructor
  }//end inner class Bookmark
  //-----------------------------------------------------//
}//end class Bookmarks02 definition


Listing 17

Copyright 2006, Richard G. Baldwin.  Reproduction in whole or in part in any
form or medium without express written permission from Richard Baldwin is
prohibited.

About the author

Richard Baldwin is a
college professor (at Austin Community College in Austin, TX) and private
consultant whose primary focus is a combination of Java, C#, and XML. In
addition to the many platform and/or language independent benefits of Java and
C# applications, he believes that a combination of Java, C#, and XML will become
the primary driving force in the delivery of structured information on the Web.

Richard has participated in numerous consulting projects and he
frequently provides onsite training at the high-tech companies located in and
around Austin, Texas.  He is the author of Baldwin’s Programming
Tutorials, which have gained a
worldwide following among experienced and aspiring programmers. He has also
published articles in JavaPro magazine.

In addition to his programming expertise, Richard has many years of
practical experience in Digital Signal Processing (DSP).  His first job after he
earned his Bachelor’s degree was doing DSP in the Seismic Research Department of
Texas Instruments.  (TI is still a world leader in DSP.)  In the following
years, he applied his programming and DSP expertise to other interesting areas
including sonar and underwater acoustics.

Richard holds an MSEE degree from Southern Methodist University and has
many years of experience in the application of computer technology to real-world
problems.

Baldwin@DickBaldwin.com

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Latest Posts

Related Stories