This section contains sample applications or use cases written for the SIETS system. Each use case is in a separate section and contains a short description and source code.
This section contains the following use cases:
Use Case in PHP: Searching SIETS Storage and Returning Results in HTML
Use Case in ASP: Searching SIETS Storage and Returning Results in HTML
Use Case in FoxPro I: Updating SIETS Storage from Database Table Data
Use Case in FoxPro II: Searching SIETS Storage and Returning Results to Cursor
This application is implemented in the C programming language.
The application reads files from the file system and imports them to the SIETS storage. The application is receiving file names as command line arguments.
It also detects whether the file is a text file or a binary file by counting whitespaces in them: if a file contains relatively less whitespaces, it is considered to be a binary file, and if a file contains relatively more whitespaces, it is considered to be a text file.
* This application is implemented in the C programming language.
*
* The application reads files from the file system and imports them to the
* SIETS storage via HTTP POST interface using libcurl.
*
* The application receives file names as command line arguments.
*
* It also detects whether the file is a text file or a binary file by counting
* whitespaces in it: if a file contains relatively less whitespaces, it is
* considered to be a binary file, and if a file contains relatively more
* whitespaces, it is considered to be a text file.
*/
/* include standard headers */
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <ctype.h>
/* libcurl */
#include <curl/curl.h>
/* connection parameters */
char *url = "http://195.244.157.173/cgi-bin/siets/api.cgi";
char *storage = "ljur";
char *user = "guest";
char *passwd = "guest";
char *encoding = "US-ASCII";
char *post_fmt = "storage=%s&command=insert&user=%s&password=%s&id=%s&title=%s&rate=%d&text=%s&encoding=%s";
#define REQUIRED_WHITESPACE_FRACTION 0.12
typedef struct { int len, used; char *buf; } curl_reply;
size_t read_reply(void *buffer, size_t size, size_t nmemb, void *userp)
{
int new_len;
curl_reply *r = (curl_reply *) userp;
for (new_len = r->len; new_len < r->used + size * nmemb + 1; new_len *= 2);
if (new_len > r->len) r->buf = realloc(r->buf, new_len);
memcpy(r->buf + r->used, buffer, size * nmemb);
r->len = new_len;
r->used += size * nmemb;
r->buf[r->used] = '\0';
return size * nmemb;
}
int main(int argc, char *argv[])
{
CURL *curl_handle;
char *storage_esc, *user_esc, *passwd_esc, *title_esc, *text_esc, *encoding_esc;
curl_reply reply;
char *err_buf[CURL_ERROR_SIZE];
int i;
if (argc == 1) {
printf("Usage: [-r url] [-s storage] [-u user] [-p password] [-e encoding] files\n");
return 0;
}
/* read options */
for (i = 1; i < argc; i++) {
if (argv[i][0] == '-') {
if (i + 1 >= argc) break; /* no option value */
switch(argv[i][1]) {
case 'r':
url = argv[i+1];
break;
case 's':
storage = argv[i+1];
break;
case 'u':
user = argv[i+1];
break;
case 'p':
passwd = argv[i+1];
break;
case 'e':
encoding = argv[i+1];
break;
default:
printf("Unknown option: %s\n", argv[i]);
break;
}
i++;
}
}
/* initialization */
curl_global_init(CURL_GLOBAL_ALL);
curl_handle = curl_easy_init();
curl_easy_setopt(curl_handle, CURLOPT_URL, url);
curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, read_reply);
curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, &reply);
curl_easy_setopt(curl_handle, CURLOPT_ERRORBUFFER, err_buf);
storage_esc = curl_escape(storage, 0);
user_esc = curl_escape(user, 0);
passwd_esc = curl_escape(passwd, 0);
encoding_esc = curl_escape(encoding, 0);
/* names of files to be imported are passed as arguments
* process each of them */
for (i = 1; i < argc; i++) {
FILE *f;
struct stat st;
int k, spaces;
char *buf, *post_data;
/* check if argument is option */
if (argv[i][0] == '-') {
if (i + 1 >= argc) break; /* no option value */
i++;
continue;
}
printf("Reading file: '%s'\n", argv[i]);
/* open file */
f = fopen(argv[i], "r");
if (!f) {
fprintf(stderr, "Couldn't open file '%s'\n", argv[i]);
continue;
}
/* retrieve file information */
if (fstat(fileno(f), &st) < 0) {
fprintf(stderr, "Filesystem error retrieving info on '%s'\n", argv[i]);
fclose(f);
continue;
}
if (!S_ISREG(st.st_mode)) {
fprintf(stderr, "File '%s' is not regular file\n", argv[i]);
fclose(f);
continue;
}
printf("\tSize: %d bytes\n", st.st_size);
/* read all of it into memory */
/* note: this sample program asumes all of file fits into memory
* so if you need to work with larger files figure out something else */
buf = (char *) malloc(st.st_size + 1);
if (!buf) {
fprintf(stderr, "Memory allocation failed\n");
}
k = fread(buf, 1, st.st_size, f);
fclose(f);
if (k < st.st_size) {
fprintf(stderr, "Error reading file\n");
free(buf);
continue;
}
buf[k] = '\0';
/* see if it is text file
* estimate that by counting white space:
* natural language text in contrary to binary data
* must contain significant portion of whitespace */
spaces = 0;
for (k = 0; k < st.st_size; k++) {
if (isspace(buf[k])) spaces++;
}
if (spaces < st.st_size * REQUIRED_WHITESPACE_FRACTION) {
printf("\tBinary file: ignored\n");
free(buf);
continue;
}
/* execute SIETS insert command through HTTP POST interface */
title_esc = curl_escape(argv[i], 0);
text_esc = curl_escape(buf, k);
post_data = malloc(strlen(storage_esc) + strlen(user_esc) + strlen(passwd_esc) + strlen(post_fmt) + 2 * strlen(title_esc) + 20 + strlen(text_esc) + strlen(encoding_esc));
sprintf(post_data, post_fmt, storage_esc, user_esc, passwd_esc, title_esc, title_esc, 100, text_esc, encoding_esc);
curl_easy_setopt(curl_handle, CURLOPT_POSTFIELDS, post_data);
reply.buf = malloc(reply.len = 1);
reply.used = 0;
if (curl_easy_perform(curl_handle) != CURLE_OK) {
fprintf(stderr, "Error connecting to SIETS server: %s\n", err_buf);
} else if (strstr(reply.buf, "<siets:error>")) { /* simplified error check */
*((char *) strstr(reply.buf, "</text>")) = '\0';
fprintf(stderr, "Error returned from SIETS server: %s\n", strstr(reply.buf, "<text>") + 6);
} else {
*((char *) strstr(reply.buf, "</docid>")) = '\0';
printf("Document inserted with id %s\n", strstr(reply.buf, "<docid>") + 7);
}
/* cleanup */
free(buf);
free(reply.buf);
free(title_esc);
free(text_esc);
free(post_data);
}
/* final cleanup */
free(storage_esc);
free(user_esc);
free(passwd_esc);
free(encoding_esc);
curl_easy_cleanup(curl_handle);
curl_global_cleanup();
return 0;
}
This application is implemented in the Perl programming language.
The application reads files from the file system and imports them to the SIETS storage. The application is receiving file names as command line arguments.
#
# This application is implemented in the Perl programming language.
#
# The application reads files from the file system and imports them to the
# SIETS storage through HTTP POST interface using libcurl.
#
# The application receives file names as command line arguments.
#
# It also detects whether the file is a text file or a binary file by counting
# whitespaces in it: if a file contains relatively less whitespaces, it is
# considered to be a binary file, and if a file contains relatively more
# whitespaces, it is considered to be a text file.
#
use HTTP::Request::Common;
use LWP::UserAgent;
use File::stat;
# connection parameters
$url = "http://127.0.0.1/cgi-bin/siets/api.cgi";
$storage = "test";
$user = "guest";
$passwd = "guest";
$encoding = "US-ASCII";
$REQUIRED_WHITESPACE_FRACTION = 0.12;
if (@ARGV == 0) {
print "Usage: [-r url] [-s storage] [-u user] [-p password] [-e encoding] files\n";
exit;
}
# read options
for ($i = 0; $i < @ARGV; $i++) {
if (substr($ARGV[$i], 0, 1) eq '-') {
if ($i + 1 >= @ARGV) { last; } # no option value
$opt = substr($ARGV[$i], 1, 1);
$val = $ARGV[$i + 1];
if ($opt eq 'r') {
$url = $val;
} elsif ($opt eq 's') {
$storage = $val;
} elsif ($opt eq 'u') {
$user = $val;
} elsif ($opt eq 'p') {
$passwd = $val;
} elsif ($opt eq 'e') {
$encoding = $val;
} else {
print "Unknown option: ", $ARGV[$i], "\n";
}
$i++;
}
}
$ua = LWP::UserAgent->new;
# names of files to be imported are passed as arguments
# process each of them
for ($i = 0; $i < @ARGV; $i++) {
# check if argument is option
if (substr($ARGV[$i], 0, 1) eq '-') {
if ($i + 1 >= @ARGV) { last; } # no option value
$i++;
next;
}
print "Reading file: '", $fn = $ARGV[$i], "'\n";
# open file
if (open(f, $fn)) {
# retrieve file information
if ($st = stat(*f)) {
if (($st->mode & S_IFMT) == S_IFREG) {
print "\tSize: ", $st->size, " bytes\n";
# read all of it into memory
# note: this sample program asumes all of file fits into memory
# so if you need to work with larger files figure out something else
if (sysread(*f, $buf, $st->size) == $st->size) {
# see if it is text file
# estimate that by counting whitespace in it:
# natural language text in contrary to binary data
# must contain significant portion of whitespace
$nspaces = $buf =~ s/(\s)/$1/g;
if ($nspaces >= $st->size * $REQUIRED_WHITESPACE_FRACTION) {
# execute SIETS insert command through HTTP POST interface */
$response = $ua->request(POST $url, [
storage => $storage,
command => 'insert',
user => $user,
password => $passwd,
id => $fn,
title => $fn,
rate => 100,
text => $buf,
encoding => $encoding
]);
if ($response->is_success && $response->content) {
if ($response->content !~ /<siets:error>/) { # simplified error check
$response->content =~ /<docid>([^<]*)<\/docid>/;
print "Document inserted: docid = $1\n";
} else {
$response->content =~ /<code>([^<]*)<\/code>/;
print STDERR "Error returned from SIETS server: $1 - ";
$response->content =~ /<text>([^<]*)<\/text>/;
print STDERR "$1\n";
}
} else {
print STDERR "Error connecting to SIETS server: ", $response->code, ' - ', $response->message, "\n";
}
} else {
print "\tBinary file: ignored\n";
}
} else {
print STDERR "Error reading file\n";
}
} else {
print STDERR "File '$fn' is not a regular file\n";
}
} else {
print STDERR "Filesystem error retrieving info on '$fn'\n";
}
close(f);
} else {
print STDERR "Could not open file '$fn'\n";
}
}
This application is implemented in the PHP programming language.
The application searches the SIETS storage and returns the results in HTML.
<?
//
// This application is implemented in the PHP programming language.
//
// The application searches the SIETS storage using HTTP API and returns the
// results in HTML.
//
$SIETS_SERVER = "http://195.244.157.173/cgi-bin/siets/api.cgi";
$SIETS_STORAGE = "ljur";
$SIETS_USER = "guest";
$SIETS_PASSWD = "guest";
//search query
$query = $_GET["q"];
//current position in results
$curr_position = $_GET["p"];
//data encoding
$encoding = "UTF-8";
//send http header with correct encoding
send_headers($encoding);
//max results on page
$result_on_page = 10;
if (empty($curr_position) || $curr_position < 0) {
$curr_position = 0;
}
//max page from one domain to show
$max_page_from_domain = 2;
$xml_text = file_get_contents($SIETS_SERVER . "?storage=$SIETS_STORAGE&command=search&user=" . urlencode($SIETS_USER) . "&password=" . urlencode($SIETS_PASSWD) . "&query=" . urlencode($query) . "&docs=$result_on_page&offset=$curr_position&from_domain=$max_page_from_domain&encoding=UTF-8");
if ($xml_text == "") {
die("Siets_search error!");
}
//initialize xml to array object
$xml2a = new XMLToArray();
//parse xml
$root_node = $xml2a->parse($xml_text);
//pop root node from array
$siets_reply = array_shift($root_node["_ELEMENTS"]);
//array for storing data from search results
//like total time spent, hits, and so on
$spec_data = array();
// examining SIETS reply elements
foreach ($siets_reply["_ELEMENTS"] as $siets_reply_el) {
if ($siets_reply_el["_NAME"] == "seconds") {
$spec_data[$siets_reply_el["_NAME"]] = $siets_reply_el["_DATA"];
}
// examining SIETS content elements folder
foreach ($siets_reply_el["_ELEMENTS"] as $siets_content) {
$spec_data[$siets_content["_NAME"]] = $siets_content["_DATA"];
$last_domain = '';
foreach($siets_content["_ELEMENTS"] as $results) {
$tit = "";
$others = "";
//parse each document tag from the result set
foreach($results["_ELEMENTS"] as $documents) {
switch ($documents["_NAME"]) {
case "title" :
$tit_array = explode(":_:_:", $documents["_DATA"]);
$tit .= '<b>'.$tit_array[0].'</b>';
break;
case "link" :
$others .= '<br/><font size="-1"> Link: '.$documents["_DATA"].'</font>';
break;
case "domain" :
if ($last_domain == $documents["_DATA"])
$blockquote = TRUE;
else
$blockquote = FALSE;
$others .= '<br/><font size="-1"> Domain: <i>'.$documents["_DATA"].'</i></font>';
$last_domain = $documents["_DATA"];
break;
case "rate" :
break;
case "info" :
break;
case "text" :
if (!empty($documents["_DATA"]))
$others .= '<br/><font size="-1"> Snippet: <i>'.$documents["_DATA"].'</i></font>';
break;
}
}
//tab domains
if ($blockquote)
$output .= '<blockquote>'.$tit.$others.'</blockquote>';
else
$output .= '<br>'.$tit.$others.'<br>';
}
}
}
if ($spec_data["hits"] == 0) {
$output = "Your search <b>$query</b> did not match any documents!";
} else {
//page listing
$from = $curr_position + 1;
$to = $curr_position + strval($spec_data["found"]);
$list_begin_pos=0;
$list_end_pos=$curr_position+($result_on_page*10);
$page_list .= "<font size=\"-1\">";
$p = 1;
if($curr_position > ($result_on_page * 10)){
$list_begin_pos=$curr_position-($result_on_page*10);
$p=intval($list_begin_pos/$result_on_page)+1;
}
if ($curr_position > 0) {
$page_list .= " <a href=\"sietsu.php?p=". ($curr_position - $result_on_page) ."&q=".urlencode(stripslashes($query))."\"><<Previous</a> ";
}
$more_tag = $spec_data["more"];
if ($more_tag[0] == '=') {
$more = substr($more_tag,1);
} else {
$more = substr($more_tag,1) + 1;
}
for ($i = $list_begin_pos; $i - ($curr_position + $more) < $result_on_page && $i < $list_end_pos; $i+= $result_on_page) {
if($i>=1000) break;
if ($i != $curr_position) {
$page_list .= "<a href=\"sietsu.php?p=$i&q=".urlencode(stripslashes($query)).(!empty($dir)?"&dir=$dir":"")."\">$p</a> ";
} else {
$page_list .= "<b>$p </b>";
}
$p++;
}
if (($result_on_page+$curr_position)-($curr_position+$more) < 10 && $curr_position + $result_on_page < 1000) {
$page_list .= " <a href=\"sietsu.php?p=".($curr_position + $result_on_page)."&q=".urlencode(stripslashes($query))."\">Next>></a>";
}
$page_list .= "</font>";
//end of page listing
}
//echo output to client
echo '
<html>
<head>
<style><!--
body,td,p,a{font-family:arial,sans-serif;}
.servkat{color:003399; text-decoration:none}
.homepage{color:003399; text-decoration:none; font-size:10px;}
//-->
</style>
</head>
<body>
<table>
<tr bgcolor=\"#cccc66\">
<td><font size=\"-1\"> Searched for: <b>'.$query.'</b> Results: <b>'.$from.'</b> - <b>'.$to.'</b> from <b>'.$spec_data["hits"].'</b> Search lasted <b>'.$spec_data["seconds"].'</b> seconds </font> </td>
<tr>
</table>
'.$output.'<br>
'.$page_list.'
</body>
</html>';
//#########################################################
class XMLToArray
{
//----------------------------------------------------------------------
// private variables
var $parser;
var $node_stack = array();
//----------------------------------------------------------------------
// PUBLIC
// If a string is passed in, parse it right away.
function XMLToArray($xmlstring="")
{
if ($xmlstring) return($this->parse($xmlstring));
return(true);
}
//----------------------------------------------------------------------
// PUBLIC
// Parse a text string containing valid XML into a multidimensional array
// located at root node.
function parse($xmlstring="")
{
// set up a new XML parser to do all the work for us
$this->parser = xml_parser_create();
xml_set_object($this->parser, $this);
xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, false);
xml_set_element_handler($this->parser, "startElement", "endElement");
xml_set_character_data_handler($this->parser, "characterData");
// Build a Root node and initialize the node_stack
$this->node_stack = array();
$this->startElement(null, "root", array());
// parse the data and free the parser...
xml_parse($this->parser, $xmlstring);
xml_parser_free($this->parser);
// recover the root node from the node stack
$rnode = array_pop($this->node_stack);
// return the root node
return($rnode);
}
//----------------------------------------------------------------------
// PROTECTED
// Start a new Element. This is done by pushing the new element onto the stack
// and reseting its properties.
function startElement($parser, $name, $attrs)
{
// create a new node
$node = array();
$node["_NAME"] = $name;
foreach ($attrs as $key => $value) {
$node[$key] = $value;
}
$node["_DATA"] = "";
$node["_ELEMENTS"] = array();
// add the new node to the end of the node stack
array_push($this->node_stack, $node);
}
//----------------------------------------------------------------------
// PROTECTED
// End an element. This is done by popping the last element from the
// stack and adding it to the previous element on the stack.
function endElement($parser, $name)
{
// pop this element off the node stack
$node = array_pop($this->node_stack);
$node["_DATA"] = trim($node["_DATA"]);
// and add it an element of the last node in the stack...
$lastnode = count($this->node_stack);
array_push($this->node_stack[$lastnode-1]["_ELEMENTS"], $node);
}
//----------------------------------------------------------------------
// PROTECTED
//Collect the data onto the end of the current chars.
function characterData($parser, $data)
{
// add this data to the last node in the stack...
$lastnode = count($this->node_stack);
$this->node_stack[$lastnode-1]["_DATA"] .= $data;
}
//----------------------------------------------------------------------
}
//#########################################################
//## END OF CLASS
//#########################################################
//sends Content-type header to client browser
function send_headers($encoding)
{
Header("Content-type: text/html;charset=$encoding");
}
?>
This application is implemented in the ASP programming language.
The application searches the SIETS storage and returns the results in HTML.
<%
'
' This application is implemented in the VBScript programming language.
'
' The application searches the SIETS storage using HTTP API and returns the
' results in HTML.
'
%>
<html>
<head>
<title>Search</title>
<style>
#results div.header { margin-bottom: 35px; }
#results div.result { padding-left: 15px; }
#results p.title { margin-bottom: 3px; }
#results p.snip { margin: 0px; }
#results p.link { margin-top: 3px; font-size: 0.9em; color: gray; }
#results p.error { color: red; }
#results .pagelist { padding-top: 20px; }
#results .pagelist p { display: inline; }
#results .pagelist ul { margin: 0px; padding: 0px; display: inline; }
#results .pagelist li { display: inline; }
</style>
</head>
<body>
<div id="results">
<%
nDocs = 10 'results per page
nPages = 10 'pages listed
Offset = Int(Request.QueryString("page")) * nDocs 'pages are numbered from 0, displayed from 1
sQuery = Request.QueryString("query")
Set Http = Server.CreateObject("MSXML2.ServerXMLHTTP")
Http.Open "POST", "http://127.0.0.1/cgi-bin/siets/api.cgi", False
Http.Send "storage=test&command=search&docs=" & nDocs & "&offset=" & Offset & "&relevance=yes&query=" & Server.URLEncode(sQuery)
if Http.Status = 200 and not Http.ResponseXML is Nothing then
Set Dom = Http.ResponseXML
Dom.SetProperty "SelectionNamespaces", "xmlns:s='www.siets.net'"
Set Content = Dom.SelectSingleNode("s:reply/s:content")
if not Content is Nothing then
'command executed ok
n = Int(Content.SelectSingleNode("hits").Text)
%><div class="header"><p>Found <b><% if n > 0 then Response.Write n else Response.Write "no"
%></b> document<% if n <> 1 then Response.Write "s"
if not Content.SelectSingleNode("real_query") is Nothing then sRealQuery = Content.SelectSingleNode("real_query").Text else sRealQuery = ""
%> matching "<%= Server.HTMLEncode(sRealQuery)
%>" (<b><%= Dom.SelectSingleNode("s:reply/s:seconds").Text %></b> seconds)</p></div><%= vbCrLf %><%
if n > 0 then
'something has been found
for each Result in Content.SelectNodes("results/document")
%><div class="result"><%
sTitle = Result.SelectSingleNode("title").Text
p = InStr(sTitle, ":_:_:")
if p > 0 then sTitle = Left(sTitle, p - 1)
%><p class="title"><a href="<%= Server.HTMLEncode(Result.SelectSingleNode("id").Text) %>"><%= Server.HTMLEncode(sTitle) %></a></p><%
%><p class="snip"><%= Replace(Result.SelectSingleNode("text").Text, "#", " ") %></p><%
%><p class="link"><%= Server.HTMLEncode(Result.SelectSingleNode("id").Text) %></p><%
%></div><%= vbCrLf %><%
next
'page listing
iFrom = Int(Content.SelectSingleNode("from").Text)
nMore = Int(Mid(Content.SelectSingleNode("more").Text, 2))
nSure = Int((nMore + iFrom + 2 * nDocs - 1) / nDocs)
if iFrom > 0 or nMore > 0 then
%><div class="pagelist"><%= vbCrLf %><p>Result pages:<%= vbCrLf %><%
iPage = Int(iFrom / nDocs)
i = Int((iPage - 1) / (nPages - 2)) * (nPages - 2)
if i < 0 then i = 0
%><ul><%= vbCrLf %><%
sLink = "<a href=""search.asp?query=" & Server.URLEncode(sQuery) & "&page="
if iPage > 0 then
%><li><%= sLink & (iPage - 1) %>"><<< Previous</a></li><%= vbCrLf %><%
end if
j = i
do while j < i + nPages and j < nSure
%><li><%
if j = iPage then
%><b><%= j + 1 %></b><%
else
%><%= sLink & j %>"><%= j + 1 %></a><%
end if
%></li><%= vbCrLf %><%
j = j + 1
loop
if nMore > 0 then
%><li><%= sLink & (iPage + 1) %>">Next >>></a></li><%= vbCrLf %><%
end if
%></ul><%= vbCrLf %></p><%= vbCrLf %></div><%= vbCrLf %><%
end if
end if
else
'error
Set Content = Dom.SelectSingleNode("s:reply/s:error")
%><p class="error">Error <%= Content.SelectSingleNode("code").Text %>: <%= Server.HTMLEncode(Content.SelectSingleNode("text").Text) %></p><%= vbCrLf %><%
end if
else
%><p class="error">Search failed!</p><%= vbCrLf %><%
end if
%> </div>
</body>
</html>
This application is implemented as Java applet.
The application searches the SIETS storage and displays results.
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.util.Random;
public class SietsJApi extends JApplet implements ActionListener {
private JPanel contentPane;
private JPanel Buttons = new JPanel();
private JPanel Results = new JPanel();
private JPanel Properties = new JPanel();
private JPanel MainPan = new JPanel();
private JLabel HostLabel = new JLabel("Host:");
private JLabel StorageLabel = new JLabel("Storage:");
private JLabel QueryLabel = new JLabel("Query:");
private JButton SearchButt = new JButton("Search");
private JButton ClearButt = new JButton("Clear");
private JTextField QueryField = new JTextField(10);
private JTextField HostField = new JTextField("http://",20);
private JTextField StorageField = new JTextField(10);
private JTextArea ResultArea = new JTextArea();
public void init() {
//ContentPane Layout
contentPane = (JPanel) this.getContentPane();
contentPane.setLayout(new BorderLayout());
//Main pane
MainPan.setLayout(new GridBagLayout());
//Properties pane
Properties.setLayout(new GridBagLayout());
Properties.setBorder(BorderFactory.createTitledBorder("Properties"));
//Buttons pane
Buttons.setLayout(new GridLayout(1,2,5,0));
//Results pane
GridLayout gridLayout1 = new GridLayout();
gridLayout1.setVgap(0);
gridLayout1.setHgap(0);
gridLayout1.setColumns(1);
gridLayout1.setRows(10);
Results.setLayout(new BorderLayout());
Results.setBorder(BorderFactory.createTitledBorder("Results"));
//Add Main pane to contentPane
contentPane.add(MainPan,BorderLayout.NORTH);
//Properties pan to Main pane
MainPan.add(Properties,new GridBagConstraints(0, 0, 1, 1, 1.0, 1.0
,GridBagConstraints.NORTH, GridBagConstraints.HORIZONTAL, new Insets(1, 1, 1, 1), 0, 0));
//Add controls to Properties Pane
Properties.add(HostLabel,new GridBagConstraints(0, 1, 1, 1, 1.0, 1.0
,GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(1, 1, 1, 1), 1, 0));
Properties.add(HostField,new GridBagConstraints(1, 1, 1, 1, 1.0, 1.0
,GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(1, 1, 1, 1), 0, 0));
Properties.add(StorageLabel, new GridBagConstraints(2, 1, 1, 1, 1.0, 1.0
,GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(1, 1, 1, 1), 1, 0));
Properties.add(StorageField, new GridBagConstraints(3, 1, 1, 1, 1.0, 1.0
,GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(1, 1, 1, 1), 0, 0));
Properties.add(QueryLabel, new GridBagConstraints(0, 2, 1, 1, 1.0, 1.0
,GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(1, 1, 1, 1), 0, 0));
Properties.add(QueryField, new GridBagConstraints(1, 2, 3, 1, 1.0, 1.0
,GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(1, 1, 1, 1), 0, 0));
//Add Buttons to Main Pan
MainPan.add(Buttons,new GridBagConstraints(0, 1, 1, 1, 1.0, 1.0
,GridBagConstraints.NORTH, GridBagConstraints.NONE, new Insets(1, 1, 1, 1), 20, 0));
Buttons.add(SearchButt,null);
Buttons.add(ClearButt,null);
MainPan.add(Results,new GridBagConstraints(0, 2, 1, 1, 1.0, 1.0
,GridBagConstraints.NORTH, GridBagConstraints.BOTH, new Insets(1, 1, 0, 1), 0,0));
Results.add(ResultArea);
SearchButt.addActionListener(this);
ClearButt.addActionListener(this);
}
//Action listener search and clear buttons
public void actionPerformed(ActionEvent e) {
if (e.getSource() == ClearButt) {
QueryField.setText("");
} else if (e.getSource() == SearchButt) {
String cgiUrl = new String(HostField.getText());
SietsExch sietsReq;
//Create Siets XML query
SietsMess sietsXMLQuery = new SietsMess("search",StorageField.getText(),"guest","guest",QueryField.getText());
//Do data exchange with Siets server
sietsReq = new SietsExch(cgiUrl,sietsXMLQuery.getMess());
sietsReq.doQuery();
String temp = sietsReq.getResponse();
//Parse out XML results
SietsXMLParser sietsXMLResp = new SietsXMLParser(temp.trim());
String[][] resArray = new String[10][];
resArray = sietsXMLResp.parse();
String outp = "";
//Format output
for (int i = 0; i < sietsXMLResp.getResultLength(); i++) {
System.out.println("URL["+i+"]: "+resArray[i][1]+" Title: "+resArray[i][0]);
JLabel u;
outp += "Title: "+resArray[i][0]+"\n";
outp += "Link: "+resArray[i][1]+"\n\n";
}
ResultArea.setText(new String(outp));
}
}
}
import java.util.Calendar;
public class SietsMess {
private String iComm;
private String iData;
private String iUser;
private String iPass;
private String iStorage;
private String message;
/** Creates new SietsMess */
public SietsMess(String command,String storage,String user, String passwd) {
iComm = command;
iData = null;
iUser = user;
iPass = passwd;
iStorage = storage;
message = ComposeMess();
}
public SietsMess(String command,String storage, String user, String passwd,String data) {
iComm = command;
iData = data;
iUser = user;
iPass = passwd;
iStorage = storage;
message = ComposeMess();
}
public String getMess() {
return message;
}
private String ComposeMess() {
String mess = "";
long current = System.currentTimeMillis();
mess = "<siets:request xmlns:siets=\"www.siets.net\">";
mess += "<siets:timestamp>"+Calendar.YEAR+"/"+Calendar.MONTH+"/"+Calendar.DAY_OF_MONTH+" "+Calendar.HOUR+":"+Calendar.MINUTE+":"+Calendar.SECOND+"</siets:timestamp>";
mess += "<siets:command>"+iComm+"</siets:command>";
mess += "<siets:requestid>"+current+"</siets:requestid>";
mess += "<siets:storage>"+iStorage+"</siets:storage>";
mess += "<siets:reply_charset>UTF-8</siets:reply_charset>";
mess += "<siets:user>"+iUser+"</siets:user>";
mess += "<siets:password>"+iPass+"</siets:password>";
mess += "<siets:application>JavaApi</siets:application>";
mess += "<siets:content>";
if (iComm == "search") {
mess += "<query>"+iData+"</query>";
mess += "<docs>10</docs>";
}
mess += "</siets:content>";
mess += "</siets:request>";
return mess;
}
}
import java.io.*;
import java.net.*;
import javax.swing.*;
public class SietsExch {
private String iHost;
private String iData;
private String query;
private String response;
private String iFname;
/** Creates new siets_network */
public SietsExch(String Host, String data) {
iData = data;
URL aURL=null;
try {
aURL = new URL(Host);
} catch (MalformedURLException e) {
System.out.println("Malformed URL");
}
iHost = aURL.getHost();
iFname = aURL.getFile();
}
public int doQuery() {
try {
Socket socket = new Socket(iHost,80);
BufferedWriter wr = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
socket.setSoTimeout(60000); // set 1 minute timeout
String header = "POST "+iFname+" HTTP/1.0\r\n";
header += "Host: "+iHost+"\r\n";
header += "User-Agent: SIETS Client Sample\r\n";
header += "Content-Length: " + iData.getBytes("UTF-8").length+"\r\n\r\n";
wr.write(header);
wr.write(iData);
wr.flush();
response = read_socket(socket);
wr.close();
socket.close();
} catch (UnknownHostException e) {
System.err.println("Exception: Unknown host " + iHost + "!");
System.exit(1);
} catch (IOException e) {
System.err.println("Exception: I/O error during connection!");
System.exit(1);
}
return 1;
}
public String getResponse() {
return response;
}
private String read_socket(Socket fsocket){
String reply="";
try{
BufferedReader rd= new BufferedReader(new InputStreamReader(fsocket.getInputStream()));
StringBuffer tempresp = new StringBuffer();
int ch=0;
while (true){
ch = rd.read();
if (ch < 0)
break;
else
tempresp.append((char)ch);
}
reply = new String(tempresp);
reply = reply.substring(reply.indexOf("\r\n\r\n"));
} catch (InterruptedIOException e){
return "<siets:reply>\n<siets:error>\n<text>"+e.getMessage()+"</text><source>API</source><level>failed</level>\n</siets:error>\n</siets:reply>";
} catch (UnknownHostException e){
return "<siets:reply>\n<siets:error>\n<text>"+e.getMessage()+"</text><source>API</source><level>failed</level>\n</siets:error>\n</siets:reply>";
} catch (IOException e){
return "<siets:reply>\n<siets:error>\n<text>"+e.getMessage()+"</text><source>API</source><level>failed</level>\n</siets:error>\n</siets:reply>";
} catch (NullPointerException e){
return "<siets:reply>\n<siets:error>\n<text>"+e.getMessage()+"</text><source>API</source><level>failed</level>\n</siets:error>\n</siets:reply>";
}
return reply;
}
}
import java.io.*;
import javax.xml.parsers.*;
import org.w3c.dom.*;
import org.xml.sax.*;
public class SietsXMLParser {
private String iData;
private String[][] Resultset = new String[10][2];
private int ResCount = 0;
/** Creates new SietsXMLParser */
public SietsXMLParser(String data) {
iData = data;
}
public String[][] parse() {
try {
DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
Document doc = builder.parse(new InputSource(new StringReader(iData)));
NodeList nodes = doc.getElementsByTagName("document");
ResCount = nodes.getLength();
for (int i = 0; i < nodes.getLength(); i++) {
Element element = (Element) nodes.item(i);
NodeList title = element.getElementsByTagName("title");
Element line = (Element) title.item(0);
Resultset[i][0] = new String(getCharacterDataFromElement(line));
NodeList url = element.getElementsByTagName("id");
line = (Element) url.item(0);
Resultset[i][1] = new String(getCharacterDataFromElement(line));
}
} catch (Exception e) {
e.printStackTrace();
return null;
}
return Resultset;
}
public int getResultLength() {
return ResCount;
}
public String getCharacterDataFromElement(Element e) {
Node child = e.getFirstChild();
if (child instanceof CharacterData) {
CharacterData cd = (CharacterData) child;
return cd.getData();
}
return "?";
}
}
This application is implemented in the Microsoft Visual FoxPro programming language.
The application reads data from a database table and imports them to the SIETS storage.
Note: In this use case, a simple function called XTAGC
for searching XML tags is used instead of the fetch functions.
PROCEDURE siets_update
*!* variables for the SIETS session initiation parameters
LOCAL lcAplication,lcServer,lnPort,lcStorage,lcUsr,lcPasswd;
lcAplication=[siets_update] && application name
lcServer=[111.111.111.111] && IP adress of the server
lnPort=1111 && port number
lcStorage=[mani-dati] && storage name
lcUsr=[my-user] && user name
lcPasswd=[my-passwd] && user password
lcTimeout=60 && timeout
LOCAL lcReplyXml,lcError,lcSession
*!* initialization of SIETS API library
SIETS_DECLARE()
*!* initialization of SIETS parameters
lcSession = SIETS_OPEN_SESSION(lcServer,lnPort,lcStorage,lcUser,lcPasswd,lcTimeout)
*!* if the error ocured, returns
IF lcSession < 0
? [Error opening session]
RETURN .F.
ENDIF
*!* variables to which the indexing data will set
LOCAL lcText, lcTitle, lcLink, lnRateing, lcCharset
*!* encoding of data to be updated
lcCharset=[windows-1257]
*!* opens a table with data that are to be stored to the SIETS storage
USE dati ALIAS dati
SELECT dati
SET ORDER TO id
GO TOP
SCAN
lcLink=ALLTRIM(dati.id) && id
lcTitle=ALLTRIM(dati.title) && title
lcText=ALLTRIM(dati.text) && textual information
*!* rate is calculated by the updating date: the newer the document, the greater the rate
lnRateing=dati.date-DATE(1970,1,1)
*!* replaces the & and characters with the XML entities
lcTitle=STRTRAN(lcTitle,[&],[&]);
lcTitle=STRTRAN(lcTitle,["],["]);
lcText=STRTRAN(lcText,[&],[&]);
lcText=STRTRAN(lcText,["],["]);
*!* sends data to the SIETS storage
lcReplyXml=SIETSXML_UPDATE(lcSession,lcLink,lcTitle,lnRateing,lcText,lcCharset)
*!* parses the error message from the XML reply
lcError=XTAGC([siets_error],lcReplyXml,1);
IF NOT EMPTY(lcError)
IF XTAGC([level],lcError,1)==[failed]
*!* if the error level is failed, the system work can be continued,
*!* because the error refers only to the input data
? [The update was not executed successfully for a document with id: ]+lcLink
? [Error message: ]+XTAGC([text],lcError,1)
ELSE
*!* if the error level is error or fatal, the function returns
? [The update is interrupted for a document with id: ]+lcLink
? [Error message: ]+XTAGC([text],lcError,1)
RETURN .F.
ENDIF
ENDIF
ENDSCAN
*!* when the update is complete, the index command is executed
lcReplyXml=SIETS_INDEX(lcSession)
*!* parses the error message from the XML reply
lcError=XTAGC([siets_error],lcReplyXml,1);
*!* if the error message is not empty, returns
IF NOT EMPTY(lcError)
? [Error:] + lcError
RETURN .F.
ENDIF
SIETS_CLOSE_SESSION(lcSession)
RETURN .T.
*!* additional function XTAGC, which is used in this use case for a easier XML parsing
*!* the XTAGC function returns a substring from a given string, which contains data
*!* between the tags <m.tag>...</m.tag>
PARAMETER m.t, m.s, m.o
PRIVATE m.i,m.j
STORE .F. TO m.XTAGC_ISTAG, m.ISTAG
IF EMPTY(m.s)
RETURN ""
ENDIF
IF EMPTY(m.o)
IF !EMPTY(m.t)
m.i=ATC("<"+m.t+">",m.s)
m.j=ATC("</"+m.t+">",m.s)
ELSE
m.i=ATC(">",m.s)
m.j=ATC("</",m.s)
ENDIF
ELSE
IF !EMPTY(m.t)
m.i=ATC("<"+m.t+">",m.s,m.o)
m.j=ATC("</"+m.t+">",m.s,m.o)
ELSE
m.i=ATC(">",m.s)
m.j=ATC("</",m.s)
ENDIF
ENDIF
IF m.i=0 OR m.j=0
RETURN ""
ENDIF
STORE .T. TO m.XTAGC_ISTAG, m.ISTAG
m.i=m.i+LEN(m.t)+IIF(!EMPTY(m.t),2,1)
IF SUBSTR(m.s,m.i,2)==CHR(13)+CHR(10)
m.i=m.i+2
ENDIF
IF SUBSTR(m.s,m.j-2,2)==CHR(13)+CHR(10)
m.j=m.j-2
ENDIF
IF m.j>m.i
RETURN SUBSTR(m.s,m.i,m.j-m.i)
ENDIF
RETURN ""
This application is implemented in the Microsoft Visual FoxPro programming language.
The application searches the SIETS storage and returns the results to the cursor.
Note: In this use case, a simple function called XTAGC
for searching XML tags is used instead of the fetch functions.
PROCEDURE siets_search
*!* parameters:
*!* tcCursorName name of the cursor to which the search results will be returned
*!* tnMaxDoc number of results to be returned
*!* tnOffset intend from the beginning of the result set
*!* tcOrder mechanism by which results are to be sorted: by relevance (.T.), or rate (.F.)
*!* tcErrorMsg returns error message
*!* tcQuery search query
LPARAMETERS tcCursorName, tnMaxDoc, tnOffset, tlOrder, tcErrorMsg, tcQuery
*!* variables for the SIETS session initiation parameters
LOCAL lcAplication,lcServer,lnPort,lcStorage,lcUsr,lcPasswd;
lcAplication=[siets_update] && application name
lcServer=[111.111.111.111] && IP address of the server
lnPort=1111 && port number
lcStorage=[mani-dati] && storage name
lcUsr=[my-user] && user name
lcPasswd=[my-passwd] && user password
lcTimeout=60 && timeout
LOCAL lcReplyXml,lcError,lcSession
*!* initialization of SIETS API library
SIETS_DECLARE()
*!* initialization of SIETS parameters
lcSession = SIETS_OPEN_SESSION(lcServer,lnPort,lcStorage,lcUser,lcPasswd,lcTimeout)
*!* if the error ocured, returns
IF lcSession < 0
? [Error opening session]
RETURN .F.
ENDIF
*!* creation of the cursor where to return the search results
CREATE CURSOR (tcCursorName) (link C(10) , Title C(254), date D, Highlight M)
LOCAL lcReplyXml,lcError,lnFound,lcCaseSensitive,lcRelevance,lcFromDomain
lcRelevance=.F.
lcFromDomain=0
lcCaseSensitive=.F.
*!* performs FTS with the given search parameters
lcReplyXml=SIETSXML_SEARCH(lcSession,tcQuery,tnMaxTrans,tnOffset,lcRelevance,lcFromDomain,lcCaseSensitive,[windows-1257]) && Perform search
*!* parses an error message from the XML reply
lcError=XTAGC([siets_error],lcReplyXml,1)
*!* if the error message is not empty, returns
IF NOT EMPTY(lcError)
tcErrorMsg=XTAGC([text],lcError,1) && returns the error message
RETURN .F.
ENDIF
*!* parses the number of results from the XML reply
lnFound=VAL(XTAGC("found",lcReplyXml,1))
LOCAL lnI,lclink,lnRate,lcTitle,lcText,ldDate
*!* parses the search results from the XML reply and saves them in the cursor
FOR lnI=1 TO lnFound STEP 1
lcLink=XTAGC([link],lcReplyXml,lnI) && id
lnRate=VAL(XTAGC([rate],lcReplyXml,lnI)) && rate
lcTitle=XTAGC([title],lcReplyXml,lnI) && title
lcText=XTAGC([text],lcReplyXml,lnI) && snippet of text with search terms
ldDate=DATE(1970,1,1)+lnRate && rate converted back to the date format
*!* saving data to the cursot
INSERT INTO (tcCursorName) (link,Title,date,Highlight) VALUES (lcLink,lcTitle,ldDate,lcText)
ENDFOR
SIETS_CLOSE_SESSION(lcSession)
RETURN .T.
*!* additional function XTAGC, which is used in this use case for a easier XML parsing
*!* the XTAGC function returns a substring from a given string, which contains data
*!* between the tags <m.tag>...</m.tag>
PARAMETER m.t, m.s, m.o
PRIVATE m.i,m.j
STORE .F. TO m.XTAGC_ISTAG, m.ISTAG
IF EMPTY(m.s)
RETURN ""
ENDIF
IF EMPTY(m.o)
IF !EMPTY(m.t)
m.i=ATC("<"+m.t+">",m.s)
m.j=ATC("</"+m.t+">",m.s)
ELSE
m.i=ATC(">",m.s)
m.j=ATC("</",m.s)
ENDIF
ELSE
IF !EMPTY(m.t)
m.i=ATC("<"+m.t+">",m.s,m.o)
m.j=ATC("</"+m.t+">",m.s,m.o)
ELSE
m.i=ATC(">",m.s)
m.j=ATC("</",m.s)
ENDIF
ENDIF
IF m.i=0 OR m.j=0
RETURN ""
ENDIF
STORE .T. TO m.XTAGC_ISTAG, m.ISTAG
m.i=m.i+LEN(m.t)+IIF(!EMPTY(m.t),2,1)
IF SUBSTR(m.s,m.i,2)==CHR(13)+CHR(10)
m.i=m.i+2
ENDIF
IF SUBSTR(m.s,m.j-2,2)==CHR(13)+CHR(10)
m.j=m.j-2
ENDIF
IF m.j>m.i
RETURN SUBSTR(m.s,m.i,m.j-m.i)
ENDIF
RETURN ""