blob: 08f01466a9f7817b9b265df62dcd7f5a22e3ec27 [file] [log] [blame]
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Untitled Document</title>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
</head>
<body>
<h1>SOAP Based AXIS Client for Google Search</h1>
<h2>Section 1 - Basic Operations</h2>
<h3><strong>Introduction</strong></h3>
<p>This is a client that can be used  to do Google searches using the Google
Web API. It allows the user to enter a word as the query parameters in the
given text field of the GUI and in a moment it shows the search results in
the text pane below. The special feature of this client is, when the user
presses the space key after typing a word it starts searching for that word
and displays the results while the user typing the next word. This feature is
made possible by the non blocking  invocation capability of Axis2. </p>
<h3><strong>Getting Started</strong></h3>
<p>Google search operation is done by means of Google Web API. (You can learn
more and create your own account in Google Web API <a
href="http://www.google.com/apis/">here</a>). If you need to build your own
client using this Web API, you should obtain a license key which can be
obtained easily at the Google Web API page.</p>
<p>When you work with this client, you can use the given license key with
this release (This default key is included in a property file inside the jar
file which will be automatically used in the sample when started). However it
is convenient for you to get a license key of your own since the daily limit
per key is 1000 requests and the limit will be reached quickly if a single
license key is shared by many users.</p>
<p>The first and the easiest option is downloading the binary distribution
which includes the compiled samples. Scripts are included for starting the
program in either Windows or Unix.</p>
<p>Second option is to build the samples from source. This has to be done
with Maven. All you have to do is go to Modules/Samples and type maven in the
command prompt. This will compile and will build all the jars required and
copy the necessary scripts as well.</p>
<p>Execute the necessary shell scripts / batch files to start the tool.</p>
<h3><strong>Items in the UI</strong></h3>
<p>The following figure shows the UI of the tool</p>
<p><img border="0" src="sceenShot1.JPG" width="616" height="577"></p>
<p>The key can be set by using the settings menu</p>
<p><img border="0" src="screenShot2.JPG" width="163" height="129"></p>
<p>The Help menu pops up a help window which includes this text</p>
<p><img border="0" src="screenShot3.JPG" width="193" height="112"></p>
<p> </p>
<h3><strong>Operation</strong></h3>
<p>Now you are ready to do a Google search - SOAP style. Just type the word
you want to search in the small text field in the GUI. After you press enter
or space, client starts the searching and you will see the results displayed
few seconds.</p>
<p>You can also set the number of results per page from the set menu. Maximum
is 10 results. You can view more results for the last search by pressing
"More Results" button and can come back to previous page by "Previous Page"
button.</p>
<h2>Section 2 - How the sample works</h2>
<h3><strong>Architecture</strong></h3>
<p>This client is built from five classes.</p>
<ol>
<li>AsynchronousClient:- This class is responsible for sending requests</li>
<li>ClientUtil:- Utility class to build the soap envelope and the
messageContext;</li>
<li>ClientCallbackHandler:- receives the response messages and processes it
to extract the required content.</li>
<li>LinkFollower:- Listens to the hyperlink events and produce new windows
to open relevant URLs.</li>
<li>GUIHandler:- Builds &amp; shows the GUI, Listens  to the events in the
GUI, </li>
</ol>
<p><img src="archi.JPG" width="550" height="384"></p>
<p>The main method is inside the AsynchronousClient class. First it
instantiates a LinkFollower and a GUIHandler . Then the main program calls to
the GUIHandler to display the GUI. After that, the program starts running and
captures and acts according to the events fired by the GUI. The KeyListner
that listens to the text field events fires a search when it detects a space
or Enter key. It would not take long time send a request, but here it's done
using a separate thread because it's important to isolate the GUI from
internal actions. The user never gets interrupted in anyway. So the user can
type the query terms continuously on the text field while the program does
the search for the query terms that are already typed and displays the
results.</p>
<p>The use of the other thread comes when the user click on a hyperlink. Then
the program opens the URL in a new window. This may take a while to load up
depending on the Web site. Hence a separate thread is used , where the 
LinkFollower is made a Thread. </p>
<h3><strong>More on the Code</strong></h3>
<p>Now we have two threads, one is for  sending the soap request without
interrupting the user and other is to open a new windows for clicked URLs.
But there is another important action. That is processing the received
response and displaying the results. That is done in the
ClientCallbackHandler. This is also an important feature of the
InvokeNonBlocking operation of Axis2. It lets you to have an additional
thread in the callbackHandler class. All you have to do is send an object of
that class as a parameter when you send the message. How it is done in the
program is as follows. </p>
<p><code>call.invokeNonBlocking(opdesc, requestContext, new
ClientEchoCallbackHandler());</code></p>
<p>opDesc is a QName which caries the operation name and relevant
namespace.</p>
<p>requestContext is a MessageContext that holds the request soap
envelope.</p>
<p>ClientEchoCallbackHandler is a class that receives the response soap
envelope.</p>
<p>Briefly, client thread is just sending the requests and it is not waiting
for the response. So this client can send any amount of requests sequentially
irrespective of whether the responses are received or not.
ClientEchoCallbackHandler is responsible for receiving response messages and
processing it. It extracts the required details from the message and displays
it in the text pane of the GUI.</p>
<p>The request soap message is built at the ClientUtil class. According to
the Google Web API WSDL file, required namespaces are selected and attached
to the envelope. We don't have to include anything in the header. The name of
the first child element of the body should be operation name and it should be
namespace qualified. We also have to include the binding namespace to this
element. Here it is attached as an attribute to that element,</p>
<p><code>OMElement operation = omFactory.createOMElement("doGoogleSearch",
"urn:GoogleSearch", "ns1");</code></p>
<p><code>opration.addAttribute("SOAP-ENV:encordingStyle",
"http://schemas.xmlsoap.org/soap/encoding/", null);</code></p>
<p>All the child elements of the operation element are carrying required
parameters such as license key, query terms, results per page, etc. (for more
information, download the developer kit from <a
href="http://www.google.com/apis/download.html">http://www.google.com/apis/download.html
</a>, and refer "APIs_Reference.html")</p>
<p>This is a sample request soap enelope,</p>
<p><samp>&lt;soapenv:Envelope
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance/"
xmlns:xsd="http://www.w3.org/1999/XMLSchema"&gt;<br>
&lt;soapenv:Header&gt;&lt;/soapenv:Header&gt;<br>
&lt;soapenv:Body&gt;</samp></p>
<blockquote>
<p><samp>&lt;ns1:doGoogleSearch xmlns:ns1="urn:GoogleSearch"
SOAP-ENV:encordingStyle="http://schemas.xmlsoap.org/soap/encoding/"&gt;<br>
&lt;key xmlns=""
xsi:type="xsd:string"&gt;F0wt5EFQFHKxTs+rl3P+27o6D112BTWd&lt;/key&gt;<br>
&lt;q xmlns="" xsi:type="xsd:string"&gt;axis&lt;/q&gt;<br>
&lt;start xmlns="" xsi:type="xsd:int"&gt;0&lt;/start&gt;<br>
&lt;maxResults xmlns="" xsi:type="xsd:int"&gt;2&lt;/maxResults&gt;<br>
&lt;filter xmlns="" xsi:type="xsd:boolean"&gt;true&lt;/filter&gt;<br>
&lt;restrict xmlns="" xsi:type="xsd:string"&gt;&lt;/restrict&gt;<br>
&lt;safeSearch xmlns=""
xsi:type="xsd:boolean"&gt;false&lt;/safeSearch&gt;<br>
&lt;lr xmlns="" xsi:type="xsd:string"&gt;&lt;/lr&gt;<br>
&lt;ie xmlns="" xsi:type="xsd:string"&gt;latin1&lt;/ie&gt;<br>
&lt;oe xmlns="" xsi:type="xsd:string"&gt;latin1&lt;/oe&gt;<br>
&lt;/ns1:doGoogleSearch&gt;</samp></p>
</blockquote>
<p><samp>&lt;/soapenv:Body&gt;&lt;/soapenv:Envelope&gt;</samp></p>
<p>You can find a sample soap response message from the toolkit that you
download from the Google Web API page.. ClientCallbackHandler processing
response soap and extract elements which have the local names as "snippet"
and "URL". It has to work with AXIOM. You can notice that it uses several
Iterators to go through the children of an OMElement.  the Iterator returns
an object that can be cast into an OMNode. Since you can't call for the
children of an OMNode we have to cast it to an OMElement where a type
checking needs to be done as follows. </p>
<pre>Iterator iterator0 =
operation.getChildren();
while (iterator0.hasNext()) {
OMNode node = (OMNode) iterator0.next();
if (node.getType() == OMNode.ELEMENT_NODE) {
OMElement elem = (OMElement) node;</pre>
<p>A notable fact here is that the text in the snippet element is in the HTML
format. But it cannot be displayed straight away because you have to attach
the HTML header and footer to that. "beginHTML" and "endHTML" static
variables are used for that purpose.</p>
<h3><strong>Extending the Client</strong></h3>
<p>If you observe the WSDL file of the Google API, you can find two more
operations other than "<strong>doGoogleSearch</strong>". Those are
<strong>"doGetCachedPage" </strong> and " <strong>doSpellingSuggestion"
</strong>. You can extend this program to work these operations too. Because
the soap requests and responses are different, it will need separate
ClientUtil classes and ClientCallbackHandler classes to fulfill this task.</p>
<p>  </p>
<hr>
</body>
</html>