forked from I2P_Developers/i2p.i2p
* Blockfile:
- More query options - More exception logging - Fix lookup infinite loop - Fix lookup NPE * SusiDNS: - Refactoring for new NamingService API - Initial conversion to new NamingService API (still needs work) - Fix lots of HTML warnings - Some Java 5 cleanup
This commit is contained in:
@@ -26,13 +26,10 @@ package i2p.susi.dns;
|
||||
|
||||
import java.util.Comparator;
|
||||
|
||||
public class AddressByNameSorter implements Comparator
|
||||
public class AddressByNameSorter implements Comparator<AddressBean>
|
||||
{
|
||||
public int compare(Object arg0, Object arg1)
|
||||
public int compare(AddressBean a, AddressBean b)
|
||||
{
|
||||
AddressBean a = (AddressBean)arg0;
|
||||
AddressBean b = (AddressBean)arg1;
|
||||
|
||||
if( a == null )
|
||||
return 1;
|
||||
|
||||
|
@@ -42,12 +42,13 @@ import net.i2p.util.SecureFileOutputStream;
|
||||
|
||||
public class AddressbookBean
|
||||
{
|
||||
private String book, action, serial, lastSerial, filter, search, hostname, destination;
|
||||
private int beginIndex, endIndex;
|
||||
private Properties properties, addressbook;
|
||||
protected String book, action, serial, lastSerial, filter, search, hostname, destination;
|
||||
protected int beginIndex, endIndex;
|
||||
protected final Properties properties;
|
||||
private Properties addressbook;
|
||||
private int trClass;
|
||||
private LinkedList deletionMarks;
|
||||
private static Comparator sorter;
|
||||
protected final LinkedList<String> deletionMarks;
|
||||
protected static final Comparator<AddressBean> sorter;
|
||||
private static final int DISPLAY_SIZE=100;
|
||||
|
||||
static {
|
||||
@@ -88,7 +89,7 @@ public class AddressbookBean
|
||||
private long configLastLoaded = 0;
|
||||
private static final String PRIVATE_BOOK = "private_addressbook";
|
||||
private static final String DEFAULT_PRIVATE_BOOK = "../privatehosts.txt";
|
||||
private void loadConfig()
|
||||
protected void loadConfig()
|
||||
{
|
||||
long currentTime = System.currentTimeMillis();
|
||||
|
||||
@@ -123,11 +124,14 @@ public class AddressbookBean
|
||||
} catch (IOException ioe) {}
|
||||
return filename;
|
||||
}
|
||||
private Object[] entries;
|
||||
public Object[] getEntries()
|
||||
|
||||
protected AddressBean[] entries;
|
||||
|
||||
public AddressBean[] getEntries()
|
||||
{
|
||||
return entries;
|
||||
}
|
||||
|
||||
public String getAction() {
|
||||
return action;
|
||||
}
|
||||
@@ -167,7 +171,7 @@ public class AddressbookBean
|
||||
try {
|
||||
fis = new FileInputStream( getFileName() );
|
||||
addressbook.load( fis );
|
||||
LinkedList list = new LinkedList();
|
||||
LinkedList<AddressBean> list = new LinkedList();
|
||||
Enumeration e = addressbook.keys();
|
||||
while( e.hasMoreElements() ) {
|
||||
String name = (String)e.nextElement();
|
||||
@@ -189,52 +193,11 @@ public class AddressbookBean
|
||||
}
|
||||
list.addLast( new AddressBean( name, destination ) );
|
||||
}
|
||||
Object array[] = list.toArray();
|
||||
AddressBean array[] = list.toArray(new AddressBean[list.size()]);
|
||||
Arrays.sort( array, sorter );
|
||||
entries = array;
|
||||
|
||||
// Format a message about filtered addressbook size, and the number of displayed entries
|
||||
// addressbook.jsp catches the case where the whole book is empty.
|
||||
String filterArg = "";
|
||||
if( search != null && search.length() > 0 ) {
|
||||
message = _("Search") + ' ';
|
||||
}
|
||||
if( filter != null && filter.length() > 0 ) {
|
||||
if( search != null && search.length() > 0 )
|
||||
message = _("Search within filtered list") + ' ';
|
||||
else
|
||||
message = _("Filtered list") + ' ';
|
||||
filterArg = "&filter=" + filter;
|
||||
}
|
||||
if (entries.length == 0) {
|
||||
message += "- " + _("no matches") + '.';
|
||||
} else if (getBeginInt() == 0 && getEndInt() == entries.length - 1) {
|
||||
if (message.length() == 0)
|
||||
message = _("Addressbook") + ' ';
|
||||
if (entries.length <= 0)
|
||||
message += _("contains no entries");
|
||||
else if (entries.length == 1)
|
||||
message += _("contains 1 entry");
|
||||
else
|
||||
message += _("contains {0} entries", entries.length);
|
||||
message += '.';
|
||||
} else {
|
||||
if (getBeginInt() > 0) {
|
||||
int newBegin = Math.max(0, getBeginInt() - DISPLAY_SIZE);
|
||||
int newEnd = Math.max(0, getBeginInt() - 1);
|
||||
message += "<a href=\"addressbook.jsp?book=" + getBook() + filterArg +
|
||||
"&begin=" + newBegin + "&end=" + newEnd + "\">" + newBegin +
|
||||
'-' + newEnd + "</a> | ";
|
||||
}
|
||||
message += _("Showing {0} of {1}", "" + getBegin() + '-' + getEnd(), entries.length);
|
||||
if (getEndInt() < entries.length - 1) {
|
||||
int newBegin = Math.min(entries.length - 1, getEndInt() + 1);
|
||||
int newEnd = Math.min(entries.length, getEndInt() + DISPLAY_SIZE);
|
||||
message += " | <a href=\"addressbook.jsp?book=" + getBook() + filterArg +
|
||||
"&begin=" + newBegin + "&end=" + newEnd + "\">" + newBegin +
|
||||
'-' + newEnd + "</a>";
|
||||
}
|
||||
}
|
||||
message = generateLoadMessage();
|
||||
}
|
||||
catch (Exception e) {
|
||||
Debug.debug( e.getClass().getName() + ": " + e.getMessage() );
|
||||
@@ -246,6 +209,54 @@ public class AddressbookBean
|
||||
message = "<p>" + message + "</p>";
|
||||
return message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Format a message about filtered addressbook size, and the number of displayed entries
|
||||
* addressbook.jsp catches the case where the whole book is empty.
|
||||
*/
|
||||
protected String generateLoadMessage() {
|
||||
String message = "";
|
||||
String filterArg = "";
|
||||
if( search != null && search.length() > 0 ) {
|
||||
message = _("Search") + ' ';
|
||||
}
|
||||
if( filter != null && filter.length() > 0 ) {
|
||||
if( search != null && search.length() > 0 )
|
||||
message = _("Search within filtered list") + ' ';
|
||||
else
|
||||
message = _("Filtered list") + ' ';
|
||||
filterArg = "&filter=" + filter;
|
||||
}
|
||||
if (entries.length == 0) {
|
||||
message += "- " + _("no matches") + '.';
|
||||
} else if (getBeginInt() == 0 && getEndInt() == entries.length - 1) {
|
||||
if (message.length() == 0)
|
||||
message = _("Addressbook") + ' ';
|
||||
if (entries.length <= 0)
|
||||
message += _("contains no entries");
|
||||
else
|
||||
message += _(entries.length, "contains 1 entry", "contains {0} entries");
|
||||
message += '.';
|
||||
} else {
|
||||
if (getBeginInt() > 0) {
|
||||
int newBegin = Math.max(0, getBeginInt() - DISPLAY_SIZE);
|
||||
int newEnd = Math.max(0, getBeginInt() - 1);
|
||||
message += "<a href=\"addressbook.jsp?book=" + getBook() + filterArg +
|
||||
"&begin=" + newBegin + "&end=" + newEnd + "\">" + newBegin +
|
||||
'-' + newEnd + "</a> | ";
|
||||
}
|
||||
message += _("Showing {0} of {1}", "" + getBegin() + '-' + getEnd(), entries.length);
|
||||
if (getEndInt() < entries.length - 1) {
|
||||
int newBegin = Math.min(entries.length - 1, getEndInt() + 1);
|
||||
int newEnd = Math.min(entries.length, getEndInt() + DISPLAY_SIZE);
|
||||
message += " | <a href=\"addressbook.jsp?book=" + getBook() + filterArg +
|
||||
"&begin=" + newBegin + "&end=" + newEnd + "\">" + newBegin +
|
||||
'-' + newEnd + "</a>";
|
||||
}
|
||||
}
|
||||
return message;
|
||||
}
|
||||
|
||||
/** Perform actions, returning messages about this. */
|
||||
public String getMessages()
|
||||
{
|
||||
@@ -255,8 +266,6 @@ public class AddressbookBean
|
||||
if( action != null ) {
|
||||
if( lastSerial != null && serial != null && serial.compareTo( lastSerial ) == 0 ) {
|
||||
boolean changed = false;
|
||||
int deleted = 0;
|
||||
String name = null;
|
||||
if (action.equals(_("Add")) || action.equals(_("Replace"))) {
|
||||
if( addressbook != null && hostname != null && destination != null ) {
|
||||
String oldDest = (String) addressbook.get(hostname);
|
||||
@@ -291,12 +300,14 @@ public class AddressbookBean
|
||||
// clear search when adding
|
||||
search = null;
|
||||
} else if (action.equals(_("Delete Selected"))) {
|
||||
Iterator it = deletionMarks.iterator();
|
||||
while( it.hasNext() ) {
|
||||
name = (String)it.next();
|
||||
addressbook.remove( name );
|
||||
changed = true;
|
||||
deleted++;
|
||||
String name = null;
|
||||
int deleted = 0;
|
||||
for (String n : deletionMarks) {
|
||||
addressbook.remove(n);
|
||||
if (deleted++ == 0) {
|
||||
changed = true;
|
||||
name = n;
|
||||
}
|
||||
}
|
||||
if( changed ) {
|
||||
if (deleted == 1)
|
||||
@@ -337,6 +348,7 @@ public class AddressbookBean
|
||||
fos.close();
|
||||
} catch (IOException ioe) {}
|
||||
}
|
||||
|
||||
public String getFilter() {
|
||||
return filter;
|
||||
}
|
||||
@@ -382,7 +394,7 @@ public class AddressbookBean
|
||||
public void setHostname(String hostname) {
|
||||
this.hostname = DataHelper.stripHTML(hostname).trim(); // XSS
|
||||
}
|
||||
private int getBeginInt() {
|
||||
protected int getBeginInt() {
|
||||
return Math.max(0, Math.min(entries.length - 1, beginIndex));
|
||||
}
|
||||
public String getBegin() {
|
||||
@@ -393,7 +405,7 @@ public class AddressbookBean
|
||||
beginIndex = Integer.parseInt(s);
|
||||
} catch (NumberFormatException nfe) {}
|
||||
}
|
||||
private int getEndInt() {
|
||||
protected int getEndInt() {
|
||||
return Math.max(0, Math.max(getBeginInt(), Math.min(entries.length - 1, endIndex)));
|
||||
}
|
||||
public String getEnd() {
|
||||
@@ -406,17 +418,22 @@ public class AddressbookBean
|
||||
}
|
||||
|
||||
/** translate */
|
||||
private static String _(String s) {
|
||||
protected static String _(String s) {
|
||||
return Messages.getString(s);
|
||||
}
|
||||
|
||||
/** translate */
|
||||
private static String _(String s, Object o) {
|
||||
protected static String _(String s, Object o) {
|
||||
return Messages.getString(s, o);
|
||||
}
|
||||
|
||||
/** translate */
|
||||
private static String _(String s, Object o, Object o2) {
|
||||
protected static String _(String s, Object o, Object o2) {
|
||||
return Messages.getString(s, o, o2);
|
||||
}
|
||||
|
||||
/** translate (ngettext) @since 0.8.6 */
|
||||
protected static String _(int n, String s, String p) {
|
||||
return Messages.getString(n, s, p);
|
||||
}
|
||||
}
|
||||
|
@@ -31,4 +31,9 @@ public class Messages {
|
||||
public static String getString(String s, Object o, Object o2) {
|
||||
return Translate.getString(s, o, o2, I2PAppContext.getGlobalContext(), BUNDLE_NAME);
|
||||
}
|
||||
|
||||
/** translate (ngettext) @since 0.8.6 */
|
||||
public static String getString(int n, String s, String p) {
|
||||
return Translate.getString(n, s, p, I2PAppContext.getGlobalContext(), BUNDLE_NAME);
|
||||
}
|
||||
}
|
||||
|
228
apps/susidns/src/java/src/i2p/susi/dns/NamingServiceBean.java
Normal file
228
apps/susidns/src/java/src/i2p/susi/dns/NamingServiceBean.java
Normal file
@@ -0,0 +1,228 @@
|
||||
/*
|
||||
* This file is part of susidns project, see http://susi.i2p/
|
||||
*
|
||||
* Copyright (C) 2005 <susi23@mail.i2p>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* @since 0.8.6
|
||||
*/
|
||||
|
||||
package i2p.susi.dns;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.client.naming.NamingService;
|
||||
import net.i2p.data.DataFormatException;
|
||||
import net.i2p.data.DataHelper;
|
||||
import net.i2p.data.Destination;
|
||||
|
||||
/**
|
||||
* Talk to the NamingService API instead of modifying the hosts.txt files directly
|
||||
*
|
||||
* @since 0.8.5
|
||||
*/
|
||||
public class NamingServiceBean extends AddressbookBean
|
||||
{
|
||||
private static final String DEFAULT_NS = "BlockfileNamingService";
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isNotEmpty()
|
||||
{
|
||||
return getNamingService().size() > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFileName()
|
||||
{
|
||||
loadConfig();
|
||||
String filename = properties.getProperty( getBook() + "_addressbook" );
|
||||
int slash = filename.lastIndexOf('/');
|
||||
if (slash >= 0)
|
||||
filename = filename.substring(slash + 1);
|
||||
return filename;
|
||||
}
|
||||
|
||||
/** depth-first search */
|
||||
private NamingService searchNamingService(NamingService ns, String srch)
|
||||
{
|
||||
String name = ns.getName();
|
||||
if (name == srch || name == DEFAULT_NS)
|
||||
return ns;
|
||||
List<NamingService> list = ns.getNamingServices();
|
||||
if (list != null) {
|
||||
for (NamingService nss : list) {
|
||||
NamingService rv = searchNamingService(nss, srch);
|
||||
if (rv != null)
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/** @return the NamingService for the current file name, or the root NamingService */
|
||||
private NamingService getNamingService()
|
||||
{
|
||||
NamingService root = I2PAppContext.getGlobalContext().namingService();
|
||||
NamingService rv = searchNamingService(root, getFileName());
|
||||
return rv != null ? rv : root;
|
||||
}
|
||||
|
||||
/** Load addressbook and apply filter, returning messages about this. */
|
||||
@Override
|
||||
public String getLoadBookMessages()
|
||||
{
|
||||
NamingService service = getNamingService();
|
||||
Debug.debug("Searching within " + service + " with filename=" + getFileName() + " and with filter=" + filter + " and with search=" + search);
|
||||
String message = "";
|
||||
try {
|
||||
LinkedList<AddressBean> list = new LinkedList();
|
||||
Map<String, Destination> results;
|
||||
Properties searchProps = new Properties();
|
||||
// only blockfile needs this
|
||||
searchProps.setProperty("list", getFileName());
|
||||
if (filter != null) {
|
||||
String startsAt = filter == "0-9" ? "0" : filter;
|
||||
searchProps.setProperty("startsWith", startsAt);
|
||||
}
|
||||
if (beginIndex > 0)
|
||||
searchProps.setProperty("skip", Integer.toString(beginIndex));
|
||||
int limit = 1 + endIndex - beginIndex;
|
||||
if (limit > 0)
|
||||
searchProps.setProperty("limit", Integer.toString(limit));
|
||||
results = service.getEntries(searchProps);
|
||||
|
||||
Debug.debug("Result count: " + results.size());
|
||||
for (Map.Entry<String, Destination> entry : results.entrySet()) {
|
||||
String name = entry.getKey();
|
||||
if( filter != null && filter.length() > 0 ) {
|
||||
if( filter.compareTo( "0-9" ) == 0 ) {
|
||||
char first = name.charAt(0);
|
||||
if( first < '0' || first > '9' )
|
||||
continue;
|
||||
}
|
||||
else if( ! name.toLowerCase().startsWith( filter.toLowerCase() ) ) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if( search != null && search.length() > 0 ) {
|
||||
if( name.indexOf( search ) == -1 ) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
String destination = entry.getValue().toBase64();
|
||||
list.addLast( new AddressBean( name, destination ) );
|
||||
}
|
||||
AddressBean array[] = list.toArray(new AddressBean[list.size()]);
|
||||
Arrays.sort( array, sorter );
|
||||
entries = array;
|
||||
|
||||
message = generateLoadMessage();
|
||||
}
|
||||
catch (Exception e) {
|
||||
Debug.debug( e.getClass().getName() + ": " + e.getMessage() );
|
||||
}
|
||||
if( message.length() > 0 )
|
||||
message = "<p>" + message + "</p>";
|
||||
return message;
|
||||
}
|
||||
|
||||
/** Perform actions, returning messages about this. */
|
||||
@Override
|
||||
public String getMessages()
|
||||
{
|
||||
// Loading config and addressbook moved into getLoadBookMessages()
|
||||
String message = "";
|
||||
|
||||
if( action != null ) {
|
||||
Properties nsOptions = new Properties();
|
||||
// only blockfile needs this
|
||||
nsOptions.setProperty("list", getFileName());
|
||||
if( lastSerial != null && serial != null && serial.compareTo( lastSerial ) == 0 ) {
|
||||
boolean changed = false;
|
||||
if (action.equals(_("Add")) || action.equals(_("Replace"))) {
|
||||
if(hostname != null && destination != null) {
|
||||
Destination oldDest = getNamingService().lookup(hostname, nsOptions, null);
|
||||
if (oldDest != null && destination.equals(oldDest.toBase64())) {
|
||||
message = _("Host name {0} is already in addressbook, unchanged.", hostname);
|
||||
} else if (oldDest != null && !action.equals(_("Replace"))) {
|
||||
message = _("Host name {0} is already in addressbook with a different destination. Click \"Replace\" to overwrite.", hostname);
|
||||
} else {
|
||||
boolean valid = true;
|
||||
try {
|
||||
Destination dest = new Destination(destination);
|
||||
getNamingService().put(hostname, dest, nsOptions);
|
||||
} catch (DataFormatException dfe) {
|
||||
valid = false;
|
||||
}
|
||||
if (valid) {
|
||||
changed = true;
|
||||
if (oldDest == null)
|
||||
message = _("Destination added for {0}.", hostname);
|
||||
else
|
||||
message = _("Destination changed for {0}.", hostname);
|
||||
// clear form
|
||||
hostname = null;
|
||||
destination = null;
|
||||
} else {
|
||||
message = _("Invalid Base 64 destination.");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
message = _("Please enter a host name and destination");
|
||||
}
|
||||
// clear search when adding
|
||||
search = null;
|
||||
} else if (action.equals(_("Delete Selected"))) {
|
||||
String name = null;
|
||||
int deleted = 0;
|
||||
for (String n : deletionMarks) {
|
||||
getNamingService().remove(n, nsOptions);
|
||||
if (deleted++ == 0) {
|
||||
changed = true;
|
||||
name = n;
|
||||
}
|
||||
}
|
||||
if( changed ) {
|
||||
if (deleted == 1)
|
||||
message = _("Destination {0} deleted.", name);
|
||||
else
|
||||
message = _("{0} destinations deleted.", deleted);
|
||||
}
|
||||
}
|
||||
if( changed ) {
|
||||
message += "<br>" + _("Addressbook saved.");
|
||||
}
|
||||
}
|
||||
else {
|
||||
message = _("Invalid form submission, probably because you used the \"back\" or \"reload\" button on your browser. Please resubmit.");
|
||||
}
|
||||
}
|
||||
|
||||
action = null;
|
||||
|
||||
if( message.length() > 0 )
|
||||
message = "<p class=\"messages\">" + message + "</p>";
|
||||
return message;
|
||||
}
|
||||
}
|
@@ -32,7 +32,7 @@
|
||||
<%@ page contentType="text/html"%>
|
||||
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
|
||||
<jsp:useBean id="version" class="i2p.susi.dns.VersionBean" scope="application" />
|
||||
<jsp:useBean id="book" class="i2p.susi.dns.AddressbookBean" scope="session" />
|
||||
<jsp:useBean id="book" class="i2p.susi.dns.NamingServiceBean" scope="session" />
|
||||
<jsp:useBean id="intl" class="i2p.susi.dns.Messages" scope="application" />
|
||||
<jsp:setProperty name="book" property="*" />
|
||||
<jsp:setProperty name="book" property="resetDeletionMarks" value="1"/>
|
||||
@@ -55,10 +55,10 @@
|
||||
<div id="navi">
|
||||
<p>
|
||||
<%=intl._("addressbooks")%>
|
||||
<a href="addressbook.jsp?book=private&filter=none&begin=0&end=99"><%=intl._("private")%></a> |
|
||||
<a href="addressbook.jsp?book=master&filter=none&begin=0&end=99"><%=intl._("master")%></a> |
|
||||
<a href="addressbook.jsp?book=router&filter=none&begin=0&end=99"><%=intl._("router")%></a> |
|
||||
<a href="addressbook.jsp?book=published&filter=none&begin=0&end=99"><%=intl._("published")%></a> *
|
||||
<a href="addressbook.jsp?book=private&filter=none&begin=0&end=99"><%=intl._("private")%></a> |
|
||||
<a href="addressbook.jsp?book=master&filter=none&begin=0&end=99"><%=intl._("master")%></a> |
|
||||
<a href="addressbook.jsp?book=router&filter=none&begin=0&end=99"><%=intl._("router")%></a> |
|
||||
<a href="addressbook.jsp?book=published&filter=none&begin=0&end=99"><%=intl._("published")%></a> *
|
||||
<a href="subscriptions.jsp"><%=intl._("subscriptions")%></a> *
|
||||
<a href="config.jsp"><%=intl._("configuration")%></a> *
|
||||
<a href="index.jsp"><%=intl._("overview")%></a>
|
||||
@@ -71,42 +71,42 @@
|
||||
|
||||
<div id="messages">${book.messages}</div>
|
||||
|
||||
<span>${book.loadBookMessages}</span>
|
||||
${book.loadBookMessages}
|
||||
|
||||
<c:if test="${book.notEmpty}">
|
||||
<div id="filter">
|
||||
<p><%=intl._("Filter")%>:
|
||||
<a href="addressbook.jsp?filter=a&begin=0&end=99">a</a>
|
||||
<a href="addressbook.jsp?filter=b&begin=0&end=99">b</a>
|
||||
<a href="addressbook.jsp?filter=c&begin=0&end=99">c</a>
|
||||
<a href="addressbook.jsp?filter=d&begin=0&end=99">d</a>
|
||||
<a href="addressbook.jsp?filter=e&begin=0&end=99">e</a>
|
||||
<a href="addressbook.jsp?filter=f&begin=0&end=99">f</a>
|
||||
<a href="addressbook.jsp?filter=g&begin=0&end=99">g</a>
|
||||
<a href="addressbook.jsp?filter=h&begin=0&end=99">h</a>
|
||||
<a href="addressbook.jsp?filter=i&begin=0&end=99">i</a>
|
||||
<a href="addressbook.jsp?filter=j&begin=0&end=99">j</a>
|
||||
<a href="addressbook.jsp?filter=k&begin=0&end=99">k</a>
|
||||
<a href="addressbook.jsp?filter=l&begin=0&end=99">l</a>
|
||||
<a href="addressbook.jsp?filter=m&begin=0&end=99">m</a>
|
||||
<a href="addressbook.jsp?filter=n&begin=0&end=99">n</a>
|
||||
<a href="addressbook.jsp?filter=o&begin=0&end=99">o</a>
|
||||
<a href="addressbook.jsp?filter=p&begin=0&end=99">p</a>
|
||||
<a href="addressbook.jsp?filter=q&begin=0&end=99">q</a>
|
||||
<a href="addressbook.jsp?filter=r&begin=0&end=99">r</a>
|
||||
<a href="addressbook.jsp?filter=s&begin=0&end=99">s</a>
|
||||
<a href="addressbook.jsp?filter=t&begin=0&end=99">t</a>
|
||||
<a href="addressbook.jsp?filter=u&begin=0&end=99">u</a>
|
||||
<a href="addressbook.jsp?filter=v&begin=0&end=99">v</a>
|
||||
<a href="addressbook.jsp?filter=w&begin=0&end=99">w</a>
|
||||
<a href="addressbook.jsp?filter=x&begin=0&end=99">x</a>
|
||||
<a href="addressbook.jsp?filter=y&begin=0&end=99">y</a>
|
||||
<a href="addressbook.jsp?filter=z&begin=0&end=99">z</a>
|
||||
<a href="addressbook.jsp?filter=0-9&begin=0&end=99">0-9</a>
|
||||
<a href="addressbook.jsp?filter=none&begin=0&end=99"><%=intl._("all")%></a></p>
|
||||
<a href="addressbook.jsp?filter=a&begin=0&end=99">a</a>
|
||||
<a href="addressbook.jsp?filter=b&begin=0&end=99">b</a>
|
||||
<a href="addressbook.jsp?filter=c&begin=0&end=99">c</a>
|
||||
<a href="addressbook.jsp?filter=d&begin=0&end=99">d</a>
|
||||
<a href="addressbook.jsp?filter=e&begin=0&end=99">e</a>
|
||||
<a href="addressbook.jsp?filter=f&begin=0&end=99">f</a>
|
||||
<a href="addressbook.jsp?filter=g&begin=0&end=99">g</a>
|
||||
<a href="addressbook.jsp?filter=h&begin=0&end=99">h</a>
|
||||
<a href="addressbook.jsp?filter=i&begin=0&end=99">i</a>
|
||||
<a href="addressbook.jsp?filter=j&begin=0&end=99">j</a>
|
||||
<a href="addressbook.jsp?filter=k&begin=0&end=99">k</a>
|
||||
<a href="addressbook.jsp?filter=l&begin=0&end=99">l</a>
|
||||
<a href="addressbook.jsp?filter=m&begin=0&end=99">m</a>
|
||||
<a href="addressbook.jsp?filter=n&begin=0&end=99">n</a>
|
||||
<a href="addressbook.jsp?filter=o&begin=0&end=99">o</a>
|
||||
<a href="addressbook.jsp?filter=p&begin=0&end=99">p</a>
|
||||
<a href="addressbook.jsp?filter=q&begin=0&end=99">q</a>
|
||||
<a href="addressbook.jsp?filter=r&begin=0&end=99">r</a>
|
||||
<a href="addressbook.jsp?filter=s&begin=0&end=99">s</a>
|
||||
<a href="addressbook.jsp?filter=t&begin=0&end=99">t</a>
|
||||
<a href="addressbook.jsp?filter=u&begin=0&end=99">u</a>
|
||||
<a href="addressbook.jsp?filter=v&begin=0&end=99">v</a>
|
||||
<a href="addressbook.jsp?filter=w&begin=0&end=99">w</a>
|
||||
<a href="addressbook.jsp?filter=x&begin=0&end=99">x</a>
|
||||
<a href="addressbook.jsp?filter=y&begin=0&end=99">y</a>
|
||||
<a href="addressbook.jsp?filter=z&begin=0&end=99">z</a>
|
||||
<a href="addressbook.jsp?filter=0-9&begin=0&end=99">0-9</a>
|
||||
<a href="addressbook.jsp?filter=none&begin=0&end=99"><%=intl._("all")%></a></p>
|
||||
<c:if test="${book.hasFilter}">
|
||||
<p><%=intl._("Current filter")%>: ${book.filter}
|
||||
(<a href="addressbook.jsp?filter=none&begin=0&end=99"><%=intl._("clear filter")%></a>)</p>
|
||||
(<a href="addressbook.jsp?filter=none&begin=0&end=99"><%=intl._("clear filter")%></a>)</p>
|
||||
</c:if>
|
||||
</div>
|
||||
|
||||
@@ -176,8 +176,8 @@
|
||||
</c:if>
|
||||
|
||||
<div id="add">
|
||||
<p class="add">
|
||||
<h3><%=intl._("Add new destination")%>:</h3>
|
||||
<p class="add">
|
||||
<b><%=intl._("Hostname")%>:</b> <input type="text" name="hostname" value="${book.hostname}" size="20">
|
||||
<b><%=intl._("Destination")%>:</b> <textarea name="destination" rows="1" style="height: 3em;" cols="40" wrap="off" >${book.destination}</textarea><br/>
|
||||
</p><p>
|
||||
|
@@ -67,6 +67,7 @@ import net.metanotion.util.skiplist.SkipList;
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* All host names are converted to lower case.
|
||||
*/
|
||||
public class BlockfileNamingService extends DummyNamingService {
|
||||
|
||||
@@ -350,7 +351,7 @@ public class BlockfileNamingService extends DummyNamingService {
|
||||
|
||||
@Override
|
||||
public Destination lookup(String hostname, Properties lookupOptions, Properties storedOptions) {
|
||||
Destination d = super.lookup(hostname);
|
||||
Destination d = super.lookup(hostname, null, null);
|
||||
if (d != null)
|
||||
return d;
|
||||
|
||||
@@ -460,9 +461,11 @@ public class BlockfileNamingService extends DummyNamingService {
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
} catch (IOException re) {
|
||||
} catch (IOException ioe) {
|
||||
_log.error("DB remove error", ioe);
|
||||
return false;
|
||||
} catch (RuntimeException re) {
|
||||
_log.error("DB remove error", re);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -471,6 +474,7 @@ public class BlockfileNamingService extends DummyNamingService {
|
||||
/**
|
||||
* @param options If non-null and contains the key "list", get
|
||||
* from that list (default "hosts.txt", NOT all lists)
|
||||
* Key "skip": skip that many entries
|
||||
* Key "limit": max number to return
|
||||
* Key "startsWith": return only those starting with
|
||||
* Key "beginWith": start here in the iteration
|
||||
@@ -482,8 +486,11 @@ public class BlockfileNamingService extends DummyNamingService {
|
||||
String startsWith = null;
|
||||
String beginWith = null;
|
||||
int limit = Integer.MAX_VALUE;
|
||||
int skip = 0;
|
||||
if (options != null) {
|
||||
listname = options.getProperty("list");
|
||||
String ln = options.getProperty("list");
|
||||
if (ln != null)
|
||||
listname = ln;
|
||||
startsWith = options.getProperty("startsWith");
|
||||
beginWith = options.getProperty("beginWith");
|
||||
if (beginWith == null)
|
||||
@@ -492,18 +499,30 @@ public class BlockfileNamingService extends DummyNamingService {
|
||||
try {
|
||||
limit = Integer.parseInt(lim);
|
||||
} catch (NumberFormatException nfe) {}
|
||||
String sk = options.getProperty("skip");
|
||||
try {
|
||||
skip = Integer.parseInt(sk);
|
||||
} catch (NumberFormatException nfe) {}
|
||||
}
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Searching " + listname + " beginning with " + beginWith + " starting with " + startsWith + " limit=" + limit + " skip=" + skip);
|
||||
synchronized(_bf) {
|
||||
try {
|
||||
SkipList sl = _bf.getIndex(listname, _stringSerializer, _destSerializer);
|
||||
if (sl == null)
|
||||
if (sl == null) {
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn("No skiplist found for lookup in " + listname);
|
||||
return Collections.EMPTY_MAP;
|
||||
}
|
||||
SkipIterator iter;
|
||||
if (startsWith != null)
|
||||
if (beginWith != null)
|
||||
iter = sl.find(beginWith);
|
||||
else
|
||||
iter = sl.iterator();
|
||||
Map<String, Destination> rv = new HashMap();
|
||||
for (int i = 0; i < skip && iter.hasNext(); i++) {
|
||||
iter.next();
|
||||
}
|
||||
for (int i = 0; i < limit && iter.hasNext(); i++) {
|
||||
String key = (String) iter.nextKey();
|
||||
if (startsWith != null && !key.startsWith(startsWith))
|
||||
@@ -512,9 +531,11 @@ public class BlockfileNamingService extends DummyNamingService {
|
||||
rv.put(key, de.dest);
|
||||
}
|
||||
return rv;
|
||||
} catch (IOException re) {
|
||||
} catch (IOException ioe) {
|
||||
_log.error("DB lookup error", ioe);
|
||||
return Collections.EMPTY_MAP;
|
||||
} catch (RuntimeException re) {
|
||||
_log.error("DB lookup error", re);
|
||||
return Collections.EMPTY_MAP;
|
||||
}
|
||||
}
|
||||
@@ -539,9 +560,11 @@ public class BlockfileNamingService extends DummyNamingService {
|
||||
if (sl == null)
|
||||
return 0;
|
||||
return sl.size();
|
||||
} catch (IOException re) {
|
||||
} catch (IOException ioe) {
|
||||
_log.error("DB size error", ioe);
|
||||
return 0;
|
||||
} catch (RuntimeException re) {
|
||||
_log.error("DB size error", re);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -708,6 +731,9 @@ public class BlockfileNamingService extends DummyNamingService {
|
||||
return;
|
||||
}
|
||||
|
||||
System.out.println("size() reports " + bns.size());
|
||||
System.out.println("getEntries() returns " + bns.getEntries().size());
|
||||
|
||||
System.out.println("Testing with " + names.size() + " hostnames");
|
||||
int found = 0;
|
||||
int notfound = 0;
|
||||
|
@@ -85,6 +85,11 @@ public abstract class NamingService {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getClass().getSimpleName();
|
||||
}
|
||||
|
||||
///// New API Starts Here
|
||||
|
||||
/**
|
||||
|
Reference in New Issue
Block a user