Skip to main content

By clicking Submit, you agree to the developerWorks terms of use.

The first time you sign into developerWorks, a profile is created for you. Select information in your developerWorks profile is displayed to the public, but you may edit the information at any time. Your first name, last name (unless you choose to hide them), and display name will accompany the content that you post.

All information submitted is secure.

  • Close [x]

The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerworks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

By clicking Submit, you agree to the developerWorks terms of use.

All information submitted is secure.

  • Close [x]

Integrating Google’s Web API service in Domino applications

Sui-Man Chan, Application Developer, Federal Reserve Bank of New York
Sui-Man Chan has worked in the transportation and banking industry since the early 1990's and has been involved in various stages of application and systems development. Sui comes from a background of mainframe, client-server, and Web-based platform systems. She has been involved with IBM Lotus Domino application development since Release 3 in 1995.

Summary:  Add Google Web search functionality to your Domino applications with Google's Web API service. This article shows how to implement that search functionality in an application using a simple agent. Download the code samples and get googling!

Date:  12 Jan 2004
Level:  Intermediate
Also available in:   Japanese

Activity:  3335 views
Comments:  

With Google’s current and ever expanding index of over 3 billion Web pages, it is easy to understand why it is one of the best tools to conduct industrial-strength research on the Internet. In addition to its quantity of Web pages, the quality of the search results is high due to its proprietary search algorithm that is based on relevancy and popularity. Recent reports indicate that Google answers 200 million search requests daily (an average of 2,300 per second!) in 88 different languages. And according to SearchEngineWatch.com, Google handles 75 percent of all Web-based search queries.

Obviously, many Web users are familiar with Google and its search features. What may not be as well known is the fact that you can incorporate Google's search functionality into your own Domino applications using Google's Web API service. (You can download this API free as we explain in the next section.) This article describes how to add Google's search functionality to a Domino application. We briefly introduce the Google APIs and how they work. Then we examine a sample application that integrates Google search functionality with a Domino application. We conclude by offering some ideas how you can expand and customize our simple example. (All examples shown in this article are contained in a Domino database you can download from the Sandbox.)

This article assumes that you're an experienced Domino developer familiar with writing Domino agents. And although advanced Java experience is not required to understand our example, a basic knowledge of Java is highly recommended.

The Google APIs

To use Google’s APIs, download the Google Web APIs developer’s kit (googleapi.zip) from Google's Web APIs download page and create a free Google account for a license key. The key allows you a maximum of 1,000 searches daily. (You must include this license key in your query when making the search request. You do this programmatically, so users don't have to type in the code each time they perform a query.) The developer’s kit comes with documentation and examples that give you a basic understanding of how Google’s automated searches work.

After you download googleapi.zip, unpack it to the c:\googleapi directory. You can then quickly invoke the Web APIs by typing the following command at the MS-DOS prompt: java -cp googleapi.jar com.google.soap.search.GoogleAPIDemo <key> search Lotus Domino > result.html where < key > is your registration key, "Lotus Domino" is the item you want to search for, and result.html is the name of the file into which we want the search results to be written. For instance, the following example:


Listing 1. Search results
…
Start Index = 1 
End Index = 10 
Estimated Total Results Number = 663000 
…  

shows the first 10 items in the display results from an estimated 663,000 items.

However, if you try the same query on the Google Web site, you may get a different result. For example, the same query for "Lotus Domino" at Google results in an estimated 596,000 items. (The Google API Support team has confirmed that both the Web APIs and the Google site itself use the same search engine and index pages, but slight differences in results may be caused by the many data centers that Google operates.) A quick look at GoogleAPIDemo.java in the googleapi directory:


Listing 2. Snippet from GoogleAPIDemo.java
 …
GoogleSearch s = new GoogleSearch();
…
GoogleSearchResult r = s.doSearch();
…  

reveals that the doSearch() method invokes the Google search, after the license key and the search query string attributes are set.

