📄 z39lsp.java
字号:
return;
// add header for GServer.
// if (gservResource != null)
// System.arraycopy(gservResource, 0, req.record(), 0,
// gservLength);
pendingRequests++;
try {
client.init.Response(((BerConnect)client.connection).doRequest(req, client.host, client.port));
} catch (Exception e) {
pendingRequests--;
client.reset();
throw new DLI2FEException(DLI2FEException.SERVER_ERROR_EXC, "Could not initialize " + client.host + ":" + client.port + ": " + e.getMessage());
}
pendingRequests--;
// System.out.println("Done with Init request");
// if (client.init.MessageOfTheDay != null)
// System.out.println(client.init.MessageOfTheDay);
switch (client.init.failureCode) {
case Z39presentApi.success: // valid init
createSubcollectionInfo();
break;
case Z39initApi.InvalidAutho:
throw new DLI2FEException(DLI2FEException.SERVER_ERROR_EXC, "Init failure: Invalid Autho");
case Z39initApi.BadAuthoPassword:
throw new DLI2FEException(DLI2FEException.SERVER_ERROR_EXC, "Init failure: Unmatched authorization/password");
case Z39initApi.NoSearchesRemaining:
throw new DLI2FEException(DLI2FEException.SERVER_ERROR_EXC, "Init failure: No Searches remaining for the autho");
case Z39initApi.IncorrectInterfaceType:
throw new DLI2FEException(DLI2FEException.SERVER_ERROR_EXC, "Init failure: Autho has incorrect interface type");
case Z39initApi.MaxNumberSimultaneousUsers:
throw new DLI2FEException(DLI2FEException.SERVER_ERROR_EXC, "Init failure: Max Number Simultaneous Users for the autho");
case Z39initApi.BlockedIPAddress:
throw new DLI2FEException(DLI2FEException.SERVER_ERROR_EXC, "Init failure: Blocked IP Address");
default:
throw new DLI2FEException(DLI2FEException.SERVER_ERROR_EXC, "Init failure: Unknown Z39.50 reason code = '" +
client.init.failureCode + "'");
}
/*
if (client.init.failureCode != 0)
return false;
CanDoScan = true;
if (client.init.options.length() > 7 &&
client.init.options.charAt(7) == 'y') {
}
else
System.out.println(
"This server indicates that it does NOT support the Scan Facility");
*/
//lsp.dbg.println(DBG.SHORT, "Session established to " + lsp.host + ":" + lsp.port);
}
if(query == null) // collect metadata only
return;
if(!searchAttempted) {
// run the query
searchAttempted = true;
//lsp.dbg.println(DBG.SHORT, "Running query " + query);
//if(lsp.defaultSubcol == null)
// throw new DLI2FEException(DLI2FEException.SERVER_ERROR_EXC, "Internal error: no default subcollection specified!");
pendingRequests++;
BerString req = client.search.Request(0, 0,
1, 0,
1, "default", lsp.defaultSubcol,
null, null, lsp.preferredRecordSyntax, query, lsp.queryType,
null, null, null, "1.2.840.10003.10.1000.17.7",
null, null, gservLength, gservLength);
pendingRequests--;
if (req == null)
throw new DLI2FEException(DLI2FEException.SERVER_ERROR_EXC, "Internal error: query translation failed.");
// if (gservResource != null)
// System.arraycopy(gservResource, 0, req.record(), 0,
// gservLength);
pendingRequests++;
try {
client.search.Response(((BerConnect)client.connection).doRequest(req, client.host, client.port));
} catch (AccessControl aa) {
pendingRequests--;
throw new DLI2FEException(DLI2FEException.SERVER_ERROR_EXC, "Access denied.");
} catch (Exception e) {
client.reset();
pendingRequests--;
throw new DLI2FEException(DLI2FEException.SERVER_ERROR_EXC, "Search failed: " + e.getMessage());
}
pendingRequests--;
/*
if (client.search.searchStatus == 0 &&
client.search.errorCode == 107 &&
query_type == 101)
{
System.out.println("Query Type101 not support by server. "
+ " Degrading to Type1 and retrying. ");
System.out.println("All future queries will be of Type1.");
query_type = 1;
return true;
}
*/
if (client.search.searchStatus != 0 /*|| client.search.errorCode == 12 partial results*/) {
//lsp.dbg.println(DBG.SHORT, "Search successful");
addRecords(1, client.search.Present);
} else {
throw new DLI2FEException(DLI2FEException.SERVER_ERROR_EXC, "Search failed: Z39.50 error code = " + client.search.errorCode +
", message = " + client.search.errorMsg);
}
}
}
public String toString() {
return "[SID:" + SID + "]";
}
}
static final int DEFAULT_Z3950_PORT = 210;
static final int MAX_STATE_TIMEOUT = 10 * 60; // 10 min
static final int MAX_DOCS_PER_FETCH = 100;
Hashtable sessions = new Hashtable(); // Integer -> Session
int lastSessionID = 0;
String host;
int port;
XMLObject subcolInfo;
String defaultSubcol;
String preferredRecordSyntax = Z39presentApi.MARC_SYNTAX;
int queryType = 1;
public Z39LSP(String hostPort) throws DLI2FEException {
try {
// extract host and port, misuse URL for that
URL lspURI = new URL("http://" + hostPort);
host = lspURI.getHost();
port = lspURI.getPort();
if(port <= 0)
port = DEFAULT_Z3950_PORT;
} catch (MalformedURLException mue) {
throw new DLI2FEException(DLI2FEException.SERVER_ERROR_EXC, "Invalid Z39.50 server access point: " + hostPort);
}
}
public void setDefaultSubcol(String subcol) {
defaultSubcol = subcol;
}
public void getSiteMetadata (dli2fe.XMLObject theSiteMetadata) throws DLI2FEException {
collectMetadata();
if(this.subcolInfo == null)
throw new DLI2FEException(DLI2FEException.NOT_IMPLEMENTED_EXC, "");
else
XMLObject.setElement(theSiteMetadata, subcolInfo.getElement());
}
public void getAttributeInfo (String ctgrName,
dli2fe.XMLObject attributeInfo) throws DLI2FEException {
}
public void search(
int clientSID,
dli2fe.XMLObject subcollections,
dli2fe.XMLObject query,
int numDocs,
dli2fe.XMLObject docProps,
dli2fe.XMLObject queryOptions,
IntHolder expectedTotal,
IntHolder serverSID,
dli2fe.XMLObject result
)
throws DLI2FEException {
/* get Elements from anonymous XMLObjects */
Element eQuery = XMLObject.create(query).getElement();
Element eWhere = DOMUtil.getChild(eQuery, DAV.where);
Element queryBody = QueryUtil.inside(eWhere);
String rpnQuery = null;
// case 1: simple "contains" query
String containsStr = DOMUtil.getDescendantText(eWhere, DAV.contains);
if(containsStr != null) {
rpnQuery =
enquote(containsStr) + "/u=4 " +
enquote(containsStr) + "/u=62 OR " +
enquote(containsStr) + "/u=1003 OR";
} else {
// complex query
queryBody = QueryUtil.canonicalDNF(queryBody);
if(QueryUtil.isTrue(queryBody))
throw new DLI2FEException(DLI2FEException.BAD_QUERY_EXC, "Query is always true!");
if(QueryUtil.isFalse(queryBody)) {
// empty set
expectedTotal.value = 0;
result.setString("<SearchResult xmlns='" + DLI2FE.Namespace + "'/>");
return;
}
rpnQuery = getRPNQuery(queryBody);
}
System.out.println("--- RPN query: " + rpnQuery);
// create a new session
Session session = new Session(++lastSessionID, rpnQuery, this);
// stateful request, save the new session
addSession(session);
String docSelection = (numDocs == dli2fe.Searcher.RETURN_ALL_DOCS) ? "1-" : "1-" + numDocs;
/* deliver the result */
XMLObject.setElement(result, session.getDocs(docSelection, docProps));
// set expected total number of results
expectedTotal.value = session.getNumDocs();
// set timeout after request processing for more accurate result
serverSID.value = session.getSID();
}
String getRPNQuery(Element op) throws DLI2FEException {
String orSubQuery = null;
NodeList orList = DOMUtil.getChildElements(op, "*");
for(int i=0; i < orList.getLength(); i++) {
NodeList andList = DOMUtil.getChildElements((Element)orList.item(i), "*");
String andSubQuery = null;
// separate negated and non-negated operands
Vector nonneg = new Vector();
Vector neg = new Vector();
for(int j=0; j < andList.getLength(); j++) {
Element predicate = (Element)andList.item(j);
if(QueryUtil.isNOT(predicate))
neg.addElement(predicate);
else
nonneg.addElement(predicate);
}
// if there are no positive operands, throw an error
if(nonneg.size() == 0)
throw new DLI2FEException(DLI2FEException.BAD_QUERY_EXC, "Unbound operand(s) in the query, cannot replace with AND-NOT");
// process non-negative
for(int k = 0; k < nonneg.size(); k++) {
Element predicate = (Element)nonneg.elementAt(k);
String res = getRPNPredicate(predicate);
if(andSubQuery == null)
andSubQuery = res;
else
andSubQuery += " " + res + " AND";
}
// process negative
for(int k = 0; k < neg.size(); k++) {
Element predicate = (Element)neg.elementAt(k);
andSubQuery += " " + getRPNPredicate(QueryUtil.inside(predicate)) + " NOT";
}
if(orSubQuery == null)
orSubQuery = andSubQuery;
else
orSubQuery += " " + andSubQuery + " OR";
}
return orSubQuery;
}
String getRPNPredicate(Element op) throws DLI2FEException {
Element eProp = QueryUtil.inside(DOMUtil.getChild(op, DAV.prop));
String value = DOMUtil.getChildText(op, DAV.literal);
if(eProp == null || value == null)
throw new DLI2FEException(DLI2FEException.BAD_QUERY_EXC, "Malformed operand: " + op.getTagName());
String tag = eProp.getLocalName();
String s = null;
if(DublinCore.Title.equals(tag))
s = enquote(value) + "/u=4";
else if(DublinCore.Creator.equals(tag))
s = enquote(value) + "/u=1003";
else if(DublinCore.Description.equals(tag))
s = enquote(value) + "/u=62";
else if(DublinCore.Subject.equals(tag))
s = enquote(value) + "/u=21";
else
throw new DLI2FEException(DLI2FEException.BAD_QUERY_EXC, "Unsupported operator: " + tag);
return s;
}
String enquote(String s) {
if(s.indexOf('"') >= 0)
return s;
else
return "\"" + s + "\"";
}
/* Method of Timeoutable */
/*
public void timeout(Object handle) {
Session session = (Session)handle;
dbg.println(DBG.SHORT, "Session " + session + " timed out!");
removeSession(session);
}
*/
/* Methods of the source metadata interface */
public void getInterface(dli2fe.XMLObject intf) throws DLI2FEException {
collectMetadata();
intf.setString("");
}
public void getSubcollectionInfo(dli2fe.XMLObject subcolInfo) throws DLI2FEException {
collectMetadata();
if(this.subcolInfo == null)
throw new DLI2FEException(DLI2FEException.NOT_IMPLEMENTED_EXC, "");
else
XMLObject.setElement(subcolInfo, this.subcolInfo.getElement());
}
public void setSubcollectionInfo(dli2fe.XMLObject subcolInfo) throws DLI2FEException {
this.subcolInfo = XMLObject.create(subcolInfo);
}
boolean isMetadataCollected = false;
synchronized void collectMetadata() throws DLI2FEException {
if(subcolInfo != null || isMetadataCollected)
return;
isMetadataCollected = true;
Session session = new Session(0, null, this);
session.initialize();
session.cancel();
}
public void getPropertyInfo(String subcolName,
dli2fe.XMLObject propInfo) throws DLI2FEException {
propInfo.setString("<propList xmlns='" + DLI2FE.Namespace + "'" +
" xmlns:dc='" + DublinCore.Namespace + "'>" +
" <dc:Title><searchable/><retrievable/></dc:Title>" +
" <dc:Creator><searchable/><retrievable/></dc:Creator>" +
" <dc:Description><searchable/><retrievable/></dc:Description>" +
"</propList>");
}
// Methods of the ResultAccess interface
// ResultAccess implementation
public void cancelRequest(int serverSID, int reqID)
throws DLI2FEException {
// we can only cancel the whole session ;(
Session s = findSession(serverSID);
//dbg.println(DBG.SHORT, "Cancelling session " + s);
s.cancel();
if(reqID == ResultAccess.CANCEL_ALL_REQUESTS) {
removeSession(s);
}
}
public void getSessionInfo(
int serverSID,
IntHolder expectedTotal,
IntHolder stateTimeout
)
throws DLI2FEException {
Session session = findSession(serverSID);
expectedTotal.value = session.getNumDocs();
stateTimeout.value = session.getTimeout();
//dbg.println(DBG.SHORT, "Info requested for " + session + ": total=" + expectedTotal.value + ", timeout=" + stateTimeout.value);
}
public void getDocs(
int serverSID,
int reqID,
dli2fe.XMLObject docPropList,
String docsToGet,
dli2fe.XMLObject res )
throws DLI2FEException {
Session session = findSession(serverSID);
//dbg.println(DBG.SHORT, "Getting documents " + docsToGet + " for " + session);
XMLObject.setElement(res, session.getDocs(docsToGet, docPropList));
}
public void extendStateTimeout(int serverSID,
int additionalTime )
throws DLI2FEException {
Session session = findSession(serverSID);
// it can happen that the killer thread is under way...
if(session.getTimeout() == 0)
throw new DLI2FEException(DLI2FEException.REQUEST_TIMEOUT_EXC, "Invalid or timed out session");
session.extendTimeout(additionalTime);
//dbg.println(DBG.SHORT, "Extended state timeout of " + session + " for " + timeAllotted.value);
}
// Private methods
void addSession(Session s) {
sessions.put(new Integer(s.getSID()), s);
//dbg.println(DBG.SHORT, "New session " + s + " created");
}
void removeSession(Session s) {
s.cancel();
sessions.remove(new Integer(s.getSID()));
//dbg.println(DBG.SHORT, "Removing session " + s + ", " + sessions.size() + " left");
}
Session findSession(int SID) throws DLI2FEException {
Session s = (Session)sessions.get(new Integer(SID));
if(s == null)
throw new DLI2FEException(DLI2FEException.REQUEST_TIMEOUT_EXC, "Invalid or timed out session");
return s;
}
public String toString() {
return "Z3950LSP_" + host + "_" + port;
}
public static void main(String args[]) throws Exception {
/* Instantiate an DLI2FE/DASL transport module
* This also starts the server on the given port */
/*
if(args.length < 2) {
System.err.println("Usage: java dli2fe.sample.Z39LSP <Z39-host>[:<Z39-port>] <port> [default subcollection]");
System.exit(1);
}*/
Z39LSP lsp = new Z39LSP("melvyl.ucop.edu");
lsp.setDefaultSubcol("CATALOG");
//Z39LSP lsp = new Z39LSP("z3950.loc.gov:7090");
//Z39LSP lsp = new Z39LSP("202.96.221.143");
//lsp.setDefaultSubcol("shcl");
//Z39LSP lsp = new Z39LSP("202.120.227.53");
//lsp.setDefaultSubcol("cnhorizon");
//lsp.setDefaultSubcol("VOYAGER");
//DBG dbg = new DBG(DBG.SHORT);
//lsp.setDBG(dbg);
/* Initialize CORBA transport only if runtime libraries are available */
ServerCORBATransport t2 = new ServerCORBATransport();
t2.addLSP(lsp);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -