📄 proxynewsdb.java
字号:
// Is the names list the same as overviewFmt?
if ( names != lastOkNames )
{
if ( ! Utils.equalsStrings( names, overviewFmt ) )
return null;
lastOkNames = names;
}
// Check that this group is one of ours.
if ( group.getDbStamp() != dbStamp )
throw new NewsDbException( "mismatched database stamps" );
// Do we need to refresh overview data for this group?
long now = System.currentTimeMillis();
long time = overviewCache.getLastTime( group );
if ( time == -1 || now - time >= NnrpdUtils.INT_CHECKOVERVIEW )
{
readOverview( group );
overviewCache.setLastTime( group );
}
// Now just get articles from the cache.
int numArts = lastArtNum - firstArtNum + 1;
String[][] results = new String[numArts][];
// Check if we already have cached results for any of these articles.
for ( int i = 0; i < numArts; ++i )
{
int artNum = firstArtNum + i;
results[i] = overviewCache.getEntry( group, artNum );
}
return results;
}
private void readOverview( NewsDbGroup group ) throws NewsDbException
{
// Make sure it's the current group on the remote server.
if ( currentGroup == null ||
! group.getName().equals( currentGroup.getName() ) )
setGroup( group.getName() );
// Do the XOVER command.
pout.println(
NnrpdUtils.CMD_XOVER + " " +
group.getFirstArtNum() + "-" + group.getLastArtNum() );
// Get and interpret results.
String[] resp = readResp();
int respNum = Utils.parseInt( resp[0], -1 );
switch ( respNum )
{
case 224:
while ( true )
{
String line;
try
{
line = din.readLine();
}
catch ( IOException e )
{
break;
}
if ( line == null || line.equals( "." ) )
break;
int tab = line.indexOf( '\t' );
int artNum;
try
{
artNum = Integer.parseInt( line.substring( 0, tab ) );
}
catch ( NumberFormatException e )
{
continue;
}
String[] overviewEntry =
Utils.splitStr( line.substring( tab + 1 ), '\t' );
if ( overviewEntry.length != overviewFmt.length )
continue; // ignore malformed lines
overviewCache.addEntry( overviewEntry, group, artNum );
}
break;
default:
throw new NewsDbException(
"unexpected response to XOVER command: " +
Utils.flattenStrarr( resp ) );
}
}
/// Get an enumeration of all the groups.
// @exception NewsDbException if something goes wrong
public Enumeration getGroups() throws NewsDbException
{
checkGroups();
return groupTable.elements();
}
/// Get an enumeration of all groups created after a given time.
// @exception NewsDbException if something goes wrong
public synchronized Enumeration getGroups( long since ) throws NewsDbException
{
// Do the NEWGROUPS command.
pout.println(
NnrpdUtils.CMD_NEWGROUPS + " " +
NnrpdUtils.rfc977DateTime( since ) );
// Get and interpret results.
String[] resp = readResp();
int respNum = Utils.parseInt( resp[0], -1 );
switch ( respNum )
{
case 231:
return readGroups().elements();
default:
throw new NewsDbException(
"unexpected response to NEWGROUPS command: " +
Utils.flattenStrarr( resp ) );
}
}
/// Get an enumeration of all groups created after a given time that match
// a given distributions pattern.
// @exception NewsDbException if something goes wrong
public synchronized Enumeration getGroups( long since, String distsPat ) throws NewsDbException
{
// Do the NEWGROUPS command.
pout.println(
NnrpdUtils.CMD_NEWGROUPS + " " +
NnrpdUtils.rfc977DateTime( since ) + " " + distsPat );
// Get and interpret results.
String[] resp = readResp();
int respNum = Utils.parseInt( resp[0], -1 );
switch ( respNum )
{
case 231:
return readGroups().elements();
default:
throw new NewsDbException(
"unexpected response to NEWGROUPS command: " +
Utils.flattenStrarr( resp ) );
}
}
/// Get an enumeration of all message-ids received after a given time
// in groups matching the given pattern.
// @exception NewsDbException if something goes wrong
public Enumeration getMessageIds( String groupsPat, long since ) throws NewsDbException
{
// !!! This is purposely not implemented yet, because the NEWNEWS
// command takes too long and would tie up the connection to the
// remote server. At some point I'll do an implementation which
// opens up a second connection just for this one command.
Vector messageIds = new Vector();
return messageIds.elements();
}
/// Get an enumeration of all message-ids received after a given time
// in groups matching the given pattern, that also match the
// given distributions pattern.
// @exception NewsDbException if something goes wrong
public Enumeration getMessageIds( String groupsPat, long since, String distsPat ) throws NewsDbException
{
// !!! This is purposely not implemented yet, because the NEWNEWS
// command takes too long and would tie up the connection to the
// remote server. At some point I'll do an implementation which
// opens up a second connection just for this one command.
Vector messageIds = new Vector();
return messageIds.elements();
}
/// Post an article.
// @exception NewsDbException if something goes wrong
public synchronized void post( String artText ) throws NewsDbException
{
// Do the POST command.
pout.println( NnrpdUtils.CMD_POST );
// Get and interpret results.
String[] resp = readResp();
int respNum = Utils.parseInt( resp[0], -1 );
switch ( respNum )
{
case 340:
pout.print( artText );
pout.println( "." );
// Get and interpret results.
resp = readResp();
respNum = Utils.parseInt( resp[0], -1 );
switch ( respNum )
{
case 240:
// Ok!
break;
case 441:
throw new NewsDbException(
"post failed: " + Utils.flattenStrarr( resp ) );
default:
throw new NewsDbException(
"unexpected response to posted article: " +
Utils.flattenStrarr( resp ) );
}
break;
default:
throw new NewsDbException(
"unexpected response to POST command: " +
Utils.flattenStrarr( resp ) );
}
}
/// Shut down the news database.
public synchronized void close()
{
pout.println( NnrpdUtils.CMD_QUIT );
try
{
din.close();
pout.flush();
pout.close();
socket.close();
}
catch ( IOException ignore ) {}
}
/// Read a response from the server, and return it split into words.
private synchronized String[] readResp() throws NewsDbException
{
pout.flush();
String line;
try
{
line = din.readLine();
}
catch ( IOException e )
{
throw new NewsDbException(
"problem reading remote response: " + e );
}
if ( line == null || line.length() == 0 )
throw new NewsDbException( "problem reading remote response" );
return Utils.splitStr( line );
}
/// Read the list of groups, if necessary.
private synchronized void checkGroups() throws NewsDbException
{
checkGroupDescs(); // check group descriptions cache too
long now = System.currentTimeMillis();
if ( groupTable != null &&
now - groupsFetched < NnrpdUtils.INT_CHECKGROUPS )
return;
// Do the LIST command.
pout.println( NnrpdUtils.CMD_LIST );
// Get and interpret results.
String[] resp = readResp();
int respNum = Utils.parseInt( resp[0], -1 );
switch ( respNum )
{
case 215:
groupTable = readGroups();
groupsFetched = now;
return;
default:
throw new NewsDbException(
"unexpected response to LIST command: " +
Utils.flattenStrarr( resp ) );
}
}
/// Read the list of groups descriptions, if necessary.
private synchronized void checkGroupDescs() throws NewsDbException
{
long now = System.currentTimeMillis();
if ( groupDescsTable != null &&
now - groupDescsFetched < NnrpdUtils.INT_CHECKGROUPDESCS )
return;
// Do the LIST newsgroups command.
pout.println( NnrpdUtils.CMD_LIST + " newsgroups" );
// Get and interpret results.
String[] resp = readResp();
int respNum = Utils.parseInt( resp[0], -1 );
switch ( respNum )
{
case 215:
groupDescsTable = new Hashtable();
String line, groupName, groupDesc;
int ws, nws;
while ( true )
{
try
{
line = din.readLine();
}
catch ( IOException e )
{
break;
}
if ( line == null || line.equals( "." ) )
break;
ws = Utils.strCSpan( line, " \t" );
nws = ws + Utils.strSpan( line, " \t", ws );
groupName = line.substring( 0, ws );
groupDesc = line.substring( nws );
groupDescsTable.put( groupName, groupDesc );
}
groupDescsFetched = now;
return;
default:
throw new NewsDbException(
"unexpected response to LIST newsgroups command: " +
Utils.flattenStrarr( resp ) );
}
}
/// Read a list of groups.
private synchronized Hashtable readGroups() throws NewsDbException
{
Hashtable gt = new Hashtable();
String line;
String[] words;
String groupName;
int lastArtNum, firstArtNum;
char flag;
NewsDbGroup group;
while ( true )
{
try
{
line = din.readLine();
}
catch ( IOException e )
{
break;
}
if ( line == null || line.equals( "." ) )
break;
words = Utils.splitStr( line );
groupName = words[0];
try
{
lastArtNum = Integer.parseInt( words[1] );
firstArtNum = Integer.parseInt( words[2] );
}
catch ( NumberFormatException e )
{
continue;
}
flag = words[3].charAt( 0 );
group = new NewsDbGroup(
dbStamp, groupName, lastArtNum - firstArtNum + 1,
firstArtNum, lastArtNum, flag,
(String) groupDescsTable.get( groupName ) );
gt.put( group.getName(), group );
}
return gt;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -