/* * (C) Copyright IBM Corp. 2008 * * LICENSE: Eclipse Public License v1.0 * http://www.eclipse.org/legal/epl-v10.html */ package com.ibm.gaiandb.searchapis; import java.io.BufferedInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.Arrays; import java.util.Properties; import java.util.Vector; import org.apache.derby.iapi.types.DataValueDescriptor; import org.apache.derby.iapi.types.SQLChar; import org.apache.derby.iapi.types.SQLInteger; import com.ibm.gaiandb.Logger; import com.ibm.gaiandb.diags.GDBMessages; import com.ibm.siapi.common.ApplicationInfo; import com.ibm.siapi.common.CollectionInfo; import com.ibm.siapi.search.BaseQuery; import com.ibm.siapi.search.Query; import com.ibm.siapi.search.RemoteFederator; import com.ibm.siapi.search.Result; import com.ibm.siapi.search.ResultSet; import com.ibm.siapi.search.SearchFactory; import com.ibm.siapi.search.SearchService; import com.ibm.siapi.search.Searchable; public class SearchSIAPI { // Use PROPRIETARY notice if class contains a main() method, otherwise use COPYRIGHT notice. public static final String COPYRIGHT_NOTICE = "(c) Copyright IBM Corp. 2008"; private static final Logger logger = new Logger( "SearchSIAPI", 25 ); public static void printTest() { // logger.logInfo("In Search"); } // The Vector rows argument contains DataValueDescriptor[] elements, each of which is a derby database row. public static void retrieveDocumentReferences(Vector<DataValueDescriptor[]> rows, String hostname, String portNumber, String collections, String queryString, int maxResults, String applicationName, String applicationPassword ) { try { // obtain the OmniFind specific SIAPI Search factory implementation SearchFactory searchFactory = (SearchFactory) Class.forName("com.ibm.es.api.search.RemoteSearchFactory").newInstance(); ApplicationInfo appinfo = searchFactory.createApplicationInfo(applicationName); appinfo.setPassword(applicationPassword); int collectionSize=0; String[] collectionIDs=null; Query query = searchFactory.createQuery(queryString); query.setRequestedResultRange(0, maxResults); query.setQueryLanguage("en_US"); query.setSpellCorrectionEnabled(true); query.setPredefinedResultsEnabled(true); query.setReturnedAttribute(Query.RETURN_RESULT_FIELDS, true); query.setReturnedAttribute(Query.RETURN_RESULT_URI, true); query.setSortKey(BaseQuery.SORT_KEY_NONE); Properties config = new Properties(); config.setProperty("hostname", hostname); config.setProperty("port", portNumber); config.setProperty("timeout", "60"); config.setProperty("username", applicationName); config.setProperty("password", applicationPassword); // obtain the Search Service implementation SearchService searchService = searchFactory.getSearchService(config); Searchable searchable = null; // String collectionID = null; logger.logInfo("Collections = " + collections); //if there are no collections specified select all collections and construct a list of collectionIDs if ( null == collections || "*".equals(collections) ) { RemoteFederator federator = searchService.getFederator(appinfo, appinfo.getId()); if ( null == federator ) { logger.logWarning(GDBMessages.SIAPI_OMNIFIND_RESOLVE_ERROR, "Unable to resolve Omnifind Federator for app " + applicationName + ", appID " + appinfo.getId() + " - check collection name and id match, and check security for search app - returning no results"); return; } CollectionInfo[] CollectionInfos = federator.getCollectionInfos(); collectionIDs = new String[CollectionInfos.length]; for (int i=0;i<CollectionInfos.length;i++) collectionIDs[i] = CollectionInfos[i].getID(); collectionSize = CollectionInfos.length; } else { // Create an array of the list of collections from which search results are to be obtained String[] collectionNames = collections.split(","); collectionIDs = new String[collectionNames.length]; for (int i=0;i<collectionNames.length;i++) collectionIDs[i] = CollectionIDfromName(searchService,appinfo,collectionNames[i]); collectionSize = collectionNames.length; } // String[] collectionIDs = collectionID.split(","); // String[] collectionIDs = {"col_92810","col_56175","Graham","SSCatsa","col_57441"}; logger.logInfo(" CollectionSize= " + collectionSize + ", CollectionIDs = " + Arrays.asList( collectionIDs ) ); // String[] collectionIDs = {collectionID}; // String[] collectionIDs = new String[2]; // collectionIDs[0] = "col_57441"; // collectionIDs[1] = "SSCatsa"; for ( int collectionCount=0; collectionCount<collectionSize; collectionCount++ ) { searchable = searchService.getSearchable(appinfo,collectionIDs[collectionCount].trim()); ResultSet rs = searchable.search(query); // logger.logInfo("Estimated results: " + rs.getEstimatedNumberOfResults()); // logger.logInfo("Available results: " + rs.getAvailableNumberOfResults()); logger.logInfo("Evaluation time: " + rs.getQueryEvaluationTime()); if (rs != null) { // get the array of results from the ResultSet Result r[] = rs.getResults(); if (r != null) { // walk the results list and print out the // document identifier int numResults = r.length; logger.logInfo("Number of results: " + numResults ); for (int k = 0; k < numResults; k++) { // get the entry element String uri = r[k].getDocumentID(); // logger.logInfo("Description = " +r[k].getDescription()); if ( null == uri ) continue; //documentPath = (String) documentPath.subSequence(0,documentPath.length()-1); // DRV 09/12/10 - Removing: // 1) decoding of URIs and hence, 2) option to hash on the encoded or decoded URIs // String documentPath = URLDecoder.decode( uri, Charset.defaultCharset().name() ); // int id = hashDecodedPaths ? documentPath.hashCode() : uri.hashCode(); int id = uri.hashCode(); logger.logInfo("Adding row with docHashID: " + id + ", docURI: " + uri); // logger.logInfo("Other row info description: " + r[k].getDescription()); rows.add( new DataValueDescriptor[] { new SQLInteger(id), new SQLChar(uri), new SQLChar(r[k].getDescription()) } ); } } } } } catch (Exception e) { logger.logException(GDBMessages.SIAPI_EE_DOC_SEARCH_RESOLVE_ERROR, "Unable to resolve Omnifind EE document search, cause: ", e); } } protected static void printUsage() { // logger.logInfo("Search <hostname> <port> <index> <query> [Local XSL File]"); } protected static byte[] streamToByteArray(InputStream stream) throws IOException { // Handle null if(stream == null) { return null; } BufferedInputStream bufStream = new BufferedInputStream(stream); ByteArrayOutputStream outStream = new ByteArrayOutputStream(); // Read in 4K chunks - this could be increased to improve performance, but // 4K seems to be a generally accepted size to use. byte[] buffer = new byte[4096]; int len = 0; while((len = bufStream.read(buffer, 0, 4096)) > 0) { outStream.write(buffer, 0, len); } bufStream.close(); outStream.close(); return outStream.toByteArray(); } public static String CollectionIDfromName(SearchService searchService,ApplicationInfo appinfo,String collectionName){ try { // obtain the list of collection names and id's that the current user can access RemoteFederator federator = searchService.getFederator(appinfo, appinfo.getId()); // logger.logInfo("Appinfo_id = " + appinfo.getId()); CollectionInfo[] CollectionInfos = federator.getCollectionInfos(); for (int i=0; i<CollectionInfos.length; i++) { if ( collectionName.equals(CollectionInfos[i].getLabel()) ){ collectionName = CollectionInfos[i].getID(); return collectionName; } } } catch(Exception e){ } return collectionName; } }