Before we move on to our example, let's take a quick look at several methods in Google’s Web API that you will use:

  • setKey() sets the user license key.
  • setQueryString() sets the query string.
  • doSearch() invokes the Google search.
  • toString() returns a formatted representation of a Google search result.
  • getResultElements() returns an array of result elements.
  • getSnippet() returns a snippet that shows the query in context on the URL where it appears.
  • getSummary() returns the ODP summary if this document is contained in the ODP directory.
  • getTitle() returns the title of the search result, formatted as HTML.
  • getURL() returns the absolute URL of the search result.

In addition, the following set of methods can improve the sophistication of your search application:

  • setStartResult() sets the index of the first result to be returned. For instance, if there are 500 results, you may want to start at 100.
  • setMaxResults() sets the maximum number of results to be returned per query. The maximum value per query is 10. If you perform a query that doesn't have many matches, the actual number of results you get may be smaller than what you request.
  • setFilter() enables or disables the "related-queries" filter. This filter eliminates results that are very similar.

The simpleSearch agent

Let us begin our example by creating a Notes agent called simpleSearch in a new database named GoogleSe.nsf. You can download this database from the Sandbox. This database contains the simpleSearch agent, as well as the goSearch agent and the forms and view discussed later in this article. We built this application on Windows 2000, but as a Java application it can run on any platform. No special proxy setting is required to run the Google APIs from Lotus Domino. When the APIs are invoked, they use whatever configuration Domino has.

First, copy the following lines of code from the file GoogleAPIDemo.java in the developer’s kit (note that clientKey is initialized by the license key sent to you after you register with Google):


