/**
*
*/
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
{
/**
* 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);
/**
*
*/
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;
/**
* Returns the name register.
*
* @return name register
*/
public static NameRegister getRegistry()
{
if (_register == null)
{
_register = new UniqueNamePerInterface();
}
return _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;
}
}
}
}