com.senzing.naming.Registry Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of senzing-commons Show documentation
Show all versions of senzing-commons Show documentation
Utility classes and functions common to multiple Senzing projects.
The newest version!
package com.senzing.naming;
import com.senzing.util.AccessToken;
import javax.naming.NameAlreadyBoundException;
import javax.naming.NameNotFoundException;
import javax.naming.NoPermissionException;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Objects;
/**
* Provides a basic registry for objects of a specific type. This class acts
* as a simplified version of {@link javax.naming.Context} that is dedicated to
* instances of a specific class and confined to a single process in-memory
* lookup. Unbinding of previously bound objects is only allowed if the caller
* uses the {@link AccessToken} returned when the original binding was created
* to authorize the unbinding.
*
* @param The type of object provided by the registry instance.
*/
public class Registry {
/**
* The {@link Map} of {@link String} keys to the bound objects of the
* provided type.
*/
private Map bindingMap;
/**
* The {@link Map} of {@link String} keys to {@link AccessToken} instances
* used for authorizing unbinding.
*/
private Map tokenMap;
/**
* Indicates whether null
objects can be bound to names in this
* registry.
*/
private boolean allowNull;
/**
* Default constructor. Constructing with this constructor creates an
* instance that will not allow null
references in bindings.
*/
public Registry() {
this(false);
}
/**
* Constructs with the flag indicating if null
references can be
* bound in the registry.
*
* @param allowNull true
if bindings in this registry may exist
* to null
references, and false
* if bindings must be to non-null objects.
*/
public Registry(boolean allowNull) {
this.bindingMap = new LinkedHashMap<>();
this.tokenMap = new LinkedHashMap<>();
this.allowNull = allowNull;
}
/**
* Checks whether this registry instance allows bindings to null
* references. This returns true
if null
bindings
* are allowed, otherwise false
if they are forbidden and would
* generate a {@link NullPointerException} on an attempt to bind a
* null
reference.
*
* @return true
if null
bindings are allowed,
* otherwise false
*/
public boolean isAllowingNull() {
return this.allowNull;
}
/**
* Binds the specified object to the specified name in the registry. If
* an object is already bound to the specified name then an {@link
* NameAlreadyBoundException} is thrown. If the specified name is
* null
then a {@link NullPointerException} is thrown. If
* null
bindings {@linkplain #isAllowingNull() are not allowed}
* by this registry and the specified object is null
then a
* {@link NullPointerException} is thrown.
*
* @param name The non-null name to which to bind the specified object should
* be bound.
* @param object The object to bind to the specified name, which {@linkplain
* #isAllowingNull()} may be forbidden} from being
* null
.
*
* @return The {@link AccessToken} that the caller can use to {@linkplain
* #unbind(String, AccessToken) unbind} the name from the object.
*
* @throws NullPointerException If the specified name is null
or
* if null
bindings {@linkplain
* #isAllowingNull() are not allowed} and the
* specified object is null
.
*
* @throws NameAlreadyBoundException If the specified name is already bound
* to an object.
*/
public synchronized AccessToken bind(String name, T object)
throws NameAlreadyBoundException, NullPointerException
{
Objects.requireNonNull(name, "The bound name cannot be null");
if (!this.isAllowingNull()) {
Objects.requireNonNull(object, "The bound object cannot be null");
}
if (this.bindingMap.containsKey(name)) {
throw new NameAlreadyBoundException(
"The specified name is already bound: " + name);
}
AccessToken token = new AccessToken();
this.bindingMap.put(name, object);
this.tokenMap.put(name, token);
return token;
}
/**
* Looks up the object bound to the specified name and returns a reference to
* it. If no object is bound to the specified name then a {@link
* NameNotFoundException} is thrown. This may return null
if
* the registry {@linkplain #isAllowingNull() allows} null
* bindings.
*
* @param name The name for which the bound object should be returned.
*
* @return The object bound to the specified name.
*
* @throws NullPointerException If the specified name is null
.
* @throws NameNotFoundException If the specified name is not bound to an
* object.
*/
public synchronized T lookup(String name)
throws NullPointerException, NameNotFoundException
{
if (!this.bindingMap.containsKey(name)) {
throw new NameNotFoundException(
"The specified name is not bound: " + name);
}
return this.bindingMap.get(name);
}
/**
* Checks if the specified name is bound to a an object. Synchronize on this
* {@link Registry} instance to atomically combine a call to this method with
* another method call on this instance.
*
* @param name The name to check.
*
* @return true
if the specified name is bound, otherwise
* false
.
*
* @throws NullPointerException If the specified name is null
.
*/
public synchronized boolean isBound(String name)
throws NullPointerException
{
Objects.requireNonNull(name, "The specified name cannot be null");
return this.bindingMap.containsKey(name);
}
/**
* Unbinds the object that is bound to the specified name providing the
* specified {@link AccessToken} is the one that was returned when it was
* originally bound.
*
* @param name The non-null name for which to remove the binding.
* @param token The non-null {@link AccessToken} for authorizing permission to
* unbind the object.
*
* @throws NullPointerException If either of the parameters is
* null
.
* @throws NameNotFoundException If the specified name is not bound to any
* object.
* @throws NoPermissionException If the specified name is recognized, but
* the specified {@link AccessToken} is not
* the one associated with the specified name.
*/
public synchronized void unbind(String name, AccessToken token)
throws NullPointerException, NameNotFoundException, NoPermissionException
{
Objects.requireNonNull(name, "The provider name cannot be null");
Objects.requireNonNull(token, "The access token cannot be null");
AccessToken expected = this.tokenMap.get(name);
if (expected == null) {
throw new NameNotFoundException(
"The specified provider name is not recognized: " + name);
}
if (token != expected) {
throw new NoPermissionException(
"The specified token does not match the specified name: " + name);
}
this.bindingMap.remove(name);
this.tokenMap.remove(name);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy