⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 z39lsp.java

📁 数字图书馆的互操作接口
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
package dli2fe.sample;

/**
 * Title:        Digial Library Interoperable Interface Fudan Edition
 * Description:  This project contains all the classes required for DLI2FE interface. Developers use these classes to implement the wrapper and client side codes. The basic functions of DLI2FE is as follows:
 * Search: Search a digital library source site.
 * Metadata: Fetch metadata for a site.
 * ResultAccess: Get results for a given query.
 * DLI2FE uses Dublin Core as the basic attribute model, DAV/DASL as the general XML-based query language and CORBA as distributed object transportation mechanism.
 * Copyright:    Copyright (c) 2001
 * Company:      Fudan University
 * @author Carl Tao
 * @version 1.0
 */

import dli2fe.DLI2FE;
import dli2fe.DLI2FEException;
import dli2fe.Metadata;
import dli2fe.Searcher;
import dli2fe.ResultAccess;
import dli2fe.DublinCore;
import dli2fe.DAV;
/* transport module libraries */
import dli2fe.helpers.*;
/* DOM-enabled XMLObject */
import dli2fe.xml.*;
/* holder for integer values */
import org.omg.CORBA.IntHolder;

import org.w3c.dom.*;

import java.util.*;
import java.net.*;
import javax.swing.Timer;
import java.awt.event.*;

import ORG.oclc.ber.*;
import ORG.oclc.z39.*;
import ORG.oclc.z39.client.*;

/**
 * sample run arg
 * dli2fens:http://localhost:9524/ search 1 "<basicsearch xmlns='DAV:' xmlns:dc='http://purl.org/metadata/dublin_core#'> <where> <eq> <prop><dc:Creator/></prop> <literal>larson</literal> </eq> </where></basicsearch>" 20
 *
 * sample search
 *
<basicsearch xmlns='DAV:' xmlns:dc='http://purl.org/metadata/dublin_core#'>
  <where>
    <eq>
     <prop><dc:Creator/></prop>
     <literal>larson</literal>
    </eq>
  </where>
</basicsearch>
 */

public class Z39LSP implements Searcher, ResultAccess, Metadata {

  /** A session corresponds to a standing TCP/IP connection to a Z39.50 server.
   * Only a "default" result set is used within a session */

  class Session implements ActionListener {

    int SID;
    Timer timer;
    // need it to be able to set the metadata
    Z39LSP lsp;
    Z39session client;
    private int  gservLength = 0;
    String query;
    boolean searchAttempted;
    boolean interrupted;
    int pendingRequests = 0;
    Hashtable records = new Hashtable(); // Integer -> eDoc element
    long endTime;

    public Session(int SID, String query, Z39LSP lsp) {

      this.SID = SID;
      this.lsp = lsp;
      this.endTime = System.currentTimeMillis() + DLI2FE.DEFAULT_TIMEOUT*1000;
      this.timer = new Timer(DLI2FE.DEFAULT_TIMEOUT*1000, this);
      this.timer.setRepeats(false);
      this.timer.start();
      this.query = query;
    }

    public void actionPerformed(ActionEvent e) {
      lsp.removeSession(this);
    }

    public int getTimeout() {
      return (int)((endTime - System.currentTimeMillis())/1000);
    }

    public void extendTimeout(int seconds) {
      endTime = System.currentTimeMillis() + seconds * 1000;
      timer.stop();
      timer.setDelay(seconds*1000);
      timer.setRepeats(false);
      timer.start();
    }

    Element getRecord(int i) {

      return (Element)records.get(new Integer(i));
    }

    /** after the invocation, range.get() yields either -1 or leaps to the next non-consec. value */
    int getNextConsecutive(RangeEnumerator range) {

      int i = range.get();
      while(range.next() && range.get() == i + 1)
	i++;
      return i;
    }

