This section lists the Java code used to build the example Web application, as shown in the TextSearchApp.jsp
file.
<%@page language="java" pageEncoding="utf-8" contentType="text/html; charset=utf-8" %> <%@ page import="java.sql.*, java.util.*, java.net.*, oracle.jdbc.*, oracle.sql.*, oracle.jsp.dbutil.*" %> <% // Change these details to suit your database and user details String connStr = "jdbc:oracle:thin:@//servername:1521/pdb1"; String dbUser = "scott"; String dbPass = "tiger"; // The table we're running queries against is called SEARCH_TABLE. // It must have columns: // tk number primary key, (primary key is important for document services) // title varchar2(2000), // text clob // There must be a CONTEXT index called IDX_SEARCH_TABLE on the text column request.setCharacterEncoding("UTF-8"); java.util.Properties info=new java.util.Properties(); Connection conn = null; ResultSet rset = null; OracleCallableStatement callStmt = null; Statement stmt = null; String userQuery = null; String myQuery = null; String action = null; String theTk = null; URLEncoder myEncoder; int count=0; int loopNum=0; int startNum=0; userQuery = request.getParameter("query"); action = request.getParameter("action"); theTk = request.getParameter("tk"); if (action == null) action = ""; // Connect to database try { DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver() ); info.put ("user", dbUser); info.put ("password", dbPass); conn = DriverManager.getConnection(connStr,info); } catch (SQLException e) { %> <b>Error: </b> <%= e %><p> <% } if ( action.equals("doHTML") ) { // Directly display the text of the document try { // not attempting to share the output table for this example, we'll truncate it each time conn.createStatement().execute("truncate table OUTPUT_TABLE"); String sql = "{ call ctx_doc.filter( index_name=>'IDX_SEARCH_TABLE', textkey=> '" + theTk + "', restab=>'OUTPUT_TABLE', plaintext=>false ) }"; PreparedStatement s = conn.prepareCall( sql ); s.execute(); sql = "select document from output_table where rownum = 1"; stmt = conn.createStatement(); rset = stmt.executeQuery(sql); rset.next(); oracle.sql.CLOB res = (oracle.sql.CLOB) rset.getClob(1); // should fetch from clob piecewise, but to keep it simple we'll just fetch 32K to a string String txt = res.getSubString(1, 32767); out.println(txt); } catch (SQLException e) { %> <b>Error: </b> <%= e %><p> <% } } else if ( action.equals("doHighlight") ) { // Display the text of the document with highlighting from the "markup" function try { // not attempting to share the output table for this example, we'll truncate it each time conn.createStatement().execute("truncate table OUTPUT_TABLE"); String sql = "{ call ctx_doc.markup( index_name=>'IDX_SEARCH_TABLE', textkey=> '" + theTk + "', text_query => '" + userQuery + "', restab=>'OUTPUT_TABLE', plaintext=>false, starttag => '<i><font color=\"red\">', endtag => '</font></i>' ) }"; PreparedStatement s = conn.prepareCall( sql ); s.execute(); sql = "select document from output_table where rownum = 1"; stmt = conn.createStatement(); rset = stmt.executeQuery(sql); rset.next(); oracle.sql.CLOB res = (oracle.sql.CLOB) rset.getClob(1); // should fetch from clob piecewise, but to keep it simple we'll just fetch 32K to a string String txt = res.getSubString(1, 32767); out.println(txt); } catch (SQLException e) { %> <b>Error: </b> <%= e %><p> <% } } else if ( action.equals("doThemes") ) { // Display the text of the document with highlighting from the "markup" function try { // not attempting to share the output table for this example, we'll truncate it each time conn.createStatement().execute("truncate table THEME_TABLE"); String sql = "{ call ctx_doc.themes( index_name=>'IDX_SEARCH_TABLE', textkey=> '" + theTk + "', restab=>'THEME_TABLE') }"; PreparedStatement s = conn.prepareCall( sql ); s.execute(); sql = "select * from ( select theme, weight from theme_table order by weight desc ) where rownum <= 20"; stmt = conn.createStatement(); rset = stmt.executeQuery(sql); int weight = 0; String theme = ""; %> <h2>The top 20 themes of the document</h2> <table BORDER=1 CELLSPACING=0 CELLPADDING=0" <tr bgcolor="#CCCC99"> <th><font face="arial" color="#336699">Theme</th> <th><font face="arial" color="#336699">Weight</th> </tr> <% while ( rset.next() ) { theme = rset.getString(1); weight = (int)rset.getInt(2); %> <tr bgcolor="ffffe0"> <td align="center"><font face="arial"><b> <%= theme %> </b></font></td> <td align="center"><font face="arial"> <%= weight %></font></td> </tr> <% } %> </table> <% } catch (SQLException e) { %> <b>Error: </b> <%= e %><p> <% } } else if ( action.equals("doGists") ) { // Display the text of the document with highlighting from the "markup" function try { // not attempting to share the output table for this example, we'll truncate it each time conn.createStatement().execute("truncate table GIST_TABLE"); String sql = "{ call ctx_doc.gist( index_name=>'IDX_SEARCH_TABLE', textkey=> '" + theTk + "', restab=>'GIST_TABLE', query_id=>1) }"; PreparedStatement s = conn.prepareCall( sql ); s.execute(); sql = "select pov, gist from gist_table where pov = 'GENERIC' and query_id = 1"; stmt = conn.createStatement(); rset = stmt.executeQuery(sql); String pov = ""; String gist = ""; while ( rset.next() ) { pov = rset.getString(1); oracle.sql.CLOB gistClob = (oracle.sql.CLOB) rset.getClob(2); out.println("<h3>Document Gist for Point of View: " + pov + "</h3>"); gist = gistClob.getSubString(1, 32767); out.println(gist); } %> </table> <% } catch (SQLException e) { %> <b>Error: </b> <%= e %><p> <% } } if ( (action.equals("")) && ( (userQuery == null) || (userQuery.length() == 0) ) ) { %> <html> <title>Text Search</title> <body> <table width="100%"> <tr bgcolor="#336699"> <td><font face="arial" align="left" color="#CCCC99" size="+2">Text Search</td> </tr> </table> <center> <form method = post> Search for: <input type="text" name="query" size = "30"> <input type="submit" value="Search"> </form> </center> </body> </html> <% } else if (action.equals("") ) { %> <html> <title>Text Search Result Page</title> <body text="#000000" bgcolor="#FFFFFF" link="#663300" vlink="#996633" alink="#ff6600"> <table width="100%"> <tr bgcolor="#336699"> <td><font face="arial" align="left" color="#CCCC99" size=+2>Text Search</td> </tr> </table> <center> <form method = post action="TextSearchApp.jsp"> Search for: <input type=text name="query" value="<%= userQuery %>" size = 30> <input type=submit value="Search"> </form> </center> <% myQuery = URLEncoder.encode(userQuery); try { stmt = conn.createStatement(); String numStr = request.getParameter("sn"); if(numStr!=null) startNum=Integer.parseInt(numStr); String theQuery = translate(userQuery); callStmt =(OracleCallableStatement)conn.prepareCall("begin "+ "?:=ctx_query.count_hits(index_name=>'IDX_SEARCH_TABLE', "+ "text_query=>?"+ "); " + "end; "); callStmt.setString(2,theQuery); callStmt.registerOutParameter(1, OracleTypes.NUMBER); callStmt.execute(); count=((OracleCallableStatement)callStmt).getNUMBER(1).intValue(); if(count>=(startNum+20)){ %> <font color="#336699" FACE="Arial" SIZE=+1>Results <%=startNum+1%> - <%=startNum+20%> of <%=count%> matches <% } else if(count>0){ %> <font color="#336699" FACE="Arial" SIZE=+1>Results <%=startNum+1%> - <%=count%> of <%=count%> matches <% } else { %> <font color="#336699" FACE="Arial" SIZE=+1>No match found <% } %> <table width="100%"> <TR ALIGN="RIGHT"> <% if((startNum>0)&(count<=startNum+20)) { %> <TD ALIGN="RIGHT"> <a href="TextSearchApp.jsp?sn=<%=startNum-20 %>&query= <%=myQuery %>">previous20</a> </TD> <% } else if((count>startNum+20)&(startNum==0)) { %> <TD ALIGN="RIGHT"> <a href="TextSearchApp.jsp?sn=<%=startNum+20 %>&query=<%=myQuery %>">next20</a> </TD> <% } else if((count>startNum+20)&(startNum>0)) { %> <TD ALIGN="RIGHT"> <a href="TextSearchApp.jsp?sn=<%=startNum-20 %>&query= <%=myQuery %>">previous20</a> <a href="TextSearchApp.jsp?sn=<%=startNum+20 %>&query= <%=myQuery %>">next20</a> </TD> <% } %> </TR> </table> <% String ctxQuery = " select /*+ FIRST_ROWS */ " + " tk, TITLE, score(1) scr, " + " ctx_doc.snippet ('IDX_SEARCH_TABLE', tk, '" + theQuery + "') " + " from search_table " + " where contains(TEXT, '"+theQuery+"',1 ) > 0 " + " order by score(1) desc"; rset = stmt.executeQuery(ctxQuery); String tk = null; String[] colToDisplay = new String[1]; int myScore = 0; String snippet = ""; int items = 0; while (rset.next()&&items< 20) { if(loopNum>=startNum) { tk = rset.getString(1); colToDisplay[0] = rset.getString(2); myScore = (int)rset.getInt(3); snippet = rset.getString(4); items++; if (items == 1) { %> <center> <table BORDER=1 CELLSPACING=0 CELLPADDING=0 width="100%" <tr bgcolor="#CCCC99"> <th><font face="arial" color="#336699">Score</th> <th><font face="arial" color="#336699">TITLE</th> <th><font face="arial" color="#336699">Snippet</th> <th> <font face="arial" color="#336699">Document Services</th> </tr> <% } %> <tr bgcolor="#FFFFE0"> <td ALIGN="CENTER"> <%= myScore %>%</td> <td> <%= colToDisplay[0] %> </td> <td> <%= snippet %> </td> <td> <a href="TextSearchApp.jsp?action=doHTML&tk=<%= tk %>">HTML</a> <a href="TextSearchApp.jsp?action=doHighlight&tk=<%= tk %>&query=<%= theQuery %>">Highlight</a> <a href="TextSearchApp.jsp?action=doThemes&tk=<%= tk %>&query=<%= theQuery %>">Themes</a> <a href="TextSearchApp.jsp?action=doGists&tk=<%= tk %>">Gist</a> </td> </tr> <% } loopNum++; } } catch (SQLException e) { %> <b>Error: </b> <%= e %><p> <% } finally { if (conn != null) conn.close(); if (stmt != null) stmt.close(); if (rset != null) rset.close(); } %> </table> </center> <table width="100%"> <TR ALIGN="RIGHT"> <% if((startNum>0)&(count<=startNum+20)) { %> <TD ALIGN="RIGHT"> <a href="TextSearchApp.jsp?sn=<%=startNum-20 %>&query= <%=myQuery %>">previous20</a> </TD> <% } else if((count>startNum+20)&(startNum==0)) { %> <TD ALIGN="RIGHT"> <a href="TextSearchApp.jsp?sn=<%=startNum+20 %>&query= <%=myQuery %>">next20</a> </TD> <% } else if((count>startNum+20)&(startNum>0)) { %> <TD ALIGN="RIGHT"> <a href="TextSearchApp.jsp?sn=<%=startNum-20 %>&query= <%=myQuery %>">previous20</a> <a href="TextSearchApp.jsp?sn=<%=startNum+20 %>&query= <%=myQuery %>">next20</a> </TD> <% } %> </TR> </table> </body></html> <%} %> <%! public String translate (String input) { Vector reqWords = new Vector(); StringTokenizer st = new StringTokenizer(input, " '", true); while (st.hasMoreTokens()) { String token = st.nextToken(); if (token.equals("'")) { String phrase = getQuotedPhrase(st); if (phrase != null) { reqWords.addElement(phrase); } } else if (!token.equals(" ")) { reqWords.addElement(token); } } return getQueryString(reqWords); } private String getQuotedPhrase(StringTokenizer st) { StringBuffer phrase = new StringBuffer(); String token = null; while (st.hasMoreTokens() && (!(token = st.nextToken()).equals("'"))) { phrase.append(token); } return phrase.toString(); } private String getQueryString(Vector reqWords) { StringBuffer query = new StringBuffer(""); int length = (reqWords == null) ? 0 : reqWords.size(); for (int ii=0; ii < length; ii++) { if (ii != 0) { query.append(" & "); } query.append("{"); query.append(reqWords.elementAt(ii)); query.append("}"); } return query.toString(); } %>