?? z39lsp.java
字號:
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 + -