    public Element getDocs(String docSelection,  dli2fe.XMLObject docProps) throws DLI2FEException {

      System.err.println("--- getDocs");

      initialize();

      System.err.println("--- init done");

      // get the list of attributes to retrieve
      Vector attrs = NestedAttribute.collectAttributes(XMLObject.create(docProps).getElement());

      Element eSearchResult = XMLObject.getDocument().createElementNS(DLI2FE.Namespace, DLI2FE.SearchResult);

      // we know how many results to expect...
      docSelection = docSelection.trim();
      if(docSelection.endsWith("-"))
	docSelection += getNumDocs();

      RangeEnumerator range = new RangeEnumerator(docSelection);

      range.next();
      int counter = 0;

      System.err.println("--- starting loop");

      while(!interrupted && counter < lsp.MAX_DOCS_PER_FETCH) {

	int first = range.get();
	if(first == -1)
	  break;
	int last = first;

	System.err.println("--- getRecords: " + first + "," + last);

	Element eDoc = getRecord(range.get());
	if(eDoc == null) {
	  // record fault, fetch next consecutive records
	  first = range.get();
	  last = getNextConsecutive(range);
	  fetchDocuments(first, last);
	} else
	  range.next();

	for(int i = first; i <= last; i++) {
	  eDoc = getRecord(i);
	  if(eDoc != null) {
	    // match against available data
            try {
	    eSearchResult.appendChild( NestedAttribute.matchDoc(attrs, eDoc) );
            }  catch (Exception any) {
              any.printStackTrace();
              throw new DLI2FEException(DLI2FEException.ILLEGAL_METHOD_EXC, "Unknown internal error");
            }
	  }
	  counter++;
	}
      }

      //      board.getDocs(eSearchResult, new RangeEnumerator(docSelection));
      return eSearchResult;
    }

    void fetchDocuments(int first, int last) throws DLI2FEException {

      if(last > getNumDocs())
	last = getNumDocs();
      if(first > last)
	return;

      //lsp.dbg.println(DBG.SHORT, "Fetching records " + first + " through " + last);

      pendingRequests++;
      BerString req = client.present.Request(0,"default", first, last - first + 1,
					     "F", preferredRecordSyntax,
					     gservLength, gservLength);
      pendingRequests--;

      if (req == null)
	return;
	    // add header for GServer
      //	    if (gservResource != null)
      //	        System.arraycopy(gservResource, 0, req.record(), 0,
      //		    gservLength);
      try {
	pendingRequests++;
	client.present.Response(((BerConnect)client.connection).doRequest(req, client.host,client.port));
	pendingRequests--;
      } catch (Exception e) {
	//lsp.dbg.println(DBG.SHORT, "Fetching records failed: " + e.getMessage());
	client.reset();
      }

      //lsp.dbg.println(DBG.SHORT, "" + client.present.numberOfRecordsReturned +
      //	      " records returned");
      switch (client.present.presentStatus)
	    {
		case Z39presentApi.success:
		    break;
		case Z39presentApi.partial_1:
		case Z39presentApi.partial_2:
		case Z39presentApi.partial_3:
/*		case Z39presentApi.partial_4:*/
		  //lsp.dbg.println(DBG.SHORT, "Partial results returned");
		  break;
		case Z39presentApi.failure:
		  //lsp.dbg.println(DBG.SHORT, "Present failed");
		  break;
	    }

      if (client.present.errorCode != 0)
	{
	  //lsp.dbg.println(DBG.SHORT, "Could not retrieve results: Z39.50 errorCode=" + client.present.errorCode +
	  //		  ", message='" + client.present.errorMsg + "'");
	}
      addRecords(first, client.present);
    }

    String toString(DataDir dir) {

      if(dir == null)
	return "";

      StringBuffer str = new StringBuffer();

      DataDir ch = dir.child();
      if(ch != null) {
	while(ch != null) {
	  str.append(toString(ch));
	  ch = ch.next();
	}
      } else { // primitive
	str.append(dir.getString());
      }

      return str.toString();
    }

    void appendProp(Element ePropList, String namespace, String tagName, DataDir dir) {
      if(dir != null)
	ePropList.appendChild( DOMUtil.createTextNode(ePropList.getOwnerDocument(), namespace, tagName, toString(dir)) );
    }


    void addRecords(int offset, Z39present present) {

      if (present.numberOfRecordsReturned != 0)
	present.decodeRecords();

      Document doc = XMLObject.getDocument();

      for (int i=0; i<present.numberOfRecordsReturned; i++) {

	int DID = offset + i;

	if (present.presentData.elementAt(i) == null)
	  {
	    //lsp.dbg.println(DBG.SHORT, "Record " + DID + "absent from returned records!");
	    continue;
	  }
	/*
	  if (output_file != null) {
	  if (present.records[i] instanceof BerString)
	  output_file.write(((BerString)present.records[i]).record());
	  }
	  */

	Element eDoc = doc.createElementNS(DLI2FE.Namespace, DLI2FE.doc);
	Element eDID = DOMUtil.createTextNode(doc, DLI2FE.Namespace, DLI2FE.DID, String.valueOf(DID));
	eDoc.appendChild(eDID);
	Element ePropList = doc.createElementNS(DLI2FE.Namespace, DLI2FE.propList);
	eDoc.appendChild(ePropList);
	records.put(new Integer(DID), eDoc);

	DataDir dir = (DataDir)((DbPresentData)present.presentData.elementAt(i)).data;

	//if(dbg.is(DBG.VERBOSE))
	//  lsp.dbg.println(DBG.VERBOSE, "DOCUMENT:\n" + dir);

	// 0, 1, 8, 245 - almost the same!

	DataDir sec;

	sec = dir.find(245);
	if(sec != null)
	  appendProp(ePropList, DublinCore.Namespace, DublinCore.Title, sec.find(1));
	sec = dir.find(100);
	if(sec != null)
	  appendProp(ePropList, DublinCore.Namespace, DublinCore.Creator, sec.find(1));

	// co-authors
	int occ = 0;
	do {
	  sec = dir.find(700, -1, ++occ);
	  if(sec != null)
	    appendProp(ePropList, DublinCore.Namespace, DublinCore.Creator, sec.find(1));
	} while (sec != null);

	appendProp(ePropList, DublinCore.Namespace, DublinCore.Description, dir.find(500));
	appendProp(ePropList, DublinCore.Namespace, DublinCore.Description, dir.find(504));
	appendProp(ePropList, DublinCore.Namespace, DublinCore.Description, dir.find(300));

	sec = dir.find(650);
	if(sec != null)
	  appendProp(ePropList, DublinCore.Namespace, DublinCore.Subject, sec.find(1));

	sec = dir.find(260);
	if(sec != null) {
	  appendProp(ePropList, DublinCore.Namespace, DublinCore.Publisher, sec.find(2));
	  appendProp(ePropList, DublinCore.Namespace, DublinCore.Date, sec.find(3));
	}



	//	DataDir dPublisher = dir.find(260);
	/*
	String ids = "";
	DataDir t = dir.child();
	while(t != null) {
	  ids += t.fldid() + ", ";
	  t = t.next();
	}
	  //	DataDir dDescription = dir.find(500);

	//	ePropList.appendChild( DOMUtil.createTextNode(doc, DublinCore.Creator,
	//						      toString(dCreator)) );
	ePropList.appendChild( DOMUtil.createTextNode(doc, DublinCore.Description,
						      ids) );
						      */
	  /*
	  if (present.recordSyntax == null) {
	    System.out.println(((DbPresentData)present.presentData.elementAt(i)).data);
	  }
	  else if (present.recordSyntax.equals(Z39presentApi.SIMPLETEXT_SYNTAX))
	    {
	      DataDir dd =
		(DataDir)((DbPresentData)present.presentData.elementAt(i)).data;
	      while (dd.form() != ASN1.PRIMITIVE)
		dd = dd.child();
	      if (dd != null)
		System.out.println(dd.dgetChar());

	    }
	  else if (present.recordSyntax.equals(
					       Z39presentApi.OCLC_BER_SYNTAX) ||
		   present.recordSyntax.equals(Z39presentApi.MARC_SYNTAX) ||
		   present.recordSyntax.equals(Z39presentApi.OPAC_SYNTAX))

	    {
	      System.out.println((DataDir)((DbPresentData)present.presentData.elementAt(i)).data);
	    }
	  else if (present.recordSyntax.equals(Z39presentApi.EXPLAIN_SYNTAX))
	    {
	      System.out.println(Explain.getRecord(
						   new DataDir((BerString)((DbPresentData)present.presentData.elementAt(i)).data)));
	    }
	  else
	    System.out.println(((DbPresentData)present.presentData.elementAt(i)).data);
	    */
      }
    }

