Package com.sun.xmlsearch.servlet

Source Code of com.sun.xmlsearch.servlet.SearchState$ServiceNode

/*************************************************************************
*
*  OpenOffice.org - a multi-platform office productivity suite
*
*  $RCSfile: SearchState.java,v $
*
*  $Revision: 1.2 $
*
*  last change: $Author: rt $ $Date: 2005/09/09 16:37:28 $
*
*  The Contents of this file are made available subject to
*  the terms of GNU Lesser General Public License Version 2.1.
*
*
*    GNU Lesser General Public License Version 2.1
*    =============================================
*    Copyright 2005 by Sun Microsystems, Inc.
*    901 San Antonio Road, Palo Alto, CA 94303, USA
*
*    This library is free software; you can redistribute it and/or
*    modify it under the terms of the GNU Lesser General Public
*    License version 2.1, as published by the Free Software Foundation.
*
*    This library is distributed in the hope that it will be useful,
*    but WITHOUT ANY WARRANTY; without even the implied warranty of
*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
*    Lesser General Public License for more details.
*
*    You should have received a copy of the GNU Lesser General Public
*    License along with this library; if not, write to the Free Software
*    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
*    MA  02111-1307  USA
*
************************************************************************/

package com.sun.xmlsearch.servlet;

import java.io.*;
import java.util.Hashtable;
import java.util.Vector;
import java.util.Enumeration;
import java.util.StringTokenizer;

import javax.swing.tree.TreeNode;
import javax.servlet.*;
import javax.servlet.http.*;

// for configuration
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import java.net.URL;
import com.sun.xmlsearch.util.Configuration;
import com.sun.xmlsearch.util.ServiceFinder;

import com.sun.xmlsearch.tree.*;
import com.sun.xmlsearch.xml.qe.*;

final class SearchState {
    private final class ServiceNode implements TreeNode {
  private QueryProcessor _service;
  private String         _serviceName;
  private ServiceNode    _parent;
  private Vector         _children = new Vector();

  public ServiceNode(String name, QueryProcessor service) {
      _serviceName = name;
      _service = service;
      _expandedServiceNodes.put(name, name); // all expanded at first
  }

  public void collectServices(Vector result) throws Exception {
      if (_service != null) {
    result.addElement(_service);
    _collectionClassification = _service.getClassification();
      }
      for (int i = 0; i < _children.size(); i++)
    ((ServiceNode)_children.elementAt(i)).collectServices(result);
  }

  public QueryProcessor getService() {
      return _service;
  }

  public void addChild(ServiceNode node) {
      _children.addElement(node);
  }

  public String toString() {
      return _serviceName;
  }

  public TreeNode getParent() {
      return _parent;
  }

  public boolean getAllowsChildren() {
      return true;
  }

  public boolean isLeaf() {
      return getChildCount() == 0;
  }

  public int getChildCount() {
      return _children.size();
  }

  public TreeNode getChildAt(int i) {
      return (TreeNode)_children.elementAt(i);
  }

  public int getIndex(final TreeNode node) {
      return isLeaf() ? -1 : _children.indexOf(node);
  }
   
  public Enumeration children() {
      return _children.elements();
  }
    } // end of ServiceNode
 
    private QueryProcessor[] _queryServices;
    private ServiceNode      _serviceTree;
    private String           _collectionClassification = "java";

    private QueryProcessor  _queryProcessor;
    private Vector          _engines = new Vector();
    private DocumentServer  _docServer;
    private QueryResults    _currentQueryResults;
    private Hashtable _tocTreeCache  = new Hashtable();
    private Hashtable _docRequests   = new Hashtable();
    private Hashtable _docFragments  = new Hashtable();
    private Hashtable _expandedNodes = new Hashtable();
    private Hashtable _selectedNodes = new Hashtable();
    private Hashtable _hitUrlStrings = new Hashtable();
 
    private Hashtable _serviceNodes         = new Hashtable();
    private Hashtable _expandedServiceNodes = new Hashtable();
 
    private String _lastQuery = "";
    private String _lastScope = "";

    private String          _currentDocUrl;
    private String          _currentDocType;
    private TocTree.TocNode _currentTocRoot;
 
    private TocTree.TocNode _currentScopeNode;
    private ServiceNode     _currentServiceNode;
 
    public static synchronized SearchState getSearchState(HttpServletRequest req) {
  String date = (new java.util.Date()).toString();
  HttpSession session = req.getSession(true);
  System.out.println(date + ": " + session.getId());
  Object object = session.getValue(session.getId());
  if (object == null) {
      System.out.println("new session with " + req.getRemoteHost());
      SearchState state = new SearchState();
      state.init();
      session.putValue(session.getId(), state);
      return state;
  }
  else
      return (SearchState)object;
    }

    private DocumentFragment fetchDocumentFragment(String key) {
  return (DocumentFragment)_docFragments.get(key);
    }

    private void init() {
  try {
      URL cfgUrl = new URL("http://bigblock.east:8084/remoteSearchServices.xml");
      Element cfg = Configuration.parse(cfgUrl);
      if (cfg != null)
    configureSearchServer(cfg);
      _queryServices = getProcessors();
      buildServiceTree(_queryServices);
      _docServer = DocumentServer.instance();
  }
  catch (Exception e) {
      e.printStackTrace();
  }
    }

    private QueryProcessor[] getProcessors() {
  QueryProcessor[] result = new QueryProcessor[_engines.size()];
  if (_engines.size() > 0)
  result = (QueryProcessor[])_engines.toArray(result);
  return result;
    }

    private void configureSearchServer(Element config) throws Exception {
  if (config.getTagName().equals("XmlQueryProcessors")) {
      NodeList list = config.getElementsByTagName("XmlSearchEngine");
      for (int i = 0; i < list.getLength(); i++) {
    Element seConfig = (Element)list.item(i);
    QueryProcessorImpl qp = new QueryProcessorImpl();
    if (qp.init(seConfig))
        _engines.addElement(qp);
      }
      // process remote services
      list = config.getElementsByTagName("XmlSearchService");
      if (list.getLength() > 0) {
    for (int i = 0; i < list.getLength(); i++) {
        Element clientConfig = (Element)list.item(i);
        System.out.println(clientConfig);
        ServiceFinder finder = new ServiceFinder(_engines, "XmlSearchService");
        // finder.configure(clientConfig);
        new Thread(finder).start();
        while (finder.getNumberOfServices() == 0)
      Thread.sleep(500);
    }
      }
      setupQueryProcessor(_engines);
  }
  else
      throw new Exception("inappropriate config element for GuiDemo");
    }
 
    private void setupQueryProcessor(Vector engines) throws Exception {
  switch (engines.size()) {
  case 0:
      System.err.println("no QueryProcessors!");
      break;
      
  case 1:
      Object whatIsIt = engines.elementAt(0);
      if (whatIsIt instanceof XmlSearchServer) // remote
    _queryProcessor = (XmlSearchServer)whatIsIt;
      else if (whatIsIt instanceof QueryProcessor)
    _queryProcessor = (QueryProcessor)whatIsIt;
      else
    throw new Exception("unknown service type");
      break;

  default:
      QueryHitMerger merger = new QueryHitMerger();
      for (int i = 0; i < engines.size(); i++)
    merger.addSearchServer((XmlSearchServer)engines.elementAt(i));
      _queryProcessor = merger;
      break;
  }
    }
 
    private void buildServiceTree(QueryProcessor[] processors) {
  try {
      ServiceNode root = new ServiceNode("all collections", null);
      for (int i = 0; i < processors.length; i++) {
 
    QueryProcessor proc = processors[i];
    StringTokenizer topics = new StringTokenizer(proc.getClassification(),"/");
    ServiceNode currentNode = root;
    while (true) {
        String topic = topics.nextToken();
        if (topics.hasMoreTokens()) {
      ServiceNode topicNode = (ServiceNode)_serviceNodes.get(topic);
      if (topicNode == null) {
          topicNode = new ServiceNode(topic, null);
          _serviceNodes.put(topic, topicNode);
          currentNode.addChild(topicNode);
      }
      currentNode = topicNode;
        }
        else {
      ServiceNode topicNode = new ServiceNode(topic, proc);
      _serviceNodes.put(topic, topicNode);
      currentNode.addChild(topicNode);
      break;
        }
    }
      }
      _serviceTree = root;
  }
  catch (Exception e) {
      e.printStackTrace();
  }
    }

    private DocumentRequest getDocRequest(String document, String docType) {
  DocumentRequest req = (DocumentRequest)_docRequests.get(document);
  return req != null ? req : new DocumentRequest(document, docType);
    }

    public synchronized void retrieveDocumentFragment(String hit) {
  try {
      DocumentFragment fragment = fetchDocumentFragment(hit);
      if (fragment == null) {
    int index = Integer.parseInt(hit);
    QueryHitData hitData = _currentQueryResults.getHit(index);
    _currentDocUrl = hitData.getDocument();
    _currentDocType = hitData.getDocumentType();
    DocumentRequest request = getDocRequest(_currentDocUrl,
              _currentDocType);
    request.setFocus(hitData.getLocator());
    fragment = getDocumentFragment(request);
    _docFragments.put(hit, fragment);
    _hitUrlStrings.put(hit, _currentDocUrl);
    TocTree.TocNode[] tocPath = fragment.nodes();
    _currentTocRoot = tocPath[0];
    // setup a set of nodes expanded to show the location of the hit
    _expandedNodes.clear();
    _selectedNodes.clear();
    _expandedNodes.put("/doc", this);
    for (int i = 1; i < tocPath.length; i++) {
        String xPath = tocPath[i].getXPath();
        _expandedNodes.put(xPath, this);
        _selectedNodes.put(xPath, this);
    }
      }
      else
    _currentDocUrl = (String)_hitUrlStrings.get(hit);
  }
  catch (Exception e) {
      e.printStackTrace();
  }
    }
 
    // doc name can be of the MAN: type, etc.
    public synchronized void retrieveDocument(String docName) {
  try {
      URL docUrl = _docServer.findDocUrl(docName);
      _currentDocUrl = docUrl.toString();
      if (fetchDocumentFragment(docName) == null) {
    DocumentRequest request = getDocRequest(_currentDocUrl,
              _currentDocType);
    request.setFocus(new MultiTokenLocator("/doc"));
    DocumentFragment fragment = getDocumentFragment(request);
    _docFragments.put(docName, fragment);
    TocTree.TocNode[] tocPath = fragment.nodes();
    _currentTocRoot = tocPath[0];
    _expandedNodes.clear();
    _selectedNodes.clear();
    _expandedNodes.put("/doc", this);
    // direct children
    for (int i = 0; i < tocPath[0].getChildCount(); i++) {
        TocTree.TocNode child = (TocTree.TocNode)tocPath[0].getChildAt(i);
        _expandedNodes.put(child.getXPath(), this);
    }
      }
  }
  catch (Exception e) {
      e.printStackTrace();
  }
    }
 
    public synchronized void retrieveHitArea(String hit, OutputStream out) {
  try {
      DocumentFragment fragment = fetchDocumentFragment(hit);
      System.out.println(fragment);
      out.write(fragment.getHTML());
  }
  catch (Exception e) {
      e.printStackTrace();
  }
    }

    public synchronized void retrieveDocumentFragment(String xPath, OutputStream out) {
  try {
      DocumentRequest request = getDocRequest(_currentDocUrl,
                _currentDocType);
      request.setFocus(new MultiTokenLocator(xPath));
      DocumentFragment fragment = getDocumentFragment(request);
      out.write(fragment.getHTML());
  }
  catch (Exception e) {
      e.printStackTrace();
  }
    }

    private static int[] Widths = {15, 15, 25, 20, 20, 15, 15, 875};

    private void treeTableHeader(PrintWriter out) {
  out.write("<table cellspacing=0 cellspadding=0 border=0 width=1000><tr>");
  for (int i = 0; i < Widths.length; i++) {
      out.write("<th width=");
      out.print(Widths[i]);
      out.write('>');
  }
  out.write("</tr>");
    }

    public synchronized void getServices(PrintWriter out) {
  out.write("<h2>Select collection</h2>");
  treeTableHeader(out);
  walkServiceTree(1, _serviceTree, out);
  out.write("</table>");
    }

    public synchronized void expandServices(String name, PrintWriter out) {
  _expandedServiceNodes.put(name, name);
  getServices(out);
    }

    public synchronized void collapseServices(String name, PrintWriter out) {
  _expandedServiceNodes.remove(name);
  getServices(out);
    }

    public synchronized void activateNode(String name, PrintWriter out) {
  try {
      _lastScope = "";
      ServiceNode node = (ServiceNode)_serviceNodes.get(name);
      Vector engines = new Vector();
      node.collectServices(engines);
      setupQueryProcessor(engines);
      getScopeModel(out);
  }
  catch (Exception e) {
      e.printStackTrace();
  }
    }

