/**
*
*/
package javax.jmdns.impl;
import java.net.InetAddress;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
/**
*
*/
public interface NameRegister {
/**
*
*/
public enum NameType {
/**
* This name represents a host name
*/
HOST,
/**
* This name represents a service name
*/
SERVICE,
}
public static abstract class BaseRegister implements NameRegister {
protected String incrementNameWithDash(String name) {
StringBuilder givenName = new StringBuilder(name.length() + 5);
int hostNameCount = 0;
int plocal = name.indexOf(".local.");
int punder = name.lastIndexOf('-');
if (punder < 0) {
// This is the first increment
hostNameCount = 1;
givenName.append(name.substring(0, plocal));
} else {
try {
int value = Integer.parseInt(name.substring(punder + 1, plocal));
hostNameCount = value + 1;
givenName.append(name.substring(0, punder));
} catch (Exception e) {
// If we got an exception this means that we have a name with a "-"
hostNameCount = 1;
givenName.append(name.substring(0, plocal));
}
}
givenName.append('-');
givenName.append(hostNameCount);
givenName.append(".local.");
return givenName.toString();
}
protected String incrementNameWithParentesis(String name) {
StringBuilder givenName = new StringBuilder(name.length() + 5);
final int l = name.lastIndexOf('(');
final int r = name.lastIndexOf(')');
if ((l >= 0) && (l < r)) {
try {
givenName.append(name.substring(0, l));
givenName.append('(');
givenName.append(Integer.parseInt(name.substring(l + 1, r)) + 1);
givenName.append(')');
} catch (final NumberFormatException e) {
givenName.setLength(0);
givenName.append(name);
givenName.append(" (2)");
}
} else {
givenName.append(name);
givenName.append(" (2)");
}
return givenName.toString();
}
}
public static class UniqueNamePerInterface extends BaseRegister {
private final ConcurrentMap<InetAddress, String> _hostNames;
private final ConcurrentMap<InetAddress, Set<String>> _serviceNames;
public UniqueNamePerInterface() {
super();
_hostNames = new ConcurrentHashMap<InetAddress, String>();
_serviceNames = new ConcurrentHashMap<InetAddress, Set<String>>();
}
/*
* (non-Javadoc)
* @see javax.jmdns.impl.NameRegister#register(java.net.InetAddress, java.lang.String, javax.jmdns.impl.NameRegister.NameType)
*/
@Override
public void register(InetAddress networkInterface, String name, NameType type) {
switch (type) {
case HOST:
break;
case SERVICE:
break;
default:
// this is trash to keep the compiler happy
}
}
/*
* (non-Javadoc)
* @see javax.jmdns.impl.NameRegister#checkName(java.net.InetAddress, java.lang.String, javax.jmdns.impl.NameRegister.NameType)
*/
@Override
public boolean checkName(InetAddress networkInterface, String name, NameType type) {
switch (type) {
case HOST:
String hostname = _hostNames.get(networkInterface);
return hostname != null && hostname.equals(name);
case SERVICE:
Set<String> names = _serviceNames.get(networkInterface);
return names != null && names.contains(names);
default:
// this is trash to keep the compiler happy
return false;
}
}
/*
* (non-Javadoc)
* @see javax.jmdns.impl.NameRegister#incrementHostName(java.net.InetAddress, java.lang.String, javax.jmdns.impl.NameRegister.NameType)
*/
@Override
public String incrementName(InetAddress networkInterface, String name, NameType type) {
switch (type) {
case HOST:
return this.incrementNameWithDash(name);
case SERVICE:
return this.incrementNameWithParentesis(name);
default:
// this is trash to keep the compiler happy
return name;
}
}
}
public static class UniqueNameAcrossInterface extends BaseRegister {
/*
* (non-Javadoc)
* @see javax.jmdns.impl.NameRegister#register(java.net.InetAddress, java.lang.String, javax.jmdns.impl.NameRegister.NameType)
*/
@Override
public void register(InetAddress networkInterface, String name, NameType type) {
switch (type) {
case HOST:
break;
case SERVICE:
break;
default:
// this is trash to keep the compiler happy
}
}
/*
* (non-Javadoc)
* @see javax.jmdns.impl.NameRegister#checkName(java.net.InetAddress, java.lang.String, javax.jmdns.impl.NameRegister.NameType)
*/
@Override
public boolean checkName(InetAddress networkInterface, String name, NameType type) {
switch (type) {
case HOST:
return false;
case SERVICE:
return false;
default:
// this is trash to keep the compiler happy
return false;
}
}
/*
* (non-Javadoc)
* @see javax.jmdns.impl.NameRegister#incrementHostName(java.net.InetAddress, java.lang.String, javax.jmdns.impl.NameRegister.NameType)
*/
@Override
public String incrementName(InetAddress networkInterface, String name, NameType type) {
switch (type) {
case HOST:
return this.incrementNameWithDash(name);
case SERVICE:
return this.incrementNameWithParentesis(name);
default:
// this is trash to keep the compiler happy
return name;
}
}
}
public static class Factory {
private static volatile NameRegister _register;
/**
* Register a Name register.
*
* @param register
* new register
* @throws IllegalStateException
* the register can only be set once
*/
public static void setRegistry(NameRegister register) throws IllegalStateException {
if (_register != null) {
throw new IllegalStateException("The register can only be set once.");
}
if (register != null) {
_register = register;
}
}
/**
* Returns the name register.
*
* @return name register
*/
public static NameRegister getRegistry() {
if (_register == null) {
_register = new UniqueNamePerInterface();
}
return _register;
}
}
/**
* Registers a name that is defended by this group of mDNS.
*
* @param networkInterface
* IP address to handle
* @param name
* name to register
* @param type
* name type to register
*/
public abstract void register(InetAddress networkInterface, String name, NameType type);
/**
* Checks a name that is defended by this group of mDNS.
*
* @param networkInterface
* IP address to handle
* @param name
* name to check
* @param type
* name type to check
* @return <code>true</code> if the name is not in conflict, <code>flase</code> otherwise.
*/
public abstract boolean checkName(InetAddress networkInterface, String name, NameType type);
/**
* Increments a name that is defended by this group of mDNS after it has been found in conflict.
*
* @param networkInterface
* IP address to handle
* @param name
* name to increment
* @param type
* name type to increments
* @return new name
*/
public abstract String incrementName(InetAddress networkInterface, String name, NameType type);
}