Listing 3. simpleAgent code
...		
	String clientKey = "4B0KufpQFHJxhAxzua0tR11ElLNrHRJ6";
    	String directive = "search";
    	String directiveArg = "Lotus Domino";

    	// Report the arguments received
    	System.out.println("Parameters:"); 
	System.out.println("Client key = " + clientKey);
	System.out.println("Directive  = " + directive);
	System.out.println("Args       = " + directiveArg);

    	// Create a Google Search object, set our authorization key
    	GoogleSearch s = new GoogleSearch();
    	s.setKey(clientKey);

	// Depending on user input, do search or cache query, 
	 then print out result
 	try {
	      if (directive.equalsIgnoreCase("search")) {
		s.setQueryString(directiveArg);
    		pw.println("about to begin doSearch...");
    		GoogleSearchResult r = s.doSearch();
		pw.println("doSearch ok");
        		System.out.println("Google Search Results:");
		System.out.println("======================");
		System.out.println(r.toString());
	...  

In Domino Designer, create the simpleSearch agent and paste in the preceding code. Then execute the agent. (The search string in this example is initialized to "Lotus Domino.") To view the results of this query, open the Java Debug Console after simpleSearch finishes running. You should see results similar to the following:


Figure 1. simpleSearch results
simpleSearch results

Our simpleSearch agent provides a quick way to view your search results, showing the first 10 of the estimated 720,000 items found. For example, the first item contains the following:


Listing 4. Example search result
 URL  = "http://www.lotus.com/" 
Title = "IBM Lotus software" 
Snippet = " ... and societal demands Domino Web Access demo upgraded to 6.5 
All you've come to expect -- Lotusphere 2004 Basex Excellence Award goes to 
IBM Lotus Workplace ...  "
Directory Category = {SE="", FVN="Top/Computers/Software/Operating_Systems/
 Mainframe/IBM/Software"}
Directory Title = "Lotus Software" 
Summary = "IBM subsidiary best known for multi-platform Notes and Domino 
 messaging groupware  supports z/OS-based..." 
Cached Size = "20k" 
Related information present = true 
Host Name = ""


If you run the agent locally, make sure googleapi.jar is in the Notes program directory and is assigned to JavaUserClasses in your local Notes.ini file. (JavaUserClasses has a limitation of 256 characters, so if adding googleapi.jar to it exceeds this limit, it won't be recognized by Domino.)


Adding a Google-like interface

The search results returned by simpleSearch are informative, but are obviously unsophisticated in terms of presentation. However, you can greatly improve the usability of these results by presenting them in a format similar to the one used by Google. To do this, we create a new agent called goSearch, using the code in simpleSearch as the starting point. We also add two forms, Search and Result, to the GoogleSe.nsf database. (The complete GoogleSe.nsf database, containing the forms as well as the goSearch and simpleSearch agents, is available for download from the Sandbox.)

Search and Results forms

First, add a query form (which we call Search) to your GoogleSe.nsf database. This allows users to enter and save their query strings:


Figure 2. Search form
Search form

Then add an output form named Result to display the results of the queries:


Figure 3. Results form
Results form

The goSearch agent

Now let's build an agent that offers more sophisticated functionality than the simpleSearch agent, including automation to process a list of queries and a more "Google-like" look and feel. To begin, copy the code in simpleSearch and paste it into goSearch. Then add the following code to have the results title appear in the same text color used by Google and to render HTML in rich text fields in Notes:


Listing 5. Code for displaying results in Google format
... 
style.setColor(RichTextStyle.COLOR_BLUE); 
                                      
//renders HTML into rich text fields                                         
String str = re[a].getTitle(); 
while (str.length() > 0 ) { 
        int i = str.indexOf("<b>"); 
        int j = str.indexOf("<b>"); 
        style.setBold(RichTextStyle.NO); 
        int k = i; 
        int len = 3; 
        if (j<i || (j>i && i==-1)) { 
                style.setBold(RichTextStyle.YES); 
              &n! bsp; k=j; 
                len=4; 
        } 
        //no more <b> or </b> left on str 
        if (i==-1 && j==-1) { 
                title.appendStyle(style); 
                title.appendText(str);                 
                break; 
        } 
  !       String sstr = str.substring(0,k); 
        if (sstr.length()==0) { 
                sstr=""; 
        } 
        title.appendStyle(style); 
        title.appendText(sstr);                 
         str = str.substring(k+len); 
 } 
...  


Next, add the following code to the goSearch agent. This snippet incorporates the query results into the Result document:


Listing 6. Code for incorporating query results into Result documents
 …
Document ndoc = db.createDocument();
ndoc.appendItemValue("Form", "Result");
RichTextItem title = ndoc.createRichTextItem("Title");
...
RichTextItem snippet = ndoc.createRichTextItem("Snippet");
...
ndoc.appendItemValue("URL", re[a].getURL());
...
ndoc.save();
…  

Finally, add the following to execute all query strings saved as Search documents and generate corresponding results as Result documents.


Listing 7. Code to execute queries and generate Result documents
... 
View view = db.getView("AllSearches"); 
Document doc = view.getFirstDocument(); 
while (doc != null) { 
... 
        int a=r.getStartIndex() - 1; 
        int b=r.getEndIndex()  - 1; 
        //reiterate the result set 
        while (a<=b) { 
                ... 
&! nbsp;               a++; 
        } 
doc = view.getNextDocument(doc); 
} 
...   

The preceding example allows for batch queries in Google’s search engine and batch results saved for later analysis. Because results are saved, it also lets you analyze trends by monitoring the frequency with which certain topics are searched. You can do this by sorting and displaying Result documents by query string and date, as shown in the following AllResultsByTitleDate view:


Figure 4. AllResultsByTitleDate view
AllResultsByTitleDate view

The Title field is a rich text field. Therefore, you need to create the new text field TitleText to store the unformatted text value in Result documents, so you can use it as a column value in the preceding view: ndoc.appendItemValue("TitleText", title.getFormattedText(false, 0, 0));


Other ideas to consider

The goSearch agent can be scheduled to run at an off-peak hour to reduce traffic and improve efficiency. Another idea to improve the goSearch agent is to call the parser whenever an HTML formatted string is encountered:


Listing 8. Code to call parser in goSearch
... 
class Parser { 
                        
        //renderHTML takes 5 arguments: HTML string, 
         rich text style, rich text item 
         reference, delimiter 1 and 2 
    void renderHTML(String html, RichTextStyle style, RichTextItem rtitem, 
     String delim1, String delim2) {                         
                try { 
                        System.out.println("html:" + html); 
                                                                        
                              style.setColor(RichTextStyle.COLOR_BLUE); 
                                      
                        //renders HTML into rich text fields                                         
                        while (html.length() > 0 ) { 
                                int i = html.indexOf(delim1); 
                                int j = html.indexOf(delim2); 
                                style.setBold(RichTextStyle.NO); 
                                int k = i; 
                                int len = 3; 
                                if (j<i || (>i && i==-1)) { 
                                        style.setBold(RichTextStyle.YES! ); 
                                        k=j; 
                                        len=4; 
                                } 
                                //no more <b> or </b> left on str 
                                if (i==-1 && j==-1) { 
                                        rtitem.appendStyle(style); 
                                        rtitem.appendText(html);                 
                                        break; 
                                } 
                                String sstr = html.substring(0,k); 
                                if (sstr.length()==0) { 
                                        sstr=""; 
                                } 
                                rtitem.appendStyle(style); 
                                rtitem.appendText(sstr);                 
                                 html = html.substring(k+len); 

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

This results in a more compact agent class.

You can further extend the concept of rendering HTML input strings into Notes rich text fields by expanding the set of HTML tags that this parser can handle (for example, to <h1>…</h1> or <p>) through the use of the delim1 and delim2 parameters.


Summary

You can harness the power of Google in Domino to query high volumes of search strings. Their results are stored as documents and, over a period of time, can be used in trend analysis. In addition, you can monitor when new information for specific topics is available as Web pages. Equally important, your Domino applications can now offer Google search functionality to your users. This provides search features with which your users are likely to be very familiar, so they should find these features easy to use. This functionality is also known to be highly stable and reliable. You should consider using Google's API in any Domino application in which fast, large-volume Web searches are a requirement.


Resources

About the author

Sui-Man Chan has worked in the transportation and banking industry since the early 1990's and has been involved in various stages of application and systems development. Sui comes from a background of mainframe, client-server, and Web-based platform systems. She has been involved with IBM Lotus Domino application development since Release 3 in 1995.

Report abuse help

Report abuse

Thank you. This entry has been flagged for moderator attention.


Report abuse help

Report abuse

Report abuse submission failed. Please try again later.


developerWorks: Sign in


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Select information in your developerWorks profile is displayed to the public, but you may edit the information at any time. Your first name, last name (unless you choose to hide them), and display name will accompany the content that you post.

Choose your display name

The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


Rate this article

Comments

Help: Update or add to My dW interests

What's this?

This little timesaver lets you update your My developerWorks profile with just one click! The general subject of this content (AIX and UNIX, Information Management, Lotus, Rational, Tivoli, WebSphere, Java, Linux, Open source, SOA and Web services, Web development, or XML) will be added to the interests section of your profile, if it's not there already. You only need to be logged in to My developerWorks.

And what's the point of adding your interests to your profile? That's how you find other users with the same interests as yours, and see what they're reading and contributing to the community. Your interests also help us recommend relevant developerWorks content to you.

View your My developerWorks profile

Return from help

Help: Remove from My dW interests

What's this?

Removing this interest does not alter your profile, but rather removes this piece of content from a list of all content for which you've indicated interest. In a future enhancement to My developerWorks, you'll be able to see a record of that content.

View your My developerWorks profile

Return from help

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Lotus
ArticleID=87800
ArticleTitle=Integrating Google’s Web API service in Domino applications
publish-date=01122004
author1-email=
author1-email-cc=

Tags

Help
Use the search field to find all types of content in My developerWorks with that tag.

Use the slider bar to see more or fewer tags.

For articles in technology zones (such as Java technology, Linux, Open source, XML), Popular tags shows the top tags for all technology zones. For articles in product zones (such as Info Mgmt, Rational, WebSphere), Popular tags shows the top tags for just that product zone.

For articles in technology zones (such as Java technology, Linux, Open source, XML), My tags shows your tags for all technology zones. For articles in product zones (such as Info Mgmt, Rational, WebSphere), My tags shows your tags for just that product zone.

Use the search field to find all types of content in My developerWorks with that tag. Popular tags shows the top tags for this particular content zone (for example, Java technology, Linux, WebSphere). My tags shows your tags for this particular content zone (for example, Java technology, Linux, WebSphere).

Special offers