    public synchronized void getScopeModel(PrintWriter out) {
  try {
      TocTree.TocNode cmodel =
    _docServer.getCollectionModel(_collectionClassification).getTreeRoot();
      out.write("<h2>Select scope</h2>");
      treeTableHeader(out);
      walkScopesTree(1, cmodel, out);
      out.write("</table>");
  }
  catch (Exception e) {
      e.printStackTrace();
  }
    }

    private void walkScopesTree(int level, TocTree.TocNode node, PrintWriter out) {
  out.write("<tr><td colspan=\"");
  out.print(level);
  out.write("\">");
  if (node == _currentScopeNode) {
      out.write("<a name=\"CurrentPos\">");
      out.write("<img src=\"/icons/ab2_toc_index.gif\" border=0 width=18 height=17>");
      out.write("</a>");
  }
  out.write("</td><td> </td><td></td><td colspan=\"");
  out.print(6 - level);
  out.write("\" nowrap><a href=\"/servlet/query?scope=");
  out.write(node.getXPath());
  out.write("\" target=\"results\">");
  out.write(node.getTitle());
  out.write("</a></td></tr>");
  if (!node.isLeaf()) {
      final int nChildren = node.getChildCount();
      for (int i = 0; i < nChildren; i++)
    walkScopesTree(level + 1, (TocTree.TocNode)node.getChildAt(i), out);
  }
    }

    private void walkServiceTree(int level, ServiceNode node, PrintWriter out) {
  final String name = node.toString();
  final boolean toExpand = _expandedServiceNodes.get(name) != null;
   
  out.write("<tr><td colspan=\"");
  out.print(level);
  out.write("\"></td><td> </td>");
  if (node.isLeaf())
      out.write("<td></td>");
  else {
      out.write("<td><a href=\"/servlet/services?");
      out.write(toExpand ? "collapse=" : "expand=");
      out.write(name);
      out.write("\"><img src=\"/icons/");
      out.write(toExpand ? "ab2_minus" : "ab2_plus");
      out.write(".gif\" border=0 width=21 height=17></a></td>");
  }
  out.write("<td colspan=\"");
  out.print(6 - level);
  out.write("\" nowrap><a href=\"/servlet/services?node=");
  out.write(name);
  out.write("\" target=\"scopes\">");
  out.write(name);
  out.write("</a></td></tr>");
  if (toExpand && !node.isLeaf()) {
      final int nChildren = node.getChildCount();
      for (int i = 0; i < nChildren; i++)
    walkServiceTree(level + 1, (ServiceNode)node.getChildAt(i), out);
  }
    }

    public synchronized void expandToc(String xPath, PrintWriter out) {
  _expandedNodes.put(xPath, this);
  retrieveToc(out);
    }

    public synchronized void collapseToc(String xPath, PrintWriter out) {
  _expandedNodes.remove(xPath);
  retrieveToc(out);
    }

    public synchronized void retrieveToc(String key, PrintWriter out) {
  DocumentFragment fragment = fetchDocumentFragment(key);
  _currentTocRoot = fragment.getTocTree().getRoot();
  retrieveToc(out);
    }

    public synchronized void retrieveToc(PrintWriter out) {
  treeTableHeader(out);
  walkTocTree(1, _currentTocRoot, out);
  out.write("</table>");
    }

    private void walkTocTree(int level, TocTree.TocNode node, PrintWriter out) {
  String xPath = node.getXPath().trim();
  if (xPath.length() == 0)
      xPath = "/doc";
  final boolean toExpand = _expandedNodes.get(xPath) != null;
   
  out.write("<tr><td colspan=\"");
  out.print(level);
  out.write("\">");
  if (_selectedNodes.get(xPath) != null) {
      out.write("<a name=\"");
      out.write(xPath);
      out.write("\"><img src=\"/icons/ab2_toc_index.gif\" border=0 width=18 height=17>");
      out.write("</a>");
  }
  out.write("</td><td> </td>");
   
  if (node.isLeaf())
      out.write("<td></td>");
  else {
      out.write("<td><a href=\"/servlet/toc?");
      out.write(toExpand ? "collapse=" : "expand=");
      out.write(xPath);
      out.write("\"><img src=\"/icons/ab2_");
      out.write(toExpand ? "minus" : "plus");
      out.write(".gif\" border=0 width=21 height=17></a></td>");
  }
  out.write("<td colspan=\"");
  out.print(6 - level);
  out.write("\" nowrap><a href=\"/servlet/text?fragment=");
  out.write(xPath);
  out.write("\" target=\"text\">");
  out.write(node.getTitle());
  out.write("</a></td></tr>");
  if (toExpand && !node.isLeaf()) {
      final int nChildren = node.getChildCount();
      for (int i = 0; i < nChildren; i++)
    walkTocTree(level + 1, (TocTree.TocNode)node.getChildAt(i), out);
  }
    }

    public synchronized void retrieveCurrentResults(PrintWriter out) {
  if (_currentQueryResults != null && _currentQueryResults.isNonEmpty()) {
      QueryHitIterator iter = _currentQueryResults.makeQueryHitIterator();
      int resultCounter = 0;
      do {
    final QueryHitData hit = iter.getHit();
    final String doc = hit.getDocument();
    final int n = hit.getNumberOfTerms();
    out.write("<a href=\"/servlet/document?hit=");
    out.print(resultCounter++);
    out.write("\" target=\"_top\">");
    out.write(doc.substring(doc.lastIndexOf('/') + 1));
    out.write("</a> (");
    for (int i = 0; i < n; i++) {
        String term = hit.getTerm(i);
        out.write(term != null ? term : "--");
        if (i < n - 1)
      out.write(", ");
    }
    out.write(")<br>");
      }
      while (iter.next());
  }
  else
      out.write("no results yet");
    }

    public synchronized QueryResults runQuery(String terms) {
  return runQuery(terms, _lastScope);
    }
   
    public synchronized QueryResults runQueryNewScope(String scope) {
  return runQuery(_lastQuery, scope);
    }
   
    public synchronized String getLastQuery() {
  return _lastQuery;
    }

    private QueryResults runQuery(String terms, String scope) {
  _lastQuery = terms;
  _lastScope = scope;
  try {
      _tocTreeCache.clear();
      _docFragments.clear();
      _hitUrlStrings.clear();
      if (_queryProcessor != null) {
    terms = terms.trim();
    if (terms.length() > 0) {
        scope = scope.trim();
        if (scope.length() == 0)
      scope = null;
        QueryStatement qs = new QueryStatement(terms, scope, 50);
        _currentQueryResults = _queryProcessor.processQuery(qs);
        _currentQueryResults.translate();
        groupHits(_currentQueryResults);
        return _currentQueryResults;
    }
      }
  }
  catch (Exception e) {
      e.printStackTrace();
  }
  return null;
    }
 
    private Hashtable _docTypes = new Hashtable();
   
    private void groupHits(QueryResults hits) {
  _docRequests.clear();
  _docTypes.clear();
  if (hits.isNonEmpty()) {
      QueryHitIterator iter = hits.makeQueryHitIterator();
      do {
    QueryHitData hit = iter.getHit();
    String doc = hit.getDocument();
    Vector docLocators = (Vector)_docRequests.get(doc);
    if (docLocators == null) {
        _docRequests.put(doc, docLocators = new Vector());
        _docTypes.put(doc, hit.getDocumentType());
    }
    docLocators.addElement(hit.getLocator());
      }
      while (iter.next());
      Enumeration keys = _docRequests.keys();
      do {
    final String doc = (String)keys.nextElement();
    final String docType = (String)_docTypes.get(doc);
    DocumentRequest request = new DocumentRequest(doc, docType);
    request.setLocators((Vector)_docRequests.get(doc));
    _docRequests.put(doc, request);
      }
      while (keys.hasMoreElements());
  }
    }

    private DocumentFragment getDocumentFragment(DocumentRequest request)
  throws Exception {
  String document = request.getDocument();
  TocTree tocTree = (TocTree)_tocTreeCache.get(document);
  final boolean tocNeeded = tocTree == null;
  // request TOC if not in cache
  request.requestToc(tocNeeded);
  DocumentFragment result = _docServer.getDocumentFragment(request);
  if (tocNeeded)
      _tocTreeCache.put(document, result.getTocTree());
  else
      result.setTOC(tocTree)// reuse cached TOC
  return result;
    }
}
TOP

Related Classes of com.sun.xmlsearch.servlet.SearchState$ServiceNode

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.