First pass at a new naming system. Probably the last as well. So sad :).
This commit is contained in:
59
core/java/src/net/i2p/client/naming/AddressDB.java
Normal file
59
core/java/src/net/i2p/client/naming/AddressDB.java
Normal file
@ -0,0 +1,59 @@
|
||||
package net.i2p.client.naming;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.util.Collection;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.util.Log;
|
||||
import net.i2p.data.Address;
|
||||
|
||||
public abstract class AddressDB {
|
||||
|
||||
private final static Log _log = new Log(NamingService.class);
|
||||
protected I2PAppContext _context;
|
||||
|
||||
/** what classname should be used as the address db impl? */
|
||||
public static final String PROP_IMPL = "i2p.addressdb.impl";
|
||||
private static final String DEFAULT_IMPL = "net.i2p.client.naming.FilesystemAddressDB";
|
||||
|
||||
/**
|
||||
* The address db should only be constructed and accessed through the
|
||||
* application context. This constructor should only be used by the
|
||||
* appropriate application context itself.
|
||||
*
|
||||
*/
|
||||
protected AddressDB(I2PAppContext context) {
|
||||
_context = context;
|
||||
}
|
||||
|
||||
private AddressDB() { // nop
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an address db instance. This method ensures that there
|
||||
* will be only one address db instance (singleton) as well as
|
||||
* choose the implementation from the "i2p.addressdb.impl" system
|
||||
* property.
|
||||
*/
|
||||
public static final synchronized AddressDB createInstance(I2PAppContext context) {
|
||||
AddressDB instance = null;
|
||||
String impl = context.getProperty(PROP_IMPL, DEFAULT_IMPL);
|
||||
try {
|
||||
Class cls = Class.forName(impl);
|
||||
Constructor con = cls.getConstructor(new Class[] { I2PAppContext.class });
|
||||
instance = (AddressDB)con.newInstance(new Object[] { context });
|
||||
} catch (Exception ex) {
|
||||
_log.error("Cannot load address db implementation", ex);
|
||||
instance = new DummyAddressDB(context); // fallback
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
public abstract Address get(String hostname);
|
||||
public abstract Address put(Address address);
|
||||
public abstract Address remove(String hostname);
|
||||
public abstract Address remove(Address address);
|
||||
public abstract boolean contains(Address address);
|
||||
public abstract boolean contains(String hostname);
|
||||
public abstract Collection hostnames();
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
package net.i2p.client.naming;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.data.Destination;
|
||||
import net.i2p.data.Address;
|
||||
|
||||
public class AddressDBNamingService extends NamingService {
|
||||
|
||||
private AddressDB _addressdb;
|
||||
|
||||
public AddressDBNamingService(I2PAppContext context) {
|
||||
super(context);
|
||||
_addressdb = AddressDB.createInstance(context);
|
||||
}
|
||||
|
||||
private AddressDBNamingService() {
|
||||
super(null);
|
||||
}
|
||||
|
||||
public Destination lookup(String hostname) {
|
||||
Address addr = _addressdb.get(hostname);
|
||||
if (addr != null) {
|
||||
return addr.getDestination();
|
||||
} else {
|
||||
// If we can't find hostname in the addressdb, assume it's a key.
|
||||
return lookupBase64(hostname);
|
||||
}
|
||||
}
|
||||
|
||||
public String reverseLookup(Destination dest) {
|
||||
Iterator iter = _addressdb.hostnames().iterator();
|
||||
while (iter.hasNext()) {
|
||||
Address addr = _addressdb.get((String)iter.next());
|
||||
if (addr != null && addr.getDestination().equals(dest)) {
|
||||
return addr.getHostname();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
42
core/java/src/net/i2p/client/naming/DummyAddressDB.java
Normal file
42
core/java/src/net/i2p/client/naming/DummyAddressDB.java
Normal file
@ -0,0 +1,42 @@
|
||||
package net.i2p.client.naming;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.data.Address;
|
||||
|
||||
public class DummyAddressDB extends AddressDB {
|
||||
|
||||
public DummyAddressDB(I2PAppContext context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public Address get(String hostname) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Address put(Address address) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Address remove(String hostname) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Address remove(Address address) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean contains(Address address) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean contains(String hostname) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public Collection hostnames() {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
118
core/java/src/net/i2p/client/naming/FilesystemAddressDB.java
Normal file
118
core/java/src/net/i2p/client/naming/FilesystemAddressDB.java
Normal file
@ -0,0 +1,118 @@
|
||||
package net.i2p.client.naming;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Arrays;
|
||||
import java.util.Properties;
|
||||
import java.util.Iterator;
|
||||
import java.io.*;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.data.Address;
|
||||
import net.i2p.data.DataFormatException;
|
||||
import net.i2p.data.DataHelper;
|
||||
import net.i2p.util.Log;
|
||||
|
||||
public class FilesystemAddressDB extends AddressDB {
|
||||
|
||||
public final static String PROP_ADDRESS_DIR = "i2p.addressdir";
|
||||
public final static String DEFAULT_ADDRESS_DIR = "addressDb";
|
||||
private final static Log _log = new Log(FilesystemAddressDB.class);
|
||||
|
||||
public FilesystemAddressDB(I2PAppContext context) {
|
||||
super(context);
|
||||
|
||||
//If the address db directory doesn't exist, create it, using the
|
||||
//contents of hosts.txt.
|
||||
String dir = _context.getProperty(PROP_ADDRESS_DIR, DEFAULT_ADDRESS_DIR);
|
||||
File addrDir = new File(dir);
|
||||
if (!addrDir.exists()) {
|
||||
addrDir.mkdir();
|
||||
Properties hosts = new Properties();
|
||||
File hostsFile = new File("hosts.txt");
|
||||
if (hostsFile.exists() && hostsFile.canRead()) {
|
||||
try {
|
||||
DataHelper.loadProps(hosts, hostsFile);
|
||||
} catch (IOException ioe) {
|
||||
_log.error("Error loading hosts file " + hostsFile, ioe);
|
||||
}
|
||||
}
|
||||
Iterator iter = hosts.keySet().iterator();
|
||||
while (iter.hasNext()) {
|
||||
String hostname = (String)iter.next();
|
||||
Address addr = new Address();
|
||||
addr.setHostname(hostname);
|
||||
addr.setDestination(hosts.getProperty(hostname));
|
||||
put(addr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Address get(String hostname) {
|
||||
String dir = _context.getProperty(PROP_ADDRESS_DIR, DEFAULT_ADDRESS_DIR);
|
||||
File f = new File(dir, hostname);
|
||||
if (f.exists() && f.canRead()) {
|
||||
Address addr = new Address();
|
||||
try {
|
||||
addr.readBytes(new FileInputStream(f));
|
||||
} catch (FileNotFoundException exp) {
|
||||
return null;
|
||||
} catch (DataFormatException exp) {
|
||||
_log.error(f.getPath() + " is not a valid address file.");
|
||||
return null;
|
||||
} catch (IOException exp) {
|
||||
_log.error("Error reading " + f.getPath());
|
||||
return null;
|
||||
}
|
||||
return addr;
|
||||
} else {
|
||||
_log.warn(f.getPath() + " does not exist.");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public Address put(Address address) {
|
||||
Address previous = get(address.getHostname());
|
||||
|
||||
String dir = _context.getProperty(PROP_ADDRESS_DIR, DEFAULT_ADDRESS_DIR);
|
||||
File f = new File(dir, address.getHostname());
|
||||
try {
|
||||
address.writeBytes(new FileOutputStream(f));
|
||||
} catch (Exception exp) {
|
||||
_log.error("Error writing " + f.getPath(), exp);
|
||||
}
|
||||
return previous;
|
||||
}
|
||||
|
||||
public Address remove(String hostname) {
|
||||
Address previous = get(hostname);
|
||||
|
||||
String dir = _context.getProperty(PROP_ADDRESS_DIR, DEFAULT_ADDRESS_DIR);
|
||||
File f = new File(dir, hostname);
|
||||
f.delete();
|
||||
return previous;
|
||||
}
|
||||
|
||||
public Address remove(Address address) {
|
||||
if (contains(address)) {
|
||||
return remove(address.getHostname());
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean contains(Address address) {
|
||||
Address inDb = get(address.getHostname());
|
||||
return inDb.equals(address);
|
||||
}
|
||||
|
||||
public boolean contains(String hostname) {
|
||||
return hostnames().contains(hostname);
|
||||
}
|
||||
|
||||
public Collection hostnames() {
|
||||
String dir = _context.getProperty(PROP_ADDRESS_DIR, DEFAULT_ADDRESS_DIR);
|
||||
File f = new File(dir);
|
||||
return Arrays.asList(f.list());
|
||||
}
|
||||
|
||||
}
|
81
core/java/src/net/i2p/data/Address.java
Normal file
81
core/java/src/net/i2p/data/Address.java
Normal file
@ -0,0 +1,81 @@
|
||||
package net.i2p.data;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import net.i2p.util.Log;
|
||||
|
||||
public class Address extends DataStructureImpl {
|
||||
private final static Log _log = new Log(Address.class);
|
||||
private String _hostname;
|
||||
private Destination _destination;
|
||||
|
||||
public Address() {
|
||||
_hostname = null;
|
||||
_destination = null;
|
||||
}
|
||||
|
||||
public String getHostname() {
|
||||
return _hostname;
|
||||
}
|
||||
|
||||
public void setHostname(String hostname) {
|
||||
_hostname = hostname;
|
||||
}
|
||||
|
||||
public Destination getDestination() {
|
||||
return _destination;
|
||||
}
|
||||
|
||||
public void setDestination(Destination destination) {
|
||||
_destination = destination;
|
||||
}
|
||||
|
||||
public void setDestination(String base64) {
|
||||
try {
|
||||
Destination result = new Destination();
|
||||
result.fromBase64(base64);
|
||||
_destination = result;
|
||||
} catch (DataFormatException dfe) {
|
||||
_destination = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void readBytes(InputStream in) throws DataFormatException,
|
||||
IOException {
|
||||
_hostname = DataHelper.readString(in);
|
||||
_destination = new Destination();
|
||||
_destination.readBytes(in);
|
||||
}
|
||||
|
||||
public void writeBytes(OutputStream out) throws DataFormatException,
|
||||
IOException {
|
||||
if ((_hostname == null) || (_destination == null))
|
||||
throw new DataFormatException("Not enough data to write address");
|
||||
DataHelper.writeString(out, _hostname);
|
||||
_destination.writeBytes(out);
|
||||
}
|
||||
|
||||
public boolean equals(Object obj) {
|
||||
if ((obj == null) || !(obj instanceof Address)) return false;
|
||||
Address addr = (Address) obj;
|
||||
return DataHelper.eq(_hostname, addr.getHostname())
|
||||
&& DataHelper.eq(_destination, addr.getDestination());
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return DataHelper.hashCode(getHostname())
|
||||
+ DataHelper.hashCode(getDestination());
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
StringBuffer buf = new StringBuffer(64);
|
||||
buf.append("[Address: ");
|
||||
buf.append("\n\tHostname: ").append(getHostname());
|
||||
buf.append("\n\tDestination: ").append(getDestination());
|
||||
buf.append("]");
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user