    public Timer getTimer() {
      return timer;
    }

    public int getSID() {
      return SID;
    }

    public int getNumDocs() throws DLI2FEException {
      initialize();
      return client.search.resultCount;
    }

    public void cancel() {

      interrupted = true;
      timer.stop();

      if(client != null) {
	if(pendingRequests == 0) {
	  // good client
	  BerString req = client.close.Request(0, Z39closeApi.finished, gservLength,
					       gservLength);
	  if (req != null) {
	    // add header for GServer.
	    //	  if (gservResource != null)
	    //		    System.arraycopy(gservResource, 0, req.record(), 0,
	    //			gservLength);
	    try {client.close.Response(((BerConnect)client.connection).doRequest(req, client.host, client.port)); }
	    catch (Exception e) {}
	    client = null;
	  }
	} else {
	  //lsp.dbg.println(DBG.SHORT, "" + pendingRequests + " pending requests, shutting down the connection");
	  client.closeConnection();
	  //	  client = null; otherwise null pointer exception in awaken thread!
	}
      }
    }

    void createSubcollectionInfo() throws DLI2FEException {

      if(lsp.subcolInfo == null) {

	// determine subcollections
	Document doc = XMLObject.getDocument();
	Element eSubcolInfo = doc.createElementNS(DLI2FE.Namespace, DLI2FE.subcolInfo);

	if (client.init.DBList != null &&
	    client.init.DBList.length > 0) {

	  for (int i=0; i<client.init.DBList.length; i++) {

	    Element eSubCol = doc.createElementNS(DLI2FE.Namespace, DLI2FE.subcol);
	    eSubcolInfo.appendChild(eSubCol);
	    eSubCol.appendChild( DOMUtil.createTextNode(doc, DLI2FE.Namespace, DLI2FE.subcolName, client.init.DBList[i]) );
	    if (client.init.DisplayDBList != null)
	      eSubCol.appendChild( DOMUtil.createTextNode(doc, DLI2FE.Namespace, DLI2FE.subcolName, client.init.DisplayDBList[i]) );
	    if(i == 0) {
	      eSubCol.appendChild( doc.createElementNS(DLI2FE.Namespace, DLI2FE.defaultSubcol) );
	      lsp.defaultSubcol = client.init.DBList[0];
	    }
	  }
	  lsp.subcolInfo = new XMLObject(eSubcolInfo);
	}
      }
    }

    synchronized void initialize() throws DLI2FEException {

      if(client == null) {

	//lsp.dbg.println(DBG.SHORT, "Initializing Z39.50 session to " + lsp.host + ":" + lsp.port);

	client = new Z39session();
	client.host = lsp.host;
	client.port = lsp.port;

	// init
	pendingRequests++;
	client.initClient(client.host, client.port);

	if (client.connection == null) {
	  try {
	    client.connection = new BerConnect(client.host, client.port);
	  } catch (Exception n) {
	    pendingRequests--;
	    client.reset();
	    throw new DLI2FEException(DLI2FEException.SERVER_ERROR_EXC,
				     "Could not connect to " + client.host + ":" + client.port + ": " + n.getMessage());
	  }
	}

	//    System.out.println("Talking to port " + client.port + " of host '" +
	//		       client.host + "'");
	BerString req = client.init.Request(0,null,500000,100000000, client.autho,
					    client.password, "", null, false /*fSetReconnect*/,
					    gservLength, gservLength);
	pendingRequests--;
	if (req